2017-03-06 03:03:05 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2017-03-28 03:57:30 +00:00
|
|
|
"math"
|
|
|
|
|
2017-03-06 03:03:05 +00:00
|
|
|
ui "github.com/gizak/termui"
|
|
|
|
)
|
|
|
|
|
|
|
|
type GridCursor struct {
|
|
|
|
selectedID string // id of currently selected container
|
2017-03-08 00:46:39 +00:00
|
|
|
filtered Containers
|
2017-03-06 03:03:05 +00:00
|
|
|
cSource ContainerSource
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewGridCursor() *GridCursor {
|
|
|
|
return &GridCursor{
|
|
|
|
cSource: NewDockerContainerSource(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-09 23:09:58 +00:00
|
|
|
func (gc *GridCursor) Len() int { return len(gc.filtered) }
|
|
|
|
|
|
|
|
func (gc *GridCursor) Selected() *Container {
|
|
|
|
idx := gc.Idx()
|
|
|
|
if idx < gc.Len() {
|
|
|
|
return gc.filtered[idx]
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2017-03-06 03:03:05 +00:00
|
|
|
|
2017-03-08 00:10:38 +00:00
|
|
|
// Refresh containers from source
|
|
|
|
func (gc *GridCursor) RefreshContainers() (lenChanged bool) {
|
|
|
|
oldLen := gc.Len()
|
2017-03-06 03:03:05 +00:00
|
|
|
|
2017-03-08 00:46:39 +00:00
|
|
|
// Containers filtered by display bool
|
|
|
|
gc.filtered = Containers{}
|
2017-03-08 07:45:31 +00:00
|
|
|
var cursorVisible bool
|
|
|
|
for _, c := range gc.cSource.All() {
|
2017-03-08 00:46:39 +00:00
|
|
|
if c.display {
|
2017-03-08 07:45:31 +00:00
|
|
|
if c.Id == gc.selectedID {
|
|
|
|
cursorVisible = true
|
|
|
|
}
|
2017-03-08 00:46:39 +00:00
|
|
|
gc.filtered = append(gc.filtered, c)
|
|
|
|
}
|
|
|
|
}
|
2017-03-08 07:45:31 +00:00
|
|
|
|
|
|
|
if oldLen != gc.Len() {
|
|
|
|
lenChanged = true
|
|
|
|
}
|
|
|
|
|
|
|
|
if !cursorVisible {
|
|
|
|
gc.Reset()
|
|
|
|
}
|
|
|
|
if gc.selectedID == "" {
|
|
|
|
gc.Reset()
|
|
|
|
}
|
|
|
|
return lenChanged
|
2017-03-08 00:46:39 +00:00
|
|
|
}
|
|
|
|
|
2017-03-06 03:03:05 +00:00
|
|
|
// Set an initial cursor position, if possible
|
|
|
|
func (gc *GridCursor) Reset() {
|
2017-03-08 07:45:31 +00:00
|
|
|
for _, c := range gc.cSource.All() {
|
2017-03-08 00:46:39 +00:00
|
|
|
c.Widgets.Name.UnHighlight()
|
|
|
|
}
|
2017-03-06 03:03:05 +00:00
|
|
|
if gc.Len() > 0 {
|
2017-03-08 07:45:31 +00:00
|
|
|
gc.selectedID = gc.filtered[0].Id
|
|
|
|
gc.filtered[0].Widgets.Name.Highlight()
|
2017-03-06 03:03:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return current cursor index
|
|
|
|
func (gc *GridCursor) Idx() int {
|
2017-03-08 07:45:31 +00:00
|
|
|
for n, c := range gc.filtered {
|
2017-03-06 03:03:05 +00:00
|
|
|
if c.Id == gc.selectedID {
|
|
|
|
return n
|
|
|
|
}
|
|
|
|
}
|
2017-03-08 07:45:31 +00:00
|
|
|
gc.Reset()
|
2017-03-06 03:03:05 +00:00
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2017-03-08 07:45:31 +00:00
|
|
|
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()
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-03-06 03:03:05 +00:00
|
|
|
func (gc *GridCursor) Up() {
|
|
|
|
idx := gc.Idx()
|
2017-03-08 07:45:31 +00:00
|
|
|
if idx <= 0 { // already at top
|
2017-03-06 03:03:05 +00:00
|
|
|
return
|
|
|
|
}
|
2017-03-08 07:45:31 +00:00
|
|
|
active := gc.filtered[idx]
|
|
|
|
next := gc.filtered[idx-1]
|
2017-03-06 03:03:05 +00:00
|
|
|
|
|
|
|
active.Widgets.Name.UnHighlight()
|
|
|
|
gc.selectedID = next.Id
|
|
|
|
next.Widgets.Name.Highlight()
|
|
|
|
|
2017-03-08 07:45:31 +00:00
|
|
|
gc.ScrollPage()
|
2017-03-06 03:03:05 +00:00
|
|
|
ui.Render(cGrid)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (gc *GridCursor) Down() {
|
|
|
|
idx := gc.Idx()
|
2017-03-08 07:45:31 +00:00
|
|
|
if idx >= gc.Len()-1 { // already at bottom
|
2017-03-06 03:03:05 +00:00
|
|
|
return
|
|
|
|
}
|
2017-03-08 07:45:31 +00:00
|
|
|
active := gc.filtered[idx]
|
|
|
|
next := gc.filtered[idx+1]
|
2017-03-06 03:03:05 +00:00
|
|
|
|
|
|
|
active.Widgets.Name.UnHighlight()
|
|
|
|
gc.selectedID = next.Id
|
|
|
|
next.Widgets.Name.Highlight()
|
2017-03-08 07:45:31 +00:00
|
|
|
|
|
|
|
gc.ScrollPage()
|
2017-03-06 03:03:05 +00:00
|
|
|
ui.Render(cGrid)
|
|
|
|
}
|
2017-03-24 02:31:08 +00:00
|
|
|
|
|
|
|
func (gc *GridCursor) PgUp() {
|
2017-03-28 03:57:30 +00:00
|
|
|
idx := gc.Idx()
|
2017-03-24 02:31:08 +00:00
|
|
|
if idx <= 0 { // already at top
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var nextidx int
|
2017-03-28 03:57:30 +00:00
|
|
|
nextidx = int(math.Max(0.0, float64(idx-cGrid.MaxRows())))
|
|
|
|
cGrid.Offset = int(math.Max(float64(cGrid.Offset-cGrid.MaxRows()),
|
2017-03-24 02:31:08 +00:00
|
|
|
float64(0)))
|
|
|
|
|
|
|
|
active := gc.filtered[idx]
|
2017-03-28 03:57:30 +00:00
|
|
|
next := gc.filtered[nextidx]
|
2017-03-24 02:31:08 +00:00
|
|
|
|
|
|
|
active.Widgets.Name.UnHighlight()
|
|
|
|
gc.selectedID = next.Id
|
|
|
|
next.Widgets.Name.Highlight()
|
2017-03-28 03:57:30 +00:00
|
|
|
|
2017-03-24 02:31:08 +00:00
|
|
|
cGrid.Align()
|
|
|
|
ui.Render(cGrid)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (gc *GridCursor) PgDown() {
|
2017-03-28 03:57:30 +00:00
|
|
|
idx := gc.Idx()
|
2017-03-24 02:31:08 +00:00
|
|
|
if idx >= gc.Len()-1 { // already at bottom
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var nextidx int
|
2017-03-28 03:57:30 +00:00
|
|
|
nextidx = int(math.Min(float64(gc.Len()-1),
|
|
|
|
float64(idx+cGrid.MaxRows())))
|
|
|
|
cGrid.Offset = int(math.Min(float64(cGrid.Offset+cGrid.MaxRows()),
|
|
|
|
float64(gc.Len()-cGrid.MaxRows())))
|
2017-03-24 02:31:08 +00:00
|
|
|
|
|
|
|
active := gc.filtered[idx]
|
2017-03-28 03:57:30 +00:00
|
|
|
next := gc.filtered[nextidx]
|
2017-03-24 02:31:08 +00:00
|
|
|
|
|
|
|
active.Widgets.Name.UnHighlight()
|
|
|
|
gc.selectedID = next.Id
|
|
|
|
next.Widgets.Name.Highlight()
|
|
|
|
|
|
|
|
cGrid.Align()
|
|
|
|
ui.Render(cGrid)
|
2017-03-28 03:57:30 +00:00
|
|
|
}
|