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 = {
prefix = 'copt',
default_options = {
},
{
icon = "resources/icons/appbar.transform.rotate.right.large.png",
options = {

@ -72,19 +72,19 @@ function DjvuDocument:getPageDimensions(pageno, zoom, rotation)
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
return self.koptinterface:renderPage(self, pageno, rect, zoom, rotation, render_mode)
else
return Document.renderPage(self, pageno, rect, zoom, rotation, render_mode)
return Document.renderPage(self, pageno, rect, zoom, rotation, gamma, render_mode)
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
self.koptinterface:drawPage(self, target, x, y, rect, pageno, zoom, rotation, render_mode)
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

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

@ -6,19 +6,6 @@ require "ui/reader/readerconfig"
KoptOptions = {
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",
options = {
@ -117,6 +104,8 @@ KoptOptions = {
item_align_center = 0.8,
values = {2.0, 1.5, 1.0, 0.5, 0.2},
default_value = 1.0,
event = "GammaUpdate",
args = {0.5, 0.8, 1.0, 2.0, 4.0},
}
}
},
@ -135,7 +124,6 @@ KoptOptions = {
},
{
event = "RestoreZoomMode",
args = {"page", nil},
},
}
},

@ -68,19 +68,19 @@ function PdfDocument:getPageDimensions(pageno, zoom, rotation)
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
return self.koptinterface:renderPage(self, pageno, rect, zoom, rotation, render_mode)
else
return Document.renderPage(self, pageno, rect, zoom, rotation, render_mode)
return Document.renderPage(self, pageno, rect, zoom, rotation, gamma, render_mode)
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
self.koptinterface:drawPage(self, target, x, y, rect, pageno, zoom, rotation, render_mode)
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

@ -22,4 +22,39 @@ function math.oddEven(number)
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()
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
self.ges_events = {
AdjustCrop = {
TapAdjust = {
GestureRange:new{
ges = "tap",
range = Geom:new{
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight()
}
range = self.view.dimen,
}
},
ConfirmCrop = {
PanAdjust = {
GestureRange:new{
ges = "double_tap",
range = Geom:new{
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()
}
ges = "pan",
range = self.view.dimen,
}
},
}
@ -47,15 +31,12 @@ function BBoxWidget:init()
end
function BBoxWidget:getSize()
return Geom:new{
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight()
}
return self.view.dimen
end
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
-- upper_left
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
-- transform page bbox to screen bbox
function BBoxWidget:page_to_screen()
function BBoxWidget:getScreenBBox(page_bbox)
local bbox = {}
local scale = self.crop.zoom
local screen_offset = self.crop.screen_offset
DEBUG("screen offset in page_to_screen", screen_offset)
bbox.x0 = self.page_bbox.x0 * scale + screen_offset.x
bbox.y0 = self.page_bbox.y0 * scale + screen_offset.y
bbox.x1 = self.page_bbox.x1 * scale + screen_offset.x
bbox.y1 = self.page_bbox.y1 * scale + screen_offset.y
local scale = self.view.state.zoom
local screen_offset = self.view.state.offset
--DEBUG("screen offset in page_to_screen", screen_offset)
bbox.x0 = page_bbox.x0 * scale + screen_offset.x
bbox.y0 = page_bbox.y0 * scale + screen_offset.y
bbox.x1 = page_bbox.x1 * scale + screen_offset.x
bbox.y1 = page_bbox.y1 * scale + screen_offset.y
return bbox
end
-- transform screen bbox to page bbox
function BBoxWidget:screen_to_page()
function BBoxWidget:getPageBBox(screen_bbox)
local bbox = {}
local scale = self.crop.zoom
local screen_offset = self.crop.screen_offset
DEBUG("screen offset in screen_to_page", screen_offset)
bbox.x0 = (self.screen_bbox.x0 - screen_offset.x) / scale
bbox.y0 = (self.screen_bbox.y0 - screen_offset.y) / scale
bbox.x1 = (self.screen_bbox.x1 - screen_offset.x) / scale
bbox.y1 = (self.screen_bbox.y1 - screen_offset.y) / scale
local scale = self.view.state.zoom
local screen_offset = self.view.state.offset
--DEBUG("screen offset in screen_to_page", screen_offset)
bbox.x0 = (screen_bbox.x0 - screen_offset.x) / scale
bbox.y0 = (screen_bbox.y0 - screen_offset.y) / scale
bbox.x1 = (screen_bbox.x1 - screen_offset.x) / scale
bbox.y1 = (screen_bbox.y1 - screen_offset.y) / scale
return bbox
end
function BBoxWidget:onAdjustCrop(arg, ges)
DEBUG("adjusting crop bbox with pos", ges.pos)
function BBoxWidget:inPageArea(ges)
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 upper_left = Geom:new{ x = bbox.x0, 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_right = Geom:new{ x = bbox.x1, y = bbox.y1}
local corners = {upper_left, upper_right, bottom_left, bottom_right}
table.sort(corners, function(a,b)
return a:distance(ges.pos) < b:distance(ges.pos)
local upper_center = Geom:new{ x = (bbox.x0 + bbox.x1) / 2, y = bbox.y0}
local bottom_center = Geom:new{ x = (bbox.x0 + bbox.x1) / 2, y = bbox.y1}
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)
if corners[1] == upper_left then
--DEBUG("nearest anchor", nearest)
if nearest == upper_left then
upper_left.x = ges.pos.x
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.y = ges.pos.y
elseif corners[1] == upper_right then
elseif nearest == upper_right then
bottom_right.x = ges.pos.x
upper_left.y = ges.pos.y
elseif corners[1] == bottom_left then
elseif nearest == bottom_left then
upper_left.x = ges.pos.x
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
self.screen_bbox = {
x0 = upper_left.x,
@ -121,20 +127,30 @@ function BBoxWidget:onAdjustCrop(arg, ges)
x1 = bottom_right.x,
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
function BBoxWidget:onConfirmCrop()
self.page_bbox = self:screen_to_page()
--DEBUG("new bbox", self.page_bbox)
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))
function BBoxWidget:onTapAdjust(arg, ges)
self:adjustScreenBBox(ges)
return true
end
function BBoxWidget:onCancelCrop()
UIManager:close(self)
self.ui:handleEvent(Event:new("ExitPageCrop"))
function BBoxWidget:onPanAdjust(arg, ges)
-- up to 3 updates per second
self:adjustScreenBBox(ges, 3.0)
return true
end

@ -3,27 +3,37 @@ require "ui/widget"
--[[
a button widget
]]
Button = WidgetContainer:new{
Button = InputContainer:new{
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()
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
self[1] = FrameContainer:new{
margin = 0,
bordersize = 3,
background = 0,
radius = 15,
padding = 2,
margin = self.margin,
bordersize = self.bordersize,
background = self.background,
radius = self.radius,
padding = self.padding,
HorizontalGroup:new{
HorizontalSpan:new{ width = 8 },
TextWidget:new{
text = self.text,
face = Font:getFace("cfont", 20)
},
HorizontalSpan:new{ width = 8 },
HorizontalSpan:new{ width = (self.width - text_size.w)/2 },
text_widget,
HorizontalSpan:new{ width = (self.width - text_size.w)/2 },
}
}
if self.preselect then
@ -31,6 +41,18 @@ function Button:init()
else
self[1].color = 5
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
function Button:onFocus()
@ -43,3 +65,7 @@ function Button:onUnfocus()
return true
end
function Button:onTapSelect()
self.callback()
return true
end

@ -1,12 +1,61 @@
require "ui/widget"
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{}
function ReaderCropping:onPageCrop(mode)
if mode == "auto" then return end
self.orig_reflow_mode = self.document.configurable.text_wrap
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
self.document.configurable.text_wrap = 0
-- if we are in reflow mode, then we are already in page
@ -15,24 +64,49 @@ function ReaderCropping:onPageCrop(mode)
else
self.ui:handleEvent(Event:new("SetZoomMode", "page", "cropping"))
end
local ubbox = self.document:getPageBBox(self.current_page)
--DEBUG("used page bbox", ubbox)
self.crop_bbox = BBoxWidget:new{
page_bbox = ubbox,
self.orig_view_dimen = self.view.dimen:copy()
self.ui:handleEvent(Event:new("SetDimensions",
Geom:new{w = Screen:getWidth(), h = Screen:getHeight()*11/12})
)
self.bbox_widget = BBoxWidget:new{
ui = self.ui,
crop = self,
view = self.view,
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
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.view:recalculate()
-- Exiting should have the same look and feel with entering.
if self.orig_reflow_mode == 1 then
-- restore original reflow mode
self.document.configurable.text_wrap = 1
self.view:recalculate()
else
@ -44,38 +118,10 @@ function ReaderCropping:onExitPageCrop(confirmed)
end
end
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
function ReaderCropping:onReadSettings(config)
local bbox = config:readSetting("bbox")
self.document.bbox = bbox
--DEBUG("read document bbox", self.document.bbox)
self.document.bbox = config:readSetting("bbox")
end
function ReaderCropping:onCloseDocument()

@ -1,22 +1,34 @@
ReaderKoptinterface = InputContainer:new{}
ReaderKoptListener = EventListener:new{}
function ReaderKoptinterface:onReadSettings(config)
self.normal_zoom_mode = config:readSetting("zoom_mode") or "page"
function ReaderKoptListener:setZoomMode(zoom_mode)
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
self.ui:handleEvent(Event:new("SetZoomMode", self.normal_zoom_mode, "koptinterface"))
self.ui:handleEvent(Event:new("SetZoomMode", zoom_mode, "koptlistener"))
end
end
function ReaderKoptinterface:onRestoreZoomMode(zoom_mode)
self.ui:handleEvent(Event:new("SetZoomMode", zoom_mode or self.normal_zoom_mode, "koptinterface"))
function ReaderKoptListener:onReadSettings(config)
-- 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
end
function ReaderKoptinterface:onSetZoomMode(zoom_mode, orig)
if orig ~= "koptinterface" then
self.normal_zoom_mode = zoom_mode
end
function ReaderKoptListener:onSetZoomMode(zoom_mode, orig)
if orig == "koptlistener" then return end
-- capture zoom mode set outside of koptlistener which should always be normal zoom mode
self.normal_zoom_mode = zoom_mode
self:setZoomMode(self.normal_zoom_mode)
end

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

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

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

@ -7,6 +7,31 @@ require "ui/inputevent"
require "ui/gesturedetector"
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
@ -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
rather than class variables.
]]
Widget = {}
Widget = EventListener:new()
function Widget:new(o)
local o = o or {}
@ -40,19 +65,6 @@ end
function Widget:paintTo(bb, x, y)
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
]]
@ -151,6 +163,20 @@ function CenterContainer:paintTo(bb, x, y)
self[1]:paintTo(bb, x_pos, y_pos)
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
]]
@ -181,7 +207,7 @@ FrameContainer = WidgetContainer:new{
function FrameContainer:getSize()
local content_size =self[1]:getSize()
return {
return Geom:new{
w = content_size.w + ( self.margin + self.bordersize + self.padding ) * 2,
h = content_size.h + ( self.margin + self.bordersize + self.padding ) * 2
}

Loading…
Cancel
Save