From 6e2be98edcd6a0022a471676b9a7c937f6bbbb74 Mon Sep 17 00:00:00 2001 From: zwim <36999612+zwim@users.noreply.github.com> Date: Thu, 20 May 2021 23:14:11 +0200 Subject: [PATCH] Notifications: options to show none/some/more (#7718) Notification: adds some functions so it can be used as a notification manager. Have various bits of code emitting events that may generate notifications advertize themselves as the source for following notifications. Add a menu to allow selecting some subsets of sources to show or hide. --- frontend/apps/reader/modules/readerfont.lua | 47 ++++------- .../apps/reader/modules/readertypeset.lua | 7 ++ frontend/apps/reader/modules/readerview.lua | 7 ++ frontend/device/devicelistener.lua | 16 +--- frontend/dispatcher.lua | 3 + frontend/ui/data/creoptions.lua | 2 +- frontend/ui/data/optionsutil.lua | 55 ++++++++++++ .../elements/common_settings_menu_table.lua | 1 + frontend/ui/elements/reader_menu_order.lua | 2 + .../screen_notification_menu_table.lua | 83 +++++++++++++++++++ frontend/ui/widget/configdialog.lua | 35 ++++++++ frontend/ui/widget/notification.lua | 62 ++++++++++++++ frontend/ui/widget/toggleswitch.lua | 11 +++ 13 files changed, 289 insertions(+), 42 deletions(-) create mode 100644 frontend/ui/elements/screen_notification_menu_table.lua diff --git a/frontend/apps/reader/modules/readerfont.lua b/frontend/apps/reader/modules/readerfont.lua index 4523905a1..2deb7abca 100644 --- a/frontend/apps/reader/modules/readerfont.lua +++ b/frontend/apps/reader/modules/readerfont.lua @@ -15,6 +15,7 @@ local UIManager = require("ui/uimanager") local T = require("ffi/util").template local _ = require("gettext") local C_ = _.pgettext +local optionsutil = require("ui/data/optionsutil") local ReaderFont = InputContainer:new{ font_face = nil, @@ -36,11 +37,11 @@ function ReaderFont:init() IncreaseSize = { { "Shift", Input.group.PgFwd }, doc = "increase font size", - event = "ChangeSize", args = "increase" }, + event = "ChangeSize", args = 0.5 }, DecreaseSize = { { "Shift", Input.group.PgBack }, doc = "decrease font size", - event = "ChangeSize", args = "decrease" }, + event = "ChangeSize", args = -0.5 }, } end -- Build face_table for menu @@ -195,13 +196,8 @@ end --[[ UpdatePos event is used to tell ReaderRolling to update pos. --]] -function ReaderFont:onChangeSize(direction, font_delta) - local delta = direction == "decrease" and -1 or 1 - if font_delta then - self.font_size = self.font_size + font_delta * delta - else - self.font_size = self.font_size + delta - end +function ReaderFont:onChangeSize(delta) + self.font_size = self.font_size + delta self.ui:handleEvent(Event:new("SetFontSize", self.font_size)) return true end @@ -213,19 +209,15 @@ function ReaderFont:onSetFontSize(new_size) self.font_size = new_size self.ui.document:setFontSize(Screen:scaleBySize(new_size)) self.ui:handleEvent(Event:new("UpdatePos")) - UIManager:show(Notification:new{ - text = T( _("Font size set to %1."), self.font_size), - }) + Notification:notify(T(_("Font size set to %1."), self.font_size)) return true end function ReaderFont:onSetLineSpace(space) self.line_space_percent = math.min(200, math.max(50, space)) - UIManager:show(Notification:new{ - text = T( _("Line spacing set to %1%."), self.line_space_percent), - }) self.ui.document:setInterlineSpacePercent(self.line_space_percent) self.ui:handleEvent(Event:new("UpdatePos")) + Notification:notify(T(_("Line spacing set to %1%."), self.line_space_percent)) return true end @@ -233,6 +225,7 @@ function ReaderFont:onSetFontBaseWeight(weight) self.font_base_weight = weight self.ui.document:setFontBaseWeight(weight) self.ui:handleEvent(Event:new("UpdatePos")) + Notification:notify(T(_("Font weight set to %1."), optionsutil:getOptionText("SetFontBaseWeight", weight))) return true end @@ -240,6 +233,7 @@ function ReaderFont:onSetFontHinting(mode) self.font_hinting = mode self.ui.document:setFontHinting(mode) self.ui:handleEvent(Event:new("UpdatePos")) + Notification:notify(T(_("Font hinting set to %1."), optionsutil:getOptionText("SetFontHinting", mode))) return true end @@ -247,6 +241,7 @@ function ReaderFont:onSetFontKerning(mode) self.font_kerning = mode self.ui.document:setFontKerning(mode) self.ui:handleEvent(Event:new("UpdatePos")) + Notification:notify(T(_("Font kerning set to %1."), optionsutil:getOptionText("SetFontKerning", mode))) return true end @@ -254,6 +249,7 @@ function ReaderFont:onSetWordSpacing(values) self.word_spacing = values self.ui.document:setWordSpacing(values) self.ui:handleEvent(Event:new("UpdatePos")) + Notification:notify(T(_("Word spacing set to %1%, %2%."), values[1], values[2])) return true end @@ -261,6 +257,7 @@ function ReaderFont:onSetWordExpansion(value) self.word_expansion = value self.ui.document:setWordExpansion(value) self.ui:handleEvent(Event:new("UpdatePos")) + Notification:notify(T(_("Word expansion set to %1%."), value)) return true end @@ -268,10 +265,8 @@ function ReaderFont:onSetFontGamma(gamma) self.gamma_index = gamma self.ui.document:setGammaIndex(self.gamma_index) local gamma_level = self.ui.document:getGammaLevel() - UIManager:show(Notification:new{ - text = T( _("Font gamma set to %1."), gamma_level), - }) self.ui:handleEvent(Event:new("RedrawCurrentView")) + Notification:notify(T(_("Font gamma set to %1."), optionsutil:getOptionText("SetFontGamma", gamma_level))) return true end @@ -300,7 +295,7 @@ end function ReaderFont:makeDefault(face, touchmenu_instance) if face then UIManager:show(MultiConfirmBox:new{ - text = T( _("Would you like %1 to be used as the default font (★), or the fallback font (�)?\n\nCharacters not found in the active font are shown in the fallback font instead."), face), + text = T(_("Would you like %1 to be used as the default font (★), or the fallback font (�)?\n\nCharacters not found in the active font are shown in the fallback font instead."), face), choice1_text = _("Default"), choice1_callback = function() G_reader_settings:saveSetting("cre_font", face) @@ -342,21 +337,15 @@ end function ReaderFont:onIncreaseFontSize(ges) local delta_int = self:gesToFontSize(ges) - local info = Notification:new{text = _("Increasing font size…")} - UIManager:show(info) - UIManager:forceRePaint() - self:onChangeSize("increase", delta_int) - UIManager:close(info) + Notification:notify(_("Increasing font size…"), true) + self:onChangeSize(delta_int) return true end function ReaderFont:onDecreaseFontSize(ges) local delta_int = self:gesToFontSize(ges) - local info = Notification:new{text = _("Decreasing font size…")} - UIManager:show(info) - UIManager:forceRePaint() - self:onChangeSize("decrease", delta_int) - UIManager:close(info) + Notification:notify(_("Decreasing font size…"), true) + self:onChangeSize(-delta_int) return true end diff --git a/frontend/apps/reader/modules/readertypeset.lua b/frontend/apps/reader/modules/readertypeset.lua index 487405757..c9e1b9179 100644 --- a/frontend/apps/reader/modules/readertypeset.lua +++ b/frontend/apps/reader/modules/readertypeset.lua @@ -5,7 +5,9 @@ local InfoMessage = require("ui/widget/infomessage") local InputContainer = require("ui/widget/container/inputcontainer") local UIManager = require("ui/uimanager") local Math = require("optmath") +local Notification = require("ui/widget/notification") local lfs = require("libs/libkoreader-lfs") +local optionsutil = require("ui/data/optionsutil") local _ = require("gettext") local Screen = require("device").screen local T = require("ffi/util").template @@ -136,16 +138,19 @@ end function ReaderTypeset:onToggleEmbeddedStyleSheet(toggle) self:toggleEmbeddedStyleSheet(toggle) + Notification:notify(T( _("Embedded styles are %1."), optionsutil:getOptionText("ToggleEmbeddedStyleSheet", toggle))) return true end function ReaderTypeset:onToggleEmbeddedFonts(toggle) self:toggleEmbeddedFonts(toggle) + Notification:notify(T( _("Embedded fonts are %1."), optionsutil:getOptionText("ToggleEmbeddedFonts", toggle))) return true end function ReaderTypeset:onToggleImageScaling(toggle) self:toggleImageScaling(toggle) + Notification:notify(T( _("Image scaling set to %1."), optionsutil:getOptionText("ToggleImageScaling", toggle))) return true end @@ -156,6 +161,7 @@ end function ReaderTypeset:onSetBlockRenderingMode(mode) self:setBlockRenderingMode(mode) + Notification:notify(T( _("Render mode set to %1."), optionsutil:getOptionText("SetBlockRenderingMode", mode))) return true end @@ -177,6 +183,7 @@ local OBSOLETED_CSS = { function ReaderTypeset:onSetRenderDPI(dpi) self:setRenderDPI(dpi) + Notification:notify(T( _("Zoom set to %1."), optionsutil:getOptionText("SetRenderDPI", dpi))) return true end diff --git a/frontend/apps/reader/modules/readerview.lua b/frontend/apps/reader/modules/readerview.lua index 2aaaa9bde..4b6132983 100644 --- a/frontend/apps/reader/modules/readerview.lua +++ b/frontend/apps/reader/modules/readerview.lua @@ -9,6 +9,7 @@ local Geom = require("ui/geometry") local Event = require("ui/event") local IconWidget = require("ui/widget/iconwidget") local InfoMessage = require("ui/widget/infomessage") +local Notification = require("ui/widget/notification") local OverlapGroup = require("ui/widget/overlapgroup") local ReaderDogear = require("apps/reader/modules/readerdogear") local ReaderFlipping = require("apps/reader/modules/readerflipping") @@ -17,6 +18,7 @@ local TimeVal = require("ui/timeval") local UIManager = require("ui/uimanager") local dbg = require("dbg") local logger = require("logger") +local optionsutil = require("ui/data/optionsutil") local _ = require("gettext") local Screen = Device.screen local T = require("ffi/util").template @@ -713,6 +715,7 @@ function ReaderView:onSetRotationMode(rotation) self.ui:handleEvent(Event:new("SetDimensions", new_screen_size)) self.ui:onScreenResize(new_screen_size) self.ui:handleEvent(Event:new("InitScrollPageStates")) + Notification:notify(T(_("Rotation mode set to %1."), optionsutil:getOptionText("SetRotationMode", rotation))) return true end @@ -846,10 +849,12 @@ function ReaderView:onGammaUpdate(gamma) if self.page_scroll then self.ui:handleEvent(Event:new("UpdateScrollPageGamma", gamma)) end + Notification:notify(T(_("Font gamma set to %1."), gamma)) end function ReaderView:onFontSizeUpdate(font_size) self.ui:handleEvent(Event:new("ReZoom", font_size)) + Notification:notify(T(_("Font zoom set to %1."), font_size)) end function ReaderView:onDefectSizeUpdate() @@ -869,6 +874,7 @@ function ReaderView:onSetViewMode(new_mode) self.view_mode = new_mode self.ui.document:setViewMode(new_mode) self.ui:handleEvent(Event:new("ChangeViewMode")) + Notification:notify(T( _("View mode set to %1."), optionsutil:getOptionText("SetViewMode", new_mode))) end end @@ -877,6 +883,7 @@ end --another source (eg. coptions.lua) triggering a redraw is needed. function ReaderView:onPageGapUpdate(page_gap) self.page_gap.height = page_gap + Notification:notify(T(_("Page gap set to %1."), page_gap)) return true end diff --git a/frontend/device/devicelistener.lua b/frontend/device/devicelistener.lua index 9388cf1d2..7a13786be 100644 --- a/frontend/device/devicelistener.lua +++ b/frontend/device/devicelistener.lua @@ -51,9 +51,7 @@ function DeviceListener:onShowIntensity() else new_text = T(_("Frontlight intensity set to %1."), powerd:frontlightIntensity()) end - UIManager:show(Notification:new{ - text = new_text, - }) + Notification:notify(new_text) return true end @@ -62,9 +60,7 @@ function DeviceListener:onShowWarmth(value) if powerd.fl_warmth ~= nil then -- powerd.fl_warmth holds the warmth-value in the internal koreader scale [0,100] -- powerd.fl_warmth_max is the maximum value the hardware accepts - UIManager:show(Notification:new{ - text = T(_("Warmth set to %1."), math.floor(powerd.fl_warmth/100*powerd.fl_warmth_max)), - }) + Notification:notify(T(_("Warmth set to %1."), math.floor(powerd.fl_warmth/100*powerd.fl_warmth_max))) end return true end @@ -175,9 +171,7 @@ if Device:hasFrontlight() then if powerd.fl_warmth == nil then return false end if powerd.auto_warmth then - UIManager:show(Notification:new{ - text = _("Warmth is handled automatically."), - }) + Notification:notify(_("Warmth is handled automatically.")) return true end @@ -220,9 +214,7 @@ if Device:hasFrontlight() then else new_text = _("Frontlight disabled.") end - UIManager:show(Notification:new{ - text = new_text, - }) + Notification:notify(new_text) return true end diff --git a/frontend/dispatcher.lua b/frontend/dispatcher.lua index ac084e5c9..4e51bb5e6 100644 --- a/frontend/dispatcher.lua +++ b/frontend/dispatcher.lua @@ -30,6 +30,7 @@ Each setting contains: local CreOptions = require("ui/data/creoptions") local Device = require("device") local Event = require("ui/event") +local Notification = require("ui/widget/notification") local ReaderZooming = require("apps/reader/modules/readerzooming") local Screen = require("device").screen local UIManager = require("ui/uimanager") @@ -619,6 +620,7 @@ function Dispatcher:execute(ui, settings, gesture) if settingsList[k] ~= nil and (settingsList[k].conditions == nil or settingsList[k].conditions == true) then -- Be sure we don't send a document setting event if there's not yet or no longer a document if ui.document or (not settingsList[k].paging and not settingsList[k].rolling) then + Notification:setNotifySource(Notification.SOURCE_DISPATCHER) if settingsList[k].category == "none" then if settingsList[k].arg ~= nil then ui:handleEvent(Event:new(settingsList[k].event, settingsList[k].arg)) @@ -653,6 +655,7 @@ function Dispatcher:execute(ui, settings, gesture) end end end + Notification:resetNotifySource() end return Dispatcher diff --git a/frontend/ui/data/creoptions.lua b/frontend/ui/data/creoptions.lua index 6bac8246d..55d5534b2 100644 --- a/frontend/ui/data/creoptions.lua +++ b/frontend/ui/data/creoptions.lua @@ -432,7 +432,7 @@ Note that your selected font size is not affected by this setting.]]), }, values = {}, event = "ChangeSize", - args = {"decrease", "increase"}, + args = { -0.5, 0.5 }, alternate = false, name_text_hold_callback = function(configurable, __, prefix) local opt = { diff --git a/frontend/ui/data/optionsutil.lua b/frontend/ui/data/optionsutil.lua index 7c4a9d2d3..b8ec17951 100644 --- a/frontend/ui/data/optionsutil.lua +++ b/frontend/ui/data/optionsutil.lua @@ -6,6 +6,7 @@ local InfoMessage = require("ui/widget/infomessage") local UIManager = require("ui/uimanager") local _ = require("gettext") local T = require("ffi/util").template +local logger = require("logger") local optionsutil = {} @@ -147,4 +148,58 @@ Default margins: end end +function optionsutil:generateOptionText() + local CreOptions = require("ui/data/creoptions") + + self.option_text_table = {} + self.option_args_table = {} + for i = 1, #CreOptions do + for j = 1, #CreOptions[i].options do + local option = CreOptions[i].options[j] + if option.event then + if option.labels then + self.option_text_table[option.event] = option.labels + elseif option.toggle then + self.option_text_table[option.event] = option.toggle + end + self.option_args_table[option.event] = option.args + end + end + end +end + +function optionsutil:getOptionText(event, val) + if not self.option_text_table then + self:generateOptionText() + end + if not event or val == nil then + logger.err("[OptionsCatalog:getOptionText] Either event or val not set. This should not happen!") + return "" + end + if not self.option_text_table[event] then + logger.err("[OptionsCatalog:getOptionText] Event:" .. event .. " not found in option_text_table") + return "" + end + + local text + if type(val) == "number" then + text = self.option_text_table[event][val + 1] -- options count from zero + end + + -- if there are args, try to find the adequate toggle + if self.option_args_table[event] then + for i, args in pairs(self.option_args_table[event]) do + if args == val then + text = self.option_text_table[event][i] + end + end + end + + if text then + return text + else + return val + end +end + return optionsutil diff --git a/frontend/ui/elements/common_settings_menu_table.lua b/frontend/ui/elements/common_settings_menu_table.lua index bf2e5c2e3..9366fb89d 100644 --- a/frontend/ui/elements/common_settings_menu_table.lua +++ b/frontend/ui/elements/common_settings_menu_table.lua @@ -198,6 +198,7 @@ common_settings.screen = { common_settings.screen_rotation = require("ui/elements/screen_rotation_menu_table") common_settings.screen_dpi = require("ui/elements/screen_dpi_menu_table") common_settings.screen_eink_opt = require("ui/elements/screen_eink_opt_menu_table") +common_settings.screen_notification = require("ui/elements/screen_notification_menu_table") common_settings.menu_activate = require("ui/elements/menu_activate") common_settings.page_turns = require("ui/elements/page_turns") common_settings.screen_disable_double_tab = require("ui/elements/screen_disable_double_tap_table") diff --git a/frontend/ui/elements/reader_menu_order.lua b/frontend/ui/elements/reader_menu_order.lua index 458571e47..0eb6f0730 100644 --- a/frontend/ui/elements/reader_menu_order.lua +++ b/frontend/ui/elements/reader_menu_order.lua @@ -125,6 +125,8 @@ local order = { "----------------------------", "screen_timeout", "fullscreen", + "----------------------------", + "screen_notification", }, taps_and_gestures = { "gesture_manager", diff --git a/frontend/ui/elements/screen_notification_menu_table.lua b/frontend/ui/elements/screen_notification_menu_table.lua new file mode 100644 index 000000000..4a815be16 --- /dev/null +++ b/frontend/ui/elements/screen_notification_menu_table.lua @@ -0,0 +1,83 @@ +local Notification = require("ui/widget/notification") +local _ = require("gettext") + +local band = bit.band +local bor = bit.bor + +local function setMask(source) + G_reader_settings:saveSetting("notification_sources_to_show_mask", source) +end + +local function getMask() + return G_reader_settings:readSetting("notification_sources_to_show_mask") or Notification.SOURCE_DEFAULT +end + +return { + text = _("Notifications"), + help_text = _([[Notification popups may be shown at the top of screen on various occasions. +This allows selecting which to show or hide.]]), + checked_func = function() + local value = G_reader_settings:readSetting("notification_sources_to_show_mask") or Notification.SOURCE_DEFAULT + return value ~= 0 + end, + sub_item_table = { + { + text = _("No notifications"), + help_text = _("No notification popups will be shown."), + checked_func = function() + return getMask() == Notification.SOURCE_NONE + end, + callback = function() + setMask(Notification.SOURCE_NONE) + end, + separator = true, + }, + { + text = _("Some notifications from bottom menu"), + help_text = _("Show notification popups for bottom menu settings with no visual feedback."), + checked_func = function() + return band(getMask(), Notification.SOURCE_BOTTOM_MENU) == band(Notification.SOURCE_SOME, Notification.SOURCE_BOTTOM_MENU) + end, + callback = function() + if getMask() == Notification.SOURCE_ALL then + setMask(Notification.SOURCE_NONE) + end + setMask(bor( + band(Notification.SOURCE_SOME, Notification.SOURCE_BOTTOM_MENU), + band(getMask(), Notification.SOURCE_DISPATCHER))) + end, + }, + { + text = _("More notifications from bottom menu"), + help_text = _("Show notification popups for more bottom menu settings."), + checked_func = function() + return band(getMask(), Notification.SOURCE_BOTTOM_MENU) == band(Notification.SOURCE_DEFAULT, Notification.SOURCE_BOTTOM_MENU) + end, + callback = function() + if getMask() == Notification.SOURCE_ALL then + setMask(Notification.SOURCE_NONE) + end + setMask(bor( + band(Notification.SOURCE_DEFAULT, Notification.SOURCE_BOTTOM_MENU), + band(getMask(), Notification.SOURCE_DISPATCHER))) + end, + }, + { + text = _("Notifications from gestures and profiles"), + help_text = _("Show notification popups for changes from gestures and the profiles plugin."), + checked_func = function() + return band(getMask(), Notification.SOURCE_DISPATCHER) ~= 0 and getMask() ~= Notification.SOURCE_ALL + end, + callback = function() + if getMask() == Notification.SOURCE_ALL then + setMask(Notification.SOURCE_NONE) + end + + setMask(bor( + Notification.SOURCE_DISPATCHER, + band(getMask(), Notification.SOURCE_BOTTOM_MENU))) + end, + separator = true, + }, + } +} diff --git a/frontend/ui/widget/configdialog.lua b/frontend/ui/widget/configdialog.lua index e8f45c079..0a340b724 100644 --- a/frontend/ui/widget/configdialog.lua +++ b/frontend/ui/widget/configdialog.lua @@ -18,6 +18,7 @@ local IconButton = require("ui/widget/iconbutton") local IconWidget = require("ui/widget/iconwidget") local InputContainer = require("ui/widget/container/inputcontainer") local LineWidget = require("ui/widget/linewidget") +local Notification = require("ui/widget/notification") local RightContainer = require("ui/widget/container/rightcontainer") local Size = require("ui/size") local TextWidget = require("ui/widget/textwidget") @@ -85,12 +86,19 @@ function OptionTextItem:onTapSelect() item.underline_container.color = Blitbuffer.COLOR_WHITE end self.underline_container.color = Blitbuffer.COLOR_BLACK + + Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_ICON) self.config:onConfigChoose(self.values, self.name, self.event, self.args, self.events, self.current_item, self.hide_on_apply) + UIManager:setDirty(self.config, function() return "fast", self[1].dimen end) + + UIManager:tickAfterNext(function() + Notification:resetNotifySource() + end) return true end @@ -157,12 +165,19 @@ function OptionIconItem:onTapSelect() end --self[1][1].invert = true self.underline_container.color = Blitbuffer.COLOR_BLACK + + Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_ICON) self.config:onConfigChoose(self.values, self.name, self.event, self.args, self.events, self.current_item, self.hide_on_apply) + UIManager:setDirty(self.config, function() return "fast", self[1].dimen end) + + UIManager:tickAfterNext(function() + Notification:resetNotifySource() + end) return true end @@ -564,8 +579,12 @@ function ConfigOption:init() if self.options[c].show_true_value_func and not self.options[c].more_options_param.show_true_value_func then self.options[c].more_options_param.show_true_value_func = self.options[c].show_true_value_func end + Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_MORE) self.config:onConfigMoreChoose(self.options[c].values, self.options[c].name, self.options[c].event, arg, name_text, self.options[c].more_options_param) + UIManager:tickAfterNext(function() + Notification:resetNotifySource() + end) end end } @@ -591,20 +610,28 @@ function ConfigOption:init() num_buttons = #self.options[c].values, position = self.options[c].default_pos, callback = function(arg) + if arg == "-" or arg == "+" then + Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_FINE) self.config:onConfigFineTuneChoose(self.options[c].values, self.options[c].name, self.options[c].event, self.options[c].args, self.options[c].events, arg, self.options[c].hide_on_apply, self.options[c].fine_tune_param) elseif arg == "⋮" then + Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_MORE) self.config:onConfigMoreChoose(self.options[c].values, self.options[c].name, self.options[c].event, arg, name_text, self.options[c].more_options_param) else + Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_PROGRESS) self.config:onConfigChoose(self.options[c].values, self.options[c].name, self.options[c].event, self.options[c].args, self.options[c].events, arg, self.options[c].hide_on_apply) end + UIManager:setDirty(self.config, function() return "fast", switch.dimen end) + UIManager:tickAfterNext(function() + Notification:resetNotifySource() + end) end, hold_callback = function(arg) if arg == "-" or arg == "+" then @@ -1206,7 +1233,11 @@ function ConfigDialog:onConfigMoreChoose(values, name, event, args, name_text, m -- it actually do it when provided a callback as argument local dummy_callback = when_applied_callback and function() end args = args or {} + Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_MORE) self:onConfigEvent(event, value_tables, dummy_callback) + UIManager:tickAfterNext(function() + Notification:resetNotifySource() + end) self:update() end end, @@ -1298,6 +1329,7 @@ function ConfigDialog:onConfigMoreChoose(values, name, event, args, name_text, m -- it actually do it when provided a callback as argument local dummy_callback = when_applied_callback and function() end args = args or {} + Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_MORE) if more_options_param.value_table then if more_options_param.args_table then self:onConfigEvent(event, more_options_param.args_table[spin.value_index], dummy_callback) @@ -1307,6 +1339,9 @@ function ConfigDialog:onConfigMoreChoose(values, name, event, args, name_text, m else self:onConfigEvent(event, spin.value, dummy_callback) end + UIManager:tickAfterNext(function() + Notification:resetNotifySource() + end) self:update() end end, diff --git a/frontend/ui/widget/notification.lua b/frontend/ui/widget/notification.lua index 65ecee04a..c4c9ceccf 100644 --- a/frontend/ui/widget/notification.lua +++ b/frontend/ui/widget/notification.lua @@ -19,6 +19,26 @@ local VerticalGroup = require("ui/widget/verticalgroup") local Input = Device.input local Screen = Device.screen +local band = bit.band + +-- The following constants are positions in a bitfield +local SOURCE_BOTTOM_MENU_ICON = 0x0001 -- icons in bottom menu +local SOURCE_BOTTOM_MENU_TOGGLE = 0x0002 -- toggles in bottom menu +local SOURCE_BOTTOM_MENU_FINE = 0x0004 -- toggles with fine-tuning ("increase", "+" etc) +local SOURCE_BOTTOM_MENU_MORE = 0x0008 -- three dots in bottom menu +local SOURCE_BOTTOM_MENU_PROGRESS = 0x0010 -- progress indicator on bottom menu +local SOURCE_DISPATCHER = 0x0020 -- dispatcher +local SOURCE_OTHER = 0x0040 -- all other sources (e.g. keyboard) + +-- All bottom menu bits +local SOURCE_BOTTOM_MENU = SOURCE_BOTTOM_MENU_ICON + SOURCE_BOTTOM_MENU_TOGGLE + SOURCE_BOTTOM_MENU_FINE + + SOURCE_BOTTOM_MENU_MORE + SOURCE_BOTTOM_MENU_PROGRESS + +-- these values can be changed here +local SOURCE_SOME = SOURCE_BOTTOM_MENU_FINE + SOURCE_DISPATCHER +local SOURCE_DEFAULT = SOURCE_SOME + SOURCE_BOTTOM_MENU_MORE + SOURCE_BOTTOM_MENU_PROGRESS +local SOURCE_ALL = SOURCE_BOTTOM_MENU + SOURCE_DISPATCHER + SOURCE_OTHER + local Notification = InputContainer:new{ face = Font:getFace("x_smallinfofont"), text = "Null Message", @@ -28,6 +48,21 @@ local Notification = InputContainer:new{ toast = true, -- closed on any event, and let the event propagate to next top widget _nums_shown = {}, -- array of stacked notifications + + SOURCE_BOTTOM_MENU_ICON = SOURCE_BOTTOM_MENU_ICON, + SOURCE_BOTTOM_MENU_TOGGLE = SOURCE_BOTTOM_MENU_TOGGLE, + SOURCE_BOTTOM_MENU_FINE = SOURCE_BOTTOM_MENU_FINE, + SOURCE_BOTTOM_MENU_MORE = SOURCE_BOTTOM_MENU_MORE, + SOURCE_BOTTOM_MENU_PROGRESS = SOURCE_BOTTOM_MENU_PROGRESS, + SOURCE_DISPATCHER = SOURCE_DISPATCHER, + SOURCE_OTHER = SOURCE_OTHER, + + SOURCE_BOTTOM_MENU = SOURCE_BOTTOM_MENU, + + SOURCE_NONE = 0, + SOURCE_SOME = SOURCE_SOME, + SOURCE_DEFAULT = SOURCE_DEFAULT, + SOURCE_ALL = SOURCE_ALL, } function Notification:init() @@ -93,6 +128,33 @@ function Notification:init() } end +function Notification:setNotifySource(source) + self.notify_source = source +end + +function Notification:resetNotifySource() + self.notify_source = Notification.SOURCE_OTHER +end + +function Notification:getNotifySource() + return self.notify_source +end + +-- show popups if `self.notify_source` is not masked by the setting `notification_sources_to_show_mask` +function Notification:notify(arg, refresh_after) + local mask = G_reader_settings:readSetting("notification_sources_to_show_mask") or self.SOURCE_DEFAULT + if self.notify_source and band(mask, self.notify_source) ~= 0 then + UIManager:show(Notification:new{ + text = arg, + }) + if refresh_after then + UIManager:forceRePaint() + end + return true + end + return false +end + function Notification:_cleanShownStack(num) -- Clean stack of shown notifications if num then diff --git a/frontend/ui/widget/toggleswitch.lua b/frontend/ui/widget/toggleswitch.lua index e134b0916..f008b44eb 100644 --- a/frontend/ui/widget/toggleswitch.lua +++ b/frontend/ui/widget/toggleswitch.lua @@ -15,6 +15,7 @@ local GestureRange = require("ui/gesturerange") local HorizontalGroup = require("ui/widget/horizontalgroup") local InputContainer = require("ui/widget/container/inputcontainer") local FrameContainer = require("ui/widget/container/framecontainer") +local Notification = require("ui/widget/notification") local Size = require("ui/size") local TextWidget = require("ui/widget/textwidget") local UIManager = require("ui/uimanager") @@ -217,11 +218,21 @@ function ToggleSwitch:onTapSelect(arg, gev) self.callback(self.position) end if self.toggle[self.position] ~= "⋮" then + if #self.values == 0 then -- this is a toggle which is not selectable (eg. increase, decrease) + Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_FINE) + else + Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_TOGGLE) + end self.config:onConfigChoose(self.values, self.name, self.event, self.args, self.events, self.position, self.hide_on_apply) + UIManager:setDirty(self.config, function() return "ui", self.dimen end) + + UIManager:tickAfterNext(function() + Notification:setNotifySource(Notification.SOURCE_OTHER) -- only allow events, if they are activated + end) end return true end