1 type DataItem @mut = 2 var obs name = "" 3 4 type Selector = 5 inherit Decorator 6 7 let overlay : Overlay @auto 8 val items @mut = obs/List<DataItem>.new 9 var obs selected_item : Option<DataItem> = None 10 11 is_focusable = true 12 align_h = AlignH/Left 13 align_v = AlignV/Up 14 15 let text_block = TextBlock.new 16 val rectangle = Rectangle.new 17 let popup = Stack.new 18 let popup_rectangle = Rectangle.new 19 20 let stack = Stack 21 position = Vector3 0 0 Control.offset_z 22 rectangle 23 color = Vector3.gray 0.8 24 text_block 25 popup_rectangle 26 is_popup = true 27 is_visible = false 28 color = Vector3 1 1 1 29 popup 30 31 text_block.set_z Control.offset_z 32 33 selected_item@atom.bind { maybe_item -> 34 let s = case maybe_item of 35 None -> "" 36 Some item -> item.name 37 38 text_block.text = s } |> push_token 39 40 items |> Obs.map { item -> Button on_press <- { selected_item = item } 41 text = item.name 42 is_focusable = true } 43 44 |> bind { index button -> popup.items.add index button } 45 { index button -> popup.items.remove index button } 46 |> push_token 47 48 subscribe { _, event -> if event ? FlagEvent/IsFocused x then 49 popup_rectangle.is_visible = x 50 if x then 51 overlay.add popup_rectangle 52 else 53 overlay.remove popup_rectangle } 54 55 content = stack 56 57 def Control.measure w h = 58 measure_clamped stack w Control.max_size 59 let res_w = stack.measure_width 60 let res_h = rectangle.measure_height 61 62 measure_width = res_w 63 measure_height = res_h 64 65 def Control.arrange = 66 arrange_measured stack 67