2017-09-13 14:56:20 +00:00
--[[--
TouchMenu widget for hierarchical menus .
] ]
2019-12-06 21:55:39 +00:00
local BD = require ( " ui/bidi " )
2017-04-29 08:38:09 +00:00
local Blitbuffer = require ( " ffi/blitbuffer " )
local Button = require ( " ui/widget/button " )
2013-10-18 20:38:07 +00:00
local CenterContainer = require ( " ui/widget/container/centercontainer " )
2017-08-15 07:28:27 +00:00
local CheckMark = require ( " ui/widget/checkmark " )
2017-04-29 08:38:09 +00:00
local Device = require ( " device " )
2018-03-14 21:16:38 +00:00
local FocusManager = require ( " ui/widget/focusmanager " )
2017-04-29 08:38:09 +00:00
local Font = require ( " ui/font " )
local FrameContainer = require ( " ui/widget/container/framecontainer " )
local Geom = require ( " ui/geometry " )
local GestureRange = require ( " ui/gesturerange " )
2013-10-18 20:38:07 +00:00
local HorizontalGroup = require ( " ui/widget/horizontalgroup " )
local HorizontalSpan = require ( " ui/widget/horizontalspan " )
local IconButton = require ( " ui/widget/iconbutton " )
2018-05-25 18:56:37 +00:00
local InfoMessage = require ( " ui/widget/infomessage " )
2017-04-29 08:38:09 +00:00
local InputContainer = require ( " ui/widget/container/inputcontainer " )
local LeftContainer = require ( " ui/widget/container/leftcontainer " )
local LineWidget = require ( " ui/widget/linewidget " )
2022-02-01 19:56:28 +00:00
local RadioMark = require ( " ui/widget/radiomark " )
2017-04-29 08:38:09 +00:00
local RightContainer = require ( " ui/widget/container/rightcontainer " )
2017-09-13 14:56:20 +00:00
local Size = require ( " ui/size " )
2017-04-29 08:38:09 +00:00
local TextWidget = require ( " ui/widget/textwidget " )
2013-10-18 20:38:07 +00:00
local UIManager = require ( " ui/uimanager " )
2018-03-14 21:16:38 +00:00
local UnderlineContainer = require ( " ui/widget/container/underlinecontainer " )
2017-04-29 08:38:09 +00:00
local VerticalGroup = require ( " ui/widget/verticalgroup " )
local VerticalSpan = require ( " ui/widget/verticalspan " )
2020-08-29 16:25:34 +00:00
local util = require ( " util " )
2019-12-06 21:55:39 +00:00
local getMenuText = require ( " ui/widget/menu " ) . getMenuText
2017-04-23 04:32:58 +00:00
local _ = require ( " gettext " )
2019-12-06 21:55:39 +00:00
local T = require ( " ffi/util " ) . template
2018-03-14 21:16:38 +00:00
local Input = Device.input
local Screen = Device.screen
2013-03-14 05:06:42 +00:00
--[[
TouchMenuItem widget
--]]
2013-10-18 20:38:07 +00:00
local TouchMenuItem = InputContainer : new {
2014-03-13 13:52:43 +00:00
menu = nil ,
vertical_align = " center " ,
item = nil ,
dimen = nil ,
2017-04-29 08:38:09 +00:00
face = Font : getFace ( " smallinfofont " ) ,
2014-03-13 13:52:43 +00:00
show_parent = nil ,
2013-03-14 05:06:42 +00:00
}
function TouchMenuItem : init ( )
2014-03-13 13:52:43 +00:00
self.ges_events = {
TapSelect = {
GestureRange : new {
ges = " tap " ,
range = self.dimen ,
} ,
2014-06-05 06:58:53 +00:00
doc = " Select Menu Item " ,
2014-03-13 13:52:43 +00:00
} ,
2014-07-02 14:51:27 +00:00
HoldSelect = {
GestureRange : new {
ges = " hold " ,
range = self.dimen ,
} ,
doc = " Hold Menu Item " ,
} ,
2014-03-13 13:52:43 +00:00
}
2014-05-01 10:37:12 +00:00
local item_enabled = self.item . enabled
if self.item . enabled_func then
item_enabled = self.item . enabled_func ( )
end
2017-08-15 07:28:27 +00:00
local item_checkable = false
2014-06-05 11:06:35 +00:00
local item_checked = self.item . checked
if self.item . checked_func then
2017-08-15 07:28:27 +00:00
item_checkable = true
2014-06-05 11:06:35 +00:00
item_checked = self.item . checked_func ( )
end
2022-02-01 19:56:28 +00:00
local checkmark_widget
if self.item . radio then
checkmark_widget = RadioMark : new {
checkable = item_checkable ,
checked = item_checked ,
enabled = item_enabled ,
}
else
checkmark_widget = CheckMark : new {
checkable = item_checkable ,
checked = item_checked ,
enabled = item_enabled ,
}
end
2019-01-15 17:37:36 +00:00
local checked_widget = CheckMark : new { -- for layout, to :getSize()
checked = true ,
2014-06-05 11:06:35 +00:00
}
2018-07-05 05:20:15 +00:00
-- text_max_width should be the TouchMenuItem width minus the below
-- FrameContainer default paddings minus the checked widget width
local text_max_width = self.dimen . w - 2 * Size.padding . default - checked_widget : getSize ( ) . w
local text = getMenuText ( self.item )
2020-10-05 18:26:33 +00:00
local face = self.face
local forced_baseline , forced_height
if self.item . font_func then
-- A font_func() may be provided by ReaderFont to have each font name
-- displayed in its own font: we must tell TextWidget to use the default
-- font baseline and height for items to be correctly aligned without
-- variations due to each font different metrics.
face = self.item . font_func ( self.face . orig_size )
if face then
local w = TextWidget : new { text = " " , face = self.face }
forced_baseline = w : getBaseline ( )
forced_height = w : getSize ( ) . h
w : free ( )
else
face = self.face
end
end
2021-01-29 17:39:04 +00:00
local text_widget = TextWidget : new {
text = text ,
max_width = text_max_width ,
fgcolor = item_enabled ~= false and Blitbuffer.COLOR_BLACK or Blitbuffer.COLOR_DARK_GRAY ,
face = face ,
forced_baseline = forced_baseline ,
forced_height = forced_height ,
}
self.text_truncated = text_widget : isTruncated ( )
2014-03-13 13:52:43 +00:00
self.item_frame = FrameContainer : new {
width = self.dimen . w ,
bordersize = 0 ,
2014-10-22 13:34:11 +00:00
color = Blitbuffer.COLOR_BLACK ,
2014-03-13 13:52:43 +00:00
HorizontalGroup : new {
align = " center " ,
2014-06-05 11:06:35 +00:00
CenterContainer : new {
dimen = Geom : new { w = checked_widget : getSize ( ) . w } ,
2019-01-15 17:37:36 +00:00
checkmark_widget ,
2014-06-05 11:06:35 +00:00
} ,
2021-01-29 17:39:04 +00:00
text_widget ,
2014-03-13 13:52:43 +00:00
} ,
}
2018-03-14 21:16:38 +00:00
self._underline_container = UnderlineContainer : new {
vertical_align = " center " ,
2018-06-02 16:10:55 +00:00
dimen = self.dimen ,
2018-03-14 21:16:38 +00:00
self.item_frame
}
self [ 1 ] = self._underline_container
function self : isEnabled ( )
return item_enabled ~= false and true
end
end
function TouchMenuItem : onFocus ( )
self._underline_container . color = Blitbuffer.COLOR_BLACK
return true
end
function TouchMenuItem : onUnfocus ( )
self._underline_container . color = Blitbuffer.COLOR_WHITE
return true
2013-03-14 05:06:42 +00:00
end
function TouchMenuItem : onTapSelect ( arg , ges )
2014-05-01 10:37:12 +00:00
local enabled = self.item . enabled
if self.item . enabled_func then
enabled = self.item . enabled_func ( )
end
if enabled == false then return end
2021-06-18 17:23:03 +00:00
-- If the menu hasn't actually been drawn yet, don't do anything (as it's confusing, and the coordinates may be wrong).
if not self.item_frame . dimen then return end
2017-10-10 21:50:45 +00:00
if G_reader_settings : isFalse ( " flash_ui " ) then
2014-11-12 07:39:04 +00:00
self.menu : onMenuSelect ( self.item )
2017-10-10 21:50:45 +00:00
else
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 17:22:48 +00:00
-- c.f., ui/widget/iconbutton for the canonical documentation about the flash_ui code flow
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
-- The item frame's width stops at the text width, but we want it to match the menu's length instead
local highlight_dimen = self.item_frame . dimen
highlight_dimen.w = self.item_frame . width
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 17:22:48 +00:00
-- Highlight
--
2017-10-10 21:50:45 +00:00
self.item_frame . invert = true
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 00:51:09 +00:00
UIManager : widgetInvert ( self.item_frame , highlight_dimen.x , highlight_dimen.y , highlight_dimen.w )
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 17:22:48 +00:00
UIManager : setDirty ( nil , " fast " , highlight_dimen )
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 00:51:09 +00:00
UIManager : forceRePaint ( )
2021-02-22 01:09:44 +00:00
UIManager : yieldToEPDC ( )
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 00:51:09 +00:00
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 17:22:48 +00:00
-- Unhighlight
--
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 00:51:09 +00:00
self.item_frame . invert = false
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 17:22:48 +00:00
-- NOTE: If the menu is going to be closed, we can safely drop that.
if self.item . keep_menu_open then
UIManager : widgetInvert ( self.item_frame , highlight_dimen.x , highlight_dimen.y , highlight_dimen.w )
UIManager : setDirty ( nil , " ui " , highlight_dimen )
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
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 17:22:48 +00:00
-- Callback
--
self.menu : onMenuSelect ( self.item )
Assorted fixes after #7118 (#7161)
* I'd failed to notice that ButtonTable *also* instantiates seven billion Buttons on each update. Unfortunately, that one is way trickier to fix properly, so, work around its behavior in Button. (This fixes multiple issues with stuff using ButtonTable, which is basically anything with a persistent set of buttons. A good and easy test-case is the dictionary popup, e.g., the Highlight button changes text, and the next/prev dic buttons change state. All that, and more, was broken ;p).
* Handle corner-cases related to VirtualKeyboard (e.g., Terminal & Text Editor), which screwed with both TouchMenu & Button heuristics because it's weird.
* Flag a the dictionary switch buttons as vsync
(They trigger a partial repaint of the dictionary content).
* Flag the ReaderSearch buttons as vsync
They very obviously trigger a partial repaint, much like SkimTo ;p.
2021-01-18 15:51:25 +00:00
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 17:22:48 +00:00
UIManager : forceRePaint ( )
2017-10-10 21:50:45 +00:00
end
2014-10-30 07:51:31 +00:00
return true
2013-03-14 05:06:42 +00:00
end
2014-07-02 14:51:27 +00:00
function TouchMenuItem : onHoldSelect ( arg , ges )
local enabled = self.item . enabled
if self.item . enabled_func then
enabled = self.item . enabled_func ( )
end
if enabled == false then return end
2021-06-18 17:23:03 +00:00
if not self.item_frame . dimen then return end
2017-10-10 21:50:45 +00:00
if G_reader_settings : isFalse ( " flash_ui " ) then
2021-01-29 17:39:04 +00:00
self.menu : onMenuHold ( self.item , self.text_truncated )
2017-10-10 21:50:45 +00:00
else
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 17:22:48 +00:00
-- c.f., ui/widget/iconbutton for the canonical documentation about the flash_ui code flow
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
-- The item frame's width stops at the text width, but we want it to match the menu's length instead
local highlight_dimen = self.item_frame . dimen
highlight_dimen.w = self.item_frame . width
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 17:22:48 +00:00
-- Highlight
--
2018-06-02 16:10:55 +00:00
self.item_frame . invert = true
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 00:51:09 +00:00
UIManager : widgetInvert ( self.item_frame , highlight_dimen.x , highlight_dimen.y , highlight_dimen.w )
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 17:22:48 +00:00
UIManager : setDirty ( nil , " fast " , highlight_dimen )
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 00:51:09 +00:00
UIManager : forceRePaint ( )
2021-02-22 01:09:44 +00:00
UIManager : yieldToEPDC ( )
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 00:51:09 +00:00
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 17:22:48 +00:00
-- Unhighlight
--
Revamp "flash_ui" handling (#7118)
* Wherever possible, do an actual dumb invert on the Screen BB instead of repainting the widget, *then* inverting it (which is what the "invert" flag does).
* Instead of playing with nextTick/tickAfterNext delays, explicitly fence stuff with forceRePaint
* And, in the few cases where said Mk. 7 quirk kicks in, make the fences more marked by using a well-placed WAIT_FOR_UPDATE_COMPLETE
* Fix an issue in Button where show/hide & enable/disable where actually all toggles, which meant that duplicate calls or timing issues would do the wrong thing. (This broke dimming some icons, and mistakenly dropped the background from FM chevrons, for example).
* Speaking of, fix Button's hide/show to actually restore the background properly (there was a stupid typo in the variable name)
* Still in Button, fix the insanity of the double repaint on rounded buttons. Turns out it made sense, after all (and was related to said missing background, and bad interaction with invert & text with no background).
* KeyValuePage suffered from a similar issue with broken highlights (all black) because of missing backgrounds.
* In ConfigDialog, only instanciate IconButtons once (because every tab switch causes a full instantiation; and the initial display implies a full instanciation and an initial tab switch). Otherwise, both instances linger, and catch taps, and as such, double highlights.
* ConfigDialog: Restore the "don't repaint ReaderUI" when switching between similarly sized tabs (re #6131). I never could reproduce that on eInk, and I can't now on the emulator, so I'm assuming @poire-z fixed it during the swap to SVG icons.
* KeyValuePage: Only instanciate Buttons once (again, this is a widget that goes through a full init every page). Again, caused highlight/dimming issues because buttons were stacked.
* Menu: Ditto.
* TouchMenu: Now home of the gnarliest unhilight heuristics, because of the sheer amount of different things that can happen (and/or thanks to stuff not flagged covers_fullscreen properly ;p).
* Bump base
https://github.com/koreader/koreader-base/pull/1280
https://github.com/koreader/koreader-base/pull/1282
https://github.com/koreader/koreader-base/pull/1283
https://github.com/koreader/koreader-base/pull/1284
* Bump android-luajit-launcher
https://github.com/koreader/android-luajit-launcher/pull/284
https://github.com/koreader/android-luajit-launcher/pull/285
https://github.com/koreader/android-luajit-launcher/pull/286
https://github.com/koreader/android-luajit-launcher/pull/287
2021-01-10 00:51:09 +00:00
self.item_frame . invert = false
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 17:22:48 +00:00
-- NOTE: If the menu is going to be closed, we can safely drop that.
-- (This field defaults to nil, meaning keep the menu open, hence the negated test)
if self.item . hold_keep_menu_open ~= false then
Assorted fixes after #7118 (#7161)
* I'd failed to notice that ButtonTable *also* instantiates seven billion Buttons on each update. Unfortunately, that one is way trickier to fix properly, so, work around its behavior in Button. (This fixes multiple issues with stuff using ButtonTable, which is basically anything with a persistent set of buttons. A good and easy test-case is the dictionary popup, e.g., the Highlight button changes text, and the next/prev dic buttons change state. All that, and more, was broken ;p).
* Handle corner-cases related to VirtualKeyboard (e.g., Terminal & Text Editor), which screwed with both TouchMenu & Button heuristics because it's weird.
* Flag a the dictionary switch buttons as vsync
(They trigger a partial repaint of the dictionary content).
* Flag the ReaderSearch buttons as vsync
They very obviously trigger a partial repaint, much like SkimTo ;p.
2021-01-18 15:51:25 +00:00
UIManager : widgetInvert ( self.item_frame , highlight_dimen.x , highlight_dimen.y , highlight_dimen.w )
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 17:22:48 +00:00
UIManager : setDirty ( nil , " ui " , highlight_dimen )
Assorted fixes after #7118 (#7161)
* I'd failed to notice that ButtonTable *also* instantiates seven billion Buttons on each update. Unfortunately, that one is way trickier to fix properly, so, work around its behavior in Button. (This fixes multiple issues with stuff using ButtonTable, which is basically anything with a persistent set of buttons. A good and easy test-case is the dictionary popup, e.g., the Highlight button changes text, and the next/prev dic buttons change state. All that, and more, was broken ;p).
* Handle corner-cases related to VirtualKeyboard (e.g., Terminal & Text Editor), which screwed with both TouchMenu & Button heuristics because it's weird.
* Flag a the dictionary switch buttons as vsync
(They trigger a partial repaint of the dictionary content).
* Flag the ReaderSearch buttons as vsync
They very obviously trigger a partial repaint, much like SkimTo ;p.
2021-01-18 15:51:25 +00:00
end
Revamp flash_ui handling, once more, with feeling ;) (#7262)
* Simplify flash_ui handling (by handling the unhighlight pre-callback, c.f., #7262 for more details).
* UIManager: Handle translucent window-level widgets (and those wrapped in a translucent MovableContainer) properly in setDirty directly, making sure what's *underneath* them gets repainted to avoid alpha layering glitches. (This was previously handled via localized hacks).
* Update UIManager's documentation, and format it properly for ldoc parsing, making the HTML docs more useful.
* ReaderView: Reinitialize the various page areas when opening a new document, to prevent poisoning from the previous document.
* Event: Handle nils in an event's arguments.
* CheckButton/RadioButton: Switch to simple inversion to handle highlighting
* CheckButton: Make the highlight span the inner frame's width, instead of just the text's width, if possible.
* AlphaContainer: Fix & simplify, given the UIManager alpha handling.
* MovableContainer: When translucent, cache the canvas bb used for composition.
* Avoid spurious refreshes in a few widgets using various dummy *TextWidgets in order to first compute a text height.
* KeyValuePage: Avoid floats in size computations.
2021-02-20 17:22:48 +00:00
-- Callback
--
self.menu : onMenuHold ( self.item , self.text_truncated )
UIManager : forceRePaint ( )
2017-10-10 21:50:45 +00:00
end
2014-10-30 07:51:31 +00:00
return true
2014-07-02 14:51:27 +00:00
end
2013-03-14 05:06:42 +00:00
--[[
TouchMenuBar widget
--]]
2013-10-18 20:38:07 +00:00
local TouchMenuBar = InputContainer : new {
2014-03-13 13:52:43 +00:00
width = Screen : getWidth ( ) ,
icons = { } ,
-- touch menu that holds the bar, used for trigger repaint on icons
show_parent = nil ,
menu = nil ,
2013-03-14 05:06:42 +00:00
}
function TouchMenuBar : init ( )
2017-09-13 14:56:20 +00:00
local icon_sep_width = Size.span . vertical_default
2014-05-28 12:05:38 +00:00
local icons_sep_width = icon_sep_width * ( # self.icons + 1 )
2014-06-05 04:58:57 +00:00
-- we assume all icons are of the same width
2020-12-19 11:18:30 +00:00
local icon_width = Screen : scaleBySize ( DGENERIC_ICON_SIZE )
2017-09-23 20:01:30 +00:00
local icon_height = icon_width
2017-09-13 08:12:29 +00:00
-- content_width is the width of all the icon images
2017-09-23 20:01:30 +00:00
local content_width = icon_width * # self.icons + icons_sep_width
2014-06-05 04:58:57 +00:00
local spacing_width = ( self.width - content_width ) / ( # self.icons * 2 )
2017-09-23 20:01:30 +00:00
local icon_padding = math.min ( spacing_width , Screen : scaleBySize ( 16 ) )
2020-12-19 11:18:30 +00:00
self.height = icon_height + 2 * Size.padding . default
2014-06-05 04:58:57 +00:00
self.show_parent = self.show_parent or self
self.bar_icon_group = HorizontalGroup : new { }
2014-03-13 13:52:43 +00:00
-- build up image widget for menu icon bar
self.icon_widgets = { }
2014-05-28 12:05:38 +00:00
-- hold icon seperators
self.icon_seps = { }
2014-03-13 13:52:43 +00:00
-- the start_seg for first icon_widget should be 0
-- we asign negative here to offset it in the loop
2014-05-28 12:05:38 +00:00
local start_seg = - icon_sep_width
local end_seg = start_seg
2017-03-26 10:53:55 +00:00
-- self.width is the screen width
2017-09-13 08:12:29 +00:00
-- content_width is the width of all the icon images
-- (2 * icon_padding * #self.icons) is the combined width of icons paddings
local stretch_width = self.width - content_width - ( 2 * icon_padding * # self.icons ) + icon_sep_width
2017-03-26 10:53:55 +00:00
2014-03-13 13:52:43 +00:00
for k , v in ipairs ( self.icons ) do
local ib = IconButton : new {
show_parent = self.show_parent ,
2020-12-19 11:18:30 +00:00
icon = v ,
2017-09-23 20:01:30 +00:00
width = icon_width ,
height = icon_height ,
2014-03-13 13:52:43 +00:00
callback = nil ,
2017-09-27 16:15:11 +00:00
padding_left = icon_padding ,
padding_right = icon_padding ,
2018-03-14 21:16:38 +00:00
menu = self.menu ,
2014-03-13 13:52:43 +00:00
}
2017-09-13 08:12:29 +00:00
table.insert ( self.icon_widgets , ib )
2018-03-14 21:16:38 +00:00
table.insert ( self.menu . layout , ib ) -- for the focusmanager
2014-11-11 02:06:17 +00:00
2014-03-13 13:52:43 +00:00
-- we have to use local variable here for closure callback
2014-05-28 12:05:38 +00:00
local _start_seg = end_seg + icon_sep_width
2014-03-13 13:52:43 +00:00
local _end_seg = _start_seg + self.icon_widgets [ k ] : getSize ( ) . w
2019-12-06 21:55:39 +00:00
end_seg = _end_seg -- for next loop _start_seg
if BD.mirroredUILayout ( ) then
_start_seg , _end_seg = self.width - _end_seg , self.width - _start_seg
end
2014-03-13 13:52:43 +00:00
if k == 1 then
self.bar_sep = LineWidget : new {
dimen = Geom : new {
w = self.width ,
2017-09-13 14:56:20 +00:00
h = Size.line . thick ,
2014-03-13 13:52:43 +00:00
} ,
empty_segments = {
{
s = _start_seg , e = _end_seg
}
} ,
}
end
2014-05-28 12:05:38 +00:00
local icon_sep = LineWidget : new {
style = k == 1 and " solid " or " none " ,
dimen = Geom : new {
2017-02-28 21:46:32 +00:00
w = icon_sep_width ,
2014-05-28 12:05:38 +00:00
h = self.height ,
}
}
2017-03-26 10:53:55 +00:00
-- no separator on the right
if k < # self.icons then
table.insert ( self.icon_seps , icon_sep )
end
2014-05-28 12:05:38 +00:00
-- callback to set visual style
2014-03-13 13:52:43 +00:00
ib.callback = function ( )
self.bar_sep . empty_segments = {
{
s = _start_seg , e = _end_seg
}
}
2014-05-28 12:05:38 +00:00
for i , sep in ipairs ( self.icon_seps ) do
2017-03-26 10:53:55 +00:00
local current_icon , last_icon
if k == # self.icons then
current_icon = false
last_icon = i == k
else
current_icon = i == k - 1 or i == k
last_icon = false
end
-- if the active icon is the last icon then the empty bar segment has
-- to move over to the right by the width of a separator and the stretch width
if last_icon then
2019-12-06 21:55:39 +00:00
local _start_last_seg = icon_sep_width + stretch_width + _start_seg
local _end_last_seg = icon_sep_width + stretch_width + _end_seg
if BD.mirroredUILayout ( ) then
_start_last_seg = _start_seg - icon_sep_width - stretch_width
_end_last_seg = _end_seg - icon_sep_width - stretch_width
end
2017-03-26 10:53:55 +00:00
self.bar_sep . empty_segments = {
{
2019-12-06 21:55:39 +00:00
s = _start_last_seg , e = _end_last_seg
2017-03-26 10:53:55 +00:00
}
}
sep.style = " solid "
-- regular behavior
else
sep.style = current_icon and " solid " or " none "
end
2014-05-28 12:05:38 +00:00
end
2014-03-13 13:52:43 +00:00
self.menu : switchMenuTab ( k )
end
table.insert ( self.bar_icon_group , self.icon_widgets [ k ] )
table.insert ( self.bar_icon_group , icon_sep )
2017-03-26 10:53:55 +00:00
-- if we're at the before-last icon, add an extra span and the final separator
if k == # self.icons - 1 then
table.insert ( self.bar_icon_group , HorizontalSpan : new {
width = stretch_width
} )
-- need to create a new LineWidget otherwise it's just a reference to the same instance
local icon_sep_duplicate = LineWidget : new {
style = " none " ,
dimen = Geom : new {
w = icon_sep_width ,
h = self.height ,
}
}
table.insert ( self.icon_seps , icon_sep_duplicate )
table.insert ( self.bar_icon_group , icon_sep_duplicate )
end
2014-03-13 13:52:43 +00:00
end
self [ 1 ] = FrameContainer : new {
bordersize = 0 ,
padding = 0 ,
VerticalGroup : new {
align = " left " ,
-- bar icons
self.bar_icon_group ,
2014-05-28 12:05:38 +00:00
-- horizontal separate line
2014-03-13 13:52:43 +00:00
self.bar_sep
} ,
}
2014-06-05 04:58:57 +00:00
self.dimen = Geom : new { w = self.width , h = self.height }
2013-03-14 05:06:42 +00:00
end
2014-11-11 02:06:17 +00:00
function TouchMenuBar : switchToTab ( index )
2017-02-25 10:58:39 +00:00
-- a little safety check
-- don't auto-activate a non-existent index
2017-09-13 08:12:29 +00:00
if index > # self.icon_widgets then
2018-04-06 09:32:54 +00:00
index = # self.icon_widgets
2017-02-25 10:58:39 +00:00
end
2020-12-19 11:18:30 +00:00
if self.menu . tab_item_table [ index ] and self.menu . tab_item_table [ index ] . remember == false then
-- Don't auto-activate those that should not be
-- remembered (FM plus menu on non-touch devices)
index = 1
end
2017-09-13 08:12:29 +00:00
self.icon_widgets [ index ] . callback ( )
2014-11-11 02:06:17 +00:00
end
2013-03-14 05:06:42 +00:00
--[[
2014-06-05 12:12:47 +00:00
TouchMenu widget for hierarchical menus
2013-03-14 05:06:42 +00:00
--]]
2018-03-14 21:16:38 +00:00
local TouchMenu = FocusManager : new {
2021-04-15 00:46:44 +00:00
tab_item_table = nil , -- mandatory
2018-06-02 16:10:55 +00:00
-- for returning in multi-level menus
2014-03-13 13:52:43 +00:00
item_table_stack = nil ,
2021-05-25 14:16:53 +00:00
parent_id = nil ,
2014-03-13 13:52:43 +00:00
item_table = nil ,
2017-09-13 14:56:20 +00:00
item_height = Size.item . height_large ,
2017-10-14 20:00:58 +00:00
bordersize = Size.border . window ,
2020-12-19 11:18:30 +00:00
padding = Size.padding . default , -- (not used at top)
2017-04-29 08:38:09 +00:00
fface = Font : getFace ( " ffont " ) ,
2014-03-13 13:52:43 +00:00
width = nil ,
height = nil ,
page = 1 ,
2020-02-14 07:22:25 +00:00
max_per_page_default = 10 ,
2014-03-13 13:52:43 +00:00
-- for UIManager:setDirty
show_parent = nil ,
cur_tab = - 1 ,
close_callback = nil ,
2018-06-02 16:10:55 +00:00
is_fresh = true ,
2013-03-14 05:06:42 +00:00
}
function TouchMenu : init ( )
2017-10-14 20:00:58 +00:00
-- We won't include self.bordersize in our width calculations, so that
-- borders are pushed off-(screen-)width and so not visible.
-- We'll then be similar to bottom menu ConfigDialog (where this
-- nice effect is caused by some width calculations bug).
2015-09-13 08:06:22 +00:00
if not self.dimen then self.dimen = Geom : new { } end
2014-03-13 13:52:43 +00:00
self.show_parent = self.show_parent or self
if not self.close_callback then
self.close_callback = function ( )
UIManager : close ( self.show_parent )
end
end
2018-03-14 21:16:38 +00:00
self.layout = { }
2014-03-13 13:52:43 +00:00
self.ges_events . TapCloseAllMenus = {
GestureRange : new {
ges = " tap " ,
range = Geom : new {
x = 0 , y = 0 ,
w = Screen : getWidth ( ) ,
h = Screen : getHeight ( ) ,
}
}
}
self.ges_events . Swipe = {
GestureRange : new {
ges = " swipe " ,
range = self.dimen ,
}
}
2022-01-23 17:40:37 +00:00
self.key_events . Back = { { Input.group . Back } , doc = " back to upper menu or close touchmenu " }
2020-06-04 11:26:18 +00:00
if Device : hasFewKeys ( ) then
self.key_events . Back = { { " Left " } , doc = " back to upper menu or close touchmenu " }
end
2018-03-14 21:16:38 +00:00
self.key_events . NextPage = { { Input.group . PgFwd } , doc = " next page " }
self.key_events . PrevPage = { { Input.group . PgBack } , doc = " previous page " }
2014-06-10 07:57:10 +00:00
2014-03-13 13:52:43 +00:00
local icons = { }
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 _ , v in ipairs ( self.tab_item_table ) do
2014-03-13 13:52:43 +00:00
table.insert ( icons , v.icon )
end
self.bar = TouchMenuBar : new {
2017-10-14 20:00:58 +00:00
width = self.width , -- will impose width and push left and right borders offscreen
2014-03-13 13:52:43 +00:00
icons = icons ,
show_parent = self.show_parent ,
menu = self ,
}
self.item_group = VerticalGroup : new {
2017-10-14 20:00:58 +00:00
align = " center " ,
2014-03-13 13:52:43 +00:00
}
2014-06-05 12:12:47 +00:00
-- group for page info
2020-12-19 11:18:30 +00:00
local chevron_left = " chevron.left "
local chevron_right = " chevron.right "
2019-12-06 21:55:39 +00:00
if BD.mirroredUILayout ( ) then
chevron_left , chevron_right = chevron_right , chevron_left
end
2014-06-05 12:12:47 +00:00
self.page_info_left_chev = Button : new {
2019-12-06 21:55:39 +00:00
icon = chevron_left ,
2014-06-05 12:12:47 +00:00
callback = function ( ) self : onPrevPage ( ) end ,
2021-04-02 16:12:06 +00:00
hold_callback = function ( ) self : onFirstPage ( ) end ,
2014-06-05 12:12:47 +00:00
bordersize = 0 ,
Enable HW dithering in a few key places (#4541)
* Enable HW dithering on supported devices (Clara HD, Forma; Oasis 2, PW4)
* FileManager and co. (where appropriate, i.e., when covers are shown)
* Book Status
* Reader, where appropriate:
* CRe: on pages whith image content (for over 7.5% of the screen area, should hopefully leave stuff like bullet points or small scene breaks alone).
* Other engines: on user-request (in the gear tab of the bottom menu), via the new "Dithering" knob (will only appear on supported devices).
* ScreenSaver
* ImageViewer
* Minimize repaints when flash_ui is enabled (by, almost everywhere, only repainting the flashing element, and not the toplevel window which hosts it).
(The first pass of this involved fixing a few Button instances whose show_parent was wrong, in particular, chevrons in the FM & TopMenu).
* Hunted down a few redundant repaints (unneeded setDirty("all") calls),
either by switching the widget to nil when only a refresh was needed, and not a repaint,
or by passing the appropritate widget to setDirty.
(Note to self: Enable *verbose* debugging to catch broken setDirty calls via its post guard).
There were also a few instances of 'em right behind a widget close.
* Don't repaint the underlying widget when initially showing TopMenu & ConfigDialog.
We unfortunately do need to do it when switching tabs, because of their variable heights.
* On Kobo, disabled the extra and completely useless full refresh before suspend/reboot/poweroff, as well as on resume. No more double refreshes!
* Fix another debug guard in Kobo sysfs_light
* Switch ImageWidget & ImageViewer mostly to "ui" updates, which will be better suited to image content pretty much everywhere, REAGL or not.
PS: (Almost :100: commits! :D)
2019-02-07 00:14:37 +00:00
show_parent = self.show_parent ,
2014-06-05 12:12:47 +00:00
}
self.page_info_right_chev = Button : new {
2019-12-06 21:55:39 +00:00
icon = chevron_right ,
2014-06-05 12:12:47 +00:00
callback = function ( ) self : onNextPage ( ) end ,
2021-04-02 16:12:06 +00:00
hold_callback = function ( ) self : onLastPage ( ) end ,
2014-06-05 12:12:47 +00:00
bordersize = 0 ,
Enable HW dithering in a few key places (#4541)
* Enable HW dithering on supported devices (Clara HD, Forma; Oasis 2, PW4)
* FileManager and co. (where appropriate, i.e., when covers are shown)
* Book Status
* Reader, where appropriate:
* CRe: on pages whith image content (for over 7.5% of the screen area, should hopefully leave stuff like bullet points or small scene breaks alone).
* Other engines: on user-request (in the gear tab of the bottom menu), via the new "Dithering" knob (will only appear on supported devices).
* ScreenSaver
* ImageViewer
* Minimize repaints when flash_ui is enabled (by, almost everywhere, only repainting the flashing element, and not the toplevel window which hosts it).
(The first pass of this involved fixing a few Button instances whose show_parent was wrong, in particular, chevrons in the FM & TopMenu).
* Hunted down a few redundant repaints (unneeded setDirty("all") calls),
either by switching the widget to nil when only a refresh was needed, and not a repaint,
or by passing the appropritate widget to setDirty.
(Note to self: Enable *verbose* debugging to catch broken setDirty calls via its post guard).
There were also a few instances of 'em right behind a widget close.
* Don't repaint the underlying widget when initially showing TopMenu & ConfigDialog.
We unfortunately do need to do it when switching tabs, because of their variable heights.
* On Kobo, disabled the extra and completely useless full refresh before suspend/reboot/poweroff, as well as on resume. No more double refreshes!
* Fix another debug guard in Kobo sysfs_light
* Switch ImageWidget & ImageViewer mostly to "ui" updates, which will be better suited to image content pretty much everywhere, REAGL or not.
PS: (Almost :100: commits! :D)
2019-02-07 00:14:37 +00:00
show_parent = self.show_parent ,
2014-06-05 12:12:47 +00:00
}
self.page_info_left_chev : hide ( )
self.page_info_right_chev : hide ( )
self.page_info_text = TextWidget : new {
2014-03-13 13:52:43 +00:00
text = " " ,
2014-06-05 12:12:47 +00:00
face = self.fface ,
}
self.page_info = HorizontalGroup : new {
self.page_info_left_chev ,
self.page_info_text ,
self.page_info_right_chev
2014-03-13 13:52:43 +00:00
}
2018-06-02 16:10:55 +00:00
-- group for device info
2014-03-13 13:52:43 +00:00
self.time_info = TextWidget : new {
text = " " ,
2014-06-05 12:12:47 +00:00
face = self.fface ,
2014-03-13 13:52:43 +00:00
}
2014-11-11 04:12:34 +00:00
self.device_info = HorizontalGroup : new {
self.time_info ,
2017-10-14 20:00:58 +00:00
-- Add some span to balance up_button image included padding
HorizontalSpan : new { width = Size.span . horizontal_default } ,
2014-11-11 04:12:34 +00:00
}
2019-08-03 16:02:45 +00:00
local footer_width = self.width - self.padding * 2
2014-11-20 10:02:28 +00:00
local up_button = IconButton : new {
2020-12-19 11:18:30 +00:00
icon = " chevron.up " ,
2014-11-20 10:02:28 +00:00
show_parent = self.show_parent ,
2020-06-12 23:56:36 +00:00
padding_left = math.floor ( footer_width * 0.33 * 0.1 ) ,
padding_right = math.floor ( footer_width * 0.33 * 0.1 ) ,
2014-11-20 10:02:28 +00:00
callback = function ( )
self : backToUpperMenu ( )
end ,
}
2017-09-13 14:56:20 +00:00
local footer_height = up_button : getSize ( ) . h + Size.line . thick
2014-03-13 13:52:43 +00:00
self.footer = HorizontalGroup : new {
LeftContainer : new {
2020-06-12 23:56:36 +00:00
dimen = Geom : new { w = math.floor ( footer_width * 0.33 ) , h = footer_height } ,
2014-11-20 10:02:28 +00:00
up_button ,
2014-03-13 13:52:43 +00:00
} ,
CenterContainer : new {
2020-06-12 23:56:36 +00:00
dimen = Geom : new { w = math.floor ( footer_width * 0.33 ) , h = footer_height } ,
2014-06-05 12:12:47 +00:00
self.page_info ,
2014-03-13 13:52:43 +00:00
} ,
RightContainer : new {
2020-06-12 23:56:36 +00:00
dimen = Geom : new { w = math.floor ( footer_width * 0.33 ) , h = footer_height } ,
2014-09-14 14:05:28 +00:00
self.device_info ,
2014-03-13 13:52:43 +00:00
}
}
2017-10-14 20:00:58 +00:00
self.menu_frame = FrameContainer : new {
2014-03-13 13:52:43 +00:00
padding = self.padding ,
2020-12-19 11:18:30 +00:00
padding_top = 0 , -- ensured by TouchMenuBar
2014-03-13 13:52:43 +00:00
bordersize = self.bordersize ,
2014-10-22 13:34:11 +00:00
background = Blitbuffer.COLOR_WHITE ,
2014-03-13 13:52:43 +00:00
-- menubar and footer will be inserted in
-- item_group in updateItems
self.item_group ,
}
2017-10-14 20:00:58 +00:00
-- This CenterContainer will make the left and right borders drawn
-- off-screen
self [ 1 ] = CenterContainer : new {
dimen = Screen : getSize ( ) ,
ignore = " height " ,
self.menu_frame
}
2014-03-13 13:52:43 +00:00
2017-10-14 20:00:58 +00:00
self.item_width = self.width - self.padding * 2
2016-02-28 21:32:25 +00:00
self.split_line = HorizontalGroup : new {
-- pad with 10 pixel to align with the up arrow in footer
2017-09-13 14:56:20 +00:00
HorizontalSpan : new { width = Size.span . horizontal_default } ,
2016-02-28 21:32:25 +00:00
LineWidget : new {
2019-03-14 19:58:45 +00:00
background = Blitbuffer.COLOR_GRAY ,
2016-02-28 21:32:25 +00:00
dimen = Geom : new {
2017-10-14 20:00:58 +00:00
w = self.item_width - 2 * Size.span . horizontal_default ,
2017-09-13 14:56:20 +00:00
h = Size.line . medium ,
2016-02-28 21:32:25 +00:00
}
2017-10-14 20:00:58 +00:00
} ,
HorizontalSpan : new { width = Size.span . horizontal_default } ,
2016-02-28 21:32:25 +00:00
}
2017-09-13 14:56:20 +00:00
self.footer_top_margin = VerticalSpan : new { width = Size.span . vertical_default }
2016-02-28 21:32:25 +00:00
self.bar : switchToTab ( self.last_index or 1 )
2013-03-14 05:06:42 +00:00
end
2014-12-01 16:21:42 +00:00
function TouchMenu : onCloseWidget ( )
ReaderUI: Saner FM/RD lifecycle
* Ensure that going from one to the other tears down the former and
its plugins before instantiating the latter and its plugins.
UIManager: Unify Event sending & broadcasting
* Make the two behave the same way (walk the widget stack from top to
bottom), and properly handle the window stack shrinking shrinking
*and* growing.
Previously, broadcasting happened bottom-to-top and didn't really
handle the list shrinking/growing, while sending only handled the list
shrinking by a single element, and hopefully that element being the one
the event was just sent to.
These two items combined allowed us to optimize suboptimal
refresh behavior with Menu and other Menu classes when
opening/closing a document.
e.g., the "opening document" Notification is now properly regional,
and the "open last doc" option no longer flashes like a crazy person
anymore.
Plugins: Allow optimizing Menu refresh with custom menus, too.
Requires moving Menu's close_callback *after* onMenuSelect, which, eh,
probably makes sense, and is probably harmless in the grand scheme of
things.
2021-05-01 16:53:04 +00:00
-- NOTE: We don't pass a region in order to ensure a full-screen flash to avoid ghosting,
-- but we only need to do that if we actually have a FM or RD below us.
-- Don't do anything when we're switching between the two, or if we don't actually have a live instance of 'em...
local FileManager = require ( " apps/filemanager/filemanager " )
local ReaderUI = require ( " apps/reader/readerui " )
local reader_ui = ReaderUI : _getRunningInstance ( )
if ( FileManager.instance and not FileManager.instance . tearing_down ) or ( reader_ui and not reader_ui.tearing_down ) then
UIManager : setDirty ( nil , " flashui " )
end
2014-12-01 16:21:42 +00:00
end
2016-02-28 21:32:25 +00:00
function TouchMenu : _recalculatePageLayout ( )
local content_height -- content == item_list + footer
2014-03-13 13:52:43 +00:00
2016-02-28 21:32:25 +00:00
local bar_height = self.bar : getSize ( ) . h
local footer_height = self.footer : getSize ( ) . h
if self.height then
content_height = self.height - bar_height
2014-03-13 13:52:43 +00:00
else
2016-02-28 21:32:25 +00:00
content_height = # self.item_table * self.item_height + footer_height
-- split line height
content_height = content_height + ( # self.item_table - 1 )
content_height = content_height + self.footer_top_margin : getSize ( ) . h
2014-03-13 13:52:43 +00:00
end
2016-02-28 21:32:25 +00:00
if content_height + bar_height > Screen : getHeight ( ) then
content_height = Screen : getHeight ( ) - bar_height
2014-03-13 13:52:43 +00:00
end
2016-02-28 21:32:25 +00:00
local item_list_content_height = content_height - footer_height
self.perpage = math.floor ( item_list_content_height / self.item_height )
2020-02-14 07:22:25 +00:00
local max_per_page = self.item_table . max_per_page or self.max_per_page_default
if self.perpage > max_per_page then
self.perpage = max_per_page
2014-03-13 13:52:43 +00:00
end
self.page_num = math.ceil ( # self.item_table / self.perpage )
2013-03-14 05:06:42 +00:00
end
function TouchMenu : updateItems ( )
2014-11-30 12:04:33 +00:00
local old_dimen = self.dimen and self.dimen : copy ( )
2016-02-28 21:32:25 +00:00
self : _recalculatePageLayout ( )
2014-03-13 13:52:43 +00:00
self.item_group : clear ( )
2018-03-14 21:16:38 +00:00
self.layout = { }
2014-03-13 13:52:43 +00:00
table.insert ( self.item_group , self.bar )
2018-06-02 16:10:55 +00:00
table.insert ( self.layout , self.bar . icon_widgets ) -- for the focusmanager
2014-03-13 13:52:43 +00:00
for c = 1 , self.perpage do
-- calculate index in item_table
local i = ( self.page - 1 ) * self.perpage + c
if i <= # self.item_table then
2017-02-28 21:46:32 +00:00
local item = self.item_table [ i ]
2017-03-05 11:57:39 +00:00
local item_tmp = TouchMenuItem : new {
item = item ,
menu = self ,
dimen = Geom : new {
w = self.item_width ,
h = self.item_height ,
} ,
show_parent = self.show_parent ,
}
table.insert ( self.item_group , item_tmp )
2018-03-14 21:16:38 +00:00
if item_tmp : isEnabled ( ) then
2018-06-02 16:10:55 +00:00
table.insert ( self.layout , { [ self.cur_tab ] = item_tmp } ) -- for the focusmanager
2018-03-14 21:16:38 +00:00
end
2017-03-05 11:57:39 +00:00
if item.separator and c ~= self.perpage then
-- insert split line
table.insert ( self.item_group , self.split_line )
2014-03-13 13:52:43 +00:00
end
else
-- item not enough to fill the whole page, break out of loop
2016-02-16 06:34:28 +00:00
break
2014-03-13 13:52:43 +00:00
end -- if i <= self.items
end -- for c=1, self.perpage
2016-02-28 21:32:25 +00:00
table.insert ( self.item_group , self.footer_top_margin )
2014-03-13 13:52:43 +00:00
table.insert ( self.item_group , self.footer )
2019-10-21 12:24:29 +00:00
if self.page_num > 1 then
-- @translators %1 is the current page. %2 is the total number of pages. In some languages a good translation might need to reverse this order, for instance: "Total %2, page %1".
2019-12-06 21:55:39 +00:00
self.page_info_text : setText ( T ( _ ( " Page %1 of %2 " ) , self.page , self.page_num ) )
2019-10-21 12:24:29 +00:00
else
self.page_info_text : setText ( " " )
end
2014-06-05 12:12:47 +00:00
self.page_info_left_chev : showHide ( self.page_num > 1 )
self.page_info_right_chev : showHide ( self.page_num > 1 )
self.page_info_left_chev : enableDisable ( self.page > 1 )
self.page_info_right_chev : enableDisable ( self.page < self.page_num )
2019-10-21 12:24:29 +00:00
ReaderFooter: Don't duplicate a 12h clock time format option (#6973)
* ReaderFooter:
* Honor the global twelve_hour_clock setting, instead of
duplicating a local one.
(Re #6969)
* os.date is a thin wrapper around strftime, so we might be able to get
away with some not-quite-standard extensions...
These are *definitely* supported on Linux, but are *NOT* the glibc
extension (that'd be e.g., %-I), so, hopefully, they're somewhat
portable...
They are also supported on BSD/macOS.
They are *not* supported by the MS UCRT. That means MinGW-w64, too.
This *appears* to be supported on current Bionic (it might even support
said glibc format altering extensions).
* And of course, Windows is terrible, so, make this terribly ugly to not
break it there...
* Turns out BSD also supports the dash trim format extension, so, leave
the trimming to the libc, and handle the special-casing in a way that
doesn't create stupid locals.
* Random unrelated cleanup ^^.
(https://gitter.im/koreader/koreader?at=5fd24be492aa1c4ef5d11f31)
* Update the testsuite
(Because the default used to be 24h clock).
Changed the default to 24h clock ;p.
* Explain why we don't try to fix it in Lua
2020-12-12 09:44:35 +00:00
local time_info_txt = util.secondsToHour ( os.time ( ) , G_reader_settings : isTrue ( " twelve_hour_clock " ) )
2019-10-27 04:22:17 +00:00
local powerd = Device : getPowerDevice ( )
2020-07-20 22:52:50 +00:00
if Device : hasBattery ( ) then
2022-01-15 22:36:46 +00:00
local batt_lvl = powerd : getCapacity ( )
A host of low power states related tweaks (#9036)
* Disable all non power management related input during suspend. (This prevents wonky touch events from being tripped when closing a sleep cover on an already-in-suspend device, among other things).
* Kobo: Use our WakeupMgr instance, not the class.
* WakupMgr: split `removeTask` in two:
* `removeTask`, which *only* takes a queue index as input, and only removes a single task. Greatly simplifies the function (i.e., it's just a `table.remove`).
* `removeTasks`, which takes an epoch or a cb ref, and removes *every* task that matches.
* Both of these will also *always* re-schedule the next task (if any) on exit, since we can have multiple WakeupMgr tasks queued, but we can only have a single RTC wake alarm set ;).
* `wakeupAction` now takes a `proximity` argument, which it passes on to its `validateWakeupAlarmByProximity` call, allowing call sites to avoir having to duplicate that call themselves when they want to use a custom proximity window.
* `wakeupAction` now re-schedules the next task (if any) on exit.
* Simplify `Kobo:checkUnexpectedWakeup`, by removing the duplicate `WakerupMgr:validateWakeupAlarmByProximity` call, now that we can pass a proximity window to `WakeuoMgr:wakeupAction`.
* The various network activity timeouts are now halved when autostandby is enabled.
* Autostandby: get rid of the dummy deadline_guard task, as it's no longer necessary since #9009.
* UIManager: The previous change allows us to simplify `getNextTaskTimes` into a simpler `getNextTaskTime` variant, getting rid of a table & a loop.
* ReaderFooter & ReaderHeader: Make sure we only perform a single refresh when exiting standby.
* Kobo: Rewrite sysfs writes to use ANSI C via FFI instead of stdio via Lua, as it obscured some common error cases (e.g., EBUSY on /sys/power/state).
* Kobo: Simplify `suspend`, now that we have sane error handling in sysfs writes.
* Kobo.powerd: Change `isCharging` & `isAuxCharging` behavior to match the behavior of the NTX ioctl (i.e., Charging == Plugged-in). This has the added benefit of making the AutoSuspend checks behave sensibly in the "fully-charged but still plugged in" scenario (because being plugged in is enough to break PM on `!canPowerSaveWhileCharging` devices).
* AutoSuspend: Disable our `AllowStandby` handler when auto standby is disabled, so as to not interfere with other modules using `UIManager:allowStandby` (fix #9038).
* PowerD: Allow platforms to implement `isCharged`, indicating that the battery is full while still plugged in to a power source (battery icon becomes a power plug icon).
* Kobo.powerd: Implement `isCharged`, and kill charging LEDs once battery is full.
* Kindle.powerd: Implement `isCharged` on post-Wario devices. (`isCharging` is still true in that state, as it ought to).
2022-05-01 21:41:08 +00:00
local batt_symbol = powerd : getBatterySymbol ( powerd : isCharged ( ) , powerd : isCharging ( ) , batt_lvl )
2020-04-11 15:45:37 +00:00
time_info_txt = BD.wrap ( time_info_txt ) .. " " .. BD.wrap ( " ⌁ " ) .. BD.wrap ( batt_symbol ) .. BD.wrap ( batt_lvl .. " % " )
2022-01-15 22:36:46 +00:00
if Device : hasAuxBattery ( ) and powerd : isAuxBatteryConnected ( ) then
local aux_batt_lvl = powerd : getAuxCapacity ( )
A host of low power states related tweaks (#9036)
* Disable all non power management related input during suspend. (This prevents wonky touch events from being tripped when closing a sleep cover on an already-in-suspend device, among other things).
* Kobo: Use our WakeupMgr instance, not the class.
* WakupMgr: split `removeTask` in two:
* `removeTask`, which *only* takes a queue index as input, and only removes a single task. Greatly simplifies the function (i.e., it's just a `table.remove`).
* `removeTasks`, which takes an epoch or a cb ref, and removes *every* task that matches.
* Both of these will also *always* re-schedule the next task (if any) on exit, since we can have multiple WakeupMgr tasks queued, but we can only have a single RTC wake alarm set ;).
* `wakeupAction` now takes a `proximity` argument, which it passes on to its `validateWakeupAlarmByProximity` call, allowing call sites to avoir having to duplicate that call themselves when they want to use a custom proximity window.
* `wakeupAction` now re-schedules the next task (if any) on exit.
* Simplify `Kobo:checkUnexpectedWakeup`, by removing the duplicate `WakerupMgr:validateWakeupAlarmByProximity` call, now that we can pass a proximity window to `WakeuoMgr:wakeupAction`.
* The various network activity timeouts are now halved when autostandby is enabled.
* Autostandby: get rid of the dummy deadline_guard task, as it's no longer necessary since #9009.
* UIManager: The previous change allows us to simplify `getNextTaskTimes` into a simpler `getNextTaskTime` variant, getting rid of a table & a loop.
* ReaderFooter & ReaderHeader: Make sure we only perform a single refresh when exiting standby.
* Kobo: Rewrite sysfs writes to use ANSI C via FFI instead of stdio via Lua, as it obscured some common error cases (e.g., EBUSY on /sys/power/state).
* Kobo: Simplify `suspend`, now that we have sane error handling in sysfs writes.
* Kobo.powerd: Change `isCharging` & `isAuxCharging` behavior to match the behavior of the NTX ioctl (i.e., Charging == Plugged-in). This has the added benefit of making the AutoSuspend checks behave sensibly in the "fully-charged but still plugged in" scenario (because being plugged in is enough to break PM on `!canPowerSaveWhileCharging` devices).
* AutoSuspend: Disable our `AllowStandby` handler when auto standby is disabled, so as to not interfere with other modules using `UIManager:allowStandby` (fix #9038).
* PowerD: Allow platforms to implement `isCharged`, indicating that the battery is full while still plugged in to a power source (battery icon becomes a power plug icon).
* Kobo.powerd: Implement `isCharged`, and kill charging LEDs once battery is full.
* Kindle.powerd: Implement `isCharged` on post-Wario devices. (`isCharging` is still true in that state, as it ought to).
2022-05-01 21:41:08 +00:00
local aux_batt_symbol = powerd : getBatterySymbol ( powerd : isAuxCharged ( ) , powerd : isAuxCharging ( ) , aux_batt_lvl )
2022-01-15 22:36:46 +00:00
time_info_txt = time_info_txt .. " " .. BD.wrap ( " + " ) .. BD.wrap ( aux_batt_symbol ) .. BD.wrap ( aux_batt_lvl .. " % " )
end
2020-04-11 15:45:37 +00:00
end
2016-02-28 21:32:25 +00:00
self.time_info : setText ( time_info_txt )
-- recalculate dimen based on new layout
self.dimen . w = self.width
2020-12-19 11:18:30 +00:00
self.dimen . h = self.item_group : getSize ( ) . h + self.bordersize * 2 + self.padding -- (no padding at top)
2022-03-04 20:20:00 +00:00
self : moveFocusTo ( self.cur_tab , 1 , FocusManager.NOT_FOCUS ) -- reset the position of the focusmanager
2014-11-30 12:04:33 +00:00
2018-06-02 16:10:55 +00:00
-- NOTE: We use a slightly ugly hack to detect a brand new menu vs. a tab switch,
-- in order to optionally flash on initial menu popup...
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
-- NOTE: Also avoid repainting what's underneath us on initial popup.
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 menu...
local keep_bg = old_dimen and self.dimen . h >= old_dimen.h
UIManager : setDirty ( ( self.is_fresh or keep_bg ) and self.show_parent or " all " , function ( )
2014-11-30 12:04:33 +00:00
local refresh_dimen =
old_dimen and old_dimen : combine ( self.dimen )
or self.dimen
2018-06-02 16:10:55 +00:00
local refresh_type = " ui "
if self.is_fresh then
refresh_type = " flashui "
-- Drop the region, too, to make it full-screen? May help when starting from a "small" menu.
--refresh_dimen = nil
self.is_fresh = false
end
return refresh_type , refresh_dimen
2014-11-30 12:04:33 +00:00
end )
2013-03-14 05:06:42 +00:00
end
2014-09-14 14:05:28 +00:00
2013-03-14 05:06:42 +00:00
function TouchMenu : switchMenuTab ( tab_num )
2014-11-11 02:06:17 +00:00
if self.tab_item_table [ tab_num ] . remember ~= false then
self.last_index = tab_num
end
2014-11-05 04:15:07 +00:00
if self.touch_menu_callback then
self.touch_menu_callback ( )
end
2014-03-13 13:52:43 +00:00
if self.tab_item_table [ tab_num ] . callback then
self.tab_item_table [ tab_num ] . callback ( )
end
2020-12-29 22:08:49 +00:00
-- It's like getting a new menu everytime we switch tab!
-- Also, switching to the _same_ tab resets the stack and takes us back to
-- the top of the menu tree
self.page = 1
-- clear item table stack
self.item_table_stack = { }
2021-05-25 14:16:53 +00:00
self.parent_id = nil
2020-12-29 22:08:49 +00:00
self.cur_tab = tab_num
self.item_table = self.tab_item_table [ tab_num ]
self : updateItems ( )
2013-03-15 09:18:34 +00:00
end
function TouchMenu : backToUpperMenu ( )
2014-03-13 13:52:43 +00:00
if # self.item_table_stack ~= 0 then
self.item_table = table.remove ( self.item_table_stack )
self.page = 1
2021-05-25 14:16:53 +00:00
if self.parent_id then
self : _recalculatePageLayout ( ) -- we need an accurate self.perpage
for i = 1 , # self.item_table do
if self.item_table [ i ] . menu_item_id == self.parent_id then
self.page = math.floor ( ( i - 1 ) / self.perpage ) + 1
break
end
end
self.parent_id = nil
end
2014-03-13 13:52:43 +00:00
self : updateItems ( )
2014-11-30 12:04:33 +00:00
else
self : closeMenu ( )
2014-03-13 13:52:43 +00:00
end
2013-03-14 05:06:42 +00:00
end
function TouchMenu : closeMenu ( )
2014-03-13 13:52:43 +00:00
self.close_callback ( )
2013-03-14 05:06:42 +00:00
end
2013-03-16 00:30:42 +00:00
function TouchMenu : onNextPage ( )
2014-03-13 13:52:43 +00:00
if self.page < self.page_num then
self.page = self.page + 1
2015-08-01 09:44:40 +00:00
elseif self.page == self.page_num then
self.page = 1
2014-03-13 13:52:43 +00:00
end
2015-08-01 09:44:40 +00:00
self : updateItems ( )
2014-03-13 13:52:43 +00:00
return true
2013-03-16 00:30:42 +00:00
end
function TouchMenu : onPrevPage ( )
2014-03-13 13:52:43 +00:00
if self.page > 1 then
self.page = self.page - 1
2015-08-01 09:44:40 +00:00
elseif self.page == 1 then
self.page = self.page_num
2014-03-13 13:52:43 +00:00
end
2015-08-01 09:44:40 +00:00
self : updateItems ( )
2014-03-13 13:52:43 +00:00
return true
2013-03-16 00:30:42 +00:00
end
2021-04-02 16:12:06 +00:00
function TouchMenu : onFirstPage ( )
self.page = 1
self : updateItems ( )
return true
end
function TouchMenu : onLastPage ( )
self.page = self.page_num
self : updateItems ( )
return true
end
2013-03-16 00:30:42 +00:00
function TouchMenu : onSwipe ( arg , ges_ev )
2019-12-06 21:55:39 +00:00
local direction = BD.flipDirectionIfMirroredUILayout ( ges_ev.direction )
if direction == " west " then
2014-03-13 13:52:43 +00:00
self : onNextPage ( )
2019-12-06 21:55:39 +00:00
elseif direction == " east " then
2014-03-13 13:52:43 +00:00
self : onPrevPage ( )
2019-12-06 21:55:39 +00:00
elseif direction == " north " then
2017-04-15 12:45:56 +00:00
self : closeMenu ( )
2014-03-13 13:52:43 +00:00
end
2013-03-16 00:30:42 +00:00
end
2013-03-14 05:06:42 +00:00
function TouchMenu : onMenuSelect ( item )
2014-11-05 04:15:07 +00:00
if self.touch_menu_callback then
self.touch_menu_callback ( )
end
2017-03-28 22:47:18 +00:00
if item.tap_input or type ( item.tap_input_func ) == " function " then
2018-09-04 21:55:58 +00:00
if not item.keep_menu_open then
self : closeMenu ( )
end
2017-03-28 22:47:18 +00:00
if item.tap_input then
self : onInput ( item.tap_input )
else
self : onInput ( item.tap_input_func ( ) )
end
2014-08-05 02:22:57 +00:00
else
local sub_item_table = item.sub_item_table
if item.sub_item_table_func then
sub_item_table = item.sub_item_table_func ( )
end
if sub_item_table == nil then
2015-03-12 06:19:10 +00:00
-- keep menu opened if this item is a check option
local callback , refresh = item.callback , item.checked or item.checked_func
2014-08-05 02:22:57 +00:00
if item.callback_func then
callback = item.callback_func ( )
end
if callback 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
-- Provide callback with us, so it can call our
-- closemenu() or updateItems() when it sees fit
-- (if not providing checked or checked_fund, caller
-- must set keep_menu_open=true if that is wished)
callback ( self )
if refresh then
self : updateItems ( )
elseif not item.keep_menu_open then
self : closeMenu ( )
end
2014-08-05 02:22:57 +00:00
end
else
table.insert ( self.item_table_stack , self.item_table )
2021-05-25 14:16:53 +00:00
self.parent_id = item.menu_item_id
2014-08-05 02:22:57 +00:00
self.item_table = sub_item_table
2016-08-01 01:22:35 +00:00
self.page = 1
2021-04-02 16:12:06 +00:00
if self.item_table . open_on_menu_item_id_func then
self : _recalculatePageLayout ( ) -- we need an accurate self.perpage
local open_id = self.item_table . open_on_menu_item_id_func ( )
for i = 1 , # self.item_table do
if self.item_table [ i ] . menu_item_id == open_id then
self.page = math.floor ( ( i - 1 ) / self.perpage ) + 1
break
end
end
end
2014-08-05 02:22:57 +00:00
self : updateItems ( )
end
2014-05-01 10:37:12 +00:00
end
2014-08-05 02:22:57 +00:00
return true
end
2021-01-29 17:39:04 +00:00
function TouchMenu : onMenuHold ( item , text_truncated )
2014-11-05 04:15:07 +00:00
if self.touch_menu_callback then
self.touch_menu_callback ( )
end
2017-03-28 22:47:18 +00:00
if item.hold_input or type ( item.hold_input_func ) == " function " then
2018-09-04 21:55:58 +00:00
if item.hold_keep_menu_open == false then
self : closeMenu ( )
end
2017-03-28 22:47:18 +00:00
if item.hold_input then
self : onInput ( item.hold_input )
else
self : onInput ( item.hold_input_func ( ) )
end
2018-05-25 18:56:37 +00:00
elseif item.hold_callback or type ( item.hold_callback_func ) == " function " then
2014-08-05 02:22:57 +00:00
local callback = item.hold_callback
if item.hold_callback_func then
callback = item.hold_callback_func ( )
2014-05-01 10:37:12 +00:00
end
if callback 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
-- With hold, the default is to keep menu open, as we're
-- most often showing a ConfirmBox that can be cancelled
-- (provide hold_keep_menu_open=false to override)
if item.hold_keep_menu_open == false then
self : closeMenu ( )
end
-- Provide callback with us, so it can call our
-- closemenu() or updateItems() when it sees fit
callback ( self )
2014-03-13 13:52:43 +00:00
end
2018-05-25 18:56:37 +00:00
elseif item.help_text or type ( item.help_text_func ) == " function " then
local help_text = item.help_text
if item.help_text_func then
2021-11-09 17:04:44 +00:00
help_text = item.help_text_func ( self )
2018-05-25 18:56:37 +00:00
end
if help_text then
UIManager : show ( InfoMessage : new { text = help_text , } )
end
2021-01-29 17:39:04 +00:00
elseif text_truncated then
2021-07-05 10:38:24 +00:00
UIManager : show ( InfoMessage : new {
text = getMenuText ( item ) ,
show_icon = false ,
} )
2014-03-13 13:52:43 +00:00
end
return true
2013-03-14 05:06:42 +00:00
end
function TouchMenu : onTapCloseAllMenus ( arg , ges_ev )
2014-03-13 13:52:43 +00:00
if ges_ev.pos : notIntersectWith ( self.dimen ) then
self : closeMenu ( )
end
2013-03-14 05:06:42 +00:00
end
2014-06-10 07:57:10 +00:00
function TouchMenu : onClose ( )
self : closeMenu ( )
end
2018-03-14 21:16:38 +00:00
function TouchMenu : onBack ( )
self : backToUpperMenu ( )
end
2013-10-18 20:38:07 +00:00
return TouchMenu