mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
As most pages are portrait there is no reason to fit "portrait" page on "landscape" screen. And "pagewidth" is used less often than "contentwidth". So "contentwidth" is choosed to set zoom mode on landscape screen.
224 lines
6.0 KiB
Lua
224 lines
6.0 KiB
Lua
ReaderView = WidgetContainer:new{
|
|
_name = "ReaderView",
|
|
document = nil,
|
|
|
|
state = {
|
|
page = 0,
|
|
pos = 0,
|
|
zoom = 1.0,
|
|
rotation = 0,
|
|
gamma = 1.0,
|
|
offset = {},
|
|
bbox = nil,
|
|
},
|
|
outer_page_color = 7,
|
|
-- DjVu page rendering mode (used in djvu.c:drawPage())
|
|
render_mode = 0, -- default to COLOR
|
|
-- Crengine view mode
|
|
view_mode = "page", -- default to page mode
|
|
|
|
-- visible area within current viewing page
|
|
visible_area = Geom:new{x = 0, y = 0},
|
|
-- dimen for current viewing page
|
|
page_area = Geom:new{},
|
|
-- dimen for area to dim
|
|
dim_area = Geom:new{w = 0, h = 0},
|
|
}
|
|
|
|
function ReaderView:paintTo(bb, x, y)
|
|
DEBUG("painting", self.visible_area, "to", x, y)
|
|
local inner_offset = Geom:new{x = 0, y = 0}
|
|
|
|
-- draw surrounding space, if any
|
|
if self.ui.dimen.h > self.visible_area.h then
|
|
inner_offset.y = (self.ui.dimen.h - self.visible_area.h) / 2
|
|
bb:paintRect(x, y, self.ui.dimen.w, inner_offset.y, self.outer_page_color)
|
|
bb:paintRect(x, y + self.ui.dimen.h - inner_offset.y - 1, self.ui.dimen.w, inner_offset.y + 1, self.outer_page_color)
|
|
end
|
|
if self.ui.dimen.w > self.visible_area.w then
|
|
inner_offset.x = (self.ui.dimen.w - self.visible_area.w) / 2
|
|
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))
|
|
-- draw content
|
|
if self.ui.document.info.has_pages then
|
|
self.ui.document:drawPage(
|
|
bb,
|
|
x + inner_offset.x,
|
|
y + inner_offset.y,
|
|
self.visible_area,
|
|
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
|
|
if self.view_mode == "page" then
|
|
self.ui.document:drawCurrentViewByPage(
|
|
bb,
|
|
x + inner_offset.x,
|
|
y + inner_offset.y,
|
|
self.visible_area,
|
|
self.state.page)
|
|
else
|
|
self.ui.document:drawCurrentViewByPos(
|
|
bb,
|
|
x + inner_offset.x,
|
|
y + inner_offset.y,
|
|
self.visible_area,
|
|
self.state.pos)
|
|
end
|
|
end
|
|
-- dim last read area
|
|
if self.document.view_mode ~= "page"
|
|
and self.dim_area.w ~= 0 and self.dim_area.h ~= 0 then
|
|
bb:dimRect(
|
|
self.dim_area.x, self.dim_area.y,
|
|
self.dim_area.w, self.dim_area.h
|
|
)
|
|
end
|
|
end
|
|
|
|
--[[
|
|
This method is supposed to be only used by ReaderPaging
|
|
--]]
|
|
function ReaderView:recalculate()
|
|
local page_size = nil
|
|
if self.ui.document.info.has_pages then
|
|
if not self.bbox then
|
|
self.page_area = self.ui.document:getPageDimensions(
|
|
self.state.page,
|
|
self.state.zoom,
|
|
self.state.rotation)
|
|
else
|
|
self.page_area = self.ui.document:getUsedBBoxDimensions(
|
|
self.state.page,
|
|
self.state.zoom,
|
|
self.state.rotation)
|
|
end
|
|
-- starts from left top of page_area
|
|
self.visible_area.x = self.page_area.x
|
|
self.visible_area.y = self.page_area.y
|
|
-- reset our size
|
|
self.visible_area:setSizeTo(self.dimen)
|
|
-- and recalculate it according to page size
|
|
self.visible_area:offsetWithin(self.page_area, 0, 0)
|
|
-- clear dim area
|
|
self.dim_area.w = 0
|
|
self.dim_area.h = 0
|
|
self.ui:handleEvent(
|
|
Event:new("ViewRecalculate", self.visible_area, self.page_area))
|
|
else
|
|
self.visible_area:setSizeTo(self.dimen)
|
|
end
|
|
-- flag a repaint so self:paintTo will be called
|
|
UIManager:setDirty(self.dialog)
|
|
end
|
|
|
|
function ReaderView:PanningUpdate(dx, dy)
|
|
DEBUG("pan by", dx, dy)
|
|
local old = self.visible_area:copy()
|
|
self.visible_area:offsetWithin(self.page_area, dx, dy)
|
|
if self.visible_area ~= old then
|
|
-- flag a repaint
|
|
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
|
|
|
|
function ReaderView:onSetScreenMode(new_mode)
|
|
if new_mode == "landscape" or new_mode == "portrait" then
|
|
self.screen_mode = 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
|
|
|
|
function ReaderView:onRestoreScreenMode(old_mode)
|
|
if old_mode == "landscape" or old_mode == "portrait" then
|
|
Screen:setScreenMode(old_mode)
|
|
self.ui:handleEvent(Event:new("SetDimensions", Screen:getSize()))
|
|
end
|
|
return true
|
|
end
|
|
|
|
function ReaderView:onSetDimensions(dimensions)
|
|
self.dimen = dimensions
|
|
-- recalculate view
|
|
self:recalculate()
|
|
end
|
|
|
|
function ReaderView:onReadSettings(config)
|
|
self.render_mode = config:readSetting("render_mode") or 0
|
|
local screen_mode = config:readSetting("screen_mode")
|
|
if screen_mode then
|
|
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)
|
|
self.state.page = new_page_no
|
|
self:recalculate()
|
|
end
|
|
|
|
function ReaderView:onPosUpdate(new_pos)
|
|
self.state.pos = new_pos
|
|
self:recalculate()
|
|
end
|
|
|
|
function ReaderView:onZoomUpdate(zoom)
|
|
self.state.zoom = zoom
|
|
self:recalculate()
|
|
end
|
|
|
|
function ReaderView:onBBoxUpdate(bbox)
|
|
self.bbox = bbox
|
|
end
|
|
|
|
function ReaderView:onRotationUpdate(rotation)
|
|
self.state.rotation = 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
|
|
end
|
|
|
|
function ReaderView:onSetViewMode(new_mode)
|
|
self.ui.view_mode = new_mode
|
|
self.ui.document:setViewMode(new_mode)
|
|
self.ui:handleEvent(Event:new("UpdatePos"))
|
|
return true
|
|
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
|