From b5d33058761625111d176123121bcc881864a64e Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Fri, 21 Aug 2020 14:33:08 +0200 Subject: [PATCH] A few e-Ink flash rate QoL tweaks (#6528) * Add an option to *always* flash on chapter boundaries * Optionally, in flash on chapter boundaries mode, also flash on the *second* page of a chapter. (There's often a large river at the top of the page on a chapter's first page) * In CRe, request a flashing update when there is significant image content on the page. * Register all refresh rate related options in Dispatcher, making them available in Gestures & Profiles. --- frontend/apps/reader/modules/readertoc.lua | 34 ++++++++++--- frontend/apps/reader/modules/readerview.lua | 2 + frontend/device/devicelistener.lua | 54 ++++++++++++++++++++- frontend/dispatcher.lua | 16 ++++++ frontend/ui/elements/refresh_menu_table.lua | 29 ++++++++--- frontend/ui/uimanager.lua | 22 +++++++-- 6 files changed, 136 insertions(+), 21 deletions(-) diff --git a/frontend/apps/reader/modules/readertoc.lua b/frontend/apps/reader/modules/readertoc.lua index 23823b139..a70933e31 100644 --- a/frontend/apps/reader/modules/readertoc.lua +++ b/frontend/apps/reader/modules/readertoc.lua @@ -60,10 +60,16 @@ end function ReaderToc:onPageUpdate(pageno) self.pageno = pageno - if UIManager.FULL_REFRESH_COUNT == -1 then + if UIManager.FULL_REFRESH_COUNT == -1 or G_reader_settings:isTrue("refresh_on_chapter_boundaries") then + local flash_on_second = G_reader_settings:nilOrFalse("no_refresh_on_second_chapter_page") if self:isChapterEnd(pageno, 0) then self.chapter_refresh = true - elseif self:isChapterBegin(pageno, 0) and self.chapter_refresh then + elseif self.chapter_refresh and self:isChapterStart(pageno, 0) then + UIManager:setDirty(nil, "full") + if not flash_on_second then + self.chapter_refresh = false + end + elseif self.chapter_refresh and self:isChapterSecondPage(pageno, 0) then UIManager:setDirty(nil, "full") self.chapter_refresh = false else @@ -356,21 +362,33 @@ function ReaderToc:getPreviousChapter(cur_pageno, level) return previous_chapter end -function ReaderToc:isChapterBegin(cur_pageno, level) +function ReaderToc:isChapterStart(cur_pageno, level) local ticks = self:getTocTicks(level) - local _begin = false + local _start = false for i = 1, #ticks do if ticks[i] == cur_pageno then - _begin = true + _start = true + break + end + end + return _start +end + +function ReaderToc:isChapterSecondPage(cur_pageno, level) + local ticks = self:getTocTicks(level) + local _second = false + for i = 1, #ticks do + if ticks[i] + 1 == cur_pageno then + _second = true break end end - return _begin + return _second end function ReaderToc:isChapterEnd(cur_pageno, level) local ticks = self:getTocTicks(level) - local _end= false + local _end = false for i = 1, #ticks do if ticks[i] - 1 == cur_pageno then _end = true @@ -390,7 +408,7 @@ function ReaderToc:getChapterPagesLeft(pageno, level) end function ReaderToc:getChapterPagesDone(pageno, level) - if self:isChapterBegin(pageno, level) then return 0 end + if self:isChapterStart(pageno, level) then return 0 end local previous_chapter = self:getPreviousChapter(pageno, level) if previous_chapter then previous_chapter = pageno - previous_chapter diff --git a/frontend/apps/reader/modules/readerview.lua b/frontend/apps/reader/modules/readerview.lua index bed92558d..18f263302 100644 --- a/frontend/apps/reader/modules/readerview.lua +++ b/frontend/apps/reader/modules/readerview.lua @@ -223,6 +223,8 @@ function ReaderView:paintTo(bb, x, y) -- With some nil guards because this may not be implemented in every engine ;). if img_count and img_count > 0 and img_coverage and img_coverage >= 0.075 then self.dialog.dithered = true + -- Request a flashing update while we're at it + UIManager:setDirty(nil, "full") end end end diff --git a/frontend/device/devicelistener.lua b/frontend/device/devicelistener.lua index 326645e99..0e8d7b1e0 100644 --- a/frontend/device/devicelistener.lua +++ b/frontend/device/devicelistener.lua @@ -11,6 +11,18 @@ local T = require("ffi/util").template local DeviceListener = InputContainer:new{} +local function _setSetting(name) + G_reader_settings:saveSetting(name, true) +end + +local function _unsetSetting(name) + G_reader_settings:delSetting(name) +end + +local function _toggleSetting(name) + G_reader_settings:flipNilOrFalse(name) +end + function DeviceListener:onToggleNightMode() local night_mode = G_reader_settings:isTrue("night_mode") Screen:toggleNightMode() @@ -223,7 +235,7 @@ end if Device:canToggleGSensor() then function DeviceListener:onToggleGSensor() - G_reader_settings:flipNilOrFalse("input_ignore_gsensor") + _toggleSetting("input_ignore_gsensor") Device:toggleGSensor(not G_reader_settings:isTrue("input_ignore_gsensor")) local new_text if G_reader_settings:isTrue("input_ignore_gsensor") then @@ -269,6 +281,46 @@ function DeviceListener:onSwapRotation() return true end +function DeviceListener:onSetRefreshRates(day, night) + UIManager:setRefreshRate(day, night) +end + +function DeviceListener:onSetBothRefreshRates(rate) + UIManager:setRefreshRate(rate, rate) +end + +function DeviceListener:onSetDayRefreshRate(day) + UIManager:setRefreshRate(day, nil) +end + +function DeviceListener:onSetNightRefreshRate(night) + UIManager:setRefreshRate(nil, night) +end + +function DeviceListener:onSetFlashOnChapterBoundaries(toggle) + if toggle == true then + _setSetting("refresh_on_chapter_boundaries") + else + _unsetSetting("refresh_on_chapter_boundaries") + end +end + +function DeviceListener:onToggleFlashOnChapterBoundaries() + _toggleSetting("refresh_on_chapter_boundaries") +end + +function DeviceListener:onSetNoFlashOnSecondChapterPage(toggle) + if toggle == true then + _setSetting("no_refresh_on_second_chapter_page") + else + _unsetSetting("no_refresh_on_second_chapter_page") + end +end + +function DeviceListener:onToggleNoFlashOnSecondChapterPage() + _toggleSetting("no_refresh_on_second_chapter_page") +end + if Device:canReboot() then function DeviceListener:onReboot() UIManager:show(ConfirmBox:new{ diff --git a/frontend/dispatcher.lua b/frontend/dispatcher.lua index ef63dc016..c82b97727 100644 --- a/frontend/dispatcher.lua +++ b/frontend/dispatcher.lua @@ -66,6 +66,13 @@ local settingsList = { toggle_rotation = { category="none", event="SwapRotation", title=_("Toggle orientation"), device=true,}, invert_rotation = { category="none", event="InvertRotation", title=_("Invert rotation"), device=true,}, iterate_rotation = { category="none", event="IterateRotation", title=_("Rotate by 90° CW"), device=true, separator=true,}, + set_refresh_rate = { category="absolutenumber", event="SetBothRefreshRates", min=-1, max=200, title=_("Flash every %1 pages (always)"), device=true,}, + set_day_refresh_rate = { category="absolutenumber", event="SetDayRefreshRate", min=-1, max=200, title=_("Flash every %1 pages (not in night mode)"), device=true,}, + set_night_refresh_rate = { category="absolutenumber", event="SetNightRefreshRate", min=-1, max=200, title=_("Flash every %1 pages (in night mode)"), device=true,}, + set_flash_on_chapter_boundaries = { category="string", event="SetFlashOnChapterBoundaries", title=_("Always flash on chapter boundaries"), device=true, args={true, false}, toggle={_("On"), _("Off")},}, + toggle_flash_on_chapter_boundaries = { category="none", event="ToggleFlashOnChapterBoundaries", title=_("Toggle flashing on chapter boundaries"), device=true,}, + set_no_flash_on_second_chapter_page = { category="string", event="SetNoFlashOnSecondChapterPage", title=_("Never flash on chapter's 2nd page"), device=true, args={true, false}, toggle={_("On"), _("Off")},}, + toggle_no_flash_on_second_chapter_page = { category="none", event="ToggleNoFlashOnSecondChapterPage", title=_("Toggle flashing on chapter's 2nd page"), device=true, separator=true,}, wallabag_download = { category="none", event="SynchronizeWallabag", title=_("Wallabag retrieval"), device=true,}, calibre_search = { category="none", event="CalibreSearch", title=_("Search in calibre metadata"), device=true,}, calibre_browse_tags = { category="none", event="CalibreBrowseTags", title=_("Browse all calibre tags"), device=true,}, @@ -177,11 +184,20 @@ local dispatcher_menu_order = { "decrease_frontlight_warmth", "toggle_hold_corners", + "toggle_gsensor", "toggle_rotation", "invert_rotation", "iterate_rotation", + "set_refresh_rate", + "set_day_refresh_rate", + "set_night_refresh_rate", + "set_flash_on_chapter_boundaries", + "toggle_flash_on_chapter_boundaries", + "set_no_flash_on_second_chapter_page", + "toggle_no_flash_on_second_chapter_page", + "wifi_on", "wifi_off", "toggle_wifi", diff --git a/frontend/ui/elements/refresh_menu_table.lua b/frontend/ui/elements/refresh_menu_table.lua index 301b809b3..43b34f124 100644 --- a/frontend/ui/elements/refresh_menu_table.lua +++ b/frontend/ui/elements/refresh_menu_table.lua @@ -1,4 +1,5 @@ local Device = require("device") +local Event = require("ui/event") local UIManager = require("ui/uimanager") local _ = require("gettext") local Screen = Device.screen @@ -44,7 +45,7 @@ local function spinWidgetSetRefresh(touchmenu_instance, refresh_rate_num) callback = function(left_value, right_value) G_reader_settings:saveSetting(refresh_rate_num, left_value) G_reader_settings:saveSetting("night_" .. refresh_rate_num, right_value) - UIManager:setRefreshRate(left_value, right_value) + UIManager:broadcastEvent(Event:new("SetRefreshRates", left_value, right_value)) touchmenu_instance:updateItems() end } @@ -59,24 +60,24 @@ return { { text = _("Never"), checked_func = function() return refreshChecked(0, 0) end, - callback = function() UIManager:setRefreshRate(0, 0) end, + callback = function() UIManager:broadcastEvent(Event:new("SetBothRefreshRates", 0)) end, }, { text = _("Every page"), checked_func = function() return refreshChecked(1, 1) end, - callback = function() UIManager:setRefreshRate(1, 1) end, + callback = function() UIManager:broadcastEvent(Event:new("SetBothRefreshRates", 1)) end, }, { text = _("Every 6 pages"), checked_func = function() return refreshChecked(6, 6) end, - callback = function() UIManager:setRefreshRate(6, 6) end, + callback = function() UIManager:broadcastEvent(Event:new("SetBothRefreshRates", 6)) end, }, { text_func = function() return T(_("Custom 1: %1:%2 pages"), custom("refresh_rate_1")) end, checked_func = function() return refreshChecked(custom("refresh_rate_1")) end, - callback = function() UIManager:setRefreshRate(custom("refresh_rate_1")) end, + callback = function() UIManager:broadcastEvent(Event:new("SetRefreshRates", custom("refresh_rate_1"))) end, hold_callback = function(touchmenu_instance) spinWidgetSetRefresh(touchmenu_instance, "refresh_rate_1") end, @@ -86,7 +87,7 @@ return { return T(_("Custom 2: %1:%2 pages"), custom("refresh_rate_2")) end, checked_func = function() return refreshChecked(custom("refresh_rate_2")) end, - callback = function() UIManager:setRefreshRate(custom("refresh_rate_2")) end, + callback = function() UIManager:broadcastEvent(Event:new("SetRefreshRates", custom("refresh_rate_2"))) end, hold_callback = function(touchmenu_instance) spinWidgetSetRefresh(touchmenu_instance, "refresh_rate_2") end, @@ -96,7 +97,7 @@ return { return T(_("Custom 3: %1:%2 pages"), custom("refresh_rate_3")) end, checked_func = function() return refreshChecked(custom("refresh_rate_3")) end, - callback = function() UIManager:setRefreshRate(custom("refresh_rate_3")) end, + callback = function() UIManager:broadcastEvent(Event:new("SetRefreshRates", custom("refresh_rate_3"))) end, hold_callback = function(touchmenu_instance) spinWidgetSetRefresh(touchmenu_instance, "refresh_rate_3") end, @@ -104,7 +105,19 @@ return { { text = _("Every chapter"), checked_func = function() return refreshChecked(-1, -1) end, - callback = function() UIManager:setRefreshRate(-1, -1) end, + callback = function() UIManager:broadcastEvent(Event:new("SetBothRefreshRates", -1)) end, + separator = true, + }, + { + text = _("Always flash on chapter boundaries"), + checked_func = function() return G_reader_settings:isTrue("refresh_on_chapter_boundaries") end, + callback = function() UIManager:broadcastEvent(Event:new("ToggleFlashOnChapterBoundaries")) end, + }, + { + text = _("except on the second page of a new chapter"), + enabled_func = function() return UIManager.FULL_REFRESH_COUNT == -1 or G_reader_settings:isTrue("refresh_on_chapter_boundaries") end, + checked_func = function() return G_reader_settings:isTrue("no_refresh_on_second_chapter_page") end, + callback = function() UIManager:broadcastEvent(Event:new("ToggleNoFlashOnSecondChapterPage")) end, }, } } diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index 5028394dd..786fa0f71 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -689,10 +689,24 @@ end -- -- Also makes the refresh rate persistent in global reader settings. function UIManager:setRefreshRate(rate, night_rate) - logger.dbg("set screen full refresh rate", rate) - self.FULL_REFRESH_COUNT = G_reader_settings:isTrue("night_mode") and night_rate or rate - G_reader_settings:saveSetting("full_refresh_count", rate) - G_reader_settings:saveSetting("night_full_refresh_count", night_rate) + logger.dbg("set screen full refresh rate", rate, night_rate) + + if G_reader_settings:isTrue("night_mode") then + if night_rate then + self.FULL_REFRESH_COUNT = night_rate + end + else + if rate then + self.FULL_REFRESH_COUNT = rate + end + end + + if rate then + G_reader_settings:saveSetting("full_refresh_count", rate) + end + if night_rate then + G_reader_settings:saveSetting("night_full_refresh_count", night_rate) + end end --- Gets full refresh rate for e-ink screen.