94 lines
1.9 KiB
Go
94 lines
1.9 KiB
Go
|
package alui
|
||
|
|
||
|
import (
|
||
|
"opslag.de/schobers/allg5"
|
||
|
"opslag.de/schobers/geom"
|
||
|
)
|
||
|
|
||
|
type Menu struct {
|
||
|
Proxy
|
||
|
|
||
|
panel *StackPanel
|
||
|
active int
|
||
|
buttons []*Button
|
||
|
}
|
||
|
|
||
|
func NewMenu() *Menu {
|
||
|
m := &Menu{}
|
||
|
m.Init()
|
||
|
return m
|
||
|
}
|
||
|
|
||
|
func (m *Menu) Init() {
|
||
|
m.panel = &StackPanel{Orientation: OrientationVertical}
|
||
|
m.Proxy.Target = m.panel
|
||
|
}
|
||
|
|
||
|
func (m *Menu) Activate(i int) {
|
||
|
if len(m.buttons) == 0 || i < 0 {
|
||
|
return
|
||
|
}
|
||
|
m.active = i % len(m.buttons)
|
||
|
}
|
||
|
|
||
|
func (m *Menu) Add(text string, onClick func()) {
|
||
|
idx := len(m.buttons)
|
||
|
button := &Button{Text: text, TextAlign: allg5.AlignCenter}
|
||
|
button.OnClick = onClick
|
||
|
button.OnEnter = func() {
|
||
|
m.updateActiveButton(idx)
|
||
|
}
|
||
|
if idx == 0 {
|
||
|
button.Over = true
|
||
|
}
|
||
|
m.buttons = append(m.buttons, button)
|
||
|
m.panel.Children = append(m.panel.Children, button)
|
||
|
}
|
||
|
|
||
|
func (m *Menu) Handle(e allg5.Event) {
|
||
|
m.Proxy.Handle(e)
|
||
|
|
||
|
if len(m.buttons) == 0 {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
switch e := e.(type) {
|
||
|
case *allg5.KeyCharEvent:
|
||
|
switch e.KeyCode {
|
||
|
case allg5.KeyDown:
|
||
|
m.updateActiveButton((m.active + 1) % len(m.buttons))
|
||
|
case allg5.KeyUp:
|
||
|
m.updateActiveButton((m.active + len(m.buttons) - 1) % len(m.buttons))
|
||
|
case allg5.KeyEnter:
|
||
|
if onClick := m.buttons[m.active].OnClick; onClick != nil {
|
||
|
onClick()
|
||
|
}
|
||
|
}
|
||
|
case *allg5.MouseMoveEvent:
|
||
|
for i, btn := range m.buttons {
|
||
|
if btn.Over {
|
||
|
m.updateActiveButton(i)
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
m.updateActiveButton(m.active)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (m *Menu) Layout(ctx *Context, bounds geom.RectangleF32) {}
|
||
|
|
||
|
func (m *Menu) Render(ctx *Context, bounds geom.RectangleF32) {
|
||
|
menuHeight := m.Proxy.DesiredSize(ctx).Y
|
||
|
width, center := bounds.Dx(), bounds.Center()
|
||
|
menuBounds := geom.RectF32(.25*width, center.Y-.5*menuHeight, .75*width, center.Y+.5*menuHeight)
|
||
|
m.Proxy.Layout(ctx, menuBounds)
|
||
|
m.Proxy.Render(ctx, menuBounds)
|
||
|
}
|
||
|
|
||
|
func (m *Menu) updateActiveButton(active int) {
|
||
|
m.active = active
|
||
|
for i, btn := range m.buttons {
|
||
|
btn.Over = i == m.active
|
||
|
}
|
||
|
}
|