Merge pull request #683 from houqp/new_ui_houqp

Bug fix & added simple TOC menu & bookmark support & notification widget
pull/2/merge
{Qingping,Dave} Hou 12 years ago
commit dbaec84f4d

@ -68,6 +68,10 @@ function Device:hasNoKeyboard()
return self:isTouchDevice() or (self.model == "Kindle4")
end
function Device:hasKeyboard()
return not self:hasNoKeyboard()
end
function Device:isTouchDevice()
if not self.model then
self.model = self:getModel()

@ -458,7 +458,7 @@ override this function to process the item selected in a different manner
]]--
function Menu:onMenuSelect(item)
if item.sub_item_table == nil then
UIManager:close(self)
self.close_callback()
self:onMenuChoice(item)
else
-- save menu title for later resume

@ -0,0 +1,52 @@
require "ui/ui"
require "ui/widget"
--[[
Widget that displays a tiny notification on top of screen
--]]
Notification = InputContainer:new{
face = Font:getFace("infofont", 20),
text = "Null Message",
timeout = nil,
key_events = {
AnyKeyPressed = { { Input.group.Any }, seqtext = "any key", doc = "close dialog" }
}
}
function Notification:init()
-- we construct the actual content here because self.text is only available now
self[1] = CenterContainer:new{
dimen = Geom:new{
w = Screen:getWidth(),
h = Screen:getHeight()/10,
},
ignore = "height",
FrameContainer:new{
background = 0,
radius = 0,
HorizontalGroup:new{
align = "center",
TextBoxWidget:new{
text = self.text,
face = self.face,
}
}
}
}
end
function Notification:onShow()
-- triggered by the UIManager after we got successfully shown (not yet painted)
if self.timeout then
UIManager:scheduleIn(self.timeout, function() UIManager:close(self) end)
end
return true
end
function Notification:onAnyKeyPressed()
-- triggered by our defined key events
UIManager:close(self)
return true
end

@ -0,0 +1,148 @@
require "ui/notification"
ReaderBookmark = InputContainer:new{
bm_menu_title = "Bookmarks",
bookmarks = nil,
}
function ReaderBookmark:init()
if Device:hasKeyboard() then
self.key_events = {
ShowToc = {
{ "B" },
doc = "show bookmarks" },
}
elseif Device:isTouchDevice() then
self.ges_events = {
AddBookmark = {
GestureRange:new{
ges = "double_tap",
range = Geom:new{
x = Screen:getWidth()/2, y = 0,
w = Screen:getWidth()/2,
h = Screen:getHeight()/2
}
}
},
}
end
self.ui.menu:registerToMainMenu(self)
end
function ReaderBookmark:onReadSettings(config)
self.bookmarks = config:readSetting("bookmarks") or {}
end
function ReaderBookmark:onCloseDocument()
self.ui.doc_settings:saveSetting("bookmarks", self.bookmarks)
end
function ReaderBookmark:onSetDimensions(dimen)
self.dimen = dimen
end
function ReaderBookmark:onAddBookmark()
local pn_or_xp = nil
if self.ui.document.getXPointer then
pn_or_xp = self.ui.document:getXPointer()
else
pn_or_xp = self.view.state.page
end
local noti_text = "Bookmark added."
if not self:addBookmark(pn_or_xp) then
noti_text = "Page already marked!"
end
UIManager:show(Notification:new{
text = noti_text,
timeout = 3
})
return true
end
function ReaderBookmark:onShowBookmark()
-- build up item_table
for k, v in ipairs(self.bookmarks) do
local page = v.page
-- for CREngine, bookmark page is xpointer
if type(page) == "string" then
page = self.ui.document:getPageFromXPointer(v.page)
end
v.text = "Page "..page.." "..v.notes.." @ "..v.datetime
end
local bm_menu = Menu:new{
title = "Bookmarks",
item_table = self.bookmarks,
width = Screen:getWidth()-20,
height = Screen:getHeight(),
}
-- buid up menu widget method as closure
local doc = self.ui.document
local sendEv = function(ev)
self.ui:handleEvent(ev)
end
function bm_menu:onMenuChoice(item)
if doc.info.has_pages then
sendEv(Event:new("PageUpdate", item.page))
elseif self.view.view_mode == "page" then
sendEv(Event:new("PageUpdate", doc:getPageFromXPointer(item.page)))
else
sendEv(Event:new("PosUpdate", doc:getPosFromXPointer(item.page)))
end
end
local menu_container = CenterContainer:new{
dimen = Screen:getSize(),
bm_menu,
}
bm_menu.close_callback = function()
UIManager:close(menu_container)
end
UIManager:show(menu_container)
return true
end
function ReaderBookmark:addToMainMenu(item_table)
-- insert table to main reader menu
table.insert(item_table, {
text = self.bm_menu_title,
callback = function()
self:onShowBookmark()
end,
})
end
--[[
return nil if page already marked, otherwise, return true
for CREngine, bookmark page is xpointer instead of page number
--]]
function ReaderBookmark:addBookmark(pn_or_xp)
for k,v in ipairs(self.bookmarks) do
if v.page == pn_or_xp then
return nil
end
end
-- build notes from TOC
local notes = self.ui.toc:getTocTitleByPage(pn_or_xp)
if notes ~= "" then
notes = "in "..notes
end
mark_item = {
page = pn_or_xp,
datetime = os.date("%Y-%m-%d %H:%M:%S"),
notes = notes,
}
table.insert(self.bookmarks, mark_item)
table.sort(self.bookmarks, function(a,b)
return self:isBookmarkInSequence(a, b)
end)
return true
end
function ReaderBookmark:isBookmarkInSequence(a, b)
return a.page < b.page
end

@ -80,6 +80,7 @@ function ReaderMenu:onShowMenu()
end
local menu_container = CenterContainer:new{
ignore = "height",
dimen = Screen:getSize(),
main_menu,
}

@ -1,12 +1,4 @@
ReaderPanning = InputContainer:new{
key_events = {
-- these will all generate the same event, just with different arguments
MoveUp = { {"Up"}, doc = "move visible area up", event = "Panning", args = {0, -1} },
MoveDown = { {"Down"}, doc = "move visible area down", event = "Panning", args = {0, 1} },
MoveLeft = { {"Left"}, doc = "move visible area left", event = "Panning", args = {-1, 0} },
MoveRight = { {"Right"}, doc = "move visible area right", event = "Panning", args = {1, 0} },
},
-- defaults
panning_steps = {
normal = 50,
@ -16,6 +8,27 @@ ReaderPanning = InputContainer:new{
},
}
function ReaderPanning:init()
if Device:isTouchDevice() then
else
self.key_events = {
-- these will all generate the same event, just with different arguments
MoveUp = {
{ "Up" }, doc = "move visible area up",
event = "Panning", args = {0, -1} },
MoveDown = {
{ "Down" }, doc = "move visible area down",
event = "Panning", args = {0, 1} },
MoveLeft = {
{ "Left" }, doc = "move visible area left",
event = "Panning", args = {-1, 0} },
MoveRight = {
{ "Right" }, doc = "move visible area right",
event = "Panning", args = {1, 0} },
}
end
end
function ReaderPanning:onSetDimensions(dimensions)
self.dimen = dimensions
end

@ -1,12 +1,18 @@
ReaderToc = InputContainer:new{
key_events = {
ShowToc = { {"T"}, doc = "show Table of Content menu"},
},
dimen = Geom:new{ w = Screen:getWidth()-20, h = Screen:getHeight()-20},
current_page = 0,
current_pos = 0,
toc_menu_title = "Table of contents",
}
function ReaderToc:init()
if not Device:hasNoKeyboard() then
self.key_events = {
ShowToc = {
{ "T" },
doc = "show Table of Content menu" },
}
end
self.ui.menu:registerToMainMenu(self)
end
function ReaderToc:cleanUpTocTitle(title)
return (title:gsub("\13", ""))
end
@ -15,20 +21,24 @@ function ReaderToc:onSetDimensions(dimen)
self.dimen = dimen
end
--function ReaderToc:fillToc()
--self.toc = self.doc:getToc()
--end
function ReaderToc:fillToc()
self.toc = self.ui.document:getToc()
end
-- getTocTitleByPage wrapper, so specific reader
-- _getTocTitleByPage wrapper, so specific reader
-- can tranform pageno according its need
function ReaderToc:getTocTitleByPage(pageno)
return self:_getTocTitleByPage(pageno)
function ReaderToc:getTocTitleByPage(pn_or_xp)
local page = pn_or_xp
if type(pn_or_xp) == "string" then
page = self.ui.document:getPageFromXPointer(pn_or_xp)
end
return self:_getTocTitleByPage(page)
end
function ReaderToc:_getTocTitleByPage(pageno)
if not self.toc then
-- build toc when needed.
self:fillToc()
-- build toc when needed.
self:fillToc()
end
-- no table of content
@ -56,29 +66,36 @@ function ReaderToc:onShowToc()
for _,v in ipairs(items) do
v.text = (" "):rep(v.depth-1)..self:cleanUpTocTitle(v.title)
end
local toc_menu = Menu:new{
title = "Table of Contents",
item_table = items,
dimen = self.dimen,
ui = self.ui
ui = self.ui,
width = Screen:getWidth()-20,
height = Screen:getHeight(),
}
function toc_menu:onMenuChoice(item)
self.ui:handleEvent(Event:new("PageUpdate", item.page))
end
UIManager:show(toc_menu)
end
function ReaderToc:onSetDimensions(dimen)
self.dimen = dimen
end
local menu_container = CenterContainer:new{
dimen = Screen:getSize(),
toc_menu,
}
toc_menu.close_callback = function()
UIManager:close(menu_container)
end
function ReaderToc:onPageUpdate(new_page_no)
self.current_page = new_page_no
UIManager:show(menu_container)
return true
end
function ReaderToc:onPosUpdate(new_pos)
self.current_pos = new_pos
function ReaderToc:addToMainMenu(item_table)
-- insert table to main reader menu
table.insert(item_table, {
text = self.toc_menu_title,
callback = function()
self:onShowToc()
end,
})
end

@ -122,6 +122,8 @@ function ReaderView:PanningUpdate(dx, dy)
UIManager:setDirty(self.dialog)
DEBUG("on pan: page_area", self.page_area)
DEBUG("on pan: visible_area", self.visible_area)
self.ui:handleEvent(
Event:new("ViewRecalculate", self.visible_area, self.page_area))
end
return true
end

@ -6,6 +6,7 @@ require "ui/reader/readerrotation"
require "ui/reader/readerpaging"
require "ui/reader/readerrolling"
require "ui/reader/readertoc"
require "ui/reader/readerbookmark"
require "ui/reader/readerfont"
require "ui/reader/readermenu"
@ -18,7 +19,6 @@ it works using data gathered from a document interface
ReaderUI = InputContainer:new{
key_events = {
Close = { {"Home"}, doc = "close document", event = "Close" },
Back = { {"Back"}, doc = "close document", event = "Close" },
},
-- our own size
@ -41,6 +41,12 @@ function ReaderUI:init()
self.dialog = self
end
if Device:hasKeyboard() then
self.key_events.Back = {
{ "Back" }, doc = "close document",
event = "Close" }
end
self.doc_settings = DocSettings:open(self.document.file)
-- a view container (so it must be child #1!)
@ -56,18 +62,26 @@ function ReaderUI:init()
view = self[1],
ui = self
}
-- Toc menu controller
self[3] = ReaderToc:new{
-- reader menu controller
self[3] = ReaderMenu:new{
view = self[1],
ui = self
}
self.menu = self[3] -- hold reference to menu widget
-- Table of content controller
self[4] = ReaderToc:new{
dialog = self.dialog,
view = self[1],
ui = self
}
-- reader menu controller
self[4] = ReaderMenu:new{
self.toc = self[4] -- hold reference to bm widget
-- bookmark controller
local reader_bm = ReaderBookmark:new{
dialog = self.dialog,
view = self[1],
ui = self
}
self.menu = self[4] -- hold reference to menu widget
table.insert(self, reader_bm)
if self.document.info.has_pages then
-- for page specific controller

@ -126,9 +126,15 @@ function CenterContainer:paintTo(bb, x, y)
-- throw error? paint to scrap buffer and blit partially?
-- for now, we ignore this
end
self[1]:paintTo(bb,
x + (self.dimen.w - contentSize.w)/2,
y + (self.dimen.h - contentSize.h)/2)
local x_pos = x
local y_pos = y
if self.ignore ~= "height" then
y_pos = y + (self.dimen.h - contentSize.h)/2
end
if self.ignore ~= "width" then
x_pos = x + (self.dimen.w - contentSize.w)/2
end
self[1]:paintTo(bb, x_pos, y_pos)
end
--[[
@ -605,6 +611,10 @@ function InputContainer:_init()
end
end
self.ges_events = new_ges_events
if not self.dimen then
self.dimen = Geom:new{}
end
end
function InputContainer:paintTo(bb, x, y)

Loading…
Cancel
Save