mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Reader: Do less work on same-orientation non-gyro rotations (#11297)
Namely, don't recompute layouts, as they do not change. (The gyro codepaths were already doing something similar.) * Keep ConfigDialog, FileManagerMenu & ReaderMenu open on rotation. (In practice, only ConfigDialog is affected, as *Menu doesn't handle the rotation event.) * Plugged an instance leak in the aforementioned Menu classes. * Unify behavior & code with the gyro codepaths.
This commit is contained in:
@@ -66,6 +66,7 @@ end
|
||||
|
||||
FileManagerMenu.onPhysicalKeyboardConnected = FileManagerMenu.registerKeyEvents
|
||||
|
||||
-- NOTE: FileManager emits a SetDimensions on init, it's our only caller
|
||||
function FileManagerMenu:initGesListener()
|
||||
if not Device:isTouchDevice() then return end
|
||||
|
||||
@@ -968,10 +969,11 @@ function FileManagerMenu:onShowMenu(tab_index)
|
||||
end
|
||||
|
||||
function FileManagerMenu:onCloseFileManagerMenu()
|
||||
if not self.menu_container then return end
|
||||
if not self.menu_container then return true end
|
||||
local last_tab_index = self.menu_container[1].last_index
|
||||
G_reader_settings:saveSetting("filemanagermenu_tab_index", last_tab_index)
|
||||
UIManager:close(self.menu_container)
|
||||
self.menu_container = nil
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -1009,11 +1011,14 @@ function FileManagerMenu:onSwipeShowMenu(ges)
|
||||
end
|
||||
|
||||
function FileManagerMenu:onSetDimensions(dimen)
|
||||
self:onCloseFileManagerMenu()
|
||||
-- update listening according to new screen dimen
|
||||
if Device:isTouchDevice() then
|
||||
self:initGesListener()
|
||||
-- This widget doesn't support in-place layout updates, so, close & reopen
|
||||
if self.menu_container then
|
||||
self:onCloseFileManagerMenu()
|
||||
self:onShowMenu()
|
||||
end
|
||||
|
||||
-- update gesture zones according to new screen dimen
|
||||
self:initGesListener()
|
||||
end
|
||||
|
||||
function FileManagerMenu:onMenuSearch()
|
||||
|
||||
@@ -158,11 +158,11 @@ function ReaderConfig:onSwipeShowConfigMenu(ges)
|
||||
end
|
||||
end
|
||||
|
||||
-- For some reason, things are fine and dandy without any of this for rotations, but we need it for actual resizes...
|
||||
function ReaderConfig:onSetDimensions(dimen)
|
||||
-- since we cannot redraw config_dialog with new size, we close
|
||||
-- the old one on screen size change
|
||||
if self.config_dialog then
|
||||
self.config_dialog:closeDialog()
|
||||
-- init basically calls update & initGesListener and nothing else, which is exactly what we want.
|
||||
self.config_dialog:init()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ function ReaderMenu:getPreviousFile()
|
||||
return require("readhistory"):getPreviousFile(self.ui.document.file)
|
||||
end
|
||||
|
||||
function ReaderMenu:onReaderReady()
|
||||
function ReaderMenu:initGesListener()
|
||||
if not Device:isTouchDevice() then return end
|
||||
|
||||
local DTAP_ZONE_MENU = G_defaults:readSetting("DTAP_ZONE_MENU")
|
||||
@@ -179,6 +179,8 @@ function ReaderMenu:onReaderReady()
|
||||
})
|
||||
end
|
||||
|
||||
ReaderMenu.onReaderReady = ReaderMenu.initGesListener
|
||||
|
||||
function ReaderMenu:setUpdateItemTable()
|
||||
for _, widget in pairs(self.registered_widgets) do
|
||||
local ok, err = pcall(widget.addToMainMenu, widget, self.menu_items)
|
||||
@@ -456,16 +458,24 @@ function ReaderMenu:onShowMenu(tab_index)
|
||||
end
|
||||
|
||||
function ReaderMenu:onCloseReaderMenu()
|
||||
if self.menu_container then
|
||||
self.last_tab_index = self.menu_container[1].last_index
|
||||
self:onSaveSettings()
|
||||
UIManager:close(self.menu_container)
|
||||
end
|
||||
if not self.menu_container then return true end
|
||||
self.last_tab_index = self.menu_container[1].last_index
|
||||
self:onSaveSettings()
|
||||
UIManager:close(self.menu_container)
|
||||
self.menu_container = nil
|
||||
return true
|
||||
end
|
||||
|
||||
function ReaderMenu:onSetDimensions(dimen)
|
||||
self:onCloseReaderMenu()
|
||||
-- This widget doesn't support in-place layout updates, so, close & reopen
|
||||
if self.menu_container then
|
||||
self:onCloseReaderMenu()
|
||||
self:onShowMenu()
|
||||
end
|
||||
|
||||
-- update gesture zones according to new screen dimen
|
||||
-- (On CRe, this will get called a second time by ReaderReady once the document is reloaded).
|
||||
self:initGesListener()
|
||||
end
|
||||
|
||||
function ReaderMenu:onCloseDocument()
|
||||
|
||||
@@ -815,12 +815,32 @@ end
|
||||
|
||||
function ReaderView:onSetRotationMode(rotation)
|
||||
if rotation ~= nil then
|
||||
if rotation == Screen:getRotationMode() then
|
||||
local old_rotation = Screen:getRotationMode()
|
||||
if rotation == old_rotation then
|
||||
return true
|
||||
end
|
||||
|
||||
-- NOTE: We cannot rely on getScreenMode, as it actually checks the screen dimensions, instead of the rotation mode.
|
||||
-- (i.e., it returns how the screen *looks* like, not how it's oriented relative to its native layout).
|
||||
-- This would horribly break if you started in Portrait (both rotation and visually),
|
||||
-- then resized your window to a Landscape layout *without* changing the rotation.
|
||||
-- If you then attempted to switch to a Landscape *rotation*, it would mistakenly think the layout hadn't changed!
|
||||
-- So, instead, as we're concerned with *rotation* layouts, just compare the two.
|
||||
-- We use LinuxFB-style constants, so, Portraits are even, Landscapes are odds, making this trivial.
|
||||
local matching_orientation = bit.band(rotation, 1) == bit.band(old_rotation, 1)
|
||||
|
||||
if rotation ~= old_rotation and matching_orientation then
|
||||
-- No layout change, just rotate & repaint with a flash
|
||||
Screen:setRotationMode(rotation)
|
||||
UIManager:setDirty(self.dialog, "full")
|
||||
Notification:notify(T(_("Rotation mode set to: %1"), optionsutil:getOptionText("SetRotationMode", rotation)))
|
||||
return true
|
||||
end
|
||||
|
||||
Screen:setRotationMode(rotation)
|
||||
end
|
||||
UIManager:setDirty(self.dialog, "full")
|
||||
|
||||
UIManager:setDirty(nil, "full") -- SetDimensions will only request a partial, we want a flash
|
||||
local new_screen_size = Screen:getSize()
|
||||
self.ui:handleEvent(Event:new("SetDimensions", new_screen_size))
|
||||
self.ui:onScreenResize(new_screen_size)
|
||||
|
||||
@@ -984,39 +984,37 @@ end
|
||||
--- (Translation should be done via registerEventAdjustHook in Device implementations).
|
||||
--- This needs to be called *via handleGyroEv* in a handleMiscEv implementation (c.f., Kobo, Kindle or PocketBook).
|
||||
function Input:handleMiscGyroEv(ev)
|
||||
local rotation_mode, screen_mode
|
||||
local rotation
|
||||
if ev.value == C.DEVICE_ROTATED_UPRIGHT then
|
||||
-- i.e., UR
|
||||
rotation_mode = framebuffer.DEVICE_ROTATED_UPRIGHT
|
||||
screen_mode = "portrait"
|
||||
rotation = framebuffer.DEVICE_ROTATED_UPRIGHT
|
||||
elseif ev.value == C.DEVICE_ROTATED_CLOCKWISE then
|
||||
-- i.e., CW
|
||||
rotation_mode = framebuffer.DEVICE_ROTATED_CLOCKWISE
|
||||
screen_mode = "landscape"
|
||||
rotation = framebuffer.DEVICE_ROTATED_CLOCKWISE
|
||||
elseif ev.value == C.DEVICE_ROTATED_UPSIDE_DOWN then
|
||||
-- i.e., UD
|
||||
rotation_mode = framebuffer.DEVICE_ROTATED_UPSIDE_DOWN
|
||||
screen_mode = "portrait"
|
||||
rotation = framebuffer.DEVICE_ROTATED_UPSIDE_DOWN
|
||||
elseif ev.value == C.DEVICE_ROTATED_COUNTER_CLOCKWISE then
|
||||
-- i.e., CCW
|
||||
rotation_mode = framebuffer.DEVICE_ROTATED_COUNTER_CLOCKWISE
|
||||
screen_mode = "landscape"
|
||||
rotation = framebuffer.DEVICE_ROTATED_COUNTER_CLOCKWISE
|
||||
else
|
||||
-- Discard FRONT/BACK
|
||||
return
|
||||
end
|
||||
|
||||
local old_rotation_mode = self.device.screen:getRotationMode()
|
||||
local old_rotation = self.device.screen:getRotationMode()
|
||||
if self.device:isGSensorLocked() then
|
||||
local old_screen_mode = self.device.screen:getScreenMode()
|
||||
if rotation_mode and rotation_mode ~= old_rotation_mode and screen_mode == old_screen_mode then
|
||||
local matching_orientation = bit.band(rotation, 1) == bit.band(old_rotation, 1)
|
||||
if rotation and rotation ~= old_rotation and matching_orientation then
|
||||
-- Cheaper than a full SetRotationMode event, as we don't need to re-layout anything.
|
||||
self.device.screen:setRotationMode(rotation_mode)
|
||||
self.device.screen:setRotationMode(rotation)
|
||||
UIManager:onRotation()
|
||||
end
|
||||
else
|
||||
if rotation_mode and rotation_mode ~= old_rotation_mode then
|
||||
return Event:new("SetRotationMode", rotation_mode)
|
||||
if rotation and rotation ~= old_rotation then
|
||||
-- NOTE: We do *NOT* send a broadcast manually, and instead rely on the main loop's sendEvent:
|
||||
-- this ensures that only widgets that actually know how to handle a rotation will do so ;).
|
||||
return Event:new("SetRotationMode", rotation)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -897,9 +897,7 @@ function ConfigDialog:init()
|
||||
end
|
||||
end
|
||||
|
||||
function ConfigDialog:updateConfigPanel(index)
|
||||
|
||||
end
|
||||
function ConfigDialog:updateConfigPanel(index) end
|
||||
|
||||
function ConfigDialog:update()
|
||||
self:moveFocusTo(1, 1) -- reset selected for re-created layout
|
||||
|
||||
Reference in New Issue
Block a user