From 86fb2b2d7cd6a9e0920f9213cba01b149a2cea37 Mon Sep 17 00:00:00 2001 From: Boris Yumankulov Date: Sat, 29 Nov 2025 11:28:37 +0500 Subject: [PATCH] chore: added refresh hint Signed-off-by: Boris Yumankulov --- portprotonqt/main_window.py | 215 ++++++++++++++++-- portprotonqt/themes/standart/images/key_+.svg | 1 + .../themes/standart/images/key_f5.svg | 1 + portprotonqt/themes/standart/images/ps_ps.svg | 1 + .../themes/standart/images/xbox_xbox.svg | 1 + 5 files changed, 198 insertions(+), 21 deletions(-) create mode 100644 portprotonqt/themes/standart/images/key_+.svg create mode 100644 portprotonqt/themes/standart/images/key_f5.svg create mode 100644 portprotonqt/themes/standart/images/ps_ps.svg create mode 100644 portprotonqt/themes/standart/images/xbox_xbox.svg diff --git a/portprotonqt/main_window.py b/portprotonqt/main_window.py index 0587b57..0d7966c 100644 --- a/portprotonqt/main_window.py +++ b/portprotonqt/main_window.py @@ -270,7 +270,7 @@ class MainWindow(QMainWindow): GamepadType.PLAYSTATION: "ps_options", }, 'menu': { - GamepadType.XBOX: "xbox_view", + GamepadType.XBOX: "xbox_view", # Select button on Xbox GamepadType.PLAYSTATION: "ps_share", }, 'search': { @@ -281,6 +281,10 @@ class MainWindow(QMainWindow): GamepadType.XBOX: "xbox_y", GamepadType.PLAYSTATION: "ps_square", }, + 'guide_select': { + GamepadType.XBOX: "xbox_xbox", # Xbox Guide button + GamepadType.PLAYSTATION: "ps_ps", # PS button + }, } return mappings.get(action, {}).get(gtype, "placeholder") @@ -320,6 +324,7 @@ class MainWindow(QMainWindow): ("context_menu", _("Menu")), ("menu", _("Fullscreen")), ("search", _("Search")), + ("guide_select", _("Refresh Grid")), ] keyboard_hints = [ @@ -328,6 +333,7 @@ class MainWindow(QMainWindow): ("key_e", _("Add Game")), ("key_context", _("Menu")), ("key_f11", _("Fullscreen")), + ("key_f5", _("Refresh Grid")), ] self.hintsLabels = [] @@ -375,9 +381,100 @@ class MainWindow(QMainWindow): hintsLayout.addWidget(container) + # Special function to create combination hint for Guide+Select + def makeCombinationHint(action_text: str, action: str | None = None): + container = QWidget() + layout = QHBoxLayout(container) + layout.setContentsMargins(0, 5, 0, 0) + layout.setSpacing(6) + + # First icon (Guide button) + guide_icon = QLabel() + guide_icon.setFixedSize(26, 26) + guide_icon.setAlignment(Qt.AlignmentFlag.AlignCenter) + + pixmap = QPixmap() + for candidate in ( + self.theme_manager.get_theme_image("xbox_xbox", self.current_theme_name), # Xbox Guide + self.theme_manager.get_theme_image("ps_ps", self.current_theme_name), # PS Button + self.theme_manager.get_theme_image("placeholder", self.current_theme_name), + ): + if candidate is not None and pixmap.load(str(candidate)): + break + + if not pixmap.isNull(): + guide_icon.setPixmap(pixmap.scaled( + 26, 26, + Qt.AspectRatioMode.KeepAspectRatio, + Qt.TransformationMode.SmoothTransformation + )) + + layout.addWidget(guide_icon) + + # Plus sign between icons + plus_icon = QLabel() + plus_icon.setFixedSize(26, 26) + plus_icon.setAlignment(Qt.AlignmentFlag.AlignCenter) + + plus_pixmap = QPixmap() + for candidate in ( + self.theme_manager.get_theme_image("key_+", self.current_theme_name), + self.theme_manager.get_theme_image("placeholder", self.current_theme_name), + ): + if candidate is not None and plus_pixmap.load(str(candidate)): + break + + if not plus_pixmap.isNull(): + plus_icon.setPixmap(plus_pixmap.scaled( + 26, 26, + Qt.AspectRatioMode.KeepAspectRatio, + Qt.TransformationMode.SmoothTransformation + )) + + layout.addWidget(plus_icon) + + # Second icon (Select button) + select_icon = QLabel() + select_icon.setFixedSize(26, 26) + select_icon.setAlignment(Qt.AlignmentFlag.AlignCenter) + + pixmap2 = QPixmap() + for candidate in ( + self.theme_manager.get_theme_image("xbox_view", self.current_theme_name), # Xbox Select + self.theme_manager.get_theme_image("ps_share", self.current_theme_name), # PS Share + self.theme_manager.get_theme_image("placeholder", self.current_theme_name), + ): + if candidate is not None and pixmap2.load(str(candidate)): + break + + if not pixmap2.isNull(): + select_icon.setPixmap(pixmap2.scaled( + 26, 26, + Qt.AspectRatioMode.KeepAspectRatio, + Qt.TransformationMode.SmoothTransformation + )) + + layout.addWidget(select_icon) + + # текст действия + text_label = QLabel(action_text) + text_label.setStyleSheet(self.theme.LAST_LAUNCH_VALUE_STYLE) + text_label.setAlignment(Qt.AlignmentFlag.AlignVCenter | Qt.AlignmentFlag.AlignLeft) + layout.addWidget(text_label) + + # For gamepad combination hints + container.setVisible(False) + self.hintsLabels.append((container, [guide_icon, plus_icon, select_icon], action)) # Store all three elements for dynamic update + + hintsLayout.addWidget(container) + # Create gamepad hints for action, text in gamepad_actions: - makeHint("placeholder", text, True, action) # Initial placeholder + if action == "guide_select": + # For the Guide+Select combination, create a special combination hint + makeCombinationHint(text, action) + else: + makeHint("placeholder", text, True, action) # Initial placeholder # Create keyboard hints for icon, text in keyboard_hints: @@ -432,30 +529,106 @@ class MainWindow(QMainWindow): gtype = self.input_manager.gamepad_type logger.debug("Updating control hints, gamepad connected: %s, type: %s", is_gamepad_connected, gtype.value) - gamepad_actions = ['confirm', 'back', 'add_game', 'context_menu', 'menu', 'search'] + gamepad_actions = ['confirm', 'back', 'add_game', 'context_menu', 'menu', 'search', 'guide_select'] - for container, icon_label, action in self.hintsLabels: + for container, icon_element, action in self.hintsLabels: if action in gamepad_actions: # Gamepad hint if is_gamepad_connected: container.setVisible(True) - # Update icon based on type - icon_name = self.get_button_icon(action, gtype) - icon_path = self.theme_manager.get_theme_image(icon_name, self.current_theme_name) - pixmap = QPixmap() - if icon_path: - pixmap.load(str(icon_path)) - if not pixmap.isNull(): - icon_label.setPixmap(pixmap.scaled( - 26, 26, - Qt.AspectRatioMode.KeepAspectRatio, - Qt.TransformationMode.SmoothTransformation - )) + # Check if this is a combination hint (array of icons) or single icon hint + if isinstance(icon_element, list) and len(icon_element) == 3 and action == "guide_select": + # This is a combination hint for Guide+Select + guide_icon, plus_icon, select_icon = icon_element + + # Determine guide icon based on gamepad type + if gtype == GamepadType.XBOX: + guide_icon_name = "xbox_xbox" # Xbox Guide button + elif gtype == GamepadType.PLAYSTATION: + guide_icon_name = "ps_ps" # PS Button + else: + guide_icon_name = "xbox_xbox" # Default to Xbox guide + + # Load Guide icon + guide_pixmap = QPixmap() + for candidate in ( + self.theme_manager.get_theme_image(guide_icon_name, self.current_theme_name), + self.theme_manager.get_theme_image("placeholder", self.current_theme_name), + ): + if candidate is not None and guide_pixmap.load(str(candidate)): + break + + if not guide_pixmap.isNull(): + guide_icon.setPixmap(guide_pixmap.scaled( + 26, 26, + Qt.AspectRatioMode.KeepAspectRatio, + Qt.TransformationMode.SmoothTransformation + )) + + # Load Plus icon + plus_pixmap = QPixmap() + for candidate in ( + self.theme_manager.get_theme_image("key_+", self.current_theme_name), + self.theme_manager.get_theme_image("placeholder", self.current_theme_name), + ): + if candidate is not None and plus_pixmap.load(str(candidate)): + break + + if not plus_pixmap.isNull(): + plus_icon.setPixmap(plus_pixmap.scaled( + 26, 26, + Qt.AspectRatioMode.KeepAspectRatio, + Qt.TransformationMode.SmoothTransformation + )) + + # Determine select icon based on gamepad type + if gtype == GamepadType.XBOX: + select_icon_name = "xbox_view" # Xbox Select button + elif gtype == GamepadType.PLAYSTATION: + select_icon_name = "ps_share" # PS Share button + else: + select_icon_name = "xbox_view" # Default to Xbox Select + + # Load Select icon + select_pixmap = QPixmap() + for candidate in ( + self.theme_manager.get_theme_image(select_icon_name, self.current_theme_name), + self.theme_manager.get_theme_image("placeholder", self.current_theme_name), + ): + if candidate is not None and select_pixmap.load(str(candidate)): + break + + if not select_pixmap.isNull(): + select_icon.setPixmap(select_pixmap.scaled( + 26, 26, + Qt.AspectRatioMode.KeepAspectRatio, + Qt.TransformationMode.SmoothTransformation + )) else: - # Fallback to placeholder - placeholder = self.theme_manager.get_theme_image("placeholder", self.current_theme_name) - if placeholder: - pixmap.load(str(placeholder)) - icon_label.setPixmap(pixmap.scaled(26, 26, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)) + # This is a regular single-icon hint + # Verify that icon_element is not a list before assigning + if isinstance(icon_element, list): + # This shouldn't happen based on current logic, but added for safety + logger.warning(f"Unexpected list found for single-icon hint with action: {action}") + continue # Skip this iteration to prevent error + icon_label = icon_element + # Update icon based on type + icon_name = self.get_button_icon(action, gtype) + icon_path = self.theme_manager.get_theme_image(icon_name, self.current_theme_name) + pixmap = QPixmap() + if icon_path: + pixmap.load(str(icon_path)) + if not pixmap.isNull(): + icon_label.setPixmap(pixmap.scaled( + 26, 26, + Qt.AspectRatioMode.KeepAspectRatio, + Qt.TransformationMode.SmoothTransformation + )) + else: + # Fallback to placeholder + placeholder = self.theme_manager.get_theme_image("placeholder", self.current_theme_name) + if placeholder: + pixmap.load(str(placeholder)) + icon_label.setPixmap(pixmap.scaled(26, 26, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)) else: container.setVisible(False) else: # Keyboard hint diff --git a/portprotonqt/themes/standart/images/key_+.svg b/portprotonqt/themes/standart/images/key_+.svg new file mode 100644 index 0000000..907fe2b --- /dev/null +++ b/portprotonqt/themes/standart/images/key_+.svg @@ -0,0 +1 @@ + diff --git a/portprotonqt/themes/standart/images/key_f5.svg b/portprotonqt/themes/standart/images/key_f5.svg new file mode 100644 index 0000000..6fda374 --- /dev/null +++ b/portprotonqt/themes/standart/images/key_f5.svg @@ -0,0 +1 @@ + diff --git a/portprotonqt/themes/standart/images/ps_ps.svg b/portprotonqt/themes/standart/images/ps_ps.svg new file mode 100644 index 0000000..ed38bc9 --- /dev/null +++ b/portprotonqt/themes/standart/images/ps_ps.svg @@ -0,0 +1 @@ + diff --git a/portprotonqt/themes/standart/images/xbox_xbox.svg b/portprotonqt/themes/standart/images/xbox_xbox.svg new file mode 100644 index 0000000..b5e94f7 --- /dev/null +++ b/portprotonqt/themes/standart/images/xbox_xbox.svg @@ -0,0 +1 @@ +