forked from odevices/er-301
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Widget.lua
208 lines (182 loc) · 5.54 KB
/
Widget.lua
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
local app = app
local Signal = require "Signal"
local Class = require "Base.Class"
local Observable = require "Base.Observable"
local verbose = false
local Widget = Class {}
Widget:include(Observable)
function Widget:init()
Observable.init(self)
self:setClassName("Widget")
self.children = {}
self.parent = nil
end
function Widget:setModal()
self.modal = true
end
function Widget:addChildWidget(child)
-- app.logInfo("%s:addChildWidget(%s)",self,child)
child:setParentWidget(self)
end
function Widget:removeChildWidget(child)
-- app.logInfo("%s:removeChildWidget(%s)",self,child)
if child.parent == self then child:setParentWidget(nil) end
end
function Widget:setParentWidget(parent)
if self.parent then self.parent.children[self] = nil end
self.parent = parent
if parent then parent.children[self] = true end
end
function Widget:setMainCursorController(graphic)
self.mainCursorController = graphic
-- Propagate change if the parent window exists and has a context.
local window = self:getWindow()
if window and window.context then
local focus = window:getFocusedWidget("encoder")
if focus == self then window.context:onEncoderFocusChanged() end
end
end
function Widget:setSubCursorController(graphic)
self.subCursorController = graphic
-- Propagate change if the parent window exists and has a context.
local window = self:getWindow()
if window and window.context then
local focus = window:getFocusedWidget("encoder")
if focus == self then window.context:onEncoderFocusChanged() end
end
end
function Widget:getWindow()
local widget = self
while widget.parent do
widget = widget.parent
if widget.isWindow then return widget end
end
return widget.isWindow and widget
end
-- WARNING: This will fail if the widget's containing window is not active (i.e. has no conttext).
function Widget:getRootWindow()
local window = self:getWindow()
if window and window.context then return window.context:root() end
end
function Widget:addSubGraphic(graphic)
local window = self:getWindow()
if window then window:addSubGraphic(graphic) end
end
function Widget:removeSubGraphic(graphic)
local window = self:getWindow()
if window then window:removeSubGraphic(graphic) end
end
function Widget:grabFocus(...)
local window = self:getWindow()
if window == nil then
app.logInfo("%s:grabFocus: This widget has no parent window!", self)
return
end
local events = {
...
}
for _, event in ipairs(events) do
-- app.logInfo("%s:grabFocus(%s)",self,event)
window:setFocusedWidget(event, self)
end
end
function Widget:releaseFocus(...)
local window = self:getWindow()
if window == nil then
app.logInfo("%s:releaseFocus: This widget has no parent window!", self)
return
end
local events = {
...
}
for _, event in ipairs(events) do
-- app.logInfo("%s:releaseFocus(%s)",self,event)
if window.focus[event] == self then window:setFocusedWidget(event, nil) end
end
end
function Widget:hasFocus(event)
local window = self:getWindow()
if window == nil then
app.logInfo("%s:hasFocus: This widget has no parent window!", self)
return false
end
return window.focus[event] == self
end
function Widget:queryUp(key)
if verbose then app.logInfo("%s:queryUp(%s)", self, key) end
local value = self[key]
if value then
return value
elseif self.parent then
return self.parent:queryUp(key)
else
return nil
end
end
-- callUp is for methods
function Widget:callUp(method, ...)
if verbose then app.logInfo("%s:callUp(%s)", self, method) end
local handler = self[method]
if handler then
return handler(self, ...)
elseif self.parent then
return self.parent:callUp(method, ...)
else
return nil
end
end
-- sendUp is for events
local sendUp_uid = 0
function Widget:sendUp(event, ...)
sendUp_uid = sendUp_uid + 1
if not self:sendUpHelper(sendUp_uid, verbose and event ~= "encoder", event,
...) and verbose then
app.logInfo("%s:sendUp(%s,uid=%d): not handled", self, event, sendUp_uid)
end
end
function Widget:sendUpHelper(uid, verbose, event, ...)
-- app.logInfo("%s:sendUp(%s,uid=%d)",self,method,uid)
local handler = self[event]
if handler then
if verbose then
app.logInfo("%s:sendUp(%s,uid=%d): handler found", self, event, uid)
end
if handler(self, ...) or self.modal then
if verbose then
app.logInfo("%s:sendUp(%s,uid=%d): handler accepted", self, event, uid)
end
return true
end
end
if self.parent then
-- propagate to parent
return self.parent:sendUpHelper(uid, verbose, event, ...)
else
return false
end
end
function Widget:broadcastDown(method, ...)
if verbose then app.logInfo("%s:broadcastDown(%s)", self, method) end
self:broadcastDownHelper(method, ...)
end
function Widget:broadcastDownHelper(method, ...)
local handler = self[method]
if handler then
if verbose then
app.logInfo("%s:broadcastDown(%s): handler found", self, method)
end
handler(self, ...)
end
local tmp = {}
for child, _ in pairs(self.children) do tmp[#tmp + 1] = child end
for i = 1, #tmp do tmp[i]:broadcastDownHelper(method, ...) end
end
function Widget.enableVerbose()
verbose = true
end
function Widget.disableVerbose()
verbose = false
end
-------------------------------------------------------
-- default notification handlers
return Widget