The theme layout padding values are parsed and stored as 16 bit
signed integers. However ThemeLayout::setPadding treated the
values as 8 bit signed integeres.
The padding values parsed from the STX file suited for the screen
resolution are multiplied with the device content scale factor.
The scale factor determines how content is mapped from the logical
coordinate space (measured in points) to the device coordinate
space (measured in pixels).
If the scale factor and the padding value results in a value
greater than 255 it will wrap since the 8 bit type can't hold
bigger values than that.
Running the iOS backend in debug configuration on an iPhone 12
mini, having the content scale factor value 3, and drawing the
launcher in vertical mode where the bottom padding value is 92,
the result became 3 * 92 = 276 which would wrap to 20.
That resulted in incorrect layout where the GameList was too
high and the buttons in the bottom would not fit on the screen.
Change the input type to int16 in ThemeLayout::setPadding to
conform with the padding type used everywhere else.
When statically linked, this makes about 8000 variants.
This change takes only engines and games present in a domain into
account. This speeds up loading time on slower backends quite
noticeably.
When ScummVM is started, if the updates_check value is not defined
in the config file and ScummVM was compiled with the Updates feature
(on macOS or Windows), an opt-in dialog asks the user if he wants
to check for available updates periodically. This should only be
shown once. However as ConfMan was not flushed to disk, it was
asked again the next time ScummVM is started, and again, until the
user accessed the options to change something else and this was
finally flushed to disk.
- Each resolution needs to be cycled manually in the code, default is
800x640.
- Dumps .png files in a snapshots folder for all languages at a given
resolution.
TODO:
- Cycle resolutions automatically through code.
- Add more dialogs to the dumper.
#4953 optimized redrawing of the top dialog in commit f824f8a. This
however broke console's sliding up as the code in question depended on
the fact that it was internally equivalent to a full redraw.
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
When calling any of:
- Widget::setEnabled
- EditTextWidget::setEditString
- EditableWidget::setEditString
- StaticTextWidget::setLabel
there is no need to call neither GuiManager::scheduleTopDialogRedraw nor
Widget::markAsDirty afterwards -- they set up the call by themselves.
Also, refactor a couple of code blocks into calling just
GuiManager::redrawFull as it does the same thing.
Unfortunately, it is not that simple. Tooltip may be placed also outside
of the dialog. Current implementation leaves tooltip leftovers over
the dialog below the topmost one, so reverting until I find a correct
way to achieve the goal.
This reverts commit 19b7b2aa20.
This fixes bug #14404.
The rercusive call was introduced with commit 325260f that changed
the implementation of Widget::handleMouseWheel to call handleMouseWheel
on the widget boss. If the widget boss is a dialog, its implementation
is to call handleMouseWheel on the widget under the cursor. And
we can end up with an infinite loop.
As indicated in bug #13106, which was fixed by commit 325260f, a
similar infinite loop when using the mouse wheel to scroll tabs in
the options dialog was caused by the commit and quickly fixed. But
the fix was only for that particular case. Here the fix should
be more global.
GroupedListWidget and GridWidget can save what groups they have
collapsed to the config file and reload them. "launcher.cpp" uses those
functions to persist those collapsed groups through
- changing how the games are grouped by
- going from list to grid mode and vice versa
- quitting scummvm and starting it again
textviewer.cpp:84:64: warning: format '%ld' expects argument of type 'long int', but argument 2 has type 'int64' {aka 'long long int'} [-Wformat=]
84 | warning("TextViewerDialog::loadFile(): File size is: %ld", stream->size());
| ~~^ ~~~~~~~~~~~~~~
| | |
| long int int64 {aka long long int}
| %lld
- remove Options widgets of the old wizard;
- add CloudConnectionWizard dialog;
- remove old widgets and add new ones in the layouts;
- update local webserver to allow passing a callback that needs to be called if storage was connected via /connect_cloud.