2
0
mirror of https://github.com/koreader/koreader synced 2024-10-31 21:20:20 +00:00
koreader/frontend/ui/reader/readerview.lua

196 lines
5.1 KiB
Lua
Raw Normal View History

ReaderView = WidgetContainer:new{
2013-02-02 06:36:29 +00:00
_name = "ReaderView",
document = nil,
state = {
page = 0,
2012-06-05 07:23:36 +00:00
pos = 0,
zoom = 1.0,
rotation = 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
2012-12-02 09:09:32 +00:00
-- visible area within current viewing page
visible_area = Geom:new{x = 0, y = 0},
2012-12-02 09:09:32 +00:00
-- dimen for current viewing page
page_area = Geom:new{},
2012-12-08 06:05:10 +00:00
-- 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
2012-06-05 07:23:36 +00:00
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.render_mode)
UIManager:scheduleIn(0, function() self.ui:handleEvent(Event:new("HintPage")) end)
2012-06-05 07:23:36 +00:00
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
2012-06-05 07:23:36 +00:00
end
2012-12-08 06:05:10 +00:00
-- dim last read area
2012-12-13 04:41:48 +00:00
if self.document.view_mode ~= "page"
and self.dim_area.w ~= 0 and self.dim_area.h ~= 0 then
2012-12-08 06:05:10 +00:00
bb:dimRect(
self.dim_area.x, self.dim_area.y,
self.dim_area.w, self.dim_area.h
)
end
end
2012-12-08 06:05:10 +00:00
--[[
This method is supposed to be only used by ReaderPaging
--]]
function ReaderView:recalculate()
2012-12-02 09:09:32 +00:00
local page_size = nil
2012-06-05 07:23:36 +00:00
if self.ui.document.info.has_pages then
2012-12-02 09:09:32 +00:00
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
2012-06-05 07:23:36 +00:00
-- reset our size
2012-06-12 16:14:23 +00:00
self.visible_area:setSizeTo(self.dimen)
2012-06-05 07:23:36 +00:00
-- and recalculate it according to page size
self.visible_area:offsetWithin(self.page_area, 0, 0)
2012-12-08 06:05:10 +00:00
-- 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))
2012-06-05 07:23:36 +00:00
else
2012-06-12 16:14:23 +00:00
self.visible_area:setSizeTo(self.dimen)
2012-06-05 07:23:36 +00:00
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)
2012-12-02 09:09:32 +00:00
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
Screen:setScreenMode(new_mode)
self.ui:handleEvent(Event:new("SetDimensions", Screen:getSize()))
end
return true
end
2012-06-12 16:14:23 +00:00
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
end
function ReaderView:onPageUpdate(new_page_no)
self.state.page = new_page_no
self:recalculate()
end
2012-06-05 07:23:36 +00:00
function ReaderView:onPosUpdate(new_pos)
self.state.pos = new_pos
self:recalculate()
end
function ReaderView:onZoomUpdate(zoom)
self.state.zoom = zoom
self:recalculate()
end
2012-12-02 09:09:32 +00:00
function ReaderView:onBBoxUpdate(bbox)
self.bbox = bbox
end
function ReaderView:onRotationUpdate(rotation)
self.state.rotation = rotation
self:recalculate()
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.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)
end