From bda44a99ef5476f14083e913ca1df1537e7754dc Mon Sep 17 00:00:00 2001 From: yparitcher Date: Tue, 14 Jul 2020 17:39:03 -0400 Subject: [PATCH] Dispatcher: use sections (#6364) use `device` `filemanager` `rolling` and `paging` sections to organize the dispatcher menu and allow the user to know when the action will apply add events from ReaderGesture allow profiles in FM --- frontend/apps/reader/modules/readerfont.lua | 1 + frontend/device/devicelistener.lua | 145 +++--- frontend/dispatcher.lua | 430 +++++++++++++----- .../ui/elements/filemanager_menu_order.lua | 1 + plugins/profiles.koplugin/main.lua | 6 +- 5 files changed, 410 insertions(+), 173 deletions(-) diff --git a/frontend/apps/reader/modules/readerfont.lua b/frontend/apps/reader/modules/readerfont.lua index 2b47d5dd7..6350b5c07 100644 --- a/frontend/apps/reader/modules/readerfont.lua +++ b/frontend/apps/reader/modules/readerfont.lua @@ -321,6 +321,7 @@ function ReaderFont:addToMainMenu(menu_items) end function ReaderFont:gesToFontSize(ges) + if type(ges) ~= "table" then return ges end if ges.distance == nil then ges.distance = 1 end diff --git a/frontend/device/devicelistener.lua b/frontend/device/devicelistener.lua index 4d001fdb3..9f8df840c 100644 --- a/frontend/device/devicelistener.lua +++ b/frontend/device/devicelistener.lua @@ -58,40 +58,46 @@ if Device:hasFrontlight() then -- direction -1 - decrease frontlight function DeviceListener:onChangeFlIntensity(ges, direction) local powerd = Device:getPowerDevice() - local gestureScale - local scale_multiplier - if ges.ges == "two_finger_swipe" then - -- for backward compatibility - scale_multiplier = FRONTLIGHT_SENSITIVITY_DECREASE * 0.8 - elseif ges.ges == "swipe" then - scale_multiplier = 0.8 + local delta_int + --received gesture + if type(ges) == "table" then + local gestureScale + local scale_multiplier + if ges.ges == "two_finger_swipe" then + -- for backward compatibility + scale_multiplier = FRONTLIGHT_SENSITIVITY_DECREASE * 0.8 + elseif ges.ges == "swipe" then + scale_multiplier = 0.8 + else + scale_multiplier = 1 + end + if ges.direction == "south" or ges.direction == "north" then + gestureScale = Screen:getHeight() * scale_multiplier + elseif ges.direction == "west" or ges.direction == "east" then + gestureScale = Screen:getWidth() * scale_multiplier + else + local width = Screen:getWidth() + local height = Screen:getHeight() + -- diagonal + gestureScale = math.sqrt(width * width + height * height) * scale_multiplier + end + if powerd.fl_intensity == nil then return false end + + local steps_tbl = {} + local scale = (powerd.fl_max - powerd.fl_min) / 2 / 10.6 + for i = 1, #self.steps_fl, 1 do + steps_tbl[i] = math.ceil(self.steps_fl[i] * scale) + end + + if ges.distance == nil then + ges.distance = 1 + end + local step = math.ceil(#steps_tbl * ges.distance / gestureScale) + delta_int = steps_tbl[step] or steps_tbl[#steps_tbl] else - scale_multiplier = 1 + -- received amount to change + delta_int = ges end - if ges.direction == "south" or ges.direction == "north" then - gestureScale = Screen:getHeight() * scale_multiplier - elseif ges.direction == "west" or ges.direction == "east" then - gestureScale = Screen:getWidth() * scale_multiplier - else - local width = Screen:getWidth() - local height = Screen:getHeight() - -- diagonal - gestureScale = math.sqrt(width * width + height * height) * scale_multiplier - end - if powerd.fl_intensity == nil then return false end - - local steps_tbl = {} - local scale = (powerd.fl_max - powerd.fl_min) / 2 / 10.6 - for i = 1, #self.steps_fl, 1 - do - steps_tbl[i] = math.ceil(self.steps_fl[i] * scale) - end - - if ges.distance == nil then - ges.distance = 1 - end - local step = math.ceil(#steps_tbl * ges.distance / gestureScale) - local delta_int = steps_tbl[step] or steps_tbl[#steps_tbl] if direction ~= -1 and direction ~= 1 then -- set default value (increase frontlight) direction = 1 @@ -142,47 +148,52 @@ if Device:hasFrontlight() then return true end - local gestureScale - local scale_multiplier - if ges.ges == "two_finger_swipe" then - -- for backward compatibility - scale_multiplier = FRONTLIGHT_SENSITIVITY_DECREASE * 0.8 - elseif ges.ges == "swipe" then - scale_multiplier = 0.8 - else - scale_multiplier = 1 - end - - if ges.direction == "south" or ges.direction == "north" then - gestureScale = Screen:getHeight() * scale_multiplier - elseif ges.direction == "west" or ges.direction == "east" then - gestureScale = Screen:getWidth() * scale_multiplier + local delta_int + --received gesture + if type(ges) == "table" then + local gestureScale + local scale_multiplier + if ges.ges == "two_finger_swipe" then + -- for backward compatibility + scale_multiplier = FRONTLIGHT_SENSITIVITY_DECREASE * 0.8 + elseif ges.ges == "swipe" then + scale_multiplier = 0.8 + else + scale_multiplier = 1 + end + + if ges.direction == "south" or ges.direction == "north" then + gestureScale = Screen:getHeight() * scale_multiplier + elseif ges.direction == "west" or ges.direction == "east" then + gestureScale = Screen:getWidth() * scale_multiplier + else + local width = Screen:getWidth() + local height = Screen:getHeight() + -- diagonal + gestureScale = math.sqrt(width * width + height * height) * scale_multiplier + end + + local steps_tbl = {} + local scale = (powerd.fl_max - powerd.fl_min) / 2 / 10.6 + for i = 1, #self.steps_fl, 1 do + steps_tbl[i] = math.ceil(self.steps_fl[i] * scale) + end + + if ges.distance == nil then + ges.distance = 1 + end + + local step = math.ceil(#steps_tbl * ges.distance / gestureScale) + delta_int = steps_tbl[step] or steps_tbl[#steps_tbl] else - local width = Screen:getWidth() - local height = Screen:getHeight() - -- diagonal - gestureScale = math.sqrt(width * width + height * height) * scale_multiplier - end - - local steps_tbl = {} - local scale = (powerd.fl_max - powerd.fl_min) / 2 / 10.6 - for i = 1, #self.steps_fl, 1 - do - steps_tbl[i] = math.ceil(self.steps_fl[i] * scale) + -- received amount to change + delta_int = ges end - - if ges.distance == nil then - ges.distance = 1 - end - - local step = math.ceil(#steps_tbl * ges.distance / gestureScale) - local delta_int = steps_tbl[step] or steps_tbl[#steps_tbl] - local warmth if direction ~= -1 and direction ~= 1 then -- set default value (increase frontlight) direction = 1 end - warmth = powerd.fl_warmth + direction * delta_int + local warmth = powerd.fl_warmth + direction * delta_int if warmth > 100 then warmth = 100 elseif warmth < 0 then diff --git a/frontend/dispatcher.lua b/frontend/dispatcher.lua index d459bad86..d82a88c0a 100644 --- a/frontend/dispatcher.lua +++ b/frontend/dispatcher.lua @@ -1,4 +1,5 @@ local CreOptions = require("ui/data/creoptions") +local Device = require("device") local Event = require("ui/event") local Screen = require("device").screen local UIManager = require("ui/uimanager") @@ -12,37 +13,242 @@ local Dispatcher = { --[[-- contains a list of a dispatchable settings each setting contains: - category: one of none, toggle, absolutenumber, incrementalnumber, or string. + category: one of + none: a direct event call + arg: a event that expects a gesture object or an argument + absolutenumber: event that sets a number + incrementalnumber: event that increments a number & accepts a gesture object + string: event with a list of arguments to chose from event: what to call. title: for use in ui. + section: under which menu to display (currently: device, filemanager, rolling, paging) and optionally min/max: for number default args: allowed values for string. toggle: display name for args + separator: put a separator after in the menu list --]]-- local settingsList = { - --CreOptions - rotation_mode = {category="string"}, - visible_pages = {category="string"}, - h_page_margins = {category="string"}, - sync_t_b_page_margins = {category="string"}, - t_page_margin = {category="absolutenumber"}, - b_page_margin = {category="absolutenumber"}, - view_mode = {category="string", title="View Mode (CRengine)"}, - block_rendering_mode = {category="string"}, - render_dpi = {category="string"}, - line_spacing = {category="absolutenumber"}, - font_size = {category="absolutenumber", title="Font Size (CRengine)"}, - font_weight = {category="string"}, - --font_gamma = {category="string"}, - font_hinting = {category="string"}, - font_kerning = {category="string"}, - status_line = {category="string"}, - embedded_css = {category="string"}, - embedded_fonts = {category="string"}, - smooth_scaling = {category="string"}, - nightmode_images = {category="string"}, + -- Device settings + show_frontlight_dialog = { category="none", event="ShowFlDialog", title=_("Show frontlight dialog"), device=true, condition=Device:hasFrontlight(),}, + toggle_frontlight = { category="none", event="ToggleFrontlight", title=_("Toggle frontlight"), device=true, condition=Device:hasFrontlight(),}, + increase_frontlight = { category="incrementalnumber", event="IncreaseFlIntensity", min=1, max=Device:getPowerDevice().fl_max, title=_("Increase frontlight brightness"), device=true, condition=Device:hasFrontlight(),}, + decrease_frontlight = { category="incrementalnumber", event="DecreaseFlIntensity", min=1, max=Device:getPowerDevice().fl_max, title=_("Decrease frontlight brightness"), device=true, condition=Device:hasFrontlight(),}, + increase_frontlight_warmth = { category="incrementalnumber", event="IncreaseFlWarmth", min=1, max=Device:getPowerDevice().fl_warmth_max, title=_("Increase frontlight warmth"), device=true, condition=Device:hasNaturalLight(),}, + decrease_frontlight_warmth = { category="incrementalnumber", event="DecreaseFlWarmth", min=1, max=Device:getPowerDevice().fl_warmth_max, title=_("Decrease frontlight warmth"), device=true, condition=Device:hasNaturalLight(),}, + toggle_gsensor = { category="none", event="ToggleGSensor", title=_("Toggle accelerometer"), device=true, condition=Device:canToggleGSensor(),}, + wifi_on = { category="none", event="InfoWifiOn", title=_("Turn on Wi-Fi"), device=true, condition=Device:hasWifiToggle(),}, + wifi_off = { category="none", event="InfoWifiOff", title=_("Turn off Wi-Fi"), device=true, condition=Device:hasWifiToggle(),}, + toggle_wifi = { category="none", event="ToggleWifi", title=_("Toggle Wi-Fi"), device=true, condition=Device:hasWifiToggle(),}, + reading_progress = { category="none", event="ShowReaderProgress", title=_("Reading progress"), device=true,}, + stats_calendar_view = { category="none", event="ShowCalendarView", title=_("Statistics calendar view"), device=true,}, + history = { category="none", event="ShowHist", title=_("History"), device=true,}, + open_previous_document = { category="none", event="OpenLastDoc", title=_("Open previous document"), device=true,}, + filemanager = { category="none", event="Home", title=_("File browser"), device=true,}, + dictionary_lookup = { category="none", event="ShowDictionaryLookup", title=_("Dictionary lookup"), device=true,}, + wikipedia_lookup = { category="none", event="ShowWikipediaLookup", title=_("Wikipedia lookup"), device=true,}, + fulltext_search = { category="none", event="ShowFulltextSearchInput", title=_("Fulltext search"), device=true,}, + file_search = { category="none", event="ShowFileSearch", title=_("File search"), device=true,}, + full_refresh = { category="none", event="FullRefresh", title=_("Full screen refresh"), device=true,}, + night_mode = { category="none", event="ToggleNightMode", title=_("Night mode"), device=true,}, + suspend = { category="none", event="SuspendEvent", title=_("Suspend"), device=true,}, + exit = { category="none", event="Exit", title=_("Exit KOReader"), device=true,}, + restart = { category="none", event="Restart", title=_("Restart KOReader"), device=true, condition=Device:canRestart(),}, + reboot = { category="none", event="Reboot", title=_("Reboot the device"), device=true, condition=Device:canReboot(),}, + poweroff = { category="none", event="PowerOff", title=_("Power off"), device=true, condition=Device:canPowerOff(),}, + show_menu = { category="none", event="ShowMenu", title=_("Show menu"), device=true,}, + toggle_hold_corners = { category="none", event="IgnoreHoldCorners", title=_("Toggle hold corners"), device=true,}, + toggle_rotation = { category="none", event="ToggleRotation", title=_("Toggle rotation"), device=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,}, + calibre_browse_series = { category="none", event="CalibreBrowseSeries", title=_("Browse all calibre series"), device=true,}, + favorites = { category="arg", event="ShowColl", arg="favorites", title=_("Favorites"), device=true,}, + + -- filemanager settings + folder_up = { category="none", event="FolderUp", title=_("Folder up"), filemanager=true}, + show_plus_menu = { category="none", event="ShowPlusMenu", title=_("Show plus menu"), filemanager=true}, + folder_shortcuts = { category="none", event="ShowFolderShortcutsDialog", title=_("Folder shortcuts"), filemanager=true}, + + -- reader settings + prev_chapter = { category="none", event="GotoPrevChapter", title=_("Previous chapter"), rolling=true, paging=true,}, + next_chapter = { category="none", event="GotoNextChapter", title=_("Next chapter"), rolling=true, paging=true,}, + first_page = { category="none", event="GoToBeginning", title=_("First page"), rolling=true, paging=true,}, + last_page = { category="none", event="GoToEnd", title=_("Last page"), rolling=true, paging=true,}, + prev_bookmark = { category="none", event="GotoPreviousBookmarkFromPage", title=_("Previous bookmark"), rolling=true, paging=true,}, + next_bookmark = { category="none", event="GotoNextBookmarkFromPage", title=_("Next bookmark"), rolling=true, paging=true,}, + go_to = { category="none", event="ShowGotoDialog", title=_("Go to"), rolling=true, paging=true,}, + skim = { category="none", event="ShowSkimtoDialog", title=_("Skim"), rolling=true, paging=true,}, + back = { category="none", event="Back", title=_("Back"), rolling=true, paging=true,}, + previous_location = { category="arg", event="GoBackLink", arg=true, title=_("Back to previous location"), rolling=true, paging=true,}, + latest_bookmark = { category="none", event="GoToLatestBookmark", title=_("Go to latest bookmark"), rolling=true, paging=true,}, + follow_nearest_link = { category="arg", event="GoToPageLink", arg={pos={x=0,y=0}}, title=_("Follow nearest link"), rolling=true, paging=true,}, + follow_nearest_internal_link = { category="arg", event="GoToInternalPageLink", arg={pos={x=0,y=0}}, title=_("Follow nearest internal link"), rolling=true, paging=true,}, + clear_location_history = { category="arg", event="ClearLocationStack", arg=true, title=_("Clear location history"), rolling=true, paging=true,}, + toc = { category="none", event="ShowToc", title=_("Table of contents"), rolling=true, paging=true,}, + bookmarks = { category="none", event="ShowBookmark", title=_("Bookmarks"), rolling=true, paging=true,}, + book_statistics = { category="none", event="ShowBookStats", title=_("Book statistics"), rolling=true, paging=true,}, + book_status = { category="none", event="ShowBookStatus", title=_("Book status"), rolling=true, paging=true,}, + book_info = { category="none", event="ShowBookInfo", title=_("Book information"), rolling=true, paging=true,}, + book_description = { category="none", event="ShowBookDescription", title=_("Book description"), rolling=true, paging=true,}, + book_cover = { category="none", event="ShowBookCover", title=_("Book cover"), rolling=true, paging=true,}, + show_config_menu = { category="none", event="ShowConfigMenu", title=_("Show bottom menu"), rolling=true, paging=true,}, + toggle_bookmark = { category="none", event="ToggleBookmark", title=_("Toggle bookmark"), rolling=true, paging=true,}, + toggle_inverse_reading_order = { category="none", event="ToggleReadingOrder", title=_("Toggle page turn direction"), rolling=true, paging=true,}, + cycle_highlight_action = { category="none", event="CycleHighlightAction", title=_("Cycle highlight action"), rolling=true, paging=true,}, + cycle_highlight_style = { category="none", event="CycleHighlightStyle", title=_("Cycle highlight style"), rolling=true, paging=true,}, + kosync_push_progress = { category="none", event="KOSyncPushProgress", title=_("Push progress from this device"), rolling=true, paging=true,}, + kosync_pull_progress = { category="none", event="KOSyncPullProgress", title=_("Pull progress from other devices"), rolling=true, paging=true,}, + page_jmp = { category="absolutenumber", event="GotoViewRel", min=-100, max=100, title=_("Go X pages"), rolling=true, paging=true,}, + + -- rolling reader settings + increase_font = { category="incrementalnumber", event="IncreaseFontSize", min=1, max=255, title=_("Increase font size"), rolling=true,}, + decrease_font = { category="incrementalnumber", event="DecreaseFontSize", min=1, max=255, title=_("Decrease font size"), rolling=true,}, + + -- paging reader settings + toggle_page_flipping = { category="none", event="TogglePageFlipping", title=_("Toggle page flipping"), paging=true,}, + toggle_reflow = { category="none", event="ToggleReflow", title=_("Toggle reflow"), paging=true,}, + zoom = { category="string", event="SetZoomMode", title=_("Zoom to"), args={"contentwidth", "contentheight", "pagewidth", "pageheight", "column", "content", "page"}, toggle={"content width", "content height", "page width", "page height", "column", "content", "page"}, paging=true,}, + + -- parsed from CreOptions + -- the rest of the table elements are built from their counterparts in CreOptions + rotation_mode = {category="string", device=true}, + visible_pages = {category="string", rolling=true}, + h_page_margins = {category="string", rolling=true}, + sync_t_b_page_margins = {category="string", rolling=true}, + t_page_margin = {category="absolutenumber", rolling=true}, + b_page_margin = {category="absolutenumber", rolling=true}, + view_mode = {category="string", rolling=true}, + block_rendering_mode = {category="string", rolling=true}, + render_dpi = {category="string", rolling=true}, + line_spacing = {category="absolutenumber", rolling=true}, + font_size = {category="absolutenumber", title="Font Size", rolling=true}, + font_weight = {category="string", rolling=true}, + --font_gamma = {category="string", rolling=true}, + font_hinting = {category="string", rolling=true}, + font_kerning = {category="string", rolling=true}, + status_line = {category="string", rolling=true}, + embedded_css = {category="string", rolling=true}, + embedded_fonts = {category="string", rolling=true}, + smooth_scaling = {category="string", rolling=true}, + nightmode_images = {category="string", rolling=true}, +} + +-- array for item order in menu +local dispatcher_menu_order = { + -- device + "reading_progress", + "history", + "open_previous_document", + "favorites", + "filemanager", + "stats_calendar_view", + + "dictionary_lookup", + "wikipedia_lookup", + "fulltext_search", + "file_search", + + "full_refresh", + "night_mode", + "suspend", + "exit", + "restart", + "reboot", + "poweroff", + + "show_menu", + "show_config_menu", + "show_frontlight_dialog", + "toggle_frontlight", + "increase_frontlight", + "decrease_frontlight", + "increase_frontlight_warmth", + "decrease_frontlight_warmth", + + "toggle_hold_corners", + "toggle_gsensor", + "toggle_rotation", + + "wifi_on", + "wifi_off", + "toggle_wifi", + + "wallabag_download", + "calibre_search", + "calibre_browse_tags", + "calibre_browse_series", + + "rotation_mode", + + -- filemanager + "folder_up", + "show_plus_menu", + "folder_shortcuts", + + -- reader + "page_jmp", + "prev_chapter", + "next_chapter", + "first_page", + "last_page", + "prev_bookmark", + "next_bookmark", + "go_to", + "skim", + "back", + "previous_location", + "latest_bookmark", + "follow_nearest_link", + "follow_nearest_internal_link", + "clear_location_history", + + "toc", + "bookmarks", + "book_statistics", + + "book_status", + "book_info", + "book_description", + "book_cover", + + "increase_font", + "decrease_font", + "font_size", + --"font_gamma", + "font_weight", + "font_hinting", + "font_kerning", + + "toggle_bookmark", + "toggle_page_flipping", + "toggle_reflow", + "toggle_inverse_reading_order", + "zoom", + "cycle_highlight_action", + "cycle_highlight_style", + + "kosync_push_progress", + "kosync_pull_progress", + + "visible_pages", + + "h_page_margins", + "sync_t_b_page_margins", + "t_page_margin", + "b_page_margin", + + "view_mode", + "block_rendering_mode", + "render_dpi", + "line_spacing", + + "status_line", + "embedded_css", + "embedded_fonts", + "smooth_scaling", + "nightmode_images", } --[[-- @@ -94,84 +300,50 @@ function Dispatcher:init() Dispatcher.initialized = true end ---[[-- -Add a submenu to edit which items are dispatched -arguments are: - 1) self - 2) the table representing the submenu (can be empty) - 3) the name of the parent of the settings table (must be a child of self) - 4) the name of the settings table -example usage: - Dispatcher.addSubMenu(self, sub_items, "profiles", "profile1") ---]]-- -function Dispatcher:addSubMenu(menu, location, settings) - if not Dispatcher.initialized then Dispatcher:init() end - table.insert(menu, { - text = _("None"), - separator = true, - checked_func = function() - return next(self[location][settings]) == nil - end, - callback = function(touchmenu_instance) - self[location][settings] = {} - if touchmenu_instance then touchmenu_instance:updateItems() end - end, - }) - for k, v in pairs(settingsList) do - if settingsList[k].category == "none" then - table.insert(menu, { - text = settingsList[k].title, - checked_func = function() - return self[location][settings] ~= nil and self[location][settings][k] ~= nil - end, - callback = function(touchmenu_instance) - if self[location][settings] ~= nil - and self[location][settings][k] then - self[location][settings][k] = nil - else - self[location][settings][k] = true - end - if touchmenu_instance then touchmenu_instance:updateItems() end - end, - }) - elseif settingsList[k].category == "toggle" then +function Dispatcher.addItem(caller, menu, location, settings, section) + for _, k in ipairs(dispatcher_menu_order) do + if settingsList[k][section] == true and + (settingsList[k].condition == nil or settingsList[k].condition) + then + if settingsList[k].category == "none" or settingsList[k].category == "arg" then table.insert(menu, { - text_func = function() - return T(settingsList[k].title, self[location][settings][k]) - end, + text = settingsList[k].title, checked_func = function() - return self[location][settings] ~= nil and self[location][settings][k] ~= nil + return caller[location][settings] ~= nil and caller[location][settings][k] ~= nil end, callback = function(touchmenu_instance) - self[location][settings][k] = not self[location][settings][k] - if touchmenu_instance then touchmenu_instance:updateItems() end - end, - hold_callback = function(touchmenu_instance) - self[location][settings][k] = nil + if caller[location][settings] ~= nil + and caller[location][settings][k] + then + caller[location][settings][k] = nil + else + caller[location][settings][k] = true + end if touchmenu_instance then touchmenu_instance:updateItems() end - end, - }) + end, + separator = settingsList[k].separator, + }) elseif settingsList[k].category == "absolutenumber" then table.insert(menu, { text_func = function() - return T(settingsList[k].title, self[location][settings][k] or "") + return T(settingsList[k].title, caller[location][settings][k] or "") end, checked_func = function() - return self[location][settings] ~= nil and self[location][settings][k] ~= nil + return caller[location][settings] ~= nil and caller[location][settings][k] ~= nil end, callback = function(touchmenu_instance) local SpinWidget = require("ui/widget/spinwidget") local items = SpinWidget:new{ width = Screen:getWidth() * 0.6, - value = self[location][settings][k] or settingsList[k].default or 0, + value = caller[location][settings][k] or settingsList[k].default or 0, value_min = settingsList[k].min, value_step = 1, value_hold_step = 2, value_max = settingsList[k].max, default_value = 0, - title_text = T(settingsList[k].title, self[location][settings][k] or ""), + title_text = T(settingsList[k].title, caller[location][settings][k] or ""), callback = function(spin) - self[location][settings][k] = spin.value + caller[location][settings][k] = spin.value if touchmenu_instance then touchmenu_instance:updateItems() end @@ -180,32 +352,34 @@ function Dispatcher:addSubMenu(menu, location, settings) UIManager:show(items) end, hold_callback = function(touchmenu_instance) - self[location][settings][k] = nil + caller[location][settings][k] = nil if touchmenu_instance then touchmenu_instance:updateItems() end end, + separator = settingsList[k].separator, }) elseif settingsList[k].category == "incrementalnumber" then table.insert(menu, { text_func = function() - return T(settingsList[k].title, self[location][settings][k] or "") + return T(settingsList[k].title, caller[location][settings][k] or "") end, checked_func = function() - return self[location][settings] ~= nil and self[location][settings][k] ~= nil + return caller[location][settings] ~= nil and caller[location][settings][k] ~= nil end, callback = function(touchmenu_instance) + local _ = require("gettext") local SpinWidget = require("ui/widget/spinwidget") local items = SpinWidget:new{ width = Screen:getWidth() * 0.6, - value = self[location][settings][k] or 0, + value = caller[location][settings][k] or 0, value_min = settingsList[k].min, value_step = 1, value_hold_step = 2, value_max = settingsList[k].max, default_value = 0, - title_text = T(settingsList[k].title, self[location][settings][k] or ""), - text = _([[If set to 0 and called by a gesture the amount of the gesture will be used]]), + title_text = T(settingsList[k].title, caller[location][settings][k] or ""), + info_text = _([[If called by a gesture the amount of the gesture will be used]]), callback = function(spin) - self[location][settings][k] = spin.value + caller[location][settings][k] = spin.value if touchmenu_instance then touchmenu_instance:updateItems() end @@ -214,11 +388,12 @@ function Dispatcher:addSubMenu(menu, location, settings) UIManager:show(items) end, hold_callback = function(touchmenu_instance) - self[location][settings][k] = nil + caller[location][settings][k] = nil if touchmenu_instance then touchmenu_instance:updateItems() end end, + separator = settingsList[k].separator, }) elseif settingsList[k].category == "string" then local sub_item_table = {} @@ -226,34 +401,80 @@ function Dispatcher:addSubMenu(menu, location, settings) table.insert(sub_item_table, { text = tostring(settingsList[k].toggle[i]), checked_func = function() - return self[location][settings] ~= nil - and self[location][settings][k] ~= nil - and self[location][settings][k] == settingsList[k].args[i] + return caller[location][settings] ~= nil + and caller[location][settings][k] ~= nil + and caller[location][settings][k] == settingsList[k].args[i] end, callback = function() - self[location][settings][k] = settingsList[k].args[i] + caller[location][settings][k] = settingsList[k].args[i] end, }) end table.insert(menu, { text_func = function() - return T(settingsList[k].title, self[location][settings][k]) + return T(settingsList[k].title, caller[location][settings][k]) end, checked_func = function() - return self[location][settings] ~= nil - and self[location][settings][k] ~= nil + return caller[location][settings] ~= nil + and caller[location][settings][k] ~= nil end, sub_item_table = sub_item_table, keep_menu_open = true, hold_callback = function(touchmenu_instance) - self[location][settings][k] = nil + caller[location][settings][k] = nil if touchmenu_instance then touchmenu_instance:updateItems() end end, + separator = settingsList[k].separator, }) end end + end +end + +--[[-- +Add a submenu to edit which items are dispatched +arguments are: + 1) the caller + 2) the table representing the submenu (can be empty) + 3) the name of the parent of the settings table (must be a child of self) + 4) the name of the settings table +example usage: + Dispatcher.addSubMenu(self, sub_items, "profiles", "profile1") + +Must be executed in the context of the caller to add items to the callers menu. +therefore declared as Dispatcher.addSubMenu(caller, menu, location, settings) +but should be called as Dispatcher.addSubMenu(self, menu, location, settings) +--]]-- +function Dispatcher.addSubMenu(caller, menu, location, settings) + if not Dispatcher.initialized then Dispatcher:init() end + table.insert(menu, { + text = _("None"), + separator = true, + checked_func = function() + return next(caller[location][settings]) == nil + end, + callback = function(touchmenu_instance) + caller[location][settings] = {} + if touchmenu_instance then touchmenu_instance:updateItems() end + end, + }) + local section_list = { + {"device", _("Device")}, + {"filemanager", _("Filemanager")}, + {"rolling", _("Reflowable documents (epub, fb2, txt…)")}, + {"paging", _("Fixed layout documents (pdf, djvu, pics…)")}, + } + for _, section in ipairs(section_list) do + local submenu = {} + -- pass caller's context + Dispatcher.addItem(caller, submenu, location, settings, section[1]) + table.insert(menu, { + text = section[2], + sub_item_table = submenu, + }) + end end function Dispatcher:execute(settings, gesture) @@ -262,17 +483,20 @@ function Dispatcher:execute(settings, gesture) if settingsList[k].category == "none" then self.ui:handleEvent(Event:new(settingsList[k].event)) end - if settingsList[k].category == "toggle" - or settingsList[k].category == "absolutenumber" - or settingsList[k].category == "string" then + if settingsList[k].category == "absolutenumber" + or settingsList[k].category == "string" + then self.ui:handleEvent(Event:new(settingsList[k].event, v)) end + -- the event can accept a gesture object or an argument + if settingsList[k].category == "arg" then + local arg = gesture or settingsList[k].arg + self.ui:handleEvent(Event:new(settingsList[k].event, arg)) + end + -- the event can accept a gesture object or a number if settingsList[k].category == "incrementalnumber" then - if v then - self.ui:handleEvent(Event:new(settingsList[k].event, v)) - else - self.ui:handleEvent(Event:new(settingsList[k].event, gesture)) - end + local arg = gesture or v + self.ui:handleEvent(Event:new(settingsList[k].event, arg)) end end end diff --git a/frontend/ui/elements/filemanager_menu_order.lua b/frontend/ui/elements/filemanager_menu_order.lua index f7f9d76c8..2eae2d4e9 100644 --- a/frontend/ui/elements/filemanager_menu_order.lua +++ b/frontend/ui/elements/filemanager_menu_order.lua @@ -100,6 +100,7 @@ local order = { "news_downloader", "send2ebook", "text_editor", + "profiles", "----------------------------", "more_tools", }, diff --git a/plugins/profiles.koplugin/main.lua b/plugins/profiles.koplugin/main.lua index 11ffcd11a..00ec00a79 100644 --- a/plugins/profiles.koplugin/main.lua +++ b/plugins/profiles.koplugin/main.lua @@ -6,12 +6,12 @@ local InputDialog = require("ui/widget/inputdialog") local LuaSettings = require("luasettings") local UIManager = require("ui/uimanager") local WidgetContainer = require("ui/widget/container/widgetcontainer") +local orderedPairs = require("ffi/util").orderedPairs local _ = require("gettext") local T = require("ffi/util").template local Profiles = WidgetContainer:new{ name = "profiles", - is_doc_only = true, profiles_file = DataStorage:getSettingsDir() .. "/profiles.lua", profiles = nil, data = nil, @@ -86,7 +86,7 @@ function Profiles:getSubMenuItems() separator = true, } } - for k,v in pairs(self.data) do + for k,v in orderedPairs(self.data) do local sub_items = { { text = _("Delete profile"), @@ -110,7 +110,7 @@ function Profiles:getSubMenuItems() hold_keep_menu_open = false, sub_item_table = sub_items, hold_callback = function() - Dispatcher.execute(self, v) + Dispatcher.execute(self, self.data[k]) end, }) end