diff options
Diffstat (limited to 'runtime/ui/viewmodel')
-rw-r--r-- | runtime/ui/viewmodel/filetree.go | 55 | ||||
-rw-r--r-- | runtime/ui/viewmodel/filetree_test.go | 4 |
2 files changed, 33 insertions, 26 deletions
diff --git a/runtime/ui/viewmodel/filetree.go b/runtime/ui/viewmodel/filetree.go index d0172d4..8734eaf 100644 --- a/runtime/ui/viewmodel/filetree.go +++ b/runtime/ui/viewmodel/filetree.go @@ -16,7 +16,7 @@ import ( // FileTreeViewModel holds the UI objects and data models for populating the right pane. Specifically the pane that // shows selected layer or aggregate file ASCII tree. -type FileTree struct { +type FileTreeViewModel struct { ModelTree *filetree.FileTree ViewTree *filetree.FileTree RefTrees []*filetree.FileTree @@ -39,8 +39,8 @@ type FileTree struct { } // NewFileTreeViewModel creates a new view object attached the the global [gocui] screen object. -func NewFileTreeViewModel(tree *filetree.FileTree, refTrees []*filetree.FileTree, cache filetree.Comparer) (treeViewModel *FileTree, err error) { - treeViewModel = new(FileTree) +func NewFileTreeViewModel(tree *filetree.FileTree, refTrees []*filetree.FileTree, cache filetree.Comparer) (treeViewModel *FileTreeViewModel, err error) { + treeViewModel = new(FileTreeViewModel) // populate main fields treeViewModel.ShowAttributes = viper.GetBool("filetree.show-attributes") @@ -71,13 +71,13 @@ func NewFileTreeViewModel(tree *filetree.FileTree, refTrees []*filetree.FileTree } // Setup initializes the UI concerns within the context of a global [gocui] view object. -func (vm *FileTree) Setup(lowerBound, height int) { +func (vm *FileTreeViewModel) Setup(lowerBound, height int) { vm.bufferIndexLowerBound = lowerBound vm.refHeight = height } // height returns the current height and considers the header -func (vm *FileTree) height() int { +func (vm *FileTreeViewModel) height() int { if vm.ShowAttributes { return vm.refHeight - 1 } @@ -85,24 +85,24 @@ func (vm *FileTree) height() int { } // bufferIndexUpperBound returns the current upper bounds for the view -func (vm *FileTree) bufferIndexUpperBound() int { +func (vm *FileTreeViewModel) bufferIndexUpperBound() int { return vm.bufferIndexLowerBound + vm.height() } // IsVisible indicates if the file tree view pane is currently initialized -func (vm *FileTree) IsVisible() bool { +func (vm *FileTreeViewModel) IsVisible() bool { return vm != nil } // ResetCursor moves the cursor back to the top of the buffer and translates to the top of the buffer. -func (vm *FileTree) ResetCursor() { +func (vm *FileTreeViewModel) ResetCursor() { vm.TreeIndex = 0 vm.bufferIndex = 0 vm.bufferIndexLowerBound = 0 } // SetTreeByLayer populates the view model by stacking the indicated image layer file trees. -func (vm *FileTree) SetTreeByLayer(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop int) error { +func (vm *FileTreeViewModel) SetTreeByLayer(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop int) error { if topTreeStop > len(vm.RefTrees)-1 { return fmt.Errorf("invalid layer index given: %d of %d", topTreeStop, len(vm.RefTrees)-1) } @@ -131,7 +131,7 @@ func (vm *FileTree) SetTreeByLayer(bottomTreeStart, bottomTreeStop, topTreeStart } // doCursorUp performs the internal view's buffer adjustments on cursor up. Note: this is independent of the gocui buffer. -func (vm *FileTree) CursorUp() bool { +func (vm *FileTreeViewModel) CursorUp() bool { if vm.TreeIndex <= 0 { return false } @@ -146,7 +146,7 @@ func (vm *FileTree) CursorUp() bool { } // doCursorDown performs the internal view's buffer adjustments on cursor down. Note: this is independent of the gocui buffer. -func (vm *FileTree) CursorDown() bool { +func (vm *FileTreeViewModel) CursorDown() bool { if vm.TreeIndex >= vm.ModelTree.VisibleSize() { return false } @@ -162,7 +162,7 @@ func (vm *FileTree) CursorDown() bool { } // CursorLeft moves the cursor up until we reach the Parent Node or top of the tree -func (vm *FileTree) CursorLeft(filterRegex *regexp.Regexp) error { +func (vm *FileTreeViewModel) CursorLeft(filterRegex *regexp.Regexp) error { var visitor func(*filetree.FileNode) error var evaluator func(*filetree.FileNode) bool var dfsCounter, newIndex int @@ -213,7 +213,7 @@ func (vm *FileTree) CursorLeft(filterRegex *regexp.Regexp) error { } // CursorRight descends into directory expanding it if needed -func (vm *FileTree) CursorRight(filterRegex *regexp.Regexp) error { +func (vm *FileTreeViewModel) CursorRight(filterRegex *regexp.Regexp) error { node := vm.getAbsPositionNode(filterRegex) if node == nil { return nil @@ -245,7 +245,7 @@ func (vm *FileTree) CursorRight(filterRegex *regexp.Regexp) error { } // PageDown moves to next page putting the cursor on top -func (vm *FileTree) PageDown() error { +func (vm *FileTreeViewModel) PageDown() error { nextBufferIndexLowerBound := vm.bufferIndexLowerBound + vm.height() nextBufferIndexUpperBound := nextBufferIndexLowerBound + vm.height() @@ -271,7 +271,7 @@ func (vm *FileTree) PageDown() error { } // PageUp moves to previous page putting the cursor on top -func (vm *FileTree) PageUp() error { +func (vm *FileTreeViewModel) PageUp() error { nextBufferIndexLowerBound := vm.bufferIndexLowerBound - vm.height() nextBufferIndexUpperBound := nextBufferIndexLowerBound + vm.height() @@ -296,7 +296,7 @@ func (vm *FileTree) PageUp() error { } // getAbsPositionNode determines the selected screen cursor's location in the file tree, returning the selected FileNode. -func (vm *FileTree) getAbsPositionNode(filterRegex *regexp.Regexp) (node *filetree.FileNode) { +func (vm *FileTreeViewModel) getAbsPositionNode(filterRegex *regexp.Regexp) (node *filetree.FileNode) { var visitor func(*filetree.FileNode) error var evaluator func(*filetree.FileNode) bool var dfsCounter int @@ -327,7 +327,7 @@ func (vm *FileTree) getAbsPositionNode(filterRegex *regexp.Regexp) (node *filetr } // ToggleCollapse will collapse/expand the selected FileNode. -func (vm *FileTree) ToggleCollapse(filterRegex *regexp.Regexp) error { +func (vm *FileTreeViewModel) ToggleCollapse(filterRegex *regexp.Regexp) error { node := vm.getAbsPositionNode(filterRegex) if node != nil && node.Data.FileInfo.IsDir { node.Data.ViewInfo.Collapsed = !node.Data.ViewInfo.Collapsed @@ -336,7 +336,7 @@ func (vm *FileTree) ToggleCollapse(filterRegex *regexp.Regexp) error { } // ToggleCollapseAll will collapse/expand the all directories. -func (vm *FileTree) ToggleCollapseAll() error { +func (vm *FileTreeViewModel) ToggleCollapseAll() error { vm.CollapseAll = !vm.CollapseAll visitor := func(curNode *filetree.FileNode) error { @@ -356,7 +356,14 @@ func (vm *FileTree) ToggleCollapseAll() error { return nil } -func (vm *FileTree) ConstrainLayout() { +// ToggleSortOrder will toggle the sort order in which files are displayed +func (vm *FileTreeViewModel) ToggleSortOrder() error { + vm.ModelTree.SortOrder = (vm.ModelTree.SortOrder + 1) % filetree.NumSortOrderConventions + + return nil +} + +func (vm *FileTreeViewModel) ConstrainLayout() { if !vm.constrainedRealEstate { logrus.Debugf("constraining filetree layout") vm.constrainedRealEstate = true @@ -365,7 +372,7 @@ func (vm *FileTree) ConstrainLayout() { } } -func (vm *FileTree) ExpandLayout() { +func (vm *FileTreeViewModel) ExpandLayout() { if vm.constrainedRealEstate { logrus.Debugf("expanding filetree layout") vm.ShowAttributes = vm.unconstrainedShowAttributes @@ -374,7 +381,7 @@ func (vm *FileTree) ExpandLayout() { } // ToggleCollapse will collapse/expand the selected FileNode. -func (vm *FileTree) ToggleAttributes() error { +func (vm *FileTreeViewModel) ToggleAttributes() error { // ignore any attempt to show the attributes when the layout is constrained if vm.constrainedRealEstate { return nil @@ -384,12 +391,12 @@ func (vm *FileTree) ToggleAttributes() error { } // ToggleShowDiffType will show/hide the selected DiffType in the filetree pane. -func (vm *FileTree) ToggleShowDiffType(diffType filetree.DiffType) { +func (vm *FileTreeViewModel) ToggleShowDiffType(diffType filetree.DiffType) { vm.HiddenDiffTypes[diffType] = !vm.HiddenDiffTypes[diffType] } // Update refreshes the state objects for future rendering. -func (vm *FileTree) Update(filterRegex *regexp.Regexp, width, height int) error { +func (vm *FileTreeViewModel) Update(filterRegex *regexp.Regexp, width, height int) error { vm.refWidth = width vm.refHeight = height @@ -437,7 +444,7 @@ func (vm *FileTree) Update(filterRegex *regexp.Regexp, width, height int) error } // Render flushes the state objects (file tree) to the pane. -func (vm *FileTree) Render() error { +func (vm *FileTreeViewModel) Render() error { treeString := vm.ViewTree.StringBetween(vm.bufferIndexLowerBound, vm.bufferIndexUpperBound(), vm.ShowAttributes) lines := strings.Split(treeString, "\n") diff --git a/runtime/ui/viewmodel/filetree_test.go b/runtime/ui/viewmodel/filetree_test.go index 668eb1e..f315b41 100644 --- a/runtime/ui/viewmodel/filetree_test.go +++ b/runtime/ui/viewmodel/filetree_test.go @@ -73,7 +73,7 @@ func assertTestData(t *testing.T, actualBytes []byte) { helperCheckDiff(t, expectedBytes, actualBytes) } -func initializeTestViewModel(t *testing.T) *FileTree { +func initializeTestViewModel(t *testing.T) *FileTreeViewModel { result := docker.TestAnalysisFromArchive(t, "../../../.data/test-docker-image.tar") cache := filetree.NewComparer(result.RefTrees) @@ -98,7 +98,7 @@ func initializeTestViewModel(t *testing.T) *FileTree { return vm } -func runTestCase(t *testing.T, vm *FileTree, width, height int, filterRegex *regexp.Regexp) { +func runTestCase(t *testing.T, vm *FileTreeViewModel, width, height int, filterRegex *regexp.Regexp) { err := vm.Update(filterRegex, width, height) if err != nil { t.Errorf("failed to update viewmodel: %v", err) |