fix: prevent empty area when updating game grid thank to @Vector_null

Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
This commit is contained in:
2025-06-29 23:22:51 +05:00
parent a6562ca488
commit 08ba801f74

View File

@ -696,59 +696,50 @@ class MainWindow(QMainWindow):
loaded_count += 1 loaded_count += 1
def updateGameGrid(self, games_list=None): def updateGameGrid(self, games_list=None):
"""Updates the game grid with the provided games list or self.games.""" """Обновляет сетку игровых карточек с сохранением порядка сортировки"""
if games_list is None: # Подготовка данных
games_list = self.games games_list = games_list if games_list is not None else self.games
if not games_list:
# Скрываем все карточки, если список пуст
for card in self.game_card_cache.values():
card.hide()
self.game_card_cache.clear()
self.pending_images.clear()
self.gamesListWidget.updateGeometry()
return
# Создаем словарь текущих игр с уникальным ключом (name + exec_line)
current_games = {(game_data[0], game_data[4]): game_data for game_data in games_list}
# Проверяем, изменился ли список игр или размер карточек
current_game_keys = set(current_games.keys())
cached_game_keys = set(self.game_card_cache.keys())
card_width_changed = self.card_width != getattr(self, '_last_card_width', None)
if current_game_keys == cached_game_keys and not card_width_changed:
# Список игр и размер карточек не изменились, обновляем только видимость
search_text = self.searchEdit.text().strip().lower() search_text = self.searchEdit.text().strip().lower()
for game_key, card in self.game_card_cache.items(): favorites = read_favorites()
game_name = game_key[0] sort_method = read_sort_method()
card.setVisible(search_text in game_name.lower() or not search_text)
self.loadVisibleImages()
return
# Обновляем размер карточек, если он изменился # Сортируем игры согласно текущим настройкам
if card_width_changed: def sort_key(game):
for card in self.game_card_cache.values(): name = game[0]
card.setFixedWidth(self.card_width + 20) # Учитываем extra_margin в GameCard # Избранные всегда первые
if name in favorites:
fav_order = 0
else:
fav_order = 1
# Удаляем карточки, которых больше нет в списке if sort_method == "playtime":
layout_changed = False return (fav_order, -game[11], -game[10]) # playtime_seconds, last_launch_ts
for card_key in list(self.game_card_cache.keys()): elif sort_method == "alphabetical":
if card_key not in current_games: return (fav_order, name.lower())
card = self.game_card_cache.pop(card_key) elif sort_method == "favorites":
self.gamesListLayout.removeWidget(card) return (fav_order,)
card.deleteLater() else: # "last_launch" или по умолчанию
if card_key in self.pending_images: return (fav_order, -game[10], -game[11]) # last_launch_ts, playtime_seconds
del self.pending_images[card_key]
layout_changed = True
# Добавляем новые карточки и обновляем существующие sorted_games = sorted(games_list, key=sort_key)
for game_data in games_list:
# Создаем временный список для новых карточек
new_card_order = []
# Обрабатываем каждую игру в отсортированном порядке
for game_data in sorted_games:
game_name = game_data[0] game_name = game_data[0]
game_key = (game_name, game_data[4]) exec_line = game_data[4]
search_text = self.searchEdit.text().strip().lower() game_key = (game_name, exec_line)
should_be_visible = search_text in game_name.lower() or not search_text should_be_visible = not search_text or search_text in game_name.lower()
# Если карточка уже существует - используем существующую
if game_key in self.game_card_cache:
card = self.game_card_cache[game_key]
card.setVisible(should_be_visible)
new_card_order.append((game_key, card))
continue
if game_key not in self.game_card_cache:
# Создаем новую карточку # Создаем новую карточку
card = GameCard( card = GameCard(
*game_data, *game_data,
@ -757,8 +748,11 @@ class MainWindow(QMainWindow):
card_width=self.card_width, card_width=self.card_width,
context_menu_manager=self.context_menu_manager context_menu_manager=self.context_menu_manager
) )
# Подключаем сигналы
card.hoverChanged.connect(self._on_card_hovered) card.hoverChanged.connect(self._on_card_hovered)
card.focusChanged.connect(self._on_card_focused) card.focusChanged.connect(self._on_card_focused)
# Подключаем сигналы контекстного меню # Подключаем сигналы контекстного меню
card.editShortcutRequested.connect(self.context_menu_manager.edit_game_shortcut) card.editShortcutRequested.connect(self.context_menu_manager.edit_game_shortcut)
card.deleteGameRequested.connect(self.context_menu_manager.delete_game) card.deleteGameRequested.connect(self.context_menu_manager.delete_game)
@ -769,25 +763,42 @@ class MainWindow(QMainWindow):
card.addToSteamRequested.connect(self.context_menu_manager.add_to_steam) card.addToSteamRequested.connect(self.context_menu_manager.add_to_steam)
card.removeFromSteamRequested.connect(self.context_menu_manager.remove_from_steam) card.removeFromSteamRequested.connect(self.context_menu_manager.remove_from_steam)
card.openGameFolderRequested.connect(self.context_menu_manager.open_game_folder) card.openGameFolderRequested.connect(self.context_menu_manager.open_game_folder)
# Добавляем в кэш и временный список
self.game_card_cache[game_key] = card self.game_card_cache[game_key] = card
self.gamesListLayout.addWidget(card) new_card_order.append((game_key, card))
layout_changed = True
else:
# Обновляем видимость существующей карточки
card = self.game_card_cache[game_key]
card.setVisible(should_be_visible) card.setVisible(should_be_visible)
# Сохраняем текущий card_width # Полностью перестраиваем макет в правильном порядке, чистим FlowLayout
self._last_card_width = self.card_width while self.gamesListLayout.count():
child = self.gamesListLayout.takeAt(0)
if child.widget():
child.widget().setParent(None)
# Добавляем карточки в макет в отсортированном порядке
for _game_key, card in new_card_order:
self.gamesListLayout.addWidget(card)
# Загружаем обложку, если карточка видима
if card.isVisible():
self.loadVisibleImages()
# Удаляем карточки для игр, которых больше нет в списке
existing_keys = {game_key for game_key, _ in new_card_order}
for card_key in list(self.game_card_cache.keys()):
if card_key not in existing_keys:
card = self.game_card_cache.pop(card_key)
card.deleteLater()
if card_key in self.pending_images:
del self.pending_images[card_key]
# Принудительно обновляем макет # Принудительно обновляем макет
if layout_changed:
self.gamesListLayout.update() self.gamesListLayout.update()
self.gamesListWidget.updateGeometry() self.gamesListWidget.updateGeometry()
self.gamesListWidget.update() self.gamesListWidget.update()
# Загружаем изображения для видимых карточек # Сохраняем текущий размер карточек
self.loadVisibleImages() self._last_card_width = self.card_width
def clearLayout(self, layout): def clearLayout(self, layout):
"""Удаляет все виджеты из layout.""" """Удаляет все виджеты из layout."""