neofeels/ui/list.go
2025-04-29 05:56:42 +03:00

122 lines
2.4 KiB
Go

/**
* vaxis/widget/list, edited to support wraparounds and number seeking
* soon to support confirmations, once i get around to that
*/
package ui
import (
"fmt"
"strconv"
"git.sr.ht/~rockorager/vaxis"
)
type List struct {
index int
items [][]vaxis.Segment
offset int
}
func NewList(items [][]vaxis.Segment, index int) List {
return List{
items: items,
index: index,
}
}
func (m *List) Draw(win vaxis.Window) {
_, height := win.Size()
if m.index >= m.offset+height {
m.offset = m.index - height + 1
} else if m.index < m.offset {
m.offset = m.index
}
defaultStyle := vaxis.Style{Attribute: vaxis.AttrNone}
selectedStyle := vaxis.Style{Attribute: vaxis.AttrReverse}
index := m.index - m.offset
for i, subject := range m.items[m.offset:] {
var style vaxis.Style
if i == index {
style = selectedStyle
} else {
style = defaultStyle
}
var styledSubject []vaxis.Segment
length := 0
for _, chunk := range subject {
length += len(chunk.Text)
styledSubject = append(styledSubject, vaxis.Segment{Text: chunk.Text, Style: vaxis.Style{Attribute: style.Attribute | chunk.Style.Attribute}})
}
styledSubject = append([]vaxis.Segment{{Text: " ", Style: style}}, styledSubject...)
styledSubject = append(styledSubject, vaxis.Segment{Text: fmt.Sprintf("%"+strconv.Itoa(win.Width-length-2)+"s", ""), Style: style})
win.Println(i, styledSubject...)
}
}
func (m *List) Down() {
if m.index == len(m.items)-1 {
m.index = 0
} else {
m.index++
}
}
func (m *List) Up() {
if m.index == 0 {
m.index = len(m.items) - 1
} else {
m.index--
}
}
func (m *List) Home() {
m.index = 0
}
func (m *List) End() {
m.index = len(m.items) - 1
}
func (m *List) PageDown(win vaxis.Window) {
_, height := win.Size()
m.index = min(len(m.items)-1, m.index+height)
}
func (m *List) PageUp(win vaxis.Window) {
_, height := win.Size()
m.index = max(0, m.index-height)
}
func (m *List) Items() []string {
var items []string
for _, item := range m.items {
var text string
for _, chunk := range item {
text += chunk.Text
}
items = append(items, text)
}
return items
}
func (m *List) SetItems(items [][]vaxis.Segment) {
m.items = items
m.index = min(len(items)-1, m.index)
}
func (m *List) SetItem(index int, item []vaxis.Segment) {
m.items[index] = item
}
// Returns the index of the currently selected item.
func (m *List) Index() int {
return m.index
}
func (m *List) SetIndex(index int) {
m.index = index
}