/** * 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 }