-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwidget.go
More file actions
178 lines (157 loc) · 4.54 KB
/
widget.go
File metadata and controls
178 lines (157 loc) · 4.54 KB
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
package ui
// UserCommand enumerates high-level inputs processed by widgets and containers.
type UserCommand byte
const (
IDLE UserCommand = iota
UP
DOWN
LEFT
RIGHT
NEXT
PREV
ENTER
ESC
BACK
DEL
RESET
SAVE
LOAD
LONG_UP
LONG_DOWN
LONG_LEFT
LONG_RIGHT
LONG_ENTER
LONG_ESC
LONG_BACK
LONG_DEL
LONG_RESET
USER UserCommand = 64
)
type Sizer interface {
Size() (width, height uint16)
}
type Padder interface {
Padding() (left, top, right, bottom int8)
}
type Marginer interface {
Margins() (left, top, right, bottom int8)
}
// Widget describes the minimal contract every drawable component must fulfill.
// Implementations render themselves using the provided Context and may opt into
// additional behaviours such as selection or scrolling via separate interfaces.
type Widget interface {
Sizer
// Parent returns the parent widget of the widget.
Parent() Widget
SetParent(Widget)
// Draw draws the widget into the context
Draw(ctx Context)
// Interact receives user command and does internal state changes.
// Interact returns true if the interaction was handled.
Interact(c UserCommand) bool
// Size returns Width and Height of the widget
SetSelected(s bool)
Selected() bool
}
// FocusHandler may be implemented by widgets that need to be notified whenever
// they gain or lose focus within a navigable structure.
type FocusHandler interface {
OnFocus()
OnBlur()
}
// ActivationHandler may be implemented by widgets that perform work only while
// they are active (for example, value editors). The navigator toggles them on
// ENTER/BACK transitions.
type ActivationHandler interface {
OnActivate()
OnDeactivate()
}
// Selectable marks widgets that should be considered during navigation.
// Non-selectable widgets are skipped by focus logic automatically.
type Selectable interface {
CanSelect() bool
}
// VisibleHandler can be implemented by widgets that react to visibility changes.
type VisibleHandler interface {
OnVisible(visible bool)
}
// ScrollHandler allows widgets to respond to scroll offset updates.
type ScrollHandler interface {
OnScroll(offsetX, offsetY int16)
}
// SelectHandler is notified when a widget becomes (or stops being) selected.
type SelectHandler interface {
OnSelect()
OnDeselect()
}
// ExitHandler is invoked when a widget is exited (e.g. user backs out).
type ExitHandler interface {
OnExit()
}
// EnableState allows navigation logic to skip disabled widgets.
type EnableState interface {
Enabled() bool
}
// Scrollable declares support for manual scroll offset adjustments.
// Widgets that do not implement this interface remain static in their context.
type Scrollable interface {
Scroll(dx, dy int16) bool
ScrollOffset() (x, y int16)
}
// Navigable combines Widget behaviour with indexed child traversal so the
// Navigator can manage selection/activation for hierarchical layouts.
type Navigable interface {
Widget
Index() int
SetIndex(index int)
Item() Widget
SetActive(index int)
Active() bool
ChildCount() int
Child(index int) Widget
}
// Container extends Widget with facilities for selecting and activating child
// widgets. Concrete implementations are free to decide how children are laid
// out and how indices map to widgets.
type Container interface {
Widget
// SetIndex sets selected item by index.
SetIndex(index int)
// Index returns currently selected item index.
Index() int
// Item returns currently selected item. If no item selected, returns nil.
Item() Widget
// SetActive selects an item and makes it active. If active < 0, then it deselects and makes all inactive.
SetActive(active int)
// Active means that selected item is active and is processing all interactions.
Active() bool
}
// WidgetBase implements common Widget bookkeeping (parent reference, size,
// selection). Embedding it keeps widgets lightweight without forcing extras.
type WidgetBase struct {
parent Widget
Width uint16
Height uint16
selected bool
}
// NewWidgetBase constructs a WidgetBase with fixed width/height metadata.
func NewWidgetBase(width, height uint16) WidgetBase {
return WidgetBase{
Width: width,
Height: height,
}
}
func (c *WidgetBase) Parent() Widget { return c.parent }
func (c *WidgetBase) SetParent(widget Widget) { c.parent = widget }
func (c *WidgetBase) SetSelected(s bool) { c.selected = s }
func (c *WidgetBase) Selected() bool { return c.selected }
func (c *WidgetBase) Size() (uint16, uint16) { return c.Width, c.Height }
func (c *WidgetBase) Interact(cmd UserCommand) bool {
if cmd != ESC {
return false
}
if c.selected {
c.selected = false
}
return true
}