Skip to content

Commit fa279af

Browse files
baremetalgoCopilot
andcommitted
Preserve structure across themes
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 8d59955 commit fa279af

3 files changed

Lines changed: 65 additions & 12 deletions

File tree

interface/startup.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
_run_startup_validations,
3333
_validate_writable_directory,
3434
)
35-
from .theme import apply_theme, load_startup_theme
35+
from .theme import DARK_THEME, apply_theme, current_theme, load_startup_theme
3636

3737

3838
APP_NAME = "DrunkenBot-IDE"
@@ -271,18 +271,23 @@ def showEvent(self, event: QEvent) -> None:
271271
_apply_windows_taskbar_icon(self)
272272

273273
def _render_checks(self) -> None:
274+
colors = (
275+
{"done": "#ffffff", "running": "#e2cfaa", "failed": "#ff9a9a", "pending": "#bdbdbd"}
276+
if current_theme() == DARK_THEME
277+
else {"done": "#202020", "running": "#7a5100", "failed": "#a82d2d", "pending": "#555555"}
278+
)
274279
rows: list[str] = ["<ul style='margin:0; padding-left:18px; line-height:1.8;'>"]
275280
for label in self._check_order:
276281
state = self._checks.get(label, "pending")
277282
escaped = html.escape(label)
278283
if state == "done":
279-
rows.append(f"<li style='color:#ffffff;'>[OK] {escaped}</li>")
284+
rows.append(f"<li style='color:{colors['done']};'>[OK] {escaped}</li>")
280285
elif state == "running":
281-
rows.append(f"<li style='color:#e2cfaa;'>[*] {escaped}</li>")
286+
rows.append(f"<li style='color:{colors['running']};'>[*] {escaped}</li>")
282287
elif state == "failed":
283-
rows.append(f"<li style='color:#ff9a9a;'>[FAIL] {escaped}</li>")
288+
rows.append(f"<li style='color:{colors['failed']};'>[FAIL] {escaped}</li>")
284289
else:
285-
rows.append(f"<li style='color:#bdbdbd;'>- {escaped}</li>")
290+
rows.append(f"<li style='color:{colors['pending']};'>- {escaped}</li>")
286291
rows.append("</ul>")
287292
self.checks_view.setHtml("".join(rows))
288293
QApplication.processEvents()

interface/startup_splash.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from PySide6.QtGui import QFont, QPixmap
1010
from PySide6.QtWidgets import QDialog, QLabel, QHBoxLayout, QProgressBar, QTextBrowser, QVBoxLayout
1111

12-
from interface.theme import apply_theme, load_startup_theme
12+
from interface.theme import DARK_THEME, apply_theme, current_theme, load_startup_theme
1313

1414

1515
class StartupSplash(QDialog):
@@ -107,12 +107,17 @@ def mark_check_failed(self, label: str) -> None:
107107
self._render_checks()
108108

109109
def _render_checks(self) -> None:
110+
colors = (
111+
{"done": "#ffffff", "running": "#e2cfaa", "failed": "#ff9a9a", "pending": "#bdbdbd"}
112+
if current_theme() == DARK_THEME
113+
else {"done": "#202020", "running": "#7a5100", "failed": "#a82d2d", "pending": "#555555"}
114+
)
110115
rows = ["<ul style='margin:0; padding-left:18px; line-height:1.8;'>"]
111116
for label in self._check_order:
112117
state = self._checks.get(label, "pending")
113118
escaped = html.escape(label)
114119
marker = {"done": "[OK]", "running": "[*]", "failed": "[FAIL]"}.get(state, "-")
115-
color = {"done": "#ffffff", "running": "#e2cfaa", "failed": "#ff9a9a"}.get(state, "#bdbdbd")
120+
color = colors.get(state, colors["pending"])
116121
rows.append(f"<li style='color:{color};'>{marker} {escaped}</li>")
117122
rows.append("</ul>")
118123
self.checks_view.setHtml("".join(rows))

interface/theme.py

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import json
66
from pathlib import Path
7+
import re
78

89
from PySide6.QtWidgets import QApplication
910

@@ -13,6 +14,39 @@
1314
THEME_PREFERENCE_VERSION = 1
1415
_THEME_PROPERTY = "application_theme"
1516
_RECENT_PROJECTS_PATH = Path.home() / ".drunkenbot_ide" / "recent_projects.json"
17+
_SYSTEM_COLOR_MAP = {
18+
"#111111": "#f5f5f5",
19+
"#eeeeee": "#202020",
20+
"#1f1f1f": "#ededed",
21+
"#3a3a3a": "#b8b8b8",
22+
"#171717": "#f0f0f0",
23+
"#181818": "#f7f7f7",
24+
"#242424": "#ffffff",
25+
"#3d3d3d": "#c4c4c4",
26+
"#141414": "#ffffff",
27+
"#dddddd": "#202020",
28+
"#f2f2f2": "#151515",
29+
"#d8eec2": "#29451b",
30+
"#20231d": "#f2f7ec",
31+
"#8fbf5a": "#7aa844",
32+
"#b6d77a": "#476d21",
33+
"#1b1f18": "#f7fbf3",
34+
"#6f8f45": "#7aa844",
35+
"#171a14": "#f7fbf3",
36+
"#f0f0f0": "#202020",
37+
"#555555": "#8a8a8a",
38+
"#6a6a6a": "#8a8a8a",
39+
"#1d1d1d": "#f0f0f0",
40+
"#777777": "#6a6a6a",
41+
"#333333": "#b8b8b8",
42+
"#4a4a4a": "#a0a0a0",
43+
"#d4d4d4": "#303030",
44+
"#2a2a2a": "#eeeeee",
45+
"#3a3326": "#fff7e8",
46+
"#c98f2e": "#b66a00",
47+
"#050505": "#fafafa",
48+
"#2b2b2b": "#c4c4c4",
49+
}
1650

1751

1852
def normalize_theme(theme: object) -> str:
@@ -56,17 +90,26 @@ def current_theme() -> str:
5690
return normalize_theme(app.property(_THEME_PROPERTY) if app is not None else DEFAULT_THEME)
5791

5892

93+
def _stylesheet_for_theme(theme: str) -> str:
94+
"""Return the shared widget stylesheet with the requested color palette."""
95+
stylesheet_path = Path(__file__).with_name("styles.qss")
96+
dark_stylesheet = stylesheet_path.read_text(encoding="utf-8")
97+
if theme == DARK_THEME:
98+
return dark_stylesheet
99+
return re.sub(
100+
r"#[0-9a-fA-F]{6}",
101+
lambda match: _SYSTEM_COLOR_MAP.get(match.group(0).lower(), match.group(0)),
102+
dark_stylesheet,
103+
)
104+
105+
59106
def apply_theme(theme: object) -> str:
60107
"""Apply the selected application-wide theme and return its normalized name."""
61108
selected_theme = normalize_theme(theme)
62109
app = QApplication.instance()
63110
if app is None:
64111
return selected_theme
65-
stylesheet = ""
66-
if selected_theme == DARK_THEME:
67-
stylesheet_path = Path(__file__).with_name("styles.qss")
68-
stylesheet = stylesheet_path.read_text(encoding="utf-8")
69-
app.setStyleSheet(stylesheet)
112+
app.setStyleSheet(_stylesheet_for_theme(selected_theme))
70113
app.setProperty(_THEME_PROPERTY, selected_theme)
71114
for widget in app.allWidgets():
72115
refresh = getattr(widget, "apply_theme", None)

0 commit comments

Comments
 (0)