Skip to content

Commit c6dbc03

Browse files
committed
add theme setting
1 parent f2a23bb commit c6dbc03

File tree

3 files changed

+95
-12
lines changed

3 files changed

+95
-12
lines changed

src/kevinbotlib_dashboard/__main__.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import sys
66

77
from kevinbotlib.logger import Level, Logger, LoggerConfiguration
8-
from kevinbotlib.ui.theme import Theme, ThemeStyle
98
from PySide6.QtCore import QCommandLineOption, QCommandLineParser, QCoreApplication
109
from PySide6.QtWidgets import QApplication
1110

@@ -18,8 +17,6 @@ def run():
1817
app.setApplicationName("KevinbotLib Dashboard")
1918
app.setApplicationVersion(__about__.__version__)
2019

21-
Theme(ThemeStyle.System).apply(app)
22-
2320
parser = QCommandLineParser()
2421
parser.addHelpOption()
2522
parser.addVersionOption()
@@ -38,7 +35,7 @@ def run():
3835

3936
logger.configure(LoggerConfiguration(level=log_level))
4037

41-
window = Application()
38+
window = Application(app)
4239
window.show()
4340
sys.exit(app.exec())
4441

src/kevinbotlib_dashboard/app.py

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
from kevinbotlib.comm import CommunicationClient, BaseSendable
66
from kevinbotlib.logger import Logger
7+
from kevinbotlib.ui.theme import Theme, ThemeStyle
8+
79
from PySide6.QtCore import (
810
QItemSelection,
911
QModelIndex,
@@ -40,9 +42,12 @@
4042
QTreeView,
4143
QVBoxLayout,
4244
QWidget,
45+
QRadioButton,
46+
QSizePolicy,
47+
QApplication,
4348
)
4449

45-
from kevinbotlib_dashboard.grid_theme import Themes
50+
from kevinbotlib_dashboard.grid_theme import Themes as GridThemes
4651
from kevinbotlib_dashboard.toast import Notifier, Severity
4752
from kevinbotlib_dashboard.tree import DictTreeModel
4853
from kevinbotlib_dashboard.widgets import Divider
@@ -203,7 +208,7 @@ def delete_self(self):
203208

204209

205210
class GridGraphicsView(QGraphicsView):
206-
def __init__(self, parent=None, grid_size: int = 48, rows=10, cols=10, theme: Themes = Themes.Dark):
211+
def __init__(self, parent=None, grid_size: int = 48, rows=10, cols=10, theme: GridThemes = GridThemes.Dark):
207212
super().__init__(parent)
208213
self.grid_size = grid_size
209214
self.rows, self.cols = rows, cols
@@ -223,6 +228,11 @@ def __init__(self, parent=None, grid_size: int = 48, rows=10, cols=10, theme: Th
223228
self.highlight_rect.setZValue(3)
224229
self.highlight_rect.hide()
225230

231+
def set_theme(self, theme: GridThemes):
232+
self.theme = theme
233+
self.setBackgroundBrush(QColor(theme.value.background))
234+
self.update()
235+
226236
def is_valid_drop_position(self, position, dragging_widget=None, span_x=1, span_y=1):
227237
grid_size = self.grid_size
228238
rows, cols = self.rows, self.cols
@@ -452,6 +462,11 @@ def __init__(self, parent, settings: QSettings):
452462
self.form = QFormLayout()
453463
self.root_layout.addLayout(self.form)
454464

465+
self.form.addRow(Divider("Theme"))
466+
467+
self.theme = UiColorSettingsSwitcher(settings, "theme", parent)
468+
self.form.addRow("Theme", self.theme)
469+
455470
self.form.addRow(Divider("Grid"))
456471

457472
self.grid_size = QSpinBox(minimum=8, maximum=256, singleStep=2, value=self.settings.value("grid", 48, int)) # type: ignore
@@ -487,6 +502,49 @@ def apply(self):
487502
self.on_applied.emit()
488503

489504

505+
class UiColorSettingsSwitcher(QFrame):
506+
def __init__(
507+
self,
508+
settings: QSettings,
509+
key: str,
510+
main_window: 'Application',
511+
):
512+
super().__init__()
513+
self.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Preferred)
514+
515+
self.settings = settings
516+
self.key = key
517+
self.main_window = main_window
518+
519+
root_layout = QHBoxLayout()
520+
self.setLayout(root_layout)
521+
522+
self.dark_mode = QRadioButton("Dark")
523+
self.light_mode = QRadioButton("Light")
524+
self.system_mode = QRadioButton("System")
525+
526+
root_layout.addWidget(self.dark_mode)
527+
root_layout.addWidget(self.light_mode)
528+
root_layout.addWidget(self.system_mode)
529+
530+
# Load saved theme setting
531+
current_theme = self.settings.value(self.key, "Dark")
532+
if current_theme == "Dark":
533+
self.dark_mode.setChecked(True)
534+
elif current_theme == "Light":
535+
self.light_mode.setChecked(True)
536+
else:
537+
self.system_mode.setChecked(True)
538+
539+
self.dark_mode.toggled.connect(lambda: self.save_setting("Dark"))
540+
self.light_mode.toggled.connect(lambda: self.save_setting("Light"))
541+
self.system_mode.toggled.connect(lambda: self.save_setting("System"))
542+
543+
def save_setting(self, value: str):
544+
self.settings.setValue(self.key, value)
545+
self.settings.sync()
546+
self.main_window.apply_theme()
547+
490548
class TopicStatusPanel(QStackedWidget):
491549
def __init__(self, client: CommunicationClient):
492550
super().__init__()
@@ -530,7 +588,7 @@ def set_data(self, data: str | None):
530588

531589

532590
class Application(QMainWindow):
533-
def __init__(self):
591+
def __init__(self, app: QApplication):
534592
super().__init__()
535593
self.setWindowTitle("KevinbotLib Dashboard")
536594

@@ -581,6 +639,7 @@ def __init__(self):
581639
grid_size=self.settings.value("grid", 48, int), # type: ignore
582640
rows=self.settings.value("rows", 10, int), # type: ignore
583641
cols=self.settings.value("cols", 10, int), # type: ignore
642+
theme=GridThemes.Dark,
584643
)
585644
palette = WidgetPalette(self.graphics_view, self.client)
586645
self.model = palette.model
@@ -605,6 +664,26 @@ def __init__(self):
605664
self.settings_window = SettingsWindow(self, self.settings)
606665
self.settings_window.on_applied.connect(self.refresh_settings)
607666

667+
self.theme = Theme(ThemeStyle.System)
668+
self.apply_theme()
669+
670+
def apply_theme(self):
671+
theme_name = self.settings.value("theme", "Dark")
672+
if theme_name == "Dark":
673+
self.theme.set_style(ThemeStyle.Dark)
674+
self.graphics_view.set_theme(GridThemes.Dark)
675+
elif theme_name == "Light":
676+
self.theme.set_style(ThemeStyle.Light)
677+
self.graphics_view.set_theme(GridThemes.Light)
678+
else:
679+
self.theme.set_style(ThemeStyle.System)
680+
if self.theme.is_dark():
681+
self.graphics_view.set_theme(GridThemes.Dark)
682+
else:
683+
self.graphics_view.set_theme(GridThemes.Light)
684+
self.theme.apply(self)
685+
686+
608687
def update_latency(self):
609688
if self.client.websocket:
610689
self.latency_status.setText(f"Latency: {self.client.websocket.latency*1000:.2f}ms")

src/kevinbotlib_dashboard/grid_theme.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,16 @@ class ThemeOptions:
1414

1515
class Themes(Enum):
1616
Dark = ThemeOptions(
17-
background="#1A1A1A",
18-
item_background="#2E2E2E",
19-
foreground="#E0E0E0",
20-
primary="#005C9F",
21-
border="#292929",
17+
background="#1e272a",
18+
item_background="#30383b",
19+
foreground="#d0d8d8",
20+
primary="#4682b4",
21+
border="#2d3639",
22+
)
23+
Light = ThemeOptions(
24+
background="#ffffff",
25+
item_background="#dcdcdc",
26+
foreground="#333333",
27+
primary="#4682b4",
28+
border="#d5d5d5",
2229
)

0 commit comments

Comments
 (0)