2
0
mirror of https://github.com/koreader/koreader synced 2024-10-31 21:20:20 +00:00
koreader/frontend/apps/reader/modules/readercropping.lua
Qingping Hou 0c49b915de refactor: add touch zone subsystem to inputcontainer
Touch zone decouples screen size from gesture event registration.

The win here is each individual widget does not need to update
gesture range on screen rotate/resize anymore.

Another advantage is we now have a centralized ordered array to handle
all registered touch event listeners, makes it much easier to resolve
gesture range conflicts between multiple widgets.

This patch also includes the following changes:

* migrate readerpaging to use readerui's touch zone
* migrate readerfooter to use readerui's touch zone
* move inverse read direction setting to touch menu's setting tab
* moved kobolight widget from readerview into readerui
* various dead code cleanups and comments
2016-12-10 16:06:51 -08:00

195 lines
6.5 KiB
Lua

local InputContainer = require("ui/widget/container/inputcontainer")
local UIManager = require("ui/uimanager")
local Geom = require("ui/geometry")
local Event = require("ui/event")
local Screen = require("device").screen
local LeftContainer = require("ui/widget/container/leftcontainer")
local RightContainer = require("ui/widget/container/rightcontainer")
local FrameContainer = require("ui/widget/container/framecontainer")
local VerticalGroup = require("ui/widget/verticalgroup")
local HorizontalGroup = require("ui/widget/horizontalgroup")
local BBoxWidget = require("ui/widget/bboxwidget")
local HorizontalSpan = require("ui/widget/horizontalspan")
local Button = require("ui/widget/button")
local Math = require("optmath")
local Blitbuffer = require("ffi/blitbuffer")
local PageCropDialog = VerticalGroup:new{
ok_text = "OK",
cancel_text = "Cancel",
ok_callback = function() end,
cancel_callback = function() end,
button_width = math.floor(Screen:scaleBySize(70)),
}
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,
show_parent = self,
}
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,
show_parent = self,
}
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{
horizontal_group,
background = Blitbuffer.COLOR_WHITE,
bordersize = 0,
padding = 0,
}
end
function PageCropDialog:onCloseWidget()
UIManager:setDirty(nil, function()
return "partial", self[1].dimen:combine(self[2].dimen)
end)
return true
end
function PageCropDialog:onShow()
UIManager:setDirty(self, function()
return "ui", self[1].dimen:combine(self[2].dimen)
end)
return true
end
local ReaderCropping = InputContainer:new{}
function ReaderCropping:onPageCrop(mode)
self.ui:handleEvent(Event:new("CloseConfigMenu"))
-- backup original zoom mode as cropping use "page" zoom mode
self.orig_zoom_mode = self.view.zoom_mode
if mode == "auto" then
if self.document.configurable.text_wrap ~= 1 then
self:setCropZoomMode(true)
end
return
end
-- backup original view dimen
self.orig_view_dimen = Geom:new{w = self.view.dimen.w, h = self.view.dimen.h}
-- backup original view bgcolor
self.orig_view_bgcolor = self.view.outer_page_color
self.view.outer_page_color = Blitbuffer.COLOR_GREY
-- backup original page scroll
self.orig_page_scroll = self.view.page_scroll
self.view.page_scroll = false
-- backup and disable original hinting state
self.ui:handleEvent(Event:new("DisableHinting"))
-- 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
-- mode, just force readerview to recalculate visible_area
self.view:recalculate()
else
self.ui:handleEvent(Event:new("SetZoomMode", "page", "cropping"))
end
self.ui:handleEvent(Event:new("SetDimensions",
Geom:new{w = Screen:getWidth(), h = Screen:getHeight()*11/12})
)
self.bbox_widget = BBoxWidget:new{
crop = self,
ui = self.ui,
view = self.view,
document = self.document,
}
self.crop_dialog = PageCropDialog:new{
self.bbox_widget,
ok_callback = function() self:onConfirmPageCrop() end,
cancel_callback = function() self:onCancelPageCrop() end,
}
UIManager:show(self.crop_dialog)
return true
end
function ReaderCropping:onConfirmPageCrop()
--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:onCancelPageCrop()
UIManager:close(self.crop_dialog)
self:exitPageCrop(false)
return true
end
function ReaderCropping:exitPageCrop(confirmed)
-- restore hinting state
self.ui:handleEvent(Event:new("RestoreHinting"))
-- restore page scroll
self.view.page_scroll = self.orig_page_scroll
-- restore view bgcolor
self.view.outer_page_color = self.orig_view_bgcolor
-- restore reflow mode
self.document.configurable.text_wrap = self.orig_reflow_mode
-- restore view dimens
self.ui:handleEvent(Event:new("RestoreDimensions", self.orig_view_dimen))
self.view:recalculate()
-- Exiting should have the same look and feel with entering.
if self.orig_reflow_mode == 1 then
self.ui:handleEvent(Event:new("RestoreZoomMode"))
else
self:setCropZoomMode(confirmed)
end
end
function ReaderCropping:setCropZoomMode(confirmed)
if confirmed then
-- if original zoom mode is not "content", set zoom mode to "contentwidth"
self:setZoomMode(
self.orig_zoom_mode:find("content")
and self.orig_zoom_mode
or "contentwidth")
self.ui:handleEvent(Event:new("InitScrollPageStates"))
else
self:setZoomMode(self.orig_zoom_mode)
end
end
function ReaderCropping:setZoomMode(mode)
self.ui:handleEvent(Event:new("SetZoomMode", mode))
end
function ReaderCropping:onReadSettings(config)
self.document.bbox = config:readSetting("bbox")
end
function ReaderCropping:onSaveSettings()
self.ui.doc_settings:saveSetting("bbox", self.document.bbox)
end
return ReaderCropping