1 val light_gray : u8 = 5 2 3 type AlignH = 4 | Left 5 | Right 6 | Center 7 | Stretch 8 9 type AlignV = 10 | Up 11 | Down 12 | Center 13 | Stretch 14 15 type Command @open 16 17 type Control @abstract @mut = 18 var width : u32 = 0 19 var height : u32 = 0 20 var min_width : u32 = 0 21 var max_width = u32.max 22 var min_height : u32 = 0 23 var max_height = u32.max 24 var measure_width : u32 = 0 25 var measure_height : u32 = 0 26 27 coerce 28 width measure_width { _.clamp min_width max_width } 29 height measure_height { _.clamp min_height max_height } 30 31 var align_h = AlignH/Stretch 32 var align_v = AlignV/Stretch 33 34 var parent : Option<Control> = None 35 let tokens = List<Token>.new 36 37 var origin = Vector3.new 38 var position = Vector3.new 39 var global_position @[mut private] = Vector3.new 40 41 let on_position_changed @optional (v : Vector3) 42 43 observe position origin { global_position = position + origin 44 on_position_changed global_position } 45 var is_visible = true 46 var is_hovered = false 47 var is_focused = false 48 var is_focusable = false 49 var is_resizable = false 50 var is_clickable = false 51 var is_scrollable = false 52 var is_receive_hover = false 53 var is_receive_mouse_move = false 54 var is_popup = false 55 var command : Option<Command> = None 56 val events = Stream<(Control, ControlEvent)>.new 57 58 def push (event : ControlEvent) = 59 events.push (self, event) 60 61 def subscribe (f : (Control, ControlEvent) -> Unit) = 62 events.add f 63 64 observe 65 width { _ w -> SizeEvent/Width w |> push } 66 height { _ h -> SizeEvent/Height h |> push } 67 min_width { _ w -> SizeEvent/MinWidth w |> push } 68 min_height { _ h -> SizeEvent/MinHeight h |> push } 69 max_width { _ w -> SizeEvent/MaxWidth w |> push } 70 max_height { _ h -> SizeEvent/MaxHeight h |> push } 71 is_visible { _ x -> FlagEvent/IsVisible x |> push } 72 is_hovered { _ x -> FlagEvent/IsHovered x |> push } 73 is_focused { _ x -> FlagEvent/IsFocused x |> push } 74 is_focusable { _ x -> FlagEvent/IsFocusable x |> push } 75 is_resizable { _ x -> FlagEvent/IsResizable x |> push } 76 77 def measure (w : u32) (h : u32) 78 def arrange 79 80 def push_token (token : Token) = 81 tokens.add token 82 83 def set_fixed_width (w : u32) = 84 min_width = w 85 max_width = w 86 width = w 87 88 def set_fixed_height (h : u32) = 89 min_height = h 90 max_height = h 91 height = h 92 93 def set_z (z : f32) = 94 position = position.with_z z 95 96 def contains (control : Control) : bool = 97 case control.parent of 98 None -> false 99 Some x -> if x == self 100 then true 101 else contains x 102 103 def discard = 104 for token in tokens do 105 token.discard 106 107 tokens.clear 108 109 object Control = 110 val offset_z : f32 = -0.0001 111 val window_z : f32 = -0.01 112 val max_size : u32 = u32.max / 4 113 114 type Container @abstract = 115 inherit Control 116 117 def get_slice : SafeSlice<Control> 118 119 let Control.on_position_changed (v : Vector3) = 120 let slice = get_slice 121 for item in slice do 122 item.origin = v 123 124 def init_child (control : Control) (atom : Atom<Option<Control>>) = 125 atom.subscribe { prev_maybe_x maybe_x -> 126 if prev_maybe_x ? Some prev_x then 127 assert prev_x.parent == Some control 128 prev_x.parent = None 129 130 if maybe_x ? Some x then 131 assert x.parent.is_none 132 x.parent = control 133 x.origin = control.global_position } |> control.push_token 134 135 def get_size_atom (control : Control) = 136 let atom = Atom<(u32, u32)> (control.width, control.height) 137 control.subscribe { _, event -> case event of 138 SizeEvent/Width _ | SizeEvent/Height _ -> 139 atom.set (control.width, control.height) 140 141 else -> () } 142 143 atom 144