2017-10-28 19:28:41 +00:00
|
|
|
local Button = require("ui/widget/button")
|
2017-11-04 14:31:41 +00:00
|
|
|
local ButtonProgressWidget = require("ui/widget/buttonprogresswidget")
|
2017-04-07 13:20:57 +00:00
|
|
|
local Blitbuffer = require("ffi/blitbuffer")
|
|
|
|
local BottomContainer = require("ui/widget/container/bottomcontainer")
|
2013-10-18 20:38:07 +00:00
|
|
|
local CenterContainer = require("ui/widget/container/centercontainer")
|
2017-04-07 13:20:57 +00:00
|
|
|
local ConfirmBox = require("ui/widget/confirmbox")
|
|
|
|
local Device = require("device")
|
|
|
|
local Event = require("ui/event")
|
|
|
|
local FixedTextWidget = require("ui/widget/fixedtextwidget")
|
2018-03-22 20:01:38 +00:00
|
|
|
local FocusManager = require("ui/widget/focusmanager")
|
2017-04-07 13:20:57 +00:00
|
|
|
local Font = require("ui/font")
|
2013-10-18 20:38:07 +00:00
|
|
|
local FrameContainer = require("ui/widget/container/framecontainer")
|
2017-04-07 13:20:57 +00:00
|
|
|
local Geom = require("ui/geometry")
|
|
|
|
local GestureRange = require("ui/gesturerange")
|
2014-11-20 02:59:58 +00:00
|
|
|
local HorizontalGroup = require("ui/widget/horizontalgroup")
|
2017-04-07 13:20:57 +00:00
|
|
|
local HorizontalSpan = require("ui/widget/horizontalspan")
|
|
|
|
local IconButton = require("ui/widget/iconbutton")
|
2020-12-19 11:18:30 +00:00
|
|
|
local IconWidget = require("ui/widget/iconwidget")
|
2017-04-07 13:20:57 +00:00
|
|
|
local InputContainer = require("ui/widget/container/inputcontainer")
|
2017-09-11 18:54:27 +00:00
|
|
|
local LineWidget = require("ui/widget/linewidget")
|
2021-05-20 21:14:11 +00:00
|
|
|
local Notification = require("ui/widget/notification")
|
2017-04-07 13:20:57 +00:00
|
|
|
local RightContainer = require("ui/widget/container/rightcontainer")
|
2017-09-13 14:56:20 +00:00
|
|
|
local Size = require("ui/size")
|
2014-11-20 02:59:58 +00:00
|
|
|
local TextWidget = require("ui/widget/textwidget")
|
2017-04-07 13:20:57 +00:00
|
|
|
local ToggleSwitch = require("ui/widget/toggleswitch")
|
2013-10-18 20:38:07 +00:00
|
|
|
local UIManager = require("ui/uimanager")
|
2017-04-07 13:20:57 +00:00
|
|
|
local UnderlineContainer = require("ui/widget/container/underlinecontainer")
|
|
|
|
local VerticalGroup = require("ui/widget/verticalgroup")
|
|
|
|
local VerticalSpan = require("ui/widget/verticalspan")
|
2016-12-29 08:10:38 +00:00
|
|
|
local logger = require("logger")
|
Logger: Use serpent instead of dump (#9588)
* Persist: support serpent, and use by default over dump (as we assume consistency > readability in Persist).
* Logger/Dbg: Use serpent instead of dump to dump tables (it's slightly more compact, honors __tostring, and will tag tables with their ref, which can come in handy when debugging).
* Dbg: Don't duplicate Logger's log function, just use it directly.
* Fontlist/ConfigDialog: Use serpent for the debug dump.
* Call `os.setlocale(C, "numeric")` on startup instead of peppering it around dump calls. It's process-wide, so it didn't make much sense.
* Trapper: Use LuaJIT's serde facilities instead of dump. They're more reliable in the face of funky input, much faster, and in this case, the data never makes it to human eyes, so a human-readable format didn't gain us anything.
2022-10-06 00:21:03 +00:00
|
|
|
local serpent = require("ffi/serpent")
|
2013-10-18 20:38:07 +00:00
|
|
|
local _ = require("gettext")
|
2017-04-07 13:20:57 +00:00
|
|
|
local Screen = Device.screen
|
|
|
|
local T = require("ffi/util").template
|
2013-01-15 09:24:38 +00:00
|
|
|
|
2022-09-27 23:10:50 +00:00
|
|
|
local DGENERIC_ICON_SIZE = G_defaults:readSetting("DGENERIC_ICON_SIZE")
|
|
|
|
|
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 00:14:48 +00:00
|
|
|
local OptionTextItem = InputContainer:extend{}
|
2019-01-15 19:39:33 +00:00
|
|
|
|
2012-12-23 23:54:44 +00:00
|
|
|
function OptionTextItem:init()
|
2014-03-13 13:52:43 +00:00
|
|
|
local text_widget = self[1]
|
2014-05-28 12:05:38 +00:00
|
|
|
|
2018-11-20 19:54:03 +00:00
|
|
|
self.underline_container = UnderlineContainer:new{
|
2014-03-13 13:52:43 +00:00
|
|
|
text_widget,
|
2018-11-20 19:54:03 +00:00
|
|
|
padding = self.underline_padding, -- vertical padding between text and underline
|
2014-03-13 13:52:43 +00:00
|
|
|
color = self.color,
|
|
|
|
}
|
2018-11-20 19:54:03 +00:00
|
|
|
self[1] = FrameContainer:new{
|
|
|
|
padding = 0,
|
|
|
|
padding_left = self.padding_left,
|
|
|
|
padding_right = self.padding_right,
|
|
|
|
bordersize = 0,
|
|
|
|
self.underline_container,
|
|
|
|
}
|
2014-03-13 13:52:43 +00:00
|
|
|
self.dimen = self[1]:getSize()
|
|
|
|
-- we need this table per-instance, so we declare it here
|
2022-01-25 00:32:46 +00:00
|
|
|
self.ges_events = {
|
|
|
|
TapSelect = {
|
|
|
|
GestureRange:new{
|
|
|
|
ges = "tap",
|
|
|
|
range = self.dimen,
|
2014-03-13 13:52:43 +00:00
|
|
|
},
|
2022-01-25 00:32:46 +00:00
|
|
|
},
|
|
|
|
HoldSelect = {
|
|
|
|
GestureRange:new{
|
|
|
|
ges = "hold",
|
|
|
|
range = self.dimen,
|
2014-07-03 08:30:24 +00:00
|
|
|
},
|
2022-01-25 00:32:46 +00:00
|
|
|
},
|
|
|
|
}
|
2012-12-23 23:54:44 +00:00
|
|
|
end
|
|
|
|
|
2018-03-22 20:01:38 +00:00
|
|
|
function OptionTextItem:onFocus()
|
2018-11-20 19:54:03 +00:00
|
|
|
self.underline_container.color = Blitbuffer.COLOR_BLACK
|
2018-03-22 20:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function OptionTextItem:onUnfocus()
|
2018-11-20 19:54:03 +00:00
|
|
|
self.underline_container.color = Blitbuffer.COLOR_WHITE
|
2018-03-22 20:01:38 +00:00
|
|
|
end
|
|
|
|
|
2012-12-23 23:54:44 +00:00
|
|
|
function OptionTextItem:onTapSelect()
|
2015-03-16 13:49:53 +00:00
|
|
|
if not self.enabled then return true end
|
2014-03-13 13:52:43 +00:00
|
|
|
for _, item in pairs(self.items) do
|
2018-11-20 19:54:03 +00:00
|
|
|
item.underline_container.color = Blitbuffer.COLOR_WHITE
|
2014-03-13 13:52:43 +00:00
|
|
|
end
|
2018-11-20 19:54:03 +00:00
|
|
|
self.underline_container.color = Blitbuffer.COLOR_BLACK
|
2021-05-20 21:14:11 +00:00
|
|
|
|
|
|
|
Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_ICON)
|
2014-07-03 08:30:24 +00:00
|
|
|
self.config:onConfigChoose(self.values, self.name,
|
|
|
|
self.event, self.args,
|
2021-08-30 15:21:50 +00:00
|
|
|
self.current_item, self.hide_on_apply)
|
2021-05-20 21:14:11 +00:00
|
|
|
|
2014-11-30 00:12:00 +00:00
|
|
|
UIManager:setDirty(self.config, function()
|
2018-06-02 16:10:55 +00:00
|
|
|
return "fast", self[1].dimen
|
2014-11-30 00:12:00 +00:00
|
|
|
end)
|
2021-05-20 21:14:11 +00:00
|
|
|
|
|
|
|
UIManager:tickAfterNext(function()
|
|
|
|
Notification:resetNotifySource()
|
|
|
|
end)
|
2014-03-13 13:52:43 +00:00
|
|
|
return true
|
2012-12-23 23:54:44 +00:00
|
|
|
end
|
2012-12-14 10:20:04 +00:00
|
|
|
|
2014-07-03 08:30:24 +00:00
|
|
|
function OptionTextItem:onHoldSelect()
|
|
|
|
self.config:onMakeDefault(self.name, self.name_text,
|
|
|
|
self.values or self.args,
|
|
|
|
self.values or self.item_text,
|
|
|
|
self.current_item)
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
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 00:14:48 +00:00
|
|
|
local OptionIconItem = InputContainer:extend{}
|
2019-01-15 19:39:33 +00:00
|
|
|
|
2013-02-03 03:26:14 +00:00
|
|
|
function OptionIconItem:init()
|
2018-11-20 19:54:03 +00:00
|
|
|
self.underline_container = UnderlineContainer:new{
|
2014-03-13 13:52:43 +00:00
|
|
|
self.icon,
|
2018-11-20 19:54:03 +00:00
|
|
|
padding = self.underline_padding,
|
2014-03-13 13:52:43 +00:00
|
|
|
color = self.color,
|
|
|
|
}
|
2018-11-20 19:54:03 +00:00
|
|
|
self[1] = FrameContainer:new{
|
|
|
|
padding = 0,
|
2020-11-28 16:18:57 +00:00
|
|
|
padding_top = self.underline_padding,
|
2018-11-20 19:54:03 +00:00
|
|
|
padding_left = self.padding_left,
|
|
|
|
padding_right = self.padding_right,
|
|
|
|
bordersize = 0,
|
|
|
|
self.underline_container,
|
|
|
|
}
|
|
|
|
self.dimen = self[1]:getSize()
|
2014-03-13 13:52:43 +00:00
|
|
|
-- we need this table per-instance, so we declare it here
|
2022-01-25 00:32:46 +00:00
|
|
|
self.ges_events = {
|
|
|
|
TapSelect = {
|
|
|
|
GestureRange:new{
|
|
|
|
ges = "tap",
|
|
|
|
range = self.dimen,
|
2014-03-13 13:52:43 +00:00
|
|
|
},
|
2022-01-25 00:32:46 +00:00
|
|
|
},
|
|
|
|
HoldSelect = {
|
|
|
|
GestureRange:new{
|
|
|
|
ges = "hold",
|
|
|
|
range = self.dimen,
|
2014-07-03 08:30:24 +00:00
|
|
|
},
|
2022-01-25 00:32:46 +00:00
|
|
|
},
|
2014-07-03 08:30:24 +00:00
|
|
|
|
2022-01-25 00:32:46 +00:00
|
|
|
}
|
2013-02-03 03:26:14 +00:00
|
|
|
end
|
|
|
|
|
2018-03-22 20:01:38 +00:00
|
|
|
function OptionIconItem:onFocus()
|
|
|
|
self.icon.invert = true
|
|
|
|
end
|
|
|
|
|
|
|
|
function OptionIconItem:onUnfocus()
|
|
|
|
self.icon.invert = false
|
|
|
|
end
|
|
|
|
|
2013-02-03 03:26:14 +00:00
|
|
|
function OptionIconItem:onTapSelect()
|
2015-03-16 13:49:53 +00:00
|
|
|
if not self.enabled then return true end
|
2014-03-13 13:52:43 +00:00
|
|
|
for _, item in pairs(self.items) do
|
|
|
|
--item[1][1].invert = false
|
2018-11-20 19:54:03 +00:00
|
|
|
item.underline_container.color = Blitbuffer.COLOR_WHITE
|
2014-03-13 13:52:43 +00:00
|
|
|
end
|
|
|
|
--self[1][1].invert = true
|
2018-11-20 19:54:03 +00:00
|
|
|
self.underline_container.color = Blitbuffer.COLOR_BLACK
|
2021-05-20 21:14:11 +00:00
|
|
|
|
|
|
|
Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_ICON)
|
2014-07-03 08:30:24 +00:00
|
|
|
self.config:onConfigChoose(self.values, self.name,
|
|
|
|
self.event, self.args,
|
2021-08-30 15:21:50 +00:00
|
|
|
self.current_item, self.hide_on_apply)
|
2021-05-20 21:14:11 +00:00
|
|
|
|
2014-11-30 00:12:00 +00:00
|
|
|
UIManager:setDirty(self.config, function()
|
2018-06-02 16:10:55 +00:00
|
|
|
return "fast", self[1].dimen
|
2014-11-30 00:12:00 +00:00
|
|
|
end)
|
2021-05-20 21:14:11 +00:00
|
|
|
|
|
|
|
UIManager:tickAfterNext(function()
|
|
|
|
Notification:resetNotifySource()
|
|
|
|
end)
|
2014-03-13 13:52:43 +00:00
|
|
|
return true
|
2013-02-03 03:26:14 +00:00
|
|
|
end
|
|
|
|
|
2014-07-03 08:30:24 +00:00
|
|
|
function OptionIconItem:onHoldSelect()
|
|
|
|
self.config:onMakeDefault(self.name, self.name_text,
|
2021-03-30 16:47:52 +00:00
|
|
|
self.values, self.labels or self.values, self.current_item)
|
2014-07-03 08:30:24 +00:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
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 00:14:48 +00:00
|
|
|
local ConfigOption = CenterContainer:extend{}
|
2019-01-15 19:39:33 +00:00
|
|
|
|
2012-12-19 15:45:51 +00:00
|
|
|
function ConfigOption:init()
|
2014-11-23 08:52:08 +00:00
|
|
|
-- make default styles
|
2014-03-13 13:52:43 +00:00
|
|
|
local default_name_font_size = 20
|
2019-01-15 19:39:33 +00:00
|
|
|
local default_item_font_size = 16 -- font size for letters, toggles and buttonprogress
|
|
|
|
local default_items_spacing = 40 -- spacing between letters (font sizes) and icons
|
|
|
|
local default_option_height = 50 -- height of each line
|
2020-12-19 11:18:30 +00:00
|
|
|
local max_icon_height = Screen:scaleBySize(DGENERIC_ICON_SIZE) -- max height of icons
|
2019-01-15 19:39:33 +00:00
|
|
|
-- The next ones are already scaleBySize()'d:
|
|
|
|
local default_option_vpadding = Size.padding.large -- vertical padding at top and bottom
|
|
|
|
local default_option_hpadding = Size.padding.fullscreen
|
|
|
|
-- horizontal padding at left and right, and between name and option items
|
|
|
|
local padding_small = Size.padding.small -- internal padding for options names (left)
|
|
|
|
local padding_button = Size.padding.button -- padding for underline below letters and icons
|
|
|
|
|
2019-08-23 17:53:53 +00:00
|
|
|
--- @todo Restore setting when there are more advanced settings.
|
2021-03-06 21:44:18 +00:00
|
|
|
--local show_advanced = G_reader_settings:isTrue("show_advanced")
|
2019-01-15 19:39:33 +00:00
|
|
|
local show_advanced = true
|
|
|
|
|
|
|
|
-- Get the width needed by the longest option name shown on the left
|
2014-11-23 08:52:08 +00:00
|
|
|
local max_option_name_width = 0
|
|
|
|
for c = 1, #self.options do
|
2019-01-15 19:39:33 +00:00
|
|
|
-- Ignore names of options that won't be shown
|
|
|
|
local show_default = not self.options[c].advanced or show_advanced
|
2019-06-25 22:23:41 +00:00
|
|
|
local show = self.options[c].show
|
|
|
|
-- Prefer show_func over show if there's one
|
2020-12-10 22:53:33 +00:00
|
|
|
-- Or may be not, as show_func is always used to show/hide some widget depending
|
|
|
|
-- on the value of another widget: it's best to keep it accounted for the names
|
|
|
|
-- max width, and avoid stuff moving when toggling options.
|
|
|
|
--[[
|
2019-06-25 22:23:41 +00:00
|
|
|
if self.options[c].show_func then
|
2020-11-28 16:18:57 +00:00
|
|
|
show = self.options[c].show_func(self.config.configurable, self.config.document)
|
2019-06-25 22:23:41 +00:00
|
|
|
end
|
2020-12-10 22:53:33 +00:00
|
|
|
]]--
|
2019-06-25 22:23:41 +00:00
|
|
|
if show ~= false and show_default then
|
2019-01-15 19:39:33 +00:00
|
|
|
local name_font_face = self.options[c].name_font_face and self.options[c].name_font_face or "cfont"
|
|
|
|
local name_font_size = self.options[c].name_font_size and self.options[c].name_font_size or default_name_font_size
|
2020-11-28 16:18:57 +00:00
|
|
|
local text = self.options[c].name_text_func
|
|
|
|
and self.options[c].name_text_func(self.config.configurable, self.config.document)
|
|
|
|
or self.options[c].name_text
|
2019-01-15 19:39:33 +00:00
|
|
|
local face = Font:getFace(name_font_face, name_font_size)
|
|
|
|
local txt_width = 0
|
|
|
|
if text ~= nil then
|
2019-10-21 13:20:40 +00:00
|
|
|
local tmp = TextWidget:new{
|
|
|
|
text = text,
|
|
|
|
face = face,
|
|
|
|
}
|
|
|
|
txt_width = tmp:getWidth()
|
2019-01-15 19:39:33 +00:00
|
|
|
end
|
|
|
|
max_option_name_width = math.max(max_option_name_width, txt_width)
|
2017-10-28 19:28:41 +00:00
|
|
|
end
|
2014-11-23 08:52:08 +00:00
|
|
|
end
|
2019-01-15 19:39:33 +00:00
|
|
|
-- Have option names take min 25% and max 50% of screen width
|
|
|
|
-- They will carry the left default_option_hpadding, but the in-between
|
|
|
|
-- one (and the right one) will be carried by the option items.
|
|
|
|
-- (Both these variables are between 0 and 1 and represent a % of screen width)
|
2020-06-16 20:14:14 +00:00
|
|
|
local default_name_align_right = (max_option_name_width + default_option_hpadding + 2*padding_small) / Screen:getWidth()
|
2019-01-15 19:39:33 +00:00
|
|
|
default_name_align_right = math.max(default_name_align_right, 0.25)
|
2017-10-28 19:28:41 +00:00
|
|
|
default_name_align_right = math.min(default_name_align_right, 0.5)
|
2014-11-23 08:52:08 +00:00
|
|
|
local default_item_align_center = 1 - default_name_align_right
|
|
|
|
|
|
|
|
-- fill vertical group of config tab
|
2014-03-13 13:52:43 +00:00
|
|
|
local vertical_group = VerticalGroup:new{}
|
|
|
|
table.insert(vertical_group, VerticalSpan:new{
|
2019-01-15 19:39:33 +00:00
|
|
|
width = default_option_vpadding,
|
2014-03-13 13:52:43 +00:00
|
|
|
})
|
2019-01-15 19:39:33 +00:00
|
|
|
|
2014-03-13 13:52:43 +00:00
|
|
|
for c = 1, #self.options do
|
2014-07-17 14:31:01 +00:00
|
|
|
local show_default = not self.options[c].advanced or show_advanced
|
2019-06-25 22:23:41 +00:00
|
|
|
local show = self.options[c].show
|
|
|
|
-- Prefer show_func over show if there's one
|
|
|
|
if self.options[c].show_func then
|
2020-11-28 16:18:57 +00:00
|
|
|
show = self.options[c].show_func(self.config.configurable, self.config.document)
|
2019-06-25 22:23:41 +00:00
|
|
|
end
|
|
|
|
if show ~= false and show_default then
|
2014-11-23 08:52:08 +00:00
|
|
|
local name_align = self.options[c].name_align_right and self.options[c].name_align_right or default_name_align_right
|
|
|
|
local item_align = self.options[c].item_align_center and self.options[c].item_align_center or default_item_align_center
|
2014-03-13 13:52:43 +00:00
|
|
|
local name_font_face = self.options[c].name_font_face and self.options[c].name_font_face or "cfont"
|
|
|
|
local name_font_size = self.options[c].name_font_size and self.options[c].name_font_size or default_name_font_size
|
|
|
|
local item_font_face = self.options[c].item_font_face and self.options[c].item_font_face or "cfont"
|
|
|
|
local item_font_size = self.options[c].item_font_size and self.options[c].item_font_size or default_item_font_size
|
2017-10-31 20:42:13 +00:00
|
|
|
local option_height = Screen:scaleBySize(self.options[c].height and self.options[c].height or
|
|
|
|
default_option_height + (self.options[c].height or 30) * ((self.options[c].row_count or 1) -1))
|
2017-09-13 14:56:20 +00:00
|
|
|
local item_spacing_width = Screen:scaleBySize(self.options[c].spacing and self.options[c].spacing or default_items_spacing)
|
2015-03-16 13:49:53 +00:00
|
|
|
local enabled = true
|
2017-10-28 19:28:41 +00:00
|
|
|
if item_align == 1.0 then
|
|
|
|
name_align = 0
|
|
|
|
end
|
|
|
|
if name_align + item_align > 1 then
|
|
|
|
name_align = 0.5
|
|
|
|
item_align = 0.5
|
|
|
|
end
|
2015-03-16 13:49:53 +00:00
|
|
|
if self.options[c].enabled_func then
|
2019-08-30 11:47:51 +00:00
|
|
|
enabled = self.options[c].enabled_func(self.config.configurable, self.config.document)
|
2015-03-16 13:49:53 +00:00
|
|
|
end
|
2014-03-13 13:52:43 +00:00
|
|
|
local horizontal_group = HorizontalGroup:new{}
|
2019-01-15 19:39:33 +00:00
|
|
|
|
|
|
|
-- Deal with the name on the left
|
2020-11-28 16:18:57 +00:00
|
|
|
local name_text = self.options[c].name_text_func
|
|
|
|
and self.options[c].name_text_func(self.config.configurable, self.config.document)
|
|
|
|
or self.options[c].name_text
|
|
|
|
if name_text then
|
2019-01-15 19:39:33 +00:00
|
|
|
-- the horizontal padding on the left will be ensured by the RightContainer
|
|
|
|
local name_widget_width = math.floor(name_align * Screen:getWidth())
|
2019-11-16 16:43:28 +00:00
|
|
|
-- We don't remove default_option_hpadding from name_text_max_width
|
|
|
|
-- to give more to text and avoid truncation: as it is right aligned,
|
2023-03-23 17:37:29 +00:00
|
|
|
-- the text can grow on the left.
|
|
|
|
local name_text_max_width = name_widget_width
|
2017-10-28 19:28:41 +00:00
|
|
|
local face = Font:getFace(name_font_face, name_font_size)
|
2014-03-13 13:52:43 +00:00
|
|
|
local option_name_container = RightContainer:new{
|
2019-01-15 19:39:33 +00:00
|
|
|
dimen = Geom:new{ w = name_widget_width, h = option_height},
|
2014-03-13 13:52:43 +00:00
|
|
|
}
|
2017-10-28 19:28:41 +00:00
|
|
|
local option_name = Button:new{
|
2020-11-28 16:18:57 +00:00
|
|
|
text = name_text,
|
2019-10-21 13:20:40 +00:00
|
|
|
max_width = name_text_max_width,
|
2017-10-28 19:28:41 +00:00
|
|
|
bordersize = 0,
|
|
|
|
face = face,
|
|
|
|
enabled = enabled,
|
2020-05-07 18:24:12 +00:00
|
|
|
allow_hold_when_disabled = self.options[c].name_text_hold_callback ~= nil,
|
2017-10-28 19:28:41 +00:00
|
|
|
padding = padding_small,
|
|
|
|
text_font_face = name_font_face,
|
|
|
|
text_font_size = name_font_size,
|
|
|
|
text_font_bold = false,
|
2018-05-18 22:16:02 +00:00
|
|
|
hold_callback = function()
|
|
|
|
if self.options[c].name_text_hold_callback then
|
2018-05-26 17:45:37 +00:00
|
|
|
self.options[c].name_text_hold_callback(self.config.configurable, self.options[c],
|
2021-04-28 23:37:53 +00:00
|
|
|
self.config.config_options.prefix, self.config.document)
|
2018-05-18 22:16:02 +00:00
|
|
|
end
|
|
|
|
end,
|
2014-03-13 13:52:43 +00:00
|
|
|
}
|
|
|
|
table.insert(option_name_container, option_name)
|
|
|
|
table.insert(horizontal_group, option_name_container)
|
|
|
|
end
|
|
|
|
|
2019-01-15 19:39:33 +00:00
|
|
|
-- Deal with the option widget on the right
|
|
|
|
-- The horizontal padding between name and this option widget, and
|
|
|
|
-- the one on the right, are ensured by this CenterContainer
|
|
|
|
local option_widget_outer_width = math.floor(item_align * Screen:getWidth())
|
|
|
|
local option_widget_width = option_widget_outer_width - 2*default_option_hpadding
|
2014-03-13 13:52:43 +00:00
|
|
|
local option_items_container = CenterContainer:new{
|
2019-01-15 19:39:33 +00:00
|
|
|
dimen = Geom:new{
|
|
|
|
w = option_widget_outer_width,
|
|
|
|
h = option_height
|
|
|
|
}
|
2014-03-13 13:52:43 +00:00
|
|
|
}
|
|
|
|
local option_items_group = HorizontalGroup:new{}
|
|
|
|
local option_items_fixed = false
|
|
|
|
local option_items = {}
|
|
|
|
if type(self.options[c].item_font_size) == "table" then
|
|
|
|
option_items_group.align = "bottom"
|
|
|
|
option_items_fixed = true
|
|
|
|
end
|
2019-01-15 19:39:33 +00:00
|
|
|
|
2019-03-15 22:15:05 +00:00
|
|
|
-- Find out currently selected and default items indexes
|
2014-03-13 13:52:43 +00:00
|
|
|
local current_item = nil
|
2019-03-15 22:15:05 +00:00
|
|
|
local default_item = self.options[c].default_pos
|
2014-03-13 13:52:43 +00:00
|
|
|
local function value_diff(val1, val2, name)
|
|
|
|
if type(val1) ~= type(val2) then
|
2016-12-29 08:10:38 +00:00
|
|
|
logger.dbg("different data types in option")
|
2014-03-13 13:52:43 +00:00
|
|
|
end
|
|
|
|
if type(val1) == "number" then
|
|
|
|
return math.abs(val1 - val2)
|
|
|
|
elseif type(val1) == "string" then
|
|
|
|
return val1 == val2 and 0 or 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if self.options[c].name then
|
|
|
|
if self.options[c].values then
|
|
|
|
-- check if current value is stored in configurable or calculated in runtime
|
|
|
|
local val = self.options[c].current_func and self.options[c].current_func()
|
|
|
|
or self.config.configurable[self.options[c].name]
|
2016-02-16 02:08:04 +00:00
|
|
|
local min_diff
|
2014-03-13 13:52:43 +00:00
|
|
|
if type(val) == "table" then
|
|
|
|
min_diff = value_diff(val[1], self.options[c].values[1][1])
|
|
|
|
else
|
|
|
|
min_diff = value_diff(val, self.options[c].values[1])
|
|
|
|
end
|
2014-05-28 12:05:38 +00:00
|
|
|
|
2016-02-16 02:08:04 +00:00
|
|
|
local diff
|
2014-03-13 13:52:43 +00:00
|
|
|
for index, val_ in pairs(self.options[c].values) do
|
|
|
|
if type(val) == "table" then
|
|
|
|
diff = value_diff(val[1], val_[1])
|
|
|
|
else
|
|
|
|
diff = value_diff(val, val_)
|
|
|
|
end
|
|
|
|
if val == val_ then
|
|
|
|
current_item = index
|
|
|
|
break
|
|
|
|
end
|
|
|
|
if diff <= min_diff then
|
|
|
|
min_diff = diff
|
|
|
|
current_item = index
|
|
|
|
end
|
|
|
|
end
|
2020-05-09 11:16:12 +00:00
|
|
|
-- If we want to have the ⋮ toggle selected when the value
|
|
|
|
-- is different from the predefined values:
|
|
|
|
-- if diff ~= 0 and self.options[c].alternate ~= false and self.options[c].more_options_param then
|
|
|
|
-- current_item = #self.options[c].values + 1
|
|
|
|
-- end
|
2014-03-13 13:52:43 +00:00
|
|
|
elseif self.options[c].args then
|
|
|
|
-- check if current arg is stored in configurable or calculated in runtime
|
|
|
|
local arg = self.options[c].current_func and self.options[c].current_func()
|
|
|
|
or self.config.configurable[self.options[c].name]
|
|
|
|
for idx, arg_ in pairs(self.options[c].args) do
|
|
|
|
if arg_ == arg then
|
|
|
|
current_item = idx
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2019-03-15 22:15:05 +00:00
|
|
|
local default_option_name = self.config.config_options.prefix.."_"..self.options[c].name
|
|
|
|
local default_value = G_reader_settings:readSetting(default_option_name)
|
2019-03-25 18:15:29 +00:00
|
|
|
if default_value and self.options[c].values then
|
2019-03-15 22:15:05 +00:00
|
|
|
local val = default_value
|
|
|
|
local min_diff
|
|
|
|
if type(val) == "table" then
|
|
|
|
min_diff = value_diff(val[1], self.options[c].values[1][1])
|
|
|
|
else
|
|
|
|
min_diff = value_diff(val, self.options[c].values[1])
|
|
|
|
end
|
|
|
|
|
|
|
|
local diff
|
|
|
|
for index, val_ in pairs(self.options[c].values) do
|
|
|
|
if type(val) == "table" then
|
|
|
|
diff = value_diff(val[1], val_[1])
|
|
|
|
else
|
|
|
|
diff = value_diff(val, val_)
|
|
|
|
end
|
|
|
|
if val == val_ then
|
|
|
|
default_item = index
|
|
|
|
break
|
|
|
|
end
|
|
|
|
if diff <= min_diff then
|
|
|
|
min_diff = diff
|
|
|
|
default_item = index
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2014-03-13 13:52:43 +00:00
|
|
|
end
|
2019-01-15 19:39:33 +00:00
|
|
|
|
|
|
|
-- Deal with the various kind of config widgets
|
|
|
|
|
|
|
|
-- Plain letters (ex: font sizes)
|
2014-03-13 13:52:43 +00:00
|
|
|
if self.options[c].item_text then
|
2014-06-02 14:57:50 +00:00
|
|
|
local items_count = #self.options[c].item_text
|
2017-10-28 19:28:41 +00:00
|
|
|
local items_width = 0
|
|
|
|
for d = 1, #self.options[c].item_text do
|
|
|
|
local item = OptionTextItem:new{
|
|
|
|
TextWidget:new{
|
|
|
|
text = self.options[c].item_text[d],
|
|
|
|
face = Font:getFace(item_font_face,
|
|
|
|
option_items_fixed and item_font_size[d]
|
2014-06-02 14:57:50 +00:00
|
|
|
or item_font_size),
|
2017-10-28 19:28:41 +00:00
|
|
|
}
|
2014-06-02 14:57:50 +00:00
|
|
|
}
|
2017-10-28 19:28:41 +00:00
|
|
|
items_width = items_width + item:getSize().w
|
|
|
|
end
|
2019-01-15 19:39:33 +00:00
|
|
|
local max_item_spacing = (option_widget_width - items_width) / items_count
|
2017-10-28 19:28:41 +00:00
|
|
|
local width = math.min(max_item_spacing, item_spacing_width)
|
|
|
|
if max_item_spacing < item_spacing_width / 2 then
|
|
|
|
width = item_spacing_width / 2
|
|
|
|
end
|
2018-11-20 19:54:03 +00:00
|
|
|
local horizontal_half_padding = width / 2
|
2019-01-15 19:39:33 +00:00
|
|
|
local max_item_text_width = (option_widget_width - items_count * width) / items_count
|
2014-03-13 13:52:43 +00:00
|
|
|
for d = 1, #self.options[c].item_text do
|
2016-02-16 02:08:04 +00:00
|
|
|
local option_item
|
2014-03-13 13:52:43 +00:00
|
|
|
if option_items_fixed then
|
|
|
|
option_item = OptionTextItem:new{
|
|
|
|
FixedTextWidget:new{
|
|
|
|
text = self.options[c].item_text[d],
|
|
|
|
face = Font:getFace(item_font_face, item_font_size[d]),
|
2019-03-14 19:58:45 +00:00
|
|
|
fgcolor = enabled and Blitbuffer.COLOR_BLACK or Blitbuffer.COLOR_DARK_GRAY,
|
2014-03-13 13:52:43 +00:00
|
|
|
},
|
2018-11-20 19:54:03 +00:00
|
|
|
underline_padding = padding_button,
|
|
|
|
padding_left = d > 1 and horizontal_half_padding,
|
|
|
|
padding_right = d < #self.options[c].item_text and horizontal_half_padding,
|
2019-03-14 21:09:55 +00:00
|
|
|
color = d == current_item and (enabled and Blitbuffer.COLOR_BLACK or Blitbuffer.COLOR_DARK_GRAY) or Blitbuffer.COLOR_WHITE,
|
2015-03-16 13:49:53 +00:00
|
|
|
enabled = enabled,
|
2014-03-13 13:52:43 +00:00
|
|
|
}
|
|
|
|
else
|
2017-10-28 19:28:41 +00:00
|
|
|
local text = self.options[c].item_text[d]
|
|
|
|
local face = Font:getFace(item_font_face, item_font_size)
|
2014-03-13 13:52:43 +00:00
|
|
|
option_item = OptionTextItem:new{
|
|
|
|
TextWidget:new{
|
2017-10-28 19:28:41 +00:00
|
|
|
text = text,
|
2019-10-21 13:20:40 +00:00
|
|
|
max_width = max_item_text_width,
|
2017-10-28 19:28:41 +00:00
|
|
|
face = face,
|
2019-03-14 19:58:45 +00:00
|
|
|
fgcolor = enabled and Blitbuffer.COLOR_BLACK or Blitbuffer.COLOR_DARK_GRAY,
|
2014-03-13 13:52:43 +00:00
|
|
|
},
|
2018-11-20 19:54:03 +00:00
|
|
|
underline_padding = -padding_button,
|
|
|
|
padding_left = d > 1 and horizontal_half_padding,
|
|
|
|
padding_right = d < #self.options[c].item_text and horizontal_half_padding,
|
2019-03-14 21:09:55 +00:00
|
|
|
color = d == current_item and (enabled and Blitbuffer.COLOR_BLACK or Blitbuffer.COLOR_DARK_GRAY) or Blitbuffer.COLOR_WHITE,
|
2015-03-16 13:49:53 +00:00
|
|
|
enabled = enabled,
|
2014-03-13 13:52:43 +00:00
|
|
|
}
|
|
|
|
end
|
|
|
|
option_items[d] = option_item
|
|
|
|
option_item.items = option_items
|
|
|
|
option_item.name = self.options[c].name
|
2021-02-03 15:31:11 +00:00
|
|
|
option_item.name_text = name_text or self.options[c].alt_name_text
|
2014-07-03 08:30:24 +00:00
|
|
|
option_item.item_text = self.options[c].item_text
|
2014-03-13 13:52:43 +00:00
|
|
|
option_item.values = self.options[c].values
|
|
|
|
option_item.args = self.options[c].args
|
|
|
|
option_item.event = self.options[c].event
|
|
|
|
option_item.current_item = d
|
2021-01-11 17:14:17 +00:00
|
|
|
option_item.hide_on_apply = self.options[c].hide_on_apply
|
2014-03-13 13:52:43 +00:00
|
|
|
option_item.config = self.config
|
2019-08-30 11:47:51 +00:00
|
|
|
option_item.document = self.document
|
2014-03-13 13:52:43 +00:00
|
|
|
table.insert(option_items_group, option_item)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-01-15 19:39:33 +00:00
|
|
|
-- Icons (ex: columns, text align, with PDF)
|
2021-03-29 03:12:22 +00:00
|
|
|
local item_icons = self.options[c].item_icons_func and
|
|
|
|
self.options[c].item_icons_func(self.config.configurable, self.config.document) or
|
|
|
|
self.options[c].item_icons
|
|
|
|
if item_icons then
|
|
|
|
local items_count = #item_icons
|
2020-12-19 11:18:30 +00:00
|
|
|
local icon_max_height = math.min(option_height, max_icon_height)
|
2020-11-28 16:18:57 +00:00
|
|
|
local icon_max_width = math.floor(option_widget_width / items_count)
|
|
|
|
local icon_size = math.min(icon_max_height, icon_max_width)
|
|
|
|
local max_item_spacing = (option_widget_width - icon_size * items_count) / items_count
|
2018-11-20 19:54:03 +00:00
|
|
|
local horizontal_half_padding = math.min(max_item_spacing, item_spacing_width) / 2
|
2020-11-28 16:18:57 +00:00
|
|
|
-- Our icons have a bottom padding that makes 10% to 20% of their height (5-9px in our 48px images)
|
|
|
|
-- We don't want the underline to be that far away from the image content,
|
|
|
|
-- so we use some negative padding to eat a bit on their padding.
|
|
|
|
local underline_padding = - math.floor(0.05 * icon_size)
|
2021-03-29 03:12:22 +00:00
|
|
|
for d = 1, items_count do
|
2014-03-13 13:52:43 +00:00
|
|
|
local option_item = OptionIconItem:new{
|
2020-12-19 11:18:30 +00:00
|
|
|
icon = IconWidget:new{
|
2021-03-29 03:12:22 +00:00
|
|
|
icon = item_icons[d],
|
2015-03-16 13:49:53 +00:00
|
|
|
dim = not enabled,
|
2020-11-28 16:18:57 +00:00
|
|
|
width = icon_size,
|
|
|
|
height = icon_size,
|
2014-03-13 13:52:43 +00:00
|
|
|
},
|
2020-11-28 16:18:57 +00:00
|
|
|
underline_padding = underline_padding,
|
2018-11-20 19:54:03 +00:00
|
|
|
padding_left = d > 1 and horizontal_half_padding,
|
2021-03-29 03:12:22 +00:00
|
|
|
padding_right = d < items_count and horizontal_half_padding,
|
2019-03-14 21:09:55 +00:00
|
|
|
color = d == current_item and (enabled and Blitbuffer.COLOR_BLACK or Blitbuffer.COLOR_DARK_GRAY) or Blitbuffer.COLOR_WHITE,
|
2015-03-16 13:49:53 +00:00
|
|
|
enabled = enabled,
|
2014-03-13 13:52:43 +00:00
|
|
|
}
|
|
|
|
option_items[d] = option_item
|
|
|
|
option_item.items = option_items
|
|
|
|
option_item.name = self.options[c].name
|
2021-02-03 15:31:11 +00:00
|
|
|
option_item.name_text = name_text or self.options[c].alt_name_text
|
2014-03-13 13:52:43 +00:00
|
|
|
option_item.values = self.options[c].values
|
2021-03-30 16:47:52 +00:00
|
|
|
option_item.labels = self.options[c].labels
|
2014-03-13 13:52:43 +00:00
|
|
|
option_item.args = self.options[c].args
|
|
|
|
option_item.event = self.options[c].event
|
|
|
|
option_item.current_item = d
|
2021-01-11 17:14:17 +00:00
|
|
|
option_item.hide_on_apply = self.options[c].hide_on_apply
|
2014-03-13 13:52:43 +00:00
|
|
|
option_item.config = self.config
|
|
|
|
table.insert(option_items_group, option_item)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-01-15 19:39:33 +00:00
|
|
|
-- Toggles (ex: mostly everything else)
|
2014-03-13 13:52:43 +00:00
|
|
|
if self.options[c].toggle then
|
2019-01-15 19:39:33 +00:00
|
|
|
local max_toggle_width = option_widget_width
|
|
|
|
local toggle_width = self.options[c].width and Screen:scaleBySize(self.options[c].width)
|
|
|
|
or max_toggle_width
|
2016-04-26 02:45:55 +00:00
|
|
|
local row_count = self.options[c].row_count or 1
|
|
|
|
local toggle_height = Screen:scaleBySize(self.options[c].height
|
2022-09-27 23:10:50 +00:00
|
|
|
or (30 * row_count))
|
2019-09-27 10:58:40 +00:00
|
|
|
if self.options[c].more_options then
|
|
|
|
table.insert(self.options[c].toggle, "⋮")
|
|
|
|
table.insert(self.options[c].args, "⋮")
|
|
|
|
self.options[c].more_options = false
|
|
|
|
end
|
2014-03-13 13:52:43 +00:00
|
|
|
local switch = ToggleSwitch:new{
|
2014-06-02 14:57:50 +00:00
|
|
|
width = math.min(max_toggle_width, toggle_width),
|
2016-04-26 02:45:55 +00:00
|
|
|
height = toggle_height,
|
2014-11-23 08:52:08 +00:00
|
|
|
font_face = item_font_face,
|
|
|
|
font_size = item_font_size,
|
2014-03-13 13:52:43 +00:00
|
|
|
name = self.options[c].name,
|
2020-11-28 16:18:57 +00:00
|
|
|
name_text = name_text,
|
2014-03-13 13:52:43 +00:00
|
|
|
toggle = self.options[c].toggle,
|
|
|
|
alternate = self.options[c].alternate,
|
|
|
|
values = self.options[c].values,
|
|
|
|
args = self.options[c].args,
|
|
|
|
event = self.options[c].event,
|
2021-01-11 17:14:17 +00:00
|
|
|
hide_on_apply = self.options[c].hide_on_apply,
|
2014-03-13 13:52:43 +00:00
|
|
|
config = self.config,
|
2015-03-16 13:49:53 +00:00
|
|
|
enabled = enabled,
|
2016-04-26 02:45:55 +00:00
|
|
|
row_count = row_count,
|
2019-09-27 10:58:40 +00:00
|
|
|
callback = function(arg)
|
2019-09-30 09:18:39 +00:00
|
|
|
if self.options[c].toggle[arg] == "⋮" then
|
2020-05-09 11:16:12 +00:00
|
|
|
if self.options[c].show_true_value_func and not self.options[c].more_options_param.show_true_value_func then
|
|
|
|
self.options[c].more_options_param.show_true_value_func = self.options[c].show_true_value_func
|
|
|
|
end
|
2021-05-20 21:14:11 +00:00
|
|
|
Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_MORE)
|
2022-10-04 11:44:55 +00:00
|
|
|
local default_value_original
|
2022-10-21 18:33:07 +00:00
|
|
|
if self.options[c].more_options_param and self.options[c].more_options_param.names then
|
2022-10-04 11:44:55 +00:00
|
|
|
local option1 = self.config:findOptionByName(self.options[c].more_options_param.names[1])
|
|
|
|
local option2 = self.config:findOptionByName(self.options[c].more_options_param.names[2])
|
|
|
|
default_value_original = { option1.default_value, option2.default_value }
|
|
|
|
else
|
|
|
|
default_value_original = self.options[c].default_value
|
|
|
|
end
|
|
|
|
self.config:onConfigMoreChoose(self.options[c].values, default_value_original, self.options[c].name,
|
2021-01-11 17:14:17 +00:00
|
|
|
self.options[c].event, arg, name_text, self.options[c].more_options_param)
|
2021-05-20 21:14:11 +00:00
|
|
|
UIManager:tickAfterNext(function()
|
|
|
|
Notification:resetNotifySource()
|
|
|
|
end)
|
2019-09-27 10:58:40 +00:00
|
|
|
end
|
|
|
|
end
|
2014-03-13 13:52:43 +00:00
|
|
|
}
|
|
|
|
local position = current_item
|
|
|
|
switch:setPosition(position)
|
|
|
|
table.insert(option_items_group, switch)
|
|
|
|
end
|
|
|
|
|
2019-01-15 19:39:33 +00:00
|
|
|
-- Progress bar (ex: contrast)
|
2017-11-04 14:31:41 +00:00
|
|
|
if self.options[c].buttonprogress then
|
2019-01-15 19:39:33 +00:00
|
|
|
local max_buttonprogress_width = option_widget_width
|
|
|
|
local buttonprogress_width = self.options[c].width and Screen:scaleBySize(self.options[c].width)
|
|
|
|
or max_buttonprogress_width
|
2019-03-14 21:23:17 +00:00
|
|
|
local switch
|
|
|
|
switch = ButtonProgressWidget:new{
|
2017-11-04 14:31:41 +00:00
|
|
|
width = math.min(max_buttonprogress_width, buttonprogress_width),
|
|
|
|
height = option_height,
|
2019-01-15 19:39:33 +00:00
|
|
|
padding = 0,
|
2019-03-02 11:24:15 +00:00
|
|
|
thin_grey_style = true,
|
2017-11-04 14:31:41 +00:00
|
|
|
font_face = item_font_face,
|
|
|
|
font_size = item_font_size,
|
2020-04-14 10:20:11 +00:00
|
|
|
name = self.options[c].name,
|
2017-11-04 14:31:41 +00:00
|
|
|
num_buttons = #self.options[c].values,
|
|
|
|
position = self.options[c].default_pos,
|
|
|
|
callback = function(arg)
|
2019-05-01 00:09:01 +00:00
|
|
|
if arg == "-" or arg == "+" then
|
2021-05-20 21:14:11 +00:00
|
|
|
Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_FINE)
|
2019-05-01 00:09:01 +00:00
|
|
|
self.config:onConfigFineTuneChoose(self.options[c].values, self.options[c].name,
|
2021-08-30 15:21:50 +00:00
|
|
|
self.options[c].event, self.options[c].args, arg, self.options[c].hide_on_apply,
|
2020-11-28 16:18:57 +00:00
|
|
|
self.options[c].fine_tune_param)
|
2019-09-14 14:30:25 +00:00
|
|
|
elseif arg == "⋮" then
|
2021-05-20 21:14:11 +00:00
|
|
|
Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_MORE)
|
2022-10-04 11:44:55 +00:00
|
|
|
local default_value_original
|
2022-10-22 11:28:43 +00:00
|
|
|
if self.options[c].more_options_param and self.options[c].more_options_param.names then
|
2022-10-04 11:44:55 +00:00
|
|
|
local option1 = self.config:findOptionByName(self.options[c].more_options_param.names[1])
|
|
|
|
local option2 = self.config:findOptionByName(self.options[c].more_options_param.names[2])
|
|
|
|
default_value_original = { option1.default_value, option2.default_value }
|
|
|
|
else
|
|
|
|
default_value_original = self.options[c].default_value
|
|
|
|
end
|
|
|
|
self.config:onConfigMoreChoose(self.options[c].values, default_value_original, self.options[c].name,
|
2021-01-11 17:14:17 +00:00
|
|
|
self.options[c].event, arg, name_text, self.options[c].more_options_param)
|
2019-05-01 00:09:01 +00:00
|
|
|
else
|
2022-10-04 11:44:55 +00:00
|
|
|
Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_PROGRESS)
|
2019-05-01 00:09:01 +00:00
|
|
|
self.config:onConfigChoose(self.options[c].values, self.options[c].name,
|
2021-08-30 15:21:50 +00:00
|
|
|
self.options[c].event, self.options[c].args, arg, self.options[c].hide_on_apply)
|
2019-05-01 00:09:01 +00:00
|
|
|
end
|
2021-05-20 21:14:11 +00:00
|
|
|
|
2019-03-14 21:23:17 +00:00
|
|
|
UIManager:setDirty(self.config, function()
|
|
|
|
return "fast", switch.dimen
|
2017-11-04 14:31:41 +00:00
|
|
|
end)
|
2021-05-20 21:14:11 +00:00
|
|
|
UIManager:tickAfterNext(function()
|
|
|
|
Notification:resetNotifySource()
|
|
|
|
end)
|
2017-11-04 14:31:41 +00:00
|
|
|
end,
|
|
|
|
hold_callback = function(arg)
|
2019-05-01 00:09:01 +00:00
|
|
|
if arg == "-" or arg == "+" then
|
2020-11-28 16:18:57 +00:00
|
|
|
self.config:onMakeFineTuneDefault(self.options[c].name, name_text, self.options[c].values,
|
2019-05-01 00:09:01 +00:00
|
|
|
self.options[c].labels or self.options[c].args, arg)
|
2019-09-23 22:24:45 +00:00
|
|
|
elseif arg ~= "⋮" then
|
2020-11-28 16:18:57 +00:00
|
|
|
self.config:onMakeDefault(self.options[c].name, name_text, self.options[c].values,
|
2019-05-01 00:09:01 +00:00
|
|
|
self.options[c].labels or self.options[c].args, arg)
|
|
|
|
end
|
2017-11-04 14:31:41 +00:00
|
|
|
end,
|
2022-03-14 18:56:18 +00:00
|
|
|
show_parent = self.config,
|
2017-11-04 14:31:41 +00:00
|
|
|
enabled = enabled,
|
2019-05-01 00:09:01 +00:00
|
|
|
fine_tune = self.options[c].fine_tune,
|
2020-11-28 16:18:57 +00:00
|
|
|
fine_tune_param = self.options[c].fine_tune_param,
|
2019-09-14 14:30:25 +00:00
|
|
|
more_options = self.options[c].more_options,
|
|
|
|
more_options_param = self.options[c].more_options_param,
|
2017-11-04 14:31:41 +00:00
|
|
|
}
|
2019-03-15 22:15:05 +00:00
|
|
|
switch:setPosition(current_item, default_item)
|
2017-11-04 14:31:41 +00:00
|
|
|
table.insert(option_items_group, switch)
|
|
|
|
end
|
2019-01-15 19:39:33 +00:00
|
|
|
|
|
|
|
-- Add it to our CenterContainer
|
2014-03-13 13:52:43 +00:00
|
|
|
table.insert(option_items_container, option_items_group)
|
2018-03-22 20:01:38 +00:00
|
|
|
--add line of item to the second last place in the focusmanager so the menubar stay at the bottom
|
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 00:51:09 +00:00
|
|
|
table.insert(self.config.layout, #self.config.layout, self:_itemGroupToLayoutLine(option_items_group))
|
2014-03-13 13:52:43 +00:00
|
|
|
table.insert(horizontal_group, option_items_container)
|
|
|
|
table.insert(vertical_group, horizontal_group)
|
2019-06-25 22:23:41 +00:00
|
|
|
end -- if show ~= false
|
2019-01-15 19:39:33 +00:00
|
|
|
end -- for c = 1, #self.options
|
|
|
|
|
|
|
|
table.insert(vertical_group, VerticalSpan:new{ width = default_option_vpadding })
|
2014-03-13 13:52:43 +00:00
|
|
|
self[1] = vertical_group
|
|
|
|
self.dimen = vertical_group:getSize()
|
2012-12-19 15:45:51 +00:00
|
|
|
end
|
|
|
|
|
2018-03-22 20:01:38 +00:00
|
|
|
function ConfigOption:_itemGroupToLayoutLine(option_items_group)
|
|
|
|
local layout_line = {}
|
2020-04-14 10:20:11 +00:00
|
|
|
-- Insert items (skpping item_spacing without a .name attribute),
|
2022-03-04 20:20:00 +00:00
|
|
|
local j = 1 -- no nil in row head
|
2020-04-14 10:20:11 +00:00
|
|
|
for i, v in ipairs(option_items_group) do
|
|
|
|
if v.name then
|
2022-01-25 00:32:46 +00:00
|
|
|
if v.layout and v.disableFocusManagement then -- it is a FocusManager
|
|
|
|
-- merge child layout to one row layout
|
|
|
|
-- currently child widgets are all one row
|
|
|
|
-- need improved if two or more rows widget existed
|
|
|
|
for _, row in ipairs(v.layout) do
|
|
|
|
for _, widget in ipairs(row) do
|
|
|
|
layout_line[j] = widget
|
|
|
|
j = j + 1
|
|
|
|
end
|
|
|
|
end
|
2022-03-04 20:20:00 +00:00
|
|
|
v:disableFocusManagement(self.config)
|
2022-01-25 00:32:46 +00:00
|
|
|
else
|
|
|
|
layout_line[j] = v
|
|
|
|
j = j + 1
|
|
|
|
end
|
2018-03-22 20:01:38 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
return layout_line
|
|
|
|
end
|
|
|
|
|
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 00:14:48 +00:00
|
|
|
local ConfigPanel = FrameContainer:extend{
|
2019-01-15 19:39:33 +00:00
|
|
|
background = Blitbuffer.COLOR_WHITE,
|
|
|
|
bordersize = 0,
|
|
|
|
}
|
|
|
|
|
2012-12-23 23:54:44 +00:00
|
|
|
function ConfigPanel:init()
|
2014-03-13 13:52:43 +00:00
|
|
|
local config_options = self.config_dialog.config_options
|
|
|
|
local default_option = config_options.default_options and config_options.default_options
|
|
|
|
or config_options[1].options
|
|
|
|
local panel = ConfigOption:new{
|
|
|
|
options = self.index and config_options[self.index].options or default_option,
|
|
|
|
config = self.config_dialog,
|
2019-08-30 11:47:51 +00:00
|
|
|
document = self.document,
|
2014-03-13 13:52:43 +00:00
|
|
|
}
|
|
|
|
self.dimen = panel:getSize()
|
|
|
|
table.insert(self, panel)
|
2013-01-15 09:24:38 +00:00
|
|
|
end
|
|
|
|
|
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 00:14:48 +00:00
|
|
|
local MenuBar = FrameContainer:extend{
|
2017-09-11 18:54:27 +00:00
|
|
|
bordersize = 0,
|
|
|
|
padding = 0,
|
|
|
|
background = Blitbuffer.COLOR_WHITE,
|
|
|
|
}
|
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 00:51:09 +00:00
|
|
|
|
2013-01-15 09:24:38 +00:00
|
|
|
function MenuBar:init()
|
2017-09-13 14:56:20 +00:00
|
|
|
local icon_sep_width = Size.padding.button
|
|
|
|
local line_thickness = Size.line.thick
|
2014-03-13 13:52:43 +00:00
|
|
|
local config_options = self.config_dialog.config_options
|
2020-12-19 11:18:30 +00:00
|
|
|
local icon_width = Screen:scaleBySize(DGENERIC_ICON_SIZE)
|
2017-09-24 13:22:06 +00:00
|
|
|
local icon_height = icon_width
|
|
|
|
local icons_width = (icon_width + 2*icon_sep_width) * #config_options
|
2020-12-19 11:18:30 +00:00
|
|
|
local bar_height = icon_height + 2*Size.padding.default
|
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 00:51:09 +00:00
|
|
|
if not self.menu_items then
|
|
|
|
self.menu_items = {}
|
|
|
|
for c = 1, #config_options do
|
|
|
|
local menu_icon = IconButton:new{
|
|
|
|
show_parent = self.config_dialog,
|
|
|
|
icon = config_options[c].icon,
|
|
|
|
width = icon_width,
|
|
|
|
height = icon_height,
|
|
|
|
callback = function()
|
|
|
|
self.config_dialog:handleEvent(Event:new("ShowConfigPanel", c))
|
|
|
|
end,
|
|
|
|
}
|
|
|
|
self.menu_items[c] = menu_icon
|
|
|
|
end
|
2014-03-13 13:52:43 +00:00
|
|
|
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 00:51:09 +00:00
|
|
|
table.insert(self.config_dialog.layout, self.menu_items) -- for the focusmanager
|
2017-09-13 08:12:29 +00:00
|
|
|
local available_width = Screen:getWidth() - icons_width
|
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 00:51:09 +00:00
|
|
|
-- local padding = math.floor(available_width / #self.menu_items / 2) -- all for padding
|
|
|
|
-- local padding = math.floor(available_width / #self.menu_items / 2 / 2) -- half padding, half spacing ?
|
|
|
|
local padding = math.min(math.floor(available_width / #self.menu_items / 2), Screen:scaleBySize(20)) -- as in TouchMenuBar
|
2017-09-13 08:12:29 +00:00
|
|
|
if padding > 0 then
|
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 00:51:09 +00:00
|
|
|
for c = 1, #self.menu_items do
|
|
|
|
self.menu_items[c].padding_left = padding
|
|
|
|
self.menu_items[c].padding_right = padding
|
|
|
|
self.menu_items[c]:update()
|
2017-09-13 08:12:29 +00:00
|
|
|
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 00:51:09 +00:00
|
|
|
available_width = available_width - 2*padding*#self.menu_items
|
2017-09-13 08:12:29 +00:00
|
|
|
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 00:51:09 +00:00
|
|
|
local spacing_width = math.ceil(available_width / (#self.menu_items+1))
|
2017-09-13 08:12:29 +00:00
|
|
|
|
2017-09-12 16:34:30 +00:00
|
|
|
local icon_sep_black = LineWidget:new{
|
|
|
|
background = Blitbuffer.COLOR_BLACK,
|
|
|
|
dimen = Geom:new{
|
|
|
|
w = icon_sep_width,
|
2020-12-19 11:18:30 +00:00
|
|
|
h = bar_height,
|
2017-09-12 16:34:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
local icon_sep_white = LineWidget:new{
|
|
|
|
background = Blitbuffer.COLOR_WHITE,
|
2017-09-11 18:54:27 +00:00
|
|
|
dimen = Geom:new{
|
|
|
|
w = icon_sep_width,
|
2020-12-19 11:18:30 +00:00
|
|
|
h = bar_height,
|
2017-09-11 18:54:27 +00:00
|
|
|
}
|
|
|
|
}
|
2014-03-13 13:52:43 +00:00
|
|
|
local spacing = HorizontalSpan:new{
|
2017-09-11 18:54:27 +00:00
|
|
|
width = spacing_width,
|
|
|
|
}
|
|
|
|
local spacing_line = LineWidget:new{
|
|
|
|
dimen = Geom:new{
|
|
|
|
w = spacing_width,
|
|
|
|
h = line_thickness,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
local sep_line = LineWidget:new{
|
|
|
|
dimen = Geom:new{
|
|
|
|
w = icon_sep_width,
|
|
|
|
h = line_thickness,
|
|
|
|
}
|
2014-03-13 13:52:43 +00:00
|
|
|
}
|
|
|
|
local menu_bar = HorizontalGroup:new{}
|
2017-09-11 18:54:27 +00:00
|
|
|
local line_bar = HorizontalGroup:new{}
|
2014-03-13 13:52:43 +00: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 00:51:09 +00:00
|
|
|
for c = 1, #self.menu_items do
|
2014-03-13 13:52:43 +00:00
|
|
|
table.insert(menu_bar, spacing)
|
2017-09-11 18:54:27 +00:00
|
|
|
table.insert(line_bar, spacing_line)
|
|
|
|
if c == self.panel_index then
|
2017-09-12 16:34:30 +00:00
|
|
|
table.insert(menu_bar, icon_sep_black)
|
2017-09-11 18:54:27 +00:00
|
|
|
table.insert(line_bar, sep_line)
|
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 00:51:09 +00:00
|
|
|
table.insert(menu_bar, self.menu_items[c])
|
2017-09-11 18:54:27 +00:00
|
|
|
table.insert(line_bar, LineWidget:new{
|
|
|
|
background = Blitbuffer.COLOR_WHITE,
|
|
|
|
dimen = Geom:new{
|
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 00:51:09 +00:00
|
|
|
w = self.menu_items[c]:getSize().w,
|
2017-09-11 18:54:27 +00:00
|
|
|
h = line_thickness,
|
|
|
|
}
|
|
|
|
})
|
2017-09-12 16:34:30 +00:00
|
|
|
table.insert(menu_bar, icon_sep_black)
|
2017-09-11 18:54:27 +00:00
|
|
|
table.insert(line_bar, sep_line)
|
|
|
|
else
|
2017-09-12 16:34:30 +00:00
|
|
|
table.insert(menu_bar, icon_sep_white)
|
|
|
|
table.insert(line_bar, sep_line)
|
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 00:51:09 +00:00
|
|
|
table.insert(menu_bar, self.menu_items[c])
|
2017-09-11 18:54:27 +00:00
|
|
|
table.insert(line_bar, LineWidget:new{
|
|
|
|
dimen = Geom:new{
|
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 00:51:09 +00:00
|
|
|
w = self.menu_items[c]:getSize().w,
|
2017-09-11 18:54:27 +00:00
|
|
|
h = line_thickness,
|
|
|
|
}
|
|
|
|
})
|
2017-09-12 16:34:30 +00:00
|
|
|
table.insert(menu_bar, icon_sep_white)
|
|
|
|
table.insert(line_bar, sep_line)
|
2017-09-11 18:54:27 +00:00
|
|
|
end
|
2014-03-13 13:52:43 +00:00
|
|
|
end
|
|
|
|
table.insert(menu_bar, spacing)
|
2017-09-11 18:54:27 +00:00
|
|
|
table.insert(line_bar, spacing_line)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
2020-12-19 11:18:30 +00:00
|
|
|
self.dimen = Geom:new{ w = Screen:getWidth(), h = bar_height}
|
2017-09-11 18:54:27 +00:00
|
|
|
local vertical_menu = VerticalGroup:new{
|
|
|
|
line_bar,
|
|
|
|
menu_bar,
|
|
|
|
}
|
|
|
|
table.insert(self, vertical_menu)
|
2013-01-14 16:33:03 +00:00
|
|
|
end
|
|
|
|
|
2012-12-14 10:20:04 +00:00
|
|
|
--[[
|
2013-01-15 09:24:38 +00:00
|
|
|
Widget that displays config menubar and config panel
|
|
|
|
|
|
|
|
+----------------+
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
+----------------+
|
|
|
|
| |
|
|
|
|
| Config Panel |
|
|
|
|
| |
|
|
|
|
+----------------+
|
|
|
|
| Menu Bar |
|
|
|
|
+----------------+
|
2013-03-12 17:18:53 +00:00
|
|
|
|
2012-12-14 10:20:04 +00:00
|
|
|
--]]
|
2013-01-15 09:24:38 +00: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 00:14:48 +00:00
|
|
|
local ConfigDialog = FocusManager:extend{
|
2014-03-13 13:52:43 +00:00
|
|
|
--is_borderless = false,
|
2022-06-12 17:16:46 +00:00
|
|
|
name = "ConfigDialog",
|
2014-03-13 13:52:43 +00:00
|
|
|
panel_index = 1,
|
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 00:14:37 +00:00
|
|
|
is_fresh = true,
|
2012-12-14 10:20:04 +00:00
|
|
|
}
|
|
|
|
|
2012-12-23 23:54:44 +00:00
|
|
|
function ConfigDialog:init()
|
2014-03-13 13:52:43 +00:00
|
|
|
------------------------------------------
|
|
|
|
-- start to set up widget layout ---------
|
|
|
|
------------------------------------------
|
|
|
|
self:update()
|
|
|
|
------------------------------------------
|
|
|
|
-- start to set up input event callback --
|
|
|
|
------------------------------------------
|
2022-01-25 00:32:46 +00:00
|
|
|
self.ges_events.TapCloseMenu = {
|
|
|
|
GestureRange:new{
|
|
|
|
ges = "tap",
|
|
|
|
range = Geom:new{
|
|
|
|
x = 0, y = 0,
|
|
|
|
w = Screen:getWidth(),
|
|
|
|
h = Screen:getHeight(),
|
2014-03-13 13:52:43 +00:00
|
|
|
}
|
|
|
|
}
|
2022-01-25 00:32:46 +00:00
|
|
|
}
|
|
|
|
self.ges_events.SwipeCloseMenu = {
|
|
|
|
GestureRange:new{
|
|
|
|
ges = "swipe",
|
|
|
|
range = Geom:new{
|
|
|
|
x = 0, y = 0,
|
|
|
|
w = Screen:getWidth(),
|
|
|
|
h = Screen:getHeight(),
|
2017-08-14 09:06:10 +00:00
|
|
|
}
|
|
|
|
}
|
2022-01-25 00:32:46 +00:00
|
|
|
}
|
2014-06-10 07:57:10 +00:00
|
|
|
if Device:hasKeys() then
|
2014-03-13 13:52:43 +00:00
|
|
|
-- set up keyboard events
|
2022-01-23 17:40:37 +00:00
|
|
|
local close_keys = Device:hasFewKeys() and { "Back", "Left" } or Device.input.group.Back
|
2022-10-27 00:01:51 +00:00
|
|
|
self.key_events.Close = { { close_keys } }
|
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-07 23:56:32 +00:00
|
|
|
end
|
2013-01-14 16:33:03 +00:00
|
|
|
end
|
|
|
|
|
2013-01-15 09:24:38 +00:00
|
|
|
function ConfigDialog:updateConfigPanel(index)
|
2014-05-28 12:05:38 +00:00
|
|
|
|
2013-07-22 14:08:40 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function ConfigDialog:update()
|
2022-03-04 20:20:00 +00:00
|
|
|
self:moveFocusTo(1, 1) -- reset selected for re-created layout
|
2018-03-22 20:01:38 +00:00
|
|
|
self.layout = {}
|
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 00:51:09 +00:00
|
|
|
|
|
|
|
if self.config_menubar then
|
|
|
|
self.config_menubar:clear()
|
|
|
|
self.config_menubar.panel_index = self.panel_index
|
|
|
|
self.config_menubar:init()
|
|
|
|
else
|
|
|
|
self.config_menubar = MenuBar:new{
|
|
|
|
config_dialog = self,
|
|
|
|
panel_index = self.panel_index,
|
|
|
|
}
|
|
|
|
end
|
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-28 23:20:15 +00:00
|
|
|
if self.config_panel then
|
|
|
|
self.config_panel:free()
|
|
|
|
end
|
2014-03-13 13:52:43 +00:00
|
|
|
self.config_panel = ConfigPanel:new{
|
|
|
|
index = self.panel_index,
|
|
|
|
config_dialog = self,
|
|
|
|
}
|
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 00:51:09 +00:00
|
|
|
|
2021-05-13 11:05:05 +00:00
|
|
|
local old_dimen = self.dialog_frame and self.dialog_frame.dimen and self.dialog_frame.dimen:copy() or Geom:new{}
|
2014-03-13 13:52:43 +00:00
|
|
|
self.dialog_frame = FrameContainer:new{
|
2014-10-22 13:34:11 +00:00
|
|
|
background = Blitbuffer.COLOR_WHITE,
|
2020-12-19 11:18:30 +00:00
|
|
|
padding_bottom = 0, -- ensured by MenuBar
|
2014-03-13 13:52:43 +00:00
|
|
|
VerticalGroup:new{
|
|
|
|
self.config_panel,
|
|
|
|
self.config_menubar,
|
|
|
|
},
|
|
|
|
}
|
2021-05-13 11:05:05 +00:00
|
|
|
-- Ensure we have a sane-ish Geom object *before* paintTo gets called,
|
|
|
|
-- to avoid weirdness in race-y SwipeCloseMenu calls...
|
|
|
|
self.dialog_frame.dimen = old_dimen
|
|
|
|
|
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-07 23:56:32 +00:00
|
|
|
-- Reset the focusmanager cursor
|
2022-03-04 20:20:00 +00:00
|
|
|
self:moveFocusTo(self.panel_index, #self.layout, FocusManager.NOT_FOCUS)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
|
|
|
self[1] = BottomContainer:new{
|
|
|
|
dimen = Screen:getSize(),
|
|
|
|
self.dialog_frame,
|
|
|
|
}
|
2012-12-14 10:20:04 +00:00
|
|
|
end
|
|
|
|
|
2014-12-01 14:39:41 +00:00
|
|
|
function ConfigDialog:onCloseWidget()
|
2018-06-02 16:10:55 +00:00
|
|
|
-- NOTE: As much as we would like to flash here, don't, because of adverse interactions with touchmenu that might lead to a double flash...
|
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 00:14:37 +00:00
|
|
|
UIManager:setDirty(nil, function()
|
2014-12-01 14:39:41 +00:00
|
|
|
return "partial", self.dialog_frame.dimen
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
|
2013-01-15 09:24:38 +00:00
|
|
|
function ConfigDialog:onShowConfigPanel(index)
|
2014-03-13 13:52:43 +00:00
|
|
|
self.panel_index = index
|
2014-11-30 11:26:35 +00:00
|
|
|
local old_dimen = self.dialog_frame.dimen and self.dialog_frame.dimen:copy()
|
2019-10-15 19:57:51 +00:00
|
|
|
local old_layout_h = self.layout and #self.layout
|
2014-03-13 13:52:43 +00:00
|
|
|
self:update()
|
2018-06-02 16:10:55 +00:00
|
|
|
-- NOTE: Keep that one as UI to avoid delay when both this and the topmenu are shown.
|
|
|
|
-- Plus, this is also called for each tab anyway, so that wouldn't have been great.
|
2019-10-15 19:57:51 +00:00
|
|
|
-- NOTE: And we also only need to repaint what's behind us when switching to a smaller dialog...
|
|
|
|
-- This is trickier than in touchmenu, because dimen appear to fluctuate before/after painting...
|
|
|
|
-- So we've settled instead for the amount of lines in the panel, as line-height is constant.
|
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 00:51:09 +00:00
|
|
|
local keep_bg = old_layout_h and #self.layout >= old_layout_h
|
2019-10-15 19:57:51 +00:00
|
|
|
UIManager:setDirty((self.is_fresh or keep_bg) and self or "all", function()
|
2014-11-30 11:26:35 +00:00
|
|
|
local refresh_dimen =
|
|
|
|
old_dimen and old_dimen:combine(self.dialog_frame.dimen)
|
|
|
|
or self.dialog_frame.dimen
|
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 00:14:37 +00:00
|
|
|
self.is_fresh = false
|
2015-04-26 18:07:17 +00:00
|
|
|
return "ui", refresh_dimen
|
2014-11-30 11:26:35 +00:00
|
|
|
end)
|
2014-03-13 13:52:43 +00:00
|
|
|
return true
|
2012-12-14 10:20:04 +00:00
|
|
|
end
|
|
|
|
|
2013-02-02 20:42:59 +00:00
|
|
|
function ConfigDialog:onConfigChoice(option_name, option_value)
|
2021-05-13 02:38:52 +00:00
|
|
|
self.ui:handleEvent(Event:new("ConfigChange", option_name, option_value))
|
2014-03-13 13:52:43 +00:00
|
|
|
return true
|
2013-02-02 20:42:59 +00:00
|
|
|
end
|
|
|
|
|
2021-01-11 17:14:17 +00:00
|
|
|
function ConfigDialog:onConfigEvent(option_event, option_arg, when_applied_callback)
|
|
|
|
self.ui:handleEvent(Event:new(option_event, option_arg, when_applied_callback))
|
2014-03-13 13:52:43 +00:00
|
|
|
return true
|
2014-01-03 14:09:55 +00:00
|
|
|
end
|
|
|
|
|
2021-08-30 15:21:50 +00:00
|
|
|
function ConfigDialog:onConfigChoose(values, name, event, args, position, hide_on_apply)
|
2018-06-02 16:10:55 +00:00
|
|
|
UIManager:tickAfterNext(function()
|
2019-05-05 08:15:13 +00:00
|
|
|
-- Repainting may be delayed depending on options
|
|
|
|
local refresh_dialog_func = function()
|
|
|
|
self.skip_paint = nil
|
2021-05-13 02:38:52 +00:00
|
|
|
UIManager:setDirty(self, function()
|
|
|
|
return "ui", self.dialog_frame.dimen
|
|
|
|
end)
|
2019-05-05 08:15:13 +00:00
|
|
|
end
|
2021-01-11 17:14:17 +00:00
|
|
|
local when_applied_callback = nil
|
|
|
|
if type(hide_on_apply) == "number" then -- timeout
|
|
|
|
UIManager:scheduleIn(hide_on_apply, refresh_dialog_func)
|
2019-05-05 08:15:13 +00:00
|
|
|
self.skip_paint = true
|
2021-01-11 17:14:17 +00:00
|
|
|
elseif hide_on_apply then -- anything but nil or false: provide a callback
|
2019-05-05 08:15:13 +00:00
|
|
|
-- This needs the config option to have an "event" key
|
|
|
|
-- The event handler is responsible for calling this callback when
|
|
|
|
-- it considers it appropriate
|
2021-01-11 17:14:17 +00:00
|
|
|
when_applied_callback = refresh_dialog_func
|
2019-05-05 08:15:13 +00:00
|
|
|
self.skip_paint = true
|
|
|
|
end
|
2014-03-13 13:52:43 +00:00
|
|
|
if values then
|
|
|
|
self:onConfigChoice(name, values[position])
|
|
|
|
end
|
|
|
|
if event then
|
|
|
|
args = args or {}
|
2021-01-11 17:14:17 +00:00
|
|
|
self:onConfigEvent(event, args[position], when_applied_callback)
|
2014-03-13 13:52:43 +00:00
|
|
|
end
|
2019-03-14 21:23:17 +00:00
|
|
|
-- Even if each toggle refreshes itself when toggled, we still
|
|
|
|
-- need to update and repaint the whole config panel, as other
|
|
|
|
-- toggles may have their state (enabled/disabled) modified
|
|
|
|
-- after this toggle update.
|
2015-03-16 13:49:53 +00:00
|
|
|
self:update()
|
2021-01-11 17:14:17 +00:00
|
|
|
if not hide_on_apply then -- immediate refresh
|
2019-05-05 08:15:13 +00:00
|
|
|
refresh_dialog_func()
|
2019-03-14 21:23:17 +00:00
|
|
|
end
|
2014-03-13 13:52:43 +00:00
|
|
|
end)
|
2013-02-02 20:42:59 +00:00
|
|
|
end
|
|
|
|
|
2019-05-01 00:09:01 +00:00
|
|
|
-- Tweaked variant used with the fine_tune variant of buttonprogress (direction can only be "-" or "+")
|
2021-08-30 15:21:50 +00:00
|
|
|
function ConfigDialog:onConfigFineTuneChoose(values, name, event, args, direction, hide_on_apply, params)
|
2019-05-01 00:09:01 +00:00
|
|
|
UIManager:tickAfterNext(function()
|
2019-05-05 08:15:13 +00:00
|
|
|
-- Repainting may be delayed depending on options
|
|
|
|
local refresh_dialog_func = function()
|
|
|
|
self.skip_paint = nil
|
2021-05-13 02:38:52 +00:00
|
|
|
UIManager:setDirty(self, function()
|
|
|
|
return "ui", self.dialog_frame.dimen
|
|
|
|
end)
|
2019-05-05 08:15:13 +00:00
|
|
|
end
|
2021-01-11 17:14:17 +00:00
|
|
|
local when_applied_callback = nil
|
|
|
|
if type(hide_on_apply) == "number" then -- timeout
|
|
|
|
UIManager:scheduleIn(hide_on_apply, refresh_dialog_func)
|
2019-05-05 08:15:13 +00:00
|
|
|
self.skip_paint = true
|
2021-01-11 17:14:17 +00:00
|
|
|
elseif hide_on_apply then -- anything but nil or false: provide a callback
|
2019-05-05 08:15:13 +00:00
|
|
|
-- This needs the config option to have an "event" key
|
|
|
|
-- The event handler is responsible for calling this callback when
|
|
|
|
-- it considers it appropriate
|
2021-01-11 17:14:17 +00:00
|
|
|
when_applied_callback = refresh_dialog_func
|
2019-05-05 08:15:13 +00:00
|
|
|
self.skip_paint = true
|
|
|
|
end
|
2019-05-01 00:09:01 +00:00
|
|
|
if values then
|
|
|
|
local value
|
2020-11-28 16:18:57 +00:00
|
|
|
local step = params and params.value_step or 1
|
2019-05-01 00:09:01 +00:00
|
|
|
if direction == "-" then
|
|
|
|
value = self.configurable[name] or values[1]
|
2019-09-01 19:26:11 +00:00
|
|
|
if type(value) == "table" then
|
2020-07-25 21:15:31 +00:00
|
|
|
-- Don't update directly this table: it might be a reference
|
|
|
|
-- to one of the original preset values tables
|
|
|
|
local updated = {}
|
2019-09-01 19:26:11 +00:00
|
|
|
for i=1, #value do
|
2020-11-28 16:18:57 +00:00
|
|
|
local v = value[i] - step
|
2020-07-25 21:15:31 +00:00
|
|
|
if v < 0 then
|
|
|
|
v = 0
|
2019-09-01 19:26:11 +00:00
|
|
|
end
|
2020-07-25 21:15:31 +00:00
|
|
|
table.insert(updated, v)
|
2019-09-01 19:26:11 +00:00
|
|
|
end
|
2020-07-25 21:15:31 +00:00
|
|
|
value = updated
|
2019-09-01 19:26:11 +00:00
|
|
|
else
|
2020-11-28 16:18:57 +00:00
|
|
|
value = value - step
|
2019-09-01 19:26:11 +00:00
|
|
|
if value < 0 then
|
|
|
|
value = 0
|
|
|
|
end
|
2019-05-01 00:09:01 +00:00
|
|
|
end
|
|
|
|
else
|
|
|
|
value = self.configurable[name] or values[#values]
|
2019-09-01 19:26:11 +00:00
|
|
|
if type(value) == "table" then
|
2020-07-25 21:15:31 +00:00
|
|
|
local updated = {}
|
2019-09-01 19:26:11 +00:00
|
|
|
for i=1, #value do
|
2020-11-28 16:18:57 +00:00
|
|
|
table.insert(updated, value[i] + step)
|
2019-09-01 19:26:11 +00:00
|
|
|
end
|
2020-07-25 21:15:31 +00:00
|
|
|
value = updated
|
2019-09-01 19:26:11 +00:00
|
|
|
else
|
2020-11-28 16:18:57 +00:00
|
|
|
value = value + step
|
2019-09-01 19:26:11 +00:00
|
|
|
end
|
2019-05-01 00:09:01 +00:00
|
|
|
end
|
|
|
|
self:onConfigChoice(name, value)
|
|
|
|
end
|
|
|
|
if event then
|
|
|
|
args = args or {}
|
|
|
|
local arg
|
|
|
|
if direction == "-" then
|
|
|
|
arg = self.configurable[name] or args[1]
|
|
|
|
if not values then
|
|
|
|
arg = arg - 1
|
|
|
|
if arg < 0 then
|
|
|
|
arg = 0
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
arg = self.configurable[name] or args[#args]
|
|
|
|
if not values then
|
|
|
|
arg = arg + 1
|
|
|
|
end
|
|
|
|
end
|
2021-01-11 17:14:17 +00:00
|
|
|
self:onConfigEvent(event, arg, when_applied_callback)
|
2019-05-01 00:09:01 +00:00
|
|
|
end
|
|
|
|
-- Even if each toggle refreshes itself when toggled, we still
|
|
|
|
-- need to update and repaint the whole config panel, as other
|
|
|
|
-- toggles may have their state (enabled/disabled) modified
|
|
|
|
-- after this toggle update.
|
|
|
|
self:update()
|
2021-01-11 17:14:17 +00:00
|
|
|
if not hide_on_apply then -- immediate refresh
|
2019-05-05 08:15:13 +00:00
|
|
|
refresh_dialog_func()
|
2019-05-01 00:09:01 +00:00
|
|
|
end
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
|
2019-09-14 14:30:25 +00:00
|
|
|
-- Tweaked variant used with the more options variant of buttonprogress and fine tune with numpicker
|
|
|
|
-- events are not supported
|
2022-10-04 11:44:55 +00:00
|
|
|
function ConfigDialog:onConfigMoreChoose(values, default_value_orig, name, event, args, name_text, more_options_param)
|
2019-09-14 14:30:25 +00:00
|
|
|
if not more_options_param then
|
|
|
|
more_options_param = {}
|
|
|
|
end
|
|
|
|
UIManager:tickAfterNext(function()
|
|
|
|
-- Repainting may be delayed depending on options
|
2021-01-11 17:14:17 +00:00
|
|
|
local refresh_dialog_func = function(keep_skip_paint)
|
|
|
|
if self.skip_paint and not keep_skip_paint then
|
|
|
|
self.skip_paint = nil
|
|
|
|
end
|
2021-05-13 02:38:52 +00:00
|
|
|
if self.skip_paint then
|
|
|
|
-- Redraw anything below the now hidden ConfigDialog
|
|
|
|
UIManager:setDirty("all", function()
|
|
|
|
return "partial", self.dialog_frame.dimen
|
|
|
|
end)
|
2019-09-14 14:30:25 +00:00
|
|
|
else
|
2021-05-13 02:38:52 +00:00
|
|
|
UIManager:setDirty(self, function()
|
|
|
|
return "ui", self.dialog_frame.dimen
|
|
|
|
end)
|
2019-09-14 14:30:25 +00:00
|
|
|
end
|
|
|
|
end
|
2021-01-11 17:14:17 +00:00
|
|
|
local hide_on_picker_show = more_options_param.hide_on_picker_show
|
|
|
|
if hide_on_picker_show == nil then -- default to true if unset
|
|
|
|
hide_on_picker_show = true
|
|
|
|
end
|
|
|
|
local when_applied_callback = nil
|
|
|
|
if type(hide_on_picker_show) == "number" then -- timeout
|
|
|
|
UIManager:scheduleIn(hide_on_picker_show, refresh_dialog_func)
|
2019-09-14 14:30:25 +00:00
|
|
|
self.skip_paint = true
|
2021-01-11 17:14:17 +00:00
|
|
|
elseif hide_on_picker_show then -- anything but nil or false: provide a callback
|
2019-09-14 14:30:25 +00:00
|
|
|
-- This needs the config option to have an "event" key
|
|
|
|
-- The event handler is responsible for calling this callback when
|
|
|
|
-- it considers it appropriate
|
2021-01-11 17:14:17 +00:00
|
|
|
when_applied_callback = refresh_dialog_func
|
2019-09-14 14:30:25 +00:00
|
|
|
self.skip_paint = true
|
|
|
|
end
|
|
|
|
if values and event then
|
2019-09-27 10:58:40 +00:00
|
|
|
if more_options_param.name then
|
|
|
|
name = more_options_param.name
|
|
|
|
end
|
|
|
|
if more_options_param.name_text then
|
|
|
|
name_text = more_options_param.name_text
|
|
|
|
end
|
|
|
|
if more_options_param.event then
|
|
|
|
event = more_options_param.event
|
|
|
|
end
|
2020-05-09 11:16:12 +00:00
|
|
|
local widget
|
2021-12-01 15:41:30 +00:00
|
|
|
if more_options_param.left_min then -- DoubleSpinWidget
|
2020-05-09 11:16:12 +00:00
|
|
|
local DoubleSpinWidget = require("ui/widget/doublespinwidget")
|
|
|
|
-- (No support for value_table - add it if needed)
|
2022-10-04 11:44:55 +00:00
|
|
|
local curr_values, left_default, right_default
|
2021-01-02 22:15:48 +00:00
|
|
|
if more_options_param.names then -- allows managing 2 different settings
|
|
|
|
curr_values = { self.configurable[more_options_param.names[1]],
|
|
|
|
self.configurable[more_options_param.names[2]] }
|
2022-10-04 11:44:55 +00:00
|
|
|
left_default = G_reader_settings:readSetting(self.config_options.prefix.."_"..more_options_param.names[1])
|
|
|
|
or default_value_orig[1]
|
|
|
|
right_default = G_reader_settings:readSetting(self.config_options.prefix.."_"..more_options_param.names[2])
|
|
|
|
or default_value_orig[2]
|
2021-01-02 22:15:48 +00:00
|
|
|
else
|
|
|
|
curr_values = self.configurable[name]
|
2022-10-04 11:44:55 +00:00
|
|
|
local default_values = G_reader_settings:readSetting(self.config_options.prefix.."_"..name)
|
|
|
|
or default_value_orig
|
|
|
|
left_default = default_values[1]
|
|
|
|
right_default = default_values[2]
|
2021-01-02 22:15:48 +00:00
|
|
|
end
|
2020-05-09 11:16:12 +00:00
|
|
|
widget = DoubleSpinWidget:new{
|
2021-10-01 18:32:16 +00:00
|
|
|
width_factor = more_options_param.widget_width_factor,
|
2021-01-11 17:14:17 +00:00
|
|
|
title_text = name_text or _("Set values"),
|
|
|
|
info_text = more_options_param.info_text,
|
2020-05-09 11:16:12 +00:00
|
|
|
left_text = more_options_param.left_text,
|
|
|
|
right_text = more_options_param.right_text,
|
|
|
|
left_value = curr_values[1],
|
|
|
|
left_min = more_options_param.left_min,
|
|
|
|
left_max = more_options_param.left_max,
|
|
|
|
left_step = more_options_param.left_step,
|
|
|
|
left_hold_step = more_options_param.left_hold_step,
|
|
|
|
right_value = curr_values[2],
|
|
|
|
right_min = more_options_param.right_min,
|
|
|
|
right_max = more_options_param.right_max,
|
|
|
|
right_step = more_options_param.right_step,
|
|
|
|
right_hold_step = more_options_param.right_hold_step,
|
2022-10-04 11:44:55 +00:00
|
|
|
left_default = left_default,
|
|
|
|
right_default = right_default,
|
2020-05-09 11:16:12 +00:00
|
|
|
keep_shown_on_apply = true,
|
2022-06-04 07:35:33 +00:00
|
|
|
unit = more_options_param.unit,
|
|
|
|
precision = more_options_param.precision,
|
2021-01-11 17:14:17 +00:00
|
|
|
close_callback = function()
|
|
|
|
if when_applied_callback then
|
|
|
|
when_applied_callback()
|
|
|
|
when_applied_callback = nil
|
2019-09-23 22:24:45 +00:00
|
|
|
end
|
2021-01-11 17:14:17 +00:00
|
|
|
end,
|
|
|
|
callback = function(left_value, right_value)
|
2020-05-09 11:16:12 +00:00
|
|
|
local value_tables = { left_value, right_value }
|
2021-01-02 22:15:48 +00:00
|
|
|
if more_options_param.names then
|
|
|
|
self:onConfigChoice(more_options_param.names[1], left_value)
|
|
|
|
self:onConfigChoice(more_options_param.names[2], right_value)
|
|
|
|
else
|
|
|
|
self:onConfigChoice(name, value_tables)
|
|
|
|
end
|
2021-01-11 17:14:14 +00:00
|
|
|
if event then
|
2021-01-11 17:14:17 +00:00
|
|
|
-- Repainting (with when_applied_callback) if hide_on_picker_show
|
|
|
|
-- is done in close_callback, but we want onConfigEvent to
|
|
|
|
-- show a message when settings applied: handlers that can do
|
|
|
|
-- it actually do it when provided a callback as argument
|
|
|
|
local dummy_callback = when_applied_callback and function() end
|
2020-05-09 11:16:12 +00:00
|
|
|
args = args or {}
|
2021-05-20 21:14:11 +00:00
|
|
|
Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_MORE)
|
2021-01-11 17:14:17 +00:00
|
|
|
self:onConfigEvent(event, value_tables, dummy_callback)
|
2021-05-20 21:14:11 +00:00
|
|
|
UIManager:tickAfterNext(function()
|
|
|
|
Notification:resetNotifySource()
|
|
|
|
end)
|
2019-09-14 14:30:25 +00:00
|
|
|
self:update()
|
2020-05-09 11:16:12 +00:00
|
|
|
end
|
|
|
|
end,
|
|
|
|
extra_text = _("Set as default"),
|
|
|
|
extra_callback = function(left_value, right_value)
|
|
|
|
local value_tables = { left_value, right_value }
|
|
|
|
local values_string
|
|
|
|
if more_options_param.show_true_value_func then
|
|
|
|
values_string = more_options_param.show_true_value_func(value_tables)
|
2019-09-23 22:24:45 +00:00
|
|
|
else
|
2020-05-09 11:16:12 +00:00
|
|
|
values_string = T("%1, %2", left_value, right_value)
|
|
|
|
end
|
|
|
|
UIManager:show(ConfirmBox:new{
|
|
|
|
text = T(_("Set default %1 to %2?"), (name_text or ""), values_string),
|
|
|
|
ok_text = T(_("Set as default")),
|
|
|
|
ok_callback = function()
|
2021-12-01 15:41:30 +00:00
|
|
|
local setting_name
|
2021-01-02 22:15:48 +00:00
|
|
|
if more_options_param.names then
|
2021-12-01 15:41:30 +00:00
|
|
|
setting_name = self.config_options.prefix.."_"..more_options_param.names[1]
|
|
|
|
G_reader_settings:saveSetting(setting_name, left_value)
|
|
|
|
setting_name = self.config_options.prefix.."_"..more_options_param.names[2]
|
|
|
|
G_reader_settings:saveSetting(setting_name, right_value)
|
2021-01-02 22:15:48 +00:00
|
|
|
else
|
2021-12-01 15:41:30 +00:00
|
|
|
setting_name = self.config_options.prefix.."_"..name
|
|
|
|
G_reader_settings:saveSetting(setting_name, value_tables)
|
2021-01-02 22:15:48 +00:00
|
|
|
end
|
2022-09-25 12:37:22 +00:00
|
|
|
widget.left_default = left_value
|
|
|
|
widget.right_default = right_value
|
|
|
|
widget:update()
|
2020-05-09 11:16:12 +00:00
|
|
|
self:update()
|
|
|
|
UIManager:setDirty(self, function()
|
|
|
|
return "ui", self.dialog_frame.dimen
|
|
|
|
end)
|
|
|
|
end,
|
|
|
|
})
|
|
|
|
end,
|
|
|
|
}
|
|
|
|
else -- SpinWidget with single value
|
|
|
|
local SpinWidget = require("ui/widget/spinwidget")
|
|
|
|
local value_hold_step = 0
|
|
|
|
if more_options_param.value_hold_step then
|
|
|
|
value_hold_step = more_options_param.value_hold_step
|
|
|
|
elseif values and #values > 1 then
|
|
|
|
value_hold_step = values[2] - values[1]
|
|
|
|
end
|
|
|
|
local curr_items = self.configurable[name]
|
2022-09-25 12:37:22 +00:00
|
|
|
local value_index
|
|
|
|
local default_value = G_reader_settings:readSetting(self.config_options.prefix.."_"..name)
|
2022-10-04 11:44:55 +00:00
|
|
|
or default_value_orig
|
2020-05-09 11:16:12 +00:00
|
|
|
if more_options_param.value_table then
|
2022-09-25 12:37:22 +00:00
|
|
|
local table_shift = more_options_param.value_table_shift or 0
|
|
|
|
value_index = curr_items + table_shift
|
|
|
|
default_value = default_value + table_shift
|
2020-05-09 11:16:12 +00:00
|
|
|
end
|
|
|
|
widget = SpinWidget:new{
|
2021-10-01 18:32:16 +00:00
|
|
|
width_factor = more_options_param.widget_width_factor,
|
2021-01-11 17:14:17 +00:00
|
|
|
title_text = name_text or _("Set value"),
|
|
|
|
info_text = more_options_param.info_text,
|
2020-05-09 11:16:12 +00:00
|
|
|
value = curr_items,
|
|
|
|
value_index = value_index,
|
|
|
|
value_table = more_options_param.value_table,
|
|
|
|
value_min = more_options_param.value_min or values[1],
|
|
|
|
value_step = more_options_param.value_step or 1,
|
|
|
|
value_hold_step = value_hold_step,
|
|
|
|
value_max = more_options_param.value_max or values[#values],
|
2022-06-04 07:35:33 +00:00
|
|
|
unit = more_options_param.unit,
|
|
|
|
precision = more_options_param.precision,
|
2022-09-25 12:37:22 +00:00
|
|
|
default_value = default_value,
|
2020-05-09 11:16:12 +00:00
|
|
|
keep_shown_on_apply = true,
|
2021-01-11 17:14:17 +00:00
|
|
|
close_callback = function()
|
|
|
|
if when_applied_callback then
|
|
|
|
when_applied_callback()
|
|
|
|
when_applied_callback = nil
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
callback = function(spin)
|
2022-09-25 12:37:22 +00:00
|
|
|
local spin_value
|
2021-01-11 17:14:17 +00:00
|
|
|
if more_options_param.value_table then
|
2022-09-25 12:37:22 +00:00
|
|
|
local table_shift = more_options_param.value_table_shift or 0
|
|
|
|
spin_value = spin.value_index - table_shift
|
2021-01-11 17:14:17 +00:00
|
|
|
else
|
2022-09-25 12:37:22 +00:00
|
|
|
spin_value = spin.value
|
2021-01-11 17:14:17 +00:00
|
|
|
end
|
2022-09-25 12:37:22 +00:00
|
|
|
self:onConfigChoice(name, spin_value)
|
2021-01-11 17:14:17 +00:00
|
|
|
if event then
|
|
|
|
-- Repainting (with when_applied_callback) if hide_on_picker_show
|
|
|
|
-- is done in close_callback, but we want onConfigEvent to
|
|
|
|
-- show a message when settings applied: handlers that can do
|
|
|
|
-- it actually do it when provided a callback as argument
|
|
|
|
local dummy_callback = when_applied_callback and function() end
|
|
|
|
args = args or {}
|
2021-05-20 21:14:11 +00:00
|
|
|
Notification:setNotifySource(Notification.SOURCE_BOTTOM_MENU_MORE)
|
2022-09-25 12:37:22 +00:00
|
|
|
self:onConfigEvent(event, spin_value, dummy_callback)
|
2021-05-20 21:14:11 +00:00
|
|
|
UIManager:tickAfterNext(function()
|
|
|
|
Notification:resetNotifySource()
|
|
|
|
end)
|
2021-01-11 17:14:17 +00:00
|
|
|
self:update()
|
|
|
|
end
|
|
|
|
end,
|
2020-05-09 11:16:12 +00:00
|
|
|
extra_text = _("Set as default"),
|
|
|
|
extra_callback = function(spin)
|
|
|
|
local value_string
|
|
|
|
if more_options_param.show_true_value_func then
|
|
|
|
value_string = more_options_param.show_true_value_func(spin.value)
|
|
|
|
else
|
|
|
|
value_string = spin.value
|
|
|
|
end
|
|
|
|
UIManager:show(ConfirmBox:new{
|
|
|
|
text = T(_("Set default %1 to %2?"), (name_text or ""), value_string),
|
|
|
|
ok_text = T(_("Set as default")),
|
|
|
|
ok_callback = function()
|
2022-09-25 12:37:22 +00:00
|
|
|
local spin_value
|
2020-05-09 11:16:12 +00:00
|
|
|
if more_options_param.value_table then
|
2022-09-25 12:37:22 +00:00
|
|
|
local table_shift = more_options_param.value_table_shift or 0
|
|
|
|
spin_value = spin.value_index - table_shift
|
|
|
|
widget.default_value = spin.value_index
|
2020-05-09 11:16:12 +00:00
|
|
|
else
|
2022-09-25 12:37:22 +00:00
|
|
|
spin_value = spin.value
|
|
|
|
widget.default_value = spin.value
|
2020-05-09 11:16:12 +00:00
|
|
|
end
|
2022-09-25 12:37:22 +00:00
|
|
|
G_reader_settings:saveSetting(self.config_options.prefix.."_"..name, spin_value)
|
|
|
|
widget:update()
|
2020-05-09 11:16:12 +00:00
|
|
|
self:update()
|
|
|
|
UIManager:setDirty(self, function()
|
|
|
|
return "ui", self.dialog_frame.dimen
|
|
|
|
end)
|
|
|
|
end,
|
|
|
|
})
|
|
|
|
end,
|
2022-06-05 10:36:33 +00:00
|
|
|
option_text = more_options_param.other_button and more_options_param.other_button.text,
|
|
|
|
option_callback = more_options_param.other_button and function()
|
|
|
|
when_applied_callback = nil -- prevent bottom menu from being shown (before being hidden again)
|
|
|
|
widget:onClose()
|
|
|
|
local option = self:findOptionByName(more_options_param.other_button.other_option)
|
2022-10-04 11:44:55 +00:00
|
|
|
local default_value_original
|
|
|
|
if option.more_options_param.names then
|
|
|
|
local option1 = self:findOptionByName(option.more_options_param.names[1])
|
|
|
|
local option2 = self:findOptionByName(option.more_options_param.names[2])
|
|
|
|
default_value_original = { option1.default_value, option2.default_value }
|
|
|
|
else
|
|
|
|
default_value_original = option.default_value
|
|
|
|
end
|
|
|
|
self:onConfigMoreChoose(option.values, default_value_original, option.name,
|
|
|
|
option.event, nil, option.name_text, option.more_options_param)
|
2022-06-05 10:36:33 +00:00
|
|
|
end,
|
2020-05-09 11:16:12 +00:00
|
|
|
}
|
|
|
|
end
|
|
|
|
UIManager:show(widget)
|
2019-09-14 14:30:25 +00:00
|
|
|
end
|
2021-01-11 17:14:17 +00:00
|
|
|
-- Even if skip_paint (to temporarily hide it), we need
|
|
|
|
-- to issue setDirty for what's below to be painted
|
|
|
|
refresh_dialog_func(true)
|
2019-09-14 14:30:25 +00:00
|
|
|
end)
|
|
|
|
end
|
|
|
|
|
2014-07-03 08:30:24 +00:00
|
|
|
function ConfigDialog:onMakeDefault(name, name_text, values, labels, position)
|
2019-03-01 11:55:55 +00:00
|
|
|
local display_value = labels[position]
|
2017-06-19 00:34:01 +00:00
|
|
|
if name == "font_fine_tune" then
|
|
|
|
return
|
2019-03-01 11:55:55 +00:00
|
|
|
-- known table value, make it pretty
|
2019-05-01 00:09:01 +00:00
|
|
|
elseif name == "h_page_margins" then
|
2019-08-22 15:11:47 +00:00
|
|
|
display_value = T(_([[
|
|
|
|
|
2019-05-01 00:09:01 +00:00
|
|
|
left: %1
|
|
|
|
right: %2
|
2019-03-01 11:55:55 +00:00
|
|
|
]]),
|
2019-05-01 00:09:01 +00:00
|
|
|
display_value[1], display_value[2])
|
2019-03-01 11:55:55 +00:00
|
|
|
end
|
|
|
|
-- generic fallback to support table values
|
|
|
|
if type(display_value) == "table" then
|
Logger: Use serpent instead of dump (#9588)
* Persist: support serpent, and use by default over dump (as we assume consistency > readability in Persist).
* Logger/Dbg: Use serpent instead of dump to dump tables (it's slightly more compact, honors __tostring, and will tag tables with their ref, which can come in handy when debugging).
* Dbg: Don't duplicate Logger's log function, just use it directly.
* Fontlist/ConfigDialog: Use serpent for the debug dump.
* Call `os.setlocale(C, "numeric")` on startup instead of peppering it around dump calls. It's process-wide, so it didn't make much sense.
* Trapper: Use LuaJIT's serde facilities instead of dump. They're more reliable in the face of funky input, much faster, and in this case, the data never makes it to human eyes, so a human-readable format didn't gain us anything.
2022-10-06 00:21:03 +00:00
|
|
|
display_value = serpent.block(display_value, { maxlevel = 6, indent = " ", comment = false, nocode = true })
|
2017-06-19 00:34:01 +00:00
|
|
|
end
|
|
|
|
|
2014-07-03 08:30:24 +00:00
|
|
|
UIManager:show(ConfirmBox:new{
|
2014-11-28 13:10:37 +00:00
|
|
|
text = T(
|
|
|
|
_("Set default %1 to %2?"),
|
|
|
|
(name_text or ""),
|
2019-03-01 11:55:55 +00:00
|
|
|
display_value
|
2014-11-28 13:10:37 +00:00
|
|
|
),
|
2020-05-09 11:16:12 +00:00
|
|
|
ok_text = T(_("Set as default")),
|
2014-07-03 08:30:24 +00:00
|
|
|
ok_callback = function()
|
2016-02-16 02:08:04 +00:00
|
|
|
name = self.config_options.prefix.."_"..name
|
2014-07-03 08:30:24 +00:00
|
|
|
G_reader_settings:saveSetting(name, values[position])
|
2019-03-15 22:15:05 +00:00
|
|
|
self:update()
|
|
|
|
UIManager:setDirty(self, function()
|
|
|
|
return "ui", self.dialog_frame.dimen
|
|
|
|
end)
|
2014-07-03 08:30:24 +00:00
|
|
|
end,
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
2019-05-01 00:09:01 +00:00
|
|
|
-- Tweaked variant used with the fine_tune variant of buttonprogress (direction can only be "-" or "+")
|
|
|
|
-- NOTE: This sets the defaults to the *current* value, as the -/+ buttons have no fixed value ;).
|
|
|
|
function ConfigDialog:onMakeFineTuneDefault(name, name_text, values, labels, direction)
|
2019-09-03 11:41:15 +00:00
|
|
|
local current_value = self.configurable[name] or direction == "-" and labels[1] or labels[#labels]
|
|
|
|
|
|
|
|
local display_value
|
|
|
|
-- known table value, make it pretty
|
|
|
|
if name == "h_page_margins" then
|
|
|
|
display_value = T(_([[
|
|
|
|
|
|
|
|
left: %1
|
|
|
|
right: %2
|
|
|
|
]]),
|
|
|
|
current_value[1], current_value[2])
|
|
|
|
elseif type(current_value) == "table" then
|
Logger: Use serpent instead of dump (#9588)
* Persist: support serpent, and use by default over dump (as we assume consistency > readability in Persist).
* Logger/Dbg: Use serpent instead of dump to dump tables (it's slightly more compact, honors __tostring, and will tag tables with their ref, which can come in handy when debugging).
* Dbg: Don't duplicate Logger's log function, just use it directly.
* Fontlist/ConfigDialog: Use serpent for the debug dump.
* Call `os.setlocale(C, "numeric")` on startup instead of peppering it around dump calls. It's process-wide, so it didn't make much sense.
* Trapper: Use LuaJIT's serde facilities instead of dump. They're more reliable in the face of funky input, much faster, and in this case, the data never makes it to human eyes, so a human-readable format didn't gain us anything.
2022-10-06 00:21:03 +00:00
|
|
|
display_value = serpent.block(current_value, { maxlevel = 6, indent = " ", comment = false, nocode = true })
|
2019-09-03 11:41:15 +00:00
|
|
|
else
|
|
|
|
display_value = current_value
|
|
|
|
end
|
2019-05-01 00:09:01 +00:00
|
|
|
|
|
|
|
UIManager:show(ConfirmBox:new{
|
|
|
|
text = T(
|
|
|
|
_("Set default %1 to %2?"),
|
|
|
|
(name_text or ""),
|
|
|
|
display_value
|
|
|
|
),
|
2020-05-09 11:16:12 +00:00
|
|
|
ok_text = T(_("Set as default")),
|
2019-05-01 00:09:01 +00:00
|
|
|
ok_callback = function()
|
|
|
|
name = self.config_options.prefix.."_"..name
|
2019-09-03 11:41:15 +00:00
|
|
|
G_reader_settings:saveSetting(name, current_value)
|
2019-05-01 00:09:01 +00:00
|
|
|
self:update()
|
|
|
|
UIManager:setDirty(self, function()
|
|
|
|
return "ui", self.dialog_frame.dimen
|
|
|
|
end)
|
|
|
|
end,
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
2022-06-05 10:36:33 +00:00
|
|
|
function ConfigDialog:findOptionByName(name)
|
|
|
|
local option
|
|
|
|
for i=1, #self.config_options do
|
|
|
|
local options = self.config_options[i].options
|
|
|
|
for j=1, #options do
|
|
|
|
if options[j].name == name then
|
|
|
|
option = options[j]
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if option then
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return option
|
|
|
|
end
|
|
|
|
|
2013-02-02 20:42:59 +00:00
|
|
|
function ConfigDialog:closeDialog()
|
2014-03-13 13:52:43 +00:00
|
|
|
UIManager:close(self)
|
|
|
|
if self.close_callback then
|
|
|
|
self.close_callback()
|
|
|
|
end
|
|
|
|
return true
|
2012-12-14 10:20:04 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function ConfigDialog:onTapCloseMenu(arg, ges_ev)
|
2014-03-13 13:52:43 +00:00
|
|
|
if ges_ev.pos:notIntersectWith(self.dialog_frame.dimen) then
|
|
|
|
self:closeDialog()
|
|
|
|
return true
|
|
|
|
end
|
2012-12-23 23:54:44 +00:00
|
|
|
end
|
2013-10-18 20:38:07 +00:00
|
|
|
|
2017-08-14 09:06:10 +00:00
|
|
|
function ConfigDialog:onSwipeCloseMenu(arg, ges_ev)
|
2022-09-27 23:10:50 +00:00
|
|
|
local DTAP_ZONE_CONFIG = G_defaults:readSetting("DTAP_ZONE_CONFIG")
|
2021-05-14 15:43:08 +00:00
|
|
|
local range = Geom:new{
|
2017-08-14 09:06:10 +00:00
|
|
|
x = DTAP_ZONE_CONFIG.x * Screen:getWidth(),
|
|
|
|
y = DTAP_ZONE_CONFIG.y * Screen:getHeight(),
|
|
|
|
w = DTAP_ZONE_CONFIG.w * Screen:getWidth(),
|
|
|
|
h = DTAP_ZONE_CONFIG.h * Screen:getHeight(),
|
|
|
|
}
|
2022-09-27 23:10:50 +00:00
|
|
|
local DTAP_ZONE_CONFIG_EXT = G_defaults:readSetting("DTAP_ZONE_CONFIG_EXT")
|
2021-05-14 15:43:08 +00:00
|
|
|
local range_ext = Geom:new{
|
2020-12-03 16:33:54 +00:00
|
|
|
x = DTAP_ZONE_CONFIG_EXT.x * Screen:getWidth(),
|
|
|
|
y = DTAP_ZONE_CONFIG_EXT.y * Screen:getHeight(),
|
|
|
|
w = DTAP_ZONE_CONFIG_EXT.w * Screen:getWidth(),
|
|
|
|
h = DTAP_ZONE_CONFIG_EXT.h * Screen:getHeight(),
|
|
|
|
}
|
2017-08-14 09:06:10 +00:00
|
|
|
if ges_ev.direction == "south" and (ges_ev.pos:intersectWith(self.dialog_frame.dimen)
|
2020-12-03 16:33:54 +00:00
|
|
|
or ges_ev.pos:intersectWith(range) or ges_ev.pos:intersectWith(range_ext)) then
|
2017-08-14 09:06:10 +00:00
|
|
|
self:closeDialog()
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-06-10 07:57:10 +00:00
|
|
|
function ConfigDialog:onClose()
|
|
|
|
self:closeDialog()
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2013-10-18 20:38:07 +00:00
|
|
|
return ConfigDialog
|