Menu/MenuItem work

This commit is contained in:
2025-08-01 15:00:03 -05:00
parent 9e88799391
commit 1474caffaa
2 changed files with 89 additions and 9 deletions

View File

@@ -36,12 +36,15 @@ type MenuItem struct {
w, h int
menuType MenuType
cursor int
items []*MenuItem
onPressed func() bool
manualExpand bool
expanded bool
disabled bool
keyMap KeyMap
}
func NewMenuItem(id string, style tcell.Style) *MenuItem {
@@ -54,6 +57,21 @@ func (w *MenuItem) Init(id string, style tcell.Style) {
w.id = id
w.style = style
w.visible = true
w.keyMap = NewKeyMap(map[tcell.Key]func(ev *tcell.EventKey) bool{
tcell.KeyUp: w.MoveUp,
tcell.KeyDown: w.MoveDown,
tcell.KeyEnter: func(ev *tcell.EventKey) bool {
if w.onPressed != nil {
return w.onPressed()
} else if len(w.items) > w.cursor && w.items[w.cursor].HandleKey(ev) {
return true
}
return false
},
})
for i := range w.items {
w.items[i].SetActive(i == w.cursor)
}
}
func (w *MenuItem) Id() string { return w.id }
func (w *MenuItem) HandleResize(ev *tcell.EventResize) {}
@@ -61,12 +79,8 @@ func (w *MenuItem) HandleKey(ev *tcell.EventKey) bool {
if !w.active {
return false
}
if ev.Key() == tcell.KeyEnter {
if w.onPressed != nil {
return w.onPressed()
}
}
return false
// Look for a sub-item that's selected
return w.keyMap.Handle(ev)
}
func (w *MenuItem) HandleTime(ev *tcell.EventTime) {}
func (w *MenuItem) Draw(screen tcell.Screen) {
@@ -77,10 +91,15 @@ func (w *MenuItem) Draw(screen tcell.Screen) {
if w.active {
st = w.style.Reverse(true)
}
if w.disabled {
st = st.Dim(true)
st = st.Italic(true)
}
x, y := w.x, w.y
wd := w.w
h.DrawText(x, y, h.PadR(w.label, wd), st, screen)
y += 1
if w.expanded {
x += 2
for i := range w.items {
@@ -140,10 +159,47 @@ func (w *MenuItem) Expand(e bool) {
}
}
func (w *MenuItem) updateActive() {
for i := range w.items {
w.items[i].SetActive(i == w.cursor)
}
}
func (w *MenuItem) MoveUp(ev *tcell.EventKey) bool {
// Look for a previous enabled item
st := w.cursor
i := (w.cursor - 1 + len(w.items)) % len(w.items)
for ; i != st; i = (i - 1 + len(w.items)) % len(w.items) {
if !w.items[i].IsDisabled() {
break
}
}
w.cursor = i
w.updateActive()
return true
}
func (w *MenuItem) MoveDown(ev *tcell.EventKey) bool {
// Look for next enabled item
st := w.cursor
i := (st + 1) % len(w.items)
for ; i != st; i = (i + 1) % len(w.items) {
if !w.items[i].IsDisabled() {
break
}
}
w.cursor = i
w.updateActive()
return true
}
func (w *MenuItem) SetLabel(lbl string) { w.label = lbl }
func (w *MenuItem) SetDisabled(d bool) { w.disabled = d }
func (w *MenuItem) IsDisabled() bool { return w.disabled }
func (w *MenuItem) AddItems(iL ...*MenuItem) {
w.items = append(w.items, iL...)
for i := range w.items {
w.items[i].SetActive(i == w.cursor)
}
}
func (w *MenuItem) SetOnPressed(p func() bool) { w.onPressed = p }