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