KeyMap Expansion
This commit is contained in:
18
chat.go
18
chat.go
@@ -166,12 +166,12 @@ func (w *Chat) WantW() int { return w.w }
|
||||
func (w *Chat) WantH() int { return w.h }
|
||||
|
||||
func (w *Chat) initKeyMap() {
|
||||
w.keyMap = NewKeyMap(map[tcell.Key]func() bool{
|
||||
tcell.KeyEsc: func() bool {
|
||||
w.keyMap = NewKeyMap(map[tcell.Key]func(ev *tcell.EventKey) bool{
|
||||
tcell.KeyEsc: func(ev *tcell.EventKey) bool {
|
||||
w.SetActive(false)
|
||||
return true
|
||||
},
|
||||
tcell.KeyUp: func() bool {
|
||||
tcell.KeyUp: func(ev *tcell.EventKey) bool {
|
||||
if w.historyPosition < len(w.history)-1 {
|
||||
w.historyPosition++
|
||||
w.value = w.history[w.historyPosition].Message
|
||||
@@ -180,7 +180,7 @@ func (w *Chat) initKeyMap() {
|
||||
}
|
||||
return false
|
||||
},
|
||||
tcell.KeyDown: func() bool {
|
||||
tcell.KeyDown: func(ev *tcell.EventKey) bool {
|
||||
if w.historyPosition > -1 {
|
||||
w.historyPosition--
|
||||
if w.historyPosition == -1 {
|
||||
@@ -193,31 +193,31 @@ func (w *Chat) initKeyMap() {
|
||||
}
|
||||
return false
|
||||
},
|
||||
tcell.KeyLeft: func() bool {
|
||||
tcell.KeyLeft: func(ev *tcell.EventKey) bool {
|
||||
if w.cursor > 0 {
|
||||
w.cursor--
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
tcell.KeyRight: func() bool {
|
||||
tcell.KeyRight: func(ev *tcell.EventKey) bool {
|
||||
if w.cursor < len(w.value) {
|
||||
w.cursor++
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
tcell.KeyCtrlU: func() bool {
|
||||
tcell.KeyCtrlU: func(ev *tcell.EventKey) bool {
|
||||
w.value = w.value[w.cursor:]
|
||||
w.cursor = 0
|
||||
return true
|
||||
},
|
||||
tcell.KeyTab: func() bool {
|
||||
tcell.KeyTab: func(ev *tcell.EventKey) bool {
|
||||
// Auto-complete
|
||||
// TODO: Find best guess for current word
|
||||
return false
|
||||
},
|
||||
tcell.KeyEnter: func() bool {
|
||||
tcell.KeyEnter: func(ev *tcell.EventKey) bool {
|
||||
// TODO: Submit the message
|
||||
return false
|
||||
},
|
||||
|
||||
18
cli.go
18
cli.go
@@ -171,12 +171,12 @@ func (w *Cli) WantW() int { return w.w }
|
||||
func (w *Cli) WantH() int { return w.h }
|
||||
|
||||
func (w *Cli) initKeyMap() {
|
||||
w.keyMap = NewKeyMap(map[tcell.Key]func() bool{
|
||||
tcell.KeyEsc: func() bool {
|
||||
w.keyMap = NewKeyMap(map[tcell.Key]func(ev *tcell.EventKey) bool{
|
||||
tcell.KeyEsc: func(ev *tcell.EventKey) bool {
|
||||
w.SetActive(false)
|
||||
return true
|
||||
},
|
||||
tcell.KeyUp: func() bool {
|
||||
tcell.KeyUp: func(ev *tcell.EventKey) bool {
|
||||
if w.historyPosition < len(w.history)-1 {
|
||||
w.historyPosition++
|
||||
w.value = w.history[w.historyPosition]
|
||||
@@ -185,7 +185,7 @@ func (w *Cli) initKeyMap() {
|
||||
}
|
||||
return false
|
||||
},
|
||||
tcell.KeyDown: func() bool {
|
||||
tcell.KeyDown: func(ev *tcell.EventKey) bool {
|
||||
if w.historyPosition > -1 {
|
||||
w.historyPosition--
|
||||
if w.historyPosition == -1 {
|
||||
@@ -198,26 +198,26 @@ func (w *Cli) initKeyMap() {
|
||||
}
|
||||
return false
|
||||
},
|
||||
tcell.KeyLeft: func() bool {
|
||||
tcell.KeyLeft: func(ev *tcell.EventKey) bool {
|
||||
if w.cursor > 0 {
|
||||
w.cursor--
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
tcell.KeyRight: func() bool {
|
||||
tcell.KeyRight: func(ev *tcell.EventKey) bool {
|
||||
if w.cursor < len(w.value) {
|
||||
w.cursor++
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
tcell.KeyCtrlU: func() bool {
|
||||
tcell.KeyCtrlU: func(ev *tcell.EventKey) bool {
|
||||
w.value = w.value[w.cursor:]
|
||||
w.cursor = 0
|
||||
return true
|
||||
},
|
||||
tcell.KeyTab: func() bool {
|
||||
tcell.KeyTab: func(ev *tcell.EventKey) bool {
|
||||
// Auto-complete
|
||||
guess := w.findBestGuess()
|
||||
if guess != "" {
|
||||
@@ -227,7 +227,7 @@ func (w *Cli) initKeyMap() {
|
||||
}
|
||||
return false
|
||||
},
|
||||
tcell.KeyEnter: func() bool {
|
||||
tcell.KeyEnter: func(ev *tcell.EventKey) bool {
|
||||
cmds := strings.Split(w.value, " ")
|
||||
if v, ok := w.commandMap[cmds[0]]; ok {
|
||||
w.history = append(w.history, w.value)
|
||||
|
||||
16
field.go
16
field.go
@@ -63,7 +63,7 @@ func (w *Field) Init(id string, style tcell.Style) {
|
||||
return h.IsBS(*ev) ||
|
||||
h.KeyIsDisplayable(*ev)
|
||||
}
|
||||
w.keyMap = NewKeyMap(map[tcell.Key]func() bool{
|
||||
w.keyMap = NewKeyMap(map[tcell.Key]func(ev *tcell.EventKey) bool{
|
||||
tcell.KeyLeft: w.handleLeft,
|
||||
tcell.KeyRight: w.handleRight,
|
||||
tcell.KeyHome: w.handleHome,
|
||||
@@ -79,7 +79,7 @@ func (w *Field) HandleKey(ev *tcell.EventKey) bool {
|
||||
return false
|
||||
}
|
||||
if h.IsBS(*ev) {
|
||||
return w.handleBackspace()
|
||||
return w.handleBackspace(ev)
|
||||
}
|
||||
if ok := w.keyMap.Handle(ev); ok {
|
||||
return true
|
||||
@@ -153,7 +153,7 @@ func (w *Field) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
|
||||
func (w *Field) Focusable() bool { return true }
|
||||
|
||||
/* Non-Widget-Interface Functions */
|
||||
func (w *Field) handleBackspace() bool {
|
||||
func (w *Field) handleBackspace(ev *tcell.EventKey) bool {
|
||||
st := w.cursor
|
||||
if w.cursor > 0 {
|
||||
w.cursor--
|
||||
@@ -167,7 +167,7 @@ func (w *Field) handleBackspace() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *Field) handleLeft() bool {
|
||||
func (w *Field) handleLeft(ev *tcell.EventKey) bool {
|
||||
if w.cursor > 0 {
|
||||
w.cursor--
|
||||
return true
|
||||
@@ -175,7 +175,7 @@ func (w *Field) handleLeft() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *Field) handleRight() bool {
|
||||
func (w *Field) handleRight(ev *tcell.EventKey) bool {
|
||||
if w.cursor < len(w.value) {
|
||||
w.cursor++
|
||||
return true
|
||||
@@ -183,18 +183,18 @@ func (w *Field) handleRight() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *Field) clearValueBeforeCursor() bool {
|
||||
func (w *Field) clearValueBeforeCursor(ev *tcell.EventKey) bool {
|
||||
w.SetValue(w.value[w.cursor:])
|
||||
w.cursor = 0
|
||||
return true
|
||||
}
|
||||
|
||||
func (w *Field) handleHome() bool {
|
||||
func (w *Field) handleHome(ev *tcell.EventKey) bool {
|
||||
w.cursor = 0
|
||||
return true
|
||||
}
|
||||
|
||||
func (w *Field) handleEnd() bool {
|
||||
func (w *Field) handleEnd(ev *tcell.EventKey) bool {
|
||||
w.cursor = len(w.value)
|
||||
return true
|
||||
}
|
||||
|
||||
62
keymap.go
62
keymap.go
@@ -23,27 +23,69 @@ package widgets
|
||||
|
||||
import "github.com/gdamore/tcell"
|
||||
|
||||
type KeyMap map[tcell.Key]func() bool
|
||||
type KeyMap struct {
|
||||
Keys map[tcell.Key]func(*tcell.EventKey) bool
|
||||
Runes map[rune]func(*tcell.EventKey) bool
|
||||
}
|
||||
|
||||
func BlankKeyMap() KeyMap {
|
||||
return KeyMap(make(map[tcell.Key]func() bool))
|
||||
return KeyMap{
|
||||
Keys: make(map[tcell.Key]func(*tcell.EventKey) bool),
|
||||
Runes: make(map[rune]func(*tcell.EventKey) bool),
|
||||
}
|
||||
}
|
||||
|
||||
func NewKeyMap(m map[tcell.Key]func() bool) KeyMap {
|
||||
return KeyMap(m)
|
||||
func NewKeyMap(m map[tcell.Key]func(*tcell.EventKey) bool) KeyMap {
|
||||
return KeyMap{
|
||||
Keys: m,
|
||||
Runes: make(map[rune]func(*tcell.EventKey) bool),
|
||||
}
|
||||
}
|
||||
|
||||
func (m KeyMap) Add(k tcell.Key, do func() bool) { m[k] = do }
|
||||
func NewRuneMap(m map[rune]func(*tcell.EventKey) bool) KeyMap {
|
||||
return KeyMap{
|
||||
Keys: make(map[tcell.Key]func(*tcell.EventKey) bool),
|
||||
Runes: m,
|
||||
}
|
||||
}
|
||||
|
||||
func (m KeyMap) Add(k tcell.Key, do func(*tcell.EventKey) bool) { m.Keys[k] = do }
|
||||
func (m KeyMap) Remove(k tcell.Key) {
|
||||
if _, ok := m[k]; ok {
|
||||
delete(m, k)
|
||||
if _, ok := m.Keys[k]; ok {
|
||||
delete(m.Keys, k)
|
||||
}
|
||||
}
|
||||
|
||||
func (m KeyMap) AddAll(all map[tcell.Key]func(*tcell.EventKey) bool) {
|
||||
for k, v := range all {
|
||||
m.Add(k, v)
|
||||
}
|
||||
}
|
||||
func (m KeyMap) AddRune(k rune, do func(*tcell.EventKey) bool) { m.Runes[k] = do }
|
||||
func (m KeyMap) RemoveRune(k rune) {
|
||||
if _, ok := m.Runes[k]; ok {
|
||||
delete(m.Runes, k)
|
||||
}
|
||||
}
|
||||
|
||||
func (m KeyMap) AddRunes(all map[rune]func(*tcell.EventKey) bool) {
|
||||
for k, v := range all {
|
||||
m.AddRune(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (m KeyMap) Handle(ev *tcell.EventKey) bool {
|
||||
for k, v := range m {
|
||||
if ev.Key() == k {
|
||||
return v()
|
||||
if ev.Key() == tcell.KeyRune {
|
||||
for k, v := range m.Runes {
|
||||
if ev.Rune() == k {
|
||||
return v(ev)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for k, v := range m.Keys {
|
||||
if ev.Key() == k {
|
||||
return v(ev)
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
||||
22
list.go
22
list.go
@@ -46,6 +46,7 @@ type List struct {
|
||||
|
||||
onSelect func(int, string) bool
|
||||
keyMap KeyMap
|
||||
vimMode bool
|
||||
}
|
||||
|
||||
var _ Widget = (*List)(nil)
|
||||
@@ -59,16 +60,28 @@ func NewList(id string, style tcell.Style) *List {
|
||||
func (w *List) Init(id string, style tcell.Style) {
|
||||
w.id = id
|
||||
w.style = style
|
||||
w.keyMap = NewKeyMap(map[tcell.Key]func() bool{
|
||||
w.keyMap = NewKeyMap(map[tcell.Key]func(ev *tcell.EventKey) bool{
|
||||
tcell.KeyUp: w.MoveUp,
|
||||
tcell.KeyDown: w.MoveDown,
|
||||
tcell.KeyEnter: func() bool {
|
||||
tcell.KeyEnter: func(ev *tcell.EventKey) bool {
|
||||
if w.onSelect != nil && w.cursor < len(w.list) {
|
||||
return w.onSelect(w.cursor, w.list[w.cursor])
|
||||
}
|
||||
return false
|
||||
},
|
||||
})
|
||||
w.keyMap.AddRune('j', func(ev *tcell.EventKey) bool {
|
||||
if w.vimMode {
|
||||
return w.MoveDown(ev)
|
||||
}
|
||||
return false
|
||||
})
|
||||
w.keyMap.AddRune('k', func(ev *tcell.EventKey) bool {
|
||||
if w.vimMode {
|
||||
return w.MoveUp(ev)
|
||||
}
|
||||
return false
|
||||
})
|
||||
w.itemsStyle = make(map[int]tcell.Style)
|
||||
}
|
||||
func (w *List) Id() string { return w.id }
|
||||
@@ -149,7 +162,7 @@ func (w *List) WantH() int {
|
||||
func (w *List) SetFocusable(f bool) { w.focusable = f }
|
||||
|
||||
func (w *List) SetCursorWrap(b bool) { w.cursorWrap = b }
|
||||
func (w *List) MoveUp() bool {
|
||||
func (w *List) MoveUp(ev *tcell.EventKey) bool {
|
||||
if w.cursor > 0 {
|
||||
w.cursor--
|
||||
return true
|
||||
@@ -160,7 +173,7 @@ func (w *List) MoveUp() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *List) MoveDown() bool {
|
||||
func (w *List) MoveDown(ev *tcell.EventKey) bool {
|
||||
if w.cursor < len(w.list)-1 {
|
||||
w.cursor++
|
||||
return true
|
||||
@@ -204,3 +217,4 @@ func (w *List) SetItem(idx int, txt string) {
|
||||
func (w *List) GetIdx() int { return w.cursor }
|
||||
func (w *List) ClearBorder() { w.border = []rune{} }
|
||||
func (w *List) SetOnSelect(s func(int, string) bool) { w.onSelect = s }
|
||||
func (w *List) SetVimMode(b bool) { w.vimMode = b }
|
||||
|
||||
13
menu.go
13
menu.go
@@ -41,6 +41,7 @@ type Menu struct {
|
||||
onPressed func() bool
|
||||
manualExpand bool
|
||||
expanded bool
|
||||
vimMode bool
|
||||
|
||||
keyMap KeyMap
|
||||
}
|
||||
@@ -62,12 +63,12 @@ func (w *Menu) Init(id string, style tcell.Style) {
|
||||
w.id = id
|
||||
w.style = style
|
||||
w.visible = true
|
||||
w.keyMap = NewKeyMap(map[tcell.Key]func() bool{
|
||||
w.keyMap = NewKeyMap(map[tcell.Key]func(ev *tcell.EventKey) bool{
|
||||
tcell.KeyRight: w.MoveRight,
|
||||
tcell.KeyLeft: w.MoveLeft,
|
||||
tcell.KeyUp: w.MoveUp,
|
||||
tcell.KeyDown: w.MoveDown,
|
||||
tcell.KeyEnter: func() bool {
|
||||
tcell.KeyEnter: func(ev *tcell.EventKey) bool {
|
||||
if w.onPressed != nil {
|
||||
return w.onPressed()
|
||||
}
|
||||
@@ -201,7 +202,7 @@ func (w *Menu) AddItems(iL ...Widget) {
|
||||
w.SetW(maxW)
|
||||
}
|
||||
|
||||
func (w *Menu) MoveRight() bool {
|
||||
func (w *Menu) MoveRight(ev *tcell.EventKey) bool {
|
||||
if w.menuType != MenuTypeH {
|
||||
return false
|
||||
}
|
||||
@@ -209,7 +210,7 @@ func (w *Menu) MoveRight() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (w *Menu) MoveLeft() bool {
|
||||
func (w *Menu) MoveLeft(ev *tcell.EventKey) bool {
|
||||
if w.menuType != MenuTypeH {
|
||||
return false
|
||||
}
|
||||
@@ -217,7 +218,7 @@ func (w *Menu) MoveLeft() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (w *Menu) MoveUp() bool {
|
||||
func (w *Menu) MoveUp(ev *tcell.EventKey) bool {
|
||||
if w.menuType != MenuTypeV {
|
||||
return false
|
||||
}
|
||||
@@ -225,7 +226,7 @@ func (w *Menu) MoveUp() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (w *Menu) MoveDown() bool {
|
||||
func (w *Menu) MoveDown(ev *tcell.EventKey) bool {
|
||||
if w.menuType != MenuTypeV {
|
||||
return false
|
||||
}
|
||||
|
||||
16
searcher.go
16
searcher.go
@@ -68,7 +68,7 @@ func (w *Searcher) Init(id string, style tcell.Style) {
|
||||
w.search.SetOnChange(func(prev, curr string) {
|
||||
w.updateFilter()
|
||||
})
|
||||
w.keyMap = NewKeyMap(map[tcell.Key]func() bool{
|
||||
w.keyMap = NewKeyMap(map[tcell.Key]func(ev *tcell.EventKey) bool{
|
||||
tcell.KeyUp: w.handleKeyUp,
|
||||
tcell.KeyDown: w.handleKeyDown,
|
||||
tcell.KeyHome: w.handleKeyHome,
|
||||
@@ -90,17 +90,17 @@ func (w *Searcher) HandleKey(ev *tcell.EventKey) bool {
|
||||
return w.search.HandleKey(ev)
|
||||
}
|
||||
|
||||
func (w *Searcher) handleKeyUp() bool {
|
||||
func (w *Searcher) handleKeyUp(ev *tcell.EventKey) bool {
|
||||
w.cursor = ((w.cursor - 1) + len(w.filteredData)) % len(w.filteredData)
|
||||
return true
|
||||
}
|
||||
|
||||
func (w *Searcher) handleKeyDown() bool {
|
||||
func (w *Searcher) handleKeyDown(ev *tcell.EventKey) bool {
|
||||
w.cursor = ((w.cursor + 1) + len(w.filteredData)) % len(w.filteredData)
|
||||
return true
|
||||
}
|
||||
|
||||
func (w *Searcher) handleKeyHome() bool {
|
||||
func (w *Searcher) handleKeyHome(ev *tcell.EventKey) bool {
|
||||
if w.cursor == 0 {
|
||||
return false
|
||||
}
|
||||
@@ -108,7 +108,7 @@ func (w *Searcher) handleKeyHome() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (w *Searcher) handleKeyEnd() bool {
|
||||
func (w *Searcher) handleKeyEnd(ev *tcell.EventKey) bool {
|
||||
if w.cursor == len(w.filteredData)-1 {
|
||||
return false
|
||||
}
|
||||
@@ -116,7 +116,7 @@ func (w *Searcher) handleKeyEnd() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (w *Searcher) handleKeyPgUp() bool {
|
||||
func (w *Searcher) handleKeyPgUp(ev *tcell.EventKey) bool {
|
||||
if w.cursor == 0 {
|
||||
return false
|
||||
}
|
||||
@@ -128,7 +128,7 @@ func (w *Searcher) handleKeyPgUp() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *Searcher) handleKeyPgDn() bool {
|
||||
func (w *Searcher) handleKeyPgDn(ev *tcell.EventKey) bool {
|
||||
mx := len(w.filteredData) - 1
|
||||
if w.cursor == mx {
|
||||
return false
|
||||
@@ -140,7 +140,7 @@ func (w *Searcher) handleKeyPgDn() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *Searcher) handleKeyEnter() bool {
|
||||
func (w *Searcher) handleKeyEnter(ev *tcell.EventKey) bool {
|
||||
if w.hideOnSelect {
|
||||
w.visible = false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user