2019-12-06 22:55:39 +01:00
local BD = require ( " ui/bidi " )
2013-10-18 22:38:07 +02:00
local CenterContainer = require ( " ui/widget/container/centercontainer " )
2018-07-07 13:03:33 +02:00
local ConfirmBox = require ( " ui/widget/confirmbox " )
2014-10-30 19:42:18 +01:00
local Device = require ( " device " )
2013-10-18 22:38:07 +02:00
local Event = require ( " ui/event " )
2017-03-28 15:10:36 -07:00
local InputContainer = require ( " ui/widget/container/inputcontainer " )
local Screensaver = require ( " ui/screensaver " )
local UIManager = require ( " ui/uimanager " )
2017-04-21 02:19:14 -07:00
local logger = require ( " logger " )
local dbg = require ( " dbg " )
2018-07-07 13:03:33 +02:00
local util = require ( " util " )
2017-04-21 02:19:14 -07:00
local Screen = Device.screen
2017-04-23 23:27:29 -07:00
local _ = require ( " gettext " )
2018-07-07 13:03:33 +02:00
local T = require ( " ffi/util " ) . template
2013-10-18 22:38:07 +02:00
Clarify our OOP semantics across the codebase (#9586)
Basically:
* Use `extend` for class definitions
* Use `new` for object instantiations
That includes some minor code cleanups along the way:
* Updated `Widget`'s docs to make the semantics clearer.
* Removed `should_restrict_JIT` (it's been dead code since https://github.com/koreader/android-luajit-launcher/pull/283)
* Minor refactoring of LuaSettings/LuaData/LuaDefaults/DocSettings to behave (mostly, they are instantiated via `open` instead of `new`) like everything else and handle inheritance properly (i.e., DocSettings is now a proper LuaSettings subclass).
* Default to `WidgetContainer` instead of `InputContainer` for stuff that doesn't actually setup key/gesture events.
* Ditto for explicit `*Listener` only classes, make sure they're based on `EventListener` instead of something uselessly fancier.
* Unless absolutely necessary, do not store references in class objects, ever; only values. Instead, always store references in instances, to avoid both sneaky inheritance issues, and sneaky GC pinning of stale references.
* ReaderUI: Fix one such issue with its `active_widgets` array, with critical implications, as it essentially pinned *all* of ReaderUI's modules, including their reference to the `Document` instance (i.e., that was a big-ass leak).
* Terminal: Make sure the shell is killed on plugin teardown.
* InputText: Fix Home/End/Del physical keys to behave sensibly.
* InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time (previously, only InputContainers did, which might have had something to do with random widgets unconcerned about input using it as a baseclass instead of WidgetContainer...).
* OverlapGroup: Compute self.dimen at *init* time, because for some reason it needs to do that, but do it directly in OverlapGroup instead of going through a weird WidgetContainer method that it was the sole user of.
* ReaderCropping: Under no circumstances should a Document instance member (here, self.bbox) risk being `nil`ed!
* Kobo: Minor code cleanups.
2022-10-06 02:14:48 +02:00
local ReaderMenu = InputContainer : extend {
2014-03-13 21:52:43 +08:00
tab_item_table = nil ,
Clarify our OOP semantics across the codebase (#9586)
Basically:
* Use `extend` for class definitions
* Use `new` for object instantiations
That includes some minor code cleanups along the way:
* Updated `Widget`'s docs to make the semantics clearer.
* Removed `should_restrict_JIT` (it's been dead code since https://github.com/koreader/android-luajit-launcher/pull/283)
* Minor refactoring of LuaSettings/LuaData/LuaDefaults/DocSettings to behave (mostly, they are instantiated via `open` instead of `new`) like everything else and handle inheritance properly (i.e., DocSettings is now a proper LuaSettings subclass).
* Default to `WidgetContainer` instead of `InputContainer` for stuff that doesn't actually setup key/gesture events.
* Ditto for explicit `*Listener` only classes, make sure they're based on `EventListener` instead of something uselessly fancier.
* Unless absolutely necessary, do not store references in class objects, ever; only values. Instead, always store references in instances, to avoid both sneaky inheritance issues, and sneaky GC pinning of stale references.
* ReaderUI: Fix one such issue with its `active_widgets` array, with critical implications, as it essentially pinned *all* of ReaderUI's modules, including their reference to the `Document` instance (i.e., that was a big-ass leak).
* Terminal: Make sure the shell is killed on plugin teardown.
* InputText: Fix Home/End/Del physical keys to behave sensibly.
* InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time (previously, only InputContainers did, which might have had something to do with random widgets unconcerned about input using it as a baseclass instead of WidgetContainer...).
* OverlapGroup: Compute self.dimen at *init* time, because for some reason it needs to do that, but do it directly in OverlapGroup instead of going through a weird WidgetContainer method that it was the sole user of.
* ReaderCropping: Under no circumstances should a Document instance member (here, self.bbox) risk being `nil`ed!
* Kobo: Minor code cleanups.
2022-10-06 02:14:48 +02:00
menu_items = nil , -- table, mandatory
registered_widgets = nil , -- array
2012-12-15 09:20:12 +08:00
}
2012-11-11 15:24:11 +08:00
function ReaderMenu : init ( )
2017-03-03 07:41:10 +01:00
self.menu_items = {
[ " KOMenu:menu_buttons " ] = {
-- top menu
} ,
-- items in top menu
navi = {
2020-12-19 12:18:30 +01:00
icon = " appbar.navigation " ,
2017-03-03 07:41:10 +01:00
} ,
typeset = {
2020-12-19 12:18:30 +01:00
icon = " appbar.typeset " ,
2017-03-03 07:41:10 +01:00
} ,
setting = {
2020-12-19 12:18:30 +01:00
icon = " appbar.settings " ,
2017-03-03 07:41:10 +01:00
} ,
tools = {
2020-12-19 12:18:30 +01:00
icon = " appbar.tools " ,
2017-03-03 07:41:10 +01:00
} ,
search = {
2020-12-19 12:18:30 +01:00
icon = " appbar.search " ,
2017-03-03 07:41:10 +01:00
} ,
filemanager = {
2020-12-19 12:18:30 +01:00
icon = " appbar.filebrowser " ,
2017-03-03 07:41:10 +01:00
remember = false ,
callback = function ( )
self : onTapCloseMenu ( )
2024-06-30 14:29:22 +03:00
local file = self.ui . document.file
2017-03-03 07:41:10 +01:00
self.ui : onClose ( )
2024-06-30 14:29:22 +03:00
self.ui : showFileManager ( file )
2017-03-03 07:41:10 +01:00
end ,
} ,
main = {
2020-12-19 12:18:30 +01:00
icon = " appbar.menu " ,
2017-03-03 07:41:10 +01:00
}
2017-02-28 22:46:32 +01:00
}
2014-03-13 21:52:43 +08:00
self.registered_widgets = { }
2022-11-01 23:22:07 +01:00
self : registerKeyEvents ( )
2022-11-01 00:17:25 +01:00
if G_reader_settings : has ( " activate_menu " ) then
self.activation_menu = G_reader_settings : readSetting ( " activate_menu " )
else
self.activation_menu = " swipe_tap "
end
-- delegate gesture listener to readerui, NOP our own
self.ges_events = nil
end
function ReaderMenu : onGesture ( ) end
2022-11-01 23:22:07 +01:00
function ReaderMenu : registerKeyEvents ( )
2014-06-10 15:57:10 +08:00
if Device : hasKeys ( ) then
2016-12-26 23:06:47 -08:00
if Device : isTouchDevice ( ) then
2022-11-15 18:35:14 +01:00
self.key_events . PressMenu = { { " Menu " } }
2020-06-04 13:26:18 +02:00
if Device : hasFewKeys ( ) then
2022-11-15 18:35:14 +01:00
self.key_events . PressMenu = { { { " Menu " , " Right " } } }
2020-06-04 13:26:18 +02:00
end
2016-12-26 23:06:47 -08:00
else
2022-11-15 18:35:14 +01:00
-- Map Menu key to top menu only, because the bottom menu is only designed for touch devices.
--- @fixme: Is this still the case?
--- (Swapping between top and bottom might not be implemented, though, so it might still be a good idea).
2022-10-27 02:01:51 +02:00
self.key_events . ShowMenu = { { " Menu " } }
2020-06-04 13:26:18 +02:00
if Device : hasFewKeys ( ) then
2022-10-27 02:01:51 +02:00
self.key_events . ShowMenu = { { { " Menu " , " Right " } } }
2020-06-04 13:26:18 +02:00
end
2016-12-26 23:06:47 -08:00
end
2014-03-13 21:52:43 +08:00
end
2012-11-11 15:24:11 +08:00
end
2012-06-10 20:14:29 +02:00
2022-11-01 00:17:25 +01:00
ReaderMenu.onPhysicalKeyboardConnected = ReaderMenu.registerKeyEvents
2022-10-30 23:05:04 +01:00
2019-02-22 16:29:19 +01:00
function ReaderMenu : getPreviousFile ( )
2020-05-06 21:11:34 +02:00
return require ( " readhistory " ) : getPreviousFile ( self.ui . document.file )
2019-02-22 16:29:19 +01:00
end
2024-01-12 19:13:44 +01:00
function ReaderMenu : initGesListener ( )
2016-12-18 20:27:56 -08:00
if not Device : isTouchDevice ( ) then return end
2022-09-28 01:10:50 +02:00
local DTAP_ZONE_MENU = G_defaults : readSetting ( " DTAP_ZONE_MENU " )
local DTAP_ZONE_MENU_EXT = G_defaults : readSetting ( " DTAP_ZONE_MENU_EXT " )
2016-12-18 20:27:56 -08:00
self.ui : registerTouchZones ( {
2017-06-02 00:32:06 +08:00
{
id = " readermenu_tap " ,
ges = " tap " ,
screen_zone = {
ratio_x = DTAP_ZONE_MENU.x , ratio_y = DTAP_ZONE_MENU.y ,
ratio_w = DTAP_ZONE_MENU.w , ratio_h = DTAP_ZONE_MENU.h ,
} ,
2019-03-30 21:05:44 +01:00
overrides = {
" tap_forward " ,
" tap_backward " ,
} ,
2017-06-02 00:32:06 +08:00
handler = function ( ges ) return self : onTapShowMenu ( ges ) end ,
} ,
2020-12-03 17:33:54 +01:00
{
id = " readermenu_ext_tap " ,
ges = " tap " ,
screen_zone = {
ratio_x = DTAP_ZONE_MENU_EXT.x , ratio_y = DTAP_ZONE_MENU_EXT.y ,
ratio_w = DTAP_ZONE_MENU_EXT.w , ratio_h = DTAP_ZONE_MENU_EXT.h ,
} ,
overrides = {
" readermenu_tap " ,
} ,
handler = function ( ges ) return self : onTapShowMenu ( ges ) end ,
} ,
2016-12-18 20:27:56 -08:00
{
2017-04-15 14:45:56 +02:00
id = " readermenu_swipe " ,
ges = " swipe " ,
2016-12-18 20:27:56 -08:00
screen_zone = {
ratio_x = DTAP_ZONE_MENU.x , ratio_y = DTAP_ZONE_MENU.y ,
ratio_w = DTAP_ZONE_MENU.w , ratio_h = DTAP_ZONE_MENU.h ,
} ,
2019-03-30 21:05:44 +01:00
overrides = {
" rolling_swipe " ,
" paging_swipe " ,
} ,
2017-04-15 14:45:56 +02:00
handler = function ( ges ) return self : onSwipeShowMenu ( ges ) end ,
2014-03-13 21:52:43 +08:00
} ,
2020-12-03 17:33:54 +01:00
{
id = " readermenu_ext_swipe " ,
ges = " swipe " ,
screen_zone = {
ratio_x = DTAP_ZONE_MENU_EXT.x , ratio_y = DTAP_ZONE_MENU_EXT.y ,
ratio_w = DTAP_ZONE_MENU_EXT.w , ratio_h = DTAP_ZONE_MENU_EXT.h ,
} ,
overrides = {
" readermenu_swipe " ,
} ,
handler = function ( ges ) return self : onSwipeShowMenu ( ges ) end ,
} ,
2017-04-23 23:33:12 -07:00
{
id = " readermenu_pan " ,
ges = " pan " ,
screen_zone = {
ratio_x = DTAP_ZONE_MENU.x , ratio_y = DTAP_ZONE_MENU.y ,
ratio_w = DTAP_ZONE_MENU.w , ratio_h = DTAP_ZONE_MENU.h ,
} ,
2019-03-30 21:05:44 +01:00
overrides = {
" rolling_pan " ,
" paging_pan " ,
} ,
2017-04-23 23:33:12 -07:00
handler = function ( ges ) return self : onSwipeShowMenu ( ges ) end ,
} ,
2020-12-03 17:33:54 +01:00
{
id = " readermenu_ext_pan " ,
ges = " pan " ,
screen_zone = {
ratio_x = DTAP_ZONE_MENU_EXT.x , ratio_y = DTAP_ZONE_MENU_EXT.y ,
ratio_w = DTAP_ZONE_MENU_EXT.w , ratio_h = DTAP_ZONE_MENU_EXT.h ,
} ,
overrides = {
" readermenu_pan " ,
} ,
handler = function ( ges ) return self : onSwipeShowMenu ( ges ) end ,
} ,
2016-12-18 20:27:56 -08:00
} )
2013-02-02 14:36:29 +08:00
end
2024-01-12 19:13:44 +01:00
ReaderMenu.onReaderReady = ReaderMenu.initGesListener
2012-12-15 09:20:12 +08:00
function ReaderMenu : setUpdateItemTable ( )
2014-03-13 21:52:43 +08:00
for _ , widget in pairs ( self.registered_widgets ) do
2017-04-21 02:19:14 -07:00
local ok , err = pcall ( widget.addToMainMenu , widget , self.menu_items )
if not ok then
logger.err ( " failed to register widget " , widget.name , err )
end
2014-03-13 21:52:43 +08:00
end
2021-09-06 22:30:35 +03:00
-- typeset tab
2022-10-25 06:34:23 -04:00
self.menu_items . document_settings = {
text = _ ( " Document settings " ) ,
sub_item_table = {
{
text = _ ( " Reset document settings to default " ) ,
keep_menu_open = true ,
callback = function ( )
UIManager : show ( ConfirmBox : new {
text = _ ( " Reset current document settings to their default values? \n \n Reading position, highlights and bookmarks will be kept. \n The document will be reloaded. " ) ,
ok_text = _ ( " Reset " ) ,
ok_callback = function ( )
local current_file = self.ui . document.file
self : onTapCloseMenu ( )
self.ui : onClose ( )
require ( " apps/filemanager/filemanagerutil " ) . resetDocumentSettings ( current_file )
require ( " apps/reader/readerui " ) : showReader ( current_file )
end ,
} )
2021-11-07 20:29:53 +02:00
end ,
2022-10-25 06:34:23 -04:00
} ,
{
text = _ ( " Save document settings as default " ) ,
keep_menu_open = true ,
callback = function ( )
UIManager : show ( ConfirmBox : new {
text = _ ( " Save current document settings as default values? " ) ,
ok_text = _ ( " Save " ) ,
ok_callback = function ( )
self : onTapCloseMenu ( )
self : saveDocumentSettingsAsDefault ( )
UIManager : show ( require ( " ui/widget/notification " ) : new {
text = _ ( " Default settings updated " ) ,
} )
end ,
} )
end ,
} ,
} ,
2021-11-07 20:29:53 +02:00
}
2022-10-25 06:34:23 -04:00
2024-09-16 17:11:42 +02:00
self.menu_items . page_overlap = dofile ( " frontend/ui/elements/page_overlap.lua " )
2021-09-06 22:30:35 +03:00
2014-11-21 15:41:14 +01:00
-- settings tab
-- insert common settings
2019-03-02 21:45:12 +01:00
for id , common_setting in pairs ( dofile ( " frontend/ui/elements/common_settings_menu_table.lua " ) ) do
2017-02-28 22:46:32 +01:00
self.menu_items [ id ] = common_setting
2014-11-21 15:41:14 +01:00
end
2022-01-02 15:01:08 +01:00
if Device : isTouchDevice ( ) then
2023-08-15 11:30:39 +02:00
-- Settings > Taps & Gestures; mostly concerns touch related page turn stuff, and only applies to Reader
2024-09-16 17:11:42 +02:00
self.menu_items . page_turns = dofile ( " frontend/ui/elements/page_turns.lua " )
2022-01-02 15:01:08 +01:00
end
2023-08-12 03:15:11 +02:00
-- Settings > Navigation; while also related to page turns, this mostly concerns physical keys, and applies *everywhere*
2023-08-12 00:53:11 +02:00
if Device : hasKeys ( ) then
2024-09-16 17:11:42 +02:00
self.menu_items . physical_buttons_setup = dofile ( " frontend/ui/elements/physical_buttons.lua " )
2023-08-12 00:53:11 +02:00
end
2014-11-21 15:41:14 +01:00
-- insert DjVu render mode submenu just before the last entry (show advanced)
-- this is a bit of a hack
2014-10-15 20:31:24 +08:00
if self.ui . document.is_djvu then
2017-03-03 07:41:10 +01:00
self.menu_items . djvu_render_mode = self.view : getRenderModeMenuTable ( )
2014-10-15 20:31:24 +08:00
end
2014-07-27 21:41:38 +08:00
2017-11-10 11:31:00 +01:00
if Device : supportsScreensaver ( ) then
2017-12-17 18:27:24 +01:00
local ss_book_settings = {
2024-04-08 21:47:17 +01:00
text = _ ( " Do not show this book cover on sleep screen " ) ,
2017-12-17 18:27:24 +01:00
enabled_func = function ( )
2022-12-14 15:30:38 -08:00
if self.ui and self.ui . document then
local screensaverType = G_reader_settings : readSetting ( " screensaver_type " )
return screensaverType == " cover " or screensaverType == " disable "
else
return false
end
2017-12-17 18:27:24 +01:00
end ,
2018-01-21 19:44:12 +01:00
checked_func = function ( )
2021-03-06 22:44:18 +01:00
return self.ui and self.ui . doc_settings and self.ui . doc_settings : isTrue ( " exclude_screensaver " )
2018-01-21 19:44:12 +01:00
end ,
callback = function ( )
2021-03-06 22:44:18 +01:00
if Screensaver : isExcluded ( ) then
self.ui . doc_settings : makeFalse ( " exclude_screensaver " )
2018-01-21 19:44:12 +01:00
else
2021-03-06 22:44:18 +01:00
self.ui . doc_settings : makeTrue ( " exclude_screensaver " )
2018-01-21 19:44:12 +01:00
end
self.ui : saveSettings ( )
2019-10-17 15:03:40 +02:00
end ,
2017-02-28 22:46:32 +01:00
}
2024-09-16 17:11:42 +02:00
local screensaver_sub_item_table = dofile ( " frontend/ui/elements/screensaver_menu.lua " )
2019-10-17 15:03:40 +02:00
table.insert ( screensaver_sub_item_table , ss_book_settings )
2017-12-17 18:27:24 +01:00
self.menu_items . screensaver = {
2024-04-08 21:47:17 +01:00
text = _ ( " Sleep screen " ) ,
2019-10-17 15:03:40 +02:00
sub_item_table = screensaver_sub_item_table ,
2017-12-17 18:27:24 +01:00
}
2014-09-17 12:25:13 +02:00
end
2018-08-17 20:54:11 +02:00
local PluginLoader = require ( " pluginloader " )
self.menu_items . plugin_management = {
text = _ ( " Plugin management " ) ,
sub_item_table = PluginLoader : genPluginManagerSubItem ( )
}
2024-02-28 07:29:33 +02:00
-- main menu tab
2024-03-05 07:38:06 +02:00
-- insert common info
for id , common_setting in pairs ( dofile ( " frontend/ui/elements/common_info_menu_table.lua " ) ) do
self.menu_items [ id ] = common_setting
end
-- insert common exit for reader
for id , common_setting in pairs ( dofile ( " frontend/ui/elements/common_exit_menu_table.lua " ) ) do
self.menu_items [ id ] = common_setting
end
2018-07-07 13:03:33 +02:00
self.menu_items . open_previous_document = {
text_func = function ( )
2019-02-22 16:29:19 +01:00
local previous_file = self : getPreviousFile ( )
2018-07-07 13:03:33 +02:00
if not G_reader_settings : isTrue ( " open_last_menu_show_filename " ) or not previous_file then
return _ ( " Open previous document " )
end
2018-11-28 21:14:07 +01:00
local path , file_name = util.splitFilePathName ( previous_file ) -- luacheck: no unused
2020-01-04 01:18:51 +01:00
return T ( _ ( " Previous: %1 " ) , BD.filename ( file_name ) )
2018-07-07 13:03:33 +02:00
end ,
enabled_func = function ( )
2019-02-22 16:29:19 +01:00
return self : getPreviousFile ( ) ~= nil
2018-07-07 13:03:33 +02:00
end ,
callback = function ( )
2020-07-12 14:47:49 -04:00
self.ui : onOpenLastDoc ( )
2018-07-07 13:03:33 +02:00
end ,
hold_callback = function ( )
2019-02-22 16:29:19 +01:00
local previous_file = self : getPreviousFile ( )
2018-07-07 13:03:33 +02:00
UIManager : show ( ConfirmBox : new {
2020-01-04 01:18:51 +01:00
text = T ( _ ( " Would you like to open the previous document: %1? " ) , BD.filepath ( previous_file ) ) ,
2018-07-07 13:03:33 +02:00
ok_text = _ ( " OK " ) ,
ok_callback = function ( )
self.ui : switchDocument ( previous_file )
end ,
} )
end
}
2024-09-16 17:11:42 +02:00
-- NOTE: This is cached via require for ui/plugin/insert_menu's sake...
2017-04-14 11:12:21 -07:00
local order = require ( " ui/elements/reader_menu_order " )
2017-02-28 22:46:32 +01:00
2017-04-14 11:12:21 -07:00
local MenuSorter = require ( " ui/menusorter " )
2017-03-24 21:15:35 +01:00
self.tab_item_table = MenuSorter : mergeAndSort ( " reader " , self.menu_items , order )
2012-12-15 09:20:12 +08:00
end
2017-04-21 02:19:14 -07:00
dbg : guard ( ReaderMenu , ' setUpdateItemTable ' ,
function ( self )
local mock_menu_items = { }
for _ , widget in pairs ( self.registered_widgets ) do
-- make sure addToMainMenu works in debug mode
widget : addToMainMenu ( mock_menu_items )
end
end )
2012-12-15 09:20:12 +08:00
2022-10-25 06:34:23 -04:00
function ReaderMenu : saveDocumentSettingsAsDefault ( )
local prefix
if self.ui . rolling then
G_reader_settings : saveSetting ( " cre_font " , self.ui . font.font_face )
G_reader_settings : saveSetting ( " copt_css " , self.ui . document.default_css )
G_reader_settings : saveSetting ( " style_tweaks " , self.ui . styletweak.global_tweaks )
prefix = " copt_ "
else
prefix = " kopt_ "
end
for k , v in pairs ( self.ui . document.configurable ) do
G_reader_settings : saveSetting ( prefix .. k , v )
end
end
2020-11-28 22:48:09 +01:00
function ReaderMenu : exitOrRestart ( callback , force )
-- Only restart sets a callback, which suits us just fine for this check ;)
if callback and not force and not Device : isStartupScriptUpToDate ( ) then
UIManager : show ( ConfirmBox : new {
text = _ ( " KOReader's startup script has been updated. You'll need to completely exit KOReader to finalize the update. " ) ,
ok_text = _ ( " Restart anyway " ) ,
ok_callback = function ( )
self : exitOrRestart ( callback , true )
end ,
} )
return
end
2024-09-14 15:21:26 +03:00
self : onTapCloseMenu ( )
2017-05-16 02:11:11 -07:00
UIManager : nextTick ( function ( )
self.ui : onClose ( )
2024-09-14 15:21:26 +03:00
if callback then
callback ( )
2017-05-16 02:11:11 -07:00
end
end )
end
2024-03-05 07:38:06 +02:00
function ReaderMenu : onShowMenu ( tab_index )
2017-03-05 12:46:27 +01:00
if self.tab_item_table == nil then
2014-03-13 21:52:43 +08:00
self : setUpdateItemTable ( )
end
2024-03-05 07:38:06 +02:00
if not tab_index then
2018-01-14 00:11:09 +02:00
tab_index = self.last_tab_index
end
2024-03-05 07:38:06 +02:00
local menu_container = CenterContainer : new {
covers_header = true ,
ignore = " height " ,
dimen = Screen : getSize ( ) ,
}
2015-04-26 20:49:27 -04:00
local main_menu
2018-03-14 22:16:38 +01:00
if Device : isTouchDevice ( ) or Device : hasDPad ( ) then
2014-10-25 04:02:42 -04:00
local TouchMenu = require ( " ui/widget/touchmenu " )
2014-03-13 21:52:43 +08:00
main_menu = TouchMenu : new {
width = Screen : getWidth ( ) ,
2018-01-14 00:11:09 +02:00
last_index = tab_index ,
2017-02-28 22:46:32 +01:00
tab_item_table = self.tab_item_table ,
2024-03-05 07:38:06 +02:00
show_parent = menu_container ,
2014-03-13 21:52:43 +08:00
}
else
2014-10-25 04:02:42 -04:00
local Menu = require ( " ui/widget/menu " )
2014-03-13 21:52:43 +08:00
main_menu = Menu : new {
title = _ ( " Document menu " ) ,
2014-10-25 04:02:42 -04:00
item_table = Menu.itemTableFromTouchMenu ( self.tab_item_table ) ,
2024-03-05 07:38:06 +02:00
width = Screen : getWidth ( ) - 100 ,
show_parent = menu_container ,
2014-03-13 21:52:43 +08:00
}
end
2024-03-05 07:38:06 +02:00
ReaderUI: Saner FM/RD lifecycle
* Ensure that going from one to the other tears down the former and
its plugins before instantiating the latter and its plugins.
UIManager: Unify Event sending & broadcasting
* Make the two behave the same way (walk the widget stack from top to
bottom), and properly handle the window stack shrinking shrinking
*and* growing.
Previously, broadcasting happened bottom-to-top and didn't really
handle the list shrinking/growing, while sending only handled the list
shrinking by a single element, and hopefully that element being the one
the event was just sent to.
These two items combined allowed us to optimize suboptimal
refresh behavior with Menu and other Menu classes when
opening/closing a document.
e.g., the "opening document" Notification is now properly regional,
and the "open last doc" option no longer flashes like a crazy person
anymore.
Plugins: Allow optimizing Menu refresh with custom menus, too.
Requires moving Menu's close_callback *after* onMenuSelect, which, eh,
probably makes sense, and is probably harmless in the grand scheme of
things.
2021-05-01 18:53:04 +02:00
main_menu.close_callback = function ( )
2022-11-15 18:35:14 +01:00
self : onCloseReaderMenu ( )
2014-11-05 12:15:07 +08:00
end
2024-03-05 07:38:06 +02:00
main_menu.touch_menu_callback = function ( )
self.ui : handleEvent ( Event : new ( " CloseConfigMenu " ) )
2014-03-13 21:52:43 +08:00
end
2024-03-05 07:38:06 +02:00
2014-03-13 21:52:43 +08:00
menu_container [ 1 ] = main_menu
-- maintain a reference to menu_container
self.menu_container = menu_container
UIManager : show ( menu_container )
return true
2012-06-10 20:14:29 +02:00
end
2012-11-11 15:24:11 +08:00
2014-09-05 21:02:13 +08:00
function ReaderMenu : onCloseReaderMenu ( )
2024-01-12 19:13:44 +01:00
if not self.menu_container then return true end
self.last_tab_index = self.menu_container [ 1 ] . last_index
self : onSaveSettings ( )
UIManager : close ( self.menu_container )
self.menu_container = nil
2014-09-05 21:02:13 +08:00
return true
end
2022-06-24 23:19:38 +02:00
function ReaderMenu : onSetDimensions ( dimen )
2024-01-12 19:13:44 +01:00
-- This widget doesn't support in-place layout updates, so, close & reopen
if self.menu_container then
self : onCloseReaderMenu ( )
self : onShowMenu ( )
end
-- update gesture zones according to new screen dimen
-- (On CRe, this will get called a second time by ReaderReady once the document is reloaded).
self : initGesListener ( )
2022-06-24 23:19:38 +02:00
end
2018-01-14 00:11:09 +02:00
function ReaderMenu : _getTabIndexFromLocation ( ges )
if self.tab_item_table == nil then
self : setUpdateItemTable ( )
end
2018-03-14 22:16:38 +01:00
if not ges then
return self.last_tab_index
2018-01-14 00:11:09 +02:00
-- if the start position is far right
2022-10-10 22:21:27 +02:00
elseif ges.pos . x > Screen : getWidth ( ) * ( 2 / 3 ) then
2019-12-06 22:55:39 +01:00
return BD.mirroredUILayout ( ) and 1 or # self.tab_item_table
2018-01-14 00:11:09 +02:00
-- if the start position is far left
2022-10-10 22:21:27 +02:00
elseif ges.pos . x < Screen : getWidth ( ) * ( 1 / 3 ) then
2019-12-06 22:55:39 +01:00
return BD.mirroredUILayout ( ) and # self.tab_item_table or 1
2018-01-14 00:11:09 +02:00
-- if center return the last index
else
return self.last_tab_index
end
end
2017-04-15 14:45:56 +02:00
function ReaderMenu : onSwipeShowMenu ( ges )
2017-08-08 18:20:46 +02:00
if self.activation_menu ~= " tap " and ges.direction == " south " then
2017-10-08 12:27:53 +02:00
if G_reader_settings : nilOrTrue ( " show_bottom_menu " ) then
self.ui : handleEvent ( Event : new ( " ShowConfigMenu " ) )
end
2022-11-15 18:35:14 +01:00
self : onShowMenu ( self : _getTabIndexFromLocation ( ges ) )
2021-05-19 22:57:54 +02:00
self.ui : handleEvent ( Event : new ( " HandledAsSwipe " ) ) -- cancel any pan scroll made
2017-04-15 14:45:56 +02:00
return true
end
2012-11-11 15:24:11 +08:00
end
2018-01-14 00:11:09 +02:00
function ReaderMenu : onTapShowMenu ( ges )
2017-08-08 18:20:46 +02:00
if self.activation_menu ~= " swipe " then
2017-10-08 12:27:53 +02:00
if G_reader_settings : nilOrTrue ( " show_bottom_menu " ) then
self.ui : handleEvent ( Event : new ( " ShowConfigMenu " ) )
end
2022-11-15 18:35:14 +01:00
self : onShowMenu ( self : _getTabIndexFromLocation ( ges ) )
2017-08-08 18:20:46 +02:00
return true
end
2017-06-02 00:32:06 +08:00
end
2022-11-15 18:35:14 +01:00
function ReaderMenu : onPressMenu ( )
if G_reader_settings : nilOrTrue ( " show_bottom_menu " ) then
self.ui : handleEvent ( Event : new ( " ShowConfigMenu " ) )
end
self : onShowMenu ( )
return true
end
2014-10-10 18:14:16 +08:00
function ReaderMenu : onTapCloseMenu ( )
2022-11-15 18:35:14 +01:00
self : onCloseReaderMenu ( )
2014-10-10 18:14:16 +08:00
self.ui : handleEvent ( Event : new ( " CloseConfigMenu " ) )
end
2014-11-11 10:06:17 +08:00
function ReaderMenu : onReadSettings ( config )
2014-12-01 15:32:12 +08:00
self.last_tab_index = config : readSetting ( " readermenu_tab_index " ) or 1
2014-11-11 10:06:17 +08:00
end
2013-12-27 23:18:16 +08:00
function ReaderMenu : onSaveSettings ( )
2014-12-03 16:14:30 +00:00
self.ui . doc_settings : saveSetting ( " readermenu_tab_index " , self.last_tab_index )
2012-12-15 09:20:12 +08:00
end
2022-12-18 01:25:41 +01:00
function ReaderMenu : onMenuSearch ( )
2024-03-05 07:38:06 +02:00
self : onShowMenu ( )
self.menu_container [ 1 ] : onShowMenuSearch ( )
2022-12-18 01:25:41 +01:00
end
2012-12-15 09:30:48 +08:00
function ReaderMenu : registerToMainMenu ( widget )
2014-03-13 21:52:43 +08:00
table.insert ( self.registered_widgets , widget )
2012-12-09 01:25:32 +08:00
end
2013-10-18 22:38:07 +02:00
return ReaderMenu