Merge pull request #763 from chrox/event_listener

separate abstract interface EventListener from Widget
pull/2/merge
{Qingping,Dave} Hou 11 years ago
commit de65b8934f

@ -2,8 +2,6 @@ require "ui/geometry"
CreOptions = { CreOptions = {
prefix = 'copt', prefix = 'copt',
default_options = {
},
{ {
icon = "resources/icons/appbar.transform.rotate.right.large.png", icon = "resources/icons/appbar.transform.rotate.right.large.png",
options = { options = {

@ -72,19 +72,19 @@ function DjvuDocument:getPageDimensions(pageno, zoom, rotation)
end end
end end
function DjvuDocument:renderPage(pageno, rect, zoom, rotation, render_mode) function DjvuDocument:renderPage(pageno, rect, zoom, rotation, gamma, render_mode)
if self.configurable.text_wrap == 1 then if self.configurable.text_wrap == 1 then
return self.koptinterface:renderPage(self, pageno, rect, zoom, rotation, render_mode) return self.koptinterface:renderPage(self, pageno, rect, zoom, rotation, render_mode)
else else
return Document.renderPage(self, pageno, rect, zoom, rotation, render_mode) return Document.renderPage(self, pageno, rect, zoom, rotation, gamma, render_mode)
end end
end end
function DjvuDocument:drawPage(target, x, y, rect, pageno, zoom, rotation, render_mode) function DjvuDocument:drawPage(target, x, y, rect, pageno, zoom, rotation, gamma, render_mode)
if self.configurable.text_wrap == 1 then if self.configurable.text_wrap == 1 then
self.koptinterface:drawPage(self, target, x, y, rect, pageno, zoom, rotation, render_mode) self.koptinterface:drawPage(self, target, x, y, rect, pageno, zoom, rotation, render_mode)
else else
Document.drawPage(self, target, x, y, rect, pageno, zoom, rotation, render_mode) Document.drawPage(self, target, x, y, rect, pageno, zoom, rotation, gamma, render_mode)
end end
end end

@ -56,6 +56,8 @@ Document = {
date = "" date = ""
}, },
GAMMA_NO_GAMMA = 1.0,
-- override bbox from orignal page's getUsedBBox -- override bbox from orignal page's getUsedBBox
bbox = {}, bbox = {},
@ -182,8 +184,8 @@ function Document:getToc()
return self._document:getToc() return self._document:getToc()
end end
function Document:renderPage(pageno, rect, zoom, rotation, render_mode) function Document:renderPage(pageno, rect, zoom, rotation, gamma, render_mode)
local hash = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..render_mode local hash = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..gamma.."|"..render_mode
local page_size = self:getPageDimensions(pageno, zoom, rotation) local page_size = self:getPageDimensions(pageno, zoom, rotation)
-- this will be the size we actually render -- this will be the size we actually render
local size = page_size local size = page_size
@ -198,7 +200,7 @@ function Document:renderPage(pageno, rect, zoom, rotation, render_mode)
return return
end end
-- only render required part -- only render required part
hash = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..render_mode.."|"..tostring(rect) hash = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..gamma.."|"..render_mode.."|"..tostring(rect)
size = rect size = rect
end end
@ -223,6 +225,11 @@ function Document:renderPage(pageno, rect, zoom, rotation, render_mode)
dc:setOffset(0, page_size.h) dc:setOffset(0, page_size.h)
end end
dc:setZoom(zoom) dc:setZoom(zoom)
if gamma ~= self.GAMMA_NO_GAMMA then
--DEBUG("gamma correction: ", gamma)
dc:setGamma(gamma)
end
-- render -- render
local page = self._document:openPage(pageno) local page = self._document:openPage(pageno)
@ -235,10 +242,11 @@ end
-- a hint for the cache engine to paint a full page to the cache -- a hint for the cache engine to paint a full page to the cache
-- TODO: this should trigger a background operation -- TODO: this should trigger a background operation
function Document:hintPage(pageno, zoom, rotation, render_mode) function Document:hintPage(pageno, zoom, rotation, gamma, render_mode)
local hash_full_page = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..render_mode local hash_full_page = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..gamma.."|"..render_mode
if not Cache:check(hash_full_page) then if not Cache:check(hash_full_page) then
self:renderPage(pageno, nil, zoom, rotation, render_mode) --DEBUG("hinting page", pageno)
self:renderPage(pageno, nil, zoom, rotation, gamma, render_mode)
end end
end end
@ -250,15 +258,15 @@ Draw page content to blitbuffer.
@target: target blitbuffer @target: target blitbuffer
@rect: visible_area inside document page @rect: visible_area inside document page
--]] --]]
function Document:drawPage(target, x, y, rect, pageno, zoom, rotation, render_mode) function Document:drawPage(target, x, y, rect, pageno, zoom, rotation, gamma, render_mode)
local hash_full_page = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..render_mode local hash_full_page = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..gamma.."|"..render_mode
local hash_excerpt = hash_full_page.."|"..tostring(rect) local hash_excerpt = hash_full_page.."|"..tostring(rect)
local tile = Cache:check(hash_full_page) local tile = Cache:check(hash_full_page)
if not tile then if not tile then
tile = Cache:check(hash_excerpt) tile = Cache:check(hash_excerpt)
if not tile then if not tile then
DEBUG("rendering") DEBUG("rendering")
tile = self:renderPage(pageno, rect, zoom, rotation, render_mode) tile = self:renderPage(pageno, rect, zoom, rotation, gamma, render_mode)
end end
end end
DEBUG("now painting", tile, rect) DEBUG("now painting", tile, rect)

@ -6,19 +6,6 @@ require "ui/reader/readerconfig"
KoptOptions = { KoptOptions = {
prefix = 'kopt', prefix = 'kopt',
default_options = {
{
widget = "ProgressWidget",
widget_align_center = 0.8,
width = Screen:getWidth()*0.7,
height = 5,
percentage = 0.0,
item_text = {"Goto"},
item_align_center = 0.2,
item_font_face = "tfont",
item_font_size = 20,
}
},
{ {
icon = "resources/icons/appbar.transform.rotate.right.large.png", icon = "resources/icons/appbar.transform.rotate.right.large.png",
options = { options = {
@ -117,6 +104,8 @@ KoptOptions = {
item_align_center = 0.8, item_align_center = 0.8,
values = {2.0, 1.5, 1.0, 0.5, 0.2}, values = {2.0, 1.5, 1.0, 0.5, 0.2},
default_value = 1.0, default_value = 1.0,
event = "GammaUpdate",
args = {0.5, 0.8, 1.0, 2.0, 4.0},
} }
} }
}, },
@ -135,7 +124,6 @@ KoptOptions = {
}, },
{ {
event = "RestoreZoomMode", event = "RestoreZoomMode",
args = {"page", nil},
}, },
} }
}, },

@ -68,19 +68,19 @@ function PdfDocument:getPageDimensions(pageno, zoom, rotation)
end end
end end
function PdfDocument:renderPage(pageno, rect, zoom, rotation, render_mode) function PdfDocument:renderPage(pageno, rect, zoom, rotation, gamma, render_mode)
if self.configurable.text_wrap == 1 then if self.configurable.text_wrap == 1 then
return self.koptinterface:renderPage(self, pageno, rect, zoom, rotation, render_mode) return self.koptinterface:renderPage(self, pageno, rect, zoom, rotation, render_mode)
else else
return Document.renderPage(self, pageno, rect, zoom, rotation, render_mode) return Document.renderPage(self, pageno, rect, zoom, rotation, gamma, render_mode)
end end
end end
function PdfDocument:drawPage(target, x, y, rect, pageno, zoom, rotation, render_mode) function PdfDocument:drawPage(target, x, y, rect, pageno, zoom, rotation, gamma, render_mode)
if self.configurable.text_wrap == 1 then if self.configurable.text_wrap == 1 then
self.koptinterface:drawPage(self, target, x, y, rect, pageno, zoom, rotation, render_mode) self.koptinterface:drawPage(self, target, x, y, rect, pageno, zoom, rotation, render_mode)
else else
Document.drawPage(self, target, x, y, rect, pageno, zoom, rotation, render_mode) Document.drawPage(self, target, x, y, rect, pageno, zoom, rotation, gamma, render_mode)
end end
end end

@ -22,4 +22,39 @@ function math.oddEven(number)
end end
end end
function tmin_max(tab, func, op)
if #tab == 0 then return nil, nil end
local index, value = 1, tab[1]
for i = 2, #tab do
if func then
if func(value, tab[i]) then
index, value = i, tab[i]
end
elseif op == "min" then
if value > tab[i] then
index, value = i, tab[i]
end
elseif op == "max" then
if value < tab[i] then
index, value = i, tab[i]
end
end
end
return index, value
end
--[[
Return the minimum element of a table.
The optional argument func specifies a one-argument ordering function.
]]--
function math.tmin(tab, func)
return tmin_max(tab, func, "min")
end
--[[
Return the maximum element of a table.
The optional argument func specifies a one-argument ordering function.
]]--
function math.tmax(tab, func)
return tmin_max(tab, func, "max")
end

@ -10,36 +10,20 @@ BBoxWidget = InputContainer:new{
} }
function BBoxWidget:init() function BBoxWidget:init()
self.page_bbox = self.document:getPageBBox(self.view.state.page)
--DEBUG("used page bbox on page", self.view.state.page, self.page_bbox)
if Device:isTouchDevice() then if Device:isTouchDevice() then
self.ges_events = { self.ges_events = {
AdjustCrop = { TapAdjust = {
GestureRange:new{ GestureRange:new{
ges = "tap", ges = "tap",
range = Geom:new{ range = self.view.dimen,
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight()
}
} }
}, },
ConfirmCrop = { PanAdjust = {
GestureRange:new{ GestureRange:new{
ges = "double_tap", ges = "pan",
range = Geom:new{ range = self.view.dimen,
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight()
}
}
},
CancelCrop = {
GestureRange:new{
ges = "hold",
range = Geom:new{
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight()
}
} }
}, },
} }
@ -47,15 +31,12 @@ function BBoxWidget:init()
end end
function BBoxWidget:getSize() function BBoxWidget:getSize()
return Geom:new{ return self.view.dimen
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight()
}
end end
function BBoxWidget:paintTo(bb, x, y) function BBoxWidget:paintTo(bb, x, y)
self.screen_bbox = self.screen_bbox or self:page_to_screen() -- As getScreenBBox uses view states, screen_bbox initialization is postponed.
self.screen_bbox = self.screen_bbox or self:getScreenBBox(self.page_bbox)
local bbox = self.screen_bbox local bbox = self.screen_bbox
-- upper_left -- upper_left
bb:invertRect(bbox.x0 + self.linesize, bbox.y0, bbox.x1 - bbox.x0, self.linesize) bb:invertRect(bbox.x0 + self.linesize, bbox.y0, bbox.x1 - bbox.x0, self.linesize)
@ -66,54 +47,79 @@ function BBoxWidget:paintTo(bb, x, y)
end end
-- transform page bbox to screen bbox -- transform page bbox to screen bbox
function BBoxWidget:page_to_screen() function BBoxWidget:getScreenBBox(page_bbox)
local bbox = {} local bbox = {}
local scale = self.crop.zoom local scale = self.view.state.zoom
local screen_offset = self.crop.screen_offset local screen_offset = self.view.state.offset
DEBUG("screen offset in page_to_screen", screen_offset) --DEBUG("screen offset in page_to_screen", screen_offset)
bbox.x0 = self.page_bbox.x0 * scale + screen_offset.x bbox.x0 = page_bbox.x0 * scale + screen_offset.x
bbox.y0 = self.page_bbox.y0 * scale + screen_offset.y bbox.y0 = page_bbox.y0 * scale + screen_offset.y
bbox.x1 = self.page_bbox.x1 * scale + screen_offset.x bbox.x1 = page_bbox.x1 * scale + screen_offset.x
bbox.y1 = self.page_bbox.y1 * scale + screen_offset.y bbox.y1 = page_bbox.y1 * scale + screen_offset.y
return bbox return bbox
end end
-- transform screen bbox to page bbox -- transform screen bbox to page bbox
function BBoxWidget:screen_to_page() function BBoxWidget:getPageBBox(screen_bbox)
local bbox = {} local bbox = {}
local scale = self.crop.zoom local scale = self.view.state.zoom
local screen_offset = self.crop.screen_offset local screen_offset = self.view.state.offset
DEBUG("screen offset in screen_to_page", screen_offset) --DEBUG("screen offset in screen_to_page", screen_offset)
bbox.x0 = (self.screen_bbox.x0 - screen_offset.x) / scale bbox.x0 = (screen_bbox.x0 - screen_offset.x) / scale
bbox.y0 = (self.screen_bbox.y0 - screen_offset.y) / scale bbox.y0 = (screen_bbox.y0 - screen_offset.y) / scale
bbox.x1 = (self.screen_bbox.x1 - screen_offset.x) / scale bbox.x1 = (screen_bbox.x1 - screen_offset.x) / scale
bbox.y1 = (self.screen_bbox.y1 - screen_offset.y) / scale bbox.y1 = (screen_bbox.y1 - screen_offset.y) / scale
return bbox return bbox
end end
function BBoxWidget:onAdjustCrop(arg, ges) function BBoxWidget:inPageArea(ges)
DEBUG("adjusting crop bbox with pos", ges.pos) local offset = self.view.state.offset
local page_area = self.view.page_area
local page_dimen = Geom:new{ x = offset.x, y = offset.y, h = page_area.h, w = page_area.w}
return not ges.pos:notIntersectWith(page_dimen)
end
function BBoxWidget:adjustScreenBBox(ges, rate)
--DEBUG("adjusting crop bbox with pos", ges.pos)
if not self:inPageArea(ges) then return end
local bbox = self.screen_bbox local bbox = self.screen_bbox
local upper_left = Geom:new{ x = bbox.x0, y = bbox.y0} local upper_left = Geom:new{ x = bbox.x0, y = bbox.y0}
local upper_right = Geom:new{ x = bbox.x1, y = bbox.y0} local upper_right = Geom:new{ x = bbox.x1, y = bbox.y0}
local bottom_left = Geom:new{ x = bbox.x0, y = bbox.y1} local bottom_left = Geom:new{ x = bbox.x0, y = bbox.y1}
local bottom_right = Geom:new{ x = bbox.x1, y = bbox.y1} local bottom_right = Geom:new{ x = bbox.x1, y = bbox.y1}
local corners = {upper_left, upper_right, bottom_left, bottom_right} local upper_center = Geom:new{ x = (bbox.x0 + bbox.x1) / 2, y = bbox.y0}
table.sort(corners, function(a,b) local bottom_center = Geom:new{ x = (bbox.x0 + bbox.x1) / 2, y = bbox.y1}
return a:distance(ges.pos) < b:distance(ges.pos) local right_center = Geom:new{ x = bbox.x1, y = (bbox.y0 + bbox.y1) / 2}
local left_center = Geom:new{ x = bbox.x0, y = (bbox.y0 + bbox.y1) / 2}
local anchors = {
upper_left, upper_center, upper_right,
left_center, right_center,
bottom_left, bottom_center, bottom_right,
}
local _, nearest = math.tmin(anchors, function(a,b)
return a:distance(ges.pos) > b:distance(ges.pos)
end) end)
if corners[1] == upper_left then --DEBUG("nearest anchor", nearest)
if nearest == upper_left then
upper_left.x = ges.pos.x upper_left.x = ges.pos.x
upper_left.y = ges.pos.y upper_left.y = ges.pos.y
elseif corners[1] == bottom_right then elseif nearest == bottom_right then
bottom_right.x = ges.pos.x bottom_right.x = ges.pos.x
bottom_right.y = ges.pos.y bottom_right.y = ges.pos.y
elseif corners[1] == upper_right then elseif nearest == upper_right then
bottom_right.x = ges.pos.x bottom_right.x = ges.pos.x
upper_left.y = ges.pos.y upper_left.y = ges.pos.y
elseif corners[1] == bottom_left then elseif nearest == bottom_left then
upper_left.x = ges.pos.x upper_left.x = ges.pos.x
bottom_right.y = ges.pos.y bottom_right.y = ges.pos.y
elseif nearest == upper_center then
upper_left.y = ges.pos.y
elseif nearest == right_center then
bottom_right.x = ges.pos.x
elseif nearest == bottom_center then
bottom_right.y = ges.pos.y
elseif nearest == left_center then
upper_left.x = ges.pos.x
end end
self.screen_bbox = { self.screen_bbox = {
x0 = upper_left.x, x0 = upper_left.x,
@ -121,20 +127,30 @@ function BBoxWidget:onAdjustCrop(arg, ges)
x1 = bottom_right.x, x1 = bottom_right.x,
y1 = bottom_right.y y1 = bottom_right.y
} }
UIManager.repaint_all = true if rate then
local last_time = self.last_time or {0, 0}
local this_time = { util.gettime() }
local elap_time = (this_time[1] - last_time[1]) * 1000 + (this_time[2] - last_time[2]) / 1000 -- in millisec
if elap_time > 1000 / rate then
UIManager.repaint_all = true
self.last_time = this_time
end
else
UIManager.repaint_all = true
end
end
function BBoxWidget:getModifiedPageBBox()
return self:getPageBBox(self.screen_bbox)
end end
function BBoxWidget:onConfirmCrop() function BBoxWidget:onTapAdjust(arg, ges)
self.page_bbox = self:screen_to_page() self:adjustScreenBBox(ges)
--DEBUG("new bbox", self.page_bbox) return true
UIManager:close(self)
self.ui:handleEvent(Event:new("BBoxUpdate"), self.page_bbox)
self.document.bbox[self.pageno] = self.page_bbox
self.document.bbox[math.oddEven(self.pageno)] = self.page_bbox
self.ui:handleEvent(Event:new("ExitPageCrop", true))
end end
function BBoxWidget:onCancelCrop() function BBoxWidget:onPanAdjust(arg, ges)
UIManager:close(self) -- up to 3 updates per second
self.ui:handleEvent(Event:new("ExitPageCrop")) self:adjustScreenBBox(ges, 3.0)
return true
end end

@ -3,27 +3,37 @@ require "ui/widget"
--[[ --[[
a button widget a button widget
]] ]]
Button = WidgetContainer:new{ Button = InputContainer:new{
text = nil, -- mandatory text = nil, -- mandatory
preselect = false preselect = false,
callback = nil,
margin = 0,
bordersize = 3,
background = 0,
radius = 15,
padding = 2,
width = nil,
text_font_face = "cfont",
text_font_size = 20,
} }
function Button:init() function Button:init()
local text_widget = TextWidget:new{
text = self.text,
face = Font:getFace(self.text_font_face, self.text_font_size)
}
local text_size = text_widget:getSize()
-- set FrameContainer content -- set FrameContainer content
self[1] = FrameContainer:new{ self[1] = FrameContainer:new{
margin = 0, margin = self.margin,
bordersize = 3, bordersize = self.bordersize,
background = 0, background = self.background,
radius = 15, radius = self.radius,
padding = 2, padding = self.padding,
HorizontalGroup:new{ HorizontalGroup:new{
HorizontalSpan:new{ width = 8 }, HorizontalSpan:new{ width = (self.width - text_size.w)/2 },
TextWidget:new{ text_widget,
text = self.text, HorizontalSpan:new{ width = (self.width - text_size.w)/2 },
face = Font:getFace("cfont", 20)
},
HorizontalSpan:new{ width = 8 },
} }
} }
if self.preselect then if self.preselect then
@ -31,6 +41,18 @@ function Button:init()
else else
self[1].color = 5 self[1].color = 5
end end
self.dimen = self[1]:getSize()
if Device:isTouchDevice() then
self.ges_events = {
TapSelect = {
GestureRange:new{
ges = "tap",
range = self.dimen,
},
doc = "Tap Button",
},
}
end
end end
function Button:onFocus() function Button:onFocus()
@ -43,3 +65,7 @@ function Button:onUnfocus()
return true return true
end end
function Button:onTapSelect()
self.callback()
return true
end

@ -1,12 +1,61 @@
require "ui/widget"
require "ui/bbox" require "ui/bbox"
PageCropDialog = VerticalGroup:new{
ok_text = "OK",
cancel_text = "Cancel",
ok_callback = function() end,
cancel_callback = function() end,
button_width = math.floor(70*Screen:getDPI()/167),
}
function PageCropDialog:init()
local horizontal_group = HorizontalGroup:new{}
local ok_button = Button:new{
text = self.ok_text,
callback = self.ok_callback,
width = self.button_width,
bordersize = 2,
radius = 7,
text_font_face = "cfont",
text_font_size = 20,
}
local cancel_button = Button:new{
text = self.cancel_text,
callback = self.cancel_callback,
width = self.button_width,
bordersize = 2,
radius = 7,
text_font_face = "cfont",
text_font_size = 20,
}
local ok_container = RightContainer:new{
dimen = Geom:new{ w = Screen:getWidth()*0.33, h = Screen:getHeight()/12},
ok_button,
}
local cancel_container = LeftContainer:new{
dimen = Geom:new{ w = Screen:getWidth()*0.33, h = Screen:getHeight()/12},
cancel_button,
}
table.insert(horizontal_group, ok_container)
table.insert(horizontal_group, HorizontalSpan:new{ width = Screen:getWidth()*0.34})
table.insert(horizontal_group, cancel_container)
self[2] = FrameContainer:new{
background = 0,
bordersize = 0,
horizontal_group,
}
end
ReaderCropping = InputContainer:new{} ReaderCropping = InputContainer:new{}
function ReaderCropping:onPageCrop(mode) function ReaderCropping:onPageCrop(mode)
if mode == "auto" then return end if mode == "auto" then return end
self.orig_reflow_mode = self.document.configurable.text_wrap
self.ui:handleEvent(Event:new("CloseConfig")) self.ui:handleEvent(Event:new("CloseConfig"))
self.cropping_offset = true -- backup original zoom mode as cropping use "page" zoom mode
self.orig_zoom_mode = self.view.zoom_mode
-- backup original reflow mode as cropping use non-reflow mode
self.orig_reflow_mode = self.document.configurable.text_wrap
if self.orig_reflow_mode == 1 then if self.orig_reflow_mode == 1 then
self.document.configurable.text_wrap = 0 self.document.configurable.text_wrap = 0
-- if we are in reflow mode, then we are already in page -- if we are in reflow mode, then we are already in page
@ -15,24 +64,49 @@ function ReaderCropping:onPageCrop(mode)
else else
self.ui:handleEvent(Event:new("SetZoomMode", "page", "cropping")) self.ui:handleEvent(Event:new("SetZoomMode", "page", "cropping"))
end end
local ubbox = self.document:getPageBBox(self.current_page) self.orig_view_dimen = self.view.dimen:copy()
--DEBUG("used page bbox", ubbox) self.ui:handleEvent(Event:new("SetDimensions",
self.crop_bbox = BBoxWidget:new{ Geom:new{w = Screen:getWidth(), h = Screen:getHeight()*11/12})
page_bbox = ubbox, )
self.bbox_widget = BBoxWidget:new{
ui = self.ui, ui = self.ui,
crop = self, view = self.view,
document = self.document, document = self.document,
pageno = self.current_page,
} }
UIManager:show(self.crop_bbox) self.crop_dialog = PageCropDialog:new{
self.bbox_widget,
ok_callback = function() self:confirmPageCrop() end,
cancel_callback = function() self:cancelPageCrop() end,
}
UIManager:show(self.crop_dialog)
return true
end
function ReaderCropping:confirmPageCrop()
--DEBUG("new bbox", new_bbox)
UIManager:close(self.crop_dialog)
local new_bbox = self.bbox_widget:getModifiedPageBBox()
self.ui:handleEvent(Event:new("BBoxUpdate"), new_bbox)
local pageno = self.view.state.page
self.document.bbox[pageno] = new_bbox
self.document.bbox[math.oddEven(pageno)] = new_bbox
self:exitPageCrop(true)
return true return true
end end
function ReaderCropping:onExitPageCrop(confirmed) function ReaderCropping:cancelPageCrop()
UIManager:close(self.crop_dialog)
self:exitPageCrop(false)
return true
end
function ReaderCropping:exitPageCrop(confirmed)
self.ui:handleEvent(Event:new("SetDimensions", self.orig_view_dimen))
self.document.configurable.text_wrap = self.orig_reflow_mode self.document.configurable.text_wrap = self.orig_reflow_mode
self.view:recalculate() self.view:recalculate()
-- Exiting should have the same look and feel with entering. -- Exiting should have the same look and feel with entering.
if self.orig_reflow_mode == 1 then if self.orig_reflow_mode == 1 then
-- restore original reflow mode
self.document.configurable.text_wrap = 1 self.document.configurable.text_wrap = 1
self.view:recalculate() self.view:recalculate()
else else
@ -44,38 +118,10 @@ function ReaderCropping:onExitPageCrop(confirmed)
end end
end end
UIManager.repaint_all = true UIManager.repaint_all = true
return true
end
function ReaderCropping:onPageUpdate(page_no)
--DEBUG("page updated to", page_no)
self.current_page = page_no
end
function ReaderCropping:onZoomUpdate(zoom)
--DEBUG("zoom updated to", zoom)
self.zoom = zoom
end
function ReaderCropping:onScreenOffsetUpdate(screen_offset)
if self.cropping_offset then
--DEBUG("offset updated to", screen_offset)
self.screen_offset = screen_offset
self.cropping_offset = false
end
end
function ReaderCropping:onSetZoomMode(mode, orig)
if orig ~= "cropping" and mode then
--DEBUG("backup zoom mode", mode)
self.orig_zoom_mode = mode
end
end end
function ReaderCropping:onReadSettings(config) function ReaderCropping:onReadSettings(config)
local bbox = config:readSetting("bbox") self.document.bbox = config:readSetting("bbox")
self.document.bbox = bbox
--DEBUG("read document bbox", self.document.bbox)
end end
function ReaderCropping:onCloseDocument() function ReaderCropping:onCloseDocument()

@ -1,22 +1,34 @@
ReaderKoptinterface = InputContainer:new{} ReaderKoptListener = EventListener:new{}
function ReaderKoptinterface:onReadSettings(config) function ReaderKoptListener:setZoomMode(zoom_mode)
self.normal_zoom_mode = config:readSetting("zoom_mode") or "page"
if self.document.configurable.text_wrap == 1 then if self.document.configurable.text_wrap == 1 then
self.ui:handleEvent(Event:new("SetZoomMode", "page", "koptinterface")) -- in reflow mode only "page" zoom mode is valid so override any other zoom mode
self.ui:handleEvent(Event:new("SetZoomMode", "page", "koptlistener"))
else else
self.ui:handleEvent(Event:new("SetZoomMode", self.normal_zoom_mode, "koptinterface")) self.ui:handleEvent(Event:new("SetZoomMode", zoom_mode, "koptlistener"))
end end
end end
function ReaderKoptinterface:onRestoreZoomMode(zoom_mode) function ReaderKoptListener:onReadSettings(config)
self.ui:handleEvent(Event:new("SetZoomMode", zoom_mode or self.normal_zoom_mode, "koptinterface")) -- normal zoom mode is zoom mode used in non-reflow mode.
self.normal_zoom_mode = config:readSetting("normal_zoom_mode") or "page"
self:setZoomMode(self.normal_zoom_mode)
end
function ReaderKoptListener:onCloseDocument()
self.ui.doc_settings:saveSetting("normal_zoom_mode", self.normal_zoom_mode)
end
function ReaderKoptListener:onRestoreZoomMode()
-- "RestoreZoomMode" event is sent when reflow mode on/off is toggled
self:setZoomMode(self.normal_zoom_mode)
return true return true
end end
function ReaderKoptinterface:onSetZoomMode(zoom_mode, orig) function ReaderKoptListener:onSetZoomMode(zoom_mode, orig)
if orig ~= "koptinterface" then if orig == "koptlistener" then return end
self.normal_zoom_mode = zoom_mode -- capture zoom mode set outside of koptlistener which should always be normal zoom mode
end self.normal_zoom_mode = zoom_mode
self:setZoomMode(self.normal_zoom_mode)
end end

@ -7,7 +7,8 @@ ReaderView = WidgetContainer:new{
pos = 0, pos = 0,
zoom = 1.0, zoom = 1.0,
rotation = 0, rotation = 0,
offset = {}, gamma = 1.0,
offset = nil,
bbox = nil, bbox = nil,
}, },
outer_page_color = 7, outer_page_color = 7,
@ -39,7 +40,7 @@ function ReaderView:paintTo(bb, x, y)
bb:paintRect(x, y, inner_offset.x, self.ui.dimen.h, self.outer_page_color) bb:paintRect(x, y, inner_offset.x, self.ui.dimen.h, self.outer_page_color)
bb:paintRect(x + self.ui.dimen.w - inner_offset.x - 1, y, inner_offset.x + 1, self.ui.dimen.h, self.outer_page_color) bb:paintRect(x + self.ui.dimen.w - inner_offset.x - 1, y, inner_offset.x + 1, self.ui.dimen.h, self.outer_page_color)
end end
self.ui:handleEvent(Event:new("ScreenOffsetUpdate", inner_offset)) self.state.offset = inner_offset
-- draw content -- draw content
if self.ui.document.info.has_pages then if self.ui.document.info.has_pages then
self.ui.document:drawPage( self.ui.document:drawPage(
@ -50,6 +51,7 @@ function ReaderView:paintTo(bb, x, y)
self.state.page, self.state.page,
self.state.zoom, self.state.zoom,
self.state.rotation, self.state.rotation,
self.state.gamma,
self.render_mode) self.render_mode)
UIManager:scheduleIn(0, function() self.ui:handleEvent(Event:new("HintPage")) end) UIManager:scheduleIn(0, function() self.ui:handleEvent(Event:new("HintPage")) end)
else else
@ -136,6 +138,10 @@ function ReaderView:onSetScreenMode(new_mode)
Screen:setScreenMode(new_mode) Screen:setScreenMode(new_mode)
self.ui:handleEvent(Event:new("SetDimensions", Screen:getSize())) self.ui:handleEvent(Event:new("SetDimensions", Screen:getSize()))
end end
if new_mode == "landscape" and self.document.info.has_pages then
self.ui:handleEvent(Event:new("SetZoomMode", "contentwidth"))
end
return true return true
end end
@ -160,6 +166,7 @@ function ReaderView:onReadSettings(config)
table.insert(self.ui.postInitCallback, function() table.insert(self.ui.postInitCallback, function()
self:onSetScreenMode(screen_mode) end) self:onSetScreenMode(screen_mode) end)
end end
self.state.gamma = config:readSetting("gamma") or 1.0
end end
function ReaderView:onPageUpdate(new_page_no) function ReaderView:onPageUpdate(new_page_no)
@ -186,12 +193,17 @@ function ReaderView:onRotationUpdate(rotation)
self:recalculate() self:recalculate()
end end
function ReaderView:onGammaUpdate(gamma)
self.state.gamma = gamma
end
function ReaderView:onHintPage() function ReaderView:onHintPage()
if self.state.page < self.ui.document.info.number_of_pages then if self.state.page < self.ui.document.info.number_of_pages then
self.ui.document:hintPage( self.ui.document:hintPage(
self.state.page+1, self.state.page+1,
self.state.zoom, self.state.zoom,
self.state.rotation, self.state.rotation,
self.state.gamma,
self.render_mode) self.render_mode)
end end
return true return true
@ -207,4 +219,5 @@ end
function ReaderView:onCloseDocument() function ReaderView:onCloseDocument()
self.ui.doc_settings:saveSetting("render_mode", self.render_mode) self.ui.doc_settings:saveSetting("render_mode", self.render_mode)
self.ui.doc_settings:saveSetting("screen_mode", self.screen_mode) self.ui.doc_settings:saveSetting("screen_mode", self.screen_mode)
self.ui.doc_settings:saveSetting("gamma", self.state.gamma)
end end

@ -95,6 +95,7 @@ function ReaderZooming:onZoom(direction)
end end
function ReaderZooming:onSetZoomMode(new_mode) function ReaderZooming:onSetZoomMode(new_mode)
self.view.zoom_mode = new_mode
if self.zoom_mode ~= new_mode then if self.zoom_mode ~= new_mode then
DEBUG("setting zoom mode to", new_mode) DEBUG("setting zoom mode to", new_mode)
self.zoom_mode = new_mode self.zoom_mode = new_mode

@ -160,13 +160,13 @@ function ReaderUI:init()
} }
table.insert(self, config_dialog) table.insert(self, config_dialog)
-- koptinterface controller -- koptinterface controller
local koptinterface = ReaderKoptinterface:new{ local koptlistener = ReaderKoptListener:new{
dialog = self.dialog, dialog = self.dialog,
view = self[1], view = self[1],
ui = self, ui = self,
document = self.document, document = self.document,
} }
table.insert(self, koptinterface) table.insert(self, koptlistener)
end end
--DEBUG(self.doc_settings) --DEBUG(self.doc_settings)
-- we only read settings after all the widgets are initialized -- we only read settings after all the widgets are initialized

@ -7,6 +7,31 @@ require "ui/inputevent"
require "ui/gesturedetector" require "ui/gesturedetector"
require "ui/font" require "ui/font"
--[[
The EventListener is an interface that handles events
EventListeners have a rudimentary event handler/dispatcher that
will call a method "onEventName" for an event with name
"EventName"
]]
EventListener = {}
function EventListener:new(o)
local o = o or {}
setmetatable(o, self)
self.__index = self
if o.init then o:init() end
return o
end
function EventListener:handleEvent(event)
if self[event.handler] then
return self[event.handler](self, unpack(event.args))
end
end
--[[ --[[
This is a generic Widget interface This is a generic Widget interface
@ -18,7 +43,7 @@ if the table that was given to us as parameter has an "init"
method, it will be called. use this to set _instance_ variables method, it will be called. use this to set _instance_ variables
rather than class variables. rather than class variables.
]] ]]
Widget = {} Widget = EventListener:new()
function Widget:new(o) function Widget:new(o)
local o = o or {} local o = o or {}
@ -40,19 +65,6 @@ end
function Widget:paintTo(bb, x, y) function Widget:paintTo(bb, x, y)
end end
--[[
Widgets have a rudimentary event handler/dispatcher that
will call a method "onEventName" for an event with name
"EventName"
These methods
]]
function Widget:handleEvent(event)
if self[event.handler] then
return self[event.handler](self, unpack(event.args))
end
end
--[[ --[[
WidgetContainer is a container for another Widget WidgetContainer is a container for another Widget
]] ]]
@ -151,6 +163,20 @@ function CenterContainer:paintTo(bb, x, y)
self[1]:paintTo(bb, x_pos, y_pos) self[1]:paintTo(bb, x_pos, y_pos)
end end
--[[
LeftContainer aligns its content (1 widget) at the left of its own dimensions
]]
LeftContainer = WidgetContainer:new()
function LeftContainer:paintTo(bb, x, y)
local contentSize = self[1]:getSize()
if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
-- throw error? paint to scrap buffer and blit partially?
-- for now, we ignore this
end
self[1]:paintTo(bb, x , y + (self.dimen.h - contentSize.h)/2)
end
--[[ --[[
RightContainer aligns its content (1 widget) at the right of its own dimensions RightContainer aligns its content (1 widget) at the right of its own dimensions
]] ]]
@ -181,7 +207,7 @@ FrameContainer = WidgetContainer:new{
function FrameContainer:getSize() function FrameContainer:getSize()
local content_size =self[1]:getSize() local content_size =self[1]:getSize()
return { return Geom:new{
w = content_size.w + ( self.margin + self.bordersize + self.padding ) * 2, w = content_size.w + ( self.margin + self.bordersize + self.padding ) * 2,
h = content_size.h + ( self.margin + self.bordersize + self.padding ) * 2 h = content_size.h + ( self.margin + self.bordersize + self.padding ) * 2
} }

Loading…
Cancel
Save