mirror of
https://github.com/wagoodman/dive
synced 2024-05-30 10:42:12 +02:00
basic pane swap working
This commit is contained in:
parent
b46180936e
commit
91d58ab09d
|
@ -73,6 +73,7 @@ func initConfig() {
|
|||
viper.SetDefault("keybinding.quit", "ctrl+c")
|
||||
viper.SetDefault("keybinding.toggle-view", "tab")
|
||||
viper.SetDefault("keybinding.filter-files", "ctrl+f, ctrl+slash")
|
||||
viper.SetDefault("keybinding.toggle-details", "ctrl+d")
|
||||
// keybindings: layer view
|
||||
viper.SetDefault("keybinding.compare-all", "ctrl+a")
|
||||
viper.SetDefault("keybinding.compare-layer", "ctrl+l")
|
||||
|
|
|
@ -16,9 +16,10 @@ const debug = false
|
|||
|
||||
// type global
|
||||
type app struct {
|
||||
gui *gocui.Gui
|
||||
controllers *Controller
|
||||
layout *layout.Manager
|
||||
gui *gocui.Gui
|
||||
controller *Controller
|
||||
layout *layout.Manager
|
||||
detailedMode bool
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -32,7 +33,7 @@ func newApp(gui *gocui.Gui, analysis *image.AnalysisResult, cache filetree.Compa
|
|||
var controller *Controller
|
||||
var globalHelpKeys []*key.Binding
|
||||
|
||||
controller, err = NewCollection(gui, analysis, cache)
|
||||
controller, err = NewController(gui, analysis, cache)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -59,9 +60,10 @@ func newApp(gui *gocui.Gui, analysis *image.AnalysisResult, cache filetree.Compa
|
|||
// }
|
||||
|
||||
appSingleton = &app{
|
||||
gui: gui,
|
||||
controllers: controller,
|
||||
layout: lm,
|
||||
gui: gui,
|
||||
controller: controller,
|
||||
layout: lm,
|
||||
detailedMode: false,
|
||||
}
|
||||
|
||||
var infos = []key.BindingInfo{
|
||||
|
@ -90,6 +92,19 @@ func newApp(gui *gocui.Gui, analysis *image.AnalysisResult, cache filetree.Compa
|
|||
|
||||
controller.views.Status.AddHelpKeys(globalHelpKeys...)
|
||||
|
||||
// dont show these key bindings on the status pane
|
||||
quietKeys := []key.BindingInfo{
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.toggle-details"},
|
||||
OnAction: appSingleton.toggleDetails,
|
||||
Display: "",
|
||||
},
|
||||
}
|
||||
_, err = key.GenerateBindings(gui, "", quietKeys)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// perform the first update and render now that all resources have been loaded
|
||||
err = controller.UpdateAndRender()
|
||||
if err != nil {
|
||||
|
@ -106,8 +121,8 @@ func newApp(gui *gocui.Gui, analysis *image.AnalysisResult, cache filetree.Compa
|
|||
|
||||
// debugPrint writes the given string to the debug pane (if the debug pane is enabled)
|
||||
// func debugPrint(s string) {
|
||||
// if controllers.Tree != nil && controllers.Tree.gui != nil {
|
||||
// v, _ := controllers.Tree.gui.View("debug")
|
||||
// if controller.Tree != nil && controller.Tree.gui != nil {
|
||||
// v, _ := controller.Tree.gui.View("debug")
|
||||
// if v != nil {
|
||||
// if len(v.BufferLines()) > 20 {
|
||||
// v.Clear()
|
||||
|
@ -126,6 +141,39 @@ func (a *app) quit() error {
|
|||
return gocui.ErrQuit
|
||||
}
|
||||
|
||||
func (a *app) toggleDetails() error {
|
||||
if a.detailedMode {
|
||||
err := a.layout.Remove(a.controller.views.Debug)
|
||||
if err != nil {
|
||||
logrus.Errorf("could not remove DEBUG pane")
|
||||
}
|
||||
a.layout.Add(a.controller.views.Tree, layout.LocationColumn)
|
||||
a.controller.views.Debug.ToggleHide()
|
||||
a.controller.views.Tree.ToggleHide()
|
||||
|
||||
a.controller.views.Status.Retop()
|
||||
a.controller.views.Filter.Retop()
|
||||
|
||||
a.detailedMode = false
|
||||
} else {
|
||||
err := a.layout.Remove(a.controller.views.Tree)
|
||||
if err != nil {
|
||||
logrus.Errorf("could not remove TREE pane")
|
||||
}
|
||||
a.layout.Add(a.controller.views.Debug, layout.LocationColumn)
|
||||
a.controller.views.Debug.ToggleHide()
|
||||
a.controller.views.Tree.ToggleHide()
|
||||
|
||||
a.controller.views.Status.Retop()
|
||||
a.controller.views.Filter.Retop()
|
||||
|
||||
a.detailedMode = true
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
// Run is the UI entrypoint.
|
||||
func Run(analysis *image.AnalysisResult, treeStack filetree.Comparer) error {
|
||||
var err error
|
||||
|
|
|
@ -13,9 +13,10 @@ import (
|
|||
type Controller struct {
|
||||
gui *gocui.Gui
|
||||
views *view.Views
|
||||
|
||||
}
|
||||
|
||||
func NewCollection(g *gocui.Gui, analysis *image.AnalysisResult, cache filetree.Comparer) (*Controller, error) {
|
||||
func NewController(g *gocui.Gui, analysis *image.AnalysisResult, cache filetree.Comparer) (*Controller, error) {
|
||||
views, err := view.NewViews(g, analysis, cache)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -65,7 +65,11 @@ func RenderNoHeader(width int, selected bool) string {
|
|||
return strings.Repeat(fillStr, width)
|
||||
}
|
||||
|
||||
func RenderHeader(title string, width int, selected bool) string {
|
||||
func RenderHeader(title string, width int, selected bool, nl bool) string {
|
||||
newLine := "\n"
|
||||
if !nl{
|
||||
newLine = ""
|
||||
}
|
||||
if selected {
|
||||
body := Header(fmt.Sprintf("%s%s ", selectStr, title))
|
||||
bodyLen := len(vtclean.Clean(body, false))
|
||||
|
@ -73,7 +77,7 @@ func RenderHeader(title string, width int, selected bool) string {
|
|||
if repeatCount < 0 {
|
||||
repeatCount = 0
|
||||
}
|
||||
return fmt.Sprintf("%s%s%s%s\n", selectedLeftBracketStr, body, selectedRightBracketStr, strings.Repeat(selectedFillStr, repeatCount))
|
||||
return fmt.Sprintf("%s%s%s%s%s", selectedLeftBracketStr, body, selectedRightBracketStr, strings.Repeat(selectedFillStr, repeatCount), newLine)
|
||||
//return fmt.Sprintf("%s%s%s%s\n", Selected(selectedLeftBracketStr), body, Selected(selectedRightBracketStr), Selected(strings.Repeat(selectedFillStr, width-bodyLen-2)))
|
||||
//return fmt.Sprintf("%s%s%s%s\n", Selected(selectedLeftBracketStr), body, Selected(selectedRightBracketStr), strings.Repeat(selectedFillStr, width-bodyLen-2))
|
||||
}
|
||||
|
@ -83,7 +87,7 @@ func RenderHeader(title string, width int, selected bool) string {
|
|||
if repeatCount < 0 {
|
||||
repeatCount = 0
|
||||
}
|
||||
return fmt.Sprintf("%s%s%s%s\n", leftBracketStr, body, rightBracketStr, strings.Repeat(fillStr, repeatCount))
|
||||
return fmt.Sprintf("%s%s%s%s%s", leftBracketStr, body, rightBracketStr, strings.Repeat(fillStr, repeatCount), newLine)
|
||||
}
|
||||
|
||||
func RenderHelpKey(control, title string, selected bool) string {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package layout
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/jroimartin/gocui"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
@ -26,6 +27,22 @@ func (lm *Manager) Add(element Layout, location Location) {
|
|||
lm.elements[location] = append(lm.elements[location], element)
|
||||
}
|
||||
|
||||
func (lm *Manager) Remove(element Layout) error {
|
||||
for location, elements := range lm.elements {
|
||||
idx := -1
|
||||
for i, el := range elements {
|
||||
if el == element {
|
||||
idx = i
|
||||
}
|
||||
}
|
||||
if idx >= 0 {
|
||||
lm.elements[location] = append(elements[:idx], elements[idx+1:]...)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("could not remove element from layout manager")
|
||||
}
|
||||
|
||||
func (lm *Manager) planAndLayoutHeaders(g *gocui.Gui, area Area) (Area, error) {
|
||||
// layout headers top down
|
||||
if elements, exists := lm.elements[LocationHeader]; exists {
|
||||
|
|
|
@ -14,6 +14,8 @@ type Debug struct {
|
|||
gui *gocui.Gui
|
||||
view *gocui.View
|
||||
header *gocui.View
|
||||
//once sync.Once
|
||||
hidden bool
|
||||
|
||||
selectedView Helper
|
||||
}
|
||||
|
@ -25,6 +27,7 @@ func newDebugView(gui *gocui.Gui) (controller *Debug) {
|
|||
// populate main fields
|
||||
controller.name = "debug"
|
||||
controller.gui = gui
|
||||
controller.hidden = true
|
||||
|
||||
return controller
|
||||
}
|
||||
|
@ -37,6 +40,29 @@ func (v *Debug) Name() string {
|
|||
return v.name
|
||||
}
|
||||
|
||||
func (v *Debug) ToggleHide() error {
|
||||
v.hidden = !v.hidden
|
||||
if v.hidden {
|
||||
logrus.Trace("hiding debug view...")
|
||||
|
||||
// take note: deleting a view will invoke layout again, so ensure this call is protected from an infinite loop
|
||||
err := v.gui.DeleteView(v.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// take note: deleting a view will invoke layout again, so ensure this call is protected from an infinite loop
|
||||
err = v.gui.DeleteView(v.Name() + "header")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Debug) IsHidden() bool {
|
||||
return v.hidden
|
||||
}
|
||||
|
||||
// Setup initializes the UI concerns within the context of a global [gocui] view object.
|
||||
func (v *Debug) Setup(view *gocui.View, header *gocui.View) error {
|
||||
logrus.Tracef("view.Setup() %s", v.Name())
|
||||
|
@ -82,7 +108,7 @@ func (v *Debug) Render() error {
|
|||
// update header...
|
||||
v.header.Clear()
|
||||
width, _ := g.Size()
|
||||
headerStr := format.RenderHeader("Debug", width, false)
|
||||
headerStr := format.RenderHeader("Debug", width, false, false)
|
||||
_, _ = fmt.Fprintln(v.header, headerStr)
|
||||
|
||||
// update view...
|
||||
|
@ -98,7 +124,7 @@ func (v *Debug) Render() error {
|
|||
}
|
||||
|
||||
func (v *Debug) Layout(g *gocui.Gui, minX, minY, maxX, maxY int) error {
|
||||
logrus.Tracef("view.Layout(minX: %d, minY: %d, maxX: %d, maxY: %d) %s", minX, minY, maxX, maxY, v.Name())
|
||||
logrus.Tracef("view.Layout(minX: %d, minY: %d, maxX: %d, maxY: %d, hidden: %v) %s", minX, minY, maxX, maxY, v.hidden, v.Name())
|
||||
|
||||
// header
|
||||
headerSize := 1
|
||||
|
|
|
@ -157,8 +157,8 @@ func (v *Details) Render() error {
|
|||
v.header.Clear()
|
||||
width, _ := v.view.Size()
|
||||
|
||||
layerHeaderStr := format.RenderHeader("Layer Details", width, false)
|
||||
imageHeaderStr := format.RenderHeader("Image Details", width, false)
|
||||
layerHeaderStr := format.RenderHeader("Layer Details", width, false, false)
|
||||
imageHeaderStr := format.RenderHeader("Image", width, false, false)
|
||||
|
||||
_, err := fmt.Fprintln(v.header, layerHeaderStr)
|
||||
if err != nil {
|
||||
|
@ -182,7 +182,8 @@ func (v *Details) Render() error {
|
|||
lines = append(lines, imageSizeStr)
|
||||
lines = append(lines, wastedSpaceStr)
|
||||
lines = append(lines, effStr+"\n")
|
||||
lines = append(lines, inefficiencyReport)
|
||||
lines = append(lines, format.Header("[^D for detailed image information]"))
|
||||
//lines = append(lines, inefficiencyReport)
|
||||
|
||||
_, err = fmt.Fprintln(v.view, strings.Join(lines, "\n"))
|
||||
if err != nil {
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/wagoodman/dive/runtime/ui/viewmodel"
|
||||
"github.com/wagoodman/dive/utils"
|
||||
"regexp"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type ViewOptionChangeListener func() error
|
||||
|
@ -22,6 +23,8 @@ type FileTree struct {
|
|||
gui *gocui.Gui
|
||||
view *gocui.View
|
||||
header *gocui.View
|
||||
once sync.Once
|
||||
hidden bool
|
||||
vm *viewmodel.FileTree
|
||||
title string
|
||||
|
||||
|
@ -73,6 +76,7 @@ func (v *FileTree) Name() string {
|
|||
// Setup initializes the UI concerns within the context of a global [gocui] view object.
|
||||
func (v *FileTree) Setup(view *gocui.View, header *gocui.View) error {
|
||||
logrus.Tracef("view.Setup() %s", v.Name())
|
||||
var err error
|
||||
|
||||
// set controller options
|
||||
v.view = view
|
||||
|
@ -85,89 +89,90 @@ func (v *FileTree) Setup(view *gocui.View, header *gocui.View) error {
|
|||
v.header.Wrap = false
|
||||
v.header.Frame = false
|
||||
|
||||
var infos = []key.BindingInfo{
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.toggle-collapse-dir"},
|
||||
OnAction: v.toggleCollapse,
|
||||
Display: "Collapse dir",
|
||||
},
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.toggle-collapse-all-dir"},
|
||||
OnAction: v.toggleCollapseAll,
|
||||
Display: "Collapse all dir",
|
||||
},
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.toggle-added-files"},
|
||||
OnAction: func() error { return v.toggleShowDiffType(filetree.Added) },
|
||||
IsSelected: func() bool { return !v.vm.HiddenDiffTypes[filetree.Added] },
|
||||
Display: "Added",
|
||||
},
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.toggle-removed-files"},
|
||||
OnAction: func() error { return v.toggleShowDiffType(filetree.Removed) },
|
||||
IsSelected: func() bool { return !v.vm.HiddenDiffTypes[filetree.Removed] },
|
||||
Display: "Removed",
|
||||
},
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.toggle-modified-files"},
|
||||
OnAction: func() error { return v.toggleShowDiffType(filetree.Modified) },
|
||||
IsSelected: func() bool { return !v.vm.HiddenDiffTypes[filetree.Modified] },
|
||||
Display: "Modified",
|
||||
},
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.toggle-unchanged-files", "keybinding.toggle-unmodified-files"},
|
||||
OnAction: func() error { return v.toggleShowDiffType(filetree.Unmodified) },
|
||||
IsSelected: func() bool { return !v.vm.HiddenDiffTypes[filetree.Unmodified] },
|
||||
Display: "Unmodified",
|
||||
},
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.toggle-filetree-attributes"},
|
||||
OnAction: v.toggleAttributes,
|
||||
IsSelected: func() bool { return v.vm.ShowAttributes },
|
||||
Display: "Attributes",
|
||||
},
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.page-up"},
|
||||
OnAction: v.PageUp,
|
||||
},
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.page-down"},
|
||||
OnAction: v.PageDown,
|
||||
},
|
||||
{
|
||||
Key: gocui.KeyArrowDown,
|
||||
Modifier: gocui.ModNone,
|
||||
OnAction: v.CursorDown,
|
||||
},
|
||||
{
|
||||
Key: gocui.KeyArrowUp,
|
||||
Modifier: gocui.ModNone,
|
||||
OnAction: v.CursorUp,
|
||||
},
|
||||
{
|
||||
Key: gocui.KeyArrowLeft,
|
||||
Modifier: gocui.ModNone,
|
||||
OnAction: v.CursorLeft,
|
||||
},
|
||||
{
|
||||
Key: gocui.KeyArrowRight,
|
||||
Modifier: gocui.ModNone,
|
||||
OnAction: v.CursorRight,
|
||||
},
|
||||
}
|
||||
v.once.Do(func() {
|
||||
var infos = []key.BindingInfo{
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.toggle-collapse-dir"},
|
||||
OnAction: v.toggleCollapse,
|
||||
Display: "Collapse dir",
|
||||
},
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.toggle-collapse-all-dir"},
|
||||
OnAction: v.toggleCollapseAll,
|
||||
Display: "Collapse all dir",
|
||||
},
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.toggle-added-files"},
|
||||
OnAction: func() error { return v.toggleShowDiffType(filetree.Added) },
|
||||
IsSelected: func() bool { return !v.vm.HiddenDiffTypes[filetree.Added] },
|
||||
Display: "Added",
|
||||
},
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.toggle-removed-files"},
|
||||
OnAction: func() error { return v.toggleShowDiffType(filetree.Removed) },
|
||||
IsSelected: func() bool { return !v.vm.HiddenDiffTypes[filetree.Removed] },
|
||||
Display: "Removed",
|
||||
},
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.toggle-modified-files"},
|
||||
OnAction: func() error { return v.toggleShowDiffType(filetree.Modified) },
|
||||
IsSelected: func() bool { return !v.vm.HiddenDiffTypes[filetree.Modified] },
|
||||
Display: "Modified",
|
||||
},
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.toggle-unchanged-files", "keybinding.toggle-unmodified-files"},
|
||||
OnAction: func() error { return v.toggleShowDiffType(filetree.Unmodified) },
|
||||
IsSelected: func() bool { return !v.vm.HiddenDiffTypes[filetree.Unmodified] },
|
||||
Display: "Unmodified",
|
||||
},
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.toggle-filetree-attributes"},
|
||||
OnAction: v.toggleAttributes,
|
||||
IsSelected: func() bool { return v.vm.ShowAttributes },
|
||||
Display: "Attributes",
|
||||
},
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.page-up"},
|
||||
OnAction: v.PageUp,
|
||||
},
|
||||
{
|
||||
ConfigKeys: []string{"keybinding.page-down"},
|
||||
OnAction: v.PageDown,
|
||||
},
|
||||
{
|
||||
Key: gocui.KeyArrowDown,
|
||||
Modifier: gocui.ModNone,
|
||||
OnAction: v.CursorDown,
|
||||
},
|
||||
{
|
||||
Key: gocui.KeyArrowUp,
|
||||
Modifier: gocui.ModNone,
|
||||
OnAction: v.CursorUp,
|
||||
},
|
||||
{
|
||||
Key: gocui.KeyArrowLeft,
|
||||
Modifier: gocui.ModNone,
|
||||
OnAction: v.CursorLeft,
|
||||
},
|
||||
{
|
||||
Key: gocui.KeyArrowRight,
|
||||
Modifier: gocui.ModNone,
|
||||
OnAction: v.CursorRight,
|
||||
},
|
||||
}
|
||||
|
||||
helpKeys, err := key.GenerateBindings(v.gui, v.name, infos)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.helpKeys = helpKeys
|
||||
helpKeys, err := key.GenerateBindings(v.gui, v.name, infos)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
v.helpKeys = helpKeys
|
||||
})
|
||||
|
||||
_, height := v.view.Size()
|
||||
v.vm.Setup(0, height)
|
||||
_ = v.Update()
|
||||
_ = v.Render()
|
||||
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// IsVisible indicates if the file tree view pane is currently initialized
|
||||
|
@ -328,6 +333,30 @@ func (v *FileTree) toggleShowDiffType(diffType filetree.DiffType) error {
|
|||
return v.notifyOnViewOptionChangeListeners()
|
||||
}
|
||||
|
||||
func (v *FileTree) ToggleHide() error {
|
||||
v.hidden = !v.hidden
|
||||
|
||||
if v.hidden {
|
||||
logrus.Trace("hiding filetree view...")
|
||||
|
||||
// take note: deleting a view will invoke layout again, so ensure this call is protected from an infinite loop
|
||||
err := v.gui.DeleteView(v.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// take note: deleting a view will invoke layout again, so ensure this call is protected from an infinite loop
|
||||
err = v.gui.DeleteView(v.Name() + "header")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *FileTree) IsHidden() bool {
|
||||
return v.hidden
|
||||
}
|
||||
|
||||
// OnLayoutChange is called by the UI framework to inform the view-model of the new screen dimensions
|
||||
func (v *FileTree) OnLayoutChange() error {
|
||||
err := v.Update()
|
||||
|
@ -362,7 +391,7 @@ func (v *FileTree) Render() error {
|
|||
// update the header
|
||||
v.header.Clear()
|
||||
width, _ := g.Size()
|
||||
headerStr := format.RenderHeader(title, width, isSelected)
|
||||
headerStr := format.RenderHeader(title, width, isSelected, true)
|
||||
if v.vm.ShowAttributes {
|
||||
headerStr += fmt.Sprintf(filetree.AttributeFormat+" %s", "P", "ermission", "UID:GID", "Size", "Filetree")
|
||||
}
|
||||
|
@ -391,7 +420,7 @@ func (v *FileTree) KeyHelp() string {
|
|||
}
|
||||
|
||||
func (v *FileTree) Layout(g *gocui.Gui, minX, minY, maxX, maxY int) error {
|
||||
logrus.Tracef("view.Layout(minX: %d, minY: %d, maxX: %d, maxY: %d) %s", minX, minY, maxX, maxY, v.Name())
|
||||
logrus.Tracef("view.Layout(minX: %d, minY: %d, maxX: %d, maxY: %d, hidden: %v) %s", minX, minY, maxX, maxY, v.hidden, v.Name())
|
||||
attributeRowSize := 0
|
||||
|
||||
// make the layout responsive to the available realestate. Make more room for the main content by hiding auxillary
|
||||
|
@ -408,7 +437,6 @@ func (v *FileTree) Layout(g *gocui.Gui, minX, minY, maxX, maxY int) error {
|
|||
|
||||
// header + attribute header
|
||||
headerSize := 1 + attributeRowSize
|
||||
// note: maxY needs to account for the (invisible) border, thus a +1
|
||||
header, headerErr := g.SetView(v.Name()+"header", minX, minY, maxX, minY+headerSize+1)
|
||||
// we are going to overlap the view over the (invisible) border (so minY will be one less than expected).
|
||||
// additionally, maxY will be bumped by one to include the border
|
||||
|
|
|
@ -169,6 +169,19 @@ func (v *Filter) OnLayoutChange() error {
|
|||
return v.Render()
|
||||
}
|
||||
|
||||
func (v *Filter) Retop() {
|
||||
logrus.Trace("asserting filter on top...")
|
||||
// take note: deleting a view will invoke layout again, so ensure this call is protected from an infinite loop
|
||||
err := v.gui.DeleteView(v.Name()+"label")
|
||||
if err != nil {
|
||||
logrus.Errorf("could not put filter label on top:", err)
|
||||
}
|
||||
err = v.gui.DeleteView(v.Name())
|
||||
if err != nil {
|
||||
logrus.Errorf("could not put filter on top:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Filter) Layout(g *gocui.Gui, minX, minY, maxX, maxY int) error {
|
||||
logrus.Tracef("view.Layout(minX: %d, minY: %d, maxX: %d, maxY: %d) %s", minX, minY, maxX, maxY, v.Name())
|
||||
|
||||
|
|
|
@ -307,7 +307,7 @@ func (v *Layer) Render() error {
|
|||
return err
|
||||
}
|
||||
} else {
|
||||
headerStr := format.RenderHeader(title, width, isSelected)
|
||||
headerStr := format.RenderHeader(title, width, isSelected, true)
|
||||
headerStr += fmt.Sprintf("Cmp"+image.LayerFormat, "Size", "Command")
|
||||
_, err := fmt.Fprintln(v.header, headerStr)
|
||||
if err != nil {
|
||||
|
|
|
@ -110,6 +110,15 @@ func (v *Status) KeyHelp() string {
|
|||
return help
|
||||
}
|
||||
|
||||
func (v *Status) Retop() {
|
||||
logrus.Trace("asserting status on top...")
|
||||
// take note: deleting a view will invoke layout again, so ensure this call is protected from an infinite loop
|
||||
err := v.gui.DeleteView(v.Name())
|
||||
if err != nil {
|
||||
logrus.Errorf("could not put status on top:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Status) Layout(g *gocui.Gui, minX, minY, maxX, maxY int) error {
|
||||
logrus.Tracef("view.Layout(minX: %d, minY: %d, maxX: %d, maxY: %d) %s", minX, minY, maxX, maxY, v.Name())
|
||||
|
||||
|
|
Loading…
Reference in a new issue