SHIFT+UP after starting ScummVM or after removing a game would cause
the visual selection and the internal selection to be out of sync.
The problem was that ListWidget::_lastSelectionStartItem was only
initialized on certain code paths. Now it is initialized when marking
an item as selected, if it isn't already.
Fixes bug #16635
Update ListWidget, GridWidget, and GroupedListWidget setSelected() to
clear all selections and mark only the newly selected item when
multi-select is enabled.
Add getVisualPos() method to ListWidget to convert real data indices to
visual indices in filtered/grouped lists. Simplify selection restoration
in both LauncherSimple and LauncherGrid using MIN() to handle out-of-bounds
cases cleanly. Move _lastSelectionStartItem to public for direct access.
Move scrollToCurrent() from end of handleKeyDown() to specific actions
only. Prevents list from jumping to current item during Ctrl+Click or
Shift+Click multi-select operations, keeping the view stable.
Remove _selectedItem check from highlight condition in ListWidget and
GroupedListWidget draw methods. This ensures visual state immediately
reflects the actual selection array when items are deselected via
Ctrl+Click, rather than waiting for the next redraw cycle.
Replace duplicate addSelectedItem() and removeSelectedItem() methods with
a single markSelectedItem(int item, bool state) method in both ListWidget
and GridWidget. Update all callers across list.cpp, grid.cpp, groupedlist.cpp,
and launcher.cpp to use the new unified method.
- Replace int array _selectedEntries with bool array _selectedItems in GridWidget
- Rename getSelectedItemsBool() to getSelectedItems() in ListWidget
- Update performGameRemoval() to accept bool array parameter
- Simplify selection logic and improve deletion efficiency
Switch ListWidget multi-selection tracking from Common::Array<int> to Common::Array<bool> for add, remove, and lookup operations.
Update all selection-related methods and launcher integration
Update ListWidget and GroupedListWidget to correctly map visual (filtered/grouped) indices to real data indices for all selection operations. This ensures that selection, multi-selection, and highlighting work as expected when filtering or grouping is active in the list view.
Refactor game removal logic to reduce duplication between grid and list views.
Fix an issue in ListWidget where shift-click multi-selection updated the anchor
before selecting the range. The anchor is now updated after the range selection,
ensuring multi-selection works as expected.
In member function 'MidiParser_HMP::HmpVersion MidiParser_HMP::determineVersion(const byte*)',
inlined from 'virtual int32 MidiParser_HMP::determineDataSize(Common::SeekableReadStream*)' at audio/midiparser_hmp.cpp:132:39:
audio/midiparser_hmp.cpp:161:129: warning: 'versionBytes' may be used uninitialized [-Wmaybe-uninitialized]
161 | warning("Unknown HMP version '%c%c%c%c%c%c' - assuming version 1", pos[0], pos[1], pos[2], pos[3], pos[4], pos[5]);
| ~~~~~^
audio/midiparser_hmp.cpp: In member function 'virtual int32 MidiParser_HMP::determineDataSize(Common::SeekableReadStream*)':
audio/midiparser_hmp.cpp:130:14: note: 'versionBytes' declared here
130 | byte versionBytes[6];
| ^~~~~~~~~~~~
gui/widgets/list.cpp: In member function 'void GUI::ListWidget::addSelectedItem(int)':
gui/widgets/list.cpp:228:27: warning: comparison of integer expressions of different signedness: 'int' and 'Common::Array<int>::size_type' {aka 'unsigned int'} [-Wsign-compare]
228 | for (int i = 0; i < _selectedItems.size(); ++i) {
| ~~^~~~~~~~~~~~~~~~~~~~~~~
gui/widgets/list.cpp: In member function 'void GUI::ListWidget::removeSelectedItem(int)':
gui/widgets/list.cpp:248:27: warning: comparison of integer expressions of different signedness: 'int' and 'Common::Array<int>::size_type' {aka 'unsigned int'} [-Wsign-compare]
248 | for (int i = 0; i < _selectedItems.size(); ++i) {
| ~~^~~~~~~~~~~~~~~~~~~~~~~
Only suppress Enter activation when multi-select is enabled and more than one item is selected; if exactly one item is selected, Enter activates it even when multi-select is on.
- Added _multiSelectEnabled flag to ListWidget and GridWidget (default: false)
- Added setMultiSelectEnabled() and isMultiSelectEnabled() methods
- Gated Ctrl+Click and Shift+Click logic behind _multiSelectEnabled check
- GroupedListWidget inherits this behavior from ListWidget
• Enable multi-selection in the launcher list widget (mouse, Ctrl+Click, Shift+Click).
• Update button states: disable Start, Load, and Game Options when multiple entries are selected.
• Add batch removal confirmation dialog listing selected entries.
• Refactor selection logic and highlighting in both filtered and grouped views.
• Fix group header fold indicator rendering for better UI consistency.
This let the theme define inter item spacing.
The selection box has the same height as the item height and the text in
vertically centered.
The edition caret is vertically centered.
These commands allow greater control over editable ListWidgets, although
the save dialog's list is currently the only one.
kListItemSingleClickedCmd allows clients to respond to selection changes
based on the method used (mouse vs keyboard) and allows responding to
clicking on an already selected item. In the next commit, this will fix
multiple save issues.
kListItemEditModeStartedCmd allows clients to initialize edit mode
consistently. The save dialog has been doing custom initialization after
calling startEditMode, but this is incorrect because ListWidget calls
startEditMode in response to Enter, so the initialization is skipped.
Fixes the delete/backspace hotkey on the save list dialog; it was only
working on the load list even though they both have the same delete
functionality.
This is a check from 17 years ago that I believe was confused and had
no effect at the time. I believe the intent was to ignore these keys
while in edit mode, which makes sense, but instead this code ignored
these keys on all editable lists when *not* in edit mode. This wasn't
noticeable because there's only one editable ListWidget in ScummVM,
the save list, and it didn't listen for kListItemRemovalRequestCmd
until three years ago: aac1eb12bf
When in edit mode on the save dialog, clicking on a disabled item, such
as the Autosave slot 0, would draw the stale caret on the disabled item
at the x position of the previous item.
This was actually the intention all along. But if a redraw of the widget
itself was triggered at the same time, it would draw over the caret,
effectively erasing it. To get around this, the caret is now also drawn
as part of the widget, when necessary.