Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 23 additions & 11 deletions src/surface/gui/gui/app.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import atexit
import signal
from pathlib import Path
from threading import Thread

import rclpy.utilities
from ament_index_python import get_package_share_directory
from PyQt6.QtWidgets import QApplication, QWidget
from qt_material import apply_stylesheet
from rclpy.executors import MultiThreadedExecutor

from gui.gui_node import GUINode
Expand All @@ -29,18 +32,27 @@ def run_gui(self) -> None:
# Kills with Control + C
signal.signal(signal.SIGINT, signal.SIG_DFL)

# TODO: New method of dark mode
extra_blue = {'success': '#040444', 'danger': '#040444', 'warning': '#040444'}
extra_watermelon = {'success': '#341616', 'danger': '#341616', 'warning': '#341616'}
# Apply theme
# theme_param = self.theme_param.get_parameter_value().string_value
# theme_path = Path(get_package_share_directory('gui')) / 'styles' / (theme_param + '.qss')

# base_theme = 'dark' if theme_param == 'dark' else 'light'
# custom_styles = '\n'
# if theme_path.exists():
# with theme_path.open(encoding='utf-8') as theme_file:
# custom_styles += theme_file.read()

# qdarktheme.setup_theme(base_theme, additional_qss=custom_styles)
theme_param = self.theme_param.get_parameter_value().string_value

match theme_param:
case 'dark':
base_theme = 'dark_blue.xml'
case 'light':
base_theme = 'light_blue.xml'
case 'watermelon':
base_path = Path(get_package_share_directory('gui')) / 'styles' / ('watermelon.xml')
base_theme = base_path.as_posix()
case _:
base_theme = 'dark_blue.xml'
self.node.get_logger().info(
'Theme ' + theme_param + ' not found, defaulting to dark.'
)

extra = extra_watermelon if theme_param == 'watermelon' else extra_blue
apply_stylesheet(self, theme=base_theme, style='', extra=extra)

executor = MultiThreadedExecutor()
executor.add_node(self.node)
Expand Down
17 changes: 15 additions & 2 deletions src/surface/gui/gui/styles/custom_styles.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@ class IndicatorMixin(QWidget):
# The stylesheets that correspond to each widget state
_STYLESHEETS: Final[dict[WidgetState, str]] = {
# Stylesheet for when a component is running, enabled, or armed
WidgetState.ON: 'QWidget { background-color: limegreen; }',
WidgetState.ON: """
QWidget { background-color: limegreen; }
QWidget:hover { background-color: #5bd75b; }
""",
# Stylesheet for when a component is disabled, not running, or disarmed, but could be
# enabled through this widget
WidgetState.OFF: 'QWidget { background-color: red; }',
WidgetState.OFF: """
QWidget { background-color: red; }
QWidget:hover { background-color: #ff3333; }
""",
# Stylesheet for when a component is disabled, not expected to have any effect or perform
# its function because of some external factor, either another widget or something
# external to the gui. For example, a the arm button when the pi is not connected
Expand Down Expand Up @@ -48,6 +54,13 @@ def set_state(self, new_state: WidgetState) -> None:
The new state for the widget
"""
self.current_state = new_state
match self.current_state:
case WidgetState.OFF:
self.setProperty('class', 'danger')
case WidgetState.ON:
self.setProperty('class', 'success')
case _:
self.setProperty('class', 'warning')
self.setStyleSheet(self._original_stylesheet + self._STYLESHEETS[self.current_state])


Expand Down
10 changes: 10 additions & 0 deletions src/surface/gui/gui/styles/watermelon.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!--?xml version="1.0" encoding="UTF-8"?-->
<resources>
<color name="primaryColor">#ff4d4e</color>
<color name="primaryLightColor">#bf0002</color>
<color name="secondaryColor">#6f0001</color>
<color name="secondaryLightColor">#31363b</color>
<color name="secondaryDarkColor">#1b5e1a</color>
<color name="primaryTextColor">#ffffff</color>
<color name="secondaryTextColor">#ffffff</color>
</resources>
1 change: 1 addition & 0 deletions src/surface/gui/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

<exec_depend>python3-numpy</exec_depend>
<exec_depend>cv_bridge</exec_depend>
<exec_depend>python3-qt-material-pip</exec_depend>
<exec_depend>python3-pyqtgraph</exec_depend>
<exec_depend>pyqt6-dev-tools</exec_depend>
<exec_depend>python3-pyqt6.qtmultimedia</exec_depend>
Expand Down
2 changes: 1 addition & 1 deletion src/surface/gui/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
# Include all style files.
(
str(Path('share') / PACKAGE_NAME / 'styles'),
[str(path) for path in (Path('gui') / 'styles').glob('*.qss')],
[str(path) for path in (Path('gui') / 'styles').glob('*.xml')],
),
# Include all images.
(
Expand Down