uimanager(fix): check active widgets in the correct order

pull/2051/head
Qingping Hou 8 years ago
parent ac03cd241f
commit a92a88e063

@ -381,19 +381,33 @@ end
-- transmit an event to an active widget
function UIManager:sendEvent(event)
if #self._window_stack == 0 then return end
local top_widget = self._window_stack[#self._window_stack]
-- top level widget has first access to the event
if self._window_stack[#self._window_stack].widget:handleEvent(event) then
if top_widget.widget:handleEvent(event) then
return
end
-- if the event is not consumed, active widgets can access it
for _, widget in ipairs(self._window_stack) do
if widget.widget.is_always_active then
if widget.widget:handleEvent(event) then return end
if top_widget.widget.active_widgets then
for _, active_widget in ipairs(top_widget.widget.active_widgets) do
if active_widget:handleEvent(event) then return end
end
if widget.widget.active_widgets then
for _, active_widget in ipairs(widget.widget.active_widgets) do
if active_widget:handleEvent(event) then return end
end
-- if the event is not consumed, active widgets (from top to bottom) can
-- access it. NOTE: _window_stack can shrink on close event
local checked_widgets = {top_widget}
for i = #self._window_stack-1, 1, -1 do
local widget = self._window_stack[i]
if checked_widgets[widget] == nil then
if widget.widget.is_always_active then
checked_widgets[widget] = true
if widget.widget:handleEvent(event) then return end
end
if widget.widget.active_widgets then
checked_widgets[widget] = true
for _, active_widget in ipairs(widget.widget.active_widgets) do
if active_widget:handleEvent(event) then return end
end
end
end
end

@ -191,4 +191,83 @@ describe("UIManager spec", function()
UIManager.auto_suspend_action)
Device.isKobo = old_is_kobo
end)
it("should check active widgets in order", function()
local call_signals = {false, false, false}
UIManager._window_stack = {
{
widget = {
is_always_active = true,
handleEvent = function()
call_signals[1] = true
return true
end
}
},
{
widget = {
is_always_active = true,
handleEvent = function()
call_signals[2] = true
return true
end
}
},
{
widget = {
is_always_active = true,
handleEvent = function()
call_signals[3] = true
return true
end
}
},
{widget = {handleEvent = function()end}},
}
UIManager:sendEvent("foo")
assert.falsy(call_signals[1])
assert.falsy(call_signals[2])
assert.truthy(call_signals[3])
end)
it("should handle stack change when checking for active widgets", function()
-- this senario should only happen when other active widgets
-- are closed by the one widget's handleEvent
local call_signals = {0, 0, 0}
UIManager._window_stack = {
{
widget = {
is_always_active = true,
handleEvent = function()
call_signals[1] = call_signals[1] + 1
end
}
},
{
widget = {
is_always_active = true,
handleEvent = function()
call_signals[2] = call_signals[2] + 1
end
}
},
{
widget = {
is_always_active = true,
handleEvent = function()
call_signals[3] = call_signals[3] + 1
table.remove(UIManager._window_stack, 2)
end
}
},
{widget = {handleEvent = function()end}},
}
UIManager:sendEvent("foo")
assert.is.same(call_signals[1], 1)
assert.is.same(call_signals[2], 0)
assert.is.same(call_signals[3], 1)
end)
end)

Loading…
Cancel
Save