From 2b80832a364ff65b9dbb2c1ae7e282b615ef8072 Mon Sep 17 00:00:00 2001 From: Bradley Cicenas Date: Wed, 8 Mar 2017 18:45:31 +1100 Subject: [PATCH] add pagination support for compact view --- cursor.go | 83 ++++++++++++++++++++++++++-------------- cwidgets/compact/grid.go | 28 +++++++------- grid.go | 15 +------- 3 files changed, 71 insertions(+), 55 deletions(-) diff --git a/cursor.go b/cursor.go index 5f349ed..9444e0b 100644 --- a/cursor.go +++ b/cursor.go @@ -7,7 +7,6 @@ import ( type GridCursor struct { selectedID string // id of currently selected container filtered Containers - containers Containers cSource ContainerSource } @@ -18,83 +17,109 @@ func NewGridCursor() *GridCursor { } func (gc *GridCursor) Len() int { return len(gc.filtered) } -func (gc *GridCursor) Selected() *Container { return gc.containers[gc.Idx()] } +func (gc *GridCursor) Selected() *Container { return gc.filtered[gc.Idx()] } // Refresh containers from source func (gc *GridCursor) RefreshContainers() (lenChanged bool) { oldLen := gc.Len() - gc.setContainers(gc.cSource.All()) + + // Containers filtered by display bool + gc.filtered = Containers{} + var cursorVisible bool + for _, c := range gc.cSource.All() { + if c.display { + if c.Id == gc.selectedID { + cursorVisible = true + } + gc.filtered = append(gc.filtered, c) + } + } + if oldLen != gc.Len() { lenChanged = true } + + if !cursorVisible { + gc.Reset() + } if gc.selectedID == "" { gc.Reset() } return lenChanged } -func (gc *GridCursor) setContainers(c Containers) { - gc.containers = c - // Containers filtered by display bool - gc.filtered = Containers{} - for _, c := range gc.containers { - if c.display { - gc.filtered = append(gc.filtered, c) - } - } -} - // Set an initial cursor position, if possible func (gc *GridCursor) Reset() { - for _, c := range gc.containers { + for _, c := range gc.cSource.All() { c.Widgets.Name.UnHighlight() } if gc.Len() > 0 { - gc.selectedID = gc.containers[0].Id - gc.containers[0].Widgets.Name.Highlight() + gc.selectedID = gc.filtered[0].Id + gc.filtered[0].Widgets.Name.Highlight() } } // Return current cursor index func (gc *GridCursor) Idx() int { - for n, c := range gc.containers { + for n, c := range gc.filtered { if c.Id == gc.selectedID { return n } } + gc.Reset() return 0 } +func (gc *GridCursor) ScrollPage() { + // skip scroll if no need to page + if gc.Len() < cGrid.MaxRows() { + cGrid.Offset = 0 + return + } + + idx := gc.Idx() + + // page down + if idx >= cGrid.Offset+cGrid.MaxRows() { + cGrid.Offset++ + cGrid.Align() + } + // page up + if idx < cGrid.Offset { + cGrid.Offset-- + cGrid.Align() + } + +} + func (gc *GridCursor) Up() { idx := gc.Idx() - // decrement if possible - if idx <= 0 { + if idx <= 0 { // already at top return } - active := gc.containers[idx] - next := gc.containers[idx-1] + active := gc.filtered[idx] + next := gc.filtered[idx-1] active.Widgets.Name.UnHighlight() gc.selectedID = next.Id next.Widgets.Name.Highlight() + gc.ScrollPage() ui.Render(cGrid) } func (gc *GridCursor) Down() { idx := gc.Idx() - // increment if possible - if idx >= (gc.Len() - 1) { + if idx >= gc.Len()-1 { // already at bottom return } - //if idx >= maxRows()-1 { - //return - //} - active := gc.containers[idx] - next := gc.containers[idx+1] + active := gc.filtered[idx] + next := gc.filtered[idx+1] active.Widgets.Name.UnHighlight() gc.selectedID = next.Id next.Widgets.Name.Highlight() + + gc.ScrollPage() ui.Render(cGrid) } diff --git a/cwidgets/compact/grid.go b/cwidgets/compact/grid.go index 43503e8..a55154c 100644 --- a/cwidgets/compact/grid.go +++ b/cwidgets/compact/grid.go @@ -8,11 +8,11 @@ var header = NewCompactHeader() type CompactGrid struct { ui.GridBufferer - Rows []ui.GridBufferer - X, Y int - Width int - Height int - cursorID string + Rows []ui.GridBufferer + X, Y int + Width int + Height int + Offset int // starting row offset } func NewCompactGrid() *CompactGrid { @@ -20,29 +20,31 @@ func NewCompactGrid() *CompactGrid { } func (cg *CompactGrid) Align() { - // update row y pos recursively + // update row ypos, width recursively y := cg.Y - for _, r := range cg.Rows { + for _, r := range cg.pageRows() { r.SetY(y) y += r.GetHeight() - } - - // update row width recursively - for _, r := range cg.Rows { r.SetWidth(cg.Width) } } -func (cg *CompactGrid) Clear() { cg.Rows = []ui.GridBufferer{header} } +func (cg *CompactGrid) Clear() { cg.Rows = []ui.GridBufferer{} } func (cg *CompactGrid) GetHeight() int { return len(cg.Rows) } func (cg *CompactGrid) SetX(x int) { cg.X = x } func (cg *CompactGrid) SetY(y int) { cg.Y = y } func (cg *CompactGrid) SetWidth(w int) { cg.Width = w } func (cg *CompactGrid) MaxRows() int { return ui.TermHeight() - header.Height - cg.Y } +func (cg *CompactGrid) pageRows() (rows []ui.GridBufferer) { + rows = append(rows, header) + rows = append(rows, cg.Rows[cg.Offset:]...) + return rows +} + func (cg *CompactGrid) Buffer() ui.Buffer { buf := ui.NewBuffer() - for _, r := range cg.Rows { + for _, r := range cg.pageRows() { buf.Merge(r.Buffer()) } return buf diff --git a/grid.go b/grid.go index ff72b0e..c2cb386 100644 --- a/grid.go +++ b/grid.go @@ -19,20 +19,8 @@ func RedrawRows(clr bool) { } cGrid.SetY(y) - var cursorVisible bool - max := cGrid.MaxRows() - for n, c := range cursor.filtered { - if n >= max { - break - } + for _, c := range cursor.filtered { cGrid.AddRows(c.Widgets) - if c.Id == cursor.selectedID { - cursorVisible = true - } - } - - if !cursorVisible { - cursor.Reset() } if clr { @@ -136,6 +124,7 @@ func Display() bool { ui.Handle("/sys/wnd/resize", func(e ui.Event) { header.Align() + cursor.ScrollPage() cGrid.SetWidth(ui.TermWidth()) log.Infof("resize: width=%v max-rows=%v", cGrid.Width, cGrid.MaxRows()) RedrawRows(true)