summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authordwillist <dthornton@vmware.com>2021-01-12 23:53:52 -0500
committerdwillist <dthornton@vmware.com>2021-01-12 23:53:52 -0500
commitbe945d35019f9604cb4232e558db589626cdda83 (patch)
treec0039efc6a0033a19e53260f4e8abaa162ec136e /runtime
parent92ce00a1a95fd4905e0cf9da5e28bf25133463ed (diff)
updates to layer_primitive
- add custom keybindings - add pagedown functionality (should be factored out evenutally) - add toggleable layer compare modes Signed-off-by: dwillist <dthornton@vmware.com>
Diffstat (limited to 'runtime')
-rw-r--r--runtime/ui/app.go3
-rw-r--r--runtime/ui/components/filetree_primative.go10
-rw-r--r--runtime/ui/components/layers_primative.go127
-rw-r--r--runtime/ui/viewmodels/layers_view_model.go6
-rw-r--r--runtime/ui/viewmodels/tree_view_model.go9
5 files changed, 119 insertions, 36 deletions
diff --git a/runtime/ui/app.go b/runtime/ui/app.go
index b81d2b8..f9bcf5c 100644
--- a/runtime/ui/app.go
+++ b/runtime/ui/app.go
@@ -1,6 +1,7 @@
package ui
import (
+ "os"
"sync"
"github.com/gdamore/tcell/v2"
@@ -67,7 +68,7 @@ func newApp(app *tview.Application, analysis *image.AnalysisResult, cache filetr
filterView := components.NewFilterView(treeViewModel).Setup()
- layersView := components.NewLayerList(treeViewModel).Setup()
+ layersView := components.NewLayerList(treeViewModel).Setup(config)
layersBox := components.NewWrapper("Layers", "subtitle!", layersView).Setup()
fileTreeView := components.NewTreeView(treeViewModel)
diff --git a/runtime/ui/components/filetree_primative.go b/runtime/ui/components/filetree_primative.go
index ce2f015..e593e5e 100644
--- a/runtime/ui/components/filetree_primative.go
+++ b/runtime/ui/components/filetree_primative.go
@@ -50,6 +50,7 @@ func NewTreeView(tree TreeModel) *TreeView {
tree: tree,
globalCollapseAll: true,
showAttributes: true,
+ inputHandler: nil,
}
}
@@ -322,15 +323,14 @@ func (t *TreeView) keyLeft() bool {
return true
}
-// deisred behavior,
-// move the selected cursor 1 screen height up or down, then reset the screen appropriately
+// TODO make all movement rely on a single function (shouldn't be too dificult really)
func (t *TreeView) pageDown() bool {
- // two parts of this are moving both the currently selected item & the window as a whole
_,_,_,height := t.GetInnerRect()
- t.treeIndex = intMin(t.treeIndex + height, t.tree.VisibleSize() -1)
+ visibleSize := t.tree.VisibleSize()
+ t.treeIndex = intMin(t.treeIndex + height, visibleSize)
if t.treeIndex >= t.bufferIndexUpperBound() {
- t.bufferIndexLowerBound = t.treeIndex
+ t.bufferIndexLowerBound = intMin(t.treeIndex, visibleSize - height + 1)
}
return true
}
diff --git a/runtime/ui/components/layers_primative.go b/runtime/ui/components/layers_primative.go
index 5968a6a..c6443be 100644
--- a/runtime/ui/components/layers_primative.go
+++ b/runtime/ui/components/layers_primative.go
@@ -6,11 +6,15 @@ import (
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
"github.com/sirupsen/logrus"
+ "github.com/wagoodman/dive/runtime/ui/viewmodels"
+ "go.uber.org/zap"
)
type LayersViewModel interface {
SetLayerIndex(int) bool
GetPrintableLayers() []fmt.Stringer
+ SwitchMode()
+ GetMode() viewmodels.LayerCompareMode
}
type LayerList struct {
@@ -18,6 +22,7 @@ type LayerList struct {
bufferIndexLowerBound int
cmpIndex int
changed LayerListHandler
+ inputHandler func(event *tcell.EventKey, setFocus func(p tview.Primitive))
LayersViewModel
}
@@ -28,10 +33,66 @@ func NewLayerList(model LayersViewModel) *LayerList {
Box: tview.NewBox(),
cmpIndex: 0,
LayersViewModel: model,
+ inputHandler: nil,
}
}
-func (ll *LayerList) Setup() *LayerList {
+func (ll *LayerList) Setup(config KeyBindingConfig) *LayerList {
+ bindingSettings := map[string]keyAction{
+ "keybinding.page-up": func() bool { return ll.pageUp() },
+ "keybinding.page-down": func() bool { return ll.pageDown() },
+ "keybinding.compare-all": func() bool {
+ if ll.GetMode() == viewmodels.CompareSingleLayer {
+ ll.SwitchMode()
+ return true
+ }
+ return false
+ },
+ "keybinding.compare-layer": func() bool {
+ if ll.GetMode() == viewmodels.CompareAllLayers {
+ ll.SwitchMode()
+ return true
+ }
+ return false
+ },
+ }
+
+ bindingArray := []KeyBinding{}
+ actionArray := []keyAction{}
+
+ for keybinding, action := range bindingSettings {
+ binding, err := config.GetKeyBinding(keybinding)
+ if err != nil {
+ panic(fmt.Errorf("setup error during %s: %w", keybinding, err))
+ // TODO handle this error
+ //return nil
+ }
+ bindingArray = append(bindingArray, binding)
+ actionArray = append(actionArray, action)
+ }
+
+ ll.inputHandler = func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
+ switch event.Key() {
+ case tcell.KeyUp, tcell.KeyLeft:
+ if ll.SetLayerIndex(ll.cmpIndex - 1) {
+ ll.keyUp()
+ //ll.cmpIndex--
+ //logrus.Debugf("KeyUp pressed, index: %d", ll.cmpIndex)
+ }
+ case tcell.KeyDown, tcell.KeyRight:
+ if ll.SetLayerIndex(ll.cmpIndex + 1) {
+ ll.keyDown()
+ //ll.cmpIndex++
+ //logrus.Debugf("KeyUp pressed, index: %d", ll.cmpIndex)
+
+ }
+ }
+ for idx, binding := range bindingArray {
+ if binding.Match(event) {
+ actionArray[idx]()
+ }
+ }
+ }
return ll
}
@@ -62,9 +123,11 @@ func (ll *LayerList) Draw(screen tcell.Screen) {
layer := printableLayers[layerIndex]
var cmpColor tcell.Color
switch {
- case yIndex == ll.cmpIndex:
+ case layerIndex == ll.cmpIndex:
+ cmpColor = tcell.ColorRed
+ case layerIndex > 0 && layerIndex < ll.cmpIndex && ll.GetMode() == viewmodels.CompareAllLayers:
cmpColor = tcell.ColorRed
- case yIndex < ll.cmpIndex:
+ case layerIndex < ll.cmpIndex:
cmpColor = tcell.ColorBlue
default:
cmpColor = tcell.ColorDefault
@@ -76,10 +139,10 @@ func (ll *LayerList) Draw(screen tcell.Screen) {
fg, bg, _ := style.Decompose()
style = style.Background(fg).Foreground(bg)
switch {
- case yIndex == ll.cmpIndex:
+ case layerIndex == ll.cmpIndex:
screen.SetContent(x+xIndex, y+yIndex, m, c, style)
screen.SetContent(x+xIndex, y+yIndex, m, c, style)
- case yIndex < ll.cmpIndex && xIndex < len(cmpString):
+ case layerIndex < ll.cmpIndex && xIndex < len(cmpString):
screen.SetContent(x+xIndex, y+yIndex, m, c, style)
screen.SetContent(x+xIndex, y+yIndex, m, c, style)
default:
@@ -91,23 +154,7 @@ func (ll *LayerList) Draw(screen tcell.Screen) {
}
func (ll *LayerList) InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
- return ll.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
- switch event.Key() {
- case tcell.KeyUp:
- if ll.SetLayerIndex(ll.cmpIndex - 1) {
- ll.keyUp()
- //ll.cmpIndex--
- //logrus.Debugf("KeyUp pressed, index: %d", ll.cmpIndex)
- }
- case tcell.KeyDown:
- if ll.SetLayerIndex(ll.cmpIndex + 1) {
- ll.keyDown()
- //ll.cmpIndex++
- //logrus.Debugf("KeyUp pressed, index: %d", ll.cmpIndex)
-
- }
- }
- })
+ return ll.WrapInputHandler(ll.inputHandler)
}
func (ll *LayerList) Focus(delegate func(p tview.Primitive)) {
@@ -138,19 +185,17 @@ func (ll *LayerList) keyUp() bool {
return true
}
+// TODO (simplify all page increments to rely an a single function)
func (ll *LayerList) keyDown() bool {
_, _, _, height := ll.Box.GetInnerRect()
- adjustedHeight := height - 1
- // treeIndex is the index about where we are in the current file
visibleSize := len(ll.GetPrintableLayers())
- if ll.cmpIndex+1+ll.bufferIndexLowerBound >= visibleSize {
+ if ll.cmpIndex+1 >= visibleSize {
return false
}
- if ll.cmpIndex+1 >= adjustedHeight {
+ ll.cmpIndex++
+ if ll.cmpIndex-ll.bufferIndexLowerBound >= height {
ll.bufferIndexLowerBound++
- } else {
- ll.cmpIndex++
}
logrus.Debugln("keyDown in layers")
logrus.Debugf(" cmpIndex: %d", ll.cmpIndex)
@@ -158,3 +203,29 @@ func (ll *LayerList) keyDown() bool {
return true
}
+
+func (ll *LayerList) pageUp() bool {
+ zap.S().Info("layer page up call")
+ _, _, _, height := ll.Box.GetInnerRect()
+
+ ll.cmpIndex = intMax(0, ll.cmpIndex-height)
+ if ll.cmpIndex < ll.bufferIndexLowerBound {
+ ll.bufferIndexLowerBound = ll.cmpIndex
+ }
+
+ return ll.SetLayerIndex(ll.cmpIndex)
+}
+
+func (ll *LayerList) pageDown() bool {
+ zap.S().Info("layer page down call")
+ // two parts of this are moving both the currently selected item & the window as a whole
+
+ _, _, _, height := ll.Box.GetInnerRect()
+ upperBoundIndex := len(ll.GetPrintableLayers()) - 1
+ ll.cmpIndex = intMin(ll.cmpIndex+height, upperBoundIndex)
+ if ll.cmpIndex >= ll.bufferIndexLowerBound+height {
+ ll.bufferIndexLowerBound = intMin(ll.cmpIndex, upperBoundIndex-height+1)
+ }
+
+ return ll.SetLayerIndex(ll.cmpIndex)
+}
diff --git a/runtime/ui/viewmodels/layers_view_model.go b/runtime/ui/viewmodels/layers_view_model.go
index 4418152..8ebeafe 100644
--- a/runtime/ui/viewmodels/layers_view_model.go
+++ b/runtime/ui/viewmodels/layers_view_model.go
@@ -46,10 +46,14 @@ func (lm *LayersViewModel) GetCompareIndicies() filetree.TreeIndexKey {
bottomStart := 0
bottomStop := 0
+ topStart := lm.index
if lm.mode == CompareSingleLayer {
bottomStop = intMax(lm.index-1, 0)
+ } else {
+ topStart = 1
}
- return filetree.NewTreeIndexKey(bottomStart, bottomStop, lm.index, lm.index)
+
+ return filetree.NewTreeIndexKey(bottomStart, bottomStop, topStart, lm.index)
}
func (lm *LayersViewModel) SetLayerIndex(index int) bool {
diff --git a/runtime/ui/viewmodels/tree_view_model.go b/runtime/ui/viewmodels/tree_view_model.go
index 462540e..9e004ec 100644
--- a/runtime/ui/viewmodels/tree_view_model.go
+++ b/runtime/ui/viewmodels/tree_view_model.go
@@ -20,6 +20,8 @@ type LayersModel interface {
GetCompareIndicies() filetree.TreeIndexKey
GetCurrentLayer() *image.Layer
GetPrintableLayers() []fmt.Stringer
+ GetMode() LayerCompareMode
+ SwitchMode()
}
type TreeViewModel struct {
@@ -118,7 +120,6 @@ func (tvm *TreeViewModel) FilterUpdate() error {
}
// Override functions
-
func (tvm *TreeViewModel) SetLayerIndex(index int) bool {
if tvm.LayersModel.SetLayerIndex(index) {
err := tvm.setCurrentTree(tvm.GetCompareIndicies())
@@ -167,3 +168,9 @@ func (tvm *TreeViewModel) setCurrentTree(key filetree.TreeIndexKey) error {
}
return nil
}
+
+func (tvm *TreeViewModel) SwitchMode() {
+ tvm.LayersModel.SwitchMode()
+ // TODO: Handle this error
+ tvm.setCurrentTree(tvm.GetCompareIndicies())
+}