Much Work

- Definable KeyMaps
- Change 'Tabbable' to just use 'Focusable'
This commit is contained in:
2025-09-04 11:09:34 -05:00
parent c1db729bb3
commit f571b13a31
26 changed files with 881 additions and 615 deletions

View File

@@ -32,11 +32,11 @@ type Alert struct {
id string
style tcell.Style
x, y int
w, h int
active bool
visible bool
tabbable bool
x, y int
w, h int
active bool
visible bool
focusable bool
layout *LinearLayout
title string
@@ -60,14 +60,17 @@ func (w *Alert) Init(id string, style tcell.Style) {
w.id = id
w.style = style
w.layout = NewLinearLayout(fmt.Sprintf("%s-layout", id), tcell.StyleDefault)
w.layout = NewLinearLayout(fmt.Sprintf("%s-layout", id), style)
// w.layout.SetStacked(true)
w.message = NewText(fmt.Sprintf("%s-text", id), style)
w.layout.Add(w.message)
w.layout.AddFlag(w.message, LFAlignCenter)
w.btnLayout = NewLinearLayout("alertbtn-layout", tcell.StyleDefault)
w.btnLayout = NewLinearLayout("alertbtn-layout", style)
w.btnLayout.SetOrientation(LinLayH)
w.layout.Add(w.btnLayout)
w.layout.AddFlag(w.btnLayout, LFAlignCenter)
w.btnCancel = NewButton(fmt.Sprintf("%s-cancel", id), style)
w.btnCancel.SetLabel("Cancel")
@@ -86,22 +89,27 @@ func (w *Alert) Init(id string, style tcell.Style) {
tcell.KeyUp: w.SelectNext,
tcell.KeyEnter: w.Do,
})
w.tabbable = true
w.focusable = true
}
func (w *Alert) Id() string { return w.id }
func (w *Alert) HandleResize(ev *tcell.EventResize) {
w.w, w.h = ev.Size()
if w.w > w.MinW() {
w.w = w.MinW()
}
if w.h > w.MinH() {
w.h = w.MinH()
}
// Trim space for the borders and pass on the size to the layout
w.layout.SetPos(Coord{X: 1, Y: 1})
w.layout.HandleResize(tcell.NewEventResize(w.w-2, w.h-2))
}
func (w *Alert) SetKeyMap(km KeyMap) { w.keyMap = km }
func (w *Alert) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
func (w *Alert) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys {
w.keyMap.Remove(k)
}
for r := range km.Runes {
w.keyMap.RemoveRune(r)
}
}
func (w *Alert) HandleKey(ev *tcell.EventKey) bool {
if !w.active {
return false
@@ -119,24 +127,23 @@ func (w *Alert) Draw(screen tcell.Screen) {
w.GetPos().DrawOffset(w.layout, screen)
}
func (w *Alert) Active() bool { return w.active }
func (w *Alert) SetActive(a bool) { w.active = a }
func (w *Alert) Visible() bool { return w.visible }
func (w *Alert) SetVisible(a bool) { w.visible = a }
func (w *Alert) SetX(x int) { w.x = x }
func (w *Alert) SetY(y int) { w.y = y }
func (w *Alert) GetX() int { return w.x }
func (w *Alert) GetY() int { return w.y }
func (w *Alert) GetPos() Coord { return Coord{X: w.x, Y: w.y} }
func (w *Alert) SetPos(c Coord) { w.x, w.y = c.X, c.Y }
func (w *Alert) SetW(x int) { w.w = x }
func (w *Alert) SetH(y int) { w.h = y }
func (w *Alert) GetW() int { return w.w }
func (w *Alert) GetH() int { return w.y }
func (w *Alert) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
func (w *Alert) Focusable() bool { return true }
func (w *Alert) SetTabbable(b bool) { w.tabbable = b }
func (w *Alert) Tabbable() bool { return w.tabbable }
func (w *Alert) Active() bool { return w.active }
func (w *Alert) SetActive(a bool) { w.active = a }
func (w *Alert) Visible() bool { return w.visible }
func (w *Alert) SetVisible(a bool) { w.visible = a }
func (w *Alert) SetX(x int) { w.x = x }
func (w *Alert) SetY(y int) { w.y = y }
func (w *Alert) GetX() int { return w.x }
func (w *Alert) GetY() int { return w.y }
func (w *Alert) GetPos() Coord { return Coord{X: w.x, Y: w.y} }
func (w *Alert) SetPos(c Coord) { w.x, w.y = c.X, c.Y }
func (w *Alert) SetW(x int) { w.w = x }
func (w *Alert) SetH(y int) { w.h = y }
func (w *Alert) GetW() int { return w.w }
func (w *Alert) GetH() int { return w.y }
func (w *Alert) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
func (w *Alert) Focusable() bool { return w.focusable }
func (w *Alert) SetFocusable(b bool) { w.focusable = b }
func (w *Alert) WantW() int {
return 4 + wh.Max(w.message.WantW(), (w.btnOk.WantW()+w.btnCancel.WantW()))
}
@@ -145,30 +152,40 @@ func (w *Alert) WantH() int {
return 4 + w.btnOk.WantH() + w.message.WantH()
}
// Borders + Buttons
func (w *Alert) MinW() int {
return 5 + wh.Max(w.message.MinW(), (w.btnOk.MinW()+w.btnCancel.MinW()))
return 4 + wh.Max(w.message.MinW(), (w.btnOk.MinW()+w.btnCancel.MinW()))
}
// Borders + Buttons + 2 lines for message
func (w *Alert) MinH() int {
return 5 + w.message.MinH() + w.btnOk.MinH()
return 4 + w.message.MinH() + w.btnOk.MinH()
}
func (w *Alert) SetTitle(ttl string) { w.title = ttl }
func (w *Alert) SetMessage(msg string) { w.message.SetText(msg) }
func (w *Alert) SetOkPressed(b func() bool) { w.btnOk.SetOnPressed(b) }
func (w *Alert) SetCancelPressed(b func() bool) { w.btnCancel.SetOnPressed(b) }
func (w *Alert) SetOkPressed(b func() bool) {
w.btnOk.SetVisible(b != nil)
w.btnOk.SetFocusable(b != nil)
w.btnOk.SetOnPressed(b)
}
func (w *Alert) SetCancelPressed(b func() bool) {
w.btnCancel.SetVisible(b != nil)
w.btnCancel.SetFocusable(b != nil)
w.btnCancel.SetOnPressed(b)
}
func (w *Alert) SelectNext(ev *tcell.EventKey) bool {
if w.btnOk.Active() {
if w.btnOk.Active() && w.btnCancel.Visible() {
w.btnOk.SetActive(false)
w.btnCancel.SetActive(true)
} else {
return true
} else if w.btnCancel.Active() && w.btnOk.Visible() {
w.btnOk.SetActive(true)
w.btnCancel.SetActive(false)
return true
}
return true
return false
}
func (w *Alert) Do(ev *tcell.EventKey) bool {