Merge pull request #657 from houqp/new_ui_menu_close

bug fixes and new feature for menu widget
pull/2/merge
{Qingping,Dave} Hou 12 years ago
commit a38befdf8f

@ -1,6 +1,8 @@
require "ui/menu" require "ui/menu"
FileChooser = Menu:new{ FileChooser = Menu:new{
height = Screen:getHeight(),
width = Screen:getWidth(),
path = ".", path = ".",
parent = nil, parent = nil,
show_hidden = false, show_hidden = false,

@ -204,7 +204,11 @@ 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 }, -- default width and height
width = 500,
-- height will be calculated according to item number if not given
height = nil,
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 +226,33 @@ 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
-- if height not given, dynamically calculate it
self.dimen.h = self.height or (#self.item_table + 2) * 36
if self.dimen.h > Screen:getHeight() then
self.dimen.h = Screen:getHeight()
end
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 +282,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 +295,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 +308,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,8 +349,10 @@ 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
-- calculate index in item_table
local i = (self.page - 1) * self.perpage + c local i = (self.page - 1) * self.perpage + c
if i <= #self.item_table then if i <= #self.item_table then
local item_shortcut = nil local item_shortcut = nil
@ -351,7 +379,15 @@ function Menu:updateItems(select_number)
menu = self, menu = self,
} }
table.insert(self.item_group, item_tmp) table.insert(self.item_group, item_tmp)
-- this is for focus manager
table.insert(self.layout, {item_tmp}) table.insert(self.layout, {item_tmp})
else
-- item not enough to fill the whole page, break out of loop
table.insert(self.item_group,
VerticalSpan:new{
width = (self.item_dimen.h * (self.perpage - c + 1))
})
break
end -- if i <= self.items end -- if i <= self.items
end -- for c=1, self.perpage end -- for c=1, self.perpage
if self.item_group[1] then if self.item_group[1] then
@ -365,7 +401,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 +501,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 +510,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

@ -12,7 +12,7 @@ function ReaderMenu:init()
h = Screen:getHeight()/2 h = Screen:getHeight()/2
} }
} }
} },
} }
else else
self.key_events = { self.key_events = {
@ -94,6 +94,7 @@ function ReaderMenu:onShowMenu()
table.insert(item_table, { table.insert(item_table, {
text = "Return to file browser", text = "Return to file browser",
callback = function() callback = function()
UIManager:close(self.menu_container)
self.ui:onClose() self.ui:onClose()
end end
}) })
@ -101,17 +102,25 @@ function ReaderMenu:onShowMenu()
local main_menu = Menu:new{ local main_menu = Menu:new{
title = "Document menu", title = "Document menu",
item_table = item_table, item_table = item_table,
width = 300, width = Screen:getWidth() - 100,
height = #item_table + 3 * 28
} }
function main_menu:onMenuChoice(item) function main_menu:onMenuChoice(item)
if item.callback then if item.callback then
item.callback() item.callback()
end end
end end
UIManager:show(main_menu) local menu_container = CenterContainer:new{
main_menu,
dimen = Screen:getSize(),
}
main_menu.close_callback = function ()
UIManager:close(menu_container)
end
-- maintain a reference to menu_container
self.menu_container = menu_container
UIManager:show(menu_container)
return true return true
end end
@ -121,3 +130,8 @@ function ReaderMenu:onTapShowMenu()
return true return true
end end
function ReaderMenu:onSetDimensions(dimen)
-- update gesture listenning range according to new screen orientation
self:init()
end

@ -155,16 +155,8 @@ function UIManager:run()
-- repaint dirty widgets -- repaint dirty widgets
local dirty = false local dirty = false
local update_area = Geom:new{}
for _, widget in ipairs(self._window_stack) do for _, widget in ipairs(self._window_stack) do
if self.repaint_all or self._dirty[widget.widget] then if self.repaint_all or self._dirty[widget.widget] then
widget_dimen = widget.widget:getSize()
if widget_dimen then
widget_area = Geom:new{
x = widget.x, y = widget.y,
w = widget_dimen.w, h = widget_dimen.h}
update_area = update_area:combine(widget_area)
end
widget.widget:paintTo(Screen.fb.bb, widget.x, widget.y) widget.widget:paintTo(Screen.fb.bb, widget.x, widget.y)
if self._dirty[widget.widget] == "full" then if self._dirty[widget.widget] == "full" then
self.refresh_type = 0 self.refresh_type = 0
@ -176,8 +168,6 @@ function UIManager:run()
end end
end end
self.repaint_all = false self.repaint_all = false
-- @TODO make use of update_area on refresh 19.06 2012 (houqp)
--DEBUG(update_area)
if dirty then if dirty then
-- refresh FB -- refresh FB

@ -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