bug fix in InputContainer and menu widget

* add _init callback for all widgets, which is used for base widget
initialization. see comment in Widget:new(o) for more information.

* new ges_events and key_events are created for each InputContainer
widget, previously, they shared the same tables.

* remove hardcoded menu widget dimen

* recalculate menu dimen on table item changes

* add CloseAllMenus for menu widget
pull/2/merge
Qingping Hou 12 years ago
parent 3af979b84d
commit 92bce18537

@ -204,7 +204,7 @@ Menu = FocusManager:new{
sface = Font:getFace("scfont", 20), sface = Font:getFace("scfont", 20),
title = "No Title", title = "No Title",
dimen = Geom:new{ w = 500, h = 500 }, dimen = Geom:new{},
item_table = {}, item_table = {},
item_shortcuts = { item_shortcuts = {
"Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
@ -222,17 +222,29 @@ Menu = FocusManager:new{
-- set this to true to not paint as popup menu -- set this to true to not paint as popup menu
is_borderless = false, is_borderless = false,
-- close_callback is a function, which is executed when menu is closed
-- it is usually set by the widget which creates the menu
close_callback = nil
} }
function Menu:init() function Menu:_recalculateDimen()
self.dimen.w = self.width
self.dimen.h = (#self.item_table + 2) * 36
self.item_dimen = Geom:new{ self.item_dimen = Geom:new{
w = self.dimen.w, w = self.dimen.w,
h = 36, -- hardcoded for now h = 36, -- hardcoded for now
} }
if not self.is_borderless then
-- we need to substract border, margin and padding
self.item_dimen.w = self.item_dimen.w - 14
end
self.perpage = math.floor(self.dimen.h / self.item_dimen.h) - 2 self.perpage = math.floor(self.dimen.h / self.item_dimen.h) - 2
self.page = 1
self.page_num = math.ceil(#self.item_table / self.perpage) self.page_num = math.ceil(#self.item_table / self.perpage)
end
function Menu:init()
self:_recalculateDimen()
self.page = 1
----------------------------------- -----------------------------------
-- start to set up widget layout -- -- start to set up widget layout --
@ -262,16 +274,12 @@ function Menu:init()
self.content_group = content self.content_group = content
if not self.is_borderless then if not self.is_borderless then
self[1] = CenterContainer:new{ self[1] = FrameContainer:new{
FrameContainer:new{ dimen = self.dimen,
background = 0, background = 0,
radius = math.floor(self.dimen.w/20), radius = math.floor(self.dimen.w/20),
content content
},
dimen = Screen:getSize(),
} }
-- we need to substract border, margin and padding
self.item_dimen.w = self.item_dimen.w - 14
else else
-- no border for the menu -- no border for the menu
self[1] = FrameContainer:new{ self[1] = FrameContainer:new{
@ -279,7 +287,7 @@ function Menu:init()
bordersize = 0, bordersize = 0,
padding = 0, padding = 0,
margin = 0, margin = 0,
dimen = Screen:getSize(), dimen = self.dimen,
content content
} }
end end
@ -292,6 +300,16 @@ function Menu:init()
MenuCloseButton:new{ MenuCloseButton:new{
menu = self, menu = self,
}) })
self.ges_events.TapCloseAllMenus = {
GestureRange:new{
ges = "tap",
range = Geom:new{
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight(),
}
}
}
else else
-- set up keyboard events -- set up keyboard events
self.key_events.Close = { {"Back"}, doc = "close menu" } self.key_events.Close = { {"Back"}, doc = "close menu" }
@ -323,6 +341,7 @@ function Menu:updateItems(select_number)
self.layout = {} self.layout = {}
self.item_group:clear() self.item_group:clear()
self.content_group:resetLayout() self.content_group:resetLayout()
self:_recalculateDimen()
for c = 1, self.perpage do for c = 1, self.perpage do
local i = (self.page - 1) * self.perpage + c local i = (self.page - 1) * self.perpage + c
@ -365,7 +384,7 @@ function Menu:updateItems(select_number)
self.page_info.text = "no choices available" self.page_info.text = "no choices available"
end end
-- FIXME: this is a dirty hack to clear the previous menu -- FIXME: this is a dirty hack to clear previous menus
UIManager.repaint_all = true UIManager.repaint_all = true
--UIManager:setDirty(self) --UIManager:setDirty(self)
end end
@ -465,7 +484,7 @@ end
function Menu:onClose() function Menu:onClose()
local table_length = #self.item_table_stack local table_length = #self.item_table_stack
if table_length == 0 then if table_length == 0 then
UIManager:close(self) self:onCloseAllMenus()
else else
-- back to parent menu -- back to parent menu
parent_item_table = table.remove(self.item_table_stack, table_length) parent_item_table = table.remove(self.item_table_stack, table_length)
@ -474,3 +493,19 @@ function Menu:onClose()
return true return true
end end
function Menu:onCloseAllMenus()
UIManager:close(self)
if self.close_callback then
self.close_callback()
end
return true
end
function Menu:onTapCloseAllMenus(arg, ges_ev)
if ges_ev.pos:notIntersectWith(self.dimen) then
self:onCloseAllMenus()
return true
end
end

@ -24,6 +24,11 @@ function Widget:new(o)
local o = o or {} local o = o or {}
setmetatable(o, self) setmetatable(o, self)
self.__index = self self.__index = self
-- Both o._init and o.init are called on object create. But o._init is used
-- for base widget initialization (basic component used to build other
-- widgets). While o.init is for higher level widgets, for example Menu
-- Widget
if o._init then o:_init() end
if o.init then o:init() end if o.init then o:init() end
return o return o
end end
@ -92,7 +97,7 @@ end
--[[ --[[
Containers will pass events to children or react on them themselves Containers will pass events to children or react on them themselves
]] ]]--
function WidgetContainer:handleEvent(event) function WidgetContainer:handleEvent(event)
if not self:propagateEvent(event) then if not self:propagateEvent(event) then
-- call our own standard event handler -- call our own standard event handler
@ -582,10 +587,12 @@ an example for a key_event is this:
it is suggested to reference configurable sequences from another table it is suggested to reference configurable sequences from another table
and store that table as configuration setting and store that table as configuration setting
]] ]]
InputContainer = WidgetContainer:new{ InputContainer = WidgetContainer:new{}
key_events = {},
ges_events = {}, function InputContainer:_init()
} self.key_events = {}
self.ges_events = {}
end
function InputContainer:paintTo(bb, x, y) function InputContainer:paintTo(bb, x, y)
self.dimen.x = x self.dimen.x = x

Loading…
Cancel
Save