[Scummvm-git-logs] scummvm branch-2-6 -> ebbc0b09e93e6633a44c896653ad06aeccb22e91

sev- noreply at scummvm.org
Fri Jun 10 09:16:50 UTC 2022


This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
572d5a2971 GUI: Apply filter even when changing sorting criteria
f9aca7ee31 GUI: Don't store GridItemInfo items twice
77700ab06d GUI: Implement setSelected in Grid and use it in launcher
929d60fdcc GUI: When resizing grid make sure selected entry is displayed
226ab7d8a0 GUI: Fix grid list highlight after editing game. Bug #3960
ebbc0b09e9 GUI: Fix dangling pointer when _headerEntryList was reallocated


Commit: 572d5a297157abd3861cad5611bb0b5d3f5aeb4b
    https://github.com/scummvm/scummvm/commit/572d5a297157abd3861cad5611bb0b5d3f5aeb4b
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-06-10T11:13:53+02:00

Commit Message:
GUI: Apply filter even when changing sorting criteria

Changed paths:
    gui/widgets/grid.cpp


diff --git a/gui/widgets/grid.cpp b/gui/widgets/grid.cpp
index 8c76441f31e..1b6788ebbe1 100644
--- a/gui/widgets/grid.cpp
+++ b/gui/widgets/grid.cpp
@@ -461,23 +461,53 @@ void GridWidget::sortGroups() {
 	uint oldHeight = _innerHeight;
 	_sortedEntryList.clear();
 
-	Common::sort(_groupHeaders.begin(), _groupHeaders.end());
+	if (_filter.empty()) {
+		// No filter -> display everything with group headers
+		Common::sort(_groupHeaders.begin(), _groupHeaders.end());
+
+		for (uint i = 0; i != _groupHeaders.size(); ++i) {
+			Common::U32String header = _groupHeaders[i];
+			Common::U32String displayedHeader;
+			if (_metadataNames.contains(header)) {
+				displayedHeader = _metadataNames[header];
+			} else {
+				displayedHeader = header;
+			}
+			uint groupID = _groupValueIndex[header];
 
-	for (uint i = 0; i != _groupHeaders.size(); ++i) {
-		Common::U32String header = _groupHeaders[i];
-		Common::U32String displayedHeader;
-		if (_metadataNames.contains(header)) {
-			displayedHeader = _metadataNames[header];
-		} else {
-			displayedHeader = header;
+			_sortedEntryList.push_back(GridItemInfo(_groupHeaderPrefix + displayedHeader + _groupHeaderSuffix, groupID));
+
+			if (_groupExpanded[groupID]) {
+				for (int *k = _itemsInGroup[groupID].begin(); k != _itemsInGroup[groupID].end(); ++k) {
+					_sortedEntryList.push_back(_dataEntryList[*k]);
+				}
+			}
 		}
-		uint groupID = _groupValueIndex[header];
+	} else {
+		// With filter don't display any group header
+		// Restrict the list to everything which contains all words in _filter
+		// as substrings, ignoring case.
+
+		Common::U32StringTokenizer tok(_filter);
+		Common::U32String tmp;
+		int n = 0;
+
+		_sortedEntryList.clear();
 
-		_sortedEntryList.push_back(GridItemInfo(_groupHeaderPrefix + displayedHeader + _groupHeaderSuffix, groupID));
+		for (GridItemInfo *i = _dataEntryList.begin(); i != _dataEntryList.end(); ++i, ++n) {
+			tmp = i->title;
+			tmp.toLowercase();
+			bool matches = true;
+			tok.reset();
+			while (!tok.empty()) {
+				if (!tmp.contains(tok.nextToken())) {
+					matches = false;
+					break;
+				}
+			}
 
-		if (_groupExpanded[groupID]) {
-			for (int *k = _itemsInGroup[groupID].begin(); k != _itemsInGroup[groupID].end(); ++k) {
-				_sortedEntryList.push_back(_dataEntryList[*k]);
+			if (matches) {
+				_sortedEntryList.push_back(*i);
 			}
 		}
 	}
@@ -904,45 +934,11 @@ void GridWidget::setFilter(const Common::U32String &filter) {
 
 	_filter = filt;
 
-	if (_filter.empty()) {
-		// No filter -> display everything
-		sortGroups();
-	} else {
-		// Restrict the list to everything which contains all words in _filter
-		// as substrings, ignoring case.
-
-		Common::U32StringTokenizer tok(_filter);
-		Common::U32String tmp;
-		int n = 0;
-
-		_sortedEntryList.clear();
-
-		for (GridItemInfo *i = _dataEntryList.begin(); i != _dataEntryList.end(); ++i, ++n) {
-			tmp = i->title;
-			tmp.toLowercase();
-			bool matches = true;
-			tok.reset();
-			while (!tok.empty()) {
-				if (!tmp.contains(tok.nextToken())) {
-					matches = false;
-					break;
-				}
-			}
-
-			if (matches) {
-				_sortedEntryList.push_back(*i);
-			}
-		}
-	}
-
+	// Reset the scrollbar and deselect everything if filter has changed
 	_scrollPos = 0;
 	_selectedEntry = nullptr;
 
-	markGridAsInvalid();
-	reflowLayout();
-
-	scrollBarRecalc();
-	g_gui.scheduleTopDialogRedraw();
+	sortGroups();
 }
 
 } // End of namespace GUI


Commit: f9aca7ee31d5af5f93ab42304dc84c268995bc19
    https://github.com/scummvm/scummvm/commit/f9aca7ee31d5af5f93ab42304dc84c268995bc19
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-06-10T11:13:57+02:00

Commit Message:
GUI: Don't store GridItemInfo items twice

Changed paths:
    gui/widgets/grid.cpp
    gui/widgets/grid.h


diff --git a/gui/widgets/grid.cpp b/gui/widgets/grid.cpp
index 1b6788ebbe1..83158916afc 100644
--- a/gui/widgets/grid.cpp
+++ b/gui/widgets/grid.cpp
@@ -382,6 +382,7 @@ GridWidget::~GridWidget() {
 	unloadSurfaces(_loadedSurfaces);
 	_gridItems.clear();
 	_dataEntryList.clear();
+	_headerEntryList.clear();
 	_sortedEntryList.clear();
 	_visibleEntryList.clear();
 }
@@ -414,7 +415,10 @@ const Graphics::ManagedSurface *GridWidget::platformToSurface(Common::Platform p
 
 void GridWidget::setEntryList(Common::Array<GridItemInfo> *list) {
 	_dataEntryList.clear();
+	_headerEntryList.clear();
 	_sortedEntryList.clear();
+	_selectedEntry = nullptr;
+
 	for (Common::Array<GridItemInfo>::iterator entryIter = list->begin(); entryIter != list->end(); ++entryIter) {
 		_dataEntryList.push_back(*entryIter);
 	}
@@ -460,6 +464,7 @@ void GridWidget::groupEntries() {
 void GridWidget::sortGroups() {
 	uint oldHeight = _innerHeight;
 	_sortedEntryList.clear();
+	_headerEntryList.clear();
 
 	if (_filter.empty()) {
 		// No filter -> display everything with group headers
@@ -475,11 +480,13 @@ void GridWidget::sortGroups() {
 			}
 			uint groupID = _groupValueIndex[header];
 
-			_sortedEntryList.push_back(GridItemInfo(_groupHeaderPrefix + displayedHeader + _groupHeaderSuffix, groupID));
+			// Keep the header in a buffer to be used later
+			_headerEntryList.push_back(GridItemInfo(_groupHeaderPrefix + displayedHeader + _groupHeaderSuffix, groupID));
+			_sortedEntryList.push_back(&_headerEntryList.back());
 
 			if (_groupExpanded[groupID]) {
 				for (int *k = _itemsInGroup[groupID].begin(); k != _itemsInGroup[groupID].end(); ++k) {
-					_sortedEntryList.push_back(_dataEntryList[*k]);
+					_sortedEntryList.push_back(&_dataEntryList[*k]);
 				}
 			}
 		}
@@ -507,7 +514,7 @@ void GridWidget::sortGroups() {
 			}
 
 			if (matches) {
-				_sortedEntryList.push_back(*i);
+				_sortedEntryList.push_back(i);
 			}
 		}
 	}
@@ -537,7 +544,7 @@ void GridWidget::sortGroups() {
 }
 
 // Perform a binary search to find the last element before position yPos in arr.
-int lastItemBeforeY(const Common::Array<GridItemInfo> &arr, int yPos) {
+int lastItemBeforeY(const Common::Array<GridItemInfo *> &arr, int yPos) {
 	// Binary search to find the last element whose y value is less
 	// than _scrollPos, i.e., the last item of the topmost visible row.
 	int start = 0;
@@ -546,7 +553,7 @@ int lastItemBeforeY(const Common::Array<GridItemInfo> &arr, int yPos) {
 	int ans = -1;
 	while (start <= end) {
 		mid = start + (end - start) / 2;
-		if (arr[mid].y >= yPos) {
+		if (arr[mid]->y >= yPos) {
 			end = mid - 1;
 		} else {
 			ans = mid;
@@ -564,7 +571,7 @@ bool GridWidget::calcVisibleEntries() {
 	nFirstVisibleItem = temp;
 	// We want the leftmost item from the topmost visible row, so we traverse backwards
 	while ((nFirstVisibleItem >= 0) &&
-		   (_sortedEntryList[nFirstVisibleItem].y == _sortedEntryList[temp].y)) {
+		   (_sortedEntryList[nFirstVisibleItem]->y == _sortedEntryList[temp]->y)) {
 			nFirstVisibleItem--;
 	}
 	nFirstVisibleItem++;
@@ -583,8 +590,7 @@ bool GridWidget::calcVisibleEntries() {
 
 		_visibleEntryList.clear();
 		for (int ind = _firstVisibleItem; ind < toRender; ++ind) {
-			GridItemInfo *iter = _sortedEntryList.begin() + ind;
-			_visibleEntryList.push_back(iter);
+			_visibleEntryList.push_back(_sortedEntryList[ind]);
 		}
 	}
 	return needsReload;
@@ -678,16 +684,16 @@ void GridWidget::move(int x, int y) {
 void GridWidget::scrollToEntry(int id, bool forceToTop) {
 	int newScrollPos = _scrollPos;
 	for (uint i = 0; i < _sortedEntryList.size(); ++i) {
-		if ((!_sortedEntryList[i].isHeader) && (_sortedEntryList[i].entryID == id)) {
+		if ((!_sortedEntryList[i]->isHeader) && (_sortedEntryList[i]->entryID == id)) {
 			if (forceToTop) {
-				newScrollPos = _sortedEntryList[i].y + _scrollWindowPaddingY + _gridYSpacing;
+				newScrollPos = _sortedEntryList[i]->y + _scrollWindowPaddingY + _gridYSpacing;
 			} else {
-				if (_sortedEntryList[i].y < _scrollPos) {
+				if (_sortedEntryList[i]->y < _scrollPos) {
 					// Item is above the visible view
-					newScrollPos = _sortedEntryList[i].y - _scrollWindowPaddingY - _gridYSpacing;
-				} else if (_sortedEntryList[i].y > _scrollPos + _scrollWindowHeight - _gridItemHeight - _trayHeight) {
+					newScrollPos = _sortedEntryList[i]->y - _scrollWindowPaddingY - _gridYSpacing;
+				} else if (_sortedEntryList[i]->y > _scrollPos + _scrollWindowHeight - _gridItemHeight - _trayHeight) {
 					// Item is below the visible view
-					newScrollPos = _sortedEntryList[i].y - _scrollWindowHeight + _gridItemHeight + _trayHeight;
+					newScrollPos = _sortedEntryList[i]->y - _scrollWindowHeight + _gridItemHeight + _trayHeight;
 				} else {
 					// Item already in view, do nothing
 					newScrollPos = _scrollPos;
@@ -782,7 +788,7 @@ void GridWidget::calcInnerHeight() {
 	int32 x = _scrollWindowPaddingX + _gridXSpacing, y = _scrollWindowPaddingY;
 
 	for (int k = 0; k < (int)_sortedEntryList.size(); ++k) {
-		if (_sortedEntryList[k].isHeader) {
+		if (_sortedEntryList[k]->isHeader) {
 			while (col != 0) {
 				if (++col >= _itemsPerRow) {
 					col = 0;
@@ -792,16 +798,16 @@ void GridWidget::calcInnerHeight() {
 				}
 			}
 			x = _scrollWindowPaddingX;
-			_sortedEntryList[k].x = x;;
-			_sortedEntryList[k].y = y;;
+			_sortedEntryList[k]->x = x;;
+			_sortedEntryList[k]->y = y;;
 			x = _scrollWindowPaddingX + _gridXSpacing;
 			++row;
-			y += _sortedEntryList[k].h + _gridYSpacing;
+			y += _sortedEntryList[k]->h + _gridYSpacing;
 			lastRowHeight = 0;
 		} else {
-			_sortedEntryList[k].x = x;
-			_sortedEntryList[k].y = y;
-			lastRowHeight = MAX(lastRowHeight, _sortedEntryList[k].h + _gridYSpacing);
+			_sortedEntryList[k]->x = x;
+			_sortedEntryList[k]->y = y;
+			lastRowHeight = MAX(lastRowHeight, _sortedEntryList[k]->h + _gridYSpacing);
 			if (++col >= _itemsPerRow) {
 				++row;
 				y += lastRowHeight;
@@ -809,7 +815,7 @@ void GridWidget::calcInnerHeight() {
 				col = 0;
 				x = _scrollWindowPaddingX + _gridXSpacing;
 			} else {
-				x += _sortedEntryList[k].w + _gridXSpacing;
+				x += _sortedEntryList[k]->w + _gridXSpacing;
 			}
 		}
 	}
@@ -825,7 +831,7 @@ void GridWidget::calcEntrySizes() {
 	_gridHeaderWidth = _scrollWindowWidth - _scrollBarWidth - 2 * _scrollWindowPaddingX;
 
 	for (uint i = 0; i != _sortedEntryList.size(); ++i) {
-		GridItemInfo *entry = &_sortedEntryList[i];
+		GridItemInfo *entry = _sortedEntryList[i];
 		if (entry->isHeader) {
 			entry->h = _gridHeaderHeight;
 			entry->w = _gridHeaderWidth;
diff --git a/gui/widgets/grid.h b/gui/widgets/grid.h
index 2f9dbcb97f7..0a5a656a927 100644
--- a/gui/widgets/grid.h
+++ b/gui/widgets/grid.h
@@ -103,7 +103,8 @@ protected:
 	Common::HashMap<Common::String, const Graphics::ManagedSurface *> _loadedSurfaces;
 
 	Common::Array<GridItemInfo>			_dataEntryList;
-	Common::Array<GridItemInfo>			_sortedEntryList;
+	Common::Array<GridItemInfo>			_headerEntryList;
+	Common::Array<GridItemInfo *>		_sortedEntryList;
 	Common::Array<GridItemInfo *>		_visibleEntryList;
 
 	Common::String							_groupingAttribute;


Commit: 77700ab06d2867cc93ee6b3113b14000a48550f0
    https://github.com/scummvm/scummvm/commit/77700ab06d2867cc93ee6b3113b14000a48550f0
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-06-10T11:13:57+02:00

Commit Message:
GUI: Implement setSelected in Grid and use it in launcher

Changed paths:
    gui/launcher.cpp
    gui/widgets/grid.cpp
    gui/widgets/grid.h


diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index 80c8348be5e..68971ab7862 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -1540,8 +1540,18 @@ void LauncherGrid::updateListing() {
 		gridList.push_back(GridItemInfo(k++, engineid, gameid, iter->title, iter->description, Common::parseLanguage(language), Common::parsePlatform(platform)));
 	}
 
+	const int oldSel = _grid->getSelected();
+
 	_grid->setEntryList(&gridList);
 	groupEntries(attrs);
+
+	if (oldSel < (int)gridList.size() && oldSel >= 0)
+		_grid->setSelected(oldSel);	// Restore the old selection
+	else if (oldSel != -1)
+		// Select the last entry if the list has been reduced
+		_grid->setSelected(gridList.size() - 1);
+	updateButtons();
+
 	// And fill out our structures
 	for (Common::Array<LauncherEntry>::const_iterator iter = domainList.begin(); iter != domainList.end(); ++iter) {
 		_domains.push_back(iter->key);
@@ -1556,7 +1566,19 @@ void LauncherGrid::updateButtons() {
 	}
 }
 
-void LauncherGrid::selectTarget(const Common::String &target) {}
+void LauncherGrid::selectTarget(const Common::String &target) {
+	if (!target.empty()) {
+		int itemToSelect = 0;
+		Common::StringArray::const_iterator iter;
+		for (iter = _domains.begin(); iter != _domains.end(); ++iter, ++itemToSelect) {
+			if (target == *iter) {
+				_grid->setSelected(itemToSelect);
+				break;
+			}
+		}
+	}
+}
+
 int LauncherGrid::getSelected() { return _grid->getSelected(); }
 
 void LauncherGrid::build() {
diff --git a/gui/widgets/grid.cpp b/gui/widgets/grid.cpp
index 83158916afc..0acc9e9e85f 100644
--- a/gui/widgets/grid.cpp
+++ b/gui/widgets/grid.cpp
@@ -947,4 +947,14 @@ void GridWidget::setFilter(const Common::U32String &filter) {
 	sortGroups();
 }
 
+void GridWidget::setSelected(int id) {
+	for (uint i = 0; i < _sortedEntryList.size(); ++i) {
+		if ((!_sortedEntryList[i]->isHeader) && (_sortedEntryList[i]->entryID == id)) {
+			_selectedEntry = _sortedEntryList[i];
+			scrollToEntry(id, false);
+			break;
+		}
+	}
+}
+
 } // End of namespace GUI
diff --git a/gui/widgets/grid.h b/gui/widgets/grid.h
index 0a5a656a927..01cfed28783 100644
--- a/gui/widgets/grid.h
+++ b/gui/widgets/grid.h
@@ -209,6 +209,7 @@ public:
 	void openTrayAtSelected();
 	void scrollBarRecalc();
 
+	void setSelected(int id);
 	void setFilter(const Common::U32String &filter);
 };
 


Commit: 929d60fdccd6129af8b02d640be6627bc1545420
    https://github.com/scummvm/scummvm/commit/929d60fdccd6129af8b02d640be6627bc1545420
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-06-10T11:13:57+02:00

Commit Message:
GUI: When resizing grid make sure selected entry is displayed

Without this, at startup, the grid is not scrolled on the selected game.

Changed paths:
    gui/widgets/grid.cpp


diff --git a/gui/widgets/grid.cpp b/gui/widgets/grid.cpp
index 0acc9e9e85f..38352ebe006 100644
--- a/gui/widgets/grid.cpp
+++ b/gui/widgets/grid.cpp
@@ -891,9 +891,6 @@ void GridWidget::reflowLayout() {
 	calcEntrySizes();
 	calcInnerHeight();
 
-	_scrollBar->checkBounds(_scrollBar->_currentPos);
-	_scrollPos = _scrollBar->_currentPos;
-
 	_scrollBar->resize(_scrollWindowWidth - _scrollBarWidth, 0, _scrollBarWidth, _scrollWindowHeight, false);
 
 	if (calcVisibleEntries()) {
@@ -901,6 +898,9 @@ void GridWidget::reflowLayout() {
 	}
 
 	assignEntriesToItems();
+	if (_selectedEntry) {
+		scrollToEntry(_selectedEntry->entryID, false);
+	}
 	scrollBarRecalc();
 	markAsDirty();
 }


Commit: 226ab7d8a01f69fc88818ec9b5bd7b8ceef7ad15
    https://github.com/scummvm/scummvm/commit/226ab7d8a01f69fc88818ec9b5bd7b8ceef7ad15
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2022-06-10T11:13:57+02:00

Commit Message:
GUI: Fix grid list highlight after editing game. Bug #3960

Changed paths:
    gui/widgets/groupedlist.cpp


diff --git a/gui/widgets/groupedlist.cpp b/gui/widgets/groupedlist.cpp
index 349988fe6b2..c370b5f581d 100644
--- a/gui/widgets/groupedlist.cpp
+++ b/gui/widgets/groupedlist.cpp
@@ -174,11 +174,15 @@ void GroupedListWidget::setSelected(int item) {
 		if (_editMode)
 			abortEditMode();
 
-		_selectedItem = -1;
-		for (uint i = 0; i < _listIndex.size(); ++i) {
-			if (_listIndex[i] == item) {
-				_selectedItem = i;
-				break;
+		if (!_filter.empty()) {
+			_selectedItem = item;
+		} else {
+			_selectedItem = -1;
+			for (uint i = 0; i < _listIndex.size(); ++i) {
+				if (_listIndex[i] == item) {
+					_selectedItem = i;
+					break;
+				}
 			}
 		}
 


Commit: ebbc0b09e93e6633a44c896653ad06aeccb22e91
    https://github.com/scummvm/scummvm/commit/ebbc0b09e93e6633a44c896653ad06aeccb22e91
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-06-10T11:13:58+02:00

Commit Message:
GUI: Fix dangling pointer when _headerEntryList was reallocated

As we know the size of the array in advance we can preallocate it.

Changed paths:
    gui/widgets/grid.cpp


diff --git a/gui/widgets/grid.cpp b/gui/widgets/grid.cpp
index 38352ebe006..9f3462087c4 100644
--- a/gui/widgets/grid.cpp
+++ b/gui/widgets/grid.cpp
@@ -470,6 +470,9 @@ void GridWidget::sortGroups() {
 		// No filter -> display everything with group headers
 		Common::sort(_groupHeaders.begin(), _groupHeaders.end());
 
+		// Avoid reallocation during iteration: that would invalidate our _sortedEntryList items
+		_headerEntryList.reserve(_groupHeaders.size());
+
 		for (uint i = 0; i != _groupHeaders.size(); ++i) {
 			Common::U32String header = _groupHeaders[i];
 			Common::U32String displayedHeader;




More information about the Scummvm-git-logs mailing list