1 type App = 2 let name : String 3 let is_resizable @param = false 4 val os_window = OsWindow.create 1920 1080 name is_resizable 5 Glfw.set_window_size_limits os_window.window 1200 600 Glfw.dont_care 6 Glfw.dont_care 7 Glfw.make_context_current os_window.window 8 val display = Display os_window 9 val mouse = Mouse.create os_window display.overlay.controls 10 display.controls display.focus@atom 11 12 val captured@atom = mouse.capture@atom.option_map { _.control } 13 14 let update_cursor () = 15 let maybe_control = captured.or_else mouse.hover 16 let shape = case maybe_control of 17 Some control -> case control.parent of 18 Some parent if parent is Resizer -> MouseShape/ResizeEw 19 else -> MouseShape/Arrow 20 21 None -> MouseShape/Arrow 22 23 if shape <> mouse.shape then 24 mouse.set_cursor os_window shape 25 26 let cursor_hover_token = mouse.hover@atom.subscribe { update_cursor } 27 let cursor_captured_token = captured@atom.subscribe { update_cursor } 28 29 val tick = Stream<f32>.new 30 let presenter = Presenter.new 31 let canvas = Canvas presenter 32 33 display.controls.add canvas 34 35 let f (control : Control) = 36 control.set_fixed_width os_window.width 37 set_fixed_height os_window.height 38 39 f canvas 40 f presenter 41 42 let size_token = os_window.sizes.subscribe { 43 f canvas 44 f presenter } 45 46 def run = 47 let frame_length_micros = 1000 / 0.06 |> as<u64> 48 let mut last_frame_time = Time.now - Duration 1 0 49 while not self.os_window.should_close do 50 repeat 51 let elapsed_micros = last_frame_time.elapsed.to_microseconds 52 if elapsed_micros + 200 >= frame_length_micros then 53 break 54 else 55 let sleep_duration = 56 frame_length_micros - elapsed_micros - 150 57 |> Duration.from_microseconds 58 59 thread/sleep sleep_duration 60 61 while frame_length_micros > last_frame_time.elapsed.to_microseconds 62 do 63 thread/yield 64 65 let dt = last_frame_time.elapsed.to_seconds_f32 |> min 0.049 66 last_frame_time = Time.now 67 os_window.update 68 glfw/update 69 tick.push dt 70 71 def add_window (window : Window) = 72 canvas.items.add window 73 bring_to_front window 74 75 val remove_window = { window -> 76 canvas.items.remove window 77 78 if captured.is_some && window.contains captured.unwrap then 79 mouse.capture = None }<Window> 80 81 def contains_window (window : Window) = 82 canvas.items.contains window 83 84 def set_content (content : Option<Control>) = 85 presenter.content = content 86 87 def discard = 88 size_token.discard 89 cursor_captured_token.discard 90 cursor_hover_token.discard 91 os_window.discard 92 Glfw.terminate 93 94 type Dependencies = 95 val os_window : OsWindow 96 val captured : Atom<Option<Control>> 97 val remove_window : Window -> Unit 98 val overlay : Overlay 99 100 type App 101 val dependencies = Dependencies 102 =os_window 103 captured = captured@atom 104 =remove_window 105 overlay = display.overlay 106