Menu/MenuItem work
This commit is contained in:
30
menu.go
30
menu.go
@@ -37,7 +37,8 @@ type Menu struct {
|
|||||||
|
|
||||||
menuType MenuType
|
menuType MenuType
|
||||||
cursor int
|
cursor int
|
||||||
items []Widget
|
items []*MenuItem
|
||||||
|
disabled []bool
|
||||||
onPressed func() bool
|
onPressed func() bool
|
||||||
manualExpand bool
|
manualExpand bool
|
||||||
expanded bool
|
expanded bool
|
||||||
@@ -134,7 +135,6 @@ func (w *Menu) drawVMenu(screen tcell.Screen) {
|
|||||||
h.TitledBorderFilled(x-1, y, x+w.WantW(), y+w.WantH(), w.label, h.BRD_CSIMPLE, w.style, screen)
|
h.TitledBorderFilled(x-1, y, x+w.WantW(), y+w.WantH(), w.label, h.BRD_CSIMPLE, w.style, screen)
|
||||||
}
|
}
|
||||||
h.DrawText(w.x, w.y, w.label, st, screen)
|
h.DrawText(w.x, w.y, w.label, st, screen)
|
||||||
y++
|
|
||||||
if w.expanded || (w.active && !w.manualExpand) {
|
if w.expanded || (w.active && !w.manualExpand) {
|
||||||
for i := range w.items {
|
for i := range w.items {
|
||||||
w.items[i].SetActive(w.active && w.cursor == i)
|
w.items[i].SetActive(w.active && w.cursor == i)
|
||||||
@@ -190,8 +190,14 @@ func (w *Menu) SetType(tp MenuType) { w.menuType = tp }
|
|||||||
func (w *Menu) SetLabel(lbl string) { w.label = lbl }
|
func (w *Menu) SetLabel(lbl string) { w.label = lbl }
|
||||||
func (w *Menu) SetFocusable(f bool) {}
|
func (w *Menu) SetFocusable(f bool) {}
|
||||||
|
|
||||||
|
func (w *Menu) GetItem(idx int) *MenuItem {
|
||||||
|
if len(w.items) > idx {
|
||||||
|
return w.items[idx]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
func (w *Menu) SetOnPressed(p func() bool) { w.onPressed = p }
|
func (w *Menu) SetOnPressed(p func() bool) { w.onPressed = p }
|
||||||
func (w *Menu) AddItems(iL ...Widget) {
|
func (w *Menu) AddItems(iL ...*MenuItem) {
|
||||||
var maxW int
|
var maxW int
|
||||||
for i := range iL {
|
for i := range iL {
|
||||||
if iL[i].WantW() > maxW {
|
if iL[i].WantW() > maxW {
|
||||||
@@ -202,6 +208,24 @@ func (w *Menu) AddItems(iL ...Widget) {
|
|||||||
w.SetW(maxW)
|
w.SetW(maxW)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Menu) RemoveItems(iL ...*MenuItem) {
|
||||||
|
var wrk []*MenuItem
|
||||||
|
for i := range w.items {
|
||||||
|
var skip bool
|
||||||
|
for j := range iL {
|
||||||
|
if w.items[i] == iL[j] {
|
||||||
|
skip = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if skip {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
wrk = append(wrk, w.items[i])
|
||||||
|
}
|
||||||
|
w.items = wrk
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Menu) MoveRight(ev *tcell.EventKey) bool {
|
func (w *Menu) MoveRight(ev *tcell.EventKey) bool {
|
||||||
if w.menuType != MenuTypeH {
|
if w.menuType != MenuTypeH {
|
||||||
return false
|
return false
|
||||||
|
|||||||
68
menu_item.go
68
menu_item.go
@@ -36,12 +36,15 @@ type MenuItem struct {
|
|||||||
w, h int
|
w, h int
|
||||||
|
|
||||||
menuType MenuType
|
menuType MenuType
|
||||||
|
cursor int
|
||||||
items []*MenuItem
|
items []*MenuItem
|
||||||
onPressed func() bool
|
onPressed func() bool
|
||||||
|
|
||||||
manualExpand bool
|
manualExpand bool
|
||||||
expanded bool
|
expanded bool
|
||||||
disabled bool
|
disabled bool
|
||||||
|
|
||||||
|
keyMap KeyMap
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMenuItem(id string, style tcell.Style) *MenuItem {
|
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.id = id
|
||||||
w.style = style
|
w.style = style
|
||||||
w.visible = true
|
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) Id() string { return w.id }
|
||||||
func (w *MenuItem) HandleResize(ev *tcell.EventResize) {}
|
func (w *MenuItem) HandleResize(ev *tcell.EventResize) {}
|
||||||
@@ -61,12 +79,8 @@ func (w *MenuItem) HandleKey(ev *tcell.EventKey) bool {
|
|||||||
if !w.active {
|
if !w.active {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if ev.Key() == tcell.KeyEnter {
|
// Look for a sub-item that's selected
|
||||||
if w.onPressed != nil {
|
return w.keyMap.Handle(ev)
|
||||||
return w.onPressed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func (w *MenuItem) HandleTime(ev *tcell.EventTime) {}
|
func (w *MenuItem) HandleTime(ev *tcell.EventTime) {}
|
||||||
func (w *MenuItem) Draw(screen tcell.Screen) {
|
func (w *MenuItem) Draw(screen tcell.Screen) {
|
||||||
@@ -77,10 +91,15 @@ func (w *MenuItem) Draw(screen tcell.Screen) {
|
|||||||
if w.active {
|
if w.active {
|
||||||
st = w.style.Reverse(true)
|
st = w.style.Reverse(true)
|
||||||
}
|
}
|
||||||
|
if w.disabled {
|
||||||
|
st = st.Dim(true)
|
||||||
|
st = st.Italic(true)
|
||||||
|
}
|
||||||
|
|
||||||
x, y := w.x, w.y
|
x, y := w.x, w.y
|
||||||
wd := w.w
|
wd := w.w
|
||||||
h.DrawText(x, y, h.PadR(w.label, wd), st, screen)
|
h.DrawText(x, y, h.PadR(w.label, wd), st, screen)
|
||||||
|
y += 1
|
||||||
if w.expanded {
|
if w.expanded {
|
||||||
x += 2
|
x += 2
|
||||||
for i := range w.items {
|
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) SetLabel(lbl string) { w.label = lbl }
|
||||||
func (w *MenuItem) SetDisabled(d bool) { w.disabled = d }
|
func (w *MenuItem) SetDisabled(d bool) { w.disabled = d }
|
||||||
|
func (w *MenuItem) IsDisabled() bool { return w.disabled }
|
||||||
|
|
||||||
func (w *MenuItem) AddItems(iL ...*MenuItem) {
|
func (w *MenuItem) AddItems(iL ...*MenuItem) {
|
||||||
w.items = append(w.items, iL...)
|
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 }
|
func (w *MenuItem) SetOnPressed(p func() bool) { w.onPressed = p }
|
||||||
|
|||||||
Reference in New Issue
Block a user