Much Work
- Definable KeyMaps - Change 'Tabbable' to just use 'Focusable'
This commit is contained in:
21
keymap.go
21
keymap.go
@@ -49,12 +49,17 @@ func NewRuneMap(m map[rune]func(*tcell.EventKey) bool) KeyMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m KeyMap) Merge(km KeyMap) {
|
||||||
|
for k, v := range km.Keys {
|
||||||
|
m.Keys[k] = v
|
||||||
|
}
|
||||||
|
for r, v := range km.Runes {
|
||||||
|
m.Runes[r] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (m KeyMap) Add(k tcell.Key, do func(*tcell.EventKey) bool) { m.Keys[k] = do }
|
func (m KeyMap) Add(k tcell.Key, do func(*tcell.EventKey) bool) { m.Keys[k] = do }
|
||||||
func (m KeyMap) Remove(k tcell.Key) {
|
func (m KeyMap) Remove(k tcell.Key) { delete(m.Keys, k) }
|
||||||
if _, ok := m.Keys[k]; ok {
|
|
||||||
delete(m.Keys, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m KeyMap) AddAll(all map[tcell.Key]func(*tcell.EventKey) bool) {
|
func (m KeyMap) AddAll(all map[tcell.Key]func(*tcell.EventKey) bool) {
|
||||||
for k, v := range all {
|
for k, v := range all {
|
||||||
@@ -62,11 +67,7 @@ func (m KeyMap) AddAll(all map[tcell.Key]func(*tcell.EventKey) bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (m KeyMap) AddRune(k rune, do func(*tcell.EventKey) bool) { m.Runes[k] = do }
|
func (m KeyMap) AddRune(k rune, do func(*tcell.EventKey) bool) { m.Runes[k] = do }
|
||||||
func (m KeyMap) RemoveRune(k rune) {
|
func (m KeyMap) RemoveRune(k rune) { delete(m.Runes, k) }
|
||||||
if _, ok := m.Runes[k]; ok {
|
|
||||||
delete(m.Runes, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m KeyMap) AddRunes(all map[rune]func(*tcell.EventKey) bool) {
|
func (m KeyMap) AddRunes(all map[rune]func(*tcell.EventKey) bool) {
|
||||||
for k, v := range all {
|
for k, v := range all {
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ const (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
LFAlignTopLeft = LayoutFlag(LFAlignHLeft | LFAlignVTop)
|
LFAlignTopLeft = LayoutFlag(LFAlignHLeft | LFAlignVTop)
|
||||||
|
LFAlignCenter = LayoutFlag(LFAlignHCenter | LFAlignVCenter)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (f LayoutFlag) Add(fl LayoutFlag) { f |= fl }
|
func (f LayoutFlag) Add(fl LayoutFlag) { f |= fl }
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ type AbsoluteLayout struct {
|
|||||||
|
|
||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
tabbable bool
|
focusable bool
|
||||||
|
|
||||||
|
keyMap KeyMap
|
||||||
|
|
||||||
cursor int
|
cursor int
|
||||||
disableTab bool
|
disableTab bool
|
||||||
@@ -76,20 +78,30 @@ func (w *AbsoluteLayout) Init(id string, s tcell.Style) {
|
|||||||
w.style = s
|
w.style = s
|
||||||
w.visible = true
|
w.visible = true
|
||||||
w.defAnchor = AnchorTL
|
w.defAnchor = AnchorTL
|
||||||
|
w.keyMap = BlankKeyMap()
|
||||||
w.wCoords = make(map[Widget]Coord)
|
w.wCoords = make(map[Widget]Coord)
|
||||||
w.wAnchor = make(map[Widget]AbsoluteAnchor)
|
w.wAnchor = make(map[Widget]AbsoluteAnchor)
|
||||||
w.wManualSizes = make(map[Widget]Coord)
|
w.wManualSizes = make(map[Widget]Coord)
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *AbsoluteLayout) Id() string { return w.id }
|
func (w *AbsoluteLayout) Id() string { return w.id }
|
||||||
func (w *AbsoluteLayout) HandleResize(ev *tcell.EventResize) {
|
func (w *AbsoluteLayout) HandleResize(ev *tcell.EventResize) {
|
||||||
w.w, w.h = ev.Size()
|
w.w, w.h = ev.Size()
|
||||||
// w.w = wh.Min(w.w, w.WantW())
|
|
||||||
// w.h = wh.Min(w.h, w.WantH())
|
|
||||||
w.updateWidgetLayouts()
|
w.updateWidgetLayouts()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *AbsoluteLayout) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *AbsoluteLayout) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *AbsoluteLayout) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *AbsoluteLayout) HandleKey(ev *tcell.EventKey) bool {
|
func (w *AbsoluteLayout) HandleKey(ev *tcell.EventKey) bool {
|
||||||
if !w.disableTab && ev.Key() == tcell.KeyTab {
|
if !w.disableTab && ev.Key() == tcell.KeyTab {
|
||||||
fndP := -1
|
fndP := -1
|
||||||
@@ -101,7 +113,7 @@ func (w *AbsoluteLayout) HandleKey(ev *tcell.EventKey) bool {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if w.widgets[i].Focusable() && w.widgets[i].Tabbable() {
|
if w.widgets[i].Focusable() {
|
||||||
w.widgets[i].SetActive(true)
|
w.widgets[i].SetActive(true)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -112,7 +124,7 @@ func (w *AbsoluteLayout) HandleKey(ev *tcell.EventKey) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for i := 0; i < fndP; i++ {
|
for i := 0; i < fndP; i++ {
|
||||||
if w.widgets[i].Focusable() && w.widgets[i].Tabbable() {
|
if w.widgets[i].Focusable() {
|
||||||
w.widgets[i].SetActive(true)
|
w.widgets[i].SetActive(true)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -147,9 +159,8 @@ func (w *AbsoluteLayout) Active() bool { return w.active }
|
|||||||
func (w *AbsoluteLayout) SetActive(a bool) { w.active = a }
|
func (w *AbsoluteLayout) SetActive(a bool) { w.active = a }
|
||||||
func (w *AbsoluteLayout) Visible() bool { return w.visible }
|
func (w *AbsoluteLayout) Visible() bool { return w.visible }
|
||||||
func (w *AbsoluteLayout) SetVisible(a bool) { w.visible = a }
|
func (w *AbsoluteLayout) SetVisible(a bool) { w.visible = a }
|
||||||
func (w *AbsoluteLayout) Focusable() bool { return true }
|
func (w *AbsoluteLayout) Focusable() bool { return w.focusable }
|
||||||
func (w *AbsoluteLayout) SetTabbable(b bool) { w.tabbable = b }
|
func (w *AbsoluteLayout) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *AbsoluteLayout) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *AbsoluteLayout) SetX(x int) { w.x = x }
|
func (w *AbsoluteLayout) SetX(x int) { w.x = x }
|
||||||
func (w *AbsoluteLayout) SetY(y int) { w.y = y }
|
func (w *AbsoluteLayout) SetY(y int) { w.y = y }
|
||||||
func (w *AbsoluteLayout) GetX() int { return w.x }
|
func (w *AbsoluteLayout) GetX() int { return w.x }
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ type Alert struct {
|
|||||||
w, h int
|
w, h int
|
||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
tabbable bool
|
focusable bool
|
||||||
|
|
||||||
layout *LinearLayout
|
layout *LinearLayout
|
||||||
title string
|
title string
|
||||||
@@ -60,14 +60,17 @@ func (w *Alert) Init(id string, style tcell.Style) {
|
|||||||
w.id = id
|
w.id = id
|
||||||
w.style = style
|
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.message = NewText(fmt.Sprintf("%s-text", id), style)
|
||||||
w.layout.Add(w.message)
|
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.btnLayout.SetOrientation(LinLayH)
|
||||||
w.layout.Add(w.btnLayout)
|
w.layout.Add(w.btnLayout)
|
||||||
|
w.layout.AddFlag(w.btnLayout, LFAlignCenter)
|
||||||
|
|
||||||
w.btnCancel = NewButton(fmt.Sprintf("%s-cancel", id), style)
|
w.btnCancel = NewButton(fmt.Sprintf("%s-cancel", id), style)
|
||||||
w.btnCancel.SetLabel("Cancel")
|
w.btnCancel.SetLabel("Cancel")
|
||||||
@@ -86,22 +89,27 @@ func (w *Alert) Init(id string, style tcell.Style) {
|
|||||||
tcell.KeyUp: w.SelectNext,
|
tcell.KeyUp: w.SelectNext,
|
||||||
tcell.KeyEnter: w.Do,
|
tcell.KeyEnter: w.Do,
|
||||||
})
|
})
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
}
|
}
|
||||||
func (w *Alert) Id() string { return w.id }
|
func (w *Alert) Id() string { return w.id }
|
||||||
func (w *Alert) HandleResize(ev *tcell.EventResize) {
|
func (w *Alert) HandleResize(ev *tcell.EventResize) {
|
||||||
w.w, w.h = ev.Size()
|
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
|
// Trim space for the borders and pass on the size to the layout
|
||||||
w.layout.SetPos(Coord{X: 1, Y: 1})
|
w.layout.SetPos(Coord{X: 1, Y: 1})
|
||||||
w.layout.HandleResize(tcell.NewEventResize(w.w-2, w.h-2))
|
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 {
|
func (w *Alert) HandleKey(ev *tcell.EventKey) bool {
|
||||||
if !w.active {
|
if !w.active {
|
||||||
return false
|
return false
|
||||||
@@ -134,9 +142,8 @@ func (w *Alert) SetH(y int) { w.h = y }
|
|||||||
func (w *Alert) GetW() int { return w.w }
|
func (w *Alert) GetW() int { return w.w }
|
||||||
func (w *Alert) GetH() int { return w.y }
|
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) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
||||||
func (w *Alert) Focusable() bool { return true }
|
func (w *Alert) Focusable() bool { return w.focusable }
|
||||||
func (w *Alert) SetTabbable(b bool) { w.tabbable = b }
|
func (w *Alert) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *Alert) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *Alert) WantW() int {
|
func (w *Alert) WantW() int {
|
||||||
return 4 + wh.Max(w.message.WantW(), (w.btnOk.WantW()+w.btnCancel.WantW()))
|
return 4 + wh.Max(w.message.WantW(), (w.btnOk.WantW()+w.btnCancel.WantW()))
|
||||||
}
|
}
|
||||||
@@ -145,31 +152,41 @@ func (w *Alert) WantH() int {
|
|||||||
return 4 + w.btnOk.WantH() + w.message.WantH()
|
return 4 + w.btnOk.WantH() + w.message.WantH()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Borders + Buttons
|
|
||||||
func (w *Alert) MinW() int {
|
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 {
|
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) SetTitle(ttl string) { w.title = ttl }
|
||||||
func (w *Alert) SetMessage(msg string) { w.message.SetText(msg) }
|
func (w *Alert) SetMessage(msg string) { w.message.SetText(msg) }
|
||||||
|
|
||||||
func (w *Alert) SetOkPressed(b func() bool) { w.btnOk.SetOnPressed(b) }
|
func (w *Alert) SetOkPressed(b func() bool) {
|
||||||
func (w *Alert) SetCancelPressed(b func() bool) { w.btnCancel.SetOnPressed(b) }
|
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 {
|
func (w *Alert) SelectNext(ev *tcell.EventKey) bool {
|
||||||
if w.btnOk.Active() {
|
if w.btnOk.Active() && w.btnCancel.Visible() {
|
||||||
w.btnOk.SetActive(false)
|
w.btnOk.SetActive(false)
|
||||||
w.btnCancel.SetActive(true)
|
w.btnCancel.SetActive(true)
|
||||||
} else {
|
return true
|
||||||
|
} else if w.btnCancel.Active() && w.btnOk.Visible() {
|
||||||
w.btnOk.SetActive(true)
|
w.btnOk.SetActive(true)
|
||||||
w.btnCancel.SetActive(false)
|
w.btnCancel.SetActive(false)
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Alert) Do(ev *tcell.EventKey) bool {
|
func (w *Alert) Do(ev *tcell.EventKey) bool {
|
||||||
if w.btnOk.Active() {
|
if w.btnOk.Active() {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import "github.com/gdamore/tcell"
|
|||||||
type BlankWidget struct {
|
type BlankWidget struct {
|
||||||
id string
|
id string
|
||||||
x, y int
|
x, y int
|
||||||
|
keyMap KeyMap
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Widget = (*BlankWidget)(nil)
|
var _ Widget = (*BlankWidget)(nil)
|
||||||
@@ -36,9 +37,19 @@ func NewBlankWidget(id string) *BlankWidget {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *BlankWidget) Init(id string, st tcell.Style) {}
|
func (w *BlankWidget) Init(id string, st tcell.Style) { w.keyMap = BlankKeyMap() }
|
||||||
func (w *BlankWidget) Id() string { return w.id }
|
func (w *BlankWidget) Id() string { return w.id }
|
||||||
func (w *BlankWidget) HandleResize(ev *tcell.EventResize) {}
|
func (w *BlankWidget) HandleResize(ev *tcell.EventResize) {}
|
||||||
|
func (w *BlankWidget) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *BlankWidget) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *BlankWidget) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
func (w *BlankWidget) HandleKey(ev *tcell.EventKey) bool { return false }
|
func (w *BlankWidget) HandleKey(ev *tcell.EventKey) bool { return false }
|
||||||
func (w *BlankWidget) HandleTime(ev *tcell.EventTime) {}
|
func (w *BlankWidget) HandleTime(ev *tcell.EventTime) {}
|
||||||
func (w *BlankWidget) Draw(screen tcell.Screen) {}
|
func (w *BlankWidget) Draw(screen tcell.Screen) {}
|
||||||
@@ -48,8 +59,7 @@ func (w *BlankWidget) SetActive(a bool) {}
|
|||||||
func (w *BlankWidget) Visible() bool { return true }
|
func (w *BlankWidget) Visible() bool { return true }
|
||||||
func (w *BlankWidget) SetVisible(v bool) {}
|
func (w *BlankWidget) SetVisible(v bool) {}
|
||||||
func (w *BlankWidget) Focusable() bool { return false }
|
func (w *BlankWidget) Focusable() bool { return false }
|
||||||
func (w *BlankWidget) Tabbable() bool { return false }
|
func (w *BlankWidget) SetFocusable(t bool) {}
|
||||||
func (w *BlankWidget) SetTabbable(t bool) {}
|
|
||||||
func (w *BlankWidget) SetX(x int) {}
|
func (w *BlankWidget) SetX(x int) {}
|
||||||
func (w *BlankWidget) SetY(y int) {}
|
func (w *BlankWidget) SetY(y int) {}
|
||||||
func (w *BlankWidget) GetX() int { return w.x }
|
func (w *BlankWidget) GetX() int { return w.x }
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ type BorderedWidget struct {
|
|||||||
title string
|
title string
|
||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
tabbable bool
|
focusable bool
|
||||||
|
|
||||||
logger func(string)
|
logger func(string)
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ func (w *BorderedWidget) Init(id string, s tcell.Style) {
|
|||||||
w.style = s
|
w.style = s
|
||||||
w.visible = true
|
w.visible = true
|
||||||
w.border = wh.BRD_CSIMPLE
|
w.border = wh.BRD_CSIMPLE
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *BorderedWidget) Id() string { return w.id }
|
func (w *BorderedWidget) Id() string { return w.id }
|
||||||
@@ -68,6 +68,9 @@ func (w *BorderedWidget) HandleResize(ev *tcell.EventResize) {
|
|||||||
w.widget.HandleResize(tcell.NewEventResize(w.w-2, w.h-2))
|
w.widget.HandleResize(tcell.NewEventResize(w.w-2, w.h-2))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *BorderedWidget) SetKeyMap(km KeyMap) { w.widget.SetKeyMap(km) }
|
||||||
|
func (w *BorderedWidget) AddToKeyMap(km KeyMap) { w.widget.AddToKeyMap(km) }
|
||||||
|
func (w *BorderedWidget) RemoveFromKeyMap(km KeyMap) { w.widget.RemoveFromKeyMap(km) }
|
||||||
func (w *BorderedWidget) HandleKey(ev *tcell.EventKey) bool { return w.HandleKey(ev) }
|
func (w *BorderedWidget) HandleKey(ev *tcell.EventKey) bool { return w.HandleKey(ev) }
|
||||||
|
|
||||||
func (w *BorderedWidget) HandleTime(ev *tcell.EventTime) { w.HandleTime(ev) }
|
func (w *BorderedWidget) HandleTime(ev *tcell.EventTime) { w.HandleTime(ev) }
|
||||||
@@ -88,9 +91,8 @@ func (w *BorderedWidget) Active() bool { return w.active }
|
|||||||
func (w *BorderedWidget) SetActive(a bool) { w.active = a }
|
func (w *BorderedWidget) SetActive(a bool) { w.active = a }
|
||||||
func (w *BorderedWidget) Visible() bool { return w.visible }
|
func (w *BorderedWidget) Visible() bool { return w.visible }
|
||||||
func (w *BorderedWidget) SetVisible(a bool) { w.visible = a }
|
func (w *BorderedWidget) SetVisible(a bool) { w.visible = a }
|
||||||
func (w *BorderedWidget) Focusable() bool { return true }
|
func (w *BorderedWidget) Focusable() bool { return w.focusable }
|
||||||
func (w *BorderedWidget) SetTabbable(b bool) { w.tabbable = b }
|
func (w *BorderedWidget) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *BorderedWidget) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *BorderedWidget) SetX(x int) { w.x = x }
|
func (w *BorderedWidget) SetX(x int) { w.x = x }
|
||||||
func (w *BorderedWidget) SetY(y int) { w.y = y }
|
func (w *BorderedWidget) SetY(y int) { w.y = y }
|
||||||
func (w *BorderedWidget) GetX() int { return w.x }
|
func (w *BorderedWidget) GetX() int { return w.x }
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ type Button struct {
|
|||||||
|
|
||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
tabbable bool
|
focusable bool
|
||||||
|
keyMap KeyMap
|
||||||
|
|
||||||
onPressed func() bool
|
onPressed func() bool
|
||||||
logger func(string, ...any)
|
logger func(string, ...any)
|
||||||
@@ -56,24 +57,31 @@ func (w *Button) 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.KeyEnter: func(ev *tcell.EventKey) bool { return w.onPressed() },
|
||||||
|
})
|
||||||
w.onPressed = func() bool { return false }
|
w.onPressed = func() bool { return false }
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
}
|
}
|
||||||
func (w *Button) Id() string { return w.id }
|
func (w *Button) Id() string { return w.id }
|
||||||
func (w *Button) HandleResize(ev *tcell.EventResize) {
|
func (w *Button) HandleResize(ev *tcell.EventResize) { w.w, w.h = ev.Size() }
|
||||||
w.w, w.h = ev.Size()
|
|
||||||
// w.w = wh.Min(w.w, w.WantW())
|
func (w *Button) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
// w.h = wh.Min(w.h, w.WantH())
|
func (w *Button) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *Button) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Button) HandleKey(ev *tcell.EventKey) bool {
|
func (w *Button) HandleKey(ev *tcell.EventKey) bool {
|
||||||
if !w.active {
|
if !w.active {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if ev.Key() == tcell.KeyEnter {
|
return w.keyMap.Handle(ev)
|
||||||
return w.onPressed()
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func (w *Button) HandleTime(ev *tcell.EventTime) {}
|
func (w *Button) HandleTime(ev *tcell.EventTime) {}
|
||||||
|
|
||||||
@@ -81,12 +89,7 @@ func (w *Button) Draw(screen tcell.Screen) {
|
|||||||
if !w.visible {
|
if !w.visible {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dStyle := w.style
|
dStyle := w.style.Dim(!w.active)
|
||||||
if w.active {
|
|
||||||
dStyle = w.style.Bold(true)
|
|
||||||
} else {
|
|
||||||
dStyle = w.style.Dim(true)
|
|
||||||
}
|
|
||||||
switch w.h {
|
switch w.h {
|
||||||
case 1:
|
case 1:
|
||||||
lbl := w.label
|
lbl := w.label
|
||||||
@@ -140,9 +143,8 @@ func (w *Button) GetH() int { return w.h }
|
|||||||
func (w *Button) WantW() int { return 4 + len(w.label) }
|
func (w *Button) WantW() int { return 4 + len(w.label) }
|
||||||
func (w *Button) WantH() int { return 3 }
|
func (w *Button) WantH() int { return 3 }
|
||||||
func (w *Button) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
func (w *Button) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
||||||
func (w *Button) Focusable() bool { return true }
|
func (w *Button) Focusable() bool { return w.focusable }
|
||||||
func (w *Button) SetTabbable(b bool) { w.tabbable = b }
|
func (w *Button) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *Button) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *Button) MinW() int { return len(w.label) + 2 }
|
func (w *Button) MinW() int { return len(w.label) + 2 }
|
||||||
func (w *Button) MinH() int { return 1 }
|
func (w *Button) MinH() int { return 1 }
|
||||||
|
|
||||||
|
|||||||
22
wdgt_chat.go
22
wdgt_chat.go
@@ -38,7 +38,7 @@ type Chat struct {
|
|||||||
w, h int
|
w, h int
|
||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
tabbable bool
|
focusable bool
|
||||||
|
|
||||||
title string
|
title string
|
||||||
rawLog []string
|
rawLog []string
|
||||||
@@ -66,14 +66,23 @@ func (w *Chat) Init(id string, s tcell.Style) {
|
|||||||
w.id, w.style = id, s
|
w.id, w.style = id, s
|
||||||
w.visible = true
|
w.visible = true
|
||||||
w.initKeyMap()
|
w.initKeyMap()
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Chat) Id() string { return w.id }
|
func (w *Chat) Id() string { return w.id }
|
||||||
func (w *Chat) HandleResize(ev *tcell.EventResize) {
|
func (w *Chat) HandleResize(ev *tcell.EventResize) {
|
||||||
w.w, w.h = ev.Size()
|
w.w, w.h = ev.Size()
|
||||||
// w.w = wh.Min(w.w, w.WantW())
|
}
|
||||||
// w.h = wh.Min(w.h, w.WantH())
|
|
||||||
|
func (w *Chat) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *Chat) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *Chat) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Chat) HandleKey(ev *tcell.EventKey) bool {
|
func (w *Chat) HandleKey(ev *tcell.EventKey) bool {
|
||||||
@@ -161,9 +170,8 @@ func (w *Chat) Active() bool { return w.active }
|
|||||||
func (w *Chat) SetActive(a bool) { w.active = a }
|
func (w *Chat) SetActive(a bool) { w.active = a }
|
||||||
func (w *Chat) Visible() bool { return w.visible }
|
func (w *Chat) Visible() bool { return w.visible }
|
||||||
func (w *Chat) SetVisible(a bool) { w.visible = a }
|
func (w *Chat) SetVisible(a bool) { w.visible = a }
|
||||||
func (w *Chat) Focusable() bool { return true }
|
func (w *Chat) Focusable() bool { return w.focusable }
|
||||||
func (w *Chat) SetTabbable(b bool) { w.tabbable = b }
|
func (w *Chat) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *Chat) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *Chat) SetX(x int) { w.x = x }
|
func (w *Chat) SetX(x int) { w.x = x }
|
||||||
func (w *Chat) SetY(y int) { w.y = y }
|
func (w *Chat) SetY(y int) { w.y = y }
|
||||||
func (w *Chat) GetX() int { return w.x }
|
func (w *Chat) GetX() int { return w.x }
|
||||||
|
|||||||
@@ -40,11 +40,12 @@ type Checkbox struct {
|
|||||||
style tcell.Style
|
style tcell.Style
|
||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
tabbable bool
|
focusable bool
|
||||||
state int
|
state int
|
||||||
x, y int
|
x, y int
|
||||||
w, h int
|
w, h int
|
||||||
|
|
||||||
|
keyMap KeyMap
|
||||||
stateRunes []rune
|
stateRunes []rune
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,29 +62,40 @@ func (w *Checkbox) Init(id string, style tcell.Style) {
|
|||||||
w.style = style
|
w.style = style
|
||||||
w.visible = true
|
w.visible = true
|
||||||
w.stateRunes = []rune{'X', ' ', '-'}
|
w.stateRunes = []rune{'X', ' ', '-'}
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
}
|
w.keyMap = NewKeyMap(map[tcell.Key]func(ev *tcell.EventKey) bool{
|
||||||
func (w *Checkbox) Id() string { return w.id }
|
tcell.KeyEnter: func(_ *tcell.EventKey) bool {
|
||||||
func (w *Checkbox) HandleResize(ev *tcell.EventResize) {
|
|
||||||
w.w, w.h = ev.Size()
|
|
||||||
// w.w = wh.Min(w.w, w.WantW())
|
|
||||||
// w.h = wh.Min(w.h, w.WantH())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *Checkbox) HandleKey(ev *tcell.EventKey) bool {
|
|
||||||
if !w.active {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if ev.Key() == tcell.KeyEnter {
|
|
||||||
if w.state == CHECKBOX_ON {
|
if w.state == CHECKBOX_ON {
|
||||||
w.state = CHECKBOX_OFF
|
w.state = CHECKBOX_OFF
|
||||||
} else {
|
} else {
|
||||||
w.state = CHECKBOX_ON
|
w.state = CHECKBOX_ON
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
func (w *Checkbox) Id() string { return w.id }
|
||||||
|
func (w *Checkbox) HandleResize(ev *tcell.EventResize) {
|
||||||
|
w.w, w.h = ev.Size()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Checkbox) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *Checkbox) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *Checkbox) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Checkbox) HandleKey(ev *tcell.EventKey) bool {
|
||||||
|
if !w.active {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
return w.keyMap.Handle(ev)
|
||||||
|
}
|
||||||
func (w *Checkbox) HandleTime(ev *tcell.EventTime) {}
|
func (w *Checkbox) HandleTime(ev *tcell.EventTime) {}
|
||||||
func (w *Checkbox) Draw(screen tcell.Screen) {
|
func (w *Checkbox) Draw(screen tcell.Screen) {
|
||||||
if !w.visible {
|
if !w.visible {
|
||||||
@@ -115,9 +127,8 @@ func (w *Checkbox) WantW() int {
|
|||||||
}
|
}
|
||||||
func (w *Checkbox) WantH() int { return 1 }
|
func (w *Checkbox) WantH() int { return 1 }
|
||||||
func (w *Checkbox) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
func (w *Checkbox) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
||||||
func (w *Checkbox) Focusable() bool { return true }
|
func (w *Checkbox) Focusable() bool { return w.focusable }
|
||||||
func (w *Checkbox) SetTabbable(b bool) { w.tabbable = b }
|
func (w *Checkbox) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *Checkbox) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *Checkbox) MinW() int {
|
func (w *Checkbox) MinW() int {
|
||||||
return len(fmt.Sprintf("[%s] %s", string(w.state), w.label))
|
return len(fmt.Sprintf("[%s] %s", string(w.state), w.label))
|
||||||
}
|
}
|
||||||
|
|||||||
18
wdgt_cli.go
18
wdgt_cli.go
@@ -39,7 +39,7 @@ type Cli struct {
|
|||||||
w, h int
|
w, h int
|
||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
tabbable bool
|
focusable bool
|
||||||
|
|
||||||
title string
|
title string
|
||||||
rawLog []string
|
rawLog []string
|
||||||
@@ -71,7 +71,7 @@ func (w *Cli) Init(id string, s tcell.Style) {
|
|||||||
w.id, w.style = id, s
|
w.id, w.style = id, s
|
||||||
w.visible = true
|
w.visible = true
|
||||||
w.initKeyMap()
|
w.initKeyMap()
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Cli) Id() string { return w.id }
|
func (w *Cli) Id() string { return w.id }
|
||||||
@@ -79,6 +79,17 @@ func (w *Cli) HandleResize(ev *tcell.EventResize) {
|
|||||||
w.w, w.h = ev.Size()
|
w.w, w.h = ev.Size()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Cli) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *Cli) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *Cli) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Cli) HandleKey(ev *tcell.EventKey) bool {
|
func (w *Cli) HandleKey(ev *tcell.EventKey) bool {
|
||||||
if !w.active {
|
if !w.active {
|
||||||
return false
|
return false
|
||||||
@@ -172,8 +183,7 @@ func (w *Cli) SetActive(a bool) { w.active = a }
|
|||||||
func (w *Cli) Visible() bool { return w.visible }
|
func (w *Cli) Visible() bool { return w.visible }
|
||||||
func (w *Cli) SetVisible(a bool) { w.visible = a }
|
func (w *Cli) SetVisible(a bool) { w.visible = a }
|
||||||
func (w *Cli) Focusable() bool { return true }
|
func (w *Cli) Focusable() bool { return true }
|
||||||
func (w *Cli) SetTabbable(b bool) { w.tabbable = b }
|
func (w *Cli) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *Cli) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *Cli) SetX(x int) { w.x = x }
|
func (w *Cli) SetX(x int) { w.x = x }
|
||||||
func (w *Cli) SetY(y int) { w.y = y }
|
func (w *Cli) SetY(y int) { w.y = y }
|
||||||
func (w *Cli) GetX() int { return w.x }
|
func (w *Cli) GetX() int { return w.x }
|
||||||
|
|||||||
@@ -40,9 +40,10 @@ type DebugWidget struct {
|
|||||||
drawRulers bool
|
drawRulers bool
|
||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
tabbable bool
|
focusable bool
|
||||||
mTL, mBR Coord // Margins (Top-Right & Bottom Left)
|
mTL, mBR Coord // Margins (Top-Right & Bottom Left)
|
||||||
|
|
||||||
|
keyMap KeyMap
|
||||||
logger func(string, ...any)
|
logger func(string, ...any)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,9 +61,10 @@ func (w *DebugWidget) Init(id string, s tcell.Style) {
|
|||||||
w.id = id
|
w.id = id
|
||||||
w.style = s
|
w.style = s
|
||||||
w.visible = true
|
w.visible = true
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
w.drawRulers = true
|
w.drawRulers = true
|
||||||
w.setW, w.setH = -1, -1
|
w.setW, w.setH = -1, -1
|
||||||
|
w.keyMap = BlankKeyMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *DebugWidget) SetLogger(l func(string, ...any)) { w.logger = l }
|
func (w *DebugWidget) SetLogger(l func(string, ...any)) { w.logger = l }
|
||||||
@@ -104,7 +106,23 @@ func (w *DebugWidget) HandleResize(ev *tcell.EventResize) {
|
|||||||
w.widget.HandleResize(tcell.NewEventResize(w.w-w.mTL.X-w.mBR.X, w.h-w.mTL.Y-w.mBR.Y))
|
w.widget.HandleResize(tcell.NewEventResize(w.w-w.mTL.X-w.mBR.X, w.h-w.mTL.Y-w.mBR.Y))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *DebugWidget) HandleKey(ev *tcell.EventKey) bool { return w.widget.HandleKey(ev) }
|
func (w *DebugWidget) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *DebugWidget) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *DebugWidget) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *DebugWidget) HandleKey(ev *tcell.EventKey) bool {
|
||||||
|
if ok := w.keyMap.Handle(ev); ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return w.widget.HandleKey(ev)
|
||||||
|
}
|
||||||
func (w *DebugWidget) HandleTime(ev *tcell.EventTime) { w.widget.HandleTime(ev) }
|
func (w *DebugWidget) HandleTime(ev *tcell.EventTime) { w.widget.HandleTime(ev) }
|
||||||
|
|
||||||
func (w *DebugWidget) Draw(screen tcell.Screen) {
|
func (w *DebugWidget) Draw(screen tcell.Screen) {
|
||||||
@@ -162,9 +180,8 @@ func (w *DebugWidget) SetActive(a bool) {
|
|||||||
}
|
}
|
||||||
func (w *DebugWidget) Visible() bool { return w.visible }
|
func (w *DebugWidget) Visible() bool { return w.visible }
|
||||||
func (w *DebugWidget) SetVisible(a bool) { w.visible = a }
|
func (w *DebugWidget) SetVisible(a bool) { w.visible = a }
|
||||||
func (w *DebugWidget) Focusable() bool { return true }
|
func (w *DebugWidget) Focusable() bool { return w.focusable }
|
||||||
func (w *DebugWidget) SetTabbable(b bool) { w.tabbable = b }
|
func (w *DebugWidget) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *DebugWidget) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *DebugWidget) SetX(x int) { w.x = x }
|
func (w *DebugWidget) SetX(x int) { w.x = x }
|
||||||
func (w *DebugWidget) SetY(y int) { w.y = y }
|
func (w *DebugWidget) SetY(y int) { w.y = y }
|
||||||
func (w *DebugWidget) GetX() int { return w.x }
|
func (w *DebugWidget) GetX() int { return w.x }
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ type Field struct {
|
|||||||
cursor int
|
cursor int
|
||||||
visible bool
|
visible bool
|
||||||
active bool
|
active bool
|
||||||
tabbable bool
|
focusable bool
|
||||||
x, y int
|
x, y int
|
||||||
w, h int
|
w, h int
|
||||||
|
|
||||||
@@ -71,12 +71,23 @@ func (w *Field) Init(id string, style tcell.Style) {
|
|||||||
tcell.KeyEnd: w.handleEnd,
|
tcell.KeyEnd: w.handleEnd,
|
||||||
tcell.KeyCtrlU: w.clearValueBeforeCursor,
|
tcell.KeyCtrlU: w.clearValueBeforeCursor,
|
||||||
})
|
})
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Field) Id() string { return w.id }
|
func (w *Field) Id() string { return w.id }
|
||||||
func (w *Field) HandleResize(ev *tcell.EventResize) { w.w, w.h = ev.Size() }
|
func (w *Field) HandleResize(ev *tcell.EventResize) { w.w, w.h = ev.Size() }
|
||||||
|
|
||||||
|
func (w *Field) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *Field) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *Field) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Field) HandleKey(ev *tcell.EventKey) bool {
|
func (w *Field) HandleKey(ev *tcell.EventKey) bool {
|
||||||
if !w.active {
|
if !w.active {
|
||||||
return false
|
return false
|
||||||
@@ -159,9 +170,8 @@ func (w *Field) WantH() int {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
func (w *Field) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
func (w *Field) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
||||||
func (w *Field) Focusable() bool { return true }
|
func (w *Field) Focusable() bool { return w.focusable }
|
||||||
func (w *Field) SetTabbable(b bool) { w.tabbable = b }
|
func (w *Field) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *Field) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *Field) MinW() int { return len(w.label) + wh.Max(15, len(w.value)) }
|
func (w *Field) MinW() int { return len(w.label) + wh.Max(15, len(w.value)) }
|
||||||
func (w *Field) MinH() int { return 1 }
|
func (w *Field) MinH() int { return 1 }
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ type FilePicker struct {
|
|||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
focusable bool
|
focusable bool
|
||||||
tabbable bool
|
|
||||||
|
|
||||||
x, y int
|
x, y int
|
||||||
w, h int
|
w, h int
|
||||||
@@ -50,6 +49,8 @@ type FilePicker struct {
|
|||||||
|
|
||||||
fileList *List
|
fileList *List
|
||||||
btnSelect, btnCancel *Button
|
btnSelect, btnCancel *Button
|
||||||
|
|
||||||
|
keyMap KeyMap
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Widget = (*FilePicker)(nil)
|
var _ Widget = (*FilePicker)(nil)
|
||||||
@@ -72,7 +73,8 @@ func (w *FilePicker) Init(id string, style tcell.Style) {
|
|||||||
w.btnCancel = NewButton(fmt.Sprintf("%s-cancel", id), style)
|
w.btnCancel = NewButton(fmt.Sprintf("%s-cancel", id), style)
|
||||||
w.btnCancel.SetLabel("Cancel")
|
w.btnCancel.SetLabel("Cancel")
|
||||||
w.layout.Add(w.btnCancel, nil, RelAncBL)
|
w.layout.Add(w.btnCancel, nil, RelAncBL)
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
|
w.keyMap = BlankKeyMap()
|
||||||
}
|
}
|
||||||
func (w *FilePicker) Id() string { return w.id }
|
func (w *FilePicker) Id() string { return w.id }
|
||||||
func (w *FilePicker) HandleResize(ev *tcell.EventResize) {
|
func (w *FilePicker) HandleResize(ev *tcell.EventResize) {
|
||||||
@@ -82,21 +84,29 @@ func (w *FilePicker) HandleResize(ev *tcell.EventResize) {
|
|||||||
w.btnCancel.SetPos(Coord{X: w.x + 1, Y: w.y + w.h - 1})
|
w.btnCancel.SetPos(Coord{X: w.x + 1, Y: w.y + w.h - 1})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *FilePicker) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *FilePicker) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *FilePicker) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *FilePicker) HandleKey(ev *tcell.EventKey) bool {
|
func (w *FilePicker) HandleKey(ev *tcell.EventKey) bool {
|
||||||
if !w.active {
|
if !w.active {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return false
|
return w.keyMap.Handle(ev)
|
||||||
}
|
}
|
||||||
func (w *FilePicker) HandleTime(ev *tcell.EventTime) {}
|
func (w *FilePicker) HandleTime(ev *tcell.EventTime) {}
|
||||||
func (w *FilePicker) Draw(screen tcell.Screen) {
|
func (w *FilePicker) Draw(screen tcell.Screen) {
|
||||||
if !w.visible {
|
if !w.visible {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ds := w.style
|
ds := w.style.Dim(!w.active)
|
||||||
if !w.active {
|
|
||||||
ds = ds.Dim(true)
|
|
||||||
}
|
|
||||||
wh.TitledBorderFilled(w.x, w.y, w.x+w.w, w.y+w.h, w.title, wh.BRD_SIMPLE, ds, screen)
|
wh.TitledBorderFilled(w.x, w.y, w.x+w.w, w.y+w.h, w.title, wh.BRD_SIMPLE, ds, screen)
|
||||||
// TODO: Draw the file picker
|
// TODO: Draw the file picker
|
||||||
wh.DrawText(w.x+1, w.y+1, "TODO: Draw Filepicker", ds, screen)
|
wh.DrawText(w.x+1, w.y+1, "TODO: Draw Filepicker", ds, screen)
|
||||||
@@ -120,8 +130,7 @@ func (w *FilePicker) GetW() int { return w.w }
|
|||||||
func (w *FilePicker) GetH() int { return w.y }
|
func (w *FilePicker) GetH() int { return w.y }
|
||||||
func (w *FilePicker) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
func (w *FilePicker) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
||||||
func (w *FilePicker) Focusable() bool { return w.focusable }
|
func (w *FilePicker) Focusable() bool { return w.focusable }
|
||||||
func (w *FilePicker) SetTabbable(b bool) { w.tabbable = b }
|
func (w *FilePicker) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *FilePicker) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *FilePicker) WantW() int {
|
func (w *FilePicker) WantW() int {
|
||||||
// borders + the greater of the buttons next to each other or the list width
|
// borders + the greater of the buttons next to each other or the list width
|
||||||
return wh.Max((w.btnSelect.WantW()+w.btnCancel.WantW()), w.fileList.WantW()) + 2
|
return wh.Max((w.btnSelect.WantW()+w.btnCancel.WantW()), w.fileList.WantW()) + 2
|
||||||
|
|||||||
@@ -52,10 +52,12 @@ type LinearLayout struct {
|
|||||||
|
|
||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
tabbable bool
|
focusable bool
|
||||||
disableTab bool
|
disableTab bool
|
||||||
insetBorder bool
|
insetBorder bool
|
||||||
|
|
||||||
|
keyMap KeyMap
|
||||||
|
|
||||||
logger func(string, ...any)
|
logger func(string, ...any)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,10 +80,23 @@ func (w *LinearLayout) Init(id string, s tcell.Style) {
|
|||||||
w.id = id
|
w.id = id
|
||||||
w.style = s
|
w.style = s
|
||||||
w.visible = true
|
w.visible = true
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
w.defFlags = LayoutFlag(LFAlignHCenter | LFAlignVCenter)
|
w.defFlags = LayoutFlag(LFAlignHCenter | LFAlignVCenter)
|
||||||
w.layoutFlags = make(map[Widget]LayoutFlag)
|
w.layoutFlags = make(map[Widget]LayoutFlag)
|
||||||
w.layoutWeights = make(map[Widget]int)
|
w.layoutWeights = make(map[Widget]int)
|
||||||
|
w.keyMap = BlankKeyMap()
|
||||||
|
w.keyMap.Add(tcell.KeyTab, func(ev *tcell.EventKey) bool {
|
||||||
|
active := w.findActive()
|
||||||
|
if active == nil && len(w.widgets) > 0 {
|
||||||
|
// No widget is active
|
||||||
|
if w.widgets[0].Focusable() {
|
||||||
|
w.widgets[0].SetActive(true)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return w.activateNext()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *LinearLayout) Id() string { return w.id }
|
func (w *LinearLayout) Id() string { return w.id }
|
||||||
@@ -90,6 +105,17 @@ func (w *LinearLayout) HandleResize(ev *tcell.EventResize) {
|
|||||||
w.updateWidgetLayouts()
|
w.updateWidgetLayouts()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *LinearLayout) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *LinearLayout) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *LinearLayout) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *LinearLayout) HandleKey(ev *tcell.EventKey) bool {
|
func (w *LinearLayout) HandleKey(ev *tcell.EventKey) bool {
|
||||||
if !w.active || w.disableTab {
|
if !w.active || w.disableTab {
|
||||||
return false
|
return false
|
||||||
@@ -100,19 +126,7 @@ func (w *LinearLayout) HandleKey(ev *tcell.EventKey) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ev.Key() == tcell.KeyTab {
|
return w.keyMap.Handle(ev)
|
||||||
if active == nil && len(w.widgets) > 0 {
|
|
||||||
// No widget is active
|
|
||||||
if w.widgets[0].Tabbable() {
|
|
||||||
w.widgets[0].SetActive(true)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return w.activateNext()
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func (w *LinearLayout) GetActive() Widget { return w.findActive() }
|
func (w *LinearLayout) GetActive() Widget { return w.findActive() }
|
||||||
|
|
||||||
@@ -148,9 +162,8 @@ func (w *LinearLayout) SetActive(a bool) {
|
|||||||
}
|
}
|
||||||
func (w *LinearLayout) Visible() bool { return w.visible }
|
func (w *LinearLayout) Visible() bool { return w.visible }
|
||||||
func (w *LinearLayout) SetVisible(a bool) { w.visible = a }
|
func (w *LinearLayout) SetVisible(a bool) { w.visible = a }
|
||||||
func (w *LinearLayout) Focusable() bool { return true }
|
func (w *LinearLayout) Focusable() bool { return w.focusable }
|
||||||
func (w *LinearLayout) SetTabbable(b bool) { w.tabbable = b }
|
func (w *LinearLayout) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *LinearLayout) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *LinearLayout) SetX(x int) { w.x = x }
|
func (w *LinearLayout) SetX(x int) { w.x = x }
|
||||||
func (w *LinearLayout) SetY(y int) { w.y = y }
|
func (w *LinearLayout) SetY(y int) { w.y = y }
|
||||||
func (w *LinearLayout) GetX() int { return w.x }
|
func (w *LinearLayout) GetX() int { return w.x }
|
||||||
@@ -245,7 +258,7 @@ func (w *LinearLayout) findActiveOrFirst() Widget {
|
|||||||
func (w *LinearLayout) activateNext() bool {
|
func (w *LinearLayout) activateNext() bool {
|
||||||
var found bool
|
var found bool
|
||||||
for i := range w.widgets {
|
for i := range w.widgets {
|
||||||
if found && w.widgets[i].Tabbable() {
|
if found && w.widgets[i].Focusable() {
|
||||||
w.widgets[i].SetActive(true)
|
w.widgets[i].SetActive(true)
|
||||||
return true
|
return true
|
||||||
} else if w.widgets[i].Active() {
|
} else if w.widgets[i].Active() {
|
||||||
@@ -443,8 +456,10 @@ func (w *LinearLayout) updateLLVWidgetPos(wd Widget) {
|
|||||||
if w.widgets[i] == wd {
|
if w.widgets[i] == wd {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if w.widgets[i].Visible() {
|
||||||
c.Y = w.widgets[i].GetY() + w.widgets[i].GetH()
|
c.Y = w.widgets[i].GetY() + w.widgets[i].GetH()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Do we have a layout flag for this widget?
|
// Do we have a layout flag for this widget?
|
||||||
var ok bool
|
var ok bool
|
||||||
@@ -484,8 +499,10 @@ func (w *LinearLayout) updateLLHWidgetPos(wd Widget) {
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if w.widgets[i].Visible() {
|
||||||
c.X = w.widgets[i].GetX() + w.widgets[i].GetW()
|
c.X = w.widgets[i].GetX() + w.widgets[i].GetW()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Do we have a layout flag for this widget?
|
// Do we have a layout flag for this widget?
|
||||||
var ok bool
|
var ok bool
|
||||||
|
|||||||
21
wdgt_list.go
21
wdgt_list.go
@@ -33,7 +33,6 @@ type List struct {
|
|||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
focusable bool
|
focusable bool
|
||||||
tabbable bool
|
|
||||||
|
|
||||||
x, y int
|
x, y int
|
||||||
w, h int
|
w, h int
|
||||||
@@ -86,13 +85,24 @@ func (w *List) Init(id string, style tcell.Style) {
|
|||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
w.itemsStyle = make(map[int]tcell.Style)
|
w.itemsStyle = make(map[int]tcell.Style)
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
}
|
}
|
||||||
func (w *List) Id() string { return w.id }
|
func (w *List) Id() string { return w.id }
|
||||||
func (w *List) HandleResize(ev *tcell.EventResize) {
|
func (w *List) HandleResize(ev *tcell.EventResize) {
|
||||||
w.w, w.h = ev.Size()
|
w.w, w.h = ev.Size()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *List) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *List) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *List) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *List) HandleKey(ev *tcell.EventKey) bool {
|
func (w *List) HandleKey(ev *tcell.EventKey) bool {
|
||||||
if !w.active || !w.focusable {
|
if !w.active || !w.focusable {
|
||||||
return false
|
return false
|
||||||
@@ -122,7 +132,7 @@ func (w *List) Draw(screen tcell.Screen) {
|
|||||||
rev = true
|
rev = true
|
||||||
}
|
}
|
||||||
txt := w.list[i]
|
txt := w.list[i]
|
||||||
if len(txt) > w.w-brdSz {
|
if len(txt) > w.w-brdSz && w.w-brdSz >= 0 {
|
||||||
txt = txt[:(w.w - brdSz)]
|
txt = txt[:(w.w - brdSz)]
|
||||||
}
|
}
|
||||||
var ok bool
|
var ok bool
|
||||||
@@ -151,8 +161,7 @@ func (w *List) GetW() int { return w.w }
|
|||||||
func (w *List) GetH() int { return w.y }
|
func (w *List) GetH() int { return w.y }
|
||||||
func (w *List) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
func (w *List) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
||||||
func (w *List) Focusable() bool { return w.focusable }
|
func (w *List) Focusable() bool { return w.focusable }
|
||||||
func (w *List) SetTabbable(b bool) { w.tabbable = b }
|
func (w *List) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *List) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *List) WantW() int {
|
func (w *List) WantW() int {
|
||||||
lng := wh.Longest(w.list)
|
lng := wh.Longest(w.list)
|
||||||
if len(w.border) > 0 {
|
if len(w.border) > 0 {
|
||||||
@@ -179,8 +188,6 @@ func (w *List) MinW() int {
|
|||||||
|
|
||||||
func (w *List) MinH() int { return 4 }
|
func (w *List) MinH() int { return 4 }
|
||||||
|
|
||||||
func (w *List) SetFocusable(f bool) { w.focusable = f }
|
|
||||||
|
|
||||||
func (w *List) SetCursorWrap(b bool) { w.cursorWrap = b }
|
func (w *List) SetCursorWrap(b bool) { w.cursorWrap = b }
|
||||||
func (w *List) MoveUp(ev *tcell.EventKey) bool {
|
func (w *List) MoveUp(ev *tcell.EventKey) bool {
|
||||||
if w.cursor > 0 {
|
if w.cursor > 0 {
|
||||||
|
|||||||
23
wdgt_menu.go
23
wdgt_menu.go
@@ -34,7 +34,7 @@ type Menu struct {
|
|||||||
style tcell.Style
|
style tcell.Style
|
||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
tabbable bool
|
focusable bool
|
||||||
x, y int
|
x, y int
|
||||||
w, h int
|
w, h int
|
||||||
|
|
||||||
@@ -81,18 +81,25 @@ func (w *Menu) Init(id string, style tcell.Style) {
|
|||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
}
|
}
|
||||||
func (w *Menu) Id() string { return w.id }
|
func (w *Menu) Id() string { return w.id }
|
||||||
func (w *Menu) HandleResize(ev *tcell.EventResize) {
|
func (w *Menu) HandleResize(ev *tcell.EventResize) {
|
||||||
w.w, w.h = ev.Size()
|
w.w, w.h = ev.Size()
|
||||||
|
|
||||||
// w.w = wh.Min(w.w, w.WantW())
|
|
||||||
// w.h = wh.Min(w.h, w.WantH())
|
|
||||||
|
|
||||||
// TODO: Trickle-down HandleResize
|
// TODO: Trickle-down HandleResize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Menu) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *Menu) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *Menu) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Menu) HandleKey(ev *tcell.EventKey) bool {
|
func (w *Menu) HandleKey(ev *tcell.EventKey) bool {
|
||||||
if !w.active {
|
if !w.active {
|
||||||
return false
|
return false
|
||||||
@@ -181,8 +188,7 @@ func (w *Menu) GetW() int { return w.w }
|
|||||||
func (w *Menu) GetH() int { return w.y }
|
func (w *Menu) GetH() int { return w.y }
|
||||||
func (w *Menu) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
func (w *Menu) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
||||||
func (w *Menu) Focusable() bool { return true }
|
func (w *Menu) Focusable() bool { return true }
|
||||||
func (w *Menu) SetTabbable(b bool) { w.tabbable = b }
|
func (w *Menu) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *Menu) Tabbable() bool { return w.tabbable }
|
|
||||||
|
|
||||||
func (w *Menu) WantW() int {
|
func (w *Menu) WantW() int {
|
||||||
var maxW int
|
var maxW int
|
||||||
@@ -241,7 +247,6 @@ func (w *Menu) MinH() int {
|
|||||||
}
|
}
|
||||||
func (w *Menu) SetType(tp MenuType) { w.menuType = tp }
|
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) GetItems() []*MenuItem { return w.items }
|
func (w *Menu) GetItems() []*MenuItem { return w.items }
|
||||||
func (w *Menu) GetItem(idx int) *MenuItem {
|
func (w *Menu) GetItem(idx int) *MenuItem {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ type MenuItem struct {
|
|||||||
style tcell.Style
|
style tcell.Style
|
||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
tabbable bool
|
focusable bool
|
||||||
x, y int
|
x, y int
|
||||||
w, h int
|
w, h int
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ func (w *MenuItem) Init(id string, style tcell.Style) {
|
|||||||
for i := range w.items {
|
for i := range w.items {
|
||||||
w.items[i].SetActive(i == w.cursor)
|
w.items[i].SetActive(i == w.cursor)
|
||||||
}
|
}
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
}
|
}
|
||||||
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) {
|
||||||
@@ -83,6 +83,17 @@ func (w *MenuItem) HandleResize(ev *tcell.EventResize) {
|
|||||||
// TODO: Trickle-down HandleResize
|
// TODO: Trickle-down HandleResize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *MenuItem) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *MenuItem) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *MenuItem) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *MenuItem) HandleKey(ev *tcell.EventKey) bool {
|
func (w *MenuItem) HandleKey(ev *tcell.EventKey) bool {
|
||||||
if !w.active {
|
if !w.active {
|
||||||
return false
|
return false
|
||||||
@@ -158,9 +169,8 @@ func (w *MenuItem) WantH() int {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
func (w *MenuItem) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
func (w *MenuItem) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
||||||
func (w *MenuItem) Focusable() bool { return !w.disabled }
|
func (w *MenuItem) Focusable() bool { return w.focusable && !w.disabled }
|
||||||
func (w *MenuItem) SetTabbable(b bool) { w.tabbable = b }
|
func (w *MenuItem) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *MenuItem) Tabbable() bool { return w.tabbable }
|
|
||||||
|
|
||||||
// How much width this item wants
|
// How much width this item wants
|
||||||
func (w *MenuItem) Expand(e bool) {
|
func (w *MenuItem) Expand(e bool) {
|
||||||
|
|||||||
@@ -38,13 +38,15 @@ type Prompt struct {
|
|||||||
w, h int
|
w, h int
|
||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
tabbable bool
|
focusable bool
|
||||||
|
|
||||||
title string
|
title string
|
||||||
message *Text
|
message *Text
|
||||||
field *Field
|
field *Field
|
||||||
btnOk, btnCancel *Button
|
btnOk, btnCancel *Button
|
||||||
onOk func(string) bool
|
onOk func(string) bool
|
||||||
|
|
||||||
|
keyMap KeyMap
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Widget = (*Prompt)(nil)
|
var _ Widget = (*Prompt)(nil)
|
||||||
@@ -64,7 +66,8 @@ func (w *Prompt) Init(id string, style tcell.Style) {
|
|||||||
w.btnOk.SetLabel("Ok")
|
w.btnOk.SetLabel("Ok")
|
||||||
w.btnCancel = NewButton(fmt.Sprintf("%s-cancel", id), style)
|
w.btnCancel = NewButton(fmt.Sprintf("%s-cancel", id), style)
|
||||||
w.btnCancel.SetLabel("Cancel")
|
w.btnCancel.SetLabel("Cancel")
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
|
w.keyMap = BlankKeyMap()
|
||||||
}
|
}
|
||||||
func (w *Prompt) Id() string { return w.id }
|
func (w *Prompt) Id() string { return w.id }
|
||||||
func (w *Prompt) HandleResize(ev *tcell.EventResize) {
|
func (w *Prompt) HandleResize(ev *tcell.EventResize) {
|
||||||
@@ -80,11 +83,22 @@ func (w *Prompt) HandleResize(ev *tcell.EventResize) {
|
|||||||
w.btnCancel.SetPos(Coord{X: w.x + 1, Y: w.y + w.h - 1})
|
w.btnCancel.SetPos(Coord{X: w.x + 1, Y: w.y + w.h - 1})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Prompt) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *Prompt) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *Prompt) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Prompt) HandleKey(ev *tcell.EventKey) bool {
|
func (w *Prompt) HandleKey(ev *tcell.EventKey) bool {
|
||||||
if !w.active {
|
if !w.active {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return false
|
return w.keyMap.Handle(ev)
|
||||||
}
|
}
|
||||||
func (w *Prompt) HandleTime(ev *tcell.EventTime) {}
|
func (w *Prompt) HandleTime(ev *tcell.EventTime) {}
|
||||||
func (w *Prompt) Draw(screen tcell.Screen) {
|
func (w *Prompt) Draw(screen tcell.Screen) {
|
||||||
@@ -116,9 +130,8 @@ func (w *Prompt) SetH(y int) { w.h = y }
|
|||||||
func (w *Prompt) GetW() int { return w.w }
|
func (w *Prompt) GetW() int { return w.w }
|
||||||
func (w *Prompt) GetH() int { return w.y }
|
func (w *Prompt) GetH() int { return w.y }
|
||||||
func (w *Prompt) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
func (w *Prompt) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
||||||
func (w *Prompt) Focusable() bool { return true }
|
func (w *Prompt) Focusable() bool { return w.focusable }
|
||||||
func (w *Prompt) SetTabbable(b bool) { w.tabbable = b }
|
func (w *Prompt) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *Prompt) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *Prompt) WantW() int {
|
func (w *Prompt) WantW() int {
|
||||||
return w.btnOk.WantW() + w.btnCancel.WantW() + 4
|
return w.btnOk.WantW() + w.btnCancel.WantW() + 4
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,15 +28,16 @@ import (
|
|||||||
type RelativeLayout struct {
|
type RelativeLayout struct {
|
||||||
id string
|
id string
|
||||||
style tcell.Style
|
style tcell.Style
|
||||||
|
x, y int
|
||||||
|
w, h int
|
||||||
widgetRelations map[Widget][]widgetRelation
|
widgetRelations map[Widget][]widgetRelation
|
||||||
widgets []Widget
|
widgets []Widget
|
||||||
|
|
||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
tabbable bool
|
focusable bool
|
||||||
|
|
||||||
x, y int
|
keyMap KeyMap
|
||||||
w, h int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Widget = (*RelativeLayout)(nil)
|
var _ Widget = (*RelativeLayout)(nil)
|
||||||
@@ -74,18 +75,26 @@ func (w *RelativeLayout) 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.tabbable = true
|
w.focusable = true
|
||||||
|
w.keyMap = BlankKeyMap()
|
||||||
}
|
}
|
||||||
func (w *RelativeLayout) Id() string { return w.id }
|
func (w *RelativeLayout) Id() string { return w.id }
|
||||||
func (w *RelativeLayout) HandleResize(ev *tcell.EventResize) {
|
func (w *RelativeLayout) HandleResize(ev *tcell.EventResize) {
|
||||||
w.w, w.h = ev.Size()
|
w.w, w.h = ev.Size()
|
||||||
|
|
||||||
// w.w = wh.Min(w.w, w.WantW())
|
|
||||||
// w.h = wh.Min(w.h, w.WantH())
|
|
||||||
|
|
||||||
// TODO: Trickle-down HandleResize
|
// TODO: Trickle-down HandleResize
|
||||||
}
|
}
|
||||||
func (w *RelativeLayout) HandleKey(ev *tcell.EventKey) bool { return false }
|
|
||||||
|
func (w *RelativeLayout) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *RelativeLayout) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *RelativeLayout) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (w *RelativeLayout) HandleKey(ev *tcell.EventKey) bool { return w.keyMap.Handle(ev) }
|
||||||
func (w *RelativeLayout) HandleTime(ev *tcell.EventTime) {}
|
func (w *RelativeLayout) HandleTime(ev *tcell.EventTime) {}
|
||||||
func (w *RelativeLayout) Draw(screen tcell.Screen) {
|
func (w *RelativeLayout) Draw(screen tcell.Screen) {
|
||||||
if !w.visible {
|
if !w.visible {
|
||||||
@@ -109,9 +118,8 @@ func (w *RelativeLayout) Active() bool { return w.active }
|
|||||||
func (w *RelativeLayout) SetActive(a bool) { w.active = a }
|
func (w *RelativeLayout) SetActive(a bool) { w.active = a }
|
||||||
func (w *RelativeLayout) Visible() bool { return w.visible }
|
func (w *RelativeLayout) Visible() bool { return w.visible }
|
||||||
func (w *RelativeLayout) SetVisible(a bool) { w.visible = a }
|
func (w *RelativeLayout) SetVisible(a bool) { w.visible = a }
|
||||||
func (w *RelativeLayout) Focusable() bool { return true }
|
func (w *RelativeLayout) Focusable() bool { return w.focusable }
|
||||||
func (w *RelativeLayout) SetTabbable(b bool) { w.tabbable = b }
|
func (w *RelativeLayout) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *RelativeLayout) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *RelativeLayout) SetX(x int) { w.x = x }
|
func (w *RelativeLayout) SetX(x int) { w.x = x }
|
||||||
func (w *RelativeLayout) SetY(y int) { w.y = y }
|
func (w *RelativeLayout) SetY(y int) { w.y = y }
|
||||||
func (w *RelativeLayout) GetX() int { return w.x }
|
func (w *RelativeLayout) GetX() int { return w.x }
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ type Searcher struct {
|
|||||||
w, h int
|
w, h int
|
||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
tabbable bool
|
focusable bool
|
||||||
|
|
||||||
title string
|
title string
|
||||||
search *Field
|
search *Field
|
||||||
@@ -79,7 +79,7 @@ func (w *Searcher) Init(id string, style tcell.Style) {
|
|||||||
tcell.KeyPgDn: w.handleKeyPgDn,
|
tcell.KeyPgDn: w.handleKeyPgDn,
|
||||||
tcell.KeyEnter: w.handleKeyEnter,
|
tcell.KeyEnter: w.handleKeyEnter,
|
||||||
})
|
})
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Searcher) Id() string { return w.id }
|
func (w *Searcher) Id() string { return w.id }
|
||||||
@@ -94,6 +94,17 @@ func (w *Searcher) HandleResize(ev *tcell.EventResize) {
|
|||||||
w.search.HandleResize(Coord{X: aW, Y: aH}.ResizeEvent())
|
w.search.HandleResize(Coord{X: aW, Y: aH}.ResizeEvent())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Searcher) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *Searcher) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *Searcher) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Searcher) HandleKey(ev *tcell.EventKey) bool {
|
func (w *Searcher) HandleKey(ev *tcell.EventKey) bool {
|
||||||
if !w.active {
|
if !w.active {
|
||||||
return false
|
return false
|
||||||
@@ -252,9 +263,8 @@ func (w *Searcher) SetH(y int) { w.h = y }
|
|||||||
func (w *Searcher) GetW() int { return w.w }
|
func (w *Searcher) GetW() int { return w.w }
|
||||||
func (w *Searcher) GetH() int { return w.h }
|
func (w *Searcher) GetH() int { return w.h }
|
||||||
func (w *Searcher) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
func (w *Searcher) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
||||||
func (w *Searcher) Focusable() bool { return true }
|
func (w *Searcher) Focusable() bool { return w.focusable }
|
||||||
func (w *Searcher) SetTabbable(b bool) { w.tabbable = b }
|
func (w *Searcher) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *Searcher) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *Searcher) MinW() int {
|
func (w *Searcher) MinW() int {
|
||||||
return 2 + w.search.MinW()
|
return 2 + w.search.MinW()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ func NewShrinkWrap(w Widget) *ShrinkWrap {
|
|||||||
func (w *ShrinkWrap) Init(id string, st tcell.Style) { w.widget.Init(id, st) }
|
func (w *ShrinkWrap) Init(id string, st tcell.Style) { w.widget.Init(id, st) }
|
||||||
func (w *ShrinkWrap) Id() string { return w.widget.Id() }
|
func (w *ShrinkWrap) Id() string { return w.widget.Id() }
|
||||||
func (w *ShrinkWrap) HandleResize(ev *tcell.EventResize) { w.widget.HandleResize(ev) }
|
func (w *ShrinkWrap) HandleResize(ev *tcell.EventResize) { w.widget.HandleResize(ev) }
|
||||||
|
|
||||||
|
func (w *ShrinkWrap) SetKeyMap(km KeyMap) { w.widget.SetKeyMap(km) }
|
||||||
|
func (w *ShrinkWrap) AddToKeyMap(km KeyMap) { w.widget.AddToKeyMap(km) }
|
||||||
|
func (w *ShrinkWrap) RemoveFromKeyMap(km KeyMap) { w.widget.RemoveFromKeyMap(km) }
|
||||||
func (w *ShrinkWrap) HandleKey(ev *tcell.EventKey) bool { return w.widget.HandleKey(ev) }
|
func (w *ShrinkWrap) HandleKey(ev *tcell.EventKey) bool { return w.widget.HandleKey(ev) }
|
||||||
func (w *ShrinkWrap) HandleTime(ev *tcell.EventTime) { w.widget.HandleTime(ev) }
|
func (w *ShrinkWrap) HandleTime(ev *tcell.EventTime) { w.widget.HandleTime(ev) }
|
||||||
func (w *ShrinkWrap) Draw(screen tcell.Screen) { w.widget.Draw(screen) }
|
func (w *ShrinkWrap) Draw(screen tcell.Screen) { w.widget.Draw(screen) }
|
||||||
@@ -47,8 +51,7 @@ func (w *ShrinkWrap) SetActive(a bool) { w.widget.SetActive(a) }
|
|||||||
func (w *ShrinkWrap) Visible() bool { return w.widget.Visible() }
|
func (w *ShrinkWrap) Visible() bool { return w.widget.Visible() }
|
||||||
func (w *ShrinkWrap) SetVisible(v bool) { w.widget.SetVisible(v) }
|
func (w *ShrinkWrap) SetVisible(v bool) { w.widget.SetVisible(v) }
|
||||||
func (w *ShrinkWrap) Focusable() bool { return w.widget.Focusable() }
|
func (w *ShrinkWrap) Focusable() bool { return w.widget.Focusable() }
|
||||||
func (w *ShrinkWrap) Tabbable() bool { return w.widget.Tabbable() }
|
func (w *ShrinkWrap) SetFocusable(t bool) { w.widget.SetFocusable(t) }
|
||||||
func (w *ShrinkWrap) SetTabbable(t bool) { w.widget.SetTabbable(t) }
|
|
||||||
func (w *ShrinkWrap) SetX(x int) { w.widget.SetX(x) }
|
func (w *ShrinkWrap) SetX(x int) { w.widget.SetX(x) }
|
||||||
func (w *ShrinkWrap) SetY(y int) { w.widget.SetY(y) }
|
func (w *ShrinkWrap) SetY(y int) { w.widget.SetY(y) }
|
||||||
func (w *ShrinkWrap) GetX() int { return w.widget.GetX() }
|
func (w *ShrinkWrap) GetX() int { return w.widget.GetX() }
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ type Table struct {
|
|||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
focusable bool
|
focusable bool
|
||||||
tabbable bool
|
|
||||||
|
|
||||||
header []string
|
header []string
|
||||||
footer []string
|
footer []string
|
||||||
@@ -52,6 +51,8 @@ type Table struct {
|
|||||||
w, h int
|
w, h int
|
||||||
|
|
||||||
columnWidths []int
|
columnWidths []int
|
||||||
|
|
||||||
|
keyMap KeyMap
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Widget = (*Table)(nil)
|
var _ Widget = (*Table)(nil)
|
||||||
@@ -82,21 +83,30 @@ func (w *Table) Init(id string, style tcell.Style) {
|
|||||||
w.style = style
|
w.style = style
|
||||||
w.visible = true
|
w.visible = true
|
||||||
w.border = wh.BRD_CSIMPLE
|
w.border = wh.BRD_CSIMPLE
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
|
w.keyMap = BlankKeyMap()
|
||||||
}
|
}
|
||||||
func (w *Table) Id() string { return w.id }
|
func (w *Table) Id() string { return w.id }
|
||||||
func (w *Table) HandleResize(ev *tcell.EventResize) {
|
func (w *Table) HandleResize(ev *tcell.EventResize) {
|
||||||
w.w, w.h = ev.Size()
|
w.w, w.h = ev.Size()
|
||||||
|
}
|
||||||
|
|
||||||
// w.w = wh.Min(w.w, w.WantW())
|
func (w *Table) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
// w.h = wh.Min(w.h, w.WantH())
|
func (w *Table) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *Table) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Table) HandleKey(ev *tcell.EventKey) bool {
|
func (w *Table) HandleKey(ev *tcell.EventKey) bool {
|
||||||
if !w.active {
|
if !w.active {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return false
|
return w.keyMap.Handle(ev)
|
||||||
}
|
}
|
||||||
func (w *Table) HandleTime(ev *tcell.EventTime) {}
|
func (w *Table) HandleTime(ev *tcell.EventTime) {}
|
||||||
func (w *Table) Draw(screen tcell.Screen) {
|
func (w *Table) Draw(screen tcell.Screen) {
|
||||||
@@ -254,11 +264,9 @@ func (w *Table) MinH() int {
|
|||||||
|
|
||||||
func (w *Table) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
func (w *Table) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
||||||
func (w *Table) Focusable() bool { return w.focusable }
|
func (w *Table) Focusable() bool { return w.focusable }
|
||||||
func (w *Table) SetTabbable(b bool) { w.tabbable = b }
|
func (w *Table) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *Table) Tabbable() bool { return w.tabbable }
|
|
||||||
|
|
||||||
func (w *Table) SetTitle(ttl string) { w.title = ttl }
|
func (w *Table) SetTitle(ttl string) { w.title = ttl }
|
||||||
func (w *Table) SetFocusable(f bool) { w.focusable = f }
|
|
||||||
|
|
||||||
func (w *Table) SetBorder(b []rune) { w.border = b }
|
func (w *Table) SetBorder(b []rune) { w.border = b }
|
||||||
func (w *Table) AddRow(row []string) { w.data = append(w.data, row) }
|
func (w *Table) AddRow(row []string) { w.data = append(w.data, row) }
|
||||||
|
|||||||
32
wdgt_text.go
32
wdgt_text.go
@@ -38,7 +38,9 @@ type Text struct {
|
|||||||
x, y int
|
x, y int
|
||||||
w, h int
|
w, h int
|
||||||
visible bool
|
visible bool
|
||||||
tabbable bool
|
active bool
|
||||||
|
focusable bool
|
||||||
|
keyMap KeyMap
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Widget = (*Text)(nil)
|
var _ Widget = (*Text)(nil)
|
||||||
@@ -53,11 +55,22 @@ func (w *Text) 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.tabbable = false
|
w.focusable = false
|
||||||
|
w.keyMap = BlankKeyMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Text) Id() string { return w.id }
|
func (w *Text) Id() string { return w.id }
|
||||||
func (w *Text) HandleResize(ev *tcell.EventResize) {
|
func (w *Text) HandleResize(ev *tcell.EventResize) { w.w, w.h = ev.Size() }
|
||||||
w.w, w.h = ev.Size()
|
|
||||||
|
func (w *Text) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *Text) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *Text) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
func (w *Text) HandleKey(ev *tcell.EventKey) bool { return false }
|
func (w *Text) HandleKey(ev *tcell.EventKey) bool { return false }
|
||||||
func (w *Text) HandleTime(ev *tcell.EventTime) {}
|
func (w *Text) HandleTime(ev *tcell.EventTime) {}
|
||||||
@@ -72,8 +85,8 @@ func (w *Text) Draw(screen tcell.Screen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Text) Active() bool { return false }
|
func (w *Text) Active() bool { return w.active }
|
||||||
func (w *Text) SetActive(a bool) {}
|
func (w *Text) SetActive(a bool) { w.active = a }
|
||||||
func (w *Text) Visible() bool { return w.visible }
|
func (w *Text) Visible() bool { return w.visible }
|
||||||
func (w *Text) SetVisible(a bool) { w.visible = a }
|
func (w *Text) SetVisible(a bool) { w.visible = a }
|
||||||
func (w *Text) SetX(x int) { w.x = x }
|
func (w *Text) SetX(x int) { w.x = x }
|
||||||
@@ -85,13 +98,12 @@ func (w *Text) SetPos(c Coord) { w.x, w.y = c.X, c.Y }
|
|||||||
func (w *Text) SetW(x int) { w.w = x }
|
func (w *Text) SetW(x int) { w.w = x }
|
||||||
func (w *Text) SetH(y int) { w.h = y }
|
func (w *Text) SetH(y int) { w.h = y }
|
||||||
func (w *Text) GetW() int { return w.w }
|
func (w *Text) GetW() int { return w.w }
|
||||||
func (w *Text) GetH() int { return w.y }
|
func (w *Text) GetH() int { return w.h }
|
||||||
func (w *Text) WantW() int { return wh.Longest(w.message) }
|
func (w *Text) WantW() int { return wh.Longest(w.message) }
|
||||||
func (w *Text) WantH() int { return len(w.message) }
|
func (w *Text) WantH() int { return len(w.message) }
|
||||||
func (w *Text) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
func (w *Text) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
||||||
func (w *Text) Focusable() bool { return false }
|
func (w *Text) Focusable() bool { return w.focusable }
|
||||||
func (w *Text) SetTabbable(b bool) { w.tabbable = b }
|
func (w *Text) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *Text) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *Text) MinW() int { return wh.Longest(w.message) }
|
func (w *Text) MinW() int { return wh.Longest(w.message) }
|
||||||
func (w *Text) MinH() int { return len(w.message) }
|
func (w *Text) MinH() int { return len(w.message) }
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ type TimeField struct {
|
|||||||
style tcell.Style
|
style tcell.Style
|
||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
tabbable bool
|
focusable bool
|
||||||
|
|
||||||
x, y int
|
x, y int
|
||||||
w, h int
|
w, h int
|
||||||
@@ -92,7 +92,7 @@ func (w *TimeField) Init(id string, style tcell.Style) {
|
|||||||
tcell.KeyEnd: w.handleEnd,
|
tcell.KeyEnd: w.handleEnd,
|
||||||
})
|
})
|
||||||
w.visible = true
|
w.visible = true
|
||||||
w.tabbable = true
|
w.focusable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *TimeField) Id() string { return w.id }
|
func (w *TimeField) Id() string { return w.id }
|
||||||
@@ -138,6 +138,17 @@ func (w *TimeField) HandleResize(ev *tcell.EventResize) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *TimeField) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *TimeField) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *TimeField) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *TimeField) HandleKey(ev *tcell.EventKey) bool {
|
func (w *TimeField) HandleKey(ev *tcell.EventKey) bool {
|
||||||
if !w.active {
|
if !w.active {
|
||||||
return false
|
return false
|
||||||
@@ -182,9 +193,8 @@ func (w *TimeField) SetH(y int) { w.h = y }
|
|||||||
func (w *TimeField) GetW() int { return w.w }
|
func (w *TimeField) GetW() int { return w.w }
|
||||||
func (w *TimeField) GetH() int { return w.y }
|
func (w *TimeField) GetH() int { return w.y }
|
||||||
func (w *TimeField) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
func (w *TimeField) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
||||||
func (w *TimeField) Focusable() bool { return true }
|
func (w *TimeField) Focusable() bool { return w.focusable }
|
||||||
func (w *TimeField) SetTabbable(b bool) { w.tabbable = b }
|
func (w *TimeField) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *TimeField) Tabbable() bool { return w.tabbable }
|
|
||||||
func (w *TimeField) WantW() int { return w.MinW() }
|
func (w *TimeField) WantW() int { return w.MinW() }
|
||||||
func (w *TimeField) WantH() int { return w.MinH() }
|
func (w *TimeField) WantH() int { return w.MinH() }
|
||||||
func (w *TimeField) MinW() int {
|
func (w *TimeField) MinW() int {
|
||||||
|
|||||||
@@ -41,6 +41,10 @@ type TopMenuLayout struct {
|
|||||||
|
|
||||||
active bool
|
active bool
|
||||||
visible bool
|
visible bool
|
||||||
|
focusable bool
|
||||||
|
|
||||||
|
layoutFlags LayoutFlag
|
||||||
|
keyMap KeyMap
|
||||||
|
|
||||||
logger func(string, ...any)
|
logger func(string, ...any)
|
||||||
}
|
}
|
||||||
@@ -62,9 +66,19 @@ func (w *TopMenuLayout) Init(id string, s tcell.Style) {
|
|||||||
w.menu = NewMenu(fmt.Sprintf("%s.mainmenu", id), tcell.StyleDefault)
|
w.menu = NewMenu(fmt.Sprintf("%s.mainmenu", id), tcell.StyleDefault)
|
||||||
w.menu.SetActive(false)
|
w.menu.SetActive(false)
|
||||||
w.menu.SetType(MenuTypeH)
|
w.menu.SetType(MenuTypeH)
|
||||||
w.menu.SetTabbable(false)
|
|
||||||
|
|
||||||
w.widget = NewBlankWidget("blank")
|
w.widget = NewBlankWidget("blank")
|
||||||
|
w.keyMap = BlankKeyMap()
|
||||||
|
w.keyMap.Add(tcell.KeyEscape, func(ev *tcell.EventKey) bool {
|
||||||
|
if w.menu != nil {
|
||||||
|
w.menu.SetActive(!w.menu.Active())
|
||||||
|
if w.widget != nil {
|
||||||
|
w.widget.SetActive(!w.menu.Active())
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *TopMenuLayout) Id() string { return w.id }
|
func (w *TopMenuLayout) Id() string { return w.id }
|
||||||
@@ -76,8 +90,35 @@ func (w *TopMenuLayout) HandleResize(ev *tcell.EventResize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if w.widget != nil {
|
if w.widget != nil {
|
||||||
w.widget.SetPos(Coord{X: 0, Y: 1})
|
|
||||||
w.widget.HandleResize(tcell.NewEventResize(w.w, w.h-1))
|
w.widget.HandleResize(tcell.NewEventResize(w.w, w.h-1))
|
||||||
|
w.Log("Widget Size: %d,%d", w.widget.GetW(), w.widget.GetH())
|
||||||
|
x, y := 0, 1
|
||||||
|
|
||||||
|
switch w.layoutFlags.AlignH() {
|
||||||
|
case LFAlignHRight:
|
||||||
|
x = w.w - w.widget.GetW()
|
||||||
|
case LFAlignHCenter:
|
||||||
|
x = (w.w / 2) - (w.widget.GetW() / 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch w.layoutFlags.AlignV() {
|
||||||
|
case LFAlignVBottom:
|
||||||
|
y = w.h - w.widget.GetH()
|
||||||
|
case LFAlignVCenter:
|
||||||
|
y = (w.h / 2) - (w.widget.GetH() / 2)
|
||||||
|
}
|
||||||
|
w.widget.SetPos(Coord{X: x, Y: y})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *TopMenuLayout) SetKeyMap(km KeyMap) { w.keyMap = km }
|
||||||
|
func (w *TopMenuLayout) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
|
||||||
|
func (w *TopMenuLayout) RemoveFromKeyMap(km KeyMap) {
|
||||||
|
for k := range km.Keys {
|
||||||
|
w.keyMap.Remove(k)
|
||||||
|
}
|
||||||
|
for r := range km.Runes {
|
||||||
|
w.keyMap.RemoveRune(r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,17 +126,13 @@ func (w *TopMenuLayout) HandleKey(ev *tcell.EventKey) bool {
|
|||||||
if !w.active {
|
if !w.active {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if ev.Key() == tcell.KeyEscape && w.menu != nil {
|
|
||||||
w.menu.SetActive(!w.menu.Active())
|
if w.keyMap.Handle(ev) {
|
||||||
if w.widget != nil {
|
|
||||||
w.widget.SetActive(!w.menu.Active())
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if w.menu.Active() {
|
if w.menu != nil && w.menu.Active() {
|
||||||
return w.menu.HandleKey(ev)
|
return w.menu.HandleKey(ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass the key through to the main widget
|
// Pass the key through to the main widget
|
||||||
if w.widget != nil {
|
if w.widget != nil {
|
||||||
// If we're here, that means the menu isn't active, but we are. So the
|
// If we're here, that means the menu isn't active, but we are. So the
|
||||||
@@ -145,9 +182,8 @@ func (w *TopMenuLayout) SetH(y int) { w.h = y }
|
|||||||
func (w *TopMenuLayout) GetW() int { return w.w }
|
func (w *TopMenuLayout) GetW() int { return w.w }
|
||||||
func (w *TopMenuLayout) GetH() int { return w.y }
|
func (w *TopMenuLayout) GetH() int { return w.y }
|
||||||
func (w *TopMenuLayout) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
func (w *TopMenuLayout) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
||||||
func (w *TopMenuLayout) Focusable() bool { return true }
|
func (w *TopMenuLayout) Focusable() bool { return w.focusable }
|
||||||
func (w *TopMenuLayout) SetTabbable(b bool) {}
|
func (w *TopMenuLayout) SetFocusable(b bool) { w.focusable = b }
|
||||||
func (w *TopMenuLayout) Tabbable() bool { return true }
|
|
||||||
|
|
||||||
func (w *TopMenuLayout) WantW() int { return wh.MaxInt }
|
func (w *TopMenuLayout) WantW() int { return wh.MaxInt }
|
||||||
func (w *TopMenuLayout) WantH() int { return wh.MaxInt }
|
func (w *TopMenuLayout) WantH() int { return wh.MaxInt }
|
||||||
@@ -159,6 +195,24 @@ func (w *TopMenuLayout) AddMenuItems(iL ...*MenuItem) { w.menu.AddItems(iL...
|
|||||||
func (w *TopMenuLayout) RemoveMenuItems(iL ...*MenuItem) { w.menu.RemoveItems(iL...) }
|
func (w *TopMenuLayout) RemoveMenuItems(iL ...*MenuItem) { w.menu.RemoveItems(iL...) }
|
||||||
|
|
||||||
func (w *TopMenuLayout) SetWidget(wd Widget) { w.widget = wd }
|
func (w *TopMenuLayout) SetWidget(wd Widget) { w.widget = wd }
|
||||||
|
func (w *TopMenuLayout) AddLayoutFlag(f LayoutFlag) {
|
||||||
|
if f.IsAlignH() {
|
||||||
|
w.layoutFlags.ClearAlignH()
|
||||||
|
}
|
||||||
|
if f.IsAlignV() {
|
||||||
|
w.layoutFlags.ClearAlignV()
|
||||||
|
}
|
||||||
|
w.layoutFlags.Add(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *TopMenuLayout) RemoveLayoutFlag(f LayoutFlag) {
|
||||||
|
if f.IsAlignH() {
|
||||||
|
w.layoutFlags.ClearAlignH()
|
||||||
|
}
|
||||||
|
if f.IsAlignV() {
|
||||||
|
w.layoutFlags.ClearAlignV()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *TopMenuLayout) SetLogger(l func(string, ...any)) { w.logger = l }
|
func (w *TopMenuLayout) SetLogger(l func(string, ...any)) { w.logger = l }
|
||||||
func (w *TopMenuLayout) Log(txt string, args ...any) {
|
func (w *TopMenuLayout) Log(txt string, args ...any) {
|
||||||
@@ -179,11 +233,9 @@ func (w *TopMenuLayout) CreateMenuItem(id, lbl string, do func() bool, subItems
|
|||||||
|
|
||||||
func (w *TopMenuLayout) SetItemVisible(id string, v bool) bool {
|
func (w *TopMenuLayout) SetItemVisible(id string, v bool) bool {
|
||||||
if mi := w.FindItem(id); mi != nil {
|
if mi := w.FindItem(id); mi != nil {
|
||||||
w.Log("%s.SetItemVisible: Found Item: %s (Set Visible: %t)", w.Id(), id, v)
|
|
||||||
mi.SetVisible(v)
|
mi.SetVisible(v)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
w.Log("%s.SetItemVisible: Didn't find item with id: %s", w.Id(), id)
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,14 +32,16 @@ type Widget interface {
|
|||||||
HandleResize(*tcell.EventResize)
|
HandleResize(*tcell.EventResize)
|
||||||
HandleKey(*tcell.EventKey) bool
|
HandleKey(*tcell.EventKey) bool
|
||||||
HandleTime(*tcell.EventTime)
|
HandleTime(*tcell.EventTime)
|
||||||
|
SetKeyMap(km KeyMap)
|
||||||
|
AddToKeyMap(km KeyMap)
|
||||||
|
RemoveFromKeyMap(km KeyMap)
|
||||||
Draw(tcell.Screen)
|
Draw(tcell.Screen)
|
||||||
Active() bool
|
Active() bool
|
||||||
SetActive(bool)
|
SetActive(bool)
|
||||||
Visible() bool
|
Visible() bool
|
||||||
SetVisible(bool)
|
SetVisible(bool)
|
||||||
Focusable() bool
|
Focusable() bool
|
||||||
Tabbable() bool
|
SetFocusable(bool)
|
||||||
SetTabbable(bool)
|
|
||||||
SetX(int)
|
SetX(int)
|
||||||
SetY(int)
|
SetY(int)
|
||||||
GetX() int
|
GetX() int
|
||||||
|
|||||||
Reference in New Issue
Block a user