|
|
|
@ -12,8 +12,8 @@ import (
|
|
|
|
|
// ListItem represents an item in a List.
|
|
|
|
|
type ListItem struct { |
|
|
|
|
enabled bool // Whether or not the list item is selectable.
|
|
|
|
|
mainText string // The main text of the list item.
|
|
|
|
|
secondaryText string // A secondary text to be shown underneath the main text.
|
|
|
|
|
mainText []byte // The main text of the list item.
|
|
|
|
|
secondaryText []byte // A secondary text to be shown underneath the main text.
|
|
|
|
|
shortcut rune // The key to select the list item directly, 0 if there is no shortcut.
|
|
|
|
|
selected func() // The optional function which is called when the item is selected.
|
|
|
|
|
reference interface{} // An optional reference object.
|
|
|
|
@ -24,13 +24,13 @@ type ListItem struct {
|
|
|
|
|
// NewListItem returns a new item for a list.
|
|
|
|
|
func NewListItem(mainText string) *ListItem { |
|
|
|
|
return &ListItem{ |
|
|
|
|
mainText: mainText, |
|
|
|
|
mainText: []byte(mainText), |
|
|
|
|
enabled: true, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// SetMainText sets the main text of the list item.
|
|
|
|
|
func (l *ListItem) SetMainText(val string) *ListItem { |
|
|
|
|
// SetMainBytes sets the main text of the list item.
|
|
|
|
|
func (l *ListItem) SetMainBytes(val []byte) *ListItem { |
|
|
|
|
l.Lock() |
|
|
|
|
defer l.Unlock() |
|
|
|
|
|
|
|
|
@ -38,16 +38,26 @@ func (l *ListItem) SetMainText(val string) *ListItem {
|
|
|
|
|
return l |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// GetMainText returns the item's main text.
|
|
|
|
|
func (l *ListItem) GetMainText() string { |
|
|
|
|
// SetMainText sets the main text of the list item.
|
|
|
|
|
func (l *ListItem) SetMainText(val string) *ListItem { |
|
|
|
|
return l.SetMainBytes([]byte(val)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// GetMainBytes returns the item's main text.
|
|
|
|
|
func (l *ListItem) GetMainBytes() []byte { |
|
|
|
|
l.RLock() |
|
|
|
|
defer l.RUnlock() |
|
|
|
|
|
|
|
|
|
return l.mainText |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// SetSecondaryText sets a secondary text to be shown underneath the main text.
|
|
|
|
|
func (l *ListItem) SetSecondaryText(val string) *ListItem { |
|
|
|
|
// GetMainText returns the item's main text.
|
|
|
|
|
func (l *ListItem) GetMainText() string { |
|
|
|
|
return string(l.GetMainBytes()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// SetSecondaryBytes sets a secondary text to be shown underneath the main text.
|
|
|
|
|
func (l *ListItem) SetSecondaryBytes(val []byte) *ListItem { |
|
|
|
|
l.Lock() |
|
|
|
|
defer l.Unlock() |
|
|
|
|
|
|
|
|
@ -55,14 +65,24 @@ func (l *ListItem) SetSecondaryText(val string) *ListItem {
|
|
|
|
|
return l |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// GetSecondaryText returns the item's secondary text.
|
|
|
|
|
func (l *ListItem) GetSecondaryText() string { |
|
|
|
|
// SetSecondaryText sets a secondary text to be shown underneath the main text.
|
|
|
|
|
func (l *ListItem) SetSecondaryText(val string) *ListItem { |
|
|
|
|
return l.SetSecondaryBytes([]byte(val)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// GetSecondaryBytes returns the item's secondary text.
|
|
|
|
|
func (l *ListItem) GetSecondaryBytes() []byte { |
|
|
|
|
l.RLock() |
|
|
|
|
defer l.RUnlock() |
|
|
|
|
|
|
|
|
|
return l.secondaryText |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// GetSecondaryText returns the item's secondary text.
|
|
|
|
|
func (l *ListItem) GetSecondaryText() string { |
|
|
|
|
return string(l.GetSecondaryBytes()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// SetShortcut sets the key to select the ListItem directly, 0 if there is no shortcut.
|
|
|
|
|
func (l *ListItem) SetShortcut(val rune) *ListItem { |
|
|
|
|
l.Lock() |
|
|
|
@ -612,7 +632,7 @@ func (l *List) GetItemCount() int {
|
|
|
|
|
func (l *List) GetItemText(index int) (main, secondary string) { |
|
|
|
|
l.RLock() |
|
|
|
|
defer l.RUnlock() |
|
|
|
|
return l.items[index].mainText, l.items[index].secondaryText |
|
|
|
|
return string(l.items[index].mainText), string(l.items[index].secondaryText) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// SetItemText sets an item's main and secondary text. Panics if the index is
|
|
|
|
@ -622,8 +642,8 @@ func (l *List) SetItemText(index int, main, secondary string) *List {
|
|
|
|
|
defer l.Unlock() |
|
|
|
|
|
|
|
|
|
item := l.items[index] |
|
|
|
|
item.mainText = main |
|
|
|
|
item.secondaryText = secondary |
|
|
|
|
item.mainText = []byte(main) |
|
|
|
|
item.secondaryText = []byte(secondary) |
|
|
|
|
return l |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -661,19 +681,22 @@ func (l *List) FindItems(mainSearch, secondarySearch string, mustContainBoth, ig
|
|
|
|
|
secondarySearch = strings.ToLower(secondarySearch) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
mainSearchBytes := []byte(mainSearch) |
|
|
|
|
secondarySearchBytes := []byte(secondarySearch) |
|
|
|
|
|
|
|
|
|
for index, item := range l.items { |
|
|
|
|
mainText := item.mainText |
|
|
|
|
secondaryText := item.secondaryText |
|
|
|
|
if ignoreCase { |
|
|
|
|
mainText = strings.ToLower(mainText) |
|
|
|
|
secondaryText = strings.ToLower(secondaryText) |
|
|
|
|
mainText = bytes.ToLower(mainText) |
|
|
|
|
secondaryText = bytes.ToLower(secondaryText) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// strings.Contains() always returns true for a "" search.
|
|
|
|
|
mainContained := strings.Contains(mainText, mainSearch) |
|
|
|
|
secondaryContained := strings.Contains(secondaryText, secondarySearch) |
|
|
|
|
mainContained := bytes.Contains(mainText, mainSearchBytes) |
|
|
|
|
secondaryContained := bytes.Contains(secondaryText, secondarySearchBytes) |
|
|
|
|
if mustContainBoth && mainContained && secondaryContained || |
|
|
|
|
!mustContainBoth && (mainText != "" && mainContained || secondaryText != "" && secondaryContained) { |
|
|
|
|
!mustContainBoth && (len(mainText) > 0 && mainContained || len(secondaryText) > 0 && secondaryContained) { |
|
|
|
|
indices = append(indices, index) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -871,7 +894,7 @@ func (l *List) Draw(screen tcell.Screen) {
|
|
|
|
|
break |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if item.mainText == "" && item.secondaryText == "" && item.shortcut == 0 { // Divider
|
|
|
|
|
if len(item.mainText) == 0 && len(item.secondaryText) == 0 && item.shortcut == 0 { // Divider
|
|
|
|
|
Print(screen, []byte(string(tcell.RuneLTee)), (x-5)-l.paddingLeft, y, 1, AlignLeft, l.mainTextColor) |
|
|
|
|
Print(screen, bytes.Repeat([]byte(string(tcell.RuneHLine)), width+4+l.paddingLeft+l.paddingRight), (x-4)-l.paddingLeft, y, width+4+l.paddingLeft+l.paddingRight, AlignLeft, l.mainTextColor) |
|
|
|
|
Print(screen, []byte(string(tcell.RuneRTee)), (x-5)+width+5+l.paddingRight, y, 1, AlignLeft, l.mainTextColor) |
|
|
|
@ -905,7 +928,7 @@ func (l *List) Draw(screen tcell.Screen) {
|
|
|
|
|
if index == l.currentItem && (!l.selectedFocusOnly || hasFocus) { |
|
|
|
|
textWidth := width |
|
|
|
|
if !l.highlightFullLine { |
|
|
|
|
if w := TaggedStringWidth(item.mainText); w < textWidth { |
|
|
|
|
if w := TaggedTextWidth(item.mainText); w < textWidth { |
|
|
|
|
textWidth = w |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -955,7 +978,7 @@ func (l *List) Draw(screen tcell.Screen) {
|
|
|
|
|
// What's the longest option text?
|
|
|
|
|
maxWidth := 0 |
|
|
|
|
for _, option := range ctx.items { |
|
|
|
|
strWidth := TaggedStringWidth(option.mainText) |
|
|
|
|
strWidth := TaggedTextWidth(option.mainText) |
|
|
|
|
if option.shortcut != 0 { |
|
|
|
|
strWidth += 4 |
|
|
|
|
} |
|
|
|
|