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"
FileChooser = Menu:new{
height = Screen:getHeight(),
width = Screen:getWidth(),
path = ".",
parent = nil,
show_hidden = false,

@ -204,7 +204,11 @@ Menu = FocusManager:new{
sface = Font:getFace("scfont", 20),
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_shortcuts = {
"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
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{
w = self.dimen.w,
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.page = 1
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 --
@ -262,16 +282,12 @@ function Menu:init()
self.content_group = content
if not self.is_borderless then
self[1] = CenterContainer:new{
FrameContainer:new{
background = 0,
radius = math.floor(self.dimen.w/20),
content
},
dimen = Screen:getSize(),
self[1] = FrameContainer:new{
dimen = self.dimen,
background = 0,
radius = math.floor(self.dimen.w/20),
content
}
-- we need to substract border, margin and padding
self.item_dimen.w = self.item_dimen.w - 14
else
-- no border for the menu
self[1] = FrameContainer:new{
@ -279,7 +295,7 @@ function Menu:init()
bordersize = 0,
padding = 0,
margin = 0,
dimen = Screen:getSize(),
dimen = self.dimen,
content
}
end
@ -292,6 +308,16 @@ function Menu:init()
MenuCloseButton:new{
menu = self,
})
self.ges_events.TapCloseAllMenus = {
GestureRange:new{
ges = "tap",
range = Geom:new{
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight(),
}
}
}
else
-- set up keyboard events
self.key_events.Close = { {"Back"}, doc = "close menu" }
@ -323,8 +349,10 @@ function Menu:updateItems(select_number)
self.layout = {}
self.item_group:clear()
self.content_group:resetLayout()
self:_recalculateDimen()
for c = 1, self.perpage do
-- calculate index in item_table
local i = (self.page - 1) * self.perpage + c
if i <= #self.item_table then
local item_shortcut = nil
@ -351,7 +379,15 @@ function Menu:updateItems(select_number)
menu = self,
}
table.insert(self.item_group, item_tmp)
-- this is for focus manager
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 -- for c=1, self.perpage
if self.item_group[1] then
@ -365,7 +401,7 @@ function Menu:updateItems(select_number)
self.page_info.text = "no choices available"
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:setDirty(self)
end
@ -465,7 +501,7 @@ end
function Menu:onClose()
local table_length = #self.item_table_stack
if table_length == 0 then
UIManager:close(self)
self:onCloseAllMenus()
else
-- back to parent menu
parent_item_table = table.remove(self.item_table_stack, table_length)
@ -474,3 +510,19 @@ function Menu:onClose()
return true
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
}
}
}
},
}
else
self.key_events = {
@ -94,6 +94,7 @@ function ReaderMenu:onShowMenu()
table.insert(item_table, {
text = "Return to file browser",
callback = function()
UIManager:close(self.menu_container)
self.ui:onClose()
end
})
@ -101,17 +102,25 @@ function ReaderMenu:onShowMenu()
local main_menu = Menu:new{
title = "Document menu",
item_table = item_table,
width = 300,
height = #item_table + 3 * 28
width = Screen:getWidth() - 100,
}
function main_menu:onMenuChoice(item)
if item.callback then
item.callback()
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
end
@ -121,3 +130,8 @@ function ReaderMenu:onTapShowMenu()
return true
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
local dirty = false
local update_area = Geom:new{}
for _, widget in ipairs(self._window_stack) do
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)
if self._dirty[widget.widget] == "full" then
self.refresh_type = 0
@ -176,8 +168,6 @@ function UIManager:run()
end
end
self.repaint_all = false
-- @TODO make use of update_area on refresh 19.06 2012 (houqp)
--DEBUG(update_area)
if dirty then
-- refresh FB

@ -24,6 +24,11 @@ function Widget:new(o)
local o = o or {}
setmetatable(o, 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
return o
end
@ -92,7 +97,7 @@ end
--[[
Containers will pass events to children or react on them themselves
]]
]]--
function WidgetContainer:handleEvent(event)
if not self:propagateEvent(event) then
-- 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
and store that table as configuration setting
]]
InputContainer = WidgetContainer:new{
key_events = {},
ges_events = {},
}
InputContainer = WidgetContainer:new{}
function InputContainer:_init()
self.key_events = {}
self.ges_events = {}
end
function InputContainer:paintTo(bb, x, y)
self.dimen.x = x

Loading…
Cancel
Save