mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
implement full pageturn by viewport for all modes
* add notIntersectWith method for Geom * add math.roundAwayFromZero in geometry.lua * Readerview:recalculate now signals ViewRecalculate event. For now, this event is only usefull for ReaderPaging
This commit is contained in:
@@ -137,6 +137,19 @@ function Geom:intersect(rect_b)
|
||||
return intersected
|
||||
end
|
||||
|
||||
--[[
|
||||
return true if self does not share any area with rect_b
|
||||
]]--
|
||||
function Geom:notIntersectWith(rect_b)
|
||||
if (self.x >= (rect_b.x + rect_b.w))
|
||||
or (self.y >= (rect_b.y + rect_b.h))
|
||||
or (rect_b.x >= (self.x + self.w))
|
||||
or (rect_b.y >= (self.y + self.h)) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
--[[
|
||||
set size of dimension or rectangle to size of given dimension/rectangle
|
||||
]]--
|
||||
@@ -245,3 +258,20 @@ function Geom:offsetWithin(rect_b, dx, dy)
|
||||
self.y = rect_b.y + rect_b.h - self.h
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--[[
|
||||
Simple math helper function
|
||||
]]--
|
||||
|
||||
function math.roundAwayFromZero(num)
|
||||
if num > 0 then
|
||||
return math.ceil(num)
|
||||
else
|
||||
return math.floor(num)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
ReaderPaging = InputContainer:new{
|
||||
current_page = 0,
|
||||
number_of_pages = 0
|
||||
number_of_pages = 0,
|
||||
visible_area = nil,
|
||||
page_area = nil,
|
||||
}
|
||||
|
||||
function ReaderPaging:init()
|
||||
@@ -85,10 +87,21 @@ function ReaderPaging:onReadSettings(config)
|
||||
self:gotoPage(config:readSetting("last_page") or 1)
|
||||
end
|
||||
|
||||
function ReaderPaging:onZoomModeUpdate(new_mode)
|
||||
-- we need to remember zoom mode to handle page turn event
|
||||
self.zoom_mode = new_mode
|
||||
end
|
||||
|
||||
function ReaderPaging:onPageUpdate(new_page_no)
|
||||
self.current_page = new_page_no
|
||||
end
|
||||
|
||||
function ReaderPaging:onViewRecalculate(visible_area, page_area)
|
||||
-- we need to remember areas to handle page turn event
|
||||
self.visible_area = visible_area
|
||||
self.page_area = page_area
|
||||
end
|
||||
|
||||
function ReaderPaging:onGotoPercent(percent)
|
||||
DEBUG("goto document offset in percent:", percent)
|
||||
local dest = math.floor(self.number_of_pages * percent / 100)
|
||||
@@ -102,7 +115,47 @@ end
|
||||
|
||||
function ReaderPaging:onGotoPageRel(diff)
|
||||
DEBUG("goto relative page:", diff)
|
||||
self:gotoPage(self.current_page + diff)
|
||||
local new_va = self.visible_area:copy()
|
||||
local x_pan_off, y_pan_off = 0, 0
|
||||
|
||||
if self.zoom_mode:find("width") then
|
||||
y_pan_off = self.visible_area.h * diff
|
||||
elseif self.zoom_mode:find("height") then
|
||||
x_pan_off = self.visible_area.w * diff
|
||||
else
|
||||
-- must be fit content or page zoom mode
|
||||
if self.visible_area.w == self.page_area.w then
|
||||
y_pan_off = self.visible_area.h * diff
|
||||
else
|
||||
x_pan_off = self.visible_area.w * diff
|
||||
end
|
||||
end
|
||||
|
||||
-- adjust offset to help with page turn decision
|
||||
x_pan_off = math.roundAwayFromZero(x_pan_off)
|
||||
y_pan_off = math.roundAwayFromZero(y_pan_off)
|
||||
new_va.x = math.roundAwayFromZero(self.visible_area.x+x_pan_off)
|
||||
new_va.y = math.roundAwayFromZero(self.visible_area.y+y_pan_off)
|
||||
|
||||
if (new_va:notIntersectWith(self.page_area)) then
|
||||
self:gotoPage(self.current_page + diff)
|
||||
-- if we are going back to previous page, reset
|
||||
-- view to bottom of previous page
|
||||
if x_pan_off < 0 then
|
||||
self.view:PanningUpdate(self.page_area.w, 0)
|
||||
elseif y_pan_off < 0 then
|
||||
self.view:PanningUpdate(0, self.page_area.h)
|
||||
end
|
||||
else
|
||||
-- fit new view area into page area
|
||||
new_va:offsetWithin(self.page_area, 0, 0)
|
||||
self.view:PanningUpdate(
|
||||
new_va.x - self.visible_area.x,
|
||||
new_va.y - self.visible_area.y)
|
||||
-- update self.visible_area
|
||||
self.visible_area = new_va
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@ function ReaderView:paintTo(bb, x, y)
|
||||
self.state.zoom,
|
||||
self.state.rotation,
|
||||
self.render_mode)
|
||||
self:recalculate()
|
||||
else
|
||||
self.ui.document:drawCurrentView(
|
||||
bb,
|
||||
@@ -81,6 +80,8 @@ function ReaderView:recalculate()
|
||||
else
|
||||
self.visible_area:setSizeTo(self.dimen)
|
||||
end
|
||||
self.ui:handleEvent(
|
||||
Event:new("ViewRecalculate", self.visible_area, self.page_area))
|
||||
-- flag a repaint so self:paintTo will be called
|
||||
UIManager:setDirty(self.dialog)
|
||||
end
|
||||
|
||||
@@ -2,35 +2,43 @@ ReaderZooming = InputContainer:new{
|
||||
key_events = {
|
||||
ZoomIn = {
|
||||
{ "Shift", Input.group.PgFwd },
|
||||
doc = "zoom in", event = "Zoom", args = "in"
|
||||
doc = "zoom in",
|
||||
event = "Zoom", args = "in"
|
||||
},
|
||||
ZoomOut = {
|
||||
{ "Shift", Input.group.PgBack },
|
||||
doc = "zoom out", event = "Zoom", args = "out"
|
||||
doc = "zoom out",
|
||||
event = "Zoom", args = "out"
|
||||
},
|
||||
ZoomToFitPage = {
|
||||
{ "A" },
|
||||
doc = "zoom to fit page", event = "SetZoomMode", args = "page"
|
||||
doc = "zoom to fit page",
|
||||
event = "SetZoomMode", args = "page"
|
||||
},
|
||||
ZoomToFitContent = {
|
||||
{ "Shift", "A" },
|
||||
doc = "zoom to fit content", event = "SetZoomMode", args = "content"
|
||||
doc = "zoom to fit content",
|
||||
event = "SetZoomMode", args = "content"
|
||||
},
|
||||
ZoomToFitPageWidth = {
|
||||
{ "S" },
|
||||
doc = "zoom to fit page width", event = "SetZoomMode", args = "pagewidth"
|
||||
doc = "zoom to fit page width",
|
||||
event = "SetZoomMode", args = "pagewidth"
|
||||
},
|
||||
ZoomToFitContentWidth = {
|
||||
{ "Shift", "S" },
|
||||
doc = "zoom to fit content width", event = "SetZoomMode", args = "contentwidth"
|
||||
doc = "zoom to fit content width",
|
||||
event = "SetZoomMode", args = "contentwidth"
|
||||
},
|
||||
ZoomToFitPageHeight = {
|
||||
{ "D" },
|
||||
doc = "zoom to fit page height", event = "SetZoomMode", args = "pageheight"
|
||||
doc = "zoom to fit page height",
|
||||
event = "SetZoomMode", args = "pageheight"
|
||||
},
|
||||
ZoomToFitContentHeight = {
|
||||
{ "Shift", "D" },
|
||||
doc = "zoom to fit content height", event = "SetZoomMode", args = "contentheight"
|
||||
doc = "zoom to fit content height",
|
||||
event = "SetZoomMode", args = "contentheight"
|
||||
},
|
||||
},
|
||||
zoom = 1.0,
|
||||
@@ -103,11 +111,12 @@ function ReaderZooming:onZoom(direction)
|
||||
return true
|
||||
end
|
||||
|
||||
function ReaderZooming:onSetZoomMode(what)
|
||||
if self.zoom_mode ~= what then
|
||||
DEBUG("setting zoom mode to", what)
|
||||
self.zoom_mode = what
|
||||
function ReaderZooming:onSetZoomMode(new_mode)
|
||||
if self.zoom_mode ~= new_mode then
|
||||
DEBUG("setting zoom mode to", new_mode)
|
||||
self.zoom_mode = new_mode
|
||||
self:setZoom()
|
||||
self.ui:handleEvent(Event:new("ZoomModeUpdate", new_mode))
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user