objects/menuitem.go

75 lines
1.9 KiB
Go
Raw Normal View History

2024-06-06 23:59:29 -06:00
package objects
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"
// MenuItem is a clickable button.
type MenuItem struct {
tomo.ContainerBox
label *Label
icon *Icon
labelActive bool
on struct {
click event.FuncBroadcaster
}
}
// NewMenuItem creates a new menu item with the specified text.
func NewMenuItem (text string) *MenuItem {
box := &MenuItem {
ContainerBox: tomo.NewContainerBox(),
label: NewLabel(text),
icon: NewIcon("", tomo.IconSizeSmall),
}
box.SetRole(tomo.R("objects", "MenuItem", ""))
tomo.Apply(box)
box.label.SetAlign(tomo.AlignStart, tomo.AlignMiddle)
box.SetLayout(layouts.NewGrid([]bool { false, true }, []bool { true }))
box.Add(box.icon)
box.Add(box.label)
box.CaptureDND(true)
box.CaptureMouse(true)
box.CaptureScroll(true)
box.CaptureKeyboard(true)
box.OnMouseUp(box.handleMouseUp)
box.OnKeyUp(box.handleKeyUp)
box.SetFocusable(true)
return box
}
// SetText sets the text of the items's label.
func (this *MenuItem) SetText (text string) {
this.label.SetText(text)
}
// SetIcon sets an icon for this item. Setting the icon to IconUnknown will
// remove it.
func (this *MenuItem) SetIcon (id tomo.Icon) {
if this.icon != nil { this.Remove(this.icon) }
this.Insert(NewIcon(id, tomo.IconSizeSmall), this.label)
}
// OnClick specifies a function to be called when the menu item is clicked.
func (this *MenuItem) OnClick (callback func ()) event.Cookie {
return this.on.click.Connect(callback)
}
func (this *MenuItem) handleKeyUp (key input.Key, numberPad bool) {
if key != input.KeyEnter && key != input.Key(' ') { return }
this.on.click.Broadcast()
}
func (this *MenuItem) handleMouseUp (button input.Button) {
if button != input.ButtonLeft { return }
if this.MousePosition().In(this.Bounds()) {
this.on.click.Broadcast()
}
}