From 35df1749b296ab9766668dcd48f279c0da91a64b Mon Sep 17 00:00:00 2001 From: poire-z Date: Sun, 21 Jan 2018 19:44:12 +0100 Subject: [PATCH] Screensaver: a few tweaks and fixes (#3619) When no manually added specific 'poweroff' or 'reboot' screensaver settings, use the suspend/sleep settings set via menu with an added overlay message in top right corner. Generalized some settings: "White background behind message and images" and "Stretch covers and images to fit screen", and move "Exclude this book's cover from screensaver" up a level (and remove this menu item added by ReaderMenu when closing document). Don't use memory cache with rendered screensaver images. ImageWidget: fix wrong behaviour (stretch) when 'file', 'width', 'height' and 'scale_factor' provided: now, keep aspect ratio. ImageWidget: increase file image mem cache (mostly used for icons) from 2 to 5MB to be ready for devices with very high DPI. --- frontend/apps/reader/modules/readermenu.lua | 69 ++++--------- frontend/ui/elements/screensaver_menu.lua | 16 ++- frontend/ui/screensaver.lua | 102 +++++++++++++++++--- frontend/ui/widget/imagewidget.lua | 20 ++-- 4 files changed, 132 insertions(+), 75 deletions(-) diff --git a/frontend/apps/reader/modules/readermenu.lua b/frontend/apps/reader/modules/readermenu.lua index 0fae33ee4..48435b117 100644 --- a/frontend/apps/reader/modules/readermenu.lua +++ b/frontend/apps/reader/modules/readermenu.lua @@ -128,58 +128,22 @@ function ReaderMenu:setUpdateItemTable() if Device:supportsScreensaver() then local ss_book_settings = { - text = _("Current book cover settings"), + text = _("Exclude this book's cover from screensaver"), enabled_func = function() return not (self.ui == nil or self.ui.document == nil) and G_reader_settings:readSetting('screensaver_type') == "cover" end, - sub_item_table = { - { - text = _("Exclude this book's cover from screensaver"), - checked_func = function() - return self.ui.doc_settings:readSetting("exclude_screensaver") == true - end, - callback = function() - if Screensaver:excluded() then - self.ui.doc_settings:saveSetting("exclude_screensaver", false) - else - self.ui.doc_settings:saveSetting("exclude_screensaver", true) - end - self.ui:saveSettings() - end - }, - { - text = _("Stretch book cover to fit screen"), - checked_func = function() - local settings_stretch_cover = self.ui.doc_settings:readSetting("stretch_cover") - if settings_stretch_cover == nil and G_reader_settings:readSetting("stretch_cover_default") then - return true - else - return self.ui.doc_settings:readSetting("stretch_cover") == true - end - end, - callback = function() - self.ui.doc_settings:saveSetting("stretch_cover", not Screensaver:stretchCover()) - self.ui:saveSettings() - end, - hold_callback = function() - local ConfirmBox = require("ui/widget/confirmbox") - UIManager:show(ConfirmBox:new { - text = _("Stretch all book covers to fit screen?"), - cancel_text = _("Don't stretch"), - cancel_callback = function() - G_reader_settings:delSetting("stretch_cover_default") - return - end, - ok_text = _("Stretch"), - ok_callback = function() - G_reader_settings:saveSetting("stretch_cover_default", true) - return - end, - }) - end, - }, - } + checked_func = function() + return self.ui and self.ui.doc_settings and self.ui.doc_settings:readSetting("exclude_screensaver") == true + end, + callback = function() + if Screensaver:excluded() then + self.ui.doc_settings:saveSetting("exclude_screensaver", false) + else + self.ui.doc_settings:saveSetting("exclude_screensaver", true) + end + self.ui:saveSettings() + end } self.menu_items.screensaver = { @@ -317,6 +281,15 @@ function ReaderMenu:onCloseReaderMenu() return true end +function ReaderMenu:onCloseDocument() + if Device:supportsScreensaver() then + -- Remove the 8th item we added (which cleans up references to document + -- and doc_settings embedded in functions) + local screensaver_sub_item_table = require("ui/elements/screensaver_menu") + table.remove(screensaver_sub_item_table, 8) + end +end + function ReaderMenu:_getTabIndexFromLocation(ges) if self.tab_item_table == nil then self:setUpdateItemTable() diff --git a/frontend/ui/elements/screensaver_menu.lua b/frontend/ui/elements/screensaver_menu.lua index d24eedddb..4f9c8b881 100644 --- a/frontend/ui/elements/screensaver_menu.lua +++ b/frontend/ui/elements/screensaver_menu.lua @@ -10,7 +10,8 @@ local function lastFile() return last_file end end -local function messageBackground() return G_reader_settings:isTrue("message_background") end +local function whiteBackground() return G_reader_settings:isTrue("screensaver_white_background") end +local function stretchImages() return G_reader_settings:isTrue("screensaver_stretch_images") end return { { @@ -110,12 +111,17 @@ return { end, }, { - text = _("White background in message"), - checked_func = function() - return messageBackground() + text = _("White background behind message and images"), + checked_func = whiteBackground, + callback = function() + G_reader_settings:saveSetting("screensaver_white_background", not whiteBackground()) end, + }, + { + text = _("Stretch covers and images to fit screen"), + checked_func = stretchImages, callback = function() - G_reader_settings:saveSetting("message_background", not messageBackground()) + G_reader_settings:saveSetting("screensaver_stretch_images", not stretchImages()) end, separator = true, }, diff --git a/frontend/ui/screensaver.lua b/frontend/ui/screensaver.lua index 96152d012..787824ff9 100644 --- a/frontend/ui/screensaver.lua +++ b/frontend/ui/screensaver.lua @@ -83,17 +83,12 @@ function Screensaver:chooseFolder() UIManager:show(self.choose_dialog) end -function Screensaver:stretchCover() - local lastfile = G_reader_settings:readSetting("lastfile") - if DocSettings:hasSidecarFile(lastfile) then - local doc_settings = DocSettings:open(lastfile) - local stretch_cover_ss = doc_settings:readSetting("stretch_cover") - doc_settings:close() - if stretch_cover_ss ~= nil then - return stretch_cover_ss - end - end - return G_reader_settings:readSetting("stretch_cover_default") or false +function Screensaver:stretchImages() + return G_reader_settings:isTrue("screensaver_stretch_images") +end + +function Screensaver:whiteBackground() + return G_reader_settings:isTrue("screensaver_white_background") end function Screensaver:excluded() @@ -146,8 +141,19 @@ function Screensaver:show(event, fallback_message) UIManager:close(self.left_msg) self.left_msg = nil end + local overlay_message local prefix = event and event.."_" or "" -- "", "poweroff_" or "reboot_" local screensaver_type = G_reader_settings:readSetting(prefix.."screensaver_type") + if prefix and not screensaver_type then + -- No manually added setting for poweroff/reboot, fallback to using the + -- same settings as for suspend that could be set via menus + screensaver_type = G_reader_settings:readSetting("screensaver_type") + prefix = "" + -- And display fallback_message over the common screensaver, + -- so user can distinguish between suspend (no message) and + -- poweroff (overlay message) + overlay_message = fallback_message + end if screensaver_type == nil then screensaver_type = "message" end @@ -165,7 +171,6 @@ function Screensaver:show(event, fallback_message) doc_settings:close() end if exclude ~= true then - background = Blitbuffer.COLOR_BLACK if lfs.attributes(lastfile, "mode") == "file" then local doc = DocumentRegistry:openDocument(lastfile) local image = doc:getCoverPageImage() @@ -177,8 +182,11 @@ function Screensaver:show(event, fallback_message) alpha = true, height = Screen:getHeight(), width = Screen:getWidth(), - scale_factor = not self:stretchCover() and 0 or nil, + scale_factor = not self:stretchImages() and 0 or nil, } + if not self:whiteBackground() then + background = Blitbuffer.COLOR_BLACK + end else screensaver_type = "random_image" end @@ -225,11 +233,15 @@ function Screensaver:show(event, fallback_message) else widget = ImageWidget:new{ file = image_file, + file_do_cache = false, alpha = true, height = Screen:getHeight(), width = Screen:getWidth(), - scale_factor = 0, + scale_factor = not self:stretchImages() and 0 or nil, } + if not self:whiteBackground() then + background = Blitbuffer.COLOR_BLACK + end end end if screensaver_type == "readingprogress" then @@ -241,8 +253,8 @@ function Screensaver:show(event, fallback_message) end if screensaver_type == "message" then local screensaver_message = G_reader_settings:readSetting(prefix.."screensaver_message") - if G_reader_settings:nilOrFalse("message_background") then - background = nil + if not self:whiteBackground() then + background = nil -- no background filling, let book text visible end if screensaver_message == nil then screensaver_message = fallback_message or default_screensaver_message @@ -251,6 +263,12 @@ function Screensaver:show(event, fallback_message) text = screensaver_message, readonly = true, } + -- No overlay needed as we just displayed the message + overlay_message = nil + end + + if overlay_message then + widget = self:addOverlayMessage(widget, overlay_message) end if widget then @@ -288,4 +306,56 @@ function Screensaver:close() end end +function Screensaver:addOverlayMessage(widget, text) + local Font = require("ui/font") + local FrameContainer = require("ui/widget/container/framecontainer") + local OverlapGroup = require("ui/widget/overlapgroup") + local RenderText = require("ui/rendertext") + local RightContainer = require("ui/widget/container/rightcontainer") + local Size = require("ui/size") + local TextBoxWidget = require("ui/widget/textboxwidget") + local TextWidget = require("ui/widget/textwidget") + + local face = Font:getFace("infofont") + local screen_w, screen_h = Screen:getWidth(), Screen:getHeight() + + local textw + -- Don't make our message reach full screen width + local tsize = RenderText:sizeUtf8Text(0, screen_w, face, text) + if tsize.x < screen_w * 0.9 then + textw = TextWidget:new{ + text = text, + face = face, + } + else -- if text too wide, use TextBoxWidget for multi lines display + textw = TextBoxWidget:new{ + text = text, + face = face, + width = math.floor(screen_w * 0.9) + } + end + textw = FrameContainer:new{ + background = Blitbuffer.COLOR_WHITE, + bordersize = Size.border.default, + margin = 0, + textw, + } + textw = RightContainer:new{ + dimen = { + w = screen_w, + h = textw:getSize().h, + }, + textw, + } + widget = OverlapGroup:new{ + dimen = { + h = screen_w, + w = screen_h, + }, + widget, + textw, + } + return widget +end + return Screensaver diff --git a/frontend/ui/widget/imagewidget.lua b/frontend/ui/widget/imagewidget.lua index 61998ad9d..8dbfcb497 100644 --- a/frontend/ui/widget/imagewidget.lua +++ b/frontend/ui/widget/imagewidget.lua @@ -38,7 +38,7 @@ end local DPI_SCALE = get_dpi_scale() local ImageCache = Cache:new{ - max_memsize = 2*1024*1024, -- 2M of image cache + max_memsize = 5*1024*1024, -- 5M of image cache current_memsize = 0, cache = {}, -- this will hold the LRU order of the cache @@ -129,12 +129,20 @@ function ImageWidget:_loadfile() local itype = string.lower(string.match(self.file, ".+%.([^.]+)") or "") if itype == "png" or itype == "jpg" or itype == "jpeg" or itype == "tiff" then - local hash = "image|"..self.file.."|"..(self.width or "").."|"..(self.height or "") - -- Do the scaling for DPI here, so it can be cached and not re-done - -- each time in _render() -- In our use cases for files (icons), we either provide width and height, -- or just scale_for_dpi, and scale_factor should stay nil. - -- Other combinations will result in double scaling anyway, and unexpected results. + -- Other combinations will result in double scaling, and unexpected results. + -- We should anyway only give self.width and self.height to Mupdf.renderImageFile(), + -- and use them in cache hash, when self.scale_factor is nil, when we are sure + -- we don't need to keep aspect ratio. + local width, height + if self.scale_factor == nil then + width = self.width + height = self.height + end + local hash = "image|"..self.file.."|"..(width or "").."|"..(height or "") + -- Do the scaling for DPI here, so it can be cached and not re-done + -- each time in _render() local scale_for_dpi_here = false if self.scale_for_dpi and DPI_SCALE ~= 1 then scale_for_dpi_here = true -- we'll do it before caching @@ -147,7 +155,7 @@ function ImageWidget:_loadfile() self._bb = cache.bb self._bb_disposable = false -- don't touch or free a cached _bb else - self._bb = Mupdf.renderImageFile(self.file, self.width, self.height) + self._bb = Mupdf.renderImageFile(self.file, width, height) if scale_for_dpi_here then local new_bb local bb_w, bb_h = self._bb:getWidth(), self._bb:getHeight()