Wonkiness on layout

This commit is contained in:
2025-10-10 16:46:29 -05:00
parent 79a212e601
commit 7a1afd67ac
28 changed files with 362 additions and 156 deletions

View File

@@ -91,8 +91,9 @@ func (w *AbsoluteLayout) HandleResize(ev *tcell.EventResize) {
w.updateWidgetLayouts() w.updateWidgetLayouts()
} }
func (w *AbsoluteLayout) SetKeyMap(km KeyMap) { w.keyMap = km } // AbsoluteLayout doesn't have a default keymap
func (w *AbsoluteLayout) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } func (w *AbsoluteLayout) SetKeyMap(km KeyMap, def bool) { w.keyMap = km }
func (w *AbsoluteLayout) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
func (w *AbsoluteLayout) RemoveFromKeyMap(km KeyMap) { func (w *AbsoluteLayout) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.keyMap.Remove(k)

View File

@@ -44,7 +44,8 @@ type Alert struct {
btnLayout *LinearLayout btnLayout *LinearLayout
btnOk, btnCancel *Button btnOk, btnCancel *Button
keyMap KeyMap keyMap, customKeyMap KeyMap
logger func(string, ...any) logger func(string, ...any)
} }
@@ -89,6 +90,7 @@ 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.customKeyMap = BlankKeyMap()
w.focusable = true w.focusable = true
} }
func (w *Alert) Id() string { return w.id } func (w *Alert) Id() string { return w.id }
@@ -99,14 +101,26 @@ func (w *Alert) HandleResize(ev *tcell.EventResize) {
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) SetKeyMap(km KeyMap, def bool) {
func (w *Alert) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *Alert) AddToKeyMap(km KeyMap) {
w.customKeyMap.Merge(km)
}
func (w *Alert) RemoveFromKeyMap(km KeyMap) { func (w *Alert) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.keyMap.Remove(k)
w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.keyMap.RemoveRune(r)
w.customKeyMap.RemoveRune(r)
} }
} }
@@ -114,7 +128,9 @@ func (w *Alert) HandleKey(ev *tcell.EventKey) bool {
if !w.active { if !w.active {
return false return false
} }
return w.keyMap.Handle(ev) b1 := w.keyMap.Handle(ev)
b2 := w.customKeyMap.Handle(ev)
return b1 || b2
} }
func (w *Alert) HandleTime(ev *tcell.EventTime) { func (w *Alert) HandleTime(ev *tcell.EventTime) {

View File

@@ -66,7 +66,7 @@ func (w *ArtWidget) Init(id string, st tcell.Style) {
} }
func (w *ArtWidget) Id() string { return w.id } func (w *ArtWidget) Id() string { return w.id }
func (w *ArtWidget) HandleResize(ev *tcell.EventResize) { w.w, w.h = ev.Size() } func (w *ArtWidget) HandleResize(ev *tcell.EventResize) { w.w, w.h = ev.Size() }
func (w *ArtWidget) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *ArtWidget) SetKeyMap(km KeyMap, def bool) { w.keyMap = km }
func (w *ArtWidget) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } func (w *ArtWidget) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
func (w *ArtWidget) RemoveFromKeyMap(km KeyMap) { func (w *ArtWidget) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {

View File

@@ -35,14 +35,17 @@ type BlankWidget struct {
var _ Widget = (*BlankWidget)(nil) var _ Widget = (*BlankWidget)(nil)
func NewBlankWidget(id string) *BlankWidget { func NewBlankWidget(id string) *BlankWidget {
ret := &BlankWidget{id: id} ret := &BlankWidget{
id: id,
keyMap: BlankKeyMap(),
}
return ret return ret
} }
func (w *BlankWidget) Init(id string, st tcell.Style) { w.keyMap = BlankKeyMap() } 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) SetKeyMap(km KeyMap, def bool) { w.keyMap = km }
func (w *BlankWidget) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } func (w *BlankWidget) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
func (w *BlankWidget) RemoveFromKeyMap(km KeyMap) { func (w *BlankWidget) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {

View File

@@ -69,9 +69,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) SetKeyMap(km KeyMap, def bool) { w.widget.SetKeyMap(km, def) }
func (w *BorderedWidget) AddToKeyMap(km KeyMap) { w.widget.AddToKeyMap(km) } func (w *BorderedWidget) AddToKeyMap(km KeyMap) { w.widget.AddToKeyMap(km) }
func (w *BorderedWidget) RemoveFromKeyMap(km KeyMap) { w.widget.RemoveFromKeyMap(km) } func (w *BorderedWidget) RemoveFromKeyMap(km KeyMap) { w.widget.RemoveFromKeyMap(km) }
func (w *BorderedWidget) HandleKey(ev *tcell.EventKey) bool { func (w *BorderedWidget) HandleKey(ev *tcell.EventKey) bool {
w.Log("BW(%s) Active(%s) Handlekey", w.Id(), w.widget.Id()) w.Log("BW(%s) Active(%s) Handlekey", w.Id(), w.widget.Id())
return w.widget.HandleKey(ev) return w.widget.HandleKey(ev)

View File

@@ -36,10 +36,10 @@ type Button struct {
x, y int x, y int
w, h int w, h int
active bool active bool
visible bool visible bool
focusable bool focusable bool
keyMap KeyMap keyMap, customKeyMap KeyMap
onPressed func() bool onPressed func() bool
logger func(string, ...any) logger func(string, ...any)
@@ -60,6 +60,7 @@ func (w *Button) Init(id string, style tcell.Style) {
w.keyMap = NewKeyMap(map[tcell.Key]func(ev *tcell.EventKey) bool{ w.keyMap = NewKeyMap(map[tcell.Key]func(ev *tcell.EventKey) bool{
tcell.KeyEnter: func(ev *tcell.EventKey) bool { return w.onPressed() }, tcell.KeyEnter: func(ev *tcell.EventKey) bool { return w.onPressed() },
}) })
w.customKeyMap = BlankKeyMap()
w.onPressed = func() bool { return false } w.onPressed = func() bool { return false }
w.focusable = true w.focusable = true
} }
@@ -68,14 +69,20 @@ func (w *Button) HandleResize(ev *tcell.EventResize) {
w.w, w.h = ev.Size() w.w, w.h = ev.Size()
} }
func (w *Button) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *Button) SetKeyMap(km KeyMap, def bool) {
func (w *Button) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *Button) AddToKeyMap(km KeyMap) { w.customKeyMap.Merge(km) }
func (w *Button) RemoveFromKeyMap(km KeyMap) { func (w *Button) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.RemoveRune(r)
} }
} }
@@ -83,7 +90,9 @@ func (w *Button) HandleKey(ev *tcell.EventKey) bool {
if !w.active { if !w.active {
return false return false
} }
return w.keyMap.Handle(ev) b1 := w.keyMap.Handle(ev)
b2 := w.customKeyMap.Handle(ev)
return b1 || b2
} }
func (w *Button) HandleTime(ev *tcell.EventTime) {} func (w *Button) HandleTime(ev *tcell.EventTime) {}

View File

@@ -51,7 +51,7 @@ type Chat struct {
history []ChatMsg history []ChatMsg
historyPosition int historyPosition int
keyMap KeyMap keyMap, customKeyMap KeyMap
} }
var _ Widget = (*Chat)(nil) var _ Widget = (*Chat)(nil)
@@ -74,14 +74,24 @@ func (w *Chat) HandleResize(ev *tcell.EventResize) {
w.w, w.h = ev.Size() w.w, w.h = ev.Size()
} }
func (w *Chat) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *Chat) SetKeyMap(km KeyMap, def bool) {
func (w *Chat) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *Chat) AddToKeyMap(km KeyMap) {
w.customKeyMap.Merge(km)
}
func (w *Chat) RemoveFromKeyMap(km KeyMap) { func (w *Chat) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.RemoveRune(r)
} }
} }
@@ -101,7 +111,9 @@ func (w *Chat) HandleKey(ev *tcell.EventKey) bool {
w.value = w.value[:w.cursor] + w.value[w.cursor+1:] w.value = w.value[:w.cursor] + w.value[w.cursor+1:]
} }
} }
if ok := w.keyMap.Handle(ev); ok { b1 := w.keyMap.Handle(ev)
b2 := w.customKeyMap.Handle(ev)
if b1 || b2 {
return true return true
} }
@@ -245,6 +257,7 @@ func (w *Chat) initKeyMap() {
return false return false
}, },
}) })
w.customKeyMap = BlankKeyMap()
} }
func (w *Chat) SetTitle(ttl string) { w.title = ttl } func (w *Chat) SetTitle(ttl string) { w.title = ttl }
func (w *Chat) Title() string { return w.title } func (w *Chat) Title() string { return w.title }

View File

@@ -45,8 +45,8 @@ type Checkbox struct {
x, y int x, y int
w, h int w, h int
keyMap KeyMap keyMap, customKeyMap KeyMap
stateRunes []rune stateRunes []rune
} }
var _ Widget = (*Checkbox)(nil) var _ Widget = (*Checkbox)(nil)
@@ -69,20 +69,25 @@ func (w *Checkbox) Init(id string, style tcell.Style) {
w.AddToKeyMap(NewRuneMap(map[rune]func(ev *tcell.EventKey) bool{ w.AddToKeyMap(NewRuneMap(map[rune]func(ev *tcell.EventKey) bool{
' ': w.ToggleState, ' ': w.ToggleState,
})) }))
w.customKeyMap = BlankKeyMap()
} }
func (w *Checkbox) Id() string { return w.id } func (w *Checkbox) Id() string { return w.id }
func (w *Checkbox) HandleResize(ev *tcell.EventResize) { func (w *Checkbox) HandleResize(ev *tcell.EventResize) { w.w, w.h = ev.Size() }
w.w, w.h = ev.Size()
}
func (w *Checkbox) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *Checkbox) SetKeyMap(km KeyMap, def bool) {
func (w *Checkbox) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *Checkbox) AddToKeyMap(km KeyMap) { w.customKeyMap.Merge(km) }
func (w *Checkbox) RemoveFromKeyMap(km KeyMap) { func (w *Checkbox) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.RemoveRune(r)
} }
} }
@@ -90,7 +95,9 @@ func (w *Checkbox) HandleKey(ev *tcell.EventKey) bool {
if !w.active { if !w.active {
return false return false
} }
return w.keyMap.Handle(ev) b1 := w.keyMap.Handle(ev)
b2 := w.customKeyMap.Handle(ev)
return b1 || b2
} }
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) {

View File

@@ -54,7 +54,7 @@ type Cli struct {
commands []*CliCommand commands []*CliCommand
keyMap KeyMap keyMap, customKeyMap KeyMap
} }
// TODO: Fix Command/SubCommand finding // TODO: Fix Command/SubCommand finding
@@ -81,14 +81,20 @@ func (w *Cli) HandleResize(ev *tcell.EventResize) {
} }
} }
func (w *Cli) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *Cli) SetKeyMap(km KeyMap, def bool) {
func (w *Cli) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *Cli) AddToKeyMap(km KeyMap) { w.customKeyMap.Merge(km) }
func (w *Cli) RemoveFromKeyMap(km KeyMap) { func (w *Cli) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.RemoveRune(r)
} }
} }
@@ -108,7 +114,8 @@ func (w *Cli) HandleKey(ev *tcell.EventKey) bool {
w.value = w.value[:w.cursor] + w.value[w.cursor+1:] w.value = w.value[:w.cursor] + w.value[w.cursor+1:]
} }
} }
if ok := w.keyMap.Handle(ev); ok { b1, b2 := w.keyMap.Handle(ev), w.customKeyMap.Handle(ev)
if b1 || b2 {
return true return true
} }

View File

@@ -45,7 +45,7 @@ type DatePicker struct {
dateFld *Field dateFld *Field
dateNow *Button dateNow *Button
keyMap KeyMap keyMap, customKeyMap KeyMap
logger func(string, ...any) logger func(string, ...any)
} }
@@ -96,14 +96,20 @@ func (w *DatePicker) HandleResize(ev *tcell.EventResize) {
w.dateNow.SetPos(Coord{X: wd - 6, Y: 0}) w.dateNow.SetPos(Coord{X: wd - 6, Y: 0})
} }
func (w *DatePicker) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *DatePicker) SetKeyMap(km KeyMap, def bool) {
func (w *DatePicker) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *DatePicker) AddToKeyMap(km KeyMap) { w.customKeyMap.Merge(km) }
func (w *DatePicker) RemoveFromKeyMap(km KeyMap) { func (w *DatePicker) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.RemoveRune(r)
} }
} }
@@ -134,7 +140,9 @@ func (w *DatePicker) HandleKey(ev *tcell.EventKey) bool {
} else if w.dateNow.Active() { } else if w.dateNow.Active() {
return w.dateNow.HandleKey(ev) return w.dateNow.HandleKey(ev)
} }
return w.keyMap.Handle(ev) b1 := w.keyMap.Handle(ev)
b2 := w.customKeyMap.Handle(ev)
return b1 || b2
} }
func (w *DatePicker) HandleTime(ev *tcell.EventTime) {} func (w *DatePicker) HandleTime(ev *tcell.EventTime) {}
func (w *DatePicker) Draw(screen tcell.Screen) { func (w *DatePicker) Draw(screen tcell.Screen) {
@@ -191,6 +199,7 @@ func (w *DatePicker) updateUI() {
func (w *DatePicker) initKeyMap() { func (w *DatePicker) initKeyMap() {
w.keyMap = NewKeyMap(map[tcell.Key]func(ev *tcell.EventKey) bool{}) w.keyMap = NewKeyMap(map[tcell.Key]func(ev *tcell.EventKey) bool{})
w.customKeyMap = BlankKeyMap()
} }
func (w *DatePicker) Format() string { return w.format } func (w *DatePicker) Format() string { return w.format }

View File

@@ -106,8 +106,8 @@ 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) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *DebugWidget) SetKeyMap(km KeyMap, def bool) { w.keyMap = km }
func (w *DebugWidget) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } func (w *DebugWidget) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
func (w *DebugWidget) RemoveFromKeyMap(km KeyMap) { func (w *DebugWidget) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.keyMap.Remove(k)

View File

@@ -47,7 +47,7 @@ type Field struct {
filter func(tcell.EventKey) bool filter func(tcell.EventKey) bool
onChange func(prev, curr string) onChange func(prev, curr string)
keyMap KeyMap keyMap, customKeyMap KeyMap
} }
var _ Widget = (*Field)(nil) var _ Widget = (*Field)(nil)
@@ -73,20 +73,27 @@ 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.customKeyMap = BlankKeyMap()
w.focusable = 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) SetKeyMap(km KeyMap, def bool) {
func (w *Field) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *Field) AddToKeyMap(km KeyMap) { w.customKeyMap.Merge(km) }
func (w *Field) RemoveFromKeyMap(km KeyMap) { func (w *Field) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.RemoveRune(r)
} }
} }
@@ -107,7 +114,9 @@ func (w *Field) HandleKey(ev *tcell.EventKey) bool {
return w.handleBackspace(ev) return w.handleBackspace(ev)
} }
} }
if ok := w.keyMap.Handle(ev); ok { b1 := w.keyMap.Handle(ev)
b2 := w.customKeyMap.Handle(ev)
if b1 || b2 {
return true return true
} }
if w.filter != nil && !w.filter(*ev) { if w.filter != nil && !w.filter(*ev) {
@@ -250,6 +259,12 @@ func (w *Field) SetValue(v string) {
prev := w.value prev := w.value
w.value = v w.value = v
w.doOnChange(prev, v) w.doOnChange(prev, v)
if w.cursor > len(v) {
w.cursor = len(v)
}
if w.cursor < 0 {
w.cursor = 0
}
} }
func (w *Field) Value() string { return w.value } func (w *Field) Value() string { return w.value }

View File

@@ -50,7 +50,7 @@ type FilePicker struct {
fileList *SimpleList fileList *SimpleList
btnSelect, btnCancel *Button btnSelect, btnCancel *Button
keyMap KeyMap keyMap, customKeyMap KeyMap
} }
var _ Widget = (*FilePicker)(nil) var _ Widget = (*FilePicker)(nil)
@@ -75,6 +75,7 @@ func (w *FilePicker) Init(id string, style tcell.Style) {
w.layout.Add(w.btnCancel, nil, RelAncBL) w.layout.Add(w.btnCancel, nil, RelAncBL)
w.focusable = true w.focusable = true
w.keyMap = BlankKeyMap() w.keyMap = BlankKeyMap()
w.customKeyMap = 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) {
@@ -84,14 +85,20 @@ 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) SetKeyMap(km KeyMap, def bool) {
func (w *FilePicker) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *FilePicker) AddToKeyMap(km KeyMap) { w.customKeyMap.Merge(km) }
func (w *FilePicker) RemoveFromKeyMap(km KeyMap) { func (w *FilePicker) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.RemoveRune(r)
} }
} }
@@ -99,7 +106,9 @@ func (w *FilePicker) HandleKey(ev *tcell.EventKey) bool {
if !w.active { if !w.active {
return false return false
} }
return w.keyMap.Handle(ev) b1 := w.keyMap.Handle(ev)
b2 := w.customKeyMap.Handle(ev)
return b1 || b2
} }
func (w *FilePicker) HandleTime(ev *tcell.EventTime) { w.layout.HandleTime(ev) } func (w *FilePicker) HandleTime(ev *tcell.EventTime) { w.layout.HandleTime(ev) }
func (w *FilePicker) Draw(screen tcell.Screen) { func (w *FilePicker) Draw(screen tcell.Screen) {

View File

@@ -45,7 +45,7 @@ type Form struct {
hasSubmit bool hasSubmit bool
hasCancel bool hasCancel bool
keyMap KeyMap keyMap, customKeyMap KeyMap
} }
var _ Widget = (*Form)(nil) var _ Widget = (*Form)(nil)
@@ -63,6 +63,8 @@ func (w *Form) Init(id string, style tcell.Style) {
w.focusable = true w.focusable = true
w.submit = NewButton(fmt.Sprintf("%s-submit", id), style) w.submit = NewButton(fmt.Sprintf("%s-submit", id), style)
w.cancel = NewButton(fmt.Sprintf("%s-cancel", id), style) w.cancel = NewButton(fmt.Sprintf("%s-cancel", id), style)
w.keyMap = BlankKeyMap()
w.customKeyMap = BlankKeyMap()
} }
func (w *Form) Id() string { return w.id } func (w *Form) Id() string { return w.id }
@@ -90,14 +92,20 @@ func (w *Form) HandleResize(ev *tcell.EventResize) {
} }
} }
func (w *Form) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *Form) SetKeyMap(km KeyMap, def bool) {
func (w *Form) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *Form) AddToKeyMap(km KeyMap) { w.customKeyMap.Merge(km) }
func (w *Form) RemoveFromKeyMap(km KeyMap) { func (w *Form) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.RemoveRune(r)
} }
} }
@@ -121,7 +129,9 @@ func (w *Form) HandleKey(ev *tcell.EventKey) bool {
w.updateWidgets() w.updateWidgets()
return w.cursor > pre return w.cursor > pre
} }
return false b1 := w.keyMap.Handle(ev)
b2 := w.customKeyMap.Handle(ev)
return b1 || b2
} }
func (w *Form) HandleTime(ev *tcell.EventTime) {} func (w *Form) HandleTime(ev *tcell.EventTime) {}
func (w *Form) Draw(screen tcell.Screen) { func (w *Form) Draw(screen tcell.Screen) {

View File

@@ -56,7 +56,7 @@ type LinearLayout struct {
disableTab bool disableTab bool
insetBorder bool insetBorder bool
keyMap KeyMap keyMap, customKeyMap KeyMap
logger func(string, ...any) logger func(string, ...any)
} }
@@ -98,6 +98,7 @@ func (w *LinearLayout) Init(id string, s tcell.Style) {
} }
return w.ActivateNext() return w.ActivateNext()
}) })
w.customKeyMap = BlankKeyMap()
} }
func (w *LinearLayout) Id() string { return w.id } func (w *LinearLayout) Id() string { return w.id }
@@ -106,14 +107,20 @@ func (w *LinearLayout) HandleResize(ev *tcell.EventResize) {
w.updateWidgetLayouts() w.updateWidgetLayouts()
} }
func (w *LinearLayout) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *LinearLayout) SetKeyMap(km KeyMap, def bool) {
func (w *LinearLayout) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *LinearLayout) AddToKeyMap(km KeyMap) { w.customKeyMap.Merge(km) }
func (w *LinearLayout) RemoveFromKeyMap(km KeyMap) { func (w *LinearLayout) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.RemoveRune(r)
} }
} }
@@ -128,7 +135,8 @@ func (w *LinearLayout) HandleKey(ev *tcell.EventKey) bool {
return true return true
} }
} }
return w.keyMap.Handle(ev) b1, b2 := w.keyMap.Handle(ev), w.customKeyMap.Handle(ev)
return b1 || b2
} }
func (w *LinearLayout) GetActiveWidgetIdx() int { return w.findActiveIdx() } func (w *LinearLayout) GetActiveWidgetIdx() int { return w.findActiveIdx() }
@@ -494,6 +502,9 @@ func (w *LinearLayout) updateLLVWidgetPos(wd Widget) {
c := Coord{} c := Coord{}
for i := range w.widgets { for i := range w.widgets {
if w.widgets[i] == wd { if w.widgets[i] == wd {
if i > 0 {
c.Y += 1
}
break break
} }
if w.widgets[i].Visible() { if w.widgets[i].Visible() {
@@ -590,7 +601,11 @@ func (w *LinearLayout) getWeightedH(wd Widget) int {
} else if w.stacked { } else if w.stacked {
return wd.MinH() return wd.MinH()
} }
return int(float64(w.h)*(float64(w.GetWeight(wd))/float64(w.totalWeight))) - 1 use := int(float64(w.h)*(float64(w.GetWeight(wd))/float64(w.totalWeight))) - 1
if use < wd.MinH() {
return wd.MinH()
}
return use
} }
func (w *LinearLayout) getWeightedW(wd Widget) int { func (w *LinearLayout) getWeightedW(wd Widget) int {
@@ -599,7 +614,11 @@ func (w *LinearLayout) getWeightedW(wd Widget) int {
} else if w.stacked { } else if w.stacked {
return wd.MinW() return wd.MinW()
} }
return int(float64(w.w)*(float64(w.GetWeight(wd))/float64(w.totalWeight))) - 1 use := int(float64(w.w)*(float64(w.GetWeight(wd))/float64(w.totalWeight))) - 1
if use < wd.MinW() {
return wd.MinW()
}
return use
} }
func (w *LinearLayout) SetStacked(s bool) { w.stacked = s } func (w *LinearLayout) SetStacked(s bool) { w.stacked = s }

View File

@@ -47,7 +47,7 @@ type Menu struct {
expanded bool expanded bool
vimMode bool vimMode bool
keyMap KeyMap keyMap, customKeyMap KeyMap
} }
type MenuType int type MenuType int
@@ -81,6 +81,7 @@ func (w *Menu) Init(id string, style tcell.Style) {
return false return false
}, },
}) })
w.customKeyMap = BlankKeyMap()
w.focusable = true w.focusable = true
} }
func (w *Menu) Id() string { return w.id } func (w *Menu) Id() string { return w.id }
@@ -123,14 +124,20 @@ func (w *Menu) handleResizeV(_ *tcell.EventResize) {
} }
} }
func (w *Menu) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *Menu) SetKeyMap(km KeyMap, def bool) {
func (w *Menu) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *Menu) AddToKeyMap(km KeyMap) { w.customKeyMap.Merge(km) }
func (w *Menu) RemoveFromKeyMap(km KeyMap) { func (w *Menu) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.RemoveRune(r)
} }
} }
@@ -144,10 +151,12 @@ func (w *Menu) HandleKey(ev *tcell.EventKey) bool {
w.SetActive(false) w.SetActive(false)
} }
return true return true
} else if ok := w.keyMap.Handle(ev); ok { }
// Otherwise see if we handle it b1, b2 := w.keyMap.Handle(ev), w.customKeyMap.Handle(ev)
if b1 || b2 {
return true return true
} }
// See if we can find an item that matches the key pressed // See if we can find an item that matches the key pressed
for i := range w.items { for i := range w.items {
if wh.RuneEqualsNC(ev.Rune(), w.items[i].GetHotKey()) { if wh.RuneEqualsNC(ev.Rune(), w.items[i].GetHotKey()) {

View File

@@ -51,7 +51,7 @@ type MenuItem struct {
expanded bool expanded bool
disabled bool disabled bool
keyMap KeyMap keyMap, customKeyMap KeyMap
} }
var _ Widget = (*MenuItem)(nil) var _ Widget = (*MenuItem)(nil)
@@ -78,6 +78,8 @@ func (w *MenuItem) Init(id string, style tcell.Style) {
return false return false
}, },
}) })
w.customKeyMap = BlankKeyMap()
for i := range w.items { for i := range w.items {
w.items[i].SetActive(i == w.cursor) w.items[i].SetActive(i == w.cursor)
} }
@@ -89,14 +91,20 @@ 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) SetKeyMap(km KeyMap, def bool) {
func (w *MenuItem) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *MenuItem) AddToKeyMap(km KeyMap) { w.customKeyMap.Merge(km) }
func (w *MenuItem) RemoveFromKeyMap(km KeyMap) { func (w *MenuItem) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.RemoveRune(r)
} }
} }
@@ -119,7 +127,8 @@ func (w *MenuItem) HandleKey(ev *tcell.EventKey) bool {
} }
} }
// Look for a sub-item that's selected // Look for a sub-item that's selected
return w.keyMap.Handle(ev) b1, b2 := w.keyMap.Handle(ev), w.customKeyMap.Handle(ev)
return b1 || b2
} }
func (w *MenuItem) HandleTime(ev *tcell.EventTime) { func (w *MenuItem) HandleTime(ev *tcell.EventTime) {

View File

@@ -46,7 +46,7 @@ type Prompt struct {
btnOk, btnCancel *Button btnOk, btnCancel *Button
onOk func(string) bool onOk func(string) bool
keyMap KeyMap keyMap, customKeyMap KeyMap
} }
var _ Widget = (*Prompt)(nil) var _ Widget = (*Prompt)(nil)
@@ -68,6 +68,7 @@ func (w *Prompt) Init(id string, style tcell.Style) {
w.btnCancel.SetLabel("Cancel") w.btnCancel.SetLabel("Cancel")
w.focusable = true w.focusable = true
w.keyMap = BlankKeyMap() w.keyMap = BlankKeyMap()
w.customKeyMap = 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) {
@@ -83,14 +84,20 @@ 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) SetKeyMap(km KeyMap, def bool) {
func (w *Prompt) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *Prompt) AddToKeyMap(km KeyMap) { w.customKeyMap.Merge(km) }
func (w *Prompt) RemoveFromKeyMap(km KeyMap) { func (w *Prompt) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.RemoveRune(r)
} }
} }
@@ -98,7 +105,8 @@ func (w *Prompt) HandleKey(ev *tcell.EventKey) bool {
if !w.active { if !w.active {
return false return false
} }
return w.keyMap.Handle(ev) b1, b2 := w.keyMap.Handle(ev), w.customKeyMap.Handle(ev)
return b1 || b2
} }
func (w *Prompt) HandleTime(ev *tcell.EventTime) { func (w *Prompt) HandleTime(ev *tcell.EventTime) {

View File

@@ -84,8 +84,8 @@ func (w *RelativeLayout) HandleResize(ev *tcell.EventResize) {
// TODO: Trickle-down HandleResize // TODO: Trickle-down HandleResize
} }
func (w *RelativeLayout) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *RelativeLayout) SetKeyMap(km KeyMap, def bool) { w.keyMap = km }
func (w *RelativeLayout) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } func (w *RelativeLayout) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
func (w *RelativeLayout) RemoveFromKeyMap(km KeyMap) { func (w *RelativeLayout) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.keyMap.Remove(k)

View File

@@ -50,7 +50,7 @@ type Searcher struct {
hideOnSelect bool hideOnSelect bool
logger func(string, ...any) logger func(string, ...any)
keyMap KeyMap keyMap, customKeyMap KeyMap
} }
var _ Widget = (*Searcher)(nil) var _ Widget = (*Searcher)(nil)
@@ -79,6 +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.customKeyMap = BlankKeyMap()
w.focusable = true w.focusable = true
} }
@@ -94,21 +95,29 @@ 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) SetKeyMap(km KeyMap, def bool) {
func (w *Searcher) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *Searcher) AddToKeyMap(km KeyMap) { w.customKeyMap.Merge(km) }
func (w *Searcher) RemoveFromKeyMap(km KeyMap) { func (w *Searcher) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.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
} else if ok := w.keyMap.Handle(ev); ok { }
b1, b2 := w.keyMap.Handle(ev), w.customKeyMap.Handle(ev)
if b1 || b2 {
return true return true
} }
return w.search.HandleKey(ev) return w.search.HandleKey(ev)
@@ -174,18 +183,18 @@ func (w *Searcher) handleKeyEnter(ev *tcell.EventKey) bool {
if w.hideOnSelect { if w.hideOnSelect {
w.visible = false w.visible = false
} }
if w.selectFunc != nil { if w.selectFunc == nil || len(w.filteredData) <= w.cursor {
// Figure out our true index return false
var idx int
selV := w.filteredData[w.cursor]
for i := range w.data {
if w.data[i] == selV {
idx = i
}
}
return w.selectFunc(idx, selV)
} }
return false // Figure out our true index
var idx int
selV := w.filteredData[w.cursor]
for i := range w.data {
if w.data[i] == selV {
idx = i
}
}
return w.selectFunc(idx, selV)
} }
func (w *Searcher) HandleTime(ev *tcell.EventTime) { w.search.HandleTime(ev) } func (w *Searcher) HandleTime(ev *tcell.EventTime) { w.search.HandleTime(ev) }

View File

@@ -39,7 +39,7 @@ 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) SetKeyMap(km KeyMap, def bool) { w.widget.SetKeyMap(km, def) }
func (w *ShrinkWrap) AddToKeyMap(km KeyMap) { w.widget.AddToKeyMap(km) } func (w *ShrinkWrap) AddToKeyMap(km KeyMap) { w.widget.AddToKeyMap(km) }
func (w *ShrinkWrap) RemoveFromKeyMap(km KeyMap) { w.widget.RemoveFromKeyMap(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) }

View File

@@ -43,9 +43,10 @@ type SimpleList struct {
list []string list []string
itemsStyle map[int]tcell.Style itemsStyle map[int]tcell.Style
onSelect func(int, string) bool onChange func(int, string) bool
keyMap KeyMap onSelect func(int, string) bool
vimMode bool keyMap, customKeyMap KeyMap
vimMode bool
logger func(string, ...any) logger func(string, ...any)
} }
@@ -84,22 +85,27 @@ func (w *SimpleList) Init(id string, style tcell.Style) {
} }
return false return false
}) })
w.customKeyMap = BlankKeyMap()
w.itemsStyle = make(map[int]tcell.Style) w.itemsStyle = make(map[int]tcell.Style)
w.focusable = true w.focusable = true
} }
func (w *SimpleList) Id() string { return w.id } func (w *SimpleList) Id() string { return w.id }
func (w *SimpleList) HandleResize(ev *tcell.EventResize) { func (w *SimpleList) HandleResize(ev *tcell.EventResize) { w.w, w.h = ev.Size() }
w.w, w.h = ev.Size()
}
func (w *SimpleList) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *SimpleList) SetKeyMap(km KeyMap, def bool) {
func (w *SimpleList) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *SimpleList) AddToKeyMap(km KeyMap) { w.customKeyMap.Merge(km) }
func (w *SimpleList) RemoveFromKeyMap(km KeyMap) { func (w *SimpleList) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.RemoveRune(r)
} }
} }
@@ -107,8 +113,10 @@ func (w *SimpleList) HandleKey(ev *tcell.EventKey) bool {
if !w.active || !w.focusable { if !w.active || !w.focusable {
return false return false
} }
return w.keyMap.Handle(ev) b1, b2 := w.keyMap.Handle(ev), w.customKeyMap.Handle(ev)
return b1 || b2
} }
func (w *SimpleList) HandleTime(ev *tcell.EventTime) {} func (w *SimpleList) HandleTime(ev *tcell.EventTime) {}
func (w *SimpleList) Draw(screen tcell.Screen) { func (w *SimpleList) Draw(screen tcell.Screen) {
dS := w.style dS := w.style
@@ -192,9 +200,15 @@ func (w *SimpleList) SetCursorWrap(b bool) { w.cursorWrap = b }
func (w *SimpleList) MoveUp() bool { func (w *SimpleList) MoveUp() bool {
if w.cursor > 0 { if w.cursor > 0 {
w.cursor-- w.cursor--
if w.onChange != nil {
w.onChange(w.cursor, w.list[w.cursor])
}
return true return true
} else if w.cursorWrap { } else if w.cursorWrap {
w.cursor = len(w.list) - 1 w.cursor = len(w.list) - 1
if w.onChange != nil {
w.onChange(w.cursor, w.list[w.cursor])
}
return true return true
} }
return false return false
@@ -203,9 +217,15 @@ func (w *SimpleList) MoveUp() bool {
func (w *SimpleList) MoveDown() bool { func (w *SimpleList) MoveDown() bool {
if w.cursor < len(w.list)-1 { if w.cursor < len(w.list)-1 {
w.cursor++ w.cursor++
if w.onChange != nil {
w.onChange(w.cursor, w.list[w.cursor])
}
return true return true
} else if w.cursorWrap { } else if w.cursorWrap {
w.cursor = 0 w.cursor = 0
if w.onChange != nil {
w.onChange(w.cursor, w.list[w.cursor])
}
return true return true
} }
return false return false
@@ -266,3 +286,7 @@ func (w *SimpleList) Log(txt string, args ...any) {
w.logger(txt, args...) w.logger(txt, args...)
} }
} }
func (w *SimpleList) SetOnChange(c func(int, string) bool) { w.onChange = c }
func (w *SimpleList) GetAllItemStyles() map[int]tcell.Style { return w.itemsStyle }

View File

@@ -54,7 +54,7 @@ func (w *Spinner) Init(id string, st tcell.Style) {
} }
func (w *Spinner) Id() string { return w.id } func (w *Spinner) Id() string { return w.id }
func (w *Spinner) HandleResize(ev *tcell.EventResize) {} func (w *Spinner) HandleResize(ev *tcell.EventResize) {}
func (w *Spinner) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *Spinner) SetKeyMap(km KeyMap, def bool) { w.keyMap = km }
func (w *Spinner) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } func (w *Spinner) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
func (w *Spinner) RemoveFromKeyMap(km KeyMap) { func (w *Spinner) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {

View File

@@ -52,7 +52,7 @@ type Table struct {
columnWidths []int columnWidths []int
keyMap KeyMap keyMap, customKeyMap KeyMap
} }
var _ Widget = (*Table)(nil) var _ Widget = (*Table)(nil)
@@ -85,20 +85,27 @@ func (w *Table) Init(id string, style tcell.Style) {
w.border = wh.BRD_CSIMPLE w.border = wh.BRD_CSIMPLE
w.focusable = true w.focusable = true
w.keyMap = BlankKeyMap() w.keyMap = BlankKeyMap()
w.customKeyMap = 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()
} }
func (w *Table) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *Table) SetKeyMap(km KeyMap, def bool) {
func (w *Table) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *Table) AddToKeyMap(km KeyMap) { w.customKeyMap.Merge(km) }
func (w *Table) RemoveFromKeyMap(km KeyMap) { func (w *Table) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.RemoveRune(r)
} }
} }
@@ -106,7 +113,8 @@ func (w *Table) HandleKey(ev *tcell.EventKey) bool {
if !w.active { if !w.active {
return false return false
} }
return w.keyMap.Handle(ev) b1, b2 := w.keyMap.Handle(ev), w.customKeyMap.Handle(ev)
return b1 || b2
} }
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) {

View File

@@ -62,8 +62,8 @@ func (w *Text) Init(id string, style tcell.Style) {
func (w *Text) Id() string { return w.id } func (w *Text) Id() string { return w.id }
func (w *Text) HandleResize(ev *tcell.EventResize) { w.w, w.h = ev.Size() } func (w *Text) HandleResize(ev *tcell.EventResize) { w.w, w.h = ev.Size() }
func (w *Text) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *Text) SetKeyMap(km KeyMap, def bool) { w.keyMap = km }
func (w *Text) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } func (w *Text) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) }
func (w *Text) RemoveFromKeyMap(km KeyMap) { func (w *Text) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.keyMap.Remove(k)
@@ -72,7 +72,7 @@ func (w *Text) RemoveFromKeyMap(km KeyMap) {
w.keyMap.RemoveRune(r) w.keyMap.RemoveRune(r)
} }
} }
func (w *Text) HandleKey(ev *tcell.EventKey) bool { return false } func (w *Text) HandleKey(ev *tcell.EventKey) bool { return w.keyMap.Handle(ev) }
func (w *Text) HandleTime(ev *tcell.EventTime) {} func (w *Text) HandleTime(ev *tcell.EventTime) {}
func (w *Text) Draw(screen tcell.Screen) { func (w *Text) Draw(screen tcell.Screen) {
if !w.visible { if !w.visible {

View File

@@ -57,8 +57,8 @@ type TimeField struct {
widgets []Widget widgets []Widget
cursor int cursor int
keyMap KeyMap keyMap, customKeyMap KeyMap
} }
// TODO: Allow changing the format. // TODO: Allow changing the format.
@@ -91,6 +91,7 @@ func (w *TimeField) Init(id string, style tcell.Style) {
tcell.KeyHome: w.handleHome, tcell.KeyHome: w.handleHome,
tcell.KeyEnd: w.handleEnd, tcell.KeyEnd: w.handleEnd,
}) })
w.customKeyMap = BlankKeyMap()
w.visible = true w.visible = true
w.focusable = true w.focusable = true
} }
@@ -138,14 +139,20 @@ func (w *TimeField) HandleResize(ev *tcell.EventResize) {
} }
} }
func (w *TimeField) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *TimeField) SetKeyMap(km KeyMap, def bool) {
func (w *TimeField) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *TimeField) AddToKeyMap(km KeyMap) { w.customKeyMap.Merge(km) }
func (w *TimeField) RemoveFromKeyMap(km KeyMap) { func (w *TimeField) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.RemoveRune(r)
} }
} }
@@ -154,9 +161,12 @@ func (w *TimeField) HandleKey(ev *tcell.EventKey) bool {
return false return false
} else if ev.Key() == tcell.KeyTab { } else if ev.Key() == tcell.KeyTab {
return w.handleTab(ev) return w.handleTab(ev)
} else if w.keyMap.Handle(ev) { }
b1, b2 := w.keyMap.Handle(ev), w.customKeyMap.Handle(ev)
if b1 || b2 {
return true return true
} else if w.cursor <= len(w.widgets) { }
if w.cursor <= len(w.widgets) {
return w.widgets[w.cursor].HandleKey(ev) return w.widgets[w.cursor].HandleKey(ev)
} }
return false return false

View File

@@ -43,8 +43,8 @@ type TopMenuLayout struct {
visible bool visible bool
focusable bool focusable bool
layoutFlags LayoutFlag layoutFlags LayoutFlag
keyMap KeyMap keyMap, customKeyMap KeyMap
logger func(string, ...any) logger func(string, ...any)
} }
@@ -79,6 +79,7 @@ func (w *TopMenuLayout) Init(id string, s tcell.Style) {
} }
return false return false
}) })
w.customKeyMap = BlankKeyMap()
} }
func (w *TopMenuLayout) ToggleMenu() bool { func (w *TopMenuLayout) ToggleMenu() bool {
@@ -121,14 +122,20 @@ func (w *TopMenuLayout) HandleResize(ev *tcell.EventResize) {
} }
} }
func (w *TopMenuLayout) SetKeyMap(km KeyMap) { w.keyMap = km } func (w *TopMenuLayout) SetKeyMap(km KeyMap, def bool) {
func (w *TopMenuLayout) AddToKeyMap(km KeyMap) { w.keyMap.Merge(km) } if def {
w.keyMap = km
} else {
w.customKeyMap = km
}
}
func (w *TopMenuLayout) AddToKeyMap(km KeyMap) { w.customKeyMap.Merge(km) }
func (w *TopMenuLayout) RemoveFromKeyMap(km KeyMap) { func (w *TopMenuLayout) RemoveFromKeyMap(km KeyMap) {
for k := range km.Keys { for k := range km.Keys {
w.keyMap.Remove(k) w.customKeyMap.Remove(k)
} }
for r := range km.Runes { for r := range km.Runes {
w.keyMap.RemoveRune(r) w.customKeyMap.RemoveRune(r)
} }
} }
@@ -136,8 +143,8 @@ func (w *TopMenuLayout) HandleKey(ev *tcell.EventKey) bool {
if !w.active { if !w.active {
return false return false
} }
b1, b2 := w.keyMap.Handle(ev), w.customKeyMap.Handle(ev)
if w.keyMap.Handle(ev) { if b1 || b2 {
return true return true
} }
if w.menu != nil && w.menu.Active() { if w.menu != nil && w.menu.Active() {

View File

@@ -32,7 +32,11 @@ 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) // KeyMap Handling
// SetKeyMap sets a new keymap
// if 'def' is true, the default keymap is overwritten
// otherwise, it should be treated as a custom keymap
SetKeyMap(km KeyMap, def bool)
AddToKeyMap(km KeyMap) AddToKeyMap(km KeyMap)
RemoveFromKeyMap(km KeyMap) RemoveFromKeyMap(km KeyMap)
Draw(tcell.Screen) Draw(tcell.Screen)