Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
31 changes: 20 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,24 @@ 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

base_theme = (
'dark_blue.xml'
if theme_param == 'dark'
else 'light_blue.xml'
if theme_param == 'light'
else 'watermelon.xml'
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is confusing on what conditions set the value of base_theme to each possible value. Could you please refactor this into an easier to read format such as if and elif, switch cases, or some easier to read format. Also, because we default to dark theme when there is no parameter, I think it would be good to default to dark theme when anyone enters a value for the parameter that we don't have a theme for instead of using watermelon for that situation.

if base_theme == 'watermelon.xml':
base_theme = Path(get_package_share_directory('gui')) / 'styles' / ('watermelon.xml')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is causing an error in the IDE because base_theme is storing a string, and you are assigning a Path variable to it which isn't a string. It is also confusing that you already set the value of base_theme if we are in watermelon theme on line 45 but then you are setting it to a different value here. It might be better to combine this into the original way you set the value for base_theme so that you aren't trying to set a value for this condition twice.

base_theme = base_theme.as_posix()

extra = extra_watermelon if theme_param == 'watermelon' else extra_blue
apply_stylesheet(self, theme=base_theme, 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