package objects // import "image" import "git.tebibyte.media/tomo/tomo" import "git.tebibyte.media/tomo/tomo/input" import "git.tebibyte.media/tomo/tomo/event" import "git.tebibyte.media/tomo/objects/layouts" var _ tomo.Object = new(Dropdown) // Dropdown is a non-editable text input that allows the user to pick a value // from a list. type Dropdown struct { box tomo.ContainerBox label *Label value string items []string menu *Menu on struct { valueChange event.FuncBroadcaster } } // NewDropdown creates a new dropdown input with the specified items func NewDropdown (items ...string) *Dropdown { dropdown := &Dropdown { box: tomo.NewContainerBox(), label: NewLabel(""), } dropdown.box.SetRole(tomo.R("objects", "Dropdown")) dropdown.box.SetAttr(tomo.ALayout(layouts.Row { true, false })) dropdown.box.Add(dropdown.label) dropdown.box.Add(NewIcon(tomo.IconListChoose, tomo.IconSizeSmall)) dropdown.SetItems(items...) if len(items) > 0 { dropdown.SetValue(items[0]) } dropdown.box.SetInputMask(true) dropdown.box.OnButtonDown(dropdown.handleButtonDown) dropdown.box.OnButtonUp(dropdown.handleButtonUp) dropdown.box.OnKeyDown(dropdown.handleKeyDown) dropdown.box.OnKeyUp(dropdown.handleKeyUp) dropdown.box.SetFocusable(true) return dropdown } // GetBox returns the underlying box. func (this *Dropdown) GetBox () tomo.Box { return this.box } // SetFocused sets whether or not this dropdown has keyboard focus. If set to // true, this method will steal focus away from whichever object currently has // focus. func (this *Dropdown) SetFocused (focused bool) { this.box.SetFocused(focused) } // Value returns the value of the dropdown. This does not necissarily have to be // in the list of items. func (this *Dropdown) Value () string { return this.value } // SetValue sets the value of the dropdown. This does not necissarily have to be // in the list of items. func (this *Dropdown) SetValue (value string) { this.value = value this.label.SetText(value) } // SetItems sets the items from which the user is able to pick. func (this *Dropdown) SetItems (items ...string) { this.items = items } // Choose creates a menu that allows the user to pick a value. func (this *Dropdown) Choose () { if this.menu != nil { this.menu.Close() } menu, err := NewAnchoredMenu(this, this.itemList()...) if err != nil { return } this.menu = menu menu.SetVisible(true) } func (this *Dropdown) itemList () []tomo.Object { items := make([]tomo.Object, len(this.items)) for index, value := range this.items { value := value item := NewMenuItem(value) item.OnClick(func () { this.SetValue(value) this.on.valueChange.Broadcast() }) items[index] = item } return items } func (this *Dropdown) handleKeyDown (key input.Key, numberPad bool) bool { if !isClickingKey(key) { return false } this.Choose() return true } func (this *Dropdown) handleKeyUp (key input.Key, numberPad bool) bool { if !isClickingKey(key) { return false } return true } func (this *Dropdown) handleButtonDown (button input.Button) bool { if !isClickingButton(button) { return false } return true } func (this *Dropdown) handleButtonUp (button input.Button) bool { if !isClickingButton(button) { return false } if this.box.Window().MousePosition().In(this.box.Bounds()) { this.Choose() } return true }