When displaying or hiding a tooltip, just render them on the screen
buffer and redraw the underneath foreground dialog.
For this, the tooltip is detached from the usual dialog stack and is
treated as a special case.
When a theme doesn't define an index cursor fall back to the normal cursor.
In the case of the classic theme that has a hardcoded cursor, setActiveCursor fails silently.
Introduce CursorData struct and array to store multiple cursor definitions. This prepares the ThemeEngine for supporting different cursor types (e.g., normal, cursor-index).
Replace hardcoded background color with value
extracted from the active theme.
Add ThemeEngine::getDrawDataColor() and use it
in createWidget() and drawWidget(), with
fallback to opaque white.
Until now, every (even the tiniest) widget's change of the enabled state
resulted in a redraw of a complete *dialog*. Why this was needed and how
it has been fixed requires a bit of explanation.
There are two buffers to render the widgets in: Backbuffer and Screen
(selected by ThemeEngine::drawToBackbuffer() and
ThemeEngine::drawToScreen() respectively, setting
VectorRenderer::_activeSurface). Then there are two layers/flags:
kDrawLayerBackground and kDrawLayerForeground
(selected in Dialog::drawDialog(), setting ThemeEngine::_layerToDraw).
When asked for a complete dialog rebuild in GuiManager::redraw()
(kRedrawCloseDialog, kRedrawFull) the widgets of every dialog,
regardless of their layer, are drawn into Backbuffer and then copied
into Screen.
When asked for a partial dialog rebuild (kRedrawOpenDialog,
kRedrawTopDialog) the widgets of the topmost dialog marked with
kDrawLayerBackground are drawn into Backbuffer, then copied into Screen
and finally the widgets marked with kDrawLayerForeground are drawn into
Screen *only*.
When redraw() is called just within the GuiManager's event loop the
widgets of the topmost dialog are drawn into Screen *only*. And this is
where the layers become important.
When rebuilding the dialog, it doesn't really matter which layer has
been defined for a widget: Backbuffer contains the ones with
kDrawLayerBackground and Screen will supply the rest with
kDrawLayerForeground, if needed. But which layer is taken into account
when calling Dialog::drawWidgets() ?
It is important to realize that the content of Backbuffer is
defined by the widget's initial state (idle or disabled): so Backbuffer
will contain either "idle color" or "disabled color" after dialog's
creation.
ThemeEngine::drawDD() does two checks:
1. if widget has kDrawLayerBackground set *and* _activeSurface is
Screen, copy the widget from Backbuffer to Screen
2. if widget's layer is the same as _layerToDraw, draw the widget into
_activeSurface
This is what happens in redraw(kRedrawDisabled) for kDrawLayerBackground
widgets:
- Backbuffer contains an idle/disabled (depending on its initial state)
rendition of the widget
- widget is copied from Backbuffer to Screen (1st check in drawDD())
- widget is not drawn into Screen as _layerToDraw is
kDrawLayerForeground (2nd check in drawDD())
Summary: when switching between idle/disabled state, widget's color is
not updated.
This is what happens in redraw(kRedrawDisabled) for kDrawLayerForeground
widgets:
- Backbuffer contains an idle/disabled (depending on its initial state)
rendition of the widget
- widget is not copied from Backbuffer to Screen as widget has
kDrawLayerForeground set (1st check in drawDD())
- widget is drawn into Screen as _layerToDraw is still
kDrawLayerForeground from the last redraw() (2nd check in drawDD())
Summary: when switching between idle/disabled state, widget's color is
correctly updated and not restored from Backbuffer.
Initially, I set up "button idle" to be rendered in the foreground
layer, same as "button disabled". However @lephilousophe suggested a
great improvement: render "button idle" still in the background but make
"button disabled" its child (in the foreground). Worked like a charm as
it just mimics the hovering behaviour.
And this is why hovering doesn't require scheduleTopDialogRedraw():
- Backbuffer contains an idle [kDrawLayerBackground] rendition of the
widget
- when highlighted [kDrawLayerForeground], widget is not copied from
Backbuffer to Screen
- widget is drawn into Screen
Unhovering:
- Backbuffer contains an idle [kDrawLayerBackground] rendition of the
widget
- when idle [kDrawLayerBackground], widget is copied from Backbuffer to
Screen
- widget is not drawn into Screen
This reverts commit 04f040af which forced a bitmap reloading to prevent
reusing already up/downscaled images in case that _scaleFactor has
changed.
However after commit ad31dfc this no longer applies as changing the
scale factor in GUI forces a ThemeEngine destroy and recreate. So
_bitmaps[filename] is safe to keep its cached image which is reused e.g.
during initial theme loading.
- Replace inscription with an icon to save space
- Reduced size of the search box
- Disbled grid for low-res layouts
- Fixed classic theme
- Regenerated built-in theme