style(themes): compact TOML formatting and lift semantic colors
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import os
|
||||
import tomllib
|
||||
from pathlib import Path
|
||||
|
||||
def compact_toml(path: Path):
|
||||
with open(path, "rb") as f:
|
||||
data = tomllib.load(f)
|
||||
|
||||
lines = []
|
||||
# Write top level fields
|
||||
if "name" in data: lines.append(f'name = "{data["name"]}"')
|
||||
if "syntax_palette" in data: lines.append(f'syntax_palette = "{data["syntax_palette"]}"')
|
||||
if "description" in data: lines.append(f'description = "{data["description"]}"')
|
||||
lines.append("")
|
||||
|
||||
# Write colors table
|
||||
if "colors" in data:
|
||||
lines.append("[colors]")
|
||||
colors = data["colors"]
|
||||
# Find max key length for alignment
|
||||
max_key = max(len(k) for k in colors.keys()) if colors else 0
|
||||
|
||||
# Sort keys to keep it predictable
|
||||
for k in sorted(colors.keys()):
|
||||
v = colors[k]
|
||||
# Format as compact array [R, G, B]
|
||||
val_str = f"[{v[0]:3}, {v[1]:3}, {v[2]:3}]"
|
||||
lines.append(f"{k:<{max_key}} = {val_str}")
|
||||
|
||||
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
||||
print(f"Compacted {path}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
for f in Path("themes").glob("*.toml"):
|
||||
compact_toml(f)
|
||||
@@ -0,0 +1,108 @@
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
# Mapping regex -> replacement
|
||||
# Note: we use theme.get_color("semantic", alpha=...)
|
||||
|
||||
REPLACEMENTS = [
|
||||
# status_error
|
||||
(r'imgui\.ImVec4\(1\.0, 0\.0, 0\.0, 0\.2\)', 'theme.get_color("status_error", alpha=0.2)'),
|
||||
(r'imgui\.ImVec4\(1, 0, 0, 1\)', 'theme.get_color("status_error")'),
|
||||
(r'imgui\.ImVec4\(1, 0\.3, 0\.3, ([\d\.]+)\)', r'theme.get_color("status_error", alpha=\1)'),
|
||||
(r'imgui\.ImVec4\(1, 0\.3, 0\.3, 1\)', 'theme.get_color("status_error")'),
|
||||
(r'imgui\.ImVec4\(1, 0\.4, 0\.4, 1\)', 'theme.get_color("status_error")'),
|
||||
(r'vec4\(255, 100, 100\)', 'theme.get_color("status_error")'),
|
||||
(r'vec4\(255, 72, 64, ([\d\.]+)\)', r'theme.get_color("status_error", alpha=\1)'),
|
||||
(r'vec4\(255, 72, 64\)', 'theme.get_color("status_error")'),
|
||||
(r'vec4\(255, 77, 77\)', 'theme.get_color("status_error")'),
|
||||
(r'vec4\(230, 51, 51\)', 'theme.get_color("status_error")'),
|
||||
(r'vec4\(240, 80, 80\)', 'theme.get_color("status_error")'),
|
||||
(r'vec4\(255, 120, 120\)', 'theme.get_color("status_error")'),
|
||||
(r'vec4\(255, 50, 50, ([\d\.]+)\)', r'theme.get_color("status_error", alpha=\1)'),
|
||||
(r'vec4\(255, 100, 100, ([\d\.]+)\)', r'theme.get_color("status_error", alpha=\1)'),
|
||||
|
||||
# status_warning
|
||||
(r'imgui\.ImVec4\(1\.0, 0\.85, 0\.2, 0\.15\)', 'theme.get_color("status_warning", alpha=0.15)'),
|
||||
(r'imgui\.ImVec4\(1\.0, 0\.85, 0\.2, 1\.0\)', 'theme.get_color("status_warning")'),
|
||||
(r'imgui\.ImVec4\(1, 0\.5, 0, 1\)', 'theme.get_color("status_warning")'),
|
||||
(r'imgui\.ImVec4\(1, 1, 0, 1\)', 'theme.get_color("status_warning")'),
|
||||
(r'imgui\.ImVec4\(1\.0, 1\.0, 0\.0, 1\.0\)', 'theme.get_color("status_warning")'),
|
||||
(r'imgui\.ImVec4\(1\.0, 0\.5, 0\.0, 1\.0\)', 'theme.get_color("status_warning")'),
|
||||
(r'imgui\.ImVec4\(1\.0, 0\.3, 0\.0, 1\.0\)', 'theme.get_color("status_warning")'),
|
||||
(r'vec4\(255, 152, 48\)', 'theme.get_color("status_warning")'),
|
||||
(r'vec4\(255, 200, 100\)', 'theme.get_color("status_warning")'),
|
||||
(r'vec4\(200, 200, 100\)', 'theme.get_color("status_warning")'),
|
||||
(r'vec4\(255, 230, 77\)', 'theme.get_color("status_warning")'),
|
||||
(r'vec4\(255, 255, 100\)', 'theme.get_color("status_warning")'),
|
||||
(r'vec4\(240, 200, 80\)', 'theme.get_color("status_warning")'),
|
||||
(r'vec4\(255, 150, 50\)', 'theme.get_color("status_warning")'),
|
||||
(r'vec4\(200, 180, 100\)', 'theme.get_color("status_warning")'),
|
||||
|
||||
# status_success
|
||||
(r'vec4\(80, 255, 80\)', 'theme.get_color("status_success")'),
|
||||
(r'vec4\(80, 255, 80, ([\d\.]+)\)', r'theme.get_color("status_success", alpha=\1)'),
|
||||
(r'imgui\.ImVec4\(0, 1, 0, 1\)', 'theme.get_color("status_success")'),
|
||||
(r'imgui\.ImVec4\(0\.2, 0\.9, 0\.2, 1\)', 'theme.get_color("status_success")'),
|
||||
(r'imgui\.ImVec4\(0\.2, 0\.8, 0\.2, 1\.0\)', 'theme.get_color("status_success")'),
|
||||
(r'imgui\.ImVec4\(0\.39, 1\.0, 0\.39, ([\d\.]+)\)', r'theme.get_color("status_success", alpha=\1)'),
|
||||
(r'imgui\.ImVec4\(0\.3, 0\.8, 0\.3, 1\)', 'theme.get_color("status_success")'),
|
||||
(r'vec4\(100, 255, 100\)', 'theme.get_color("status_success")'),
|
||||
(r'vec4\(120, 220, 120\)', 'theme.get_color("status_success")'),
|
||||
(r'vec4\(0, 255, 0, ([\d\.]+)\)', r'theme.get_color("status_success", alpha=\1)'),
|
||||
(r'vec4\(51, 230, 51\)', 'theme.get_color("status_success")'),
|
||||
|
||||
# status_info
|
||||
(r'imgui\.ImVec4\(0, 1, 1, 1\)', 'theme.get_color("status_info")'),
|
||||
(r'imgui\.ImVec4\(0\.3, 0\.8, 1, 1\)', 'theme.get_color("status_info")'),
|
||||
(r'imgui\.ImVec4\(0\.4, 0\.6, 0\.7, 1\.0\)', 'theme.get_color("status_info")'),
|
||||
(r'vec4\(77, 178, 255\)', 'theme.get_color("status_info")'),
|
||||
(r'vec4\(100, 150, 180\)', 'theme.get_color("status_info")'),
|
||||
|
||||
# text_disabled
|
||||
(r'imgui\.ImVec4\(0\.7, 0\.7, 0\.7, 1\)', 'theme.get_color("text_disabled")'),
|
||||
(r'vec4\(180, 180, 180\)', 'theme.get_color("text_disabled")'),
|
||||
(r'vec4\(160, 160, 160\)', 'theme.get_color("text_disabled")'),
|
||||
(r'vec4\(200, 220, 160\)', 'theme.get_color("text_disabled")'),
|
||||
|
||||
# bubble backgrounds
|
||||
(r'imgui\.ImVec4\(0\.15, 0\.14, 0\.10, 0\.7\)', 'theme.get_color("bubble_vendor", alpha=0.7)'),
|
||||
(r'vec4\(50, 40, 20\)', 'theme.get_color("bubble_vendor")'),
|
||||
|
||||
# Slices
|
||||
(r'vec4\(255, 165, 0, 0\.2\)', 'theme.get_color("slice_manual", alpha=0.2)'),
|
||||
(r'vec4\(0, 255, 0, 0\.15\)', 'theme.get_color("slice_auto", alpha=0.15)'),
|
||||
(r'vec4\(100, 100, 255, 0\.3\)', 'theme.get_color("slice_selection", alpha=0.3)'),
|
||||
(r'imgui\.ImVec4\(1\.0, 0\.65, 0, 0\.2\)', 'theme.get_color("slice_manual", alpha=0.2)'),
|
||||
(r'imgui\.ImVec4\(0, 1\.0, 0, 0\.1\)', 'theme.get_color("slice_auto", alpha=0.1)'),
|
||||
(r'imgui\.ImVec4\(0\.4, 0\.4, 1\.0, 0\.3\)', 'theme.get_color("slice_selection", alpha=0.3)'),
|
||||
(r'imgui\.ImVec4\(0, 1\.0, 0, 0\.15\)', 'theme.get_color("slice_auto", alpha=0.15)'),
|
||||
(r'imgui\.ImVec4\(0, 0, 1\.0, 0\.15\)', 'theme.get_color("slice_selection", alpha=0.15)'),
|
||||
(r'imgui\.ImVec4\(1\.0, 1\.0, 0, 0\.2\)', 'theme.get_color("status_warning", alpha=0.2)'),
|
||||
]
|
||||
|
||||
def apply_lift(path: Path):
|
||||
content = path.read_text(encoding="utf-8")
|
||||
original = content
|
||||
|
||||
for pattern, replacement in REPLACEMENTS:
|
||||
content = re.sub(pattern, replacement, content)
|
||||
|
||||
# Specialized replacements
|
||||
# MMA status block
|
||||
content = re.sub(r'if app\.mma_status == "idle": status_col = imgui\.ImVec4\(0\.7, 0\.7, 0\.7, 1\)',
|
||||
'if app.mma_status == "idle": status_col = theme.get_color("text_disabled")', content)
|
||||
content = re.sub(r'elif app\.mma_status == "running": status_col = vec4\(80, 255, 80\) if is_nerv else imgui\.ImVec4\(1, 1, 0, 1\)',
|
||||
'elif app.mma_status == "running": status_col = theme.get_color("status_warning")', content)
|
||||
content = re.sub(r'elif app\.mma_status == "done": status_col = imgui\.ImVec4\(0, 1, 0, 1\)',
|
||||
'elif app.mma_status == "done": status_col = theme.get_color("status_success")', content)
|
||||
content = re.sub(r'elif app\.mma_status == "error": status_col = vec4\(255, 72, 64\) if is_nerv else imgui\.ImVec4\(1, 0, 0, 1\)',
|
||||
'elif app.mma_status == "error": status_col = theme.get_color("status_error")', content)
|
||||
content = re.sub(r'elif app\.mma_status == "paused": status_col = imgui\.ImVec4\(1, 0\.5, 0, 1\)',
|
||||
'elif app.mma_status == "paused": status_col = theme.get_color("status_warning")', content)
|
||||
|
||||
if content != original:
|
||||
path.write_text(content, encoding="utf-8")
|
||||
print(f"Lifted colors in {path}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
apply_lift(Path("src/gui_2.py"))
|
||||
@@ -0,0 +1,82 @@
|
||||
import os
|
||||
import tomllib
|
||||
import tomli_w
|
||||
from pathlib import Path
|
||||
|
||||
# Get all keys from ThemePalette defaults
|
||||
from src.theme_models import ThemePalette
|
||||
|
||||
default_palette = ThemePalette()
|
||||
ALL_KEYS = list(default_palette.to_dict().keys())
|
||||
|
||||
DARK_SEMANTIC = {
|
||||
"status_success": [80, 255, 80],
|
||||
"status_warning": [255, 152, 48],
|
||||
"status_error": [255, 72, 64],
|
||||
"status_info": [0, 255, 255],
|
||||
"bubble_user": [30, 45, 75],
|
||||
"bubble_ai": [35, 65, 45],
|
||||
"bubble_vendor": [65, 55, 30],
|
||||
"bubble_system": [25, 25, 25],
|
||||
"slice_manual": [255, 165, 0],
|
||||
"slice_auto": [0, 255, 0],
|
||||
"slice_selection": [100, 100, 255],
|
||||
"diff_added": [51, 230, 51],
|
||||
"diff_removed": [230, 51, 51],
|
||||
"diff_header": [77, 178, 255],
|
||||
}
|
||||
|
||||
LIGHT_SEMANTIC = {
|
||||
"status_success": [40, 180, 40],
|
||||
"status_warning": [200, 140, 0],
|
||||
"status_error": [200, 40, 40],
|
||||
"status_info": [40, 100, 200],
|
||||
"bubble_user": [220, 230, 255],
|
||||
"bubble_ai": [220, 255, 220],
|
||||
"bubble_vendor": [255, 240, 200],
|
||||
"bubble_system": [240, 240, 240],
|
||||
"slice_manual": [255, 200, 0],
|
||||
"slice_auto": [80, 255, 80],
|
||||
"slice_selection": [180, 180, 255],
|
||||
"diff_added": [40, 180, 40],
|
||||
"diff_removed": [200, 40, 40],
|
||||
"diff_header": [40, 100, 200],
|
||||
}
|
||||
|
||||
def standardize_theme(path: Path):
|
||||
with open(path, "rb") as f:
|
||||
data = tomllib.load(f)
|
||||
|
||||
name = data.get("name", path.stem)
|
||||
syntax = data.get("syntax_palette", "dark")
|
||||
colors = data.get("colors", {})
|
||||
|
||||
is_light = "light" in name.lower() or syntax == "light"
|
||||
semantic = LIGHT_SEMANTIC if is_light else DARK_SEMANTIC
|
||||
|
||||
# Merge semantic
|
||||
for k, v in semantic.items():
|
||||
if k not in colors:
|
||||
colors[k] = v
|
||||
|
||||
# Ensure all keys are present (optional, but good for completeness)
|
||||
# for k in ALL_KEYS:
|
||||
# if k not in colors:
|
||||
# # We use defaults from ThemePalette anyway, so no need to bloat
|
||||
# pass
|
||||
|
||||
new_data = {
|
||||
"name": name,
|
||||
"syntax_palette": syntax,
|
||||
"description": data.get("description", ""),
|
||||
"colors": colors
|
||||
}
|
||||
|
||||
with open(path, "wb") as f:
|
||||
tomli_w.dump(new_data, f)
|
||||
print(f"Standardized {path}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
themes_dir = Path("themes")
|
||||
for f in themes_dir.glob("*.toml"):
|
||||
standardize_theme(f)
|
||||
Reference in New Issue
Block a user