diff --git a/_examples/list.go b/_examples/list.go index 6d5b1b2..dbbdf75 100644 --- a/_examples/list.go +++ b/_examples/list.go @@ -32,8 +32,8 @@ func main() { "[7] nsf/termbox-go", } l.TextStyle = ui.NewStyle(ui.ColorYellow) - l.Wrap = false - l.SetRect(0, 0, 25, 50) + l.WrapText = false + l.SetRect(0, 0, 25, 5) ui.Render(l) @@ -43,6 +43,12 @@ func main() { switch e.ID { case "q", "": return + case "j", "": + l.ScrollDown() + ui.Render(l) + case "k", "": + l.ScrollUp() + ui.Render(l) } } } diff --git a/go.mod b/go.mod index 7d0b1c6..ca49f9d 100644 --- a/go.mod +++ b/go.mod @@ -5,4 +5,5 @@ require ( github.com/mattn/go-runewidth v0.0.2 github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d + golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 // indirect ) diff --git a/go.sum b/go.sum index 495684f..121df84 100644 --- a/go.sum +++ b/go.sum @@ -6,3 +6,5 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzC github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d h1:x3S6kxmy49zXVVyhcnrFqxvNVCBPb2KZ9hV2RBdS840= github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ= +golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 h1:Pn8fQdvx+z1avAi7fdM2kRYWQNxGlavNDSyzrQg2SsU= +golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8= diff --git a/symbols.go b/symbols.go index b7bda5f..6db7d1c 100644 --- a/symbols.go +++ b/symbols.go @@ -3,6 +3,9 @@ package termui const ( DOT = '•' ELLIPSES = '…' + + UP_ARROW = '▲' + DOWN_ARROW = '▼' ) var ( diff --git a/widgets/list.go b/widgets/list.go index b6497bd..61c74e3 100644 --- a/widgets/list.go +++ b/widgets/list.go @@ -12,15 +12,19 @@ import ( type List struct { Block - Rows []string - Wrap bool - TextStyle Style + Rows []string + WrapText bool + TextStyle Style + SelectedRow uint + topRow uint + SelectedRowStyle Style } func NewList() *List { return &List{ - Block: *NewBlock(), - TextStyle: Theme.List.Text, + Block: *NewBlock(), + TextStyle: Theme.List.Text, + SelectedRowStyle: Theme.List.Text, } } @@ -29,24 +33,59 @@ func (self *List) Draw(buf *Buffer) { point := self.Inner.Min - for row := 0; row < len(self.Rows) && point.Y < self.Inner.Max.Y; row++ { + for row := self.topRow; row < uint(len(self.Rows)) && point.Y < self.Inner.Max.Y; row++ { cells := ParseText(self.Rows[row], self.TextStyle) - if self.Wrap { + if self.WrapText { cells = WrapCells(cells, uint(self.Inner.Dx())) } for j := 0; j < len(cells) && point.Y < self.Inner.Max.Y; j++ { + style := cells[j].Style + if row == self.SelectedRow { + style = self.SelectedRowStyle + } if cells[j].Rune == '\n' { point = image.Pt(self.Inner.Min.X, point.Y+1) } else { if point.X+1 == self.Inner.Max.X+1 && len(cells) > self.Inner.Dx() { - buf.SetCell(NewCell(ELLIPSES, cells[j].Style), point.Add(image.Pt(-1, 0))) + buf.SetCell(NewCell(ELLIPSES, style), point.Add(image.Pt(-1, 0))) break } else { - buf.SetCell(cells[j], point) + buf.SetCell(NewCell(cells[j].Rune, style), point) point = point.Add(image.Pt(1, 0)) } } } point = image.Pt(self.Inner.Min.X, point.Y+1) } + + if self.topRow > 0 { + buf.SetCell( + NewCell(UP_ARROW, NewStyle(ColorWhite)), + image.Pt(self.Inner.Max.X-1, self.Inner.Min.Y), + ) + } + if len(self.Rows) > int(self.topRow)+self.Inner.Dy() { + buf.SetCell( + NewCell(DOWN_ARROW, NewStyle(ColorWhite)), + image.Pt(self.Inner.Max.X-1, self.Inner.Max.Y-1), + ) + } +} + +func (self *List) ScrollUp() { + if self.SelectedRow > 0 { + self.SelectedRow-- + if self.SelectedRow < self.topRow { + self.topRow-- + } + } +} + +func (self *List) ScrollDown() { + if self.SelectedRow < uint(len(self.Rows))-1 { + self.SelectedRow++ + if self.SelectedRow-self.topRow > uint(self.Inner.Dy()-1) { + self.topRow++ + } + } }