2019-12-06 22:55:39 +01:00
|
|
|
local BD = require("ui/bidi")
|
2017-04-29 10:38:09 +02:00
|
|
|
local Blitbuffer = require("ffi/blitbuffer")
|
2013-10-18 22:38:07 +02:00
|
|
|
local BottomContainer = require("ui/widget/container/bottomcontainer")
|
|
|
|
|
local Button = require("ui/widget/button")
|
2017-04-29 10:38:09 +02:00
|
|
|
local CenterContainer = require("ui/widget/container/centercontainer")
|
|
|
|
|
local Device = require("device")
|
|
|
|
|
local FocusManager = require("ui/widget/focusmanager")
|
2013-10-18 22:38:07 +02:00
|
|
|
local Font = require("ui/font")
|
2017-04-29 10:38:09 +02:00
|
|
|
local FrameContainer = require("ui/widget/container/framecontainer")
|
2013-10-18 22:38:07 +02:00
|
|
|
local Geom = require("ui/geometry")
|
2017-04-29 10:38:09 +02:00
|
|
|
local GestureRange = require("ui/gesturerange")
|
|
|
|
|
local HorizontalGroup = require("ui/widget/horizontalgroup")
|
|
|
|
|
local HorizontalSpan = require("ui/widget/horizontalspan")
|
|
|
|
|
local InputContainer = require("ui/widget/container/inputcontainer")
|
|
|
|
|
local LeftContainer = require("ui/widget/container/leftcontainer")
|
2019-07-19 21:43:05 +02:00
|
|
|
local Math = require("optmath")
|
2017-04-29 10:38:09 +02:00
|
|
|
local OverlapGroup = require("ui/widget/overlapgroup")
|
|
|
|
|
local RightContainer = require("ui/widget/container/rightcontainer")
|
2017-09-13 16:56:20 +02:00
|
|
|
local Size = require("ui/size")
|
2018-01-13 23:38:53 +01:00
|
|
|
local TextBoxWidget = require("ui/widget/textboxwidget")
|
2017-04-29 10:38:09 +02:00
|
|
|
local TextWidget = require("ui/widget/textwidget")
|
2022-01-10 21:21:39 +02:00
|
|
|
local TitleBar = require("ui/widget/titlebar")
|
2017-04-29 10:38:09 +02:00
|
|
|
local UIManager = require("ui/uimanager")
|
|
|
|
|
local UnderlineContainer = require("ui/widget/container/underlinecontainer")
|
2021-08-14 22:29:25 +03:00
|
|
|
local Utf8Proc = require("ffi/utf8proc")
|
2017-04-29 10:38:09 +02:00
|
|
|
local VerticalGroup = require("ui/widget/verticalgroup")
|
|
|
|
|
local VerticalSpan = require("ui/widget/verticalspan")
|
|
|
|
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
2024-10-30 20:09:59 +02:00
|
|
|
local ffiUtil = require("ffi/util")
|
2016-12-29 00:10:38 -08:00
|
|
|
local logger = require("logger")
|
2021-08-14 22:29:25 +03:00
|
|
|
local util = require("util")
|
2013-10-18 22:38:07 +02:00
|
|
|
local _ = require("gettext")
|
2017-04-29 10:38:09 +02:00
|
|
|
local Input = Device.input
|
|
|
|
|
local Screen = Device.screen
|
2024-10-30 20:09:59 +02:00
|
|
|
local T = ffiUtil.template
|
2012-04-15 02:28:48 +02:00
|
|
|
|
2021-12-24 13:21:12 +02:00
|
|
|
--[[--
|
|
|
|
|
Widget that displays a shortcut icon for menu item.
|
|
|
|
|
--]]
|
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 ItemShortCutIcon = WidgetContainer:extend{
|
2024-01-17 01:58:35 +01:00
|
|
|
dimen = Geom:new{ x = 0, y = 0, w = Screen:scaleBySize(22), h = Screen:scaleBySize(22) },
|
2014-03-13 21:52:43 +08:00
|
|
|
key = nil,
|
2017-09-13 16:56:20 +02:00
|
|
|
bordersize = Size.border.default,
|
2014-03-13 21:52:43 +08:00
|
|
|
radius = 0,
|
2014-07-30 09:00:02 +02:00
|
|
|
style = "square",
|
2012-04-29 23:53:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ItemShortCutIcon:init()
|
2014-03-13 21:52:43 +08:00
|
|
|
if not self.key then
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local radius = 0
|
2014-10-22 15:34:11 +02:00
|
|
|
local background = Blitbuffer.COLOR_WHITE
|
2014-03-13 21:52:43 +08:00
|
|
|
if self.style == "rounded_corner" then
|
[RFC] Pagination UI shenanigans (#7335)
* Menu/KeyValuePage/ReaderGoTo: Unify the dialogs. (Generally, "Enter page number" as title, and "Go to page" as OK button).
* Allow *tapping* on pagination buttons, too. Added spacers around the text to accommodate for that.
* Disable input handlers when <= 1 pages, while still printing the label in black.
* Always display both the label and the chevrons, even on single page content. (Menu being an exception, because it can handle showing no content at all, in which case we hide the chevrons).
* KVP: Tweak the pagination buttons layout in order to have consistent centering, regardless of whether the return arrow is enabled or not. (Also, match Menu's layout, more or less).
* Menu: Minor layout tweaks to follow the KVP tweaks above. Fixes, among possibly other things, buttons in (non-FM) "List" menus overlapping the final entry (e.g., OPDS), and popout menus with a border being misaligned (e.g., Calibre, Find a file).
* CalendarView: Minor layout tweaks to follow the KVP tweaks. Ensures the pagination buttons are laid out in the same way as everywhere else (they used to be a wee bit higher).
2021-02-25 05:15:23 +01:00
|
|
|
radius = math.floor(self.width / 2)
|
2014-03-13 21:52:43 +08:00
|
|
|
elseif self.style == "grey_square" then
|
2019-03-14 20:58:45 +01:00
|
|
|
background = Blitbuffer.COLOR_LIGHT_GRAY
|
2014-03-13 21:52:43 +08:00
|
|
|
end
|
|
|
|
|
|
2019-08-26 15:49:50 +02:00
|
|
|
--- @todo Calculate font size by icon size 01.05 2012 (houqp).
|
2016-01-02 23:44:23 -08:00
|
|
|
local sc_face
|
2014-03-13 21:52:43 +08:00
|
|
|
if self.key:len() > 1 then
|
|
|
|
|
sc_face = Font:getFace("ffont", 14)
|
|
|
|
|
else
|
|
|
|
|
sc_face = Font:getFace("scfont", 22)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
self[1] = FrameContainer:new{
|
|
|
|
|
padding = 0,
|
|
|
|
|
bordersize = self.bordersize,
|
|
|
|
|
radius = radius,
|
|
|
|
|
background = background,
|
2024-01-17 01:58:35 +01:00
|
|
|
dimen = self.dimen:copy(),
|
2014-03-13 21:52:43 +08:00
|
|
|
CenterContainer:new{
|
|
|
|
|
dimen = self.dimen,
|
|
|
|
|
TextWidget:new{
|
|
|
|
|
text = self.key,
|
|
|
|
|
face = sc_face,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
2012-04-29 23:53:48 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--[[
|
|
|
|
|
Widget that displays an item for menu
|
2012-12-07 23:30:15 +08: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 MenuItem = InputContainer:extend{
|
2024-05-07 09:34:30 +03:00
|
|
|
font = "smallinfofont",
|
2018-01-13 23:38:53 +01:00
|
|
|
infont = "infont",
|
|
|
|
|
linesize = Size.line.medium,
|
2019-07-19 21:43:05 +02:00
|
|
|
single_line = false,
|
2024-12-27 08:27:13 +02:00
|
|
|
multilines_forced = false, -- set to true to always use TextBoxWidget
|
2021-02-04 17:43:52 +01:00
|
|
|
multilines_show_more_text = false,
|
2019-07-19 21:43:05 +02:00
|
|
|
-- Align text & mandatory baselines (only when single_line=true)
|
|
|
|
|
align_baselines = false,
|
2021-05-13 01:55:35 +02:00
|
|
|
-- Show a line of dots (also called tab or dot leaders) between text and mandatory
|
|
|
|
|
with_dots = false,
|
2012-04-29 23:53:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function MenuItem:init()
|
2017-10-10 22:23:25 +02:00
|
|
|
self.content_width = self.dimen.w - 2 * Size.padding.fullscreen
|
2024-05-07 09:34:30 +03:00
|
|
|
|
|
|
|
|
local shortcut_icon_dimen
|
2014-03-13 21:52:43 +08:00
|
|
|
if self.shortcut then
|
2024-06-01 10:32:15 +03:00
|
|
|
local icon_width = self.entry.shortcut_icon_width or math.floor(self.dimen.h * 4/5)
|
2024-05-07 09:34:30 +03:00
|
|
|
shortcut_icon_dimen = Geom:new{
|
|
|
|
|
x = 0,
|
|
|
|
|
y = 0,
|
|
|
|
|
w = icon_width,
|
|
|
|
|
h = icon_width,
|
|
|
|
|
}
|
2017-10-10 22:23:25 +02:00
|
|
|
self.content_width = self.content_width - shortcut_icon_dimen.w - Size.span.horizontal_default
|
2014-03-13 21:52:43 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- we need this table per-instance, so we declare it here
|
2022-03-05 04:20:00 +08:00
|
|
|
self.ges_events = {
|
|
|
|
|
TapSelect = {
|
|
|
|
|
GestureRange:new{
|
|
|
|
|
ges = "tap",
|
|
|
|
|
range = self.dimen,
|
2014-03-13 21:52:43 +08:00
|
|
|
},
|
2022-03-05 04:20:00 +08:00
|
|
|
},
|
|
|
|
|
HoldSelect = {
|
|
|
|
|
GestureRange:new{
|
2023-03-28 16:16:53 +03:00
|
|
|
ges = self.handle_hold_on_hold_release and "hold_release" or "hold",
|
2022-03-05 04:20:00 +08:00
|
|
|
range = self.dimen,
|
2014-03-13 21:52:43 +08:00
|
|
|
},
|
2022-03-05 04:20:00 +08:00
|
|
|
},
|
|
|
|
|
}
|
2014-03-13 21:52:43 +08:00
|
|
|
|
2019-11-15 15:14:42 +01:00
|
|
|
local max_item_height = self.dimen.h - 2 * self.linesize
|
|
|
|
|
|
|
|
|
|
-- We want to show at least one line, so cap the provided font sizes
|
|
|
|
|
local max_font_size = TextBoxWidget:getFontSizeToFitHeight(max_item_height, 1)
|
|
|
|
|
if self.font_size > max_font_size then
|
|
|
|
|
self.font_size = max_font_size
|
|
|
|
|
end
|
|
|
|
|
if self.infont_size > max_font_size then
|
|
|
|
|
self.infont_size = max_font_size
|
|
|
|
|
end
|
2024-12-27 08:27:13 +02:00
|
|
|
if not self.single_line and not self.multilines_forced
|
|
|
|
|
and not self.multilines_show_more_text and not self.items_max_lines then
|
2019-11-15 15:14:42 +01:00
|
|
|
-- For non single line menus (File browser, Bookmarks), if the
|
|
|
|
|
-- user provided font size is large and would not allow showing
|
|
|
|
|
-- more than one line in our item height, just switch to single
|
|
|
|
|
-- line mode. This allows, when truncating, to take the full
|
|
|
|
|
-- width and cut inside a word to add the ellipsis - while in
|
|
|
|
|
-- multilines modes, with TextBoxWidget, words are wrapped to
|
|
|
|
|
-- follow line breaking rules, and the ellipsis might be placed
|
|
|
|
|
-- way earlier than the full width.
|
|
|
|
|
local min_font_size_2_lines = TextBoxWidget:getFontSizeToFitHeight(max_item_height, 2)
|
|
|
|
|
if self.font_size > min_font_size_2_lines then
|
|
|
|
|
self.single_line = true
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2019-10-21 15:20:40 +02:00
|
|
|
-- State button and indentation for tree expand/collapse (for TOC)
|
2024-05-07 09:34:30 +03:00
|
|
|
local state_button = self.entry.state or HorizontalSpan:new{}
|
|
|
|
|
local state_indent = self.entry.indent or 0
|
|
|
|
|
local state_width = state_indent + (self.state_w or 0)
|
2019-10-21 15:20:40 +02:00
|
|
|
local state_container = LeftContainer:new{
|
[RFC] Pagination UI shenanigans (#7335)
* Menu/KeyValuePage/ReaderGoTo: Unify the dialogs. (Generally, "Enter page number" as title, and "Go to page" as OK button).
* Allow *tapping* on pagination buttons, too. Added spacers around the text to accommodate for that.
* Disable input handlers when <= 1 pages, while still printing the label in black.
* Always display both the label and the chevrons, even on single page content. (Menu being an exception, because it can handle showing no content at all, in which case we hide the chevrons).
* KVP: Tweak the pagination buttons layout in order to have consistent centering, regardless of whether the return arrow is enabled or not. (Also, match Menu's layout, more or less).
* Menu: Minor layout tweaks to follow the KVP tweaks above. Fixes, among possibly other things, buttons in (non-FM) "List" menus overlapping the final entry (e.g., OPDS), and popout menus with a border being misaligned (e.g., Calibre, Find a file).
* CalendarView: Minor layout tweaks to follow the KVP tweaks. Ensures the pagination buttons are laid out in the same way as everywhere else (they used to be a wee bit higher).
2021-02-25 05:15:23 +01:00
|
|
|
dimen = Geom:new{w = math.floor(self.content_width / 2), h = self.dimen.h},
|
2019-10-21 15:20:40 +02:00
|
|
|
HorizontalGroup:new{
|
2022-01-20 11:14:30 -05:00
|
|
|
HorizontalSpan:new{
|
|
|
|
|
width = state_indent,
|
2019-10-21 15:20:40 +02:00
|
|
|
},
|
|
|
|
|
state_button,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-15 15:14:42 +01:00
|
|
|
-- Font for main text (may have its size decreased to make text fit)
|
|
|
|
|
self.face = Font:getFace(self.font, self.font_size)
|
|
|
|
|
-- Font for "mandatory" on the right
|
|
|
|
|
self.info_face = Font:getFace(self.infont, self.infont_size)
|
2024-03-20 10:09:44 +01:00
|
|
|
-- Font for post_text if any: for now, this is only used with TOC, showing
|
|
|
|
|
-- the chapter length: if feels best to use the face of the main text, but
|
|
|
|
|
-- with the size of the mandatory font (which shows some number too).
|
|
|
|
|
if self.post_text then
|
|
|
|
|
self.post_text_face = Font:getFace(self.font, self.infont_size)
|
|
|
|
|
end
|
2019-11-15 15:14:42 +01:00
|
|
|
|
2019-10-21 15:20:40 +02:00
|
|
|
-- "mandatory" is the text on the right: file size, page number...
|
|
|
|
|
-- Padding before mandatory
|
2017-10-13 14:42:08 +02:00
|
|
|
local text_mandatory_padding = 0
|
|
|
|
|
local text_ellipsis_mandatory_padding = 0
|
2020-08-29 18:25:36 +02:00
|
|
|
local mandatory = self.mandatory_func and self.mandatory_func() or self.mandatory
|
2024-08-06 19:12:16 +03:00
|
|
|
local mandatory_dim = self.mandatory_dim_func and self.mandatory_dim_func() or self.mandatory_dim
|
2020-08-29 18:25:36 +02:00
|
|
|
if mandatory then
|
2017-10-13 14:42:08 +02:00
|
|
|
text_mandatory_padding = Size.span.horizontal_default
|
|
|
|
|
-- Smaller padding when ellipsis for better visual feeling
|
|
|
|
|
text_ellipsis_mandatory_padding = Size.span.horizontal_small
|
|
|
|
|
end
|
2019-11-15 15:14:42 +01:00
|
|
|
local mandatory_widget = TextWidget:new{
|
2024-08-06 19:12:16 +03:00
|
|
|
text = mandatory or "",
|
2019-11-15 15:14:42 +01:00
|
|
|
face = self.info_face,
|
|
|
|
|
bold = self.bold,
|
2024-08-06 19:12:16 +03:00
|
|
|
fgcolor = mandatory_dim and Blitbuffer.COLOR_DARK_GRAY or nil,
|
2019-11-15 15:14:42 +01:00
|
|
|
}
|
|
|
|
|
local mandatory_w = mandatory_widget:getWidth()
|
2014-10-14 21:33:13 +08:00
|
|
|
|
2022-01-20 11:14:30 -05:00
|
|
|
local available_width = self.content_width - state_width - text_mandatory_padding - mandatory_w
|
2018-01-13 23:38:53 +01:00
|
|
|
local item_name
|
2019-11-15 15:14:42 +01:00
|
|
|
|
|
|
|
|
-- Whether we show text on a single or multiple lines, we don't want it shortened
|
|
|
|
|
-- because of some \n that would push the following text on another line that would
|
|
|
|
|
-- overflow and not be displayed, or show a tofu char when displayed by TextWidget:
|
|
|
|
|
-- get rid of any \n (which could be found in highlighted text in bookmarks).
|
|
|
|
|
local text = self.text:gsub("\n", " ")
|
2018-01-13 23:38:53 +01:00
|
|
|
|
2019-12-17 13:00:37 +01:00
|
|
|
-- Wrap text with provided bidi_wrap_func (only provided by FileChooser,
|
|
|
|
|
-- to correctly display filenames and directories)
|
|
|
|
|
if self.bidi_wrap_func then
|
|
|
|
|
text = self.bidi_wrap_func(text)
|
|
|
|
|
end
|
|
|
|
|
|
2024-03-20 10:09:44 +01:00
|
|
|
-- Note: support for post_text is currently implemented only when single_line=true
|
|
|
|
|
local post_text_widget
|
|
|
|
|
local post_text_left_padding = Size.padding.large
|
|
|
|
|
local post_text_right_padding = self.with_dots and 0 or Size.padding.large
|
2021-05-13 01:55:35 +02:00
|
|
|
local dots_widget
|
|
|
|
|
local dots_left_padding = Size.padding.small
|
|
|
|
|
local dots_right_padding = Size.padding.small
|
2024-05-07 09:34:30 +03:00
|
|
|
|
|
|
|
|
if self.single_line then
|
|
|
|
|
-- Items only in single line
|
2024-03-20 10:09:44 +01:00
|
|
|
if self.post_text then
|
|
|
|
|
post_text_widget = TextWidget:new{
|
|
|
|
|
text = self.post_text,
|
|
|
|
|
face = self.post_text_face,
|
|
|
|
|
bold = self.bold,
|
|
|
|
|
fgcolor = self.dim and Blitbuffer.COLOR_DARK_GRAY or nil,
|
|
|
|
|
}
|
|
|
|
|
available_width = available_width - post_text_widget:getWidth() - post_text_left_padding - post_text_right_padding
|
|
|
|
|
end
|
2019-10-21 15:20:40 +02:00
|
|
|
-- No font size change: text will be truncated if it overflows
|
|
|
|
|
item_name = TextWidget:new{
|
2019-11-15 15:14:42 +01:00
|
|
|
text = text,
|
2019-10-21 15:20:40 +02:00
|
|
|
face = self.face,
|
|
|
|
|
bold = self.bold,
|
2023-08-10 18:01:07 +03:00
|
|
|
truncate_left = self.truncate_left,
|
2019-10-21 15:20:40 +02:00
|
|
|
fgcolor = self.dim and Blitbuffer.COLOR_DARK_GRAY or nil,
|
|
|
|
|
}
|
|
|
|
|
local w = item_name:getWidth()
|
2019-11-15 15:14:42 +01:00
|
|
|
if w > available_width then
|
2023-08-10 18:01:07 +03:00
|
|
|
local text_max_width_if_ellipsis = available_width
|
|
|
|
|
-- We give it a little more room if truncated at the right for better visual
|
2019-11-15 15:14:42 +01:00
|
|
|
-- feeling (which might make it no more truncated, but well...)
|
2023-08-10 18:01:07 +03:00
|
|
|
if not self.truncate_left then
|
|
|
|
|
text_max_width_if_ellipsis = text_max_width_if_ellipsis + text_mandatory_padding - text_ellipsis_mandatory_padding
|
|
|
|
|
end
|
2019-10-21 15:20:40 +02:00
|
|
|
item_name:setMaxWidth(text_max_width_if_ellipsis)
|
2021-05-13 01:55:35 +02:00
|
|
|
else
|
|
|
|
|
if self.with_dots then
|
|
|
|
|
local dots_width = available_width + text_mandatory_padding - w - dots_left_padding - dots_right_padding
|
|
|
|
|
if dots_width > 0 then
|
|
|
|
|
local dots_text, dots_min_width = self:getDotsText(self.info_face)
|
|
|
|
|
-- Don't show any dots if there would be less than 3
|
|
|
|
|
if dots_width >= dots_min_width then
|
|
|
|
|
dots_widget = TextWidget:new{
|
|
|
|
|
text = dots_text,
|
|
|
|
|
face = self.info_face, -- same as mandatory widget, to keep their baseline adjusted
|
|
|
|
|
max_width = dots_width,
|
|
|
|
|
truncate_with_ellipsis = false,
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2019-10-21 15:20:40 +02:00
|
|
|
end
|
|
|
|
|
if self.align_baselines then -- Align baselines of text and mandatory
|
2021-05-13 01:55:35 +02:00
|
|
|
-- The container widgets would additionally center these widgets,
|
|
|
|
|
-- so make sure they all get a height=self.dimen.h so they don't
|
|
|
|
|
-- risk being shifted later and becoming misaligned
|
2019-07-19 21:43:05 +02:00
|
|
|
local name_baseline = item_name:getBaseline()
|
2021-05-13 01:55:35 +02:00
|
|
|
local mdtr_baseline = mandatory_widget:getBaseline()
|
|
|
|
|
local name_height = item_name:getSize().h
|
|
|
|
|
local mdtr_height = mandatory_widget:getSize().h
|
|
|
|
|
-- Make all the TextWidgets be self.dimen.h
|
|
|
|
|
item_name.forced_height = self.dimen.h
|
|
|
|
|
mandatory_widget.forced_height = self.dimen.h
|
|
|
|
|
if dots_widget then
|
|
|
|
|
dots_widget.forced_height = self.dimen.h
|
|
|
|
|
end
|
2024-03-20 10:09:44 +01:00
|
|
|
if post_text_widget then
|
|
|
|
|
post_text_widget.forced_height = self.dimen.h
|
|
|
|
|
end
|
2021-05-13 01:55:35 +02:00
|
|
|
-- And adjust their baselines for proper centering and alignment
|
|
|
|
|
-- (We made sure the font sizes wouldn't exceed self.dimen.h, so we
|
|
|
|
|
-- get only non-negative pad_top here, and we're moving them down.)
|
|
|
|
|
local name_missing_pad_top = math.floor( (self.dimen.h - name_height) / 2)
|
|
|
|
|
local mdtr_missing_pad_top = math.floor( (self.dimen.h - mdtr_height) / 2)
|
|
|
|
|
name_baseline = name_baseline + name_missing_pad_top
|
|
|
|
|
mdtr_baseline = mdtr_baseline + mdtr_missing_pad_top
|
|
|
|
|
local baselines_diff = Math.round(name_baseline - mdtr_baseline)
|
2019-07-19 21:43:05 +02:00
|
|
|
if baselines_diff > 0 then
|
2021-05-13 01:55:35 +02:00
|
|
|
mdtr_baseline = mdtr_baseline + baselines_diff
|
|
|
|
|
else
|
|
|
|
|
name_baseline = name_baseline - baselines_diff
|
|
|
|
|
end
|
|
|
|
|
item_name.forced_baseline = name_baseline
|
|
|
|
|
mandatory_widget.forced_baseline = mdtr_baseline
|
|
|
|
|
if dots_widget then
|
|
|
|
|
dots_widget.forced_baseline = mdtr_baseline
|
2019-07-19 21:43:05 +02:00
|
|
|
end
|
2024-03-20 10:09:44 +01:00
|
|
|
if post_text_widget then
|
|
|
|
|
post_text_widget.forced_baseline = mdtr_baseline
|
|
|
|
|
end
|
2019-07-19 21:43:05 +02:00
|
|
|
end
|
2018-01-13 23:38:53 +01:00
|
|
|
|
2021-02-04 17:43:52 +01:00
|
|
|
elseif self.multilines_show_more_text then
|
2019-11-15 15:14:42 +01:00
|
|
|
-- Multi-lines, with font size decrease if needed to show more of the text.
|
|
|
|
|
-- It would be costly/slow with use_xtext if we were to try all
|
2021-10-18 09:52:40 +03:00
|
|
|
-- font sizes from self.font_size to min_font_size.
|
2019-11-15 15:14:42 +01:00
|
|
|
-- So, we try to optimize the search of the best font size.
|
|
|
|
|
logger.dbg("multilines_show_more_text menu item font sizing start")
|
|
|
|
|
local function make_item_name(font_size)
|
2018-01-13 23:38:53 +01:00
|
|
|
if item_name then
|
|
|
|
|
item_name:free()
|
|
|
|
|
end
|
2019-11-15 15:14:42 +01:00
|
|
|
logger.dbg("multilines_show_more_text trying font size", font_size)
|
2018-01-13 23:38:53 +01:00
|
|
|
item_name = TextBoxWidget:new {
|
2019-11-15 15:14:42 +01:00
|
|
|
text = text,
|
|
|
|
|
face = Font:getFace(self.font, font_size),
|
|
|
|
|
width = available_width,
|
2018-01-13 23:38:53 +01:00
|
|
|
alignment = "left",
|
|
|
|
|
bold = self.bold,
|
2019-03-14 20:58:45 +01:00
|
|
|
fgcolor = self.dim and Blitbuffer.COLOR_DARK_GRAY or nil,
|
2018-01-13 23:38:53 +01:00
|
|
|
}
|
2019-11-15 15:14:42 +01:00
|
|
|
-- return true if we fit
|
|
|
|
|
return item_name:getSize().h <= max_item_height
|
2019-10-22 12:48:47 +02:00
|
|
|
end
|
2021-10-18 09:52:40 +03:00
|
|
|
-- To keep item readable, do not decrease font size by more than 8 points
|
|
|
|
|
-- relative to the specified font size, being not smaller than 12 absolute points.
|
|
|
|
|
local min_font_size = math.max(12, self.font_size - 8)
|
2019-11-15 15:14:42 +01:00
|
|
|
-- First, try with specified font size: short text might fit
|
|
|
|
|
if not make_item_name(self.font_size) then
|
|
|
|
|
-- It doesn't, try with min font size: very long text might not fit
|
|
|
|
|
if not make_item_name(min_font_size) then
|
|
|
|
|
-- Does not fit with min font size: keep widget with min_font_size, but
|
|
|
|
|
-- impose a max height to show only the first lines up to where it fits
|
2019-10-22 12:48:47 +02:00
|
|
|
item_name:free()
|
2019-11-15 15:14:42 +01:00
|
|
|
item_name.height = max_item_height
|
|
|
|
|
item_name.height_adjust = true
|
|
|
|
|
item_name.height_overflow_show_ellipsis = true
|
|
|
|
|
item_name:init()
|
2019-10-22 12:48:47 +02:00
|
|
|
else
|
2019-11-15 15:14:42 +01:00
|
|
|
-- Text fits with min font size: try to find some larger
|
|
|
|
|
-- font size in between that make text fit, with some
|
|
|
|
|
-- binary search to limit the number of checks.
|
|
|
|
|
local bad_font_size = self.font_size
|
|
|
|
|
local good_font_size = min_font_size
|
|
|
|
|
local item_name_is_good = true
|
|
|
|
|
while true do
|
|
|
|
|
local test_font_size = math.floor((good_font_size + bad_font_size) / 2)
|
|
|
|
|
if test_font_size == good_font_size then -- +1 would be bad_font_size
|
|
|
|
|
if not item_name_is_good then
|
|
|
|
|
make_item_name(good_font_size)
|
|
|
|
|
end
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
if make_item_name(test_font_size) then
|
|
|
|
|
good_font_size = test_font_size
|
|
|
|
|
item_name_is_good = true
|
|
|
|
|
else
|
|
|
|
|
bad_font_size = test_font_size
|
|
|
|
|
item_name_is_good = false
|
|
|
|
|
end
|
2018-02-04 19:48:39 +01:00
|
|
|
end
|
2019-10-22 12:48:47 +02:00
|
|
|
end
|
2018-01-13 23:38:53 +01:00
|
|
|
end
|
2024-05-07 09:34:30 +03:00
|
|
|
|
2019-11-15 15:14:42 +01:00
|
|
|
else
|
|
|
|
|
-- Multi-lines, with fixed user provided font size
|
|
|
|
|
item_name = TextBoxWidget:new {
|
|
|
|
|
text = text,
|
|
|
|
|
face = self.face,
|
|
|
|
|
width = available_width,
|
2024-06-01 10:32:15 +03:00
|
|
|
height = self.entry.height and (self.entry.height - 2 * Size.span.vertical_default - self.linesize) or max_item_height,
|
2019-11-15 15:14:42 +01:00
|
|
|
height_adjust = true,
|
|
|
|
|
height_overflow_show_ellipsis = true,
|
|
|
|
|
alignment = "left",
|
|
|
|
|
bold = self.bold,
|
|
|
|
|
fgcolor = self.dim and Blitbuffer.COLOR_DARK_GRAY or nil,
|
|
|
|
|
}
|
2018-01-13 23:38:53 +01:00
|
|
|
end
|
|
|
|
|
|
2014-03-13 21:52:43 +08:00
|
|
|
local text_container = LeftContainer:new{
|
|
|
|
|
dimen = Geom:new{w = self.content_width, h = self.dimen.h},
|
2014-10-14 21:33:13 +08:00
|
|
|
HorizontalGroup:new{
|
|
|
|
|
HorizontalSpan:new{
|
2022-01-20 11:14:30 -05:00
|
|
|
width = state_width,
|
2014-10-14 21:33:13 +08:00
|
|
|
},
|
2018-01-13 23:38:53 +01:00
|
|
|
item_name,
|
2024-03-20 10:09:44 +01:00
|
|
|
post_text_widget and HorizontalSpan:new{ width = post_text_left_padding },
|
|
|
|
|
post_text_widget,
|
2014-03-13 21:52:43 +08:00
|
|
|
}
|
|
|
|
|
}
|
2014-04-04 23:02:29 +08:00
|
|
|
|
2021-05-13 01:55:35 +02:00
|
|
|
if dots_widget then
|
|
|
|
|
mandatory_widget = HorizontalGroup:new{
|
|
|
|
|
dots_widget,
|
|
|
|
|
HorizontalSpan:new{ width = dots_right_padding },
|
|
|
|
|
mandatory_widget,
|
|
|
|
|
}
|
|
|
|
|
end
|
2014-03-13 21:52:43 +08:00
|
|
|
local mandatory_container = RightContainer:new{
|
|
|
|
|
dimen = Geom:new{w = self.content_width, h = self.dimen.h},
|
2018-01-13 23:38:53 +01:00
|
|
|
mandatory_widget,
|
2014-03-13 21:52:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self._underline_container = UnderlineContainer:new{
|
2018-01-13 23:38:53 +01:00
|
|
|
color = self.line_color,
|
|
|
|
|
linesize = self.linesize,
|
2014-10-14 21:33:13 +08:00
|
|
|
vertical_align = "center",
|
2018-01-13 23:38:53 +01:00
|
|
|
padding = 0,
|
2014-03-13 21:52:43 +08:00
|
|
|
dimen = Geom:new{
|
2024-01-17 02:19:37 +01:00
|
|
|
x = 0, y = 0,
|
2014-03-13 21:52:43 +08:00
|
|
|
w = self.content_width,
|
|
|
|
|
h = self.dimen.h
|
|
|
|
|
},
|
|
|
|
|
HorizontalGroup:new{
|
|
|
|
|
align = "center",
|
|
|
|
|
OverlapGroup:new{
|
|
|
|
|
dimen = Geom:new{w = self.content_width, h = self.dimen.h},
|
2014-10-14 21:33:13 +08:00
|
|
|
state_container,
|
2014-03-13 21:52:43 +08:00
|
|
|
text_container,
|
|
|
|
|
mandatory_container,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-10-10 22:23:25 +02:00
|
|
|
local hgroup = HorizontalGroup:new{
|
|
|
|
|
align = "center",
|
2021-04-15 19:07:34 +02:00
|
|
|
HorizontalSpan:new{ width = self.items_padding or Size.padding.fullscreen },
|
2017-10-10 22:23:25 +02:00
|
|
|
}
|
|
|
|
|
if self.shortcut then
|
2025-03-19 08:01:09 +02:00
|
|
|
table.insert(hgroup, self.menu:getItemShortCutIcon(shortcut_icon_dimen, self.shortcut, self.shortcut_style))
|
2017-10-10 22:23:25 +02:00
|
|
|
table.insert(hgroup, HorizontalSpan:new{ width = Size.span.horizontal_default })
|
|
|
|
|
end
|
|
|
|
|
table.insert(hgroup, self._underline_container)
|
2019-12-06 22:55:39 +01:00
|
|
|
table.insert(hgroup, HorizontalSpan:new{ width = Size.padding.fullscreen })
|
2017-10-10 22:23:25 +02:00
|
|
|
|
2014-03-13 21:52:43 +08:00
|
|
|
self[1] = FrameContainer:new{
|
|
|
|
|
bordersize = 0,
|
|
|
|
|
padding = 0,
|
2017-10-10 22:23:25 +02:00
|
|
|
hgroup,
|
2014-03-13 21:52:43 +08:00
|
|
|
}
|
2012-04-29 23:53:48 +08:00
|
|
|
end
|
|
|
|
|
|
2021-05-13 01:55:35 +02:00
|
|
|
local _dots_cached_info
|
|
|
|
|
function MenuItem:getDotsText(face)
|
|
|
|
|
local screen_w = Screen:getWidth()
|
|
|
|
|
if not _dots_cached_info or _dots_cached_info.screen_width ~= screen_w
|
|
|
|
|
or _dots_cached_info.face ~= face then
|
|
|
|
|
local unit = "."
|
|
|
|
|
local tmp = TextWidget:new{
|
|
|
|
|
text = unit,
|
|
|
|
|
face = face,
|
|
|
|
|
}
|
|
|
|
|
local unit_w = tmp:getSize().w
|
|
|
|
|
tmp:free()
|
|
|
|
|
-- (We assume/expect no kerning will happen between consecutive units)
|
|
|
|
|
local nb_units = math.ceil(screen_w / unit_w)
|
|
|
|
|
local min_width = unit_w * 3 -- have it not shown if smaller than this
|
|
|
|
|
local text = unit:rep(nb_units)
|
|
|
|
|
_dots_cached_info = {
|
|
|
|
|
text = text,
|
|
|
|
|
min_width = min_width,
|
|
|
|
|
screen_width = screen_w,
|
|
|
|
|
face = face,
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
return _dots_cached_info.text, _dots_cached_info.min_width
|
|
|
|
|
end
|
|
|
|
|
|
FocusManager: Fix focus_flags check in moveFocusTo, and deal with the fallout (#12361)
* FocusManager: Fix `focus_flags` check in `moveFocusTo` (0 is truthy in Lua, can't do AND checks like in C ;).)
* FileManager+FileChooser: Pass our custom title bar directly to FileChooser (which also means we can now use FC's FocusManager layout directly).
* FileChooser/Menu: Get rid of the weird `outer_title_bar` hack, and simply take a `custom_title_bar` pointer to an actual TitleBar instance instead.
* FileManager/Menu/ListMenu/CoverMenu: Fix content height computations in `_recalculateDimen` (all the non-FM cases were including an old and now unused padding value, `self.header_padding`, leading to more blank space at the bottom than necessary, and, worse, leading to different item heights between FM views, possibly leading to unnecessary thumbnail scaling !)
* ButtonDialog: Proper focus management when the ButtonTable is wrapped in a ScrollableContainer.
* ConfigDialog: Implement a stupid workaround for a weird FocusManager issue when going back from `[⋮]` buttons.
* ConfigDialog: Don't move the visual focus in `update` (i.e., we use `NOT_FOCUS` now that it works as intended).
* DictQuickLookup: Ensures the `Menu` key bind does the exact same thing as the hamburger icon.
* DictQuickLookup: Ensure we refocus after having mangled the FocusManager layout (prevents an old focus highlight from lingering on the wrong button).
* FileChooser: Stop flagging it as no_title, because it is *never* without a title. (This behavior was a remnant of the previous FM-specific title bar hacks, which are no longer a thing).
* FileChooser: Stop calling `mergeTitleBarIntoLayout` twice in `updateItems`. We already call Menu's, which handles it. (Prevents the title bar from being added twice to the FocusManager layout).
* FocusManager: Relax the `Unfocus` checks in `moveFocusTo` to ensure we *always* unfocus something (if unfocusing was requested), even if we have to blast the whole widget tree to do so. This ensures callers that mangle self.layout can expect things to work after calling it regardless of how borked the current focus is.
* FocusManager: Allow passing `focus_flags` to `refocusWidget`, so that it can be forwarded to the internal `moveFocusTo` call.
* FocusManager: The above also allows us to enforce a default that ensures we do *not* send a Focus event on Touch devices, even if they have the hasDPad devcap. This essentially restores the previous/current behavior of not showing the visual feedback from such focus "events" sent programmatically, given the `focus_flags` check fix at the root of this PR ;).
* InputDialog: Fix numerous issues relating to double/ghost instances of both InputText and VirtualKeyboard, ensuring we only ever have a single InputText & VK instance live.
* InputDialog: Make sure every way we have of hiding the VK play nice together, especially when the `toggleKeyboard` button (shown w/ `add_nav_bar`) is at play. And doubly so when we're `fullscreen`, as hiding the VK implies resizing the widget.
* InputText: Make sure we're flagged as in-focus when tapping inside the text field.
* InputText: Make sure we don't attempt to show an already-visible VK in the custom `hasDPad` `onFocus` handler.
* Menu: Get rid of an old and no longer used (nor meaningful) hack in `onFocus` about the initial/programmatically-sent Focus event.
* Menu: Get rid of the unused `header_padding` field mentioned earlier in the FM/FC fixes.
* Menu: Use `FOCUS_ONLY_ON_NT` in the explicit `moveFocusTo` call in `updatePageInfo`, so as to keep the current behavior of not showing the visual feedback of this focus on Touch devices.
* Menu: Make sure *all* the `moveFocusTo` calls are gated behind the `hasDPad` devcap (previously, that was only the case for `updatePageInfo`, but not `mergeTitleBarIntoLayout` (which is called by `updateItems`).
* MultiInputDialog: Actively get rid of the InputText & VK instances from the base class's constructor that we do not use.
* MultiInputDialog: Ensure the FocusManager layout is *slightly* less broken (password fields can still be a bit weird, though).
* TextViewer: Get rid of the unfocus -> layout mangling -> refocus hack now that `refocusWidget` handles this case sanely.
* VirtualKeyboard: Notify our parent InputDialog when we get closed, so it can act accordingly (e.g., resize itself when `fullscreen`).
* ScrollableContainer: Implement the necessary machinery for focus handling inside ButtonDialog (specifically, when scrolling via PgUp/PgDwn).
* TextEditor: Given the above fixes, the plugin is no longer disabled on non-touch devices.
* ReaderBookMark: Make sure we request a full refresh when closing the "Edit note" dialog, as CRe highlights may extend past its dimensions, and if it's closed separately from VK, the refresh would have been limited to its own dimensions, leaving a neat InputDialog-sized hole in the highlights ;).
2024-08-25 19:34:31 +02:00
|
|
|
function MenuItem:onFocus()
|
|
|
|
|
self._underline_container.color = Blitbuffer.COLOR_BLACK
|
|
|
|
|
-- NOTE: Medium is really, really, really thin; so we'd ideally swap to something thicker...
|
|
|
|
|
-- Unfortunately, this affects vertical text positioning,
|
|
|
|
|
-- leading to an unsightly refresh of the item :/.
|
|
|
|
|
--self._underline_container.linesize = Size.line.thick
|
2014-03-13 21:52:43 +08:00
|
|
|
return true
|
2012-04-29 23:53:48 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function MenuItem:onUnfocus()
|
2018-01-13 23:38:53 +01:00
|
|
|
self._underline_container.color = self.line_color
|
FocusManager: Fix focus_flags check in moveFocusTo, and deal with the fallout (#12361)
* FocusManager: Fix `focus_flags` check in `moveFocusTo` (0 is truthy in Lua, can't do AND checks like in C ;).)
* FileManager+FileChooser: Pass our custom title bar directly to FileChooser (which also means we can now use FC's FocusManager layout directly).
* FileChooser/Menu: Get rid of the weird `outer_title_bar` hack, and simply take a `custom_title_bar` pointer to an actual TitleBar instance instead.
* FileManager/Menu/ListMenu/CoverMenu: Fix content height computations in `_recalculateDimen` (all the non-FM cases were including an old and now unused padding value, `self.header_padding`, leading to more blank space at the bottom than necessary, and, worse, leading to different item heights between FM views, possibly leading to unnecessary thumbnail scaling !)
* ButtonDialog: Proper focus management when the ButtonTable is wrapped in a ScrollableContainer.
* ConfigDialog: Implement a stupid workaround for a weird FocusManager issue when going back from `[⋮]` buttons.
* ConfigDialog: Don't move the visual focus in `update` (i.e., we use `NOT_FOCUS` now that it works as intended).
* DictQuickLookup: Ensures the `Menu` key bind does the exact same thing as the hamburger icon.
* DictQuickLookup: Ensure we refocus after having mangled the FocusManager layout (prevents an old focus highlight from lingering on the wrong button).
* FileChooser: Stop flagging it as no_title, because it is *never* without a title. (This behavior was a remnant of the previous FM-specific title bar hacks, which are no longer a thing).
* FileChooser: Stop calling `mergeTitleBarIntoLayout` twice in `updateItems`. We already call Menu's, which handles it. (Prevents the title bar from being added twice to the FocusManager layout).
* FocusManager: Relax the `Unfocus` checks in `moveFocusTo` to ensure we *always* unfocus something (if unfocusing was requested), even if we have to blast the whole widget tree to do so. This ensures callers that mangle self.layout can expect things to work after calling it regardless of how borked the current focus is.
* FocusManager: Allow passing `focus_flags` to `refocusWidget`, so that it can be forwarded to the internal `moveFocusTo` call.
* FocusManager: The above also allows us to enforce a default that ensures we do *not* send a Focus event on Touch devices, even if they have the hasDPad devcap. This essentially restores the previous/current behavior of not showing the visual feedback from such focus "events" sent programmatically, given the `focus_flags` check fix at the root of this PR ;).
* InputDialog: Fix numerous issues relating to double/ghost instances of both InputText and VirtualKeyboard, ensuring we only ever have a single InputText & VK instance live.
* InputDialog: Make sure every way we have of hiding the VK play nice together, especially when the `toggleKeyboard` button (shown w/ `add_nav_bar`) is at play. And doubly so when we're `fullscreen`, as hiding the VK implies resizing the widget.
* InputText: Make sure we're flagged as in-focus when tapping inside the text field.
* InputText: Make sure we don't attempt to show an already-visible VK in the custom `hasDPad` `onFocus` handler.
* Menu: Get rid of an old and no longer used (nor meaningful) hack in `onFocus` about the initial/programmatically-sent Focus event.
* Menu: Get rid of the unused `header_padding` field mentioned earlier in the FM/FC fixes.
* Menu: Use `FOCUS_ONLY_ON_NT` in the explicit `moveFocusTo` call in `updatePageInfo`, so as to keep the current behavior of not showing the visual feedback of this focus on Touch devices.
* Menu: Make sure *all* the `moveFocusTo` calls are gated behind the `hasDPad` devcap (previously, that was only the case for `updatePageInfo`, but not `mergeTitleBarIntoLayout` (which is called by `updateItems`).
* MultiInputDialog: Actively get rid of the InputText & VK instances from the base class's constructor that we do not use.
* MultiInputDialog: Ensure the FocusManager layout is *slightly* less broken (password fields can still be a bit weird, though).
* TextViewer: Get rid of the unfocus -> layout mangling -> refocus hack now that `refocusWidget` handles this case sanely.
* VirtualKeyboard: Notify our parent InputDialog when we get closed, so it can act accordingly (e.g., resize itself when `fullscreen`).
* ScrollableContainer: Implement the necessary machinery for focus handling inside ButtonDialog (specifically, when scrolling via PgUp/PgDwn).
* TextEditor: Given the above fixes, the plugin is no longer disabled on non-touch devices.
* ReaderBookMark: Make sure we request a full refresh when closing the "Edit note" dialog, as CRe highlights may extend past its dimensions, and if it's closed separately from VK, the refresh would have been limited to its own dimensions, leaving a neat InputDialog-sized hole in the highlights ;).
2024-08-25 19:34:31 +02:00
|
|
|
-- See above for reasoning.
|
|
|
|
|
--self._underline_container.linesize = self.linesize
|
2014-03-13 21:52:43 +08:00
|
|
|
return true
|
2012-04-29 23:53:48 +08:00
|
|
|
end
|
|
|
|
|
|
2014-10-21 22:18:07 +08:00
|
|
|
function MenuItem:getGesPosition(ges)
|
|
|
|
|
local dimen = self[1].dimen
|
|
|
|
|
return {
|
2021-03-03 19:39:22 +01:00
|
|
|
x = (ges.pos.x - dimen.x) / dimen.w,
|
|
|
|
|
y = (ges.pos.y - dimen.y) / dimen.h,
|
2014-10-21 22:18:07 +08:00
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function MenuItem:onTapSelect(arg, ges)
|
2021-06-19 17:49:40 +02:00
|
|
|
-- Abort if the menu hasn't been painted yet.
|
|
|
|
|
if not self[1].dimen then return end
|
|
|
|
|
|
2014-10-21 22:18:07 +08:00
|
|
|
local pos = self:getGesPosition(ges)
|
2017-10-10 23:50:45 +02:00
|
|
|
if G_reader_settings:isFalse("flash_ui") then
|
2024-05-07 09:34:30 +03:00
|
|
|
self.menu:onMenuSelect(self.entry, pos)
|
2017-10-10 23:50:45 +02:00
|
|
|
else
|
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 18:22:48 +01:00
|
|
|
-- c.f., ui/widget/iconbutton for the canonical documentation about the flash_ui code flow
|
|
|
|
|
|
|
|
|
|
-- Highlight
|
|
|
|
|
--
|
2017-10-10 23:50:45 +02:00
|
|
|
self[1].invert = true
|
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 01:51:09 +01:00
|
|
|
UIManager:widgetInvert(self[1], self[1].dimen.x, self[1].dimen.y)
|
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 18:22:48 +01:00
|
|
|
UIManager:setDirty(nil, "fast", self[1].dimen)
|
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 01:51:09 +01:00
|
|
|
|
|
|
|
|
UIManager:forceRePaint()
|
2021-02-22 02:09:44 +01:00
|
|
|
UIManager:yieldToEPDC()
|
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 18:22:48 +01:00
|
|
|
|
|
|
|
|
-- Unhighlight
|
|
|
|
|
--
|
|
|
|
|
self[1].invert = false
|
|
|
|
|
UIManager:widgetInvert(self[1], self[1].dimen.x, self[1].dimen.y)
|
|
|
|
|
UIManager:setDirty(nil, "ui", self[1].dimen)
|
|
|
|
|
|
|
|
|
|
-- Callback
|
|
|
|
|
--
|
2024-05-07 09:34:30 +03:00
|
|
|
self.menu:onMenuSelect(self.entry, pos)
|
Tame some ButtonTable users into re-using Buttontable instances if possible (#7166)
* QuickDictLookup, ImageViewer, NumberPicker: Smarter `update` that will re-use most of the widget's layout instead of re-instantiating all the things.
* SpinWidget/DoubleSpinWidget: The NumberPicker change above renders a hack to preserve alpha on these widgets almost unnecessary. Also fixed said hack to also apply to the center, value button.
* Button: Don't re-instantiate the frame in setText/setIcon when unnecessary (e.g., no change at all, or no layout change).
* Button: Add a refresh method that repaints and refreshes a *specific* Button (provided it's been painted once) all on its lonesome.
* ConfigDialog: Free everything that's going to be re-instatiated on update
* A few more post #7118 fixes:
* SkimTo: Always flag the chapter nav buttons as vsync
* Button: Fix the highlight on rounded buttons when vsync is enabled (e.g., it's now entirely visible, instead of showing a weird inverted corner glitch).
* Some more heuristic tweaks in Menu/TouchMenu/Button/IconButton
* ButtonTable: fix the annoying rounding issue I'd noticed in #7054 ;).
* Enable dithering in TextBoxWidget (e.g., in the Wikipedia full view). This involved moving the HW dithering align fixup to base, where it always ought to have been ;).
* Switch a few widgets that were using "partial" on close to "ui", or, more rarely, "flashui". The intent being to limit "partial" purely to the Reader, because it has a latency cost when mixed with other refreshes, which happens often enough in UI ;).
* Minor documentation tweaks around UIManager's `setDirty` to reflect that change.
* ReaderFooter: Force a footer repaint on resume if it is visible (otherwise, just update it).
* ReaderBookmark: In the same vein, don't repaint an invisible footer on bookmark count changes.
2021-01-29 00:20:15 +01:00
|
|
|
|
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 18:22:48 +01:00
|
|
|
UIManager:forceRePaint()
|
2017-10-10 23:50:45 +02:00
|
|
|
end
|
2014-03-13 21:52:43 +08:00
|
|
|
return true
|
2012-11-11 01:00:52 -05:00
|
|
|
end
|
|
|
|
|
|
2014-10-21 22:18:07 +08:00
|
|
|
function MenuItem:onHoldSelect(arg, ges)
|
2021-06-19 17:49:40 +02:00
|
|
|
if not self[1].dimen then return end
|
|
|
|
|
|
2014-10-21 22:18:07 +08:00
|
|
|
local pos = self:getGesPosition(ges)
|
2017-10-10 23:50:45 +02:00
|
|
|
if G_reader_settings:isFalse("flash_ui") then
|
2024-05-07 09:34:30 +03:00
|
|
|
self.menu:onMenuHold(self.entry, pos)
|
2017-10-10 23:50:45 +02:00
|
|
|
else
|
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 18:22:48 +01:00
|
|
|
-- c.f., ui/widget/iconbutton for the canonical documentation about the flash_ui code flow
|
|
|
|
|
|
|
|
|
|
-- Highlight
|
|
|
|
|
--
|
2017-10-10 23:50:45 +02:00
|
|
|
self[1].invert = true
|
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 01:51:09 +01:00
|
|
|
UIManager:widgetInvert(self[1], self[1].dimen.x, self[1].dimen.y)
|
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 18:22:48 +01:00
|
|
|
UIManager:setDirty(nil, "fast", self[1].dimen)
|
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 01:51:09 +01:00
|
|
|
|
|
|
|
|
UIManager:forceRePaint()
|
2021-02-22 02:09:44 +01:00
|
|
|
UIManager:yieldToEPDC()
|
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 01:51:09 +01:00
|
|
|
|
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 18:22:48 +01:00
|
|
|
-- Unhighlight
|
|
|
|
|
--
|
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 01:51:09 +01:00
|
|
|
self[1].invert = false
|
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 18:22:48 +01:00
|
|
|
UIManager:widgetInvert(self[1], self[1].dimen.x, self[1].dimen.y)
|
|
|
|
|
UIManager:setDirty(nil, "ui", self[1].dimen)
|
Tame some ButtonTable users into re-using Buttontable instances if possible (#7166)
* QuickDictLookup, ImageViewer, NumberPicker: Smarter `update` that will re-use most of the widget's layout instead of re-instantiating all the things.
* SpinWidget/DoubleSpinWidget: The NumberPicker change above renders a hack to preserve alpha on these widgets almost unnecessary. Also fixed said hack to also apply to the center, value button.
* Button: Don't re-instantiate the frame in setText/setIcon when unnecessary (e.g., no change at all, or no layout change).
* Button: Add a refresh method that repaints and refreshes a *specific* Button (provided it's been painted once) all on its lonesome.
* ConfigDialog: Free everything that's going to be re-instatiated on update
* A few more post #7118 fixes:
* SkimTo: Always flag the chapter nav buttons as vsync
* Button: Fix the highlight on rounded buttons when vsync is enabled (e.g., it's now entirely visible, instead of showing a weird inverted corner glitch).
* Some more heuristic tweaks in Menu/TouchMenu/Button/IconButton
* ButtonTable: fix the annoying rounding issue I'd noticed in #7054 ;).
* Enable dithering in TextBoxWidget (e.g., in the Wikipedia full view). This involved moving the HW dithering align fixup to base, where it always ought to have been ;).
* Switch a few widgets that were using "partial" on close to "ui", or, more rarely, "flashui". The intent being to limit "partial" purely to the Reader, because it has a latency cost when mixed with other refreshes, which happens often enough in UI ;).
* Minor documentation tweaks around UIManager's `setDirty` to reflect that change.
* ReaderFooter: Force a footer repaint on resume if it is visible (otherwise, just update it).
* ReaderBookmark: In the same vein, don't repaint an invisible footer on bookmark count changes.
2021-01-29 00:20:15 +01:00
|
|
|
|
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 18:22:48 +01:00
|
|
|
-- Callback
|
|
|
|
|
--
|
2024-05-07 09:34:30 +03:00
|
|
|
self.menu:onMenuHold(self.entry, pos)
|
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 18:22:48 +01:00
|
|
|
|
|
|
|
|
UIManager:forceRePaint()
|
2017-10-10 23:50:45 +02:00
|
|
|
end
|
2014-03-13 21:52:43 +08:00
|
|
|
return true
|
2014-01-18 23:15:44 +08:00
|
|
|
end
|
|
|
|
|
|
2012-04-29 23:53:48 +08:00
|
|
|
--[[
|
|
|
|
|
Widget that displays menu
|
2012-12-07 23:30:15 +08: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 Menu = FocusManager:extend{
|
2014-03-13 21:52:43 +08:00
|
|
|
show_parent = nil,
|
|
|
|
|
|
2023-12-19 09:22:53 +02:00
|
|
|
no_title = false,
|
|
|
|
|
title = "",
|
FocusManager: Fix focus_flags check in moveFocusTo, and deal with the fallout (#12361)
* FocusManager: Fix `focus_flags` check in `moveFocusTo` (0 is truthy in Lua, can't do AND checks like in C ;).)
* FileManager+FileChooser: Pass our custom title bar directly to FileChooser (which also means we can now use FC's FocusManager layout directly).
* FileChooser/Menu: Get rid of the weird `outer_title_bar` hack, and simply take a `custom_title_bar` pointer to an actual TitleBar instance instead.
* FileManager/Menu/ListMenu/CoverMenu: Fix content height computations in `_recalculateDimen` (all the non-FM cases were including an old and now unused padding value, `self.header_padding`, leading to more blank space at the bottom than necessary, and, worse, leading to different item heights between FM views, possibly leading to unnecessary thumbnail scaling !)
* ButtonDialog: Proper focus management when the ButtonTable is wrapped in a ScrollableContainer.
* ConfigDialog: Implement a stupid workaround for a weird FocusManager issue when going back from `[⋮]` buttons.
* ConfigDialog: Don't move the visual focus in `update` (i.e., we use `NOT_FOCUS` now that it works as intended).
* DictQuickLookup: Ensures the `Menu` key bind does the exact same thing as the hamburger icon.
* DictQuickLookup: Ensure we refocus after having mangled the FocusManager layout (prevents an old focus highlight from lingering on the wrong button).
* FileChooser: Stop flagging it as no_title, because it is *never* without a title. (This behavior was a remnant of the previous FM-specific title bar hacks, which are no longer a thing).
* FileChooser: Stop calling `mergeTitleBarIntoLayout` twice in `updateItems`. We already call Menu's, which handles it. (Prevents the title bar from being added twice to the FocusManager layout).
* FocusManager: Relax the `Unfocus` checks in `moveFocusTo` to ensure we *always* unfocus something (if unfocusing was requested), even if we have to blast the whole widget tree to do so. This ensures callers that mangle self.layout can expect things to work after calling it regardless of how borked the current focus is.
* FocusManager: Allow passing `focus_flags` to `refocusWidget`, so that it can be forwarded to the internal `moveFocusTo` call.
* FocusManager: The above also allows us to enforce a default that ensures we do *not* send a Focus event on Touch devices, even if they have the hasDPad devcap. This essentially restores the previous/current behavior of not showing the visual feedback from such focus "events" sent programmatically, given the `focus_flags` check fix at the root of this PR ;).
* InputDialog: Fix numerous issues relating to double/ghost instances of both InputText and VirtualKeyboard, ensuring we only ever have a single InputText & VK instance live.
* InputDialog: Make sure every way we have of hiding the VK play nice together, especially when the `toggleKeyboard` button (shown w/ `add_nav_bar`) is at play. And doubly so when we're `fullscreen`, as hiding the VK implies resizing the widget.
* InputText: Make sure we're flagged as in-focus when tapping inside the text field.
* InputText: Make sure we don't attempt to show an already-visible VK in the custom `hasDPad` `onFocus` handler.
* Menu: Get rid of an old and no longer used (nor meaningful) hack in `onFocus` about the initial/programmatically-sent Focus event.
* Menu: Get rid of the unused `header_padding` field mentioned earlier in the FM/FC fixes.
* Menu: Use `FOCUS_ONLY_ON_NT` in the explicit `moveFocusTo` call in `updatePageInfo`, so as to keep the current behavior of not showing the visual feedback of this focus on Touch devices.
* Menu: Make sure *all* the `moveFocusTo` calls are gated behind the `hasDPad` devcap (previously, that was only the case for `updatePageInfo`, but not `mergeTitleBarIntoLayout` (which is called by `updateItems`).
* MultiInputDialog: Actively get rid of the InputText & VK instances from the base class's constructor that we do not use.
* MultiInputDialog: Ensure the FocusManager layout is *slightly* less broken (password fields can still be a bit weird, though).
* TextViewer: Get rid of the unfocus -> layout mangling -> refocus hack now that `refocusWidget` handles this case sanely.
* VirtualKeyboard: Notify our parent InputDialog when we get closed, so it can act accordingly (e.g., resize itself when `fullscreen`).
* ScrollableContainer: Implement the necessary machinery for focus handling inside ButtonDialog (specifically, when scrolling via PgUp/PgDwn).
* TextEditor: Given the above fixes, the plugin is no longer disabled on non-touch devices.
* ReaderBookMark: Make sure we request a full refresh when closing the "Edit note" dialog, as CRe highlights may extend past its dimensions, and if it's closed separately from VK, the refresh would have been limited to its own dimensions, leaving a neat InputDialog-sized hole in the highlights ;).
2024-08-25 19:34:31 +02:00
|
|
|
custom_title_bar = nil,
|
2023-12-19 09:22:53 +02:00
|
|
|
subtitle = nil,
|
|
|
|
|
show_path = nil, -- path in titlebar subtitle
|
2014-03-13 21:52:43 +08:00
|
|
|
-- default width and height
|
2017-09-11 10:32:39 +02:00
|
|
|
width = nil,
|
2014-03-13 21:52:43 +08:00
|
|
|
-- height will be calculated according to item number if not given
|
|
|
|
|
height = nil,
|
2021-04-15 02:46:44 +02:00
|
|
|
dimen = nil,
|
|
|
|
|
item_table = nil, -- NOT mandatory (will be empty)
|
2024-06-01 10:32:15 +03:00
|
|
|
item_table_stack = 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
|
|
|
item_shortcuts = { -- const
|
2014-03-13 21:52:43 +08:00
|
|
|
"Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
|
|
|
|
|
"A", "S", "D", "F", "G", "H", "J", "K", "L", "Del",
|
2018-03-30 23:22:18 +02:00
|
|
|
"Z", "X", "C", "V", "B", "N", "M", ".", "Sym",
|
2014-03-13 21:52:43 +08:00
|
|
|
},
|
2024-06-01 10:32:15 +03:00
|
|
|
is_enable_shortcut = Device:hasKeyboard(),
|
2014-03-13 21:52:43 +08:00
|
|
|
|
|
|
|
|
item_dimen = nil,
|
|
|
|
|
page = 1,
|
|
|
|
|
|
|
|
|
|
item_group = nil,
|
|
|
|
|
page_info = nil,
|
2014-09-05 21:07:21 +08:00
|
|
|
page_return = nil,
|
|
|
|
|
|
2021-02-04 17:43:52 +01:00
|
|
|
items_per_page_default = 14,
|
|
|
|
|
items_per_page = nil,
|
|
|
|
|
items_font_size = nil,
|
|
|
|
|
items_mandatory_font_size = nil,
|
|
|
|
|
multilines_show_more_text = nil,
|
FocusManager: Fix focus_flags check in moveFocusTo, and deal with the fallout (#12361)
* FocusManager: Fix `focus_flags` check in `moveFocusTo` (0 is truthy in Lua, can't do AND checks like in C ;).)
* FileManager+FileChooser: Pass our custom title bar directly to FileChooser (which also means we can now use FC's FocusManager layout directly).
* FileChooser/Menu: Get rid of the weird `outer_title_bar` hack, and simply take a `custom_title_bar` pointer to an actual TitleBar instance instead.
* FileManager/Menu/ListMenu/CoverMenu: Fix content height computations in `_recalculateDimen` (all the non-FM cases were including an old and now unused padding value, `self.header_padding`, leading to more blank space at the bottom than necessary, and, worse, leading to different item heights between FM views, possibly leading to unnecessary thumbnail scaling !)
* ButtonDialog: Proper focus management when the ButtonTable is wrapped in a ScrollableContainer.
* ConfigDialog: Implement a stupid workaround for a weird FocusManager issue when going back from `[⋮]` buttons.
* ConfigDialog: Don't move the visual focus in `update` (i.e., we use `NOT_FOCUS` now that it works as intended).
* DictQuickLookup: Ensures the `Menu` key bind does the exact same thing as the hamburger icon.
* DictQuickLookup: Ensure we refocus after having mangled the FocusManager layout (prevents an old focus highlight from lingering on the wrong button).
* FileChooser: Stop flagging it as no_title, because it is *never* without a title. (This behavior was a remnant of the previous FM-specific title bar hacks, which are no longer a thing).
* FileChooser: Stop calling `mergeTitleBarIntoLayout` twice in `updateItems`. We already call Menu's, which handles it. (Prevents the title bar from being added twice to the FocusManager layout).
* FocusManager: Relax the `Unfocus` checks in `moveFocusTo` to ensure we *always* unfocus something (if unfocusing was requested), even if we have to blast the whole widget tree to do so. This ensures callers that mangle self.layout can expect things to work after calling it regardless of how borked the current focus is.
* FocusManager: Allow passing `focus_flags` to `refocusWidget`, so that it can be forwarded to the internal `moveFocusTo` call.
* FocusManager: The above also allows us to enforce a default that ensures we do *not* send a Focus event on Touch devices, even if they have the hasDPad devcap. This essentially restores the previous/current behavior of not showing the visual feedback from such focus "events" sent programmatically, given the `focus_flags` check fix at the root of this PR ;).
* InputDialog: Fix numerous issues relating to double/ghost instances of both InputText and VirtualKeyboard, ensuring we only ever have a single InputText & VK instance live.
* InputDialog: Make sure every way we have of hiding the VK play nice together, especially when the `toggleKeyboard` button (shown w/ `add_nav_bar`) is at play. And doubly so when we're `fullscreen`, as hiding the VK implies resizing the widget.
* InputText: Make sure we're flagged as in-focus when tapping inside the text field.
* InputText: Make sure we don't attempt to show an already-visible VK in the custom `hasDPad` `onFocus` handler.
* Menu: Get rid of an old and no longer used (nor meaningful) hack in `onFocus` about the initial/programmatically-sent Focus event.
* Menu: Get rid of the unused `header_padding` field mentioned earlier in the FM/FC fixes.
* Menu: Use `FOCUS_ONLY_ON_NT` in the explicit `moveFocusTo` call in `updatePageInfo`, so as to keep the current behavior of not showing the visual feedback of this focus on Touch devices.
* Menu: Make sure *all* the `moveFocusTo` calls are gated behind the `hasDPad` devcap (previously, that was only the case for `updatePageInfo`, but not `mergeTitleBarIntoLayout` (which is called by `updateItems`).
* MultiInputDialog: Actively get rid of the InputText & VK instances from the base class's constructor that we do not use.
* MultiInputDialog: Ensure the FocusManager layout is *slightly* less broken (password fields can still be a bit weird, though).
* TextViewer: Get rid of the unfocus -> layout mangling -> refocus hack now that `refocusWidget` handles this case sanely.
* VirtualKeyboard: Notify our parent InputDialog when we get closed, so it can act accordingly (e.g., resize itself when `fullscreen`).
* ScrollableContainer: Implement the necessary machinery for focus handling inside ButtonDialog (specifically, when scrolling via PgUp/PgDwn).
* TextEditor: Given the above fixes, the plugin is no longer disabled on non-touch devices.
* ReaderBookMark: Make sure we request a full refresh when closing the "Edit note" dialog, as CRe highlights may extend past its dimensions, and if it's closed separately from VK, the refresh would have been limited to its own dimensions, leaving a neat InputDialog-sized hole in the highlights ;).
2024-08-25 19:34:31 +02:00
|
|
|
-- Global settings or default values will be used if not provided
|
2024-06-01 10:32:15 +03:00
|
|
|
-- Setting this to a number enables flexible height of items
|
|
|
|
|
-- and sets the maximum number of lines in an item, longer items are truncated
|
|
|
|
|
items_max_lines = nil,
|
2021-02-04 17:43:52 +01:00
|
|
|
|
2014-03-13 21:52:43 +08:00
|
|
|
-- set this to true to not paint as popup menu
|
|
|
|
|
is_borderless = false,
|
|
|
|
|
-- if you want to embed the menu widget into another widget, set
|
|
|
|
|
-- this to false
|
|
|
|
|
is_popout = true,
|
FocusManager: Fix focus_flags check in moveFocusTo, and deal with the fallout (#12361)
* FocusManager: Fix `focus_flags` check in `moveFocusTo` (0 is truthy in Lua, can't do AND checks like in C ;).)
* FileManager+FileChooser: Pass our custom title bar directly to FileChooser (which also means we can now use FC's FocusManager layout directly).
* FileChooser/Menu: Get rid of the weird `outer_title_bar` hack, and simply take a `custom_title_bar` pointer to an actual TitleBar instance instead.
* FileManager/Menu/ListMenu/CoverMenu: Fix content height computations in `_recalculateDimen` (all the non-FM cases were including an old and now unused padding value, `self.header_padding`, leading to more blank space at the bottom than necessary, and, worse, leading to different item heights between FM views, possibly leading to unnecessary thumbnail scaling !)
* ButtonDialog: Proper focus management when the ButtonTable is wrapped in a ScrollableContainer.
* ConfigDialog: Implement a stupid workaround for a weird FocusManager issue when going back from `[⋮]` buttons.
* ConfigDialog: Don't move the visual focus in `update` (i.e., we use `NOT_FOCUS` now that it works as intended).
* DictQuickLookup: Ensures the `Menu` key bind does the exact same thing as the hamburger icon.
* DictQuickLookup: Ensure we refocus after having mangled the FocusManager layout (prevents an old focus highlight from lingering on the wrong button).
* FileChooser: Stop flagging it as no_title, because it is *never* without a title. (This behavior was a remnant of the previous FM-specific title bar hacks, which are no longer a thing).
* FileChooser: Stop calling `mergeTitleBarIntoLayout` twice in `updateItems`. We already call Menu's, which handles it. (Prevents the title bar from being added twice to the FocusManager layout).
* FocusManager: Relax the `Unfocus` checks in `moveFocusTo` to ensure we *always* unfocus something (if unfocusing was requested), even if we have to blast the whole widget tree to do so. This ensures callers that mangle self.layout can expect things to work after calling it regardless of how borked the current focus is.
* FocusManager: Allow passing `focus_flags` to `refocusWidget`, so that it can be forwarded to the internal `moveFocusTo` call.
* FocusManager: The above also allows us to enforce a default that ensures we do *not* send a Focus event on Touch devices, even if they have the hasDPad devcap. This essentially restores the previous/current behavior of not showing the visual feedback from such focus "events" sent programmatically, given the `focus_flags` check fix at the root of this PR ;).
* InputDialog: Fix numerous issues relating to double/ghost instances of both InputText and VirtualKeyboard, ensuring we only ever have a single InputText & VK instance live.
* InputDialog: Make sure every way we have of hiding the VK play nice together, especially when the `toggleKeyboard` button (shown w/ `add_nav_bar`) is at play. And doubly so when we're `fullscreen`, as hiding the VK implies resizing the widget.
* InputText: Make sure we're flagged as in-focus when tapping inside the text field.
* InputText: Make sure we don't attempt to show an already-visible VK in the custom `hasDPad` `onFocus` handler.
* Menu: Get rid of an old and no longer used (nor meaningful) hack in `onFocus` about the initial/programmatically-sent Focus event.
* Menu: Get rid of the unused `header_padding` field mentioned earlier in the FM/FC fixes.
* Menu: Use `FOCUS_ONLY_ON_NT` in the explicit `moveFocusTo` call in `updatePageInfo`, so as to keep the current behavior of not showing the visual feedback of this focus on Touch devices.
* Menu: Make sure *all* the `moveFocusTo` calls are gated behind the `hasDPad` devcap (previously, that was only the case for `updatePageInfo`, but not `mergeTitleBarIntoLayout` (which is called by `updateItems`).
* MultiInputDialog: Actively get rid of the InputText & VK instances from the base class's constructor that we do not use.
* MultiInputDialog: Ensure the FocusManager layout is *slightly* less broken (password fields can still be a bit weird, though).
* TextViewer: Get rid of the unfocus -> layout mangling -> refocus hack now that `refocusWidget` handles this case sanely.
* VirtualKeyboard: Notify our parent InputDialog when we get closed, so it can act accordingly (e.g., resize itself when `fullscreen`).
* ScrollableContainer: Implement the necessary machinery for focus handling inside ButtonDialog (specifically, when scrolling via PgUp/PgDwn).
* TextEditor: Given the above fixes, the plugin is no longer disabled on non-touch devices.
* ReaderBookMark: Make sure we request a full refresh when closing the "Edit note" dialog, as CRe highlights may extend past its dimensions, and if it's closed separately from VK, the refresh would have been limited to its own dimensions, leaving a neat InputDialog-sized hole in the highlights ;).
2024-08-25 19:34:31 +02:00
|
|
|
title_bar_fm_style = nil, -- set to true to mimic FileManager's custom title bar (extra padding & subtitle)
|
2022-01-10 21:21:39 +02:00
|
|
|
-- set icon to add title bar left button
|
|
|
|
|
title_bar_left_icon = nil,
|
2014-03-13 21:52:43 +08:00
|
|
|
-- close_callback is a function, which is executed when menu is closed
|
|
|
|
|
-- it is usually set by the widget which creates the menu
|
2018-01-13 23:38:53 +01:00
|
|
|
close_callback = nil,
|
|
|
|
|
linesize = Size.line.medium,
|
2019-03-14 20:58:45 +01:00
|
|
|
line_color = Blitbuffer.COLOR_DARK_GRAY,
|
2012-04-29 23:53:48 +08:00
|
|
|
}
|
|
|
|
|
|
2025-03-19 08:01:09 +02:00
|
|
|
function Menu:getItemShortCutIcon(dimen, key, style)
|
|
|
|
|
return ItemShortCutIcon:new{
|
|
|
|
|
dimen = dimen,
|
|
|
|
|
key = key,
|
|
|
|
|
style = style,
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
|
2024-05-16 21:57:04 +03:00
|
|
|
function Menu:_recalculateDimen(no_recalculate_dimen)
|
|
|
|
|
local perpage = self.items_per_page or G_reader_settings:readSetting("items_per_page") or self.items_per_page_default
|
2024-06-01 10:32:15 +03:00
|
|
|
local font_size = self.items_font_size or G_reader_settings:readSetting("items_font_size") or Menu.getItemFontSize(perpage)
|
|
|
|
|
if self.perpage ~= perpage or self.font_size ~= font_size then
|
2024-05-16 21:57:04 +03:00
|
|
|
self.perpage = perpage
|
2024-06-01 10:32:15 +03:00
|
|
|
self.font_size = font_size
|
2024-05-16 21:57:04 +03:00
|
|
|
no_recalculate_dimen = false
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if no_recalculate_dimen then return end
|
2024-05-07 09:34:30 +03:00
|
|
|
|
2018-01-13 23:38:53 +01:00
|
|
|
local top_height = 0
|
2023-12-22 08:01:11 +02:00
|
|
|
if self.title_bar and not self.no_title then
|
2023-12-19 09:22:53 +02:00
|
|
|
top_height = self.title_bar:getHeight()
|
2018-01-13 23:38:53 +01:00
|
|
|
end
|
2024-05-07 09:34:30 +03:00
|
|
|
local bottom_height = 0
|
|
|
|
|
if self.page_return_arrow and self.page_info_text then
|
FocusManager: Fix focus_flags check in moveFocusTo, and deal with the fallout (#12361)
* FocusManager: Fix `focus_flags` check in `moveFocusTo` (0 is truthy in Lua, can't do AND checks like in C ;).)
* FileManager+FileChooser: Pass our custom title bar directly to FileChooser (which also means we can now use FC's FocusManager layout directly).
* FileChooser/Menu: Get rid of the weird `outer_title_bar` hack, and simply take a `custom_title_bar` pointer to an actual TitleBar instance instead.
* FileManager/Menu/ListMenu/CoverMenu: Fix content height computations in `_recalculateDimen` (all the non-FM cases were including an old and now unused padding value, `self.header_padding`, leading to more blank space at the bottom than necessary, and, worse, leading to different item heights between FM views, possibly leading to unnecessary thumbnail scaling !)
* ButtonDialog: Proper focus management when the ButtonTable is wrapped in a ScrollableContainer.
* ConfigDialog: Implement a stupid workaround for a weird FocusManager issue when going back from `[⋮]` buttons.
* ConfigDialog: Don't move the visual focus in `update` (i.e., we use `NOT_FOCUS` now that it works as intended).
* DictQuickLookup: Ensures the `Menu` key bind does the exact same thing as the hamburger icon.
* DictQuickLookup: Ensure we refocus after having mangled the FocusManager layout (prevents an old focus highlight from lingering on the wrong button).
* FileChooser: Stop flagging it as no_title, because it is *never* without a title. (This behavior was a remnant of the previous FM-specific title bar hacks, which are no longer a thing).
* FileChooser: Stop calling `mergeTitleBarIntoLayout` twice in `updateItems`. We already call Menu's, which handles it. (Prevents the title bar from being added twice to the FocusManager layout).
* FocusManager: Relax the `Unfocus` checks in `moveFocusTo` to ensure we *always* unfocus something (if unfocusing was requested), even if we have to blast the whole widget tree to do so. This ensures callers that mangle self.layout can expect things to work after calling it regardless of how borked the current focus is.
* FocusManager: Allow passing `focus_flags` to `refocusWidget`, so that it can be forwarded to the internal `moveFocusTo` call.
* FocusManager: The above also allows us to enforce a default that ensures we do *not* send a Focus event on Touch devices, even if they have the hasDPad devcap. This essentially restores the previous/current behavior of not showing the visual feedback from such focus "events" sent programmatically, given the `focus_flags` check fix at the root of this PR ;).
* InputDialog: Fix numerous issues relating to double/ghost instances of both InputText and VirtualKeyboard, ensuring we only ever have a single InputText & VK instance live.
* InputDialog: Make sure every way we have of hiding the VK play nice together, especially when the `toggleKeyboard` button (shown w/ `add_nav_bar`) is at play. And doubly so when we're `fullscreen`, as hiding the VK implies resizing the widget.
* InputText: Make sure we're flagged as in-focus when tapping inside the text field.
* InputText: Make sure we don't attempt to show an already-visible VK in the custom `hasDPad` `onFocus` handler.
* Menu: Get rid of an old and no longer used (nor meaningful) hack in `onFocus` about the initial/programmatically-sent Focus event.
* Menu: Get rid of the unused `header_padding` field mentioned earlier in the FM/FC fixes.
* Menu: Use `FOCUS_ONLY_ON_NT` in the explicit `moveFocusTo` call in `updatePageInfo`, so as to keep the current behavior of not showing the visual feedback of this focus on Touch devices.
* Menu: Make sure *all* the `moveFocusTo` calls are gated behind the `hasDPad` devcap (previously, that was only the case for `updatePageInfo`, but not `mergeTitleBarIntoLayout` (which is called by `updateItems`).
* MultiInputDialog: Actively get rid of the InputText & VK instances from the base class's constructor that we do not use.
* MultiInputDialog: Ensure the FocusManager layout is *slightly* less broken (password fields can still be a bit weird, though).
* TextViewer: Get rid of the unfocus -> layout mangling -> refocus hack now that `refocusWidget` handles this case sanely.
* VirtualKeyboard: Notify our parent InputDialog when we get closed, so it can act accordingly (e.g., resize itself when `fullscreen`).
* ScrollableContainer: Implement the necessary machinery for focus handling inside ButtonDialog (specifically, when scrolling via PgUp/PgDwn).
* TextEditor: Given the above fixes, the plugin is no longer disabled on non-touch devices.
* ReaderBookMark: Make sure we request a full refresh when closing the "Edit note" dialog, as CRe highlights may extend past its dimensions, and if it's closed separately from VK, the refresh would have been limited to its own dimensions, leaving a neat InputDialog-sized hole in the highlights ;).
2024-08-25 19:34:31 +02:00
|
|
|
-- The extra padding is for UX reasons only, to leave a bit of space above the footer.
|
2024-05-07 09:34:30 +03:00
|
|
|
bottom_height = math.max(self.page_return_arrow:getSize().h, self.page_info_text:getSize().h)
|
FocusManager: Fix focus_flags check in moveFocusTo, and deal with the fallout (#12361)
* FocusManager: Fix `focus_flags` check in `moveFocusTo` (0 is truthy in Lua, can't do AND checks like in C ;).)
* FileManager+FileChooser: Pass our custom title bar directly to FileChooser (which also means we can now use FC's FocusManager layout directly).
* FileChooser/Menu: Get rid of the weird `outer_title_bar` hack, and simply take a `custom_title_bar` pointer to an actual TitleBar instance instead.
* FileManager/Menu/ListMenu/CoverMenu: Fix content height computations in `_recalculateDimen` (all the non-FM cases were including an old and now unused padding value, `self.header_padding`, leading to more blank space at the bottom than necessary, and, worse, leading to different item heights between FM views, possibly leading to unnecessary thumbnail scaling !)
* ButtonDialog: Proper focus management when the ButtonTable is wrapped in a ScrollableContainer.
* ConfigDialog: Implement a stupid workaround for a weird FocusManager issue when going back from `[⋮]` buttons.
* ConfigDialog: Don't move the visual focus in `update` (i.e., we use `NOT_FOCUS` now that it works as intended).
* DictQuickLookup: Ensures the `Menu` key bind does the exact same thing as the hamburger icon.
* DictQuickLookup: Ensure we refocus after having mangled the FocusManager layout (prevents an old focus highlight from lingering on the wrong button).
* FileChooser: Stop flagging it as no_title, because it is *never* without a title. (This behavior was a remnant of the previous FM-specific title bar hacks, which are no longer a thing).
* FileChooser: Stop calling `mergeTitleBarIntoLayout` twice in `updateItems`. We already call Menu's, which handles it. (Prevents the title bar from being added twice to the FocusManager layout).
* FocusManager: Relax the `Unfocus` checks in `moveFocusTo` to ensure we *always* unfocus something (if unfocusing was requested), even if we have to blast the whole widget tree to do so. This ensures callers that mangle self.layout can expect things to work after calling it regardless of how borked the current focus is.
* FocusManager: Allow passing `focus_flags` to `refocusWidget`, so that it can be forwarded to the internal `moveFocusTo` call.
* FocusManager: The above also allows us to enforce a default that ensures we do *not* send a Focus event on Touch devices, even if they have the hasDPad devcap. This essentially restores the previous/current behavior of not showing the visual feedback from such focus "events" sent programmatically, given the `focus_flags` check fix at the root of this PR ;).
* InputDialog: Fix numerous issues relating to double/ghost instances of both InputText and VirtualKeyboard, ensuring we only ever have a single InputText & VK instance live.
* InputDialog: Make sure every way we have of hiding the VK play nice together, especially when the `toggleKeyboard` button (shown w/ `add_nav_bar`) is at play. And doubly so when we're `fullscreen`, as hiding the VK implies resizing the widget.
* InputText: Make sure we're flagged as in-focus when tapping inside the text field.
* InputText: Make sure we don't attempt to show an already-visible VK in the custom `hasDPad` `onFocus` handler.
* Menu: Get rid of an old and no longer used (nor meaningful) hack in `onFocus` about the initial/programmatically-sent Focus event.
* Menu: Get rid of the unused `header_padding` field mentioned earlier in the FM/FC fixes.
* Menu: Use `FOCUS_ONLY_ON_NT` in the explicit `moveFocusTo` call in `updatePageInfo`, so as to keep the current behavior of not showing the visual feedback of this focus on Touch devices.
* Menu: Make sure *all* the `moveFocusTo` calls are gated behind the `hasDPad` devcap (previously, that was only the case for `updatePageInfo`, but not `mergeTitleBarIntoLayout` (which is called by `updateItems`).
* MultiInputDialog: Actively get rid of the InputText & VK instances from the base class's constructor that we do not use.
* MultiInputDialog: Ensure the FocusManager layout is *slightly* less broken (password fields can still be a bit weird, though).
* TextViewer: Get rid of the unfocus -> layout mangling -> refocus hack now that `refocusWidget` handles this case sanely.
* VirtualKeyboard: Notify our parent InputDialog when we get closed, so it can act accordingly (e.g., resize itself when `fullscreen`).
* ScrollableContainer: Implement the necessary machinery for focus handling inside ButtonDialog (specifically, when scrolling via PgUp/PgDwn).
* TextEditor: Given the above fixes, the plugin is no longer disabled on non-touch devices.
* ReaderBookMark: Make sure we request a full refresh when closing the "Edit note" dialog, as CRe highlights may extend past its dimensions, and if it's closed separately from VK, the refresh would have been limited to its own dimensions, leaving a neat InputDialog-sized hole in the highlights ;).
2024-08-25 19:34:31 +02:00
|
|
|
+ Size.padding.button
|
2024-05-07 09:34:30 +03:00
|
|
|
end
|
|
|
|
|
self.available_height = self.inner_dimen.h - top_height - bottom_height
|
2021-06-29 15:41:45 +02:00
|
|
|
self.item_dimen = Geom:new{
|
2024-01-17 02:19:37 +01:00
|
|
|
x = 0, y = 0,
|
2021-06-29 15:41:45 +02:00
|
|
|
w = self.inner_dimen.w,
|
2024-05-16 21:57:04 +03:00
|
|
|
h = math.floor(self.available_height / perpage),
|
2021-06-29 15:41:45 +02:00
|
|
|
}
|
2024-05-07 09:34:30 +03:00
|
|
|
|
2024-06-01 10:32:15 +03:00
|
|
|
if self.items_max_lines then
|
|
|
|
|
self:setupItemHeights()
|
|
|
|
|
end
|
|
|
|
|
|
2024-05-07 09:34:30 +03:00
|
|
|
self.page_num = self:getPageNumber(#self.item_table)
|
|
|
|
|
if self.page > self.page_num then
|
|
|
|
|
self.page = self.page_num
|
|
|
|
|
end
|
2012-12-09 01:18:40 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function Menu:init()
|
2014-03-13 21:52:43 +08:00
|
|
|
self.show_parent = self.show_parent or self
|
2021-04-15 02:46:44 +02:00
|
|
|
self.item_table = self.item_table or {}
|
2014-03-13 21:52:43 +08:00
|
|
|
self.item_table_stack = {}
|
2024-05-07 09:34:30 +03:00
|
|
|
self.page = 1
|
2023-03-25 09:48:30 +02:00
|
|
|
|
|
|
|
|
self.screen_w = Screen:getWidth()
|
|
|
|
|
self.screen_h = Screen:getHeight()
|
|
|
|
|
self.dimen = Geom:new{ x = 0, y = 0, w = self.width or self.screen_w, h = self.height or self.screen_h }
|
|
|
|
|
if self.dimen.h > self.screen_h then
|
|
|
|
|
self.dimen.h = self.screen_h
|
2018-01-13 23:38:53 +01:00
|
|
|
end
|
[RFC] Pagination UI shenanigans (#7335)
* Menu/KeyValuePage/ReaderGoTo: Unify the dialogs. (Generally, "Enter page number" as title, and "Go to page" as OK button).
* Allow *tapping* on pagination buttons, too. Added spacers around the text to accommodate for that.
* Disable input handlers when <= 1 pages, while still printing the label in black.
* Always display both the label and the chevrons, even on single page content. (Menu being an exception, because it can handle showing no content at all, in which case we hide the chevrons).
* KVP: Tweak the pagination buttons layout in order to have consistent centering, regardless of whether the return arrow is enabled or not. (Also, match Menu's layout, more or less).
* Menu: Minor layout tweaks to follow the KVP tweaks above. Fixes, among possibly other things, buttons in (non-FM) "List" menus overlapping the final entry (e.g., OPDS), and popout menus with a border being misaligned (e.g., Calibre, Find a file).
* CalendarView: Minor layout tweaks to follow the KVP tweaks. Ensures the pagination buttons are laid out in the same way as everywhere else (they used to be a wee bit higher).
2021-02-25 05:15:23 +01:00
|
|
|
|
|
|
|
|
self.border_size = self.is_borderless and 0 or Size.border.window
|
|
|
|
|
self.inner_dimen = Geom:new{
|
|
|
|
|
w = self.dimen.w - 2 * self.border_size,
|
|
|
|
|
h = self.dimen.h - 2 * self.border_size,
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-23 00:24:16 +01:00
|
|
|
self.paths = {} -- per instance table to trace navigation path
|
|
|
|
|
|
2014-03-13 21:52:43 +08:00
|
|
|
-----------------------------------
|
|
|
|
|
-- start to set up widget layout --
|
|
|
|
|
-----------------------------------
|
2023-12-19 09:22:53 +02:00
|
|
|
if self.show_path or not self.no_title then
|
2024-05-07 09:34:30 +03:00
|
|
|
if self.subtitle == nil and (self.show_path or self.title_bar_fm_style) then
|
|
|
|
|
self.subtitle = ""
|
2023-12-19 09:22:53 +02:00
|
|
|
end
|
FocusManager: Fix focus_flags check in moveFocusTo, and deal with the fallout (#12361)
* FocusManager: Fix `focus_flags` check in `moveFocusTo` (0 is truthy in Lua, can't do AND checks like in C ;).)
* FileManager+FileChooser: Pass our custom title bar directly to FileChooser (which also means we can now use FC's FocusManager layout directly).
* FileChooser/Menu: Get rid of the weird `outer_title_bar` hack, and simply take a `custom_title_bar` pointer to an actual TitleBar instance instead.
* FileManager/Menu/ListMenu/CoverMenu: Fix content height computations in `_recalculateDimen` (all the non-FM cases were including an old and now unused padding value, `self.header_padding`, leading to more blank space at the bottom than necessary, and, worse, leading to different item heights between FM views, possibly leading to unnecessary thumbnail scaling !)
* ButtonDialog: Proper focus management when the ButtonTable is wrapped in a ScrollableContainer.
* ConfigDialog: Implement a stupid workaround for a weird FocusManager issue when going back from `[⋮]` buttons.
* ConfigDialog: Don't move the visual focus in `update` (i.e., we use `NOT_FOCUS` now that it works as intended).
* DictQuickLookup: Ensures the `Menu` key bind does the exact same thing as the hamburger icon.
* DictQuickLookup: Ensure we refocus after having mangled the FocusManager layout (prevents an old focus highlight from lingering on the wrong button).
* FileChooser: Stop flagging it as no_title, because it is *never* without a title. (This behavior was a remnant of the previous FM-specific title bar hacks, which are no longer a thing).
* FileChooser: Stop calling `mergeTitleBarIntoLayout` twice in `updateItems`. We already call Menu's, which handles it. (Prevents the title bar from being added twice to the FocusManager layout).
* FocusManager: Relax the `Unfocus` checks in `moveFocusTo` to ensure we *always* unfocus something (if unfocusing was requested), even if we have to blast the whole widget tree to do so. This ensures callers that mangle self.layout can expect things to work after calling it regardless of how borked the current focus is.
* FocusManager: Allow passing `focus_flags` to `refocusWidget`, so that it can be forwarded to the internal `moveFocusTo` call.
* FocusManager: The above also allows us to enforce a default that ensures we do *not* send a Focus event on Touch devices, even if they have the hasDPad devcap. This essentially restores the previous/current behavior of not showing the visual feedback from such focus "events" sent programmatically, given the `focus_flags` check fix at the root of this PR ;).
* InputDialog: Fix numerous issues relating to double/ghost instances of both InputText and VirtualKeyboard, ensuring we only ever have a single InputText & VK instance live.
* InputDialog: Make sure every way we have of hiding the VK play nice together, especially when the `toggleKeyboard` button (shown w/ `add_nav_bar`) is at play. And doubly so when we're `fullscreen`, as hiding the VK implies resizing the widget.
* InputText: Make sure we're flagged as in-focus when tapping inside the text field.
* InputText: Make sure we don't attempt to show an already-visible VK in the custom `hasDPad` `onFocus` handler.
* Menu: Get rid of an old and no longer used (nor meaningful) hack in `onFocus` about the initial/programmatically-sent Focus event.
* Menu: Get rid of the unused `header_padding` field mentioned earlier in the FM/FC fixes.
* Menu: Use `FOCUS_ONLY_ON_NT` in the explicit `moveFocusTo` call in `updatePageInfo`, so as to keep the current behavior of not showing the visual feedback of this focus on Touch devices.
* Menu: Make sure *all* the `moveFocusTo` calls are gated behind the `hasDPad` devcap (previously, that was only the case for `updatePageInfo`, but not `mergeTitleBarIntoLayout` (which is called by `updateItems`).
* MultiInputDialog: Actively get rid of the InputText & VK instances from the base class's constructor that we do not use.
* MultiInputDialog: Ensure the FocusManager layout is *slightly* less broken (password fields can still be a bit weird, though).
* TextViewer: Get rid of the unfocus -> layout mangling -> refocus hack now that `refocusWidget` handles this case sanely.
* VirtualKeyboard: Notify our parent InputDialog when we get closed, so it can act accordingly (e.g., resize itself when `fullscreen`).
* ScrollableContainer: Implement the necessary machinery for focus handling inside ButtonDialog (specifically, when scrolling via PgUp/PgDwn).
* TextEditor: Given the above fixes, the plugin is no longer disabled on non-touch devices.
* ReaderBookMark: Make sure we request a full refresh when closing the "Edit note" dialog, as CRe highlights may extend past its dimensions, and if it's closed separately from VK, the refresh would have been limited to its own dimensions, leaving a neat InputDialog-sized hole in the highlights ;).
2024-08-25 19:34:31 +02:00
|
|
|
self.title_bar = self.custom_title_bar or TitleBar:new{
|
2023-12-19 09:22:53 +02:00
|
|
|
width = self.dimen.w,
|
|
|
|
|
fullscreen = "true",
|
|
|
|
|
align = "center",
|
|
|
|
|
with_bottom_line = self.with_bottom_line,
|
|
|
|
|
bottom_line_color = self.bottom_line_color,
|
|
|
|
|
bottom_line_h_padding = self.bottom_line_h_padding,
|
|
|
|
|
title = self.title,
|
|
|
|
|
title_face = self.title_face,
|
|
|
|
|
title_multilines = self.title_multilines,
|
|
|
|
|
title_shrink_font_to_fit = self.title_shrink_font_to_fit,
|
|
|
|
|
subtitle = self.subtitle,
|
|
|
|
|
subtitle_truncate_left = self.show_path,
|
|
|
|
|
subtitle_fullwidth = self.show_path,
|
|
|
|
|
title_top_padding = self.title_bar_fm_style and Screen:scaleBySize(6),
|
|
|
|
|
button_padding = self.title_bar_fm_style and Screen:scaleBySize(5),
|
|
|
|
|
left_icon = self.title_bar_left_icon,
|
|
|
|
|
left_icon_size_ratio = self.title_bar_fm_style and 1,
|
|
|
|
|
left_icon_tap_callback = function() self:onLeftButtonTap() end,
|
|
|
|
|
left_icon_hold_callback = function() self:onLeftButtonHold() end,
|
|
|
|
|
right_icon_size_ratio = self.title_bar_fm_style and 1,
|
|
|
|
|
close_callback = function() self:onClose() end,
|
|
|
|
|
show_parent = self.show_parent or self,
|
|
|
|
|
}
|
|
|
|
|
end
|
2022-01-10 21:21:39 +02:00
|
|
|
|
2014-03-13 21:52:43 +08:00
|
|
|
-- group for items
|
|
|
|
|
self.item_group = VerticalGroup:new{}
|
|
|
|
|
-- group for page info
|
2020-12-19 12:18:30 +01:00
|
|
|
local chevron_left = "chevron.left"
|
|
|
|
|
local chevron_right = "chevron.right"
|
|
|
|
|
local chevron_first = "chevron.first"
|
|
|
|
|
local chevron_last = "chevron.last"
|
2019-12-06 22:55:39 +01:00
|
|
|
if BD.mirroredUILayout() then
|
|
|
|
|
chevron_left, chevron_right = chevron_right, chevron_left
|
|
|
|
|
chevron_first, chevron_last = chevron_last, chevron_first
|
|
|
|
|
end
|
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 01:51:09 +01:00
|
|
|
self.page_info_left_chev = self.page_info_left_chev or Button:new{
|
2019-12-06 22:55:39 +01:00
|
|
|
icon = chevron_left,
|
2014-03-13 21:52:43 +08:00
|
|
|
callback = function() self:onPrevPage() end,
|
|
|
|
|
bordersize = 0,
|
Enable HW dithering in a few key places (#4541)
* Enable HW dithering on supported devices (Clara HD, Forma; Oasis 2, PW4)
* FileManager and co. (where appropriate, i.e., when covers are shown)
* Book Status
* Reader, where appropriate:
* CRe: on pages whith image content (for over 7.5% of the screen area, should hopefully leave stuff like bullet points or small scene breaks alone).
* Other engines: on user-request (in the gear tab of the bottom menu), via the new "Dithering" knob (will only appear on supported devices).
* ScreenSaver
* ImageViewer
* Minimize repaints when flash_ui is enabled (by, almost everywhere, only repainting the flashing element, and not the toplevel window which hosts it).
(The first pass of this involved fixing a few Button instances whose show_parent was wrong, in particular, chevrons in the FM & TopMenu).
* Hunted down a few redundant repaints (unneeded setDirty("all") calls),
either by switching the widget to nil when only a refresh was needed, and not a repaint,
or by passing the appropritate widget to setDirty.
(Note to self: Enable *verbose* debugging to catch broken setDirty calls via its post guard).
There were also a few instances of 'em right behind a widget close.
* Don't repaint the underlying widget when initially showing TopMenu & ConfigDialog.
We unfortunately do need to do it when switching tabs, because of their variable heights.
* On Kobo, disabled the extra and completely useless full refresh before suspend/reboot/poweroff, as well as on resume. No more double refreshes!
* Fix another debug guard in Kobo sysfs_light
* Switch ImageWidget & ImageViewer mostly to "ui" updates, which will be better suited to image content pretty much everywhere, REAGL or not.
PS: (Almost :100: commits! :D)
2019-02-07 01:14:37 +01:00
|
|
|
show_parent = self.show_parent,
|
2014-03-13 21:52:43 +08:00
|
|
|
}
|
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 01:51:09 +01:00
|
|
|
self.page_info_right_chev = self.page_info_right_chev or Button:new{
|
2019-12-06 22:55:39 +01:00
|
|
|
icon = chevron_right,
|
2014-03-13 21:52:43 +08:00
|
|
|
callback = function() self:onNextPage() end,
|
|
|
|
|
bordersize = 0,
|
Enable HW dithering in a few key places (#4541)
* Enable HW dithering on supported devices (Clara HD, Forma; Oasis 2, PW4)
* FileManager and co. (where appropriate, i.e., when covers are shown)
* Book Status
* Reader, where appropriate:
* CRe: on pages whith image content (for over 7.5% of the screen area, should hopefully leave stuff like bullet points or small scene breaks alone).
* Other engines: on user-request (in the gear tab of the bottom menu), via the new "Dithering" knob (will only appear on supported devices).
* ScreenSaver
* ImageViewer
* Minimize repaints when flash_ui is enabled (by, almost everywhere, only repainting the flashing element, and not the toplevel window which hosts it).
(The first pass of this involved fixing a few Button instances whose show_parent was wrong, in particular, chevrons in the FM & TopMenu).
* Hunted down a few redundant repaints (unneeded setDirty("all") calls),
either by switching the widget to nil when only a refresh was needed, and not a repaint,
or by passing the appropritate widget to setDirty.
(Note to self: Enable *verbose* debugging to catch broken setDirty calls via its post guard).
There were also a few instances of 'em right behind a widget close.
* Don't repaint the underlying widget when initially showing TopMenu & ConfigDialog.
We unfortunately do need to do it when switching tabs, because of their variable heights.
* On Kobo, disabled the extra and completely useless full refresh before suspend/reboot/poweroff, as well as on resume. No more double refreshes!
* Fix another debug guard in Kobo sysfs_light
* Switch ImageWidget & ImageViewer mostly to "ui" updates, which will be better suited to image content pretty much everywhere, REAGL or not.
PS: (Almost :100: commits! :D)
2019-02-07 01:14:37 +01:00
|
|
|
show_parent = self.show_parent,
|
2014-03-13 21:52:43 +08:00
|
|
|
}
|
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 01:51:09 +01:00
|
|
|
self.page_info_first_chev = self.page_info_first_chev or Button:new{
|
2019-12-06 22:55:39 +01:00
|
|
|
icon = chevron_first,
|
2014-07-30 09:00:02 +02:00
|
|
|
callback = function() self:onFirstPage() end,
|
|
|
|
|
bordersize = 0,
|
Enable HW dithering in a few key places (#4541)
* Enable HW dithering on supported devices (Clara HD, Forma; Oasis 2, PW4)
* FileManager and co. (where appropriate, i.e., when covers are shown)
* Book Status
* Reader, where appropriate:
* CRe: on pages whith image content (for over 7.5% of the screen area, should hopefully leave stuff like bullet points or small scene breaks alone).
* Other engines: on user-request (in the gear tab of the bottom menu), via the new "Dithering" knob (will only appear on supported devices).
* ScreenSaver
* ImageViewer
* Minimize repaints when flash_ui is enabled (by, almost everywhere, only repainting the flashing element, and not the toplevel window which hosts it).
(The first pass of this involved fixing a few Button instances whose show_parent was wrong, in particular, chevrons in the FM & TopMenu).
* Hunted down a few redundant repaints (unneeded setDirty("all") calls),
either by switching the widget to nil when only a refresh was needed, and not a repaint,
or by passing the appropritate widget to setDirty.
(Note to self: Enable *verbose* debugging to catch broken setDirty calls via its post guard).
There were also a few instances of 'em right behind a widget close.
* Don't repaint the underlying widget when initially showing TopMenu & ConfigDialog.
We unfortunately do need to do it when switching tabs, because of their variable heights.
* On Kobo, disabled the extra and completely useless full refresh before suspend/reboot/poweroff, as well as on resume. No more double refreshes!
* Fix another debug guard in Kobo sysfs_light
* Switch ImageWidget & ImageViewer mostly to "ui" updates, which will be better suited to image content pretty much everywhere, REAGL or not.
PS: (Almost :100: commits! :D)
2019-02-07 01:14:37 +01:00
|
|
|
show_parent = self.show_parent,
|
2014-07-30 09:00:02 +02:00
|
|
|
}
|
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 01:51:09 +01:00
|
|
|
self.page_info_last_chev = self.page_info_last_chev or Button:new{
|
2019-12-06 22:55:39 +01:00
|
|
|
icon = chevron_last,
|
2014-07-30 09:00:02 +02:00
|
|
|
callback = function() self:onLastPage() end,
|
|
|
|
|
bordersize = 0,
|
Enable HW dithering in a few key places (#4541)
* Enable HW dithering on supported devices (Clara HD, Forma; Oasis 2, PW4)
* FileManager and co. (where appropriate, i.e., when covers are shown)
* Book Status
* Reader, where appropriate:
* CRe: on pages whith image content (for over 7.5% of the screen area, should hopefully leave stuff like bullet points or small scene breaks alone).
* Other engines: on user-request (in the gear tab of the bottom menu), via the new "Dithering" knob (will only appear on supported devices).
* ScreenSaver
* ImageViewer
* Minimize repaints when flash_ui is enabled (by, almost everywhere, only repainting the flashing element, and not the toplevel window which hosts it).
(The first pass of this involved fixing a few Button instances whose show_parent was wrong, in particular, chevrons in the FM & TopMenu).
* Hunted down a few redundant repaints (unneeded setDirty("all") calls),
either by switching the widget to nil when only a refresh was needed, and not a repaint,
or by passing the appropritate widget to setDirty.
(Note to self: Enable *verbose* debugging to catch broken setDirty calls via its post guard).
There were also a few instances of 'em right behind a widget close.
* Don't repaint the underlying widget when initially showing TopMenu & ConfigDialog.
We unfortunately do need to do it when switching tabs, because of their variable heights.
* On Kobo, disabled the extra and completely useless full refresh before suspend/reboot/poweroff, as well as on resume. No more double refreshes!
* Fix another debug guard in Kobo sysfs_light
* Switch ImageWidget & ImageViewer mostly to "ui" updates, which will be better suited to image content pretty much everywhere, REAGL or not.
PS: (Almost :100: commits! :D)
2019-02-07 01:14:37 +01:00
|
|
|
show_parent = self.show_parent,
|
2014-08-05 17:41:36 +02:00
|
|
|
}
|
2014-09-05 21:07:21 +08:00
|
|
|
self.page_info_spacer = HorizontalSpan:new{
|
2014-11-20 23:07:39 +01:00
|
|
|
width = Screen:scaleBySize(32),
|
2014-07-30 09:00:02 +02:00
|
|
|
}
|
2014-03-13 21:52:43 +08:00
|
|
|
self.page_info_left_chev:hide()
|
|
|
|
|
self.page_info_right_chev:hide()
|
2014-07-30 09:00:02 +02:00
|
|
|
self.page_info_first_chev:hide()
|
|
|
|
|
self.page_info_last_chev:hide()
|
|
|
|
|
|
2018-02-09 22:33:15 +01:00
|
|
|
local buttons = {
|
|
|
|
|
{
|
|
|
|
|
{
|
2025-03-16 08:03:14 +02:00
|
|
|
text = self.search_callback and _("Search…") or _("Search"),
|
2018-02-09 22:33:15 +01:00
|
|
|
callback = function()
|
2025-03-16 08:03:14 +02:00
|
|
|
local search_string = self.page_info_text.input_dialog:getInputText()
|
|
|
|
|
if self.search_callback then
|
|
|
|
|
self.search_callback(search_string)
|
|
|
|
|
self.page_info_text:closeInputDialog()
|
|
|
|
|
else
|
|
|
|
|
if search_string ~= "" then
|
|
|
|
|
self:goToMenuItemMatching(search_string)
|
|
|
|
|
self.page_info_text:closeInputDialog()
|
|
|
|
|
end
|
|
|
|
|
end
|
2018-02-09 22:33:15 +01:00
|
|
|
end,
|
|
|
|
|
},
|
|
|
|
|
{
|
2025-03-16 08:03:14 +02:00
|
|
|
text = _("Go to letter"),
|
2018-02-09 22:33:15 +01:00
|
|
|
callback = function()
|
2025-03-16 08:03:14 +02:00
|
|
|
local search_string = self.page_info_text.input_dialog:getInputText()
|
|
|
|
|
if search_string ~= "" then
|
|
|
|
|
self:goToMenuItemMatching(search_string, true)
|
2021-04-11 01:08:29 +03:00
|
|
|
self.page_info_text:closeInputDialog()
|
2018-02-09 22:33:15 +01:00
|
|
|
end
|
|
|
|
|
end,
|
|
|
|
|
},
|
|
|
|
|
},
|
2025-03-16 08:03:14 +02:00
|
|
|
{
|
2021-08-14 22:29:25 +03:00
|
|
|
{
|
2025-03-16 08:03:14 +02:00
|
|
|
text = _("Cancel"),
|
|
|
|
|
id = "close",
|
2021-08-14 22:29:25 +03:00
|
|
|
callback = function()
|
|
|
|
|
self.page_info_text:closeInputDialog()
|
|
|
|
|
end,
|
|
|
|
|
},
|
|
|
|
|
{
|
2025-03-16 08:03:14 +02:00
|
|
|
text = _("Go to page"),
|
2021-08-14 22:29:25 +03:00
|
|
|
callback = function()
|
2025-03-16 08:03:14 +02:00
|
|
|
local page = tonumber(self.page_info_text.input_dialog:getInputText())
|
|
|
|
|
if page and page >= 1 and page <= self.page_num then
|
|
|
|
|
self:onGotoPage(page)
|
|
|
|
|
self.page_info_text:closeInputDialog()
|
2018-02-09 22:33:15 +01:00
|
|
|
end
|
2021-08-14 22:29:25 +03:00
|
|
|
end,
|
|
|
|
|
},
|
2025-03-16 08:03:14 +02:00
|
|
|
},
|
|
|
|
|
}
|
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 01:51:09 +01:00
|
|
|
self.page_info_text = self.page_info_text or Button:new{
|
2014-03-13 21:52:43 +08:00
|
|
|
text = "",
|
2025-03-16 08:03:14 +02:00
|
|
|
text_font_bold = false,
|
|
|
|
|
bordersize = 0,
|
|
|
|
|
call_hold_input_on_tap = true,
|
2015-04-13 14:45:02 +08:00
|
|
|
hold_input = {
|
2025-03-16 08:03:14 +02:00
|
|
|
title = _("Enter text, letter or page number"),
|
|
|
|
|
hint_func = function()
|
|
|
|
|
-- @translators First group is the standard range for alphabetic searches, second group is a page number range
|
|
|
|
|
return T(_("(a - z) or (1 - %1)"), self.page_num)
|
|
|
|
|
end,
|
2018-02-09 22:33:15 +01:00
|
|
|
buttons = buttons,
|
2015-04-13 14:45:02 +08:00
|
|
|
},
|
2014-03-13 21:52:43 +08:00
|
|
|
}
|
|
|
|
|
self.page_info = HorizontalGroup:new{
|
2014-07-30 09:00:02 +02:00
|
|
|
self.page_info_first_chev,
|
2014-08-05 17:41:36 +02:00
|
|
|
self.page_info_spacer,
|
2014-03-13 21:52:43 +08:00
|
|
|
self.page_info_left_chev,
|
[RFC] Pagination UI shenanigans (#7335)
* Menu/KeyValuePage/ReaderGoTo: Unify the dialogs. (Generally, "Enter page number" as title, and "Go to page" as OK button).
* Allow *tapping* on pagination buttons, too. Added spacers around the text to accommodate for that.
* Disable input handlers when <= 1 pages, while still printing the label in black.
* Always display both the label and the chevrons, even on single page content. (Menu being an exception, because it can handle showing no content at all, in which case we hide the chevrons).
* KVP: Tweak the pagination buttons layout in order to have consistent centering, regardless of whether the return arrow is enabled or not. (Also, match Menu's layout, more or less).
* Menu: Minor layout tweaks to follow the KVP tweaks above. Fixes, among possibly other things, buttons in (non-FM) "List" menus overlapping the final entry (e.g., OPDS), and popout menus with a border being misaligned (e.g., Calibre, Find a file).
* CalendarView: Minor layout tweaks to follow the KVP tweaks. Ensures the pagination buttons are laid out in the same way as everywhere else (they used to be a wee bit higher).
2021-02-25 05:15:23 +01:00
|
|
|
self.page_info_spacer,
|
2014-03-13 21:52:43 +08:00
|
|
|
self.page_info_text,
|
[RFC] Pagination UI shenanigans (#7335)
* Menu/KeyValuePage/ReaderGoTo: Unify the dialogs. (Generally, "Enter page number" as title, and "Go to page" as OK button).
* Allow *tapping* on pagination buttons, too. Added spacers around the text to accommodate for that.
* Disable input handlers when <= 1 pages, while still printing the label in black.
* Always display both the label and the chevrons, even on single page content. (Menu being an exception, because it can handle showing no content at all, in which case we hide the chevrons).
* KVP: Tweak the pagination buttons layout in order to have consistent centering, regardless of whether the return arrow is enabled or not. (Also, match Menu's layout, more or less).
* Menu: Minor layout tweaks to follow the KVP tweaks above. Fixes, among possibly other things, buttons in (non-FM) "List" menus overlapping the final entry (e.g., OPDS), and popout menus with a border being misaligned (e.g., Calibre, Find a file).
* CalendarView: Minor layout tweaks to follow the KVP tweaks. Ensures the pagination buttons are laid out in the same way as everywhere else (they used to be a wee bit higher).
2021-02-25 05:15:23 +01:00
|
|
|
self.page_info_spacer,
|
2014-07-30 09:00:02 +02:00
|
|
|
self.page_info_right_chev,
|
2014-08-05 17:41:36 +02:00
|
|
|
self.page_info_spacer,
|
2014-07-30 09:00:02 +02:00
|
|
|
self.page_info_last_chev,
|
2014-03-13 21:52:43 +08:00
|
|
|
}
|
|
|
|
|
|
2014-09-05 21:07:21 +08:00
|
|
|
-- return button
|
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 01:51:09 +01:00
|
|
|
self.page_return_arrow = self.page_return_arrow or Button:new{
|
2020-12-19 12:18:30 +01:00
|
|
|
icon = "back.top",
|
2018-11-14 20:58:56 +01:00
|
|
|
callback = function()
|
|
|
|
|
if self.onReturn then self:onReturn() end
|
|
|
|
|
end,
|
2021-06-29 11:22:03 +03:00
|
|
|
hold_callback = function()
|
|
|
|
|
if self.onHoldReturn then self:onHoldReturn() end
|
|
|
|
|
end,
|
2014-09-05 21:07:21 +08:00
|
|
|
bordersize = 0,
|
Enable HW dithering in a few key places (#4541)
* Enable HW dithering on supported devices (Clara HD, Forma; Oasis 2, PW4)
* FileManager and co. (where appropriate, i.e., when covers are shown)
* Book Status
* Reader, where appropriate:
* CRe: on pages whith image content (for over 7.5% of the screen area, should hopefully leave stuff like bullet points or small scene breaks alone).
* Other engines: on user-request (in the gear tab of the bottom menu), via the new "Dithering" knob (will only appear on supported devices).
* ScreenSaver
* ImageViewer
* Minimize repaints when flash_ui is enabled (by, almost everywhere, only repainting the flashing element, and not the toplevel window which hosts it).
(The first pass of this involved fixing a few Button instances whose show_parent was wrong, in particular, chevrons in the FM & TopMenu).
* Hunted down a few redundant repaints (unneeded setDirty("all") calls),
either by switching the widget to nil when only a refresh was needed, and not a repaint,
or by passing the appropritate widget to setDirty.
(Note to self: Enable *verbose* debugging to catch broken setDirty calls via its post guard).
There were also a few instances of 'em right behind a widget close.
* Don't repaint the underlying widget when initially showing TopMenu & ConfigDialog.
We unfortunately do need to do it when switching tabs, because of their variable heights.
* On Kobo, disabled the extra and completely useless full refresh before suspend/reboot/poweroff, as well as on resume. No more double refreshes!
* Fix another debug guard in Kobo sysfs_light
* Switch ImageWidget & ImageViewer mostly to "ui" updates, which will be better suited to image content pretty much everywhere, REAGL or not.
PS: (Almost :100: commits! :D)
2019-02-07 01:14:37 +01:00
|
|
|
show_parent = self.show_parent,
|
2018-09-29 23:15:57 +02:00
|
|
|
readonly = self.return_arrow_propagation,
|
2014-09-05 21:07:21 +08:00
|
|
|
}
|
|
|
|
|
self.page_return_arrow:hide()
|
|
|
|
|
self.return_button = HorizontalGroup:new{
|
|
|
|
|
HorizontalSpan:new{
|
2017-09-13 16:56:20 +02:00
|
|
|
width = Size.span.horizontal_small,
|
2014-09-05 21:07:21 +08:00
|
|
|
},
|
|
|
|
|
self.page_return_arrow,
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-10 21:21:39 +02:00
|
|
|
local header = self.no_title and VerticalSpan:new{ width = 0 } or self.title_bar
|
2014-03-13 21:52:43 +08:00
|
|
|
local body = self.item_group
|
|
|
|
|
local footer = BottomContainer:new{
|
[RFC] Pagination UI shenanigans (#7335)
* Menu/KeyValuePage/ReaderGoTo: Unify the dialogs. (Generally, "Enter page number" as title, and "Go to page" as OK button).
* Allow *tapping* on pagination buttons, too. Added spacers around the text to accommodate for that.
* Disable input handlers when <= 1 pages, while still printing the label in black.
* Always display both the label and the chevrons, even on single page content. (Menu being an exception, because it can handle showing no content at all, in which case we hide the chevrons).
* KVP: Tweak the pagination buttons layout in order to have consistent centering, regardless of whether the return arrow is enabled or not. (Also, match Menu's layout, more or less).
* Menu: Minor layout tweaks to follow the KVP tweaks above. Fixes, among possibly other things, buttons in (non-FM) "List" menus overlapping the final entry (e.g., OPDS), and popout menus with a border being misaligned (e.g., Calibre, Find a file).
* CalendarView: Minor layout tweaks to follow the KVP tweaks. Ensures the pagination buttons are laid out in the same way as everywhere else (they used to be a wee bit higher).
2021-02-25 05:15:23 +01:00
|
|
|
dimen = self.inner_dimen:copy(),
|
2014-03-13 21:52:43 +08:00
|
|
|
self.page_info,
|
|
|
|
|
}
|
2014-09-05 21:07:21 +08:00
|
|
|
local page_return = BottomContainer:new{
|
[RFC] Pagination UI shenanigans (#7335)
* Menu/KeyValuePage/ReaderGoTo: Unify the dialogs. (Generally, "Enter page number" as title, and "Go to page" as OK button).
* Allow *tapping* on pagination buttons, too. Added spacers around the text to accommodate for that.
* Disable input handlers when <= 1 pages, while still printing the label in black.
* Always display both the label and the chevrons, even on single page content. (Menu being an exception, because it can handle showing no content at all, in which case we hide the chevrons).
* KVP: Tweak the pagination buttons layout in order to have consistent centering, regardless of whether the return arrow is enabled or not. (Also, match Menu's layout, more or less).
* Menu: Minor layout tweaks to follow the KVP tweaks above. Fixes, among possibly other things, buttons in (non-FM) "List" menus overlapping the final entry (e.g., OPDS), and popout menus with a border being misaligned (e.g., Calibre, Find a file).
* CalendarView: Minor layout tweaks to follow the KVP tweaks. Ensures the pagination buttons are laid out in the same way as everywhere else (they used to be a wee bit higher).
2021-02-25 05:15:23 +01:00
|
|
|
dimen = self.inner_dimen:copy(),
|
2014-09-05 21:07:21 +08:00
|
|
|
WidgetContainer:new{
|
|
|
|
|
dimen = Geom:new{
|
2024-01-17 02:19:37 +01:00
|
|
|
x = 0, y = 0,
|
2023-03-25 09:48:30 +02:00
|
|
|
w = self.screen_w,
|
2014-09-05 21:07:21 +08:00
|
|
|
h = self.page_return_arrow:getSize().h,
|
|
|
|
|
},
|
|
|
|
|
self.return_button,
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-03-13 21:52:43 +08:00
|
|
|
|
2018-01-13 23:38:53 +01:00
|
|
|
self:_recalculateDimen()
|
2022-01-10 21:21:39 +02:00
|
|
|
self.content_group = VerticalGroup:new{
|
|
|
|
|
align = "left",
|
|
|
|
|
header,
|
|
|
|
|
body,
|
|
|
|
|
}
|
2018-01-13 23:38:53 +01:00
|
|
|
local content = OverlapGroup:new{
|
2019-12-06 22:55:39 +01:00
|
|
|
-- This unique allow_mirroring=false looks like it's enough
|
|
|
|
|
-- to have this complex Menu, and all widgets based on it,
|
|
|
|
|
-- be mirrored correctly with RTL languages
|
|
|
|
|
allow_mirroring = false,
|
[RFC] Pagination UI shenanigans (#7335)
* Menu/KeyValuePage/ReaderGoTo: Unify the dialogs. (Generally, "Enter page number" as title, and "Go to page" as OK button).
* Allow *tapping* on pagination buttons, too. Added spacers around the text to accommodate for that.
* Disable input handlers when <= 1 pages, while still printing the label in black.
* Always display both the label and the chevrons, even on single page content. (Menu being an exception, because it can handle showing no content at all, in which case we hide the chevrons).
* KVP: Tweak the pagination buttons layout in order to have consistent centering, regardless of whether the return arrow is enabled or not. (Also, match Menu's layout, more or less).
* Menu: Minor layout tweaks to follow the KVP tweaks above. Fixes, among possibly other things, buttons in (non-FM) "List" menus overlapping the final entry (e.g., OPDS), and popout menus with a border being misaligned (e.g., Calibre, Find a file).
* CalendarView: Minor layout tweaks to follow the KVP tweaks. Ensures the pagination buttons are laid out in the same way as everywhere else (they used to be a wee bit higher).
2021-02-25 05:15:23 +01:00
|
|
|
dimen = self.inner_dimen:copy(),
|
2018-01-13 23:38:53 +01:00
|
|
|
self.content_group,
|
|
|
|
|
page_return,
|
|
|
|
|
footer,
|
|
|
|
|
}
|
2014-03-13 21:52:43 +08:00
|
|
|
|
|
|
|
|
self[1] = FrameContainer:new{
|
2014-10-22 15:34:11 +02:00
|
|
|
background = Blitbuffer.COLOR_WHITE,
|
[RFC] Pagination UI shenanigans (#7335)
* Menu/KeyValuePage/ReaderGoTo: Unify the dialogs. (Generally, "Enter page number" as title, and "Go to page" as OK button).
* Allow *tapping* on pagination buttons, too. Added spacers around the text to accommodate for that.
* Disable input handlers when <= 1 pages, while still printing the label in black.
* Always display both the label and the chevrons, even on single page content. (Menu being an exception, because it can handle showing no content at all, in which case we hide the chevrons).
* KVP: Tweak the pagination buttons layout in order to have consistent centering, regardless of whether the return arrow is enabled or not. (Also, match Menu's layout, more or less).
* Menu: Minor layout tweaks to follow the KVP tweaks above. Fixes, among possibly other things, buttons in (non-FM) "List" menus overlapping the final entry (e.g., OPDS), and popout menus with a border being misaligned (e.g., Calibre, Find a file).
* CalendarView: Minor layout tweaks to follow the KVP tweaks. Ensures the pagination buttons are laid out in the same way as everywhere else (they used to be a wee bit higher).
2021-02-25 05:15:23 +01:00
|
|
|
bordersize = self.border_size,
|
2014-03-13 21:52:43 +08:00
|
|
|
padding = 0,
|
|
|
|
|
margin = 0,
|
2022-10-10 22:21:27 +02:00
|
|
|
radius = self.is_popout and math.floor(self.dimen.w * (1/20)) or 0,
|
2014-03-13 21:52:43 +08:00
|
|
|
content
|
|
|
|
|
}
|
2021-04-15 19:07:34 +02:00
|
|
|
|
2014-03-13 21:52:43 +08:00
|
|
|
------------------------------------------
|
|
|
|
|
-- start to set up input event callback --
|
|
|
|
|
------------------------------------------
|
2022-03-05 04:20:00 +08:00
|
|
|
-- watch for outer region if it's a self contained widget
|
|
|
|
|
if self.is_popout then
|
|
|
|
|
self.ges_events.TapCloseAllMenus = {
|
|
|
|
|
GestureRange:new{
|
|
|
|
|
ges = "tap",
|
|
|
|
|
range = Geom:new{
|
|
|
|
|
x = 0, y = 0,
|
2023-03-25 09:48:30 +02:00
|
|
|
w = self.screen_w,
|
|
|
|
|
h = self.screen_h,
|
2014-03-13 21:52:43 +08:00
|
|
|
}
|
|
|
|
|
}
|
2022-03-05 04:20:00 +08:00
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
-- delegate swipe gesture to GestureManager in filemanager
|
2025-03-24 19:12:46 +02:00
|
|
|
if self.name ~= "filemanager" then
|
2022-03-05 04:20:00 +08:00
|
|
|
self.ges_events.Swipe = {
|
|
|
|
|
GestureRange:new{
|
|
|
|
|
ges = "swipe",
|
|
|
|
|
range = self.dimen,
|
2014-03-13 21:52:43 +08:00
|
|
|
}
|
2022-03-05 04:20:00 +08:00
|
|
|
}
|
|
|
|
|
self.ges_events.MultiSwipe = {
|
|
|
|
|
GestureRange:new{
|
|
|
|
|
ges = "multiswipe",
|
|
|
|
|
range = self.dimen,
|
2022-01-25 15:24:06 +01:00
|
|
|
}
|
2022-03-05 04:20:00 +08:00
|
|
|
}
|
2014-03-13 21:52:43 +08:00
|
|
|
end
|
2024-03-09 09:11:23 +01:00
|
|
|
self.ges_events.Pan = { -- (for mousewheel scrolling support)
|
|
|
|
|
GestureRange:new{
|
|
|
|
|
ges = "pan",
|
|
|
|
|
range = self.dimen,
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-05 04:20:00 +08:00
|
|
|
self.ges_events.Close = self.on_close_ges
|
2014-09-03 12:09:25 +08:00
|
|
|
|
2014-06-10 15:57:10 +08:00
|
|
|
if Device:hasKeys() then
|
2014-03-13 21:52:43 +08:00
|
|
|
-- set up keyboard events
|
2022-10-27 02:01:51 +02:00
|
|
|
self.key_events.Close = { { Input.group.Back } }
|
2024-06-05 07:07:03 +01:00
|
|
|
self.key_events.LeftButtonTap = { { "Menu" } }
|
2020-06-04 13:26:18 +02:00
|
|
|
if Device:hasFewKeys() then
|
2022-10-27 02:01:51 +02:00
|
|
|
self.key_events.Close = { { "Left" } }
|
2020-06-04 13:26:18 +02:00
|
|
|
end
|
2022-10-27 02:01:51 +02:00
|
|
|
self.key_events.NextPage = { { Input.group.PgFwd } }
|
|
|
|
|
self.key_events.PrevPage = { { Input.group.PgBack } }
|
2024-06-21 17:07:10 +01:00
|
|
|
if Device:hasKeyboard() then
|
|
|
|
|
self.key_events.FirstPage = { { "Shift", { "LPgBack", "RPgBack" } } }
|
|
|
|
|
self.key_events.LastPage = { { "Shift", { "LPgFwd", "RPgFwd" } } }
|
|
|
|
|
self.key_events.ShowGotoDialog = { { "Shift", "Down" } }
|
|
|
|
|
elseif Device:hasScreenKB() then
|
|
|
|
|
self.key_events.FirstPage = { { "ScreenKB", { "LPgBack", "RPgBack" } } }
|
|
|
|
|
self.key_events.LastPage = { { "ScreenKB", { "LPgFwd", "RPgFwd" } } }
|
|
|
|
|
self.key_events.ShowGotoDialog = { { "ScreenKB", "Down" } }
|
|
|
|
|
end
|
A few graphics fixes after #4541 (#4554)
* Various FocusManager related tweaks to limit its usage to devices with a DPad, and prevent initial button highlights in Dialogs on devices where it makes no sense (i.e., those without a DPad. And even on DPad devices, I'm not even sure how we'd go about making one of those pop up anyway, because no Touch ;)!).
* One mysterious fix to text-only Buttons so that the flash_ui highlight always works, and always honors `FrameContainer`'s pill shape. (Before that, an unhighlight on a text button with a callback that didn't repaint anything [say, the find first/find last buttons in the Reader's search bar when you're already on the first/last match] would do a square black highlight, and a white pill-shaped unhighlight (leaving the black corners visible)).
The workaround makes *absolutely* no sense to me (as `self[1] -> self.frame`, AFAICT), but it works, and ensures all highlights/unhighlights are pill-shaped, so at least we're not doing maths for rounded corners for nothing ;).
2019-02-08 00:56:32 +01:00
|
|
|
end
|
|
|
|
|
|
2024-05-24 16:34:08 +02:00
|
|
|
if Device:hasDPad() then
|
2024-05-26 14:33:06 +01:00
|
|
|
if Device:hasFewKeys() then
|
2024-05-25 10:11:53 +01:00
|
|
|
-- we won't catch presses to "Right", leave that to MenuItem.
|
|
|
|
|
self.key_events.FocusRight = nil
|
|
|
|
|
-- add long press on "Right" key
|
|
|
|
|
self.key_events.Right = { { "Right" } }
|
|
|
|
|
end
|
2014-03-13 21:52:43 +08:00
|
|
|
-- shortcut icon is not needed for touch device
|
|
|
|
|
if self.is_enable_shortcut then
|
2022-10-27 02:01:51 +02:00
|
|
|
self.key_events.SelectByShortCut = { { self.item_shortcuts } }
|
2014-03-13 21:52:43 +08:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2024-05-07 09:34:30 +03:00
|
|
|
if self.item_table.current then
|
|
|
|
|
self.page = self:getPageNumber(self.item_table.current)
|
2017-01-10 19:02:46 +01:00
|
|
|
end
|
2024-05-07 09:34:30 +03:00
|
|
|
if not self.path_items then -- not FileChooser
|
|
|
|
|
self:updateItems(1, true)
|
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
|
|
|
end
|
2014-12-01 16:21:42 +00:00
|
|
|
end
|
|
|
|
|
|
2018-04-06 11:53:11 +02:00
|
|
|
function Menu:updatePageInfo(select_number)
|
2022-03-12 12:30:26 +02:00
|
|
|
if #self.item_table > 0 then
|
2024-10-13 18:02:51 +03:00
|
|
|
local is_focused = self.itemnumber and self.itemnumber > 0
|
|
|
|
|
if is_focused or Device:hasDPad() then
|
2025-05-22 18:00:35 +03:00
|
|
|
self.prev_itemnumber = self.itemnumber -- for CoverBrowser
|
2024-10-13 18:02:51 +03:00
|
|
|
self.itemnumber = nil -- focus only once
|
|
|
|
|
select_number = select_number or 1 -- default to select the first item
|
|
|
|
|
local x, y
|
|
|
|
|
local nb_cols = self.layout[1] and #self.layout[1] or 1
|
|
|
|
|
if nb_cols == 1 then
|
|
|
|
|
x = 1
|
|
|
|
|
y = select_number
|
|
|
|
|
else -- mosaic
|
|
|
|
|
x = select_number % nb_cols
|
2024-10-30 20:09:59 +02:00
|
|
|
x = x ~= 0 and x or nb_cols
|
2024-10-13 18:02:51 +03:00
|
|
|
y = (select_number - x) / nb_cols + 1
|
|
|
|
|
end
|
FocusManager: Fix focus_flags check in moveFocusTo, and deal with the fallout (#12361)
* FocusManager: Fix `focus_flags` check in `moveFocusTo` (0 is truthy in Lua, can't do AND checks like in C ;).)
* FileManager+FileChooser: Pass our custom title bar directly to FileChooser (which also means we can now use FC's FocusManager layout directly).
* FileChooser/Menu: Get rid of the weird `outer_title_bar` hack, and simply take a `custom_title_bar` pointer to an actual TitleBar instance instead.
* FileManager/Menu/ListMenu/CoverMenu: Fix content height computations in `_recalculateDimen` (all the non-FM cases were including an old and now unused padding value, `self.header_padding`, leading to more blank space at the bottom than necessary, and, worse, leading to different item heights between FM views, possibly leading to unnecessary thumbnail scaling !)
* ButtonDialog: Proper focus management when the ButtonTable is wrapped in a ScrollableContainer.
* ConfigDialog: Implement a stupid workaround for a weird FocusManager issue when going back from `[⋮]` buttons.
* ConfigDialog: Don't move the visual focus in `update` (i.e., we use `NOT_FOCUS` now that it works as intended).
* DictQuickLookup: Ensures the `Menu` key bind does the exact same thing as the hamburger icon.
* DictQuickLookup: Ensure we refocus after having mangled the FocusManager layout (prevents an old focus highlight from lingering on the wrong button).
* FileChooser: Stop flagging it as no_title, because it is *never* without a title. (This behavior was a remnant of the previous FM-specific title bar hacks, which are no longer a thing).
* FileChooser: Stop calling `mergeTitleBarIntoLayout` twice in `updateItems`. We already call Menu's, which handles it. (Prevents the title bar from being added twice to the FocusManager layout).
* FocusManager: Relax the `Unfocus` checks in `moveFocusTo` to ensure we *always* unfocus something (if unfocusing was requested), even if we have to blast the whole widget tree to do so. This ensures callers that mangle self.layout can expect things to work after calling it regardless of how borked the current focus is.
* FocusManager: Allow passing `focus_flags` to `refocusWidget`, so that it can be forwarded to the internal `moveFocusTo` call.
* FocusManager: The above also allows us to enforce a default that ensures we do *not* send a Focus event on Touch devices, even if they have the hasDPad devcap. This essentially restores the previous/current behavior of not showing the visual feedback from such focus "events" sent programmatically, given the `focus_flags` check fix at the root of this PR ;).
* InputDialog: Fix numerous issues relating to double/ghost instances of both InputText and VirtualKeyboard, ensuring we only ever have a single InputText & VK instance live.
* InputDialog: Make sure every way we have of hiding the VK play nice together, especially when the `toggleKeyboard` button (shown w/ `add_nav_bar`) is at play. And doubly so when we're `fullscreen`, as hiding the VK implies resizing the widget.
* InputText: Make sure we're flagged as in-focus when tapping inside the text field.
* InputText: Make sure we don't attempt to show an already-visible VK in the custom `hasDPad` `onFocus` handler.
* Menu: Get rid of an old and no longer used (nor meaningful) hack in `onFocus` about the initial/programmatically-sent Focus event.
* Menu: Get rid of the unused `header_padding` field mentioned earlier in the FM/FC fixes.
* Menu: Use `FOCUS_ONLY_ON_NT` in the explicit `moveFocusTo` call in `updatePageInfo`, so as to keep the current behavior of not showing the visual feedback of this focus on Touch devices.
* Menu: Make sure *all* the `moveFocusTo` calls are gated behind the `hasDPad` devcap (previously, that was only the case for `updatePageInfo`, but not `mergeTitleBarIntoLayout` (which is called by `updateItems`).
* MultiInputDialog: Actively get rid of the InputText & VK instances from the base class's constructor that we do not use.
* MultiInputDialog: Ensure the FocusManager layout is *slightly* less broken (password fields can still be a bit weird, though).
* TextViewer: Get rid of the unfocus -> layout mangling -> refocus hack now that `refocusWidget` handles this case sanely.
* VirtualKeyboard: Notify our parent InputDialog when we get closed, so it can act accordingly (e.g., resize itself when `fullscreen`).
* ScrollableContainer: Implement the necessary machinery for focus handling inside ButtonDialog (specifically, when scrolling via PgUp/PgDwn).
* TextEditor: Given the above fixes, the plugin is no longer disabled on non-touch devices.
* ReaderBookMark: Make sure we request a full refresh when closing the "Edit note" dialog, as CRe highlights may extend past its dimensions, and if it's closed separately from VK, the refresh would have been limited to its own dimensions, leaving a neat InputDialog-sized hole in the highlights ;).
2024-08-25 19:34:31 +02:00
|
|
|
-- Reset focus manager accordingly.
|
|
|
|
|
-- NOTE: Since this runs automatically on init,
|
|
|
|
|
-- we use FOCUS_ONLY_ON_NT as we don't want to see the initial underline on Touch devices.
|
2024-10-13 18:02:51 +03:00
|
|
|
self:moveFocusTo(x, y, is_focused and FocusManager.FORCED_FOCUS or FocusManager.FOCUS_ONLY_ON_NT)
|
2018-04-06 11:53:11 +02:00
|
|
|
end
|
|
|
|
|
-- update page information
|
2023-03-25 09:48:30 +02:00
|
|
|
self.page_info_text:setText(T(_("Page %1 of %2"), self.page, self.page_num))
|
2019-10-21 22:54:29 +10:30
|
|
|
if self.page_num > 1 then
|
2021-02-20 18:35:57 +01:00
|
|
|
self.page_info_text:enable()
|
2019-10-21 22:54:29 +10:30
|
|
|
else
|
[RFC] Pagination UI shenanigans (#7335)
* Menu/KeyValuePage/ReaderGoTo: Unify the dialogs. (Generally, "Enter page number" as title, and "Go to page" as OK button).
* Allow *tapping* on pagination buttons, too. Added spacers around the text to accommodate for that.
* Disable input handlers when <= 1 pages, while still printing the label in black.
* Always display both the label and the chevrons, even on single page content. (Menu being an exception, because it can handle showing no content at all, in which case we hide the chevrons).
* KVP: Tweak the pagination buttons layout in order to have consistent centering, regardless of whether the return arrow is enabled or not. (Also, match Menu's layout, more or less).
* Menu: Minor layout tweaks to follow the KVP tweaks above. Fixes, among possibly other things, buttons in (non-FM) "List" menus overlapping the final entry (e.g., OPDS), and popout menus with a border being misaligned (e.g., Calibre, Find a file).
* CalendarView: Minor layout tweaks to follow the KVP tweaks. Ensures the pagination buttons are laid out in the same way as everywhere else (they used to be a wee bit higher).
2021-02-25 05:15:23 +01:00
|
|
|
self.page_info_text:disableWithoutDimming()
|
2019-10-21 22:54:29 +10:30
|
|
|
end
|
[RFC] Pagination UI shenanigans (#7335)
* Menu/KeyValuePage/ReaderGoTo: Unify the dialogs. (Generally, "Enter page number" as title, and "Go to page" as OK button).
* Allow *tapping* on pagination buttons, too. Added spacers around the text to accommodate for that.
* Disable input handlers when <= 1 pages, while still printing the label in black.
* Always display both the label and the chevrons, even on single page content. (Menu being an exception, because it can handle showing no content at all, in which case we hide the chevrons).
* KVP: Tweak the pagination buttons layout in order to have consistent centering, regardless of whether the return arrow is enabled or not. (Also, match Menu's layout, more or less).
* Menu: Minor layout tweaks to follow the KVP tweaks above. Fixes, among possibly other things, buttons in (non-FM) "List" menus overlapping the final entry (e.g., OPDS), and popout menus with a border being misaligned (e.g., Calibre, Find a file).
* CalendarView: Minor layout tweaks to follow the KVP tweaks. Ensures the pagination buttons are laid out in the same way as everywhere else (they used to be a wee bit higher).
2021-02-25 05:15:23 +01:00
|
|
|
self.page_info_left_chev:show()
|
|
|
|
|
self.page_info_right_chev:show()
|
|
|
|
|
self.page_info_first_chev:show()
|
|
|
|
|
self.page_info_last_chev:show()
|
2018-04-06 11:53:11 +02:00
|
|
|
self.page_return_arrow:showHide(self.onReturn ~= nil)
|
|
|
|
|
|
|
|
|
|
self.page_info_left_chev:enableDisable(self.page > 1)
|
|
|
|
|
self.page_info_right_chev:enableDisable(self.page < self.page_num)
|
|
|
|
|
self.page_info_first_chev:enableDisable(self.page > 1)
|
|
|
|
|
self.page_info_last_chev:enableDisable(self.page < self.page_num)
|
|
|
|
|
self.page_return_arrow:enableDisable(#self.paths > 0)
|
|
|
|
|
else
|
2021-02-26 23:04:11 +01:00
|
|
|
self.page_info_text:setText(_("No items"))
|
[RFC] Pagination UI shenanigans (#7335)
* Menu/KeyValuePage/ReaderGoTo: Unify the dialogs. (Generally, "Enter page number" as title, and "Go to page" as OK button).
* Allow *tapping* on pagination buttons, too. Added spacers around the text to accommodate for that.
* Disable input handlers when <= 1 pages, while still printing the label in black.
* Always display both the label and the chevrons, even on single page content. (Menu being an exception, because it can handle showing no content at all, in which case we hide the chevrons).
* KVP: Tweak the pagination buttons layout in order to have consistent centering, regardless of whether the return arrow is enabled or not. (Also, match Menu's layout, more or less).
* Menu: Minor layout tweaks to follow the KVP tweaks above. Fixes, among possibly other things, buttons in (non-FM) "List" menus overlapping the final entry (e.g., OPDS), and popout menus with a border being misaligned (e.g., Calibre, Find a file).
* CalendarView: Minor layout tweaks to follow the KVP tweaks. Ensures the pagination buttons are laid out in the same way as everywhere else (they used to be a wee bit higher).
2021-02-25 05:15:23 +01:00
|
|
|
self.page_info_text:disableWithoutDimming()
|
2021-03-07 23:27:04 +01:00
|
|
|
|
|
|
|
|
self.page_info_left_chev:hide()
|
|
|
|
|
self.page_info_right_chev:hide()
|
|
|
|
|
self.page_info_first_chev:hide()
|
|
|
|
|
self.page_info_last_chev:hide()
|
|
|
|
|
self.page_return_arrow:showHide(self.onReturn ~= nil)
|
2018-04-06 11:53:11 +02:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2024-05-07 09:34:30 +03:00
|
|
|
function Menu:updateItems(select_number, no_recalculate_dimen)
|
2014-11-30 12:04:33 +00:00
|
|
|
local old_dimen = self.dimen and self.dimen:copy()
|
2014-03-13 21:52:43 +08:00
|
|
|
-- self.layout must be updated for focusmanager
|
|
|
|
|
self.layout = {}
|
|
|
|
|
self.item_group:clear()
|
|
|
|
|
self.page_info:resetLayout()
|
2014-09-05 21:07:21 +08:00
|
|
|
self.return_button:resetLayout()
|
2018-01-13 23:38:53 +01:00
|
|
|
self.content_group:resetLayout()
|
2024-05-16 21:57:04 +03:00
|
|
|
self:_recalculateDimen(no_recalculate_dimen)
|
2021-02-04 17:43:52 +01:00
|
|
|
|
2024-06-01 10:32:15 +03:00
|
|
|
local items_nb -- number of items in the visible page
|
|
|
|
|
local idx_offset, multilines_show_more_text
|
|
|
|
|
if self.items_max_lines then
|
|
|
|
|
items_nb = #self.page_items[self.page]
|
|
|
|
|
else
|
|
|
|
|
items_nb = self.perpage
|
|
|
|
|
idx_offset = (self.page - 1) * items_nb
|
|
|
|
|
multilines_show_more_text = self.multilines_show_more_text
|
|
|
|
|
if multilines_show_more_text == nil then
|
|
|
|
|
multilines_show_more_text = G_reader_settings:isTrue("items_multilines_show_more_text")
|
|
|
|
|
end
|
2021-02-04 17:43:52 +01:00
|
|
|
end
|
2014-03-13 21:52:43 +08:00
|
|
|
|
2024-06-01 10:32:15 +03:00
|
|
|
for idx = 1, items_nb do
|
|
|
|
|
local index = self.items_max_lines and self.page_items[self.page][idx] or idx_offset + idx
|
2024-05-07 09:34:30 +03:00
|
|
|
local item = self.item_table[index]
|
|
|
|
|
if item == nil then break end
|
|
|
|
|
item.idx = index -- index is valid only for items that have been displayed
|
2024-10-13 18:02:51 +03:00
|
|
|
if index == self.itemnumber then -- focused item
|
|
|
|
|
select_number = idx
|
|
|
|
|
end
|
2024-05-07 09:34:30 +03:00
|
|
|
local item_shortcut, shortcut_style
|
|
|
|
|
if self.is_enable_shortcut then
|
|
|
|
|
item_shortcut = self.item_shortcuts[idx]
|
|
|
|
|
-- give different shortcut_style to keys in different lines of keyboard
|
|
|
|
|
shortcut_style = (idx < 11 or idx > 20) and "square" or "grey_square"
|
|
|
|
|
end
|
2024-06-01 10:32:15 +03:00
|
|
|
if self.items_max_lines then
|
|
|
|
|
self.item_dimen.h = item.height
|
|
|
|
|
end
|
2024-05-07 09:34:30 +03:00
|
|
|
local item_tmp = MenuItem:new{
|
2024-08-06 19:12:16 +03:00
|
|
|
idx = index,
|
2024-05-07 09:34:30 +03:00
|
|
|
show_parent = self.show_parent,
|
|
|
|
|
state_w = self.state_w,
|
|
|
|
|
text = Menu.getMenuText(item),
|
|
|
|
|
bidi_wrap_func = item.bidi_wrap_func,
|
|
|
|
|
post_text = item.post_text,
|
|
|
|
|
mandatory = item.mandatory,
|
|
|
|
|
mandatory_func = item.mandatory_func,
|
|
|
|
|
mandatory_dim = item.mandatory_dim or item.dim,
|
2024-08-06 19:12:16 +03:00
|
|
|
mandatory_dim_func = item.mandatory_dim_func,
|
2024-05-07 09:34:30 +03:00
|
|
|
bold = self.item_table.current == index or item.bold == true,
|
|
|
|
|
dim = item.dim,
|
|
|
|
|
font_size = self.font_size,
|
2024-06-01 10:32:15 +03:00
|
|
|
infont_size = self.items_mandatory_font_size or (self.font_size - 4),
|
2024-05-07 09:34:30 +03:00
|
|
|
dimen = self.item_dimen:copy(),
|
|
|
|
|
shortcut = item_shortcut,
|
|
|
|
|
shortcut_style = shortcut_style,
|
|
|
|
|
entry = item,
|
|
|
|
|
menu = self,
|
|
|
|
|
linesize = self.linesize,
|
|
|
|
|
single_line = self.single_line,
|
2024-12-27 08:27:13 +02:00
|
|
|
multilines_forced = self.multilines_forced,
|
2024-05-07 09:34:30 +03:00
|
|
|
multilines_show_more_text = multilines_show_more_text,
|
2024-08-06 19:12:16 +03:00
|
|
|
items_max_lines = self.items_max_lines,
|
2024-05-07 09:34:30 +03:00
|
|
|
truncate_left = self.truncate_left,
|
|
|
|
|
align_baselines = self.align_baselines,
|
|
|
|
|
with_dots = self.with_dots,
|
|
|
|
|
line_color = self.line_color,
|
|
|
|
|
items_padding = self.items_padding,
|
|
|
|
|
handle_hold_on_hold_release = self.handle_hold_on_hold_release,
|
|
|
|
|
}
|
|
|
|
|
table.insert(self.item_group, item_tmp)
|
|
|
|
|
-- this is for focus manager
|
|
|
|
|
table.insert(self.layout, {item_tmp})
|
|
|
|
|
end
|
2014-07-30 09:00:02 +02:00
|
|
|
|
2018-04-06 11:53:11 +02:00
|
|
|
self:updatePageInfo(select_number)
|
2022-05-06 16:44:25 +08:00
|
|
|
self:mergeTitleBarIntoLayout()
|
2014-03-13 21:52:43 +08:00
|
|
|
|
Enable HW dithering in a few key places (#4541)
* Enable HW dithering on supported devices (Clara HD, Forma; Oasis 2, PW4)
* FileManager and co. (where appropriate, i.e., when covers are shown)
* Book Status
* Reader, where appropriate:
* CRe: on pages whith image content (for over 7.5% of the screen area, should hopefully leave stuff like bullet points or small scene breaks alone).
* Other engines: on user-request (in the gear tab of the bottom menu), via the new "Dithering" knob (will only appear on supported devices).
* ScreenSaver
* ImageViewer
* Minimize repaints when flash_ui is enabled (by, almost everywhere, only repainting the flashing element, and not the toplevel window which hosts it).
(The first pass of this involved fixing a few Button instances whose show_parent was wrong, in particular, chevrons in the FM & TopMenu).
* Hunted down a few redundant repaints (unneeded setDirty("all") calls),
either by switching the widget to nil when only a refresh was needed, and not a repaint,
or by passing the appropritate widget to setDirty.
(Note to self: Enable *verbose* debugging to catch broken setDirty calls via its post guard).
There were also a few instances of 'em right behind a widget close.
* Don't repaint the underlying widget when initially showing TopMenu & ConfigDialog.
We unfortunately do need to do it when switching tabs, because of their variable heights.
* On Kobo, disabled the extra and completely useless full refresh before suspend/reboot/poweroff, as well as on resume. No more double refreshes!
* Fix another debug guard in Kobo sysfs_light
* Switch ImageWidget & ImageViewer mostly to "ui" updates, which will be better suited to image content pretty much everywhere, REAGL or not.
PS: (Almost :100: commits! :D)
2019-02-07 01:14:37 +01:00
|
|
|
UIManager:setDirty(self.show_parent, function()
|
2014-11-30 12:04:33 +00:00
|
|
|
local refresh_dimen =
|
|
|
|
|
old_dimen and old_dimen:combine(self.dimen)
|
|
|
|
|
or self.dimen
|
2015-04-26 20:10:18 +02:00
|
|
|
return "ui", refresh_dimen
|
2014-11-30 12:04:33 +00:00
|
|
|
end)
|
2012-04-29 23:53:48 +08:00
|
|
|
end
|
|
|
|
|
|
2022-05-06 16:44:25 +08:00
|
|
|
-- merge TitleBar layout into self FocusManager layout
|
|
|
|
|
function Menu:mergeTitleBarIntoLayout()
|
2025-06-13 07:42:08 +03:00
|
|
|
if not self.title_bar then return end
|
2024-08-13 07:43:40 +01:00
|
|
|
if Device:hasSymKey() or Device:hasScreenKB() then
|
|
|
|
|
-- Title bar items can be accessed through key mappings on kindle
|
|
|
|
|
return
|
|
|
|
|
end
|
FocusManager: Fix focus_flags check in moveFocusTo, and deal with the fallout (#12361)
* FocusManager: Fix `focus_flags` check in `moveFocusTo` (0 is truthy in Lua, can't do AND checks like in C ;).)
* FileManager+FileChooser: Pass our custom title bar directly to FileChooser (which also means we can now use FC's FocusManager layout directly).
* FileChooser/Menu: Get rid of the weird `outer_title_bar` hack, and simply take a `custom_title_bar` pointer to an actual TitleBar instance instead.
* FileManager/Menu/ListMenu/CoverMenu: Fix content height computations in `_recalculateDimen` (all the non-FM cases were including an old and now unused padding value, `self.header_padding`, leading to more blank space at the bottom than necessary, and, worse, leading to different item heights between FM views, possibly leading to unnecessary thumbnail scaling !)
* ButtonDialog: Proper focus management when the ButtonTable is wrapped in a ScrollableContainer.
* ConfigDialog: Implement a stupid workaround for a weird FocusManager issue when going back from `[⋮]` buttons.
* ConfigDialog: Don't move the visual focus in `update` (i.e., we use `NOT_FOCUS` now that it works as intended).
* DictQuickLookup: Ensures the `Menu` key bind does the exact same thing as the hamburger icon.
* DictQuickLookup: Ensure we refocus after having mangled the FocusManager layout (prevents an old focus highlight from lingering on the wrong button).
* FileChooser: Stop flagging it as no_title, because it is *never* without a title. (This behavior was a remnant of the previous FM-specific title bar hacks, which are no longer a thing).
* FileChooser: Stop calling `mergeTitleBarIntoLayout` twice in `updateItems`. We already call Menu's, which handles it. (Prevents the title bar from being added twice to the FocusManager layout).
* FocusManager: Relax the `Unfocus` checks in `moveFocusTo` to ensure we *always* unfocus something (if unfocusing was requested), even if we have to blast the whole widget tree to do so. This ensures callers that mangle self.layout can expect things to work after calling it regardless of how borked the current focus is.
* FocusManager: Allow passing `focus_flags` to `refocusWidget`, so that it can be forwarded to the internal `moveFocusTo` call.
* FocusManager: The above also allows us to enforce a default that ensures we do *not* send a Focus event on Touch devices, even if they have the hasDPad devcap. This essentially restores the previous/current behavior of not showing the visual feedback from such focus "events" sent programmatically, given the `focus_flags` check fix at the root of this PR ;).
* InputDialog: Fix numerous issues relating to double/ghost instances of both InputText and VirtualKeyboard, ensuring we only ever have a single InputText & VK instance live.
* InputDialog: Make sure every way we have of hiding the VK play nice together, especially when the `toggleKeyboard` button (shown w/ `add_nav_bar`) is at play. And doubly so when we're `fullscreen`, as hiding the VK implies resizing the widget.
* InputText: Make sure we're flagged as in-focus when tapping inside the text field.
* InputText: Make sure we don't attempt to show an already-visible VK in the custom `hasDPad` `onFocus` handler.
* Menu: Get rid of an old and no longer used (nor meaningful) hack in `onFocus` about the initial/programmatically-sent Focus event.
* Menu: Get rid of the unused `header_padding` field mentioned earlier in the FM/FC fixes.
* Menu: Use `FOCUS_ONLY_ON_NT` in the explicit `moveFocusTo` call in `updatePageInfo`, so as to keep the current behavior of not showing the visual feedback of this focus on Touch devices.
* Menu: Make sure *all* the `moveFocusTo` calls are gated behind the `hasDPad` devcap (previously, that was only the case for `updatePageInfo`, but not `mergeTitleBarIntoLayout` (which is called by `updateItems`).
* MultiInputDialog: Actively get rid of the InputText & VK instances from the base class's constructor that we do not use.
* MultiInputDialog: Ensure the FocusManager layout is *slightly* less broken (password fields can still be a bit weird, though).
* TextViewer: Get rid of the unfocus -> layout mangling -> refocus hack now that `refocusWidget` handles this case sanely.
* VirtualKeyboard: Notify our parent InputDialog when we get closed, so it can act accordingly (e.g., resize itself when `fullscreen`).
* ScrollableContainer: Implement the necessary machinery for focus handling inside ButtonDialog (specifically, when scrolling via PgUp/PgDwn).
* TextEditor: Given the above fixes, the plugin is no longer disabled on non-touch devices.
* ReaderBookMark: Make sure we request a full refresh when closing the "Edit note" dialog, as CRe highlights may extend past its dimensions, and if it's closed separately from VK, the refresh would have been limited to its own dimensions, leaving a neat InputDialog-sized hole in the highlights ;).
2024-08-25 19:34:31 +02:00
|
|
|
-- On hasFewKeys devices, Menu uses the "Right" key to trigger the context menu: we can't use it to move focus in horizontal directions.
|
|
|
|
|
-- So, add title bar buttons to FocusManager's layout in a vertical-only layout
|
|
|
|
|
local title_bar_layout = self.title_bar:generateVerticalLayout()
|
2024-10-21 13:35:44 +02:00
|
|
|
for i, row in ipairs(title_bar_layout) do
|
|
|
|
|
-- Insert the title bar in the top rows of our layout
|
|
|
|
|
table.insert(self.layout, i, row)
|
FocusManager: Fix focus_flags check in moveFocusTo, and deal with the fallout (#12361)
* FocusManager: Fix `focus_flags` check in `moveFocusTo` (0 is truthy in Lua, can't do AND checks like in C ;).)
* FileManager+FileChooser: Pass our custom title bar directly to FileChooser (which also means we can now use FC's FocusManager layout directly).
* FileChooser/Menu: Get rid of the weird `outer_title_bar` hack, and simply take a `custom_title_bar` pointer to an actual TitleBar instance instead.
* FileManager/Menu/ListMenu/CoverMenu: Fix content height computations in `_recalculateDimen` (all the non-FM cases were including an old and now unused padding value, `self.header_padding`, leading to more blank space at the bottom than necessary, and, worse, leading to different item heights between FM views, possibly leading to unnecessary thumbnail scaling !)
* ButtonDialog: Proper focus management when the ButtonTable is wrapped in a ScrollableContainer.
* ConfigDialog: Implement a stupid workaround for a weird FocusManager issue when going back from `[⋮]` buttons.
* ConfigDialog: Don't move the visual focus in `update` (i.e., we use `NOT_FOCUS` now that it works as intended).
* DictQuickLookup: Ensures the `Menu` key bind does the exact same thing as the hamburger icon.
* DictQuickLookup: Ensure we refocus after having mangled the FocusManager layout (prevents an old focus highlight from lingering on the wrong button).
* FileChooser: Stop flagging it as no_title, because it is *never* without a title. (This behavior was a remnant of the previous FM-specific title bar hacks, which are no longer a thing).
* FileChooser: Stop calling `mergeTitleBarIntoLayout` twice in `updateItems`. We already call Menu's, which handles it. (Prevents the title bar from being added twice to the FocusManager layout).
* FocusManager: Relax the `Unfocus` checks in `moveFocusTo` to ensure we *always* unfocus something (if unfocusing was requested), even if we have to blast the whole widget tree to do so. This ensures callers that mangle self.layout can expect things to work after calling it regardless of how borked the current focus is.
* FocusManager: Allow passing `focus_flags` to `refocusWidget`, so that it can be forwarded to the internal `moveFocusTo` call.
* FocusManager: The above also allows us to enforce a default that ensures we do *not* send a Focus event on Touch devices, even if they have the hasDPad devcap. This essentially restores the previous/current behavior of not showing the visual feedback from such focus "events" sent programmatically, given the `focus_flags` check fix at the root of this PR ;).
* InputDialog: Fix numerous issues relating to double/ghost instances of both InputText and VirtualKeyboard, ensuring we only ever have a single InputText & VK instance live.
* InputDialog: Make sure every way we have of hiding the VK play nice together, especially when the `toggleKeyboard` button (shown w/ `add_nav_bar`) is at play. And doubly so when we're `fullscreen`, as hiding the VK implies resizing the widget.
* InputText: Make sure we're flagged as in-focus when tapping inside the text field.
* InputText: Make sure we don't attempt to show an already-visible VK in the custom `hasDPad` `onFocus` handler.
* Menu: Get rid of an old and no longer used (nor meaningful) hack in `onFocus` about the initial/programmatically-sent Focus event.
* Menu: Get rid of the unused `header_padding` field mentioned earlier in the FM/FC fixes.
* Menu: Use `FOCUS_ONLY_ON_NT` in the explicit `moveFocusTo` call in `updatePageInfo`, so as to keep the current behavior of not showing the visual feedback of this focus on Touch devices.
* Menu: Make sure *all* the `moveFocusTo` calls are gated behind the `hasDPad` devcap (previously, that was only the case for `updatePageInfo`, but not `mergeTitleBarIntoLayout` (which is called by `updateItems`).
* MultiInputDialog: Actively get rid of the InputText & VK instances from the base class's constructor that we do not use.
* MultiInputDialog: Ensure the FocusManager layout is *slightly* less broken (password fields can still be a bit weird, though).
* TextViewer: Get rid of the unfocus -> layout mangling -> refocus hack now that `refocusWidget` handles this case sanely.
* VirtualKeyboard: Notify our parent InputDialog when we get closed, so it can act accordingly (e.g., resize itself when `fullscreen`).
* ScrollableContainer: Implement the necessary machinery for focus handling inside ButtonDialog (specifically, when scrolling via PgUp/PgDwn).
* TextEditor: Given the above fixes, the plugin is no longer disabled on non-touch devices.
* ReaderBookMark: Make sure we request a full refresh when closing the "Edit note" dialog, as CRe highlights may extend past its dimensions, and if it's closed separately from VK, the refresh would have been limited to its own dimensions, leaving a neat InputDialog-sized hole in the highlights ;).
2024-08-25 19:34:31 +02:00
|
|
|
end
|
2024-10-21 13:35:44 +02:00
|
|
|
-- Adjust for the added rows to keep our current selection
|
|
|
|
|
self.selected.y = self.selected.y + #title_bar_layout
|
|
|
|
|
logger.dbg("Menu:mergeTitleBarIntoLayout: Adjusted focus position to account for added titlebar rows:", self.selected.x, ",", self.selected.y)
|
2022-05-06 16:44:25 +08:00
|
|
|
end
|
|
|
|
|
|
2014-09-13 14:00:57 +08:00
|
|
|
--[[
|
2024-10-24 04:46:46 -04:00
|
|
|
the itemnumber parameter determines menu page number after switching item table
|
2014-09-13 14:00:57 +08:00
|
|
|
1. itemnumber >= 0
|
|
|
|
|
the page number is calculated with items per page
|
|
|
|
|
2. itemnumber == nil
|
|
|
|
|
the page number is 1
|
|
|
|
|
3. itemnumber is negative number
|
|
|
|
|
the page number is not changed, used when item_table is appended with
|
|
|
|
|
new entries
|
2017-10-21 19:53:56 +02:00
|
|
|
|
|
|
|
|
alternatively, itemmatch may be provided as a {key = value} table,
|
|
|
|
|
and the page number will be the page containing the first item for
|
|
|
|
|
which item.key = value
|
2014-09-13 14:00:57 +08:00
|
|
|
--]]
|
2023-12-19 09:22:53 +02:00
|
|
|
function Menu:switchItemTable(new_title, new_item_table, itemnumber, itemmatch, new_subtitle)
|
2024-05-16 21:57:04 +03:00
|
|
|
local no_recalculate_dimen = true
|
|
|
|
|
|
2024-05-07 09:34:30 +03:00
|
|
|
if new_item_table then
|
|
|
|
|
self.item_table = new_item_table
|
2024-05-16 21:57:04 +03:00
|
|
|
no_recalculate_dimen = false
|
2024-05-07 09:34:30 +03:00
|
|
|
end
|
|
|
|
|
|
2023-12-19 09:22:53 +02:00
|
|
|
if self.title_bar then
|
|
|
|
|
if new_title then
|
|
|
|
|
self.title_bar:setTitle(new_title, true)
|
2024-05-16 21:57:04 +03:00
|
|
|
if self.title_multilines then
|
|
|
|
|
no_recalculate_dimen = false
|
|
|
|
|
end
|
2023-12-19 09:22:53 +02:00
|
|
|
end
|
2024-05-16 21:57:04 +03:00
|
|
|
if new_subtitle then -- always single line
|
2023-12-19 09:22:53 +02:00
|
|
|
self.title_bar:setSubTitle(new_subtitle, true)
|
|
|
|
|
end
|
2014-03-13 21:52:43 +08:00
|
|
|
end
|
2014-07-30 09:00:02 +02:00
|
|
|
|
2017-10-21 19:53:56 +02:00
|
|
|
if type(itemmatch) == "table" then
|
|
|
|
|
local key, value = next(itemmatch)
|
2024-05-07 09:34:30 +03:00
|
|
|
for num, item in ipairs(self.item_table) do
|
2017-10-21 19:53:56 +02:00
|
|
|
if item[key] == value then
|
2024-05-07 09:34:30 +03:00
|
|
|
itemnumber = num
|
2017-10-21 19:53:56 +02:00
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2024-05-07 09:34:30 +03:00
|
|
|
if itemnumber == nil then
|
2022-05-06 16:44:25 +08:00
|
|
|
self.page = 1
|
2024-05-07 09:34:30 +03:00
|
|
|
elseif itemnumber >= 0 then
|
2024-10-13 18:02:51 +03:00
|
|
|
itemnumber = math.min(itemnumber, #self.item_table)
|
2024-05-07 09:34:30 +03:00
|
|
|
self.page = self:getPageNumber(itemnumber)
|
2024-10-30 20:09:59 +02:00
|
|
|
-- Draw the focus in FileChooser when it has focused_path (i.e. itemmatch), except ".." item
|
|
|
|
|
if self.path ~= nil and type(itemmatch) == "table" and not self.item_table[itemnumber].is_go_up then
|
2024-10-13 18:02:51 +03:00
|
|
|
self.itemnumber = itemnumber
|
|
|
|
|
end
|
2022-05-06 16:44:25 +08:00
|
|
|
end
|
2014-11-23 18:06:20 +08:00
|
|
|
|
2024-05-16 21:57:04 +03:00
|
|
|
self:updateItems(1, no_recalculate_dimen)
|
2012-06-11 13:46:19 +08:00
|
|
|
end
|
|
|
|
|
|
2024-05-07 09:34:30 +03:00
|
|
|
function Menu:getPageNumber(item_number)
|
|
|
|
|
if #self.item_table == 0 or item_number == 0 then
|
|
|
|
|
return 1
|
|
|
|
|
end
|
2024-06-01 10:32:15 +03:00
|
|
|
if self.items_max_lines then
|
|
|
|
|
for page, items in ipairs(self.page_items) do
|
|
|
|
|
if item_number <= items[#items] then
|
|
|
|
|
return page
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
return #self.page_items
|
|
|
|
|
else
|
|
|
|
|
return math.ceil(math.min(item_number, #self.item_table) / self.perpage)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function Menu:setupItemHeights()
|
|
|
|
|
if #self.item_table == 0 then
|
|
|
|
|
self.page_items = {{}}
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local face = Font:getFace("smallinfofont", self.font_size)
|
|
|
|
|
local line_height = TextBoxWidget:new{
|
|
|
|
|
text = "A",
|
|
|
|
|
face = face,
|
|
|
|
|
}:getSize().h
|
|
|
|
|
local infont_size = self.items_mandatory_font_size or (self.font_size - 4)
|
|
|
|
|
local infont_face = Font:getFace("infont", infont_size)
|
|
|
|
|
local infont_char_width = TextWidget:new{
|
|
|
|
|
text = "0",
|
|
|
|
|
face = infont_face,
|
|
|
|
|
bold = true,
|
|
|
|
|
}:getSize().w
|
|
|
|
|
local available_width = self.inner_dimen.w
|
|
|
|
|
if self.is_enable_shortcut then
|
|
|
|
|
available_width = available_width - line_height - Size.span.horizontal_default
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
self.page_items = {} -- list of all 'items in the page' indexed by page
|
|
|
|
|
local items = {} -- items in a page
|
|
|
|
|
local items_height = 0 -- of all items in a page
|
|
|
|
|
for i = 1, #self.item_table do
|
|
|
|
|
local item = self.item_table[i]
|
|
|
|
|
-- exact item height can be calculated by building the TextBoxWidget for item text,
|
|
|
|
|
-- but it is slow, so estimate the number of lines by building the TextWidget
|
2024-08-06 19:12:16 +03:00
|
|
|
-- empirical 8% is added to consider unjustified unhyphenated multilines text layout
|
2024-06-01 10:32:15 +03:00
|
|
|
local item_text_width = TextWidget:new{
|
|
|
|
|
text = item.text,
|
|
|
|
|
face = face,
|
|
|
|
|
bold = item.bold,
|
2024-08-06 19:12:16 +03:00
|
|
|
}:getSize().w * 1.08
|
|
|
|
|
local item_available_width = available_width - infont_char_width * (item.mandatory and #tostring(item.mandatory) or 0)
|
2024-06-01 10:32:15 +03:00
|
|
|
local lines_nb = math.min(math.ceil(item_text_width / item_available_width), self.items_max_lines)
|
|
|
|
|
item.height = lines_nb * line_height + 2 * Size.span.vertical_default + self.linesize
|
|
|
|
|
item.shortcut_icon_width = line_height -- letter shortcuts of fixed size (1 line)
|
|
|
|
|
|
|
|
|
|
-- put items in pages
|
|
|
|
|
items_height = items_height + item.height
|
|
|
|
|
if items_height <= self.available_height then
|
|
|
|
|
table.insert(items, i)
|
|
|
|
|
else -- start building next page
|
|
|
|
|
table.insert(self.page_items, items)
|
|
|
|
|
items = { i }
|
|
|
|
|
items_height = item.height
|
|
|
|
|
end
|
|
|
|
|
if i == #self.item_table then -- last page
|
|
|
|
|
table.insert(self.page_items, items)
|
|
|
|
|
end
|
|
|
|
|
end
|
2024-05-07 09:34:30 +03:00
|
|
|
end
|
|
|
|
|
|
2018-03-19 16:18:20 +01:00
|
|
|
function Menu:onScreenResize(dimen)
|
|
|
|
|
self:init()
|
|
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
|
2024-10-10 10:54:59 +03:00
|
|
|
function Menu:onSetRotationMode(rotation)
|
|
|
|
|
if self._recreate_func and rotation ~= nil and rotation ~= Screen:getRotationMode() then
|
|
|
|
|
UIManager:close(self)
|
|
|
|
|
-- Also re-layout ReaderView or FileManager itself
|
|
|
|
|
if self._manager.ui.view then
|
|
|
|
|
self._manager.ui.view:onSetRotationMode(rotation)
|
|
|
|
|
else
|
|
|
|
|
self._manager.ui:onSetRotationMode(rotation)
|
|
|
|
|
end
|
|
|
|
|
self._recreate_func()
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2012-04-29 23:53:48 +08:00
|
|
|
function Menu:onSelectByShortCut(_, keyevent)
|
2014-03-13 21:52:43 +08:00
|
|
|
for k,v in ipairs(self.item_shortcuts) do
|
|
|
|
|
if k > self.perpage then
|
|
|
|
|
break
|
|
|
|
|
elseif v == keyevent.key then
|
|
|
|
|
if self.item_table[(self.page-1)*self.perpage + k] then
|
|
|
|
|
self:onMenuSelect(self.item_table[(self.page-1)*self.perpage + k])
|
|
|
|
|
end
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
return true
|
2012-04-29 23:53:48 +08:00
|
|
|
end
|
|
|
|
|
|
2025-03-16 08:03:14 +02:00
|
|
|
function Menu:goToMenuItemMatching(search_string, goto_letter)
|
|
|
|
|
search_string = Utf8Proc.lowercase(util.fixUtf8(search_string, "?"))
|
|
|
|
|
for i, item in ipairs(self.item_table) do
|
2025-03-26 11:30:24 +02:00
|
|
|
if not item.is_go_up then
|
2025-03-16 08:03:14 +02:00
|
|
|
local item_text = Utf8Proc.lowercase(util.fixUtf8(item.text, "?"))
|
|
|
|
|
local idx = item_text:find(search_string)
|
|
|
|
|
if idx and (idx == 1 or not goto_letter) then
|
|
|
|
|
self.itemnumber = i -- draw focus
|
|
|
|
|
self:onGotoPage(self:getPageNumber(i))
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2019-03-01 12:59:39 +01:00
|
|
|
function Menu:onShowGotoDialog()
|
|
|
|
|
if self.page_info_text and self.page_info_text.hold_input then
|
|
|
|
|
self.page_info_text:onInput(self.page_info_text.hold_input)
|
|
|
|
|
end
|
2019-03-08 21:52:45 +01:00
|
|
|
return true
|
2019-03-01 12:59:39 +01:00
|
|
|
end
|
|
|
|
|
|
2012-06-10 17:36:19 +02:00
|
|
|
--[[
|
|
|
|
|
override this function to process the item selected in a different manner
|
|
|
|
|
]]--
|
|
|
|
|
function Menu:onMenuSelect(item)
|
2014-03-13 21:52:43 +08:00
|
|
|
if item.sub_item_table == nil then
|
2021-02-20 19:05:10 +01:00
|
|
|
if item.select_enabled == false then
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
if item.select_enabled_func then
|
|
|
|
|
if not item.select_enabled_func() then
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
end
|
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
|
|
|
self:onMenuChoice(item)
|
2017-08-18 10:02:11 +02:00
|
|
|
if self.close_callback then
|
|
|
|
|
self.close_callback()
|
|
|
|
|
end
|
2014-03-13 21:52:43 +08:00
|
|
|
else
|
|
|
|
|
-- save menu title for later resume
|
|
|
|
|
self.item_table.title = self.title
|
|
|
|
|
table.insert(self.item_table_stack, self.item_table)
|
2017-02-01 06:24:21 -08:00
|
|
|
self:switchItemTable(item.text, item.sub_item_table)
|
2014-03-13 21:52:43 +08:00
|
|
|
end
|
|
|
|
|
return true
|
2012-06-10 17:36:19 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--[[
|
2014-03-13 21:52:43 +08:00
|
|
|
default to call item callback
|
|
|
|
|
override this function to handle the choice
|
2013-02-03 03:35:25 +08:00
|
|
|
--]]
|
2012-06-10 17:36:19 +02:00
|
|
|
function Menu:onMenuChoice(item)
|
2014-03-13 21:52:43 +08:00
|
|
|
if item.callback then
|
|
|
|
|
item.callback()
|
|
|
|
|
end
|
|
|
|
|
return true
|
2012-06-10 17:36:19 +02:00
|
|
|
end
|
|
|
|
|
|
2014-01-18 23:15:44 +08:00
|
|
|
--[[
|
|
|
|
|
override this function to process the item hold in a different manner
|
|
|
|
|
]]--
|
|
|
|
|
function Menu:onMenuHold(item)
|
2014-03-13 21:52:43 +08:00
|
|
|
return true
|
2014-01-18 23:15:44 +08:00
|
|
|
end
|
|
|
|
|
|
2012-04-29 23:53:48 +08:00
|
|
|
function Menu:onNextPage()
|
2024-05-07 09:34:30 +03:00
|
|
|
local page = self.page < self.page_num and self.page + 1 or 1 -- cycle for swipes only
|
|
|
|
|
return self:onGotoPage(page)
|
2012-04-29 23:53:48 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function Menu:onPrevPage()
|
2024-05-07 09:34:30 +03:00
|
|
|
local page = self.page > 1 and self.page - 1 or self.page_num -- cycle for swipes only
|
|
|
|
|
return self:onGotoPage(page)
|
2012-04-29 23:53:48 +08:00
|
|
|
end
|
|
|
|
|
|
2014-07-30 09:00:02 +02:00
|
|
|
function Menu:onFirstPage()
|
2024-05-07 09:34:30 +03:00
|
|
|
return self:onGotoPage(1)
|
2014-07-30 09:00:02 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function Menu:onLastPage()
|
2024-05-07 09:34:30 +03:00
|
|
|
return self:onGotoPage(self.page_num)
|
2014-07-30 09:00:02 +02:00
|
|
|
end
|
|
|
|
|
|
2015-04-13 14:45:02 +08:00
|
|
|
function Menu:onGotoPage(page)
|
2025-05-22 18:00:35 +03:00
|
|
|
self.prev_itemnumber = nil
|
2015-04-13 14:45:02 +08:00
|
|
|
self.page = page
|
2024-05-07 09:34:30 +03:00
|
|
|
self:updateItems(1, true)
|
2015-04-13 14:45:02 +08:00
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
|
2018-03-18 11:42:35 +01:00
|
|
|
function Menu:onRight()
|
2022-03-05 04:20:00 +08:00
|
|
|
return self:sendHoldEventToFocusedWidget()
|
2018-03-18 11:42:35 +01:00
|
|
|
end
|
|
|
|
|
|
2024-05-07 09:34:30 +03:00
|
|
|
function Menu:onShowingReader()
|
|
|
|
|
-- Clear the dither flag to prevent it from infecting the queue and re-inserting a full-screen refresh...
|
|
|
|
|
self.dithered = nil
|
|
|
|
|
end
|
|
|
|
|
Menu.onSetupShowReader = Menu.onShowingReader
|
|
|
|
|
|
|
|
|
|
function Menu:onCloseWidget()
|
|
|
|
|
--- @fixme
|
|
|
|
|
-- we cannot refresh regionally using the dimen field
|
|
|
|
|
-- because some menus without menu title use VerticalGroup to include
|
|
|
|
|
-- a text widget which is not calculated into the dimen.
|
|
|
|
|
-- For example, it's a dirty hack to use two menus (one being this menu and
|
|
|
|
|
-- the other touch menu) in the filemanager in order to capture tap gesture to popup
|
|
|
|
|
-- the filemanager menu.
|
|
|
|
|
-- NOTE: For the same reason, don't make it flash,
|
|
|
|
|
-- because that'll trigger when we close the FM and open a book...
|
|
|
|
|
|
|
|
|
|
-- Don't do anything if we're in the process of tearing down FM or RD, or if we don't actually have a live instance of 'em...
|
|
|
|
|
local FileManager = require("apps/filemanager/filemanager")
|
|
|
|
|
local ReaderUI = require("apps/reader/readerui")
|
|
|
|
|
if (FileManager.instance and not FileManager.instance.tearing_down)
|
|
|
|
|
or (ReaderUI.instance and not ReaderUI.instance.tearing_down) then
|
|
|
|
|
UIManager:setDirty(nil, "ui")
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2012-04-29 23:53:48 +08:00
|
|
|
function Menu:onClose()
|
2024-05-07 09:34:30 +03:00
|
|
|
if #self.item_table_stack == 0 then
|
2014-03-13 21:52:43 +08:00
|
|
|
self:onCloseAllMenus()
|
|
|
|
|
else
|
|
|
|
|
-- back to parent menu
|
2024-05-07 09:34:30 +03:00
|
|
|
local parent_item_table = table.remove(self.item_table_stack)
|
2017-02-01 06:24:21 -08:00
|
|
|
self:switchItemTable(parent_item_table.title, parent_item_table)
|
2014-03-13 21:52:43 +08:00
|
|
|
end
|
|
|
|
|
return true
|
2012-04-29 23:53:48 +08:00
|
|
|
end
|
2012-06-10 17:36:19 +02:00
|
|
|
|
2012-12-09 01:18:40 +08:00
|
|
|
function Menu:onCloseAllMenus()
|
2014-03-13 21:52:43 +08:00
|
|
|
UIManager:close(self)
|
|
|
|
|
if self.close_callback then
|
|
|
|
|
self.close_callback()
|
|
|
|
|
end
|
|
|
|
|
return true
|
2012-12-09 01:18:40 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function Menu:onTapCloseAllMenus(arg, ges_ev)
|
2014-03-13 21:52:43 +08:00
|
|
|
if ges_ev.pos:notIntersectWith(self.dimen) then
|
|
|
|
|
self:onCloseAllMenus()
|
|
|
|
|
return true
|
|
|
|
|
end
|
2012-12-09 01:18:40 +08:00
|
|
|
end
|
|
|
|
|
|
2012-12-30 00:56:21 -05:00
|
|
|
function Menu:onSwipe(arg, ges_ev)
|
2019-12-06 22:55:39 +01:00
|
|
|
local direction = BD.flipDirectionIfMirroredUILayout(ges_ev.direction)
|
|
|
|
|
if direction == "west" then
|
2016-02-14 13:47:36 -08:00
|
|
|
self:onNextPage()
|
2019-12-06 22:55:39 +01:00
|
|
|
elseif direction == "east" then
|
2016-02-14 13:47:36 -08:00
|
|
|
self:onPrevPage()
|
2019-12-06 22:55:39 +01:00
|
|
|
elseif direction == "south" then
|
2023-03-25 09:48:30 +02:00
|
|
|
if not self.no_title then
|
|
|
|
|
-- If there is a titlebar with a close button displayed (so, this Menu can be
|
2022-01-25 15:24:06 +01:00
|
|
|
-- closed), allow easier closing with swipe south.
|
2018-09-21 15:48:40 +02:00
|
|
|
self:onClose()
|
|
|
|
|
end
|
|
|
|
|
-- If there is no close button, it's a top level Menu and swipe
|
|
|
|
|
-- up/down may hide/show top menu
|
2019-12-06 22:55:39 +01:00
|
|
|
elseif direction == "north" then
|
2018-09-21 15:48:40 +02:00
|
|
|
-- no use for now
|
|
|
|
|
do end -- luacheck: ignore 541
|
|
|
|
|
else -- diagonal swipe
|
2019-08-04 19:59:20 +02:00
|
|
|
-- trigger full refresh
|
|
|
|
|
UIManager:setDirty(nil, "full")
|
2014-03-13 21:52:43 +08:00
|
|
|
end
|
2012-12-30 00:56:21 -05:00
|
|
|
end
|
2013-10-18 22:38:07 +02:00
|
|
|
|
2024-03-09 09:11:23 +01:00
|
|
|
function Menu:onPan(arg, ges_ev)
|
|
|
|
|
if ges_ev.mousewheel_direction then
|
|
|
|
|
if ges_ev.direction == "north" then
|
|
|
|
|
self:onNextPage()
|
|
|
|
|
elseif ges_ev.direction == "south" then
|
|
|
|
|
self:onPrevPage()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
|
2022-01-25 15:24:06 +01:00
|
|
|
function Menu:onMultiSwipe(arg, ges_ev)
|
|
|
|
|
-- For consistency with other fullscreen widgets where swipe south can't be
|
|
|
|
|
-- used to close and where we then allow any multiswipe to close, allow any
|
|
|
|
|
-- multiswipe to close this widget too.
|
2023-03-25 09:48:30 +02:00
|
|
|
if not self.no_title then
|
|
|
|
|
-- If there is a titlebar with a close button displayed (so, this Menu can be
|
2022-01-25 15:24:06 +01:00
|
|
|
-- closed), allow easier closing with swipe south.
|
|
|
|
|
self:onClose()
|
|
|
|
|
end
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
|
2022-01-10 21:21:39 +02:00
|
|
|
function Menu:setTitleBarLeftIcon(icon)
|
|
|
|
|
self.title_bar:setLeftIcon(icon)
|
2021-12-24 13:21:12 +02:00
|
|
|
end
|
|
|
|
|
|
2024-10-24 04:46:46 -04:00
|
|
|
function Menu:onLeftButtonTap() -- to be overridden and implemented by the caller
|
2021-12-24 13:21:12 +02:00
|
|
|
end
|
|
|
|
|
|
2024-10-24 04:46:46 -04:00
|
|
|
function Menu:onLeftButtonHold() -- to be overridden and implemented by the caller
|
2021-12-24 13:21:12 +02:00
|
|
|
end
|
|
|
|
|
|
2024-08-06 19:12:16 +03:00
|
|
|
function Menu:getFirstVisibleItemIndex()
|
2024-08-11 17:01:15 +03:00
|
|
|
return self.item_group[1] and self.item_group[1].idx or 1
|
2024-08-06 19:12:16 +03:00
|
|
|
end
|
|
|
|
|
|
2024-05-07 09:34:30 +03:00
|
|
|
function Menu.getItemFontSize(perpage)
|
|
|
|
|
-- Get adjusted font size for the given nb of items per page:
|
|
|
|
|
-- item font size between 14 and 24 for better matching
|
|
|
|
|
return math.floor(24 - ((perpage - 6) * (1/18)) * 10)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function Menu.getItemMandatoryFontSize(perpage)
|
|
|
|
|
-- Get adjusted font size for the given nb of items per page:
|
|
|
|
|
-- "mandatory" font size between 12 and 18 for better matching
|
|
|
|
|
return math.floor(18 - (perpage - 6) * (1/3))
|
|
|
|
|
end
|
|
|
|
|
|
2019-12-06 22:55:39 +01:00
|
|
|
--- Adds > to touch menu items with a submenu
|
|
|
|
|
local arrow_left = "◂" -- U+25C2 BLACK LEFT-POINTING SMALL TRIANGLE
|
|
|
|
|
local arrow_right = "▸" -- U+25B8 BLACK RIGHT-POINTING SMALL TRIANGLE
|
|
|
|
|
local sub_item_format
|
|
|
|
|
-- Adjust arrow direction and position for menu with sub items
|
|
|
|
|
-- according to possible user choices
|
|
|
|
|
if BD.mirroredUILayout() then
|
|
|
|
|
if BD.rtlUIText() then -- normal case with RTL language
|
|
|
|
|
sub_item_format = "%s " .. BD.rtl(arrow_left)
|
|
|
|
|
else -- user reverted text direction, so LTR
|
|
|
|
|
sub_item_format = BD.ltr(arrow_left) .. " %s"
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
if BD.rtlUIText() then -- user reverted text direction, so RTL
|
|
|
|
|
sub_item_format = BD.rtl(arrow_right) .. " %s"
|
|
|
|
|
else -- normal case with LTR language
|
|
|
|
|
sub_item_format = "%s " .. BD.ltr(arrow_right)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function Menu.getMenuText(item)
|
|
|
|
|
local text
|
|
|
|
|
if item.text_func then
|
|
|
|
|
text = item.text_func()
|
|
|
|
|
else
|
|
|
|
|
text = item.text
|
|
|
|
|
end
|
|
|
|
|
if item.sub_item_table ~= nil or item.sub_item_table_func then
|
|
|
|
|
text = string.format(sub_item_format, text)
|
|
|
|
|
end
|
|
|
|
|
return text
|
|
|
|
|
end
|
|
|
|
|
|
2014-10-25 04:02:42 -04:00
|
|
|
function Menu.itemTableFromTouchMenu(t)
|
|
|
|
|
local item_t = {}
|
2024-10-30 20:09:59 +02:00
|
|
|
for k, v in ffiUtil.orderedPairs(t) do
|
2014-10-25 04:02:42 -04:00
|
|
|
local item = { text = k }
|
|
|
|
|
if v.callback then
|
|
|
|
|
item.callback = v.callback
|
|
|
|
|
else
|
|
|
|
|
item.sub_item_table = v
|
|
|
|
|
end
|
|
|
|
|
table.insert(item_t, item)
|
|
|
|
|
end
|
|
|
|
|
return item_t
|
|
|
|
|
end
|
|
|
|
|
|
2013-10-18 22:38:07 +02:00
|
|
|
return Menu
|