-
Notifications
You must be signed in to change notification settings - Fork 7
/
basicControl.go
156 lines (129 loc) · 3.38 KB
/
basicControl.go
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
package gonsole
import "github.com/nsf/termbox-go"
// Control is the base model for a UI control
type BasicControl struct {
window *Window
parent Control
id string
Position Position
Visible bool
Enabled bool
focussable bool
ZIndex int
TabIndex int
dirty bool
// styling
Foreground termbox.Attribute
Background termbox.Attribute
border LineType
HAlign HorizontalAlignment
VAlign VerticalAlignment
Margin Sides
Padding Sides
}
func (ctrl *BasicControl) Init(id string) {
ctrl.SetID(id)
ctrl.Pollute()
}
func (ctrl *BasicControl) GetAbsolutePosition() Box {
if parent := ctrl.Parent(); parent != nil {
parentBox := parent.ContentBox()
return ctrl.Position.Box(parentBox.Width+1, parentBox.Height).Absolute(parentBox)
}
w, h := termbox.Size()
return ctrl.Position.Box(w, h)
}
func (ctrl *BasicControl) BorderBox() Box {
return ctrl.GetAbsolutePosition().Minus(ctrl.Margin)
}
func (ctrl *BasicControl) ContentBox() Box {
// substract padding and margin
contentBox := ctrl.GetAbsolutePosition().Minus(ctrl.Margin).Minus(ctrl.Padding)
// substract border if applicable
if ctrl.HasBorder() {
contentBox = contentBox.Minus(Sides{1, 1, 1, 1})
}
return contentBox
}
func (ctrl *BasicControl) DrawBorder() {
if ctrl.Border() == LineNone {
return
}
borderForeground := ctrl.Foreground
if ctrl.Focussed() {
borderForeground = termbox.ColorYellow
}
DrawBorder(ctrl.BorderBox(), ctrl.Border(), borderForeground, ctrl.Background)
}
func (ctrl *BasicControl) ParseEvent(ev *termbox.Event) bool {
// to be implemented for individual controls
return false
}
func (ctrl *BasicControl) ID() string {
return ctrl.id
}
func (ctrl *BasicControl) SetID(id string) {
ctrl.id = id
}
func (ctrl *BasicControl) Dirty() bool {
return ctrl.dirty
}
func (ctrl *BasicControl) Pollute() {
ctrl.dirty = true
}
func (ctrl *BasicControl) SetWindow(win *Window) {
ctrl.window = win
}
func (ctrl *BasicControl) Border() LineType {
return ctrl.border
}
func (ctrl *BasicControl) SetBorder(border LineType) {
ctrl.border = border
}
func (ctrl *BasicControl) HasBorder() bool {
return ctrl.border != LineNone
}
func (ctrl *BasicControl) AddEventListener(eventType string, handler func(ev *Event) bool) {
ctrl.Window().App.EventDispatcher.AddEventListener(ctrl, eventType, handler)
}
func (ctrl *BasicControl) SubmitEvent(ev *Event) {
ctrl.Window().App.EventDispatcher.SubmitEvent(ev)
}
func (ctrl *BasicControl) Repaint() {
if !ctrl.Dirty() {
return
}
ClearRect(ctrl.BorderBox(), termbox.ColorDefault, termbox.ColorDefault)
if ctrl.Background != 0 {
FillRect(ctrl.GetAbsolutePosition(), ctrl.Foreground, ctrl.Background)
}
ctrl.DrawBorder()
// implement details in controls
}
func (ctrl *BasicControl) Focussed() bool {
return ctrl.Window().FocussedControl().ID() == ctrl.ID()
}
func (ctrl *BasicControl) Focus() {
ctrl.Window().SetFocussedControl(ctrl)
}
func (ctrl *BasicControl) Focussable() bool {
return ctrl.focussable
}
func (ctrl *BasicControl) SetFocussable(focussable bool) {
ctrl.focussable = focussable
}
func (ctrl *BasicControl) Parent() Control {
return ctrl.parent
}
func (ctrl *BasicControl) SetParent(parent Control) {
ctrl.parent = parent
}
func (ctrl *BasicControl) Window() *Window {
if win := ctrl.window; win != nil {
return win
}
if parent := ctrl.Parent(); parent != nil {
return parent.Window()
}
return nil
}