local Device = require("device") local Event = require("ui/event") local InputContainer = require("ui/widget/container/inputcontainer") local Screen = require("device").screen local UIManager = require("ui/uimanager") local T = require("ffi/util").template local _ = require("gettext") local default_gesture = { tap_right_bottom_corner = "nothing", tap_left_bottom_corner = Device.hasFrontlight() and "toggle_frontlight" or "nothing", short_diagonal_swipe = "full_refresh", } local ReaderGesture = InputContainer:new{ } function ReaderGesture:init() if not Device:isTouchDevice() then return end self.is_docless = self.ui == nil or self.ui.document == nil self.ges_mode = self.is_docless and "gesture_fm" or "gesture_reader" local gm = G_reader_settings:readSetting(self.ges_mode) if gm == nil then G_reader_settings:saveSetting(self.ges_mode, {}) end self.ui.menu:registerToMainMenu(self) self:initGesture() end function ReaderGesture:initGesture() local gesture_manager = G_reader_settings:readSetting(self.ges_mode) for gesture, action in pairs(default_gesture) do if not gesture_manager[gesture] then gesture_manager[gesture] = action end end for gesture, action in pairs(gesture_manager) do self:setupGesture(gesture, action) end G_reader_settings:saveSetting(self.ges_mode, gesture_manager) end function ReaderGesture:addToMainMenu(menu_items) menu_items.gesture = { text = _("Gesture manager"), sub_item_table = { { text = _("Tap right bottom corner"), sub_item_table = self:buildMenu("tap_right_bottom_corner", default_gesture["tap_right_bottom_corner"]) }, { text = _("Tap left bottom corner"), sub_item_table = self:buildMenu("tap_left_bottom_corner", default_gesture["tap_left_bottom_corner"]) }, { text = _("Short diagonal swipe"), sub_item_table = self:buildMenu("short_diagonal_swipe", default_gesture["short_diagonal_swipe"]) }, }, } end function ReaderGesture:buildMenu(ges, default) local gesture_manager = G_reader_settings:readSetting(self.ges_mode) local menu = { --{_("Menu element), "action", enable_element}, {_("Nothing"), "nothing", true }, {_("Back 10 pages"), "page_update_down10", not self.is_docless}, {_("Forward 10 pages"), "page_update_up10", not self.is_docless}, {_("Folder up"), "folder_up", self.is_docless}, {_("Bookmarks"), "bookmarks", not self.is_docless}, {_("Table of content"), "toc", not self.is_docless}, {_("Reading progress"), "reading_progress", ReaderGesture.getReaderProgress ~= nil}, {_("Full screen refresh"), "full_refresh", true}, {_("Night mode"), "night_mode", true}, {_("Toggle frontlight"), "toggle_frontlight", Device.hasFrontlight()}, } local return_menu = {} -- add default action to the top of the submenu for __, entry in pairs(menu) do if entry[2] == default then local menu_entry_default = T(_("%1 (default)"), entry[1]) table.insert(return_menu, self:createSubMenu(menu_entry_default, entry[2], ges, true)) break end end -- another elements for _, entry in pairs(menu) do if not entry[3] and gesture_manager[ges] == entry[2] then gesture_manager[ges] = "nothing" G_reader_settings:saveSetting(self.ges_mode, gesture_manager) end if entry[2] ~= default and entry[3] then table.insert(return_menu, self:createSubMenu(entry[1], entry[2], ges, entry[2] == "nothing")) end end return return_menu end function ReaderGesture:createSubMenu(text, action, ges, separator) local gesture_manager = G_reader_settings:readSetting(self.ges_mode) return { text = text, checked_func = function() return gesture_manager[ges] == action end, callback = function() gesture_manager[ges] = action G_reader_settings:saveSetting(self.ges_mode, gesture_manager) self:setupGesture(ges, action) end, separator = separator or false, } end function ReaderGesture:setupGesture(ges, action) local ges_type local zone local overrides local direction, distance if ges == "tap_right_bottom_corner" then ges_type = "tap" zone = { ratio_x = 0.9, ratio_y = 0.9, ratio_w = 0.1, ratio_h = 0.1, } if self.is_docless then overrides = { 'filemanager_tap' } else overrides = { 'readerfooter_tap', } end elseif ges == "tap_left_bottom_corner" then ges_type = "tap" zone = { ratio_x = 0.0, ratio_y = 0.9, ratio_w = 0.1, ratio_h = 0.1, } if self.is_docless then overrides = { 'filemanager_tap' } else overrides = { 'readerfooter_tap', 'filemanager_tap' } end elseif ges == "short_diagonal_swipe" then ges_type = "swipe" zone = { ratio_x = 0.0, ratio_y = 0, ratio_w = 1, ratio_h = 1, } direction = {northeast = true, northwest = true, southeast = true, southwest = true} distance = "short" if self.is_docless then overrides = { 'filemanager_tap' } else overrides = { 'rolling_swipe', 'paging_swipe' } end else return end self:registerGesture(ges, action, ges_type, zone, overrides, direction, distance) end function ReaderGesture:registerGesture(ges, action, ges_type, zone, overrides, direction, distance) self.ui:registerTouchZones({ { id = ges, ges = ges_type, screen_zone = zone, handler = function(gest) if distance == "short" and gest.distance > Screen:scaleBySize(300) then return end if direction and not direction[gest.direction] then return end return self:gestureAction(action) end, overrides = overrides, }, }) end function ReaderGesture:gestureAction(action) if action == "reading_progress" and ReaderGesture.getReaderProgress then UIManager:show(ReaderGesture.getReaderProgress()) elseif action == "toc" then self.ui:handleEvent(Event:new("ShowToc")) elseif action == "night_mode" then local night_mode = G_reader_settings:readSetting("night_mode") or false Screen:toggleNightMode() UIManager:setDirty(nil, "full") G_reader_settings:saveSetting("night_mode", not night_mode) elseif action == "full_refresh" then UIManager:setDirty(nil, "full") elseif action == "bookmarks" then self.ui:handleEvent(Event:new("ShowBookmark")) elseif action =="page_update_up10" then self:pageUpdate(10) elseif action =="page_update_down10" then self:pageUpdate(-10) elseif action =="folder_up" then self.ui.file_chooser:changeToPath(string.format("%s/..", self.ui.file_chooser.path)) elseif action =="toggle_frontlight" then Device:getPowerDevice():toggleFrontlight() self:onShowFLOnOff() end return true end function ReaderGesture:pageUpdate(page) local curr_page if self.document.info.has_pages then curr_page = self.ui.paging.current_page else curr_page = self.document:getCurrentPage() end if curr_page and page then curr_page = curr_page + page self.ui:handleEvent(Event:new("GotoPage", curr_page)) end end function ReaderGesture:onShowFLOnOff() local Notification = require("ui/widget/notification") local powerd = Device:getPowerDevice() local new_text if powerd.is_fl_on then new_text = _("Frontlight is on.") else new_text = _("Frontlight is off.") end UIManager:show(Notification:new{ text = new_text, timeout = 1.0, }) return true end return ReaderGesture