Merge pull request #798 from houqp/new_ui_houqp

add touchmenu
pull/2/merge
Huang Xin 11 years ago
commit 2927d728d7

@ -21,10 +21,14 @@ function Dbg:logEv(ev)
end end
function DEBUG(...) function DEBUG(...)
LvDEBUG(math.huge, ...)
end
function LvDEBUG(lv, ...)
local line = "" local line = ""
for i,v in ipairs({...}) do for i,v in ipairs({...}) do
if type(v) == "table" then if type(v) == "table" then
line = line .. " " .. dump(v) line = line .. " " .. dump(v, lv)
else else
line = line .. " " .. tostring(v) line = line .. " " .. tostring(v)
end end
@ -32,5 +36,3 @@ function DEBUG(...)
print("#"..line) print("#"..line)
end end

@ -64,14 +64,22 @@ function DocSettings:delSetting(key)
self.data[key] = nil self.data[key] = nil
end end
function dump(data) function dump(data, max_lv)
local out = {} local out = {}
DocSettings:_serialize(data, out, 0) DocSettings:_serialize(data, out, 0, max_lv)
return table.concat(out) return table.concat(out)
end end
-- simple serialization function, won't do uservalues, functions, loops -- simple serialization function, won't do uservalues, functions, loops
function DocSettings:_serialize(what, outt, indent) function DocSettings:_serialize(what, outt, indent, max_lv)
if not max_lv then
max_lv = math.huge
end
if indent > max_lv then
return
end
if type(what) == "table" then if type(what) == "table" then
local didrun = false local didrun = false
table.insert(outt, "{") table.insert(outt, "{")
@ -82,9 +90,9 @@ function DocSettings:_serialize(what, outt, indent)
table.insert(outt, "\n") table.insert(outt, "\n")
table.insert(outt, string.rep("\t", indent+1)) table.insert(outt, string.rep("\t", indent+1))
table.insert(outt, "[") table.insert(outt, "[")
self:_serialize(k, outt, indent+1) self:_serialize(k, outt, indent+1, max_lv)
table.insert(outt, "] = ") table.insert(outt, "] = ")
self:_serialize(v, outt, indent+1) self:_serialize(v, outt, indent+1, max_lv)
didrun = true didrun = true
end end
if didrun then if didrun then

@ -119,9 +119,9 @@ function ReaderBookmark:onShowBookmark()
return true return true
end end
function ReaderBookmark:addToMainMenu(item_table) function ReaderBookmark:addToMainMenu(tab_item_table)
-- insert table to main reader menu -- insert table to main reader menu
table.insert(item_table, { table.insert(tab_item_table.navi, {
text = self.bm_menu_title, text = self.bm_menu_title,
callback = function() callback = function()
self:onShowBookmark() self:onShowBookmark()

@ -211,9 +211,9 @@ function ReaderFont:setFont(face)
end end
end end
function ReaderFont:addToMainMenu(item_table) function ReaderFont:addToMainMenu(tab_item_table)
-- insert table to main reader menu -- insert table to main reader menu
table.insert(item_table, { table.insert(tab_item_table.typeset, {
text = self.font_menu_title, text = self.font_menu_title,
sub_item_table = self.face_table, sub_item_table = self.face_table,
}) })

@ -1,11 +1,24 @@
require "ui/widget/menu"
require "ui/widget/touchmenu"
ReaderMenu = InputContainer:new{ ReaderMenu = InputContainer:new{
_name = "ReaderMenu", _name = "ReaderMenu",
item_table = {}, tab_item_table = nil,
registered_widgets = {}, registered_widgets = {},
} }
function ReaderMenu:init() function ReaderMenu:init()
self.item_table = {} self.tab_item_table = {
main = {
icon = "resources/icons/appbar.pokeball.png",
},
navi = {
icon = "resources/icons/appbar.page.corner.bookmark.png",
},
typeset = {
icon = "resources/icons/appbar.page.text.png",
},
}
self.registered_widgets = {} self.registered_widgets = {}
if Device:hasKeyboard() then if Device:hasKeyboard() then
@ -33,10 +46,10 @@ end
function ReaderMenu:setUpdateItemTable() function ReaderMenu:setUpdateItemTable()
for _, widget in pairs(self.registered_widgets) do for _, widget in pairs(self.registered_widgets) do
widget:addToMainMenu(self.item_table) widget:addToMainMenu(self.tab_item_table)
end end
table.insert(self.item_table, { table.insert(self.tab_item_table.main, {
text = "Return to file manager", text = "Return to file manager",
callback = function() callback = function()
self.ui:handleEvent(Event:new("RestoreScreenMode", self.ui:handleEvent(Event:new("RestoreScreenMode",
@ -48,27 +61,48 @@ function ReaderMenu:setUpdateItemTable()
end end
function ReaderMenu:onShowMenu() function ReaderMenu:onShowMenu()
if #self.item_table == 0 then if #self.tab_item_table.main == 0 then
self:setUpdateItemTable() self:setUpdateItemTable()
end end
local main_menu = Menu:new{
title = "Document menu",
item_table = self.item_table,
width = Screen:getWidth() - 100,
}
local menu_container = CenterContainer:new{ local menu_container = CenterContainer:new{
name = "haha",
ignore = "height", ignore = "height",
dimen = Screen:getSize(), dimen = Screen:getSize(),
main_menu,
} }
local main_menu = nil
if Device:isTouchDevice() then
main_menu = TouchMenu:new{
name = "wocao",
tab_item_table = {
self.tab_item_table.navi,
self.tab_item_table.typeset,
self.tab_item_table.main,
},
show_parent = menu_container,
}
else
main_menu = Menu:new{
title = "Document menu",
item_table = {},
width = Screen:getWidth() - 100,
}
for _,item_table in pairs(self.tab_item_table) do
for k,v in ipairs(item_table) do
table.insert(main_menu.item_table, v)
end
end
end
main_menu.close_callback = function () main_menu.close_callback = function ()
UIManager:close(menu_container) UIManager:close(menu_container)
end end
menu_container[1] = main_menu
-- maintain a reference to menu_container -- maintain a reference to menu_container
self.menu_container = menu_container self.menu_container = menu_container
UIManager:show(menu_container) UIManager:show(menu_container)
return true return true

@ -81,7 +81,7 @@ function ReaderToc:onShowToc()
title = "Table of Contents", title = "Table of Contents",
item_table = self.toc, item_table = self.toc,
ui = self.ui, ui = self.ui,
width = Screen:getWidth()-20, width = Screen:getWidth()-20,
height = Screen:getHeight(), height = Screen:getHeight(),
} }
function toc_menu:onMenuChoice(item) function toc_menu:onMenuChoice(item)
@ -92,7 +92,7 @@ function ReaderToc:onShowToc()
dimen = Screen:getSize(), dimen = Screen:getSize(),
toc_menu, toc_menu,
} }
toc_menu.close_callback = function() toc_menu.close_callback = function()
UIManager:close(menu_container) UIManager:close(menu_container)
end end
@ -100,9 +100,9 @@ function ReaderToc:onShowToc()
return true return true
end end
function ReaderToc:addToMainMenu(item_table) function ReaderToc:addToMainMenu(tab_item_table)
-- insert table to main reader menu -- insert table to main reader menu
table.insert(item_table, { table.insert(tab_item_table.navi, {
text = self.toc_menu_title, text = self.toc_menu_title,
callback = function() callback = function()
self:onShowToc() self:onShowToc()

@ -10,7 +10,7 @@ end
function ReaderTypeset:onReadSettings(config) function ReaderTypeset:onReadSettings(config)
self.css = config:readSetting("css") self.css = config:readSetting("css")
if self.css and self.css ~= "" then if self.css and self.css ~= "" then
self.ui.document:setStyleSheet(self.css) self.ui.document:setStyleSheet(self.css)
else else
self.ui.document:setStyleSheet("") self.ui.document:setStyleSheet("")
@ -56,7 +56,7 @@ function ReaderTypeset:genStyleSheetMenu()
if lfs.attributes("./data/"..f, "mode") == "file" and string.match(f, "%.css$") then if lfs.attributes("./data/"..f, "mode") == "file" and string.match(f, "%.css$") then
table.insert(file_list, { table.insert(file_list, {
text = f, text = f,
callback = function() callback = function()
self:setStyleSheet("./data/"..f) self:setStyleSheet("./data/"..f)
end end
}) })
@ -98,9 +98,9 @@ function ReaderTypeset:toggleEmbeddedStyleSheet()
self.ui:handleEvent(Event:new("UpdatePos")) self.ui:handleEvent(Event:new("UpdatePos"))
end end
function ReaderTypeset:addToMainMenu(item_table) function ReaderTypeset:addToMainMenu(tab_item_table)
-- insert table to main reader menu -- insert table to main reader menu
table.insert(item_table, { table.insert(tab_item_table.typeset, {
text = self.css_menu_title, text = self.css_menu_title,
sub_item_table = self:genStyleSheetMenu(), sub_item_table = self:genStyleSheetMenu(),
}) })

@ -11,29 +11,29 @@ function ReaderZooming:init()
if Device:hasKeyboard() then if Device:hasKeyboard() then
self.key_events = { self.key_events = {
ZoomIn = { ZoomIn = {
{ "Shift", Input.group.PgFwd }, { "Shift", Input.group.PgFwd },
doc = "zoom in", doc = "zoom in",
event = "Zoom", args = "in" event = "Zoom", args = "in"
}, },
ZoomOut = { ZoomOut = {
{ "Shift", Input.group.PgBack }, { "Shift", Input.group.PgBack },
doc = "zoom out", doc = "zoom out",
event = "Zoom", args = "out" event = "Zoom", args = "out"
}, },
ZoomToFitPage = { ZoomToFitPage = {
{ "A" }, { "A" },
doc = "zoom to fit page", doc = "zoom to fit page",
event = "SetZoomMode", args = "page" event = "SetZoomMode", args = "page"
}, },
ZoomToFitContent = { ZoomToFitContent = {
{ "Shift", "A" }, { "Shift", "A" },
doc = "zoom to fit content", doc = "zoom to fit content",
event = "SetZoomMode", args = "content" event = "SetZoomMode", args = "content"
}, },
ZoomToFitPageWidth = { ZoomToFitPageWidth = {
{ "S" }, { "S" },
doc = "zoom to fit page width", doc = "zoom to fit page width",
event = "SetZoomMode", args = "pagewidth" event = "SetZoomMode", args = "pagewidth"
}, },
ZoomToFitContentWidth = { ZoomToFitContentWidth = {
{ "Shift", "S" }, { "Shift", "S" },
@ -41,9 +41,9 @@ function ReaderZooming:init()
event = "SetZoomMode", args = "contentwidth" event = "SetZoomMode", args = "contentwidth"
}, },
ZoomToFitPageHeight = { ZoomToFitPageHeight = {
{ "D" }, { "D" },
doc = "zoom to fit page height", doc = "zoom to fit page height",
event = "SetZoomMode", args = "pageheight" event = "SetZoomMode", args = "pageheight"
}, },
ZoomToFitContentHeight = { ZoomToFitContentHeight = {
{ "Shift", "D" }, { "Shift", "D" },
@ -57,7 +57,7 @@ end
function ReaderZooming:onReadSettings(config) function ReaderZooming:onReadSettings(config)
-- @TODO config file from old code base uses globalzoom_mode -- @TODO config file from old code base uses globalzoom_mode
-- instead of zoom_mode, we need to handle this imcompatibility -- instead of zoom_mode, we need to handle this imcompatibility
-- 04.12 2012 (houqp) -- 04.12 2012 (houqp)
local zoom_mode = config:readSetting("zoom_mode") local zoom_mode = config:readSetting("zoom_mode")
if not zoom_mode then if not zoom_mode then
@ -113,10 +113,10 @@ function ReaderZooming:onHintPage()
if not self.view.hinting then return true end if not self.view.hinting then return true end
if self.current_page < self.ui.document.info.number_of_pages then if self.current_page < self.ui.document.info.number_of_pages then
self.ui.document:hintPage( self.ui.document:hintPage(
self.view.state.page + 1, self.view.state.page + 1,
self:getZoom(self.view.state.page + 1), self:getZoom(self.view.state.page + 1),
self.view.state.rotation, self.view.state.rotation,
self.view.state.gamma, self.view.state.gamma,
self.view.render_mode) self.view.render_mode)
end end
return true return true
@ -126,7 +126,7 @@ function ReaderZooming:getZoom(pageno)
-- check if we're in bbox mode and work on bbox if that's the case -- check if we're in bbox mode and work on bbox if that's the case
local zoom = nil local zoom = nil
local page_size = {} local page_size = {}
if self.zoom_mode == "content" if self.zoom_mode == "content"
or self.zoom_mode == "contentwidth" or self.zoom_mode == "contentwidth"
or self.zoom_mode == "contentheight" then or self.zoom_mode == "contentheight" then
local ubbox_dimen = self.ui.document:getUsedBBoxDimensions(pageno, 1) local ubbox_dimen = self.ui.document:getUsedBBoxDimensions(pageno, 1)
@ -179,9 +179,9 @@ function ReaderZooming:genSetZoomModeCallBack(mode)
end end
end end
function ReaderZooming:addToMainMenu(item_table) function ReaderZooming:addToMainMenu(tab_item_table)
if self.ui.document.info.has_pages then if self.ui.document.info.has_pages then
table.insert(item_table, { table.insert(tab_item_table.typeset, {
text = "Switch zoom mode", text = "Switch zoom mode",
sub_item_table = { sub_item_table = {
{ {

@ -2,7 +2,7 @@ require "ui/widget/container"
--[[ --[[
a button widget a button widget
]] --]]
Button = InputContainer:new{ Button = InputContainer:new{
text = nil, -- mandatory text = nil, -- mandatory
preselect = false, preselect = false,

@ -40,7 +40,7 @@ function ConfirmBox:init()
} }
self.layout = { { ok_button, cancel_button } } self.layout = { { ok_button, cancel_button } }
self.selected.x = 2 -- Cancel is default self.selected.x = 2 -- Cancel is default
self[1] = CenterContainer:new{ self[1] = CenterContainer:new{
dimen = Screen:getSize(), dimen = Screen:getSize(),

@ -140,6 +140,9 @@ FrameContainer = WidgetContainer:new{
radius = 0, radius = 0,
bordersize = 2, bordersize = 2,
padding = 5, padding = 5,
width = nil,
height = nil,
invert = false,
} }
function FrameContainer:getSize() function FrameContainer:getSize()
@ -152,13 +155,18 @@ end
function FrameContainer:paintTo(bb, x, y) function FrameContainer:paintTo(bb, x, y)
local my_size = self:getSize() local my_size = self:getSize()
local container_width = self.width or my_size.w
local container_height = self.height or my_size.h
--@TODO get rid of margin here? 13.03 2013 (houqp)
if self.background then if self.background then
bb:paintRoundedRect(x, y, my_size.w, my_size.h, self.background, self.radius) bb:paintRoundedRect(x, y, container_width, container_height,
self.background, self.radius)
end end
if self.bordersize > 0 then if self.bordersize > 0 then
bb:paintBorder(x + self.margin, y + self.margin, bb:paintBorder(x + self.margin, y + self.margin,
my_size.w - self.margin * 2, my_size.h - self.margin * 2, container_width - self.margin * 2,
container_height - self.margin * 2,
self.bordersize, self.color, self.radius) self.bordersize, self.color, self.radius)
end end
if self[1] then if self[1] then
@ -166,6 +174,9 @@ function FrameContainer:paintTo(bb, x, y)
x + self.margin + self.bordersize + self.padding, x + self.margin + self.bordersize + self.padding,
y + self.margin + self.bordersize + self.padding) y + self.margin + self.bordersize + self.padding)
end end
if self.invert then
bb:invertRect(x, y, container_width, container_height)
end
end end
@ -178,25 +189,37 @@ UnderlineContainer = WidgetContainer:new{
linesize = 2, linesize = 2,
padding = 1, padding = 1,
color = 0, color = 0,
vertical_align = "top",
} }
function UnderlineContainer:getSize() function UnderlineContainer:getSize()
if self.dimen then if self.dimen then
return { w = self.dimen.w, h = self.dimen.h } return { w = self.dimen.w, h = self.dimen.h }
else else
local contentSize = self[1]:getSize() return self:getContentSize()
return {
w = contentSize.w,
h = contentSize.h + self.linesize + self.padding
}
end end
end end
function UnderlineContainer:getContentSize()
local contentSize = self[1]:getSize()
return {
w = contentSize.w,
h = contentSize.h + self.linesize + self.padding
}
end
function UnderlineContainer:paintTo(bb, x, y) function UnderlineContainer:paintTo(bb, x, y)
local content_size = self:getSize() local container_size = self:getSize()
self[1]:paintTo(bb, x, y) local content_size = self:getContentSize()
bb:paintRect(x, y + content_size.h - self.linesize, local p_y = y
content_size.w, self.linesize, self.color) if self.vertical_align == "center" then
p_y = (container_size.h - content_size.h) / 2 + y
elseif self.vertical_align == "bottom" then
p_y = (container_size.h - content_size.h) + y
end
self[1]:paintTo(bb, x, p_y)
bb:paintRect(x, y + container_size.h - self.linesize,
container_size.w, self.linesize, self.color)
end end
@ -222,7 +245,9 @@ 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{
vertical_align = "top",
}
function InputContainer:_init() function InputContainer:_init()
-- we need to do deep copy here -- we need to do deep copy here
@ -251,7 +276,12 @@ function InputContainer:paintTo(bb, x, y)
self.dimen.x = x self.dimen.x = x
self.dimen.y = y self.dimen.y = y
if self[1] then if self[1] then
return self[1]:paintTo(bb, x, y) if self.vertical_align == "center" then
local content_size = self[1]:getSize()
self[1]:paintTo(bb, x, y + (self.dimen.h - content_size.h)/2)
else
self[1]:paintTo(bb, x, y)
end
end end
end end

@ -33,7 +33,9 @@ function HorizontalGroup:paintTo(bb, x, y)
for i, widget in ipairs(self) do for i, widget in ipairs(self) do
if self.align == "center" then if self.align == "center" then
widget:paintTo(bb, x + self._offsets[i].x, y + (size.h - self._offsets[i].y) / 2) widget:paintTo(bb,
x + self._offsets[i].x,
y + (size.h - self._offsets[i].y) / 2)
elseif self.align == "top" then elseif self.align == "top" then
widget:paintTo(bb, x + self._offsets[i].x, y) widget:paintTo(bb, x + self._offsets[i].x, y)
elseif self.align == "bottom" then elseif self.align == "bottom" then
@ -88,7 +90,7 @@ end
function VerticalGroup:paintTo(bb, x, y) function VerticalGroup:paintTo(bb, x, y)
local size = self:getSize() local size = self:getSize()
for i, widget in ipairs(self) do for i, widget in ipairs(self) do
if self.align == "center" then if self.align == "center" then
widget:paintTo(bb, x + (size.w - self._offsets[i].x) / 2, y + self._offsets[i].y) widget:paintTo(bb, x + (size.w - self._offsets[i].x) / 2, y + self._offsets[i].y)
@ -150,7 +152,7 @@ end
function OverlapGroup:paintTo(bb, x, y) function OverlapGroup:paintTo(bb, x, y)
local size = self:getSize() local size = self:getSize()
for i, wget in ipairs(self) do for i, wget in ipairs(self) do
local wget_size = wget:getSize() local wget_size = wget:getSize()
if wget.align == "right" then if wget.align == "right" then

@ -0,0 +1,55 @@
require "ui/widget/container"
require "ui/widget/image"
--[[
Button with a big icon image! Designed for touch device
--]]
IconButton = InputContainer:new{
icon_file = "resources/info-confirm.png",
dimen = nil,
-- show_parent is used for UIManager:setDirty, so we can trigger repaint
show_parent = nil,
callback = function() end,
}
function IconButton:init()
self.image = ImageWidget:new{
file = self.icon_file
}
self.show_parent = self.show_parent or self
self.dimen = self.image:getSize()
self:initGesListener()
self[1] = self.image
end
function IconButton:initGesListener()
self.ges_events = {
TapClickButton = {
GestureRange:new{
ges = "tap",
range = self.dimen,
}
},
}
end
function IconButton:onTapClickButton()
self.image.invert = true
UIManager:setDirty(self.show_parent, "partial")
-- make sure button reacts before doing callback
UIManager:scheduleIn(0.1, function()
self.callback()
self.image.invert = false
UIManager:setDirty(self.show_parent, "partial")
end)
return true
end
function IconButton:onSetDimensions(new_dimen)
self.dimen = new_dimen
end

@ -0,0 +1,31 @@
require "ui/widget/base"
LineWidget = Widget:new{
style = "solid",
background = 15,
dimen = nil,
--@TODO replay dirty hack here 13.03 2013 (houqp)
empty_segments = nil,
}
function LineWidget:paintTo(bb, x, y)
if self.style == "dashed" then
for i = 0, self.dimen.w - 20, 20 do
bb:paintRect(x + i, y,
16, self.dimen.h, self.background)
end
else
if self.empty_segments then
bb:paintRect(x, y,
self.empty_segments[1].s,
self.dimen.h,
self.background)
bb:paintRect(x + self.empty_segments[1].e, y,
self.dimen.w - x - self.empty_segments[1].e,
self.dimen.h,
self.background)
else
bb:paintRect(x, y, self.dimen.w, self.dimen.h, self.background)
end
end
end

@ -8,7 +8,7 @@ require "ui/font"
--[[ --[[
Widget that displays a shortcut icon for menu item Widget that displays a shortcut icon for menu item
]] --]]
ItemShortCutIcon = WidgetContainer:new{ ItemShortCutIcon = WidgetContainer:new{
dimen = Geom:new{ w = 22, h = 22 }, dimen = Geom:new{ w = 22, h = 22 },
key = nil, key = nil,

@ -0,0 +1,350 @@
require "ui/widget/container"
require "ui/widget/group"
require "ui/widget/line"
require "ui/widget/iconbutton"
--[[
TouchMenuItem widget
--]]
TouchMenuItem = InputContainer:new{
menu = nil,
vertical_align = "center",
item = nil,
dimen = nil,
face = Font:getFace("cfont", 22),
show_parent = nil,
}
function TouchMenuItem:init()
self.ges_events = {
TapSelect = {
GestureRange:new{
ges = "tap",
range = self.dimen,
},
doc = "Select Menu Item",
},
}
self.item_frame = FrameContainer:new{
width = self.dimen.w,
bordersize = 0,
color = 15,
HorizontalGroup:new {
align = "center",
HorizontalSpan:new{ width = 10 },
TextWidget:new{
text = self.item.text,
face = self.face,
},
},
}
self[1] = self.item_frame
end
function TouchMenuItem:onTapSelect(arg, ges)
self.item_frame.invert = true
UIManager:setDirty(self.show_parent, "partial")
UIManager:scheduleIn(0.5, function()
self.item_frame.invert = false
UIManager:setDirty(self.show_parent, "partial")
end)
self.menu:onMenuSelect(self.item)
return true
end
--[[
TouchMenuBar widget
--]]
TouchMenuBar = InputContainer:new{
height = 70 * Screen:getDPI()/167,
width = Screen:getWidth(),
icons = {},
-- touch menu that holds the bar, used for trigger repaint on icons
show_parent = nil,
menu = nil,
}
function TouchMenuBar:init()
self.show_parent = self.show_parent or self
self.dimen = Geom:new{
w = self.width,
h = self.height,
}
self.bar_icon_group = HorizontalGroup:new{}
local icon_sep = LineWidget:new{
dimen = Geom:new{
w = 2,
h = self.height,
}
}
local icon_span = HorizontalSpan:new{ width = 20 }
-- build up image widget for menu icon bar
self.icon_widgets = {}
-- the start_seg for first icon_widget should be 0
-- we asign negative here to offset it in the loop
start_seg = -icon_sep:getSize().w
end_seg = start_seg
for k, v in ipairs(self.icons) do
local ib = IconButton:new{
show_parent = self.show_parent,
icon_file = v,
callback = nil,
}
table.insert(self.icon_widgets, HorizontalGroup:new{
icon_span,
ib,
icon_span,
})
-- we have to use local variable here for closure callback
local _start_seg = end_seg + icon_sep:getSize().w
local _end_seg = _start_seg + self.icon_widgets[k]:getSize().w
if k == 1 then
self.bar_sep = LineWidget:new{
dimen = Geom:new{
w = self.width,
h = 2,
},
empty_segments = {
{
s = _start_seg, e = _end_seg
}
},
}
end
ib.callback = function()
self.bar_sep.empty_segments = {
{
s = _start_seg, e = _end_seg
}
}
self.menu:switchMenuTab(k)
end
table.insert(self.bar_icon_group, self.icon_widgets[k])
table.insert(self.bar_icon_group, icon_sep)
start_seg = _start_seg
end_seg = _end_seg
end
self[1] = FrameContainer:new{
bordersize = 0,
padding = 0,
VerticalGroup:new{
align = "left",
-- bar icons
self.bar_icon_group,
-- separate line
self.bar_sep
},
}
end
--[[
TouchMenu widget
--]]
TouchMenu = InputContainer:new{
tab_item_table = {},
-- for returnning in multi-level menus
item_table_stack = {},
item_table = nil,
--@TODO replace getDPI call (houqp)
item_height = 50 * Screen:getDPI()/167,
bordersize = 2 * Screen:getDPI()/167,
padding = 5 * Screen:getDPI()/167,
width = Screen:getWidth(),
height = nil,
page = 1,
max_per_page = 10,
-- for UIManager:setDirty
show_parent = nil,
cur_tab = -1,
close_callback = nil,
}
function TouchMenu:init()
self.show_parent = self.show_parent or self
if not self.close_callback then
self.close_callback = function()
UIManager:close(self.show_parent)
end
end
self.ges_events.TapCloseAllMenus = {
GestureRange:new{
ges = "tap",
range = Geom:new{
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight(),
}
}
}
local icons = {}
for _,v in ipairs(self.tab_item_table) do
table.insert(icons, v.icon)
end
self.bar = TouchMenuBar:new{
width = self.width - self.padding * 2 - self.bordersize * 2,
icons = icons,
show_parent = self.show_parent,
menu = self,
}
self.item_group = VerticalGroup:new{
align = "left",
}
self.footer = HorizontalGroup:new{
IconButton:new{
invert = true,
icon_file = "resources/icons/appbar.chevron.left.png",
show_parent = self.show_parent,
callback = function()
self:backToUpperMenu()
end,
}
}
self[1] = FrameContainer:new{
padding = self.padding,
bordersize = self.bordersize,
background = 0,
-- menubar and footer will be inserted in
-- item_group in updateItems
self.item_group,
}
self:switchMenuTab(1)
self:updateItems()
end
function TouchMenu:_recalculateDimen()
self.dimen.w = self.width
-- if height not given, dynamically calculate it
if not self.height then
self.dimen.h = (#self.item_table + 2) * self.item_height
+ self.bar:getSize().h
else
self.dimen.h = self.height
end
if self.dimen.h > Screen:getHeight() then
self.dimen.h = Screen:getHeight()
end
self.perpage = math.floor(self.dimen.h / self.item_height) - 2
if self.perpage > self.max_per_page then
self.perpage = self.max_per_page
end
self.page_num = math.ceil(#self.item_table / self.perpage)
end
function TouchMenu:updateItems()
self:_recalculateDimen()
self.item_group:clear()
table.insert(self.item_group, self.bar)
local item_width = self.dimen.w - self.padding*2 - self.bordersize*2
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_tmp = TouchMenuItem:new{
item = self.item_table[i],
menu = self,
dimen = Geom:new{
w = item_width,
h = self.item_height,
},
show_parent = self.show_parent,
}
table.insert(self.item_group, item_tmp)
-- insert split line
if c ~= self.perpage then
table.insert(self.item_group, HorizontalGroup:new{
-- pad with spacing
HorizontalSpan:new{width = 10},
LineWidget:new{
style = "dashed",
dimen = Geom:new{
w = item_width - 20,
h = 1,
}
}
})
end
else
-- item not enough to fill the whole page, break out of loop
--table.insert(self.item_group,
--VerticalSpan:new{
--width = self.item_height
--})
--break
end -- if i <= self.items
end -- for c=1, self.perpage
table.insert(self.item_group, VerticalSpan:new{width = 2})
table.insert(self.item_group, self.footer)
-- FIXME: this is a dirty hack to clear previous menus
-- refert to issue #664
UIManager.repaint_all = true
end
function TouchMenu:switchMenuTab(tab_num)
if self.cur_tab ~= tab_num then
self.cur_tab = tab_num
self.item_table = self.tab_item_table[tab_num]
self:updateItems()
end
end
function TouchMenu:backToUpperMenu()
if #self.item_table_stack ~= 0 then
self.item_table = table.remove(self.item_table_stack)
self:updateItems()
end
end
function TouchMenu:closeMenu()
self.close_callback()
end
function TouchMenu:onMenuSelect(item)
if item.sub_item_table == nil then
if item.callback then
-- put stuff in scheduler so we can See
-- the effect of inverted menu item
UIManager:scheduleIn(0.1, function()
self:closeMenu()
item.callback()
end)
end
else
table.insert(self.item_table_stack, self.item_table)
self.item_table = item.sub_item_table
self:updateItems()
end
return true
end
function TouchMenu:onTapCloseAllMenus(arg, ges_ev)
if ges_ev.pos:notIntersectWith(self.dimen) then
self:closeMenu()
return true
end
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 422 B

After

Width:  |  Height:  |  Size: 750 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 649 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="76" height="76" viewBox="0 0 76.00 76.00" enable-background="new 0 0 76.00 76.00" xml:space="preserve">
<path fill="#000000" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 35.8724,37.6042L 39.0391,40.7708L 50.5182,51.8542L 40.2266,51.8542L 25.1849,37.6041L 40.2266,23.3542L 50.5182,23.3542L 39.0391,34.4375L 35.8724,37.6042 Z "/>
</svg>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="76" height="76" viewBox="0 0 76.00 76.00" enable-background="new 0 0 76.00 76.00" xml:space="preserve">
<path fill="#000000" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 28,19L 8.60116,19C 7.57586,20.5832 6.67496,22.2545 5.91232,24L 28,24L 28,56L 38,45.9167L 48,56L 48,24L 52,24L 52,70.0877C 53.7455,69.3251 55.4168,68.4242 57,67.3988L 57,19L 48,19L 48,16L 28,16L 28,19 Z M 24,30L 3.91849,30C 3.5383,31.626 3.27147,33.2956 3.12678,35L 24,35L 24,30 Z M 24,40L 3.05619,40C 3.15208,41.702 3.36958,43.3715 3.70014,45L 24,45L 24,40 Z M 24,55L 24,50L 5.11131,50C 5.74451,51.735 6.51108,53.4058 7.39861,55L 24,55 Z M 46,60L 10.7772,60C 12.256,61.8276 13.9151,63.5033 15.7274,65L 46,65L 46,60 Z "/>
</svg>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="76" height="76" viewBox="0 0 76.00 76.00" enable-background="new 0 0 76.00 76.00" xml:space="preserve">
<path fill="#000000" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 20,17L 44.25,17L 56,28.75L 56,59L 20,59L 20,17 Z M 24,21L 24,55L 52,55L 52,33L 40,33L 40,21L 24,21 Z M 44,22.25L 44,29L 50.75,29L 44,22.25 Z M 26,23L 38,23L 38,28L 26,28L 26,23 Z M 26,30L 38,30L 38,33L 26,33L 26,30 Z M 26,35L 50,35L 50,38L 26,38L 26,35 Z M 26,40L 50,40L 50,43L 26,43L 26,40 Z M 26,45L 50,45L 50,48L 26,48L 26,45 Z M 26,50L 50,50L 50,53L 26,53L 26,50 Z "/>
</svg>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="76" height="76" viewBox="0 0 76.00 76.00" enable-background="new 0 0 76.00 76.00" xml:space="preserve">
<path fill="#000000" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 38,19C 48.4934,19 57,27.5066 57,38C 57,48.4934 48.4934,57 38,57C 27.5066,57 19,48.4934 19,38C 19,27.5066 27.5066,19 38,19 Z M 38,22.9583C 30.2275,22.9583 23.8319,28.8536 23.0407,36.4167L 30.2417,36.4167C 30.9752,32.8031 34.17,30.0833 38,30.0833C 41.83,30.0833 45.0248,32.8031 45.7583,36.4167L 52.9593,36.4167C 52.1681,28.8536 45.7725,22.9583 38,22.9583 Z M 23.0407,39.5833C 23.8319,47.1464 30.2275,53.0417 38,53.0417C 45.7725,53.0417 52.1681,47.1464 52.9593,39.5833L 45.7583,39.5834C 45.0248,43.1969 41.83,45.9167 38,45.9167C 34.17,45.9167 30.9752,43.1969 30.2417,39.5834L 23.0407,39.5833 Z M 38,33.25C 35.3766,33.25 33.25,35.3767 33.25,38C 33.25,40.6234 35.3766,42.75 38,42.75C 40.6233,42.75 42.75,40.6234 42.75,38C 42.75,35.3767 40.6233,33.25 38,33.25 Z M 38,35.625C 39.3117,35.625 40.375,36.6883 40.375,38C 40.375,39.3117 39.3117,40.375 38,40.375C 36.6883,40.375 35.625,39.3117 35.625,38C 35.625,36.6883 36.6883,35.625 38,35.625 Z "/>
</svg>

@ -176,24 +176,70 @@ reader = ReaderUI:new{
readerwindow[1][1] = reader readerwindow[1][1] = reader
main_menu = TouchMenu:new{ touch_menu = TouchMenu:new{
title = "Document menu", title = "Document menu",
item_table = { tab_item_table = {
{ {
text = "item1", icon = "resources/icons/appbar.pokeball.png",
callback = function() {
end, text = "item1",
callback = function()
end,
},
{
text = "item2",
callback = function()
end,
},
{
text = "item3",
callback = function()
end,
},
{
text = "item4",
callback = function()
end,
},
{
text = "item5",
callback = function()
end,
},
{
text = "item6",
callback = function()
end,
},
{
text = "item7",
callback = function()
end,
},
{
text = "item8",
callback = function()
end,
},
{
text = "item9",
callback = function()
end,
},
}, },
{ {
text = "item2", icon = "resources/icons/appbar.page.corner.bookmark.png",
callback = function() {
end, text = "item10",
}, callback = function()
{ end,
text = "item3", },
callback = function() {
end, text = "item11",
}, callback = function()
end,
},
}
}, },
} }
@ -204,11 +250,11 @@ main_menu = TouchMenu:new{
----------------------------------------------------------------------- -----------------------------------------------------------------------
UIManager:show(Background:new()) UIManager:show(Background:new())
UIManager:show(TestGrid) UIManager:show(TestGrid)
UIManager:show(Clock:new()) --UIManager:show(Clock:new())
--UIManager:show(M) --UIManager:show(M)
--UIManager:show(Quiz) --UIManager:show(Quiz)
--UIManager:show(readerwindow) --UIManager:show(readerwindow)
UIManager:show(TouchMenu:new()) UIManager:show(touch_menu)
UIManager:run() UIManager:run()

Loading…
Cancel
Save