More callback handlers for lists. And more consistency.

This commit is contained in:
Oliver 2018-01-01 17:17:20 +01:00
parent 60313b7f25
commit 997b92f1b4
2 changed files with 47 additions and 3 deletions

View File

@ -138,7 +138,7 @@ func (d *DropDown) AddOption(text string, selected func()) *DropDown {
// It will be called with the option's text and its index into the options
// slice. The "selected" parameter may be nil.
func (d *DropDown) SetOptions(texts []string, selected func(text string, index int)) *DropDown {
d.list.ClearItems()
d.list.Clear()
d.options = nil
for index, text := range texts {
func(t string, i int) {

48
list.go
View File

@ -42,9 +42,16 @@ type List struct {
// The background color for selected items.
selectedBackgroundColor tcell.Color
// An optional function which is called when the user has navigated to a list
// item.
changed func(index int, mainText, secondaryText string, shortcut rune)
// An optional function which is called when a list item was selected. This
// function will be called even if the list item defines its own callback.
selected func(index int, mainText, secondaryText string, shortcut rune)
// An optional function which is called when the user presses the Escape key.
done func()
}
// NewList returns a new form.
@ -63,6 +70,10 @@ func NewList() *List {
// SetCurrentItem sets the currently selected item by its index.
func (l *List) SetCurrentItem(index int) *List {
l.currentItem = index
if l.currentItem < len(l.items) && l.changed != nil {
item := l.items[l.currentItem]
l.changed(l.currentItem, item.MainText, item.SecondaryText, item.Shortcut)
}
return l
}
@ -102,6 +113,17 @@ func (l *List) ShowSecondaryText(show bool) *List {
return l
}
// SetChangedFunc sets the function which is called when the user navigates to
// a list item. The function receives the item's index in the list of items
// (starting with 0), its main text, secondary text, and its shortcut rune.
//
// This function is also called when the first item is added or when
// SetCurrentItem() is called.
func (l *List) SetChangedFunc(handler func(int, string, string, rune)) *List {
l.changed = handler
return l
}
// SetSelectedFunc sets the function which is called when the user selects a
// list item by pressing Enter on the current selection. The function receives
// the item's index in the list of items (starting with 0), its main text,
@ -111,6 +133,13 @@ func (l *List) SetSelectedFunc(handler func(int, string, string, rune)) *List {
return l
}
// SetDoneFunc sets a function which is called when the user presses the Escape
// key.
func (l *List) SetDoneFunc(handler func()) *List {
l.done = handler
return l
}
// AddItem adds a new item to the list. An item has a main text which will be
// highlighted when selected. It also has a secondary text which is shown
// underneath the main text (if it is set to visible) but which may remain
@ -129,11 +158,15 @@ func (l *List) AddItem(mainText, secondaryText string, shortcut rune, selected f
Shortcut: shortcut,
Selected: selected,
})
if len(l.items) == 1 && l.changed != nil {
item := l.items[0]
l.changed(0, item.MainText, item.SecondaryText, item.Shortcut)
}
return l
}
// ClearItems removes all items from the list.
func (l *List) ClearItems() *List {
// Clear removes all items from the list.
func (l *List) Clear() *List {
l.items = nil
l.currentItem = 0
return l
@ -197,6 +230,8 @@ func (l *List) Draw(screen tcell.Screen) {
// InputHandler returns the handler for this primitive.
func (l *List) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) {
return func(event *tcell.EventKey, setFocus func(p Primitive)) {
previousItem := l.currentItem
switch key := event.Key(); key {
case tcell.KeyTab, tcell.KeyDown, tcell.KeyRight:
l.currentItem++
@ -218,6 +253,10 @@ func (l *List) InputHandler() func(event *tcell.EventKey, setFocus func(p Primit
if l.selected != nil {
l.selected(l.currentItem, item.MainText, item.SecondaryText, item.Shortcut)
}
case tcell.KeyEscape:
if l.done != nil {
l.done()
}
case tcell.KeyRune:
ch := event.Rune()
if ch != ' ' {
@ -249,5 +288,10 @@ func (l *List) InputHandler() func(event *tcell.EventKey, setFocus func(p Primit
} else if l.currentItem >= len(l.items) {
l.currentItem = 0
}
if l.currentItem != previousItem && l.currentItem < len(l.items) && l.changed != nil {
item := l.items[l.currentItem]
l.changed(l.currentItem, item.MainText, item.SecondaryText, item.Shortcut)
}
}
}