♻️ refactor(gui): improve left panel readability with better fonts, colors, and layout
- Replace Segoe UI with Roboto for cross-platform compatibility - Increase font sizes for better readability (9→11, 11→12, 14→15) - Update dark theme to VS Code-like colors (#1E1E1E bg) - Brighten accent colors and improve contrast ratios - Fix StepHeader: number circle background, status icon positioning - Enlarge accent bar (4→5px) and buttons (28→32px) - Simplify status text (Completed → Done) - Improve connector line sizing and alignment
This commit is contained in:
+60
-32
@@ -42,9 +42,33 @@ from gui.styles import (
|
||||
STEP_CARD_BG,
|
||||
STEP_CARD_BG_HOVER,
|
||||
STEP_DISABLED_ALPHA,
|
||||
CIRCLE_PENDING,
|
||||
CIRCLE_RUNNING,
|
||||
CIRCLE_COMPLETE,
|
||||
CIRCLE_ERROR,
|
||||
CIRCLE_DISABLED,
|
||||
DESC_TEXT_COLOR,
|
||||
DESC_TEXT_COLOR_LIGHT,
|
||||
DISABLED_TITLE_COLOR,
|
||||
DISABLED_DESC_COLOR,
|
||||
)
|
||||
|
||||
|
||||
def _font(size: int, weight: str = "") -> tuple[str, int, str]:
|
||||
"""Build a cross-platform font tuple.
|
||||
|
||||
Args:
|
||||
size: Font size in points.
|
||||
weight: Font weight ('bold', 'italic', or '').
|
||||
|
||||
Returns:
|
||||
Font tuple compatible with CustomTkinter / tkinter.
|
||||
"""
|
||||
if weight:
|
||||
return ("Roboto", size, weight)
|
||||
return ("Roboto", size)
|
||||
|
||||
|
||||
def _is_dark() -> bool:
|
||||
"""Check if dark mode is active.
|
||||
|
||||
@@ -115,9 +139,9 @@ class StepHeader(ctk.CTkFrame):
|
||||
# Accent bar (left edge)
|
||||
self._accent_bar = ctk.CTkFrame(
|
||||
self,
|
||||
width=4,
|
||||
height=40,
|
||||
corner_radius=2,
|
||||
width=5,
|
||||
height=48,
|
||||
corner_radius=3,
|
||||
fg_color=ACCENT_PENDING,
|
||||
)
|
||||
self._accent_bar.grid(
|
||||
@@ -130,12 +154,12 @@ class StepHeader(ctk.CTkFrame):
|
||||
self._num_label = ctk.CTkLabel(
|
||||
self,
|
||||
text=str(self._step_number),
|
||||
font=("Segoe UI", 13, "bold"),
|
||||
font=_font(14, "bold"),
|
||||
width=STEP_ICON_SIZE,
|
||||
height=STEP_ICON_SIZE,
|
||||
corner_radius=STEP_ICON_SIZE // 2,
|
||||
fg_color="transparent",
|
||||
text_color=DARK_FG if _is_dark() else LIGHT_FG,
|
||||
fg_color=CIRCLE_PENDING,
|
||||
text_color="white",
|
||||
)
|
||||
self._num_label.grid(
|
||||
row=0, column=1,
|
||||
@@ -157,14 +181,14 @@ class StepHeader(ctk.CTkFrame):
|
||||
self._title_label = ctk.CTkLabel(
|
||||
content_frame,
|
||||
text=self._title,
|
||||
font=("Segoe UI", 12, "bold"),
|
||||
font=_font(13, "bold"),
|
||||
anchor="w",
|
||||
text_color=DARK_FG if _is_dark() else LIGHT_FG,
|
||||
)
|
||||
self._title_label.grid(
|
||||
row=0, column=0,
|
||||
sticky="nw",
|
||||
pady=(0, 2),
|
||||
pady=(0, 3),
|
||||
)
|
||||
|
||||
self._desc_label = ctk.CTkLabel(
|
||||
@@ -172,7 +196,7 @@ class StepHeader(ctk.CTkFrame):
|
||||
text=self._description,
|
||||
font=FONT_SMALL,
|
||||
anchor="w",
|
||||
text_color="#999999",
|
||||
text_color=DESC_TEXT_COLOR if _is_dark() else DESC_TEXT_COLOR_LIGHT,
|
||||
wraplength=400,
|
||||
)
|
||||
self._desc_label.grid(
|
||||
@@ -195,10 +219,10 @@ class StepHeader(ctk.CTkFrame):
|
||||
self._run_btn = ctk.CTkButton(
|
||||
btn_frame,
|
||||
text="▶",
|
||||
font=("Segoe UI", 12, "bold"),
|
||||
font=_font(14, "bold"),
|
||||
width=STEP_BUTTON_SIZE,
|
||||
height=STEP_BUTTON_SIZE,
|
||||
corner_radius=6,
|
||||
corner_radius=8,
|
||||
fg_color=STEP_RUN_BG,
|
||||
hover_color=STEP_RUN_BG_HOVER,
|
||||
text_color="white",
|
||||
@@ -211,10 +235,10 @@ class StepHeader(ctk.CTkFrame):
|
||||
self._rerun_btn = ctk.CTkButton(
|
||||
btn_frame,
|
||||
text="↻",
|
||||
font=("Segoe UI", 12, "bold"),
|
||||
font=_font(14, "bold"),
|
||||
width=STEP_BUTTON_SIZE,
|
||||
height=STEP_BUTTON_SIZE,
|
||||
corner_radius=6,
|
||||
corner_radius=8,
|
||||
fg_color=STEP_RUNNER_BG,
|
||||
hover_color=STEP_RUNNER_BG_HOVER,
|
||||
text_color="white",
|
||||
@@ -223,14 +247,18 @@ class StepHeader(ctk.CTkFrame):
|
||||
)
|
||||
self._rerun_btn.grid(row=0, column=0, padx=(0, PADDING_SMALL))
|
||||
|
||||
# Status icon
|
||||
# Status icon — separate from buttons
|
||||
self._status_label = ctk.CTkLabel(
|
||||
btn_frame,
|
||||
self,
|
||||
text="",
|
||||
font=("Segoe UI", 14),
|
||||
anchor="e",
|
||||
font=_font(16),
|
||||
anchor="w",
|
||||
)
|
||||
self._status_label.grid(
|
||||
row=0, column=3,
|
||||
sticky="e",
|
||||
padx=PADDING_SMALL,
|
||||
)
|
||||
self._status_label.grid(row=0, column=0)
|
||||
|
||||
# Hover effect bindings
|
||||
self.bind("<Enter>", self._on_hover_enter)
|
||||
@@ -276,16 +304,16 @@ class StepHeader(ctk.CTkFrame):
|
||||
|
||||
# Number circle
|
||||
circle_colors = {
|
||||
"pending": "#666666",
|
||||
"running": RUNNING_FADE_LIGHT,
|
||||
"complete": ACCENT_COMPLETE,
|
||||
"error": ACCENT_ERROR,
|
||||
"disabled": ACCENT_DISABLED,
|
||||
"pending": CIRCLE_PENDING,
|
||||
"running": CIRCLE_RUNNING,
|
||||
"complete": CIRCLE_COMPLETE,
|
||||
"error": CIRCLE_ERROR,
|
||||
"disabled": CIRCLE_DISABLED,
|
||||
}
|
||||
circle_color = circle_colors.get(status, "#666666")
|
||||
circle_color = circle_colors.get(status, CIRCLE_PENDING)
|
||||
self._num_label.configure(fg_color=circle_color)
|
||||
|
||||
# Status icon
|
||||
# Status icon — separate from buttons
|
||||
icons = {
|
||||
"pending": "",
|
||||
"running": "◌",
|
||||
@@ -313,10 +341,10 @@ class StepHeader(ctk.CTkFrame):
|
||||
self._run_btn.configure(state="hidden")
|
||||
self._rerun_btn.configure(state="hidden")
|
||||
self._stop_pulse()
|
||||
self.configure(fg_color="#2A2A2A")
|
||||
self._num_label.configure(fg_color=ACCENT_DISABLED)
|
||||
self._title_label.configure(text_color="#777777")
|
||||
self._desc_label.configure(text_color="#666666")
|
||||
self.configure(fg_color=DARK_CARD)
|
||||
self._num_label.configure(fg_color=CIRCLE_DISABLED)
|
||||
self._title_label.configure(text_color=DISABLED_TITLE_COLOR)
|
||||
self._desc_label.configure(text_color=DISABLED_DESC_COLOR)
|
||||
elif status == "complete":
|
||||
self._run_btn.configure(state="hidden")
|
||||
self._rerun_btn.configure(state="normal")
|
||||
@@ -333,11 +361,11 @@ class StepHeader(ctk.CTkFrame):
|
||||
self._rerun_btn.configure(state="hidden")
|
||||
self._stop_pulse()
|
||||
|
||||
# Update description
|
||||
# Update description — concise status text
|
||||
desc_map = {
|
||||
"pending": self._description or "Not started",
|
||||
"running": "Running...",
|
||||
"complete": "Completed successfully",
|
||||
"running": "Running…",
|
||||
"complete": "Done",
|
||||
"error": "Failed — click ↻ to retry",
|
||||
"disabled": "Waiting for dependencies",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user