2019-04-07 17:00:15 +00:00
|
|
|
local Geom = require("ui/geometry")
|
2020-12-19 11:18:30 +00:00
|
|
|
local IconWidget = require("ui/widget/iconwidget")
|
2013-10-18 20:38:07 +00:00
|
|
|
local LeftContainer = require("ui/widget/container/leftcontainer")
|
Clarify our OOP semantics across the codebase (#9586)
Basically:
* Use `extend` for class definitions
* Use `new` for object instantiations
That includes some minor code cleanups along the way:
* Updated `Widget`'s docs to make the semantics clearer.
* Removed `should_restrict_JIT` (it's been dead code since https://github.com/koreader/android-luajit-launcher/pull/283)
* Minor refactoring of LuaSettings/LuaData/LuaDefaults/DocSettings to behave (mostly, they are instantiated via `open` instead of `new`) like everything else and handle inheritance properly (i.e., DocSettings is now a proper LuaSettings subclass).
* Default to `WidgetContainer` instead of `InputContainer` for stuff that doesn't actually setup key/gesture events.
* Ditto for explicit `*Listener` only classes, make sure they're based on `EventListener` instead of something uselessly fancier.
* Unless absolutely necessary, do not store references in class objects, ever; only values. Instead, always store references in instances, to avoid both sneaky inheritance issues, and sneaky GC pinning of stale references.
* ReaderUI: Fix one such issue with its `active_widgets` array, with critical implications, as it essentially pinned *all* of ReaderUI's modules, including their reference to the `Document` instance (i.e., that was a big-ass leak).
* Terminal: Make sure the shell is killed on plugin teardown.
* InputText: Fix Home/End/Del physical keys to behave sensibly.
* InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time (previously, only InputContainers did, which might have had something to do with random widgets unconcerned about input using it as a baseclass instead of WidgetContainer...).
* OverlapGroup: Compute self.dimen at *init* time, because for some reason it needs to do that, but do it directly in OverlapGroup instead of going through a weird WidgetContainer method that it was the sole user of.
* ReaderCropping: Under no circumstances should a Document instance member (here, self.bbox) risk being `nil`ed!
* Kobo: Minor code cleanups.
2022-10-06 00:14:48 +00:00
|
|
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
2014-10-30 18:42:18 +00:00
|
|
|
local Screen = require("device").screen
|
2013-03-03 14:23:28 +00:00
|
|
|
|
Clarify our OOP semantics across the codebase (#9586)
Basically:
* Use `extend` for class definitions
* Use `new` for object instantiations
That includes some minor code cleanups along the way:
* Updated `Widget`'s docs to make the semantics clearer.
* Removed `should_restrict_JIT` (it's been dead code since https://github.com/koreader/android-luajit-launcher/pull/283)
* Minor refactoring of LuaSettings/LuaData/LuaDefaults/DocSettings to behave (mostly, they are instantiated via `open` instead of `new`) like everything else and handle inheritance properly (i.e., DocSettings is now a proper LuaSettings subclass).
* Default to `WidgetContainer` instead of `InputContainer` for stuff that doesn't actually setup key/gesture events.
* Ditto for explicit `*Listener` only classes, make sure they're based on `EventListener` instead of something uselessly fancier.
* Unless absolutely necessary, do not store references in class objects, ever; only values. Instead, always store references in instances, to avoid both sneaky inheritance issues, and sneaky GC pinning of stale references.
* ReaderUI: Fix one such issue with its `active_widgets` array, with critical implications, as it essentially pinned *all* of ReaderUI's modules, including their reference to the `Document` instance (i.e., that was a big-ass leak).
* Terminal: Make sure the shell is killed on plugin teardown.
* InputText: Fix Home/End/Del physical keys to behave sensibly.
* InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time (previously, only InputContainers did, which might have had something to do with random widgets unconcerned about input using it as a baseclass instead of WidgetContainer...).
* OverlapGroup: Compute self.dimen at *init* time, because for some reason it needs to do that, but do it directly in OverlapGroup instead of going through a weird WidgetContainer method that it was the sole user of.
* ReaderCropping: Under no circumstances should a Document instance member (here, self.bbox) risk being `nil`ed!
* Kobo: Minor code cleanups.
2022-10-06 00:14:48 +00:00
|
|
|
local ReaderFlipping = WidgetContainer:extend{
|
ReaderRolling: quicker partial rerenderings with EPUBs
Only available with EPUBs containing 2 or more fragments,
and a file size large enough to ensure a cache file is used.
The idea is simply, on any rendering setting change, to
skip the rerendering of the full book and to defer any
rerendering to the moment we draw a DocFragment, and
render only it.
So, on a setting change, only the fragment containing the
current page will be rerendered, and the new fragments we
may cross while turning pages.
When having done so, KOReader is in a degraded state (the
full page count is incorrect, the ToC is invalid...).
So, a full rerendering is needed, and one will happen
in the background, and when the user is idle, we reload
seamlessly and quickly from the cache file it has made.
ReaderFlipping will show some icons in the top left
corner to let it know at which steps in this procress
we are.
2023-02-16 22:30:58 +00:00
|
|
|
-- Icons to show during crengine partial rerendering automation
|
|
|
|
rolling_rendering_state_icons = {
|
|
|
|
PARTIALLY_RERENDERED = "cre.render.partial",
|
|
|
|
FULL_RENDERING_IN_BACKGROUND = "cre.render.working",
|
|
|
|
FULL_RENDERING_READY = "cre.render.ready",
|
|
|
|
RELOADING_DOCUMENT = "cre.render.reload",
|
|
|
|
},
|
2013-03-31 13:37:57 +00:00
|
|
|
}
|
2013-03-03 14:23:28 +00:00
|
|
|
|
|
|
|
function ReaderFlipping:init()
|
2020-12-19 11:18:30 +00:00
|
|
|
local icon_size = Screen:scaleBySize(32)
|
2022-11-18 19:17:25 +00:00
|
|
|
self.flipping_widget = IconWidget:new{
|
2020-12-19 11:18:30 +00:00
|
|
|
icon = "book.opened",
|
|
|
|
width = icon_size,
|
|
|
|
height = icon_size,
|
2014-03-13 13:52:43 +00:00
|
|
|
}
|
2023-03-13 07:52:10 +00:00
|
|
|
self.bookmark_flipping_widget = IconWidget:new{
|
|
|
|
icon = "bookmark",
|
|
|
|
width = icon_size,
|
|
|
|
height = icon_size,
|
|
|
|
}
|
2022-12-11 08:55:47 +00:00
|
|
|
icon_size = Screen:scaleBySize(36)
|
2022-11-18 19:17:25 +00:00
|
|
|
self.select_mode_widget = IconWidget:new{
|
2022-12-11 08:55:47 +00:00
|
|
|
icon = "texture-box",
|
2022-11-18 19:17:25 +00:00
|
|
|
width = icon_size,
|
|
|
|
height = icon_size,
|
|
|
|
alpha = true,
|
|
|
|
}
|
2014-03-13 13:52:43 +00:00
|
|
|
self[1] = LeftContainer:new{
|
2022-11-18 19:17:25 +00:00
|
|
|
dimen = Geom:new{w = Screen:getWidth(), h = self.flipping_widget:getSize().h},
|
|
|
|
self.flipping_widget,
|
2014-03-13 13:52:43 +00:00
|
|
|
}
|
2016-03-08 06:42:46 +00:00
|
|
|
self:resetLayout()
|
|
|
|
end
|
|
|
|
|
|
|
|
function ReaderFlipping:resetLayout()
|
2016-03-12 08:59:15 +00:00
|
|
|
local new_screen_width = Screen:getWidth()
|
|
|
|
if new_screen_width == self._last_screen_width then return end
|
|
|
|
self._last_screen_width = new_screen_width
|
|
|
|
|
|
|
|
self[1].dimen.w = new_screen_width
|
2013-03-03 14:23:28 +00:00
|
|
|
end
|
|
|
|
|
ReaderRolling: quicker partial rerenderings with EPUBs
Only available with EPUBs containing 2 or more fragments,
and a file size large enough to ensure a cache file is used.
The idea is simply, on any rendering setting change, to
skip the rerendering of the full book and to defer any
rerendering to the moment we draw a DocFragment, and
render only it.
So, on a setting change, only the fragment containing the
current page will be rerendered, and the new fragments we
may cross while turning pages.
When having done so, KOReader is in a degraded state (the
full page count is incorrect, the ToC is invalid...).
So, a full rerendering is needed, and one will happen
in the background, and when the user is idle, we reload
seamlessly and quickly from the cache file it has made.
ReaderFlipping will show some icons in the top left
corner to let it know at which steps in this procress
we are.
2023-02-16 22:30:58 +00:00
|
|
|
function ReaderFlipping:getRollingRenderingStateIconWidget()
|
|
|
|
if not self.rolling_rendering_state_widgets then
|
|
|
|
self.rolling_rendering_state_widgets = {}
|
|
|
|
end
|
|
|
|
local widget = self.rolling_rendering_state_widgets[self.ui.rolling.rendering_state]
|
|
|
|
if widget == nil then -- not met yet
|
|
|
|
local icon_size = Screen:scaleBySize(32)
|
|
|
|
for k, v in pairs(self.ui.rolling.RENDERING_STATE) do -- known states
|
|
|
|
if v == self.ui.rolling.rendering_state then -- current state
|
|
|
|
local icon = self.rolling_rendering_state_icons[k] -- our icon (or none) for this state
|
|
|
|
if icon then
|
|
|
|
self.rolling_rendering_state_widgets[v] = IconWidget:new{
|
|
|
|
icon = icon,
|
|
|
|
width = icon_size,
|
|
|
|
height = icon_size,
|
|
|
|
alpha = not self.ui.rolling.cre_top_bar_enabled,
|
|
|
|
-- if top status bar enabled, have them opaque, as they
|
|
|
|
-- will be displayed over the bar
|
|
|
|
-- otherwise, keep their alpha so some bits of text is
|
|
|
|
-- visible if displayed over the text when small margins
|
|
|
|
}
|
|
|
|
else
|
|
|
|
self.rolling_rendering_state_widgets[v] = false
|
|
|
|
end
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
widget = self.rolling_rendering_state_widgets[self.ui.rolling.rendering_state]
|
|
|
|
end
|
|
|
|
return widget or nil -- return nil if cached widget is false
|
|
|
|
end
|
|
|
|
|
|
|
|
function ReaderFlipping:onSetStatusLine()
|
|
|
|
-- Reset these widgets: we want new ones with proper alpha/opaque
|
|
|
|
self.rolling_rendering_state_widgets = nil
|
|
|
|
end
|
|
|
|
|
2022-11-18 19:17:25 +00:00
|
|
|
function ReaderFlipping:paintTo(bb, x, y)
|
2023-03-13 07:52:10 +00:00
|
|
|
local widget
|
|
|
|
if self.ui.paging and self.view.flipping_visible then
|
|
|
|
-- pdf page flipping or bookmark browsing mode
|
|
|
|
widget = self.ui.paging.bookmark_flipping_mode and self.bookmark_flipping_widget or self.flipping_widget
|
|
|
|
elseif self.ui.highlight.select_mode then
|
|
|
|
-- highlight select mode
|
|
|
|
widget = self.select_mode_widget
|
ReaderRolling: quicker partial rerenderings with EPUBs
Only available with EPUBs containing 2 or more fragments,
and a file size large enough to ensure a cache file is used.
The idea is simply, on any rendering setting change, to
skip the rerendering of the full book and to defer any
rerendering to the moment we draw a DocFragment, and
render only it.
So, on a setting change, only the fragment containing the
current page will be rerendered, and the new fragments we
may cross while turning pages.
When having done so, KOReader is in a degraded state (the
full page count is incorrect, the ToC is invalid...).
So, a full rerendering is needed, and one will happen
in the background, and when the user is idle, we reload
seamlessly and quickly from the cache file it has made.
ReaderFlipping will show some icons in the top left
corner to let it know at which steps in this procress
we are.
2023-02-16 22:30:58 +00:00
|
|
|
elseif self.ui.rolling and self.ui.rolling.rendering_state then
|
2023-03-13 07:52:10 +00:00
|
|
|
-- epub rerendering
|
|
|
|
widget = self:getRollingRenderingStateIconWidget()
|
|
|
|
end
|
|
|
|
if widget then
|
ReaderRolling: quicker partial rerenderings with EPUBs
Only available with EPUBs containing 2 or more fragments,
and a file size large enough to ensure a cache file is used.
The idea is simply, on any rendering setting change, to
skip the rerendering of the full book and to defer any
rerendering to the moment we draw a DocFragment, and
render only it.
So, on a setting change, only the fragment containing the
current page will be rerendered, and the new fragments we
may cross while turning pages.
When having done so, KOReader is in a degraded state (the
full page count is incorrect, the ToC is invalid...).
So, a full rerendering is needed, and one will happen
in the background, and when the user is idle, we reload
seamlessly and quickly from the cache file it has made.
ReaderFlipping will show some icons in the top left
corner to let it know at which steps in this procress
we are.
2023-02-16 22:30:58 +00:00
|
|
|
if self[1][1] ~= widget then
|
|
|
|
self[1][1] = widget
|
|
|
|
end
|
2023-03-13 07:52:10 +00:00
|
|
|
WidgetContainer.paintTo(self, bb, x, y)
|
2022-11-18 19:17:25 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-10-18 20:38:07 +00:00
|
|
|
return ReaderFlipping
|