1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
package view
import (
"fmt"
"github.com/jroimartin/gocui"
"github.com/sirupsen/logrus"
"github.com/wagoodman/dive/runtime/ui/format"
"github.com/wagoodman/dive/utils"
)
// Debug is just for me :)
type Debug struct {
name string
gui *gocui.Gui
view *gocui.View
header *gocui.View
//once sync.Once
hidden bool
selectedView Helper
}
// newDebugView creates a new view object attached the the global [gocui] screen object.
func newDebugView(gui *gocui.Gui) (controller *Debug) {
controller = new(Debug)
// populate main fields
controller.name = "debug"
controller.gui = gui
controller.hidden = true
return controller
}
func (v *Debug) SetCurrentView(r Helper) {
v.selectedView = r
}
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())
// set controller options
v.view = view
v.view.Editable = false
v.view.Wrap = false
v.view.Frame = false
v.header = header
v.header.Editable = false
v.header.Wrap = false
v.header.Frame = false
return v.Render()
}
// IsVisible indicates if the status view pane is currently initialized.
func (v *Debug) IsVisible() bool {
return v != nil
}
// Update refreshes the state objects for future rendering (currently does nothing).
func (v *Debug) Update() error {
return nil
}
// OnLayoutChange is called whenever the screen dimensions are changed
func (v *Debug) OnLayoutChange() error {
err := v.Update()
if err != nil {
return err
}
return v.Render()
}
// Render flushes the state objects to the screen.
func (v *Debug) Render() error {
logrus.Tracef("view.Render() %s", v.Name())
v.gui.Update(func(g *gocui.Gui) error {
// update header...
v.header.Clear()
width, _ := g.Size()
headerStr := format.RenderHeader("Debug", width, false, false)
_, _ = fmt.Fprintln(v.header, headerStr)
// update view...
v.view.Clear()
_, err := fmt.Fprintln(v.view, "blerg")
if err != nil {
logrus.Debug("unable to write to buffer: ", err)
}
return nil
})
return nil
}
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, hidden: %v) %s", minX, minY, maxX, maxY, v.hidden, v.Name())
// header
headerSize := 1
// 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
view, viewErr := g.SetView(v.Name(), minX, minY+headerSize, maxX, maxY+1)
if utils.IsNewView(viewErr, headerErr) {
err := v.Setup(view, header)
if err != nil {
logrus.Error("unable to setup debug controller", err)
return err
}
}
return nil
}
func (v *Debug) RequestedSize(available int) *int {
return nil
}
|