style(themes): compact TOML formatting and lift semantic colors
This commit is contained in:
+28
-3
@@ -16,7 +16,7 @@ paths = [
|
||||
"C:/projects/manual_slop/manual_slop.toml",
|
||||
"C:/projects/Pikuma/ps1-ai/pikuma_ps1.toml",
|
||||
]
|
||||
active = "C:/projects/Pikuma/ps1-ai/pikuma_ps1.toml"
|
||||
active = "C:/projects/gencpp/.ai/gencpp_sloppy.toml"
|
||||
|
||||
[gui]
|
||||
separate_message_panel = true
|
||||
@@ -62,13 +62,38 @@ Diagnostics = false
|
||||
"Undo/Redo History" = false
|
||||
|
||||
[theme]
|
||||
palette = "moss"
|
||||
palette = "gruvbox_dark"
|
||||
font_path = "C:/projects/manual_slop/assets/fonts/MapleMono-Regular.ttf"
|
||||
font_size = 20.0
|
||||
scale = 1.0
|
||||
scale = 1.0199999809265137
|
||||
transparency = 1.0
|
||||
child_transparency = 1.0
|
||||
|
||||
[theme.tone_mapping.moss]
|
||||
brightness = 1.059999942779541
|
||||
contrast = 0.5799999833106995
|
||||
gamma = 1.059999942779541
|
||||
|
||||
[theme.tone_mapping.Binks]
|
||||
brightness = 0.5600000023841858
|
||||
contrast = 0.7900000214576721
|
||||
gamma = 2.2100000381469727
|
||||
|
||||
[theme.tone_mapping.gray_variations]
|
||||
brightness = 0.7699999809265137
|
||||
contrast = 0.7200000286102295
|
||||
gamma = 0.6899999976158142
|
||||
|
||||
[theme.tone_mapping.solarized_light]
|
||||
brightness = 0.6899999976158142
|
||||
contrast = 0.8600000143051147
|
||||
gamma = 0.7699999809265137
|
||||
|
||||
[theme.tone_mapping."10x Dark"]
|
||||
brightness = 0.75
|
||||
contrast = 1.0
|
||||
gamma = 1.0
|
||||
|
||||
[mma]
|
||||
max_workers = 4
|
||||
|
||||
|
||||
+28
-28
@@ -44,20 +44,20 @@ Collapsed=0
|
||||
DockId=0x00000010,0
|
||||
|
||||
[Window][Message]
|
||||
Pos=1196,28
|
||||
Size=1362,1548
|
||||
Pos=1216,28
|
||||
Size=1603,1709
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
[Window][Response]
|
||||
Pos=0,28
|
||||
Size=1194,1548
|
||||
Size=1214,1709
|
||||
Collapsed=0
|
||||
DockId=0x00000010,5
|
||||
|
||||
[Window][Tool Calls]
|
||||
Pos=1196,28
|
||||
Size=1362,1548
|
||||
Pos=1216,28
|
||||
Size=1603,1709
|
||||
Collapsed=0
|
||||
DockId=0x00000006,3
|
||||
|
||||
@@ -76,10 +76,10 @@ Collapsed=0
|
||||
DockId=0xAFC85805,2
|
||||
|
||||
[Window][Theme]
|
||||
Pos=0,28
|
||||
Size=1194,1548
|
||||
Pos=0,29
|
||||
Size=737,1195
|
||||
Collapsed=0
|
||||
DockId=0x00000010,0
|
||||
DockId=0x00000010,1
|
||||
|
||||
[Window][Text Viewer - Entry #7]
|
||||
Pos=379,324
|
||||
@@ -105,26 +105,26 @@ Collapsed=0
|
||||
DockId=0x0000000D,0
|
||||
|
||||
[Window][Discussion Hub]
|
||||
Pos=1196,28
|
||||
Size=1362,1548
|
||||
Pos=739,29
|
||||
Size=974,1195
|
||||
Collapsed=0
|
||||
DockId=0x00000006,1
|
||||
DockId=0x00000006,0
|
||||
|
||||
[Window][Operations Hub]
|
||||
Pos=0,28
|
||||
Size=1194,1548
|
||||
Size=1214,1709
|
||||
Collapsed=0
|
||||
DockId=0x00000010,4
|
||||
|
||||
[Window][Files & Media]
|
||||
Pos=0,28
|
||||
Size=1194,1548
|
||||
Pos=0,29
|
||||
Size=737,1195
|
||||
Collapsed=0
|
||||
DockId=0x00000010,2
|
||||
|
||||
[Window][AI Settings]
|
||||
Pos=0,28
|
||||
Size=1194,1548
|
||||
Pos=0,29
|
||||
Size=737,1195
|
||||
Collapsed=0
|
||||
DockId=0x00000010,3
|
||||
|
||||
@@ -140,8 +140,8 @@ Collapsed=0
|
||||
DockId=0x00000006,2
|
||||
|
||||
[Window][Log Management]
|
||||
Pos=1196,28
|
||||
Size=1362,1548
|
||||
Pos=1216,28
|
||||
Size=1603,1709
|
||||
Collapsed=0
|
||||
DockId=0x00000006,2
|
||||
|
||||
@@ -409,10 +409,10 @@ Collapsed=0
|
||||
DockId=0x00000006,1
|
||||
|
||||
[Window][Project Settings]
|
||||
Pos=0,28
|
||||
Size=1194,1548
|
||||
Pos=0,29
|
||||
Size=737,1195
|
||||
Collapsed=0
|
||||
DockId=0x00000010,1
|
||||
DockId=0x00000010,0
|
||||
|
||||
[Window][Undo/Redo History]
|
||||
Pos=678,28
|
||||
@@ -682,10 +682,10 @@ Column 1 Width=80
|
||||
Column 2 Width=150
|
||||
|
||||
[Table][0x7804123E,3]
|
||||
RefScale=20
|
||||
Column 0 Width=99
|
||||
RefScale=21
|
||||
Column 0 Width=103
|
||||
Column 1 Weight=1.0000
|
||||
Column 2 Width=627
|
||||
Column 2 Width=658
|
||||
|
||||
[Table][0x09B0112E,3]
|
||||
RefScale=20
|
||||
@@ -829,13 +829,13 @@ Column 4 Weight=1.0000
|
||||
DockNode ID=0x00000008 Pos=3125,170 Size=593,1157 Split=Y
|
||||
DockNode ID=0x00000009 Parent=0x00000008 SizeRef=1029,147 Selected=0x0469CA7A
|
||||
DockNode ID=0x0000000A Parent=0x00000008 SizeRef=1029,145 Selected=0xDF822E02
|
||||
DockSpace ID=0xAFC85805 Window=0x079D3A04 Pos=0,28 Size=2558,1548 Split=X
|
||||
DockSpace ID=0xAFC85805 Window=0x079D3A04 Pos=0,29 Size=1713,1195 Split=X
|
||||
DockNode ID=0x00000003 Parent=0xAFC85805 SizeRef=2357,1183 Split=X
|
||||
DockNode ID=0x0000000B Parent=0x00000003 SizeRef=404,1186 Split=X Selected=0xF4139CA2
|
||||
DockNode ID=0x00000005 Parent=0x0000000B SizeRef=1194,1681 Split=Y Selected=0x3F1379AF
|
||||
DockNode ID=0x00000010 Parent=0x00000005 SizeRef=983,1140 CentralNode=1 Selected=0x418C7449
|
||||
DockNode ID=0x00000005 Parent=0x0000000B SizeRef=737,1681 Split=Y Selected=0x3F1379AF
|
||||
DockNode ID=0x00000010 Parent=0x00000005 SizeRef=983,1140 CentralNode=1 Selected=0x8CA2375C
|
||||
DockNode ID=0x00000011 Parent=0x00000005 SizeRef=983,184 Selected=0x432BAE4E
|
||||
DockNode ID=0x00000006 Parent=0x0000000B SizeRef=1362,1681 Selected=0x2C0206CE
|
||||
DockNode ID=0x00000006 Parent=0x0000000B SizeRef=974,1681 Selected=0x6F2B5B04
|
||||
DockNode ID=0x0000000D Parent=0x00000003 SizeRef=435,1186 Selected=0x363E93D6
|
||||
DockNode ID=0x00000004 Parent=0xAFC85805 SizeRef=488,1183 Selected=0x3AEC3498
|
||||
|
||||
|
||||
@@ -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)
|
||||
+104
-104
@@ -80,22 +80,23 @@ def hide_tk_root() -> Tk:
|
||||
def vec4(r: float, g: float, b: float, a: float = 1.0) -> imgui.ImVec4:
|
||||
return imgui.ImVec4(r/255.0, g/255.0, b/255.0, a)
|
||||
|
||||
C_OUT: imgui.ImVec4 = vec4(100, 200, 255)
|
||||
C_IN: imgui.ImVec4 = vec4(140, 255, 160)
|
||||
C_REQ: imgui.ImVec4 = vec4(255, 220, 100)
|
||||
C_RES: imgui.ImVec4 = vec4(180, 255, 180)
|
||||
C_TC: imgui.ImVec4 = vec4(255, 180, 80)
|
||||
C_TR: imgui.ImVec4 = vec4(180, 220, 255)
|
||||
C_TRS: imgui.ImVec4 = vec4(200, 180, 255)
|
||||
C_LBL: imgui.ImVec4 = vec4(180, 180, 180)
|
||||
C_VAL: imgui.ImVec4 = vec4(220, 220, 220)
|
||||
C_KEY: imgui.ImVec4 = vec4(140, 200, 255)
|
||||
C_NUM: imgui.ImVec4 = vec4(180, 255, 180)
|
||||
C_TRM: imgui.ImVec4 = vec4(160, 160, 150) # Trimmed/Cruft
|
||||
C_SUB: imgui.ImVec4 = vec4(220, 200, 120)
|
||||
# Standard Color Constants (now bound to the theming system)
|
||||
def C_OUT() -> imgui.ImVec4: return theme.get_color("status_info")
|
||||
def C_IN() -> imgui.ImVec4: return theme.get_color("status_success")
|
||||
def C_REQ() -> imgui.ImVec4: return theme.get_color("status_warning")
|
||||
def C_RES() -> imgui.ImVec4: return theme.get_color("status_success")
|
||||
def C_TC() -> imgui.ImVec4: return theme.get_color("status_warning")
|
||||
def C_TR() -> imgui.ImVec4: return theme.get_color("status_info")
|
||||
def C_TRS() -> imgui.ImVec4: return theme.get_color("status_info")
|
||||
def C_LBL() -> imgui.ImVec4: return theme.get_color("text_disabled")
|
||||
def C_VAL() -> imgui.ImVec4: return theme.get_color("text")
|
||||
def C_KEY() -> imgui.ImVec4: return theme.get_color("status_info")
|
||||
def C_NUM() -> imgui.ImVec4: return theme.get_color("status_success")
|
||||
def C_TRM() -> imgui.ImVec4: return theme.get_color("text_disabled")
|
||||
def C_SUB() -> imgui.ImVec4: return theme.get_color("text_disabled")
|
||||
|
||||
DIR_COLORS: dict[str, imgui.ImVec4] = {"OUT": C_OUT, "IN": C_IN}
|
||||
KIND_COLORS: dict[str, imgui.ImVec4] = {"request": C_REQ, "response": C_RES, "tool_call": C_TC, "tool_result": C_TR, "tool_result_send": C_TRS}
|
||||
DIR_COLORS: dict[str, typing.Callable[[], imgui.ImVec4]] = {"OUT": C_OUT, "IN": C_IN}
|
||||
KIND_COLORS: dict[str, typing.Callable[[], imgui.ImVec4]] = {"request": C_REQ, "response": C_RES, "tool_call": C_TC, "tool_result": C_TR, "tool_result_send": C_TRS}
|
||||
HEAVY_KEYS: set[str] = {"message", "text", "script", "output", "content"}
|
||||
|
||||
def render_text_viewer(app: App, label: str, content: str, text_type: str = 'text', force_open: bool = False, id_suffix: str = "") -> None:
|
||||
@@ -783,7 +784,7 @@ class App:
|
||||
if self.perf_profiling_enabled: self.perf_monitor.start_component("_gui_func")
|
||||
try:
|
||||
if self.is_viewing_prior_session:
|
||||
with imscope.style_color(imgui.Col_.window_bg, vec4(50, 40, 20)):
|
||||
with imscope.style_color(imgui.Col_.window_bg, theme.get_color("bubble_vendor")):
|
||||
render_main_interface(self)
|
||||
else:
|
||||
render_main_interface(self)
|
||||
@@ -1378,9 +1379,9 @@ def render_usage_analytics_panel(app: App) -> None:
|
||||
if app.controller.rag_config and app.controller.rag_config.enabled:
|
||||
# imgui.same_line()
|
||||
status = app.controller.rag_status
|
||||
if status == "indexing...": color = vec4(100, 255, 100)
|
||||
elif status == "error": color = vec4(255, 100, 100)
|
||||
else: color = vec4(180, 180, 180)
|
||||
if status == "indexing...": color = theme.get_color("status_success")
|
||||
elif status == "error": color = theme.get_color("status_error")
|
||||
else: color = theme.get_color("text_disabled")
|
||||
|
||||
imgui.text_colored(color, f"[RAG: {status}]")
|
||||
if imgui.is_item_hovered(): imgui.set_tooltip(f"RAG is enabled. Status: {status}. Click to rebuild index.")
|
||||
@@ -1448,7 +1449,7 @@ def render_diagnostics_panel(app: App) -> None:
|
||||
imgui.text(comp_name)
|
||||
imgui.table_next_column()
|
||||
if avg_val > 10.0:
|
||||
imgui.text_colored(imgui.ImVec4(1.0, 0.2, 0.2, 1.0), f"{avg_val:.2f}")
|
||||
imgui.text_colored(theme.get_color("status_error"), f"{avg_val:.2f}")
|
||||
else:
|
||||
imgui.text(f"{avg_val:.2f}")
|
||||
imgui.table_next_column()
|
||||
@@ -1512,7 +1513,7 @@ def render_cache_panel(app: App) -> None:
|
||||
ttl_pct = (ttl_remaining / ttl_total * 100) if ttl_total > 0 else 0
|
||||
imgui.text(f"Age: {age_str}")
|
||||
imgui.text(f"TTL: {remaining_str} ({ttl_pct:.0f}%)")
|
||||
color = imgui.ImVec4(0.2, 0.8, 0.2, 1.0)
|
||||
color = theme.get_color("status_success")
|
||||
if ttl_pct < 20: color = imgui.ImVec4(1.0, 0.2, 0.2, 1.0)
|
||||
elif ttl_pct < 50: color = imgui.ImVec4(1.0, 0.8, 0.0, 1.0)
|
||||
imgui.push_style_color(imgui.Col_.plot_histogram, color)
|
||||
@@ -1558,7 +1559,7 @@ def render_tool_analytics_panel(app: App) -> None:
|
||||
imgui.table_set_column_index(2)
|
||||
imgui.text(f"{avg_time:.0f}")
|
||||
imgui.table_set_column_index(3)
|
||||
if fail_pct > 0: imgui.text_colored(imgui.ImVec4(1.0, 0.2, 0.2, 1.0), f"{fail_pct:.0f}%")
|
||||
if fail_pct > 0: imgui.text_colored(theme.get_color("status_error"), f"{fail_pct:.0f}%")
|
||||
else: imgui.text("0%")
|
||||
imgui.end_table()
|
||||
if app.perf_profiling_enabled: app.perf_monitor.end_component("_render_tool_analytics_panel")
|
||||
@@ -1588,9 +1589,9 @@ def render_token_budget_panel(app: App) -> None:
|
||||
current = stats.get("estimated_prompt_tokens", stats.get("total_tokens", 0))
|
||||
limit = stats.get("max_prompt_tokens", 0)
|
||||
headroom = stats.get("headroom_tokens", max(0, limit - current))
|
||||
if pct < 50.0: color = imgui.ImVec4(0.2, 0.8, 0.2, 1.0)
|
||||
elif pct < 80.0: color = imgui.ImVec4(1.0, 0.8, 0.0, 1.0)
|
||||
else: color = imgui.ImVec4(1.0, 0.2, 0.2, 1.0)
|
||||
if pct < 50.0: color = theme.get_color("status_success")
|
||||
elif pct < 80.0: color = theme.get_color("status_warning")
|
||||
else: color = theme.get_color("status_error")
|
||||
imgui.push_style_color(imgui.Col_.plot_histogram, color)
|
||||
imgui.progress_bar(pct / 100.0, imgui.ImVec2(-1, 0), f"{pct:.1f}%")
|
||||
imgui.pop_style_color()
|
||||
@@ -1629,14 +1630,14 @@ def render_token_budget_panel(app: App) -> None:
|
||||
imgui.table_set_column_index(0); render_selectable_label(app, f"tier_{tier}", tier, width=-1)
|
||||
imgui.table_set_column_index(1); render_selectable_label(app, f"model_{tier}", model.split("-")[0], width=-1)
|
||||
imgui.table_set_column_index(2); render_selectable_label(app, f"tokens_{tier}", f"{tokens:,}", width=-1)
|
||||
imgui.table_set_column_index(3); render_selectable_label(app, f"cost_{tier}", f"${cost:.4f}", width=-1, color=imgui.ImVec4(0.2, 0.9, 0.2, 1))
|
||||
imgui.table_set_column_index(3); render_selectable_label(app, f"cost_{tier}", f"${cost:.4f}", width=-1, color=theme.get_color("status_success"))
|
||||
imgui.end_table()
|
||||
tier_total = sum(cost_tracker.estimate_cost(stats.get('model', ''), stats.get('input', 0), stats.get('output', 0)) for stats in app.mma_tier_usage.values())
|
||||
render_selectable_label(app, "session_total_cost", f"Session Total: ${tier_total:.4f}", width=-1, color=imgui.ImVec4(0, 1, 0, 1))
|
||||
render_selectable_label(app, "session_total_cost", f"Session Total: ${tier_total:.4f}", width=-1, color=theme.get_color("status_success"))
|
||||
else:
|
||||
imgui.text_disabled("No MMA tier usage data")
|
||||
if stats.get("would_trim"):
|
||||
imgui.text_colored(imgui.ImVec4(1.0, 0.3, 0.0, 1.0), "WARNING: Next call will trim history")
|
||||
imgui.text_colored(theme.get_color("status_warning"), "WARNING: Next call will trim history")
|
||||
trimmable = stats.get("trimmable_turns", 0)
|
||||
if trimmable: imgui.text_disabled(f"Trimmable turns: {trimmable}")
|
||||
msgs = stats.get("messages")
|
||||
@@ -1704,7 +1705,7 @@ def render_log_management(app: App) -> None:
|
||||
imgui.table_next_column()
|
||||
whitelisted = s_data.get("whitelisted", False)
|
||||
if whitelisted:
|
||||
imgui.text_colored(vec4(255, 215, 0), "YES")
|
||||
imgui.text_colored(theme.get_color("status_warning"), "YES")
|
||||
else:
|
||||
imgui.text("NO")
|
||||
metadata = s_data.get("metadata") or {}
|
||||
@@ -2015,10 +2016,10 @@ def render_agent_tools_panel(app: App) -> None:
|
||||
if app.ui_tool_filter_category != "All" and app.ui_tool_filter_category != cat_name: continue
|
||||
if imgui.tree_node(cat_name):
|
||||
for tool in tools:
|
||||
if tool.weight >= 5: imgui.text_colored(vec4(255, 100, 100), "[HIGH]"); imgui.same_line()
|
||||
elif tool.weight == 4: imgui.text_colored(vec4(255, 255, 100), "[PREF]"); imgui.same_line()
|
||||
elif tool.weight == 2: imgui.text_colored(vec4(255, 150, 50), "[REJECT]"); imgui.same_line()
|
||||
elif tool.weight <= 1: imgui.text_colored(vec4(180, 180, 180), "[LOW]"); imgui.same_line()
|
||||
if tool.weight >= 5: imgui.text_colored(theme.get_color("status_error"), "[HIGH]"); imgui.same_line()
|
||||
elif tool.weight == 4: imgui.text_colored(theme.get_color("status_warning"), "[PREF]"); imgui.same_line()
|
||||
elif tool.weight == 2: imgui.text_colored(theme.get_color("status_warning"), "[REJECT]"); imgui.same_line()
|
||||
elif tool.weight <= 1: imgui.text_colored(theme.get_color("text_disabled"), "[LOW]"); imgui.same_line()
|
||||
|
||||
imgui.text(tool.name); imgui.same_line(180)
|
||||
|
||||
@@ -2197,9 +2198,9 @@ def render_base_prompt_diff_modal(app: App) -> None:
|
||||
else:
|
||||
imgui.begin_child("base_prompt_diff_scroll", imgui.ImVec2(800, 500), True)
|
||||
for line in diff:
|
||||
if line.startswith("+++") or line.startswith("---") or line.startswith("@@"): imgui.text_colored(vec4(77, 178, 255), line.rstrip())
|
||||
elif line.startswith("+"): imgui.text_colored(vec4(51, 230, 51), line.rstrip())
|
||||
elif line.startswith("-"): imgui.text_colored(vec4(230, 51, 51), line.rstrip())
|
||||
if line.startswith("+++") or line.startswith("---") or line.startswith("@@"): imgui.text_colored(theme.get_color("diff_header"), line.rstrip())
|
||||
elif line.startswith("+"): imgui.text_colored(theme.get_color("diff_added"), line.rstrip())
|
||||
elif line.startswith("-"): imgui.text_colored(theme.get_color("diff_removed"), line.rstrip())
|
||||
else: imgui.text(line.rstrip())
|
||||
imgui.end_child()
|
||||
|
||||
@@ -2740,9 +2741,9 @@ def render_files_and_media(app: App) -> None:
|
||||
|
||||
imgui.table_set_column_index(2)
|
||||
if in_context:
|
||||
imgui.text_colored(imgui.ImVec4(0.3, 0.8, 0.3, 1), "Active")
|
||||
imgui.text_colored(theme.get_color("status_success"), "Active")
|
||||
elif is_cached:
|
||||
imgui.text_colored(imgui.ImVec4(0.3, 0.8, 1, 1), "Cached")
|
||||
imgui.text_colored(theme.get_color("status_info"), "Cached")
|
||||
else:
|
||||
imgui.text_disabled(" - ")
|
||||
imgui.end_table()
|
||||
@@ -3048,23 +3049,23 @@ def render_ast_inspector_modal(app: App) -> None:
|
||||
mode = 'hide'
|
||||
if deepest_node: mode = getattr(f_item, 'ast_mask', {}).get(deepest_node['full_path'], 'hide')
|
||||
if mode == 'def':
|
||||
draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + avail_width, pos.y + line_height), imgui.get_color_u32(imgui.ImVec4(0, 1.0, 0, 0.15)))
|
||||
draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + avail_width, pos.y + line_height), imgui.get_color_u32(theme.get_color("slice_auto", alpha=0.15)))
|
||||
elif mode == 'sig':
|
||||
draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + avail_width, pos.y + line_height), imgui.get_color_u32(imgui.ImVec4(0, 0, 1.0, 0.15)))
|
||||
draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + avail_width, pos.y + line_height), imgui.get_color_u32(theme.get_color("slice_selection", alpha=0.15)))
|
||||
elif deepest_node and deepest_node['full_path'] == getattr(app, '_hovered_ast_node', None):
|
||||
draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + avail_width, pos.y + line_height), imgui.get_color_u32(imgui.ImVec4(1.0, 1.0, 0, 0.2)))
|
||||
draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + avail_width, pos.y + line_height), imgui.get_color_u32(theme.get_color("status_warning", alpha=0.2)))
|
||||
|
||||
# 2. Slice Highlight
|
||||
if hasattr(f_item, 'custom_slices'):
|
||||
is_auto = any(slc['start_line'] <= line_num <= slc['end_line'] for slc in f_item.custom_slices if slc.get('tag') == 'auto-ast')
|
||||
is_man = any(slc['start_line'] <= line_num <= slc['end_line'] for slc in f_item.custom_slices if slc.get('tag') != 'auto-ast')
|
||||
if is_man: draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + avail_width, pos.y + line_height), imgui.get_color_u32(imgui.ImVec4(1.0, 0.65, 0, 0.2)))
|
||||
elif is_auto and mode == 'hide': draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + avail_width, pos.y + line_height), imgui.get_color_u32(imgui.ImVec4(0, 1.0, 0, 0.1)))
|
||||
if is_man: draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + avail_width, pos.y + line_height), imgui.get_color_u32(theme.get_color("slice_manual", alpha=0.2)))
|
||||
elif is_auto and mode == 'hide': draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + avail_width, pos.y + line_height), imgui.get_color_u32(theme.get_color("slice_auto", alpha=0.1)))
|
||||
|
||||
# 3. Active Selection Highlight
|
||||
if getattr(app, '_slice_sel_start', -1) != -1 and getattr(app, '_slice_sel_end', -1) != -1:
|
||||
s, e = min(app._slice_sel_start, app._slice_sel_end), max(app._slice_sel_start, app._slice_sel_end)
|
||||
if s <= line_num <= e: draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + avail_width, pos.y + line_height), imgui.get_color_u32(imgui.ImVec4(0.4, 0.4, 1.0, 0.3)))
|
||||
if s <= line_num <= e: draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + avail_width, pos.y + line_height), imgui.get_color_u32(theme.get_color("slice_selection", alpha=0.3)))
|
||||
|
||||
imgui.selectable(f"{line_num:4} | {line_text}##ln{line_num}", False)
|
||||
if imgui.is_item_clicked(): app._slice_sel_start = line_num; app._slice_sel_end = line_num
|
||||
@@ -3234,7 +3235,7 @@ def render_context_files_table(app: App) -> None:
|
||||
imgui.end_popup()
|
||||
if hasattr(f_item, "custom_slices") and f_item.custom_slices:
|
||||
imgui.same_line()
|
||||
imgui.text_colored(imgui.ImVec4(1.0, 0.5, 0.0, 1.0), "[Slices Active]")
|
||||
imgui.text_colored(theme.get_color("status_warning"), "[Slices Active]")
|
||||
|
||||
def render_context_presets(app: App) -> None:
|
||||
presets = app.controller.project.get('context_presets', {})
|
||||
@@ -3389,7 +3390,7 @@ def render_thinking_trace(app: App, entry: dict, segments: list[dict], entry_ind
|
||||
if not segments:
|
||||
return
|
||||
# Tint thinking trace background slightly differently
|
||||
with imscope.style_color(imgui.Col_.child_bg, imgui.ImVec4(0.15, 0.14, 0.10, 0.7)), \
|
||||
with imscope.style_color(imgui.Col_.child_bg, theme.get_color("bubble_vendor", alpha=0.7)), \
|
||||
theme.ai_text_style():
|
||||
with imscope.indent():
|
||||
show_content = True
|
||||
@@ -3458,7 +3459,7 @@ def render_discussion_entry(app: App, entry: dict, index: int) -> None:
|
||||
if usage:
|
||||
inp, out, cache = usage.get("input_tokens", 0), usage.get("output_tokens", 0), usage.get("cache_read_input_tokens", 0)
|
||||
u_str = f" in:{inp} out:{out}" + (f" cache:{cache}" if cache else "")
|
||||
imgui.same_line(); imgui.text_colored(imgui.ImVec4(0.4, 0.6, 0.7, 1.0), u_str)
|
||||
imgui.same_line(); imgui.text_colored(theme.get_color("status_info"), u_str)
|
||||
|
||||
if collapsed:
|
||||
imgui.same_line()
|
||||
@@ -3584,10 +3585,10 @@ def render_session_insights_panel(app: App) -> None:
|
||||
completed = insights.get('completed_tickets', 0)
|
||||
efficiency = insights.get('efficiency', 0)
|
||||
def render_prior_session_view(app: App) -> None:
|
||||
with imscope.style_color(imgui.Col_.child_bg, vec4(50, 40, 20)):
|
||||
with imscope.style_color(imgui.Col_.child_bg, theme.get_color("bubble_vendor")):
|
||||
if imgui.button("Exit Prior Session"): app.controller.cb_exit_prior_session(); app._comms_log_dirty = True
|
||||
imgui.same_line()
|
||||
imgui.text_colored(vec4(200, 180, 100), f"({len(app.prior_disc_entries)} entries)")
|
||||
imgui.text_colored(theme.get_color("status_warning"), f"({len(app.prior_disc_entries)} entries)")
|
||||
imgui.separator()
|
||||
avail = imgui.get_content_region_avail()
|
||||
with imscope.child("prior_scroll", imgui.ImVec2(avail.x, avail.y), imgui.WindowFlags_.horizontal_scrollbar):
|
||||
@@ -3597,12 +3598,12 @@ def render_prior_session_view(app: App) -> None:
|
||||
if imgui.button("+" if collapsed else "-"): entry["collapsed"] = not collapsed
|
||||
imgui.same_line(); role, ts = entry.get("role", "??"), entry.get("ts", "")
|
||||
imgui.text_colored(C_LBL, f"[{role}]")
|
||||
if ts: imgui.same_line(); imgui.text_colored(vec4(160, 160, 160), str(ts))
|
||||
if ts: imgui.same_line(); imgui.text_colored(theme.get_color("text_disabled"), str(ts))
|
||||
content = entry.get("content", "")
|
||||
if collapsed:
|
||||
imgui.same_line(); preview = content.replace("\n", " ")[:80]
|
||||
if len(content) > 80: preview += "..."
|
||||
imgui.text_colored(vec4(180, 180, 180), preview)
|
||||
imgui.text_colored(theme.get_color("text_disabled"), preview)
|
||||
else:
|
||||
with theme.ai_text_style():
|
||||
markdown_helper.render(content, context_id=f'prior_disc_{idx}')
|
||||
@@ -3649,8 +3650,8 @@ def render_synthesis_panel(app: App) -> None:
|
||||
|
||||
def render_comms_history_panel(app: App) -> None:
|
||||
if app.perf_profiling_enabled: app.perf_monitor.start_component("_render_comms_history_panel")
|
||||
st_col = vec4(200, 220, 160)
|
||||
if theme.is_nerv_active(): st_col = vec4(80, 255, 80) # DATA_GREEN for status in NERV
|
||||
st_col = theme.get_color("text_disabled")
|
||||
if theme.is_nerv_active(): st_col = theme.get_color("status_success") # DATA_GREEN for status in NERV
|
||||
imgui.text_colored(st_col, f"Status: {app.ai_status}")
|
||||
imgui.same_line()
|
||||
if imgui.button("Clear##comms"):
|
||||
@@ -3693,7 +3694,7 @@ def render_comms_history_panel(app: App) -> None:
|
||||
|
||||
# Row 1: #Idx TS DIR KIND Provider/Model [Tier]
|
||||
imgui.text_colored(C_LBL, f"#{i_display}"); imgui.same_line()
|
||||
imgui.text_colored(vec4(160, 160, 160), ts)
|
||||
imgui.text_colored(theme.get_color("text_disabled"), ts)
|
||||
|
||||
latency = entry.get("latency") or entry.get("metadata", {}).get("latency")
|
||||
if latency:
|
||||
@@ -3703,7 +3704,7 @@ def render_comms_history_panel(app: App) -> None:
|
||||
ticket_id = entry.get("mma_ticket_id")
|
||||
if ticket_id:
|
||||
imgui.same_line()
|
||||
imgui.text_colored(vec4(255, 120, 120), f"[{ticket_id}]")
|
||||
imgui.text_colored(theme.get_color("status_error"), f"[{ticket_id}]")
|
||||
imgui.same_line()
|
||||
d_col = DIR_COLORS.get(direction, C_VAL)
|
||||
imgui.text_colored(d_col, direction); imgui.same_line()
|
||||
@@ -3857,7 +3858,7 @@ def render_discussion_metadata(app: App) -> None:
|
||||
total_out += entry["usage"].get("output_tokens", 0)
|
||||
total_cache += entry["usage"].get("cache_read_input_tokens", 0)
|
||||
if total_in > 0 or total_out > 0:
|
||||
imgui.text_colored(vec4(100, 150, 180), f"Discussion Tokens: {total_in} In | {total_out} Out | {total_cache} Cache")
|
||||
imgui.text_colored(theme.get_color("status_info"), f"Discussion Tokens: {total_in} In | {total_out} Out | {total_cache} Cache")
|
||||
imgui.separator()
|
||||
|
||||
imgui.text_colored(C_LBL, "commit:"); imgui.same_line()
|
||||
@@ -4053,7 +4054,7 @@ def render_vendor_state(app: App) -> None:
|
||||
imgui.table_setup_column("Value", imgui.TableColumnFlags_.width_stretch)
|
||||
imgui.table_setup_column("State", imgui.TableColumnFlags_.width_fixed, 60)
|
||||
imgui.table_headers_row()
|
||||
state_colors = {"ok": vec4(120, 220, 120), "warn": vec4(240, 200, 80), "error": vec4(240, 80, 80), "info": vec4(180, 180, 180)}
|
||||
state_colors = {"ok": theme.get_color("status_success"), "warn": theme.get_color("status_warning"), "error": theme.get_color("status_error"), "info": theme.get_color("text_disabled")}
|
||||
for m in metrics:
|
||||
imgui.table_next_row()
|
||||
imgui.table_next_column(); imgui.text(m.label)
|
||||
@@ -4061,7 +4062,7 @@ def render_vendor_state(app: App) -> None:
|
||||
imgui.text(m.value)
|
||||
if imgui.is_item_hovered(): imgui.set_tooltip(m.tooltip)
|
||||
imgui.table_next_column()
|
||||
imgui.text_colored(state_colors.get(m.state, vec4(180, 180, 180)), m.state)
|
||||
imgui.text_colored(state_colors.get(m.state, theme.get_color("text_disabled")), m.state)
|
||||
imgui.end_table()
|
||||
|
||||
def render_message_panel(app: App) -> None:
|
||||
@@ -4071,8 +4072,7 @@ def render_message_panel(app: App) -> None:
|
||||
if is_live:
|
||||
val = math.sin(time.time() * 10 * math.pi)
|
||||
alpha = 1.0 if val > 0 else 0.0
|
||||
c = imgui.ImVec4(0.39, 1.0, 0.39, alpha)
|
||||
if theme.is_nerv_active(): c = vec4(80, 255, 80, alpha) # DATA_GREEN for LIVE in NERV
|
||||
c = theme.get_color("status_success", alpha=alpha)
|
||||
imgui.text_colored(c, "LIVE")
|
||||
imgui.separator()
|
||||
ch, app.ui_ai_input = imgui.input_text_multiline("##ai_in", app.ui_ai_input, imgui.ImVec2(-1, -40))
|
||||
@@ -4323,12 +4323,12 @@ def render_text_viewer_window(app: App) -> None:
|
||||
is_auto_sliced = any(slc['start_line'] <= line_num <= slc['end_line'] for slc in app.ui_editing_slices_file.custom_slices if slc.get('tag') == 'auto-ast')
|
||||
is_manual_sliced = any(slc['start_line'] <= line_num <= slc['end_line'] for slc in app.ui_editing_slices_file.custom_slices if slc.get('tag') != 'auto-ast')
|
||||
|
||||
if is_manual_sliced: draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + imgui.get_content_region_avail().x, pos.y + line_height), imgui.get_color_u32(vec4(255, 165, 0, 0.2)))
|
||||
elif is_auto_sliced: draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + imgui.get_content_region_avail().x, pos.y + line_height), imgui.get_color_u32(vec4(0, 255, 0, 0.15)))
|
||||
if is_manual_sliced: draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + imgui.get_content_region_avail().x, pos.y + line_height), imgui.get_color_u32(theme.get_color("slice_manual", alpha=0.2)))
|
||||
elif is_auto_sliced: draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + imgui.get_content_region_avail().x, pos.y + line_height), imgui.get_color_u32(theme.get_color("slice_auto", alpha=0.15)))
|
||||
|
||||
if app._slice_sel_start != -1 and app._slice_sel_end != -1:
|
||||
s, e = min(app._slice_sel_start, app._slice_sel_end), max(app._slice_sel_start, app._slice_sel_end)
|
||||
if s <= line_num <= e: draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + imgui.get_content_region_avail().x, pos.y + line_height), imgui.get_color_u32(vec4(100, 100, 255, 0.3)))
|
||||
if s <= line_num <= e: draw_list.add_rect_filled(pos, imgui.ImVec2(pos.x + imgui.get_content_region_avail().x, pos.y + line_height), imgui.get_color_u32(theme.get_color("slice_selection", alpha=0.3)))
|
||||
imgui.selectable(f"{line_num:4} | {line_text}##ln{line_num}", False)
|
||||
if imgui.is_item_clicked(): app._slice_sel_start = line_num; app._slice_sel_end = line_num
|
||||
if imgui.is_item_hovered(imgui.HoveredFlags_.allow_when_blocked_by_active_item) and imgui.is_mouse_down(0): app._slice_sel_end = line_num
|
||||
@@ -4340,7 +4340,7 @@ def render_text_viewer_window(app: App) -> None:
|
||||
if app.perf_profiling_enabled: app.perf_monitor.start_component("_render_text_viewer_ced")
|
||||
app._text_viewer_editor.render(f"##ced_{app.text_viewer_title}", imgui.ImVec2(-1, -1))
|
||||
if app.perf_profiling_enabled: app.perf_monitor.end_component("_render_text_viewer_ced")
|
||||
except Exception as e: imgui.text_colored(vec4(255, 100, 100), f"CED Error: {e}"); imgui.text_unformatted(app.text_viewer_content)
|
||||
except Exception as e: imgui.text_colored(theme.get_color("status_error"), f"CED Error: {e}"); imgui.text_unformatted(app.text_viewer_content)
|
||||
else:
|
||||
with imscope.child("tv_scroll", -1, -1, True):
|
||||
if app.text_viewer_wrap: imgui.push_text_wrap_pos(imgui.get_content_region_avail().x)
|
||||
@@ -4358,23 +4358,23 @@ def render_patch_modal(app: App) -> None:
|
||||
p_max = imgui.ImVec2(p_min.x + imgui.get_window_size().x, p_min.y + imgui.get_window_size().y)
|
||||
shaders.draw_soft_shadow(imgui.get_background_draw_list(), p_min, p_max, imgui.ImVec4(0, 0, 0, 0.6), 25.0, 6.0)
|
||||
|
||||
imgui.text_colored(vec4(255, 230, 77), "Tier 4 QA Generated a Patch")
|
||||
imgui.text_colored(theme.get_color("status_warning"), "Tier 4 QA Generated a Patch")
|
||||
imgui.separator()
|
||||
if app._pending_patch_files:
|
||||
imgui.text("Files to modify:")
|
||||
for f in app._pending_patch_files: imgui.text(f" - {f}")
|
||||
imgui.separator()
|
||||
if app._patch_error_message:
|
||||
imgui.text_colored(vec4(255, 77, 77), f"Error: {app._patch_error_message}")
|
||||
imgui.text_colored(theme.get_color("status_error"), f"Error: {app._patch_error_message}")
|
||||
imgui.separator()
|
||||
imgui.text("Diff Preview:")
|
||||
imgui.begin_child("patch_diff_scroll", imgui.ImVec2(-1, 280), True)
|
||||
if app._pending_patch_text:
|
||||
diff_lines = app._pending_patch_text.split("\n")
|
||||
for line in diff_lines:
|
||||
if line.startswith("+++") or line.startswith("---") or line.startswith("@@"): imgui.text_colored(vec4(77, 178, 255), line)
|
||||
elif line.startswith("+"): imgui.text_colored(vec4(51, 230, 51), line)
|
||||
elif line.startswith("-"): imgui.text_colored(vec4(230, 51, 51), line)
|
||||
if line.startswith("+++") or line.startswith("---") or line.startswith("@@"): imgui.text_colored(theme.get_color("diff_header"), line)
|
||||
elif line.startswith("+"): imgui.text_colored(theme.get_color("diff_added"), line)
|
||||
elif line.startswith("-"): imgui.text_colored(theme.get_color("diff_removed"), line)
|
||||
else: imgui.text(line)
|
||||
imgui.end_child()
|
||||
imgui.separator()
|
||||
@@ -4454,7 +4454,7 @@ def render_approve_script_modal(app: App) -> None:
|
||||
if not dlg: imgui.close_current_popup()
|
||||
else:
|
||||
imgui.text("The AI wants to run the following PowerShell script:")
|
||||
imgui.text_colored(vec4(200, 200, 100), f"base_dir: {dlg._base_dir}")
|
||||
imgui.text_colored(theme.get_color("status_warning"), f"base_dir: {dlg._base_dir}")
|
||||
imgui.separator()
|
||||
# Checkbox to toggle full preview inside modal
|
||||
if not hasattr(app, 'ui_approve_modal_preview'): app.ui_approve_modal_preview = False
|
||||
@@ -4632,13 +4632,13 @@ def render_error_tint(app: App) -> None:
|
||||
if not HotReloader.is_error_state: return
|
||||
draw_list = imgui.get_background_draw_list()
|
||||
display_size = imgui.get_io().display_size
|
||||
# Translucent red: (1.0, 0.0, 0.0, 0.2)
|
||||
tint_col = imgui.get_color_u32(imgui.ImVec4(1.0, 0.0, 0.0, 0.2))
|
||||
# Translucent red
|
||||
tint_col = imgui.get_color_u32(theme.get_color("status_error", alpha=0.2))
|
||||
draw_list.add_rect_filled(imgui.ImVec2(0, 0), display_size, tint_col)
|
||||
if app.perf_profiling_enabled:
|
||||
imgui.set_next_window_pos(imgui.ImVec2(10, 50))
|
||||
with imscope.window("Hot Reload Error", None, imgui.WindowFlags_.always_auto_resize | imgui.WindowFlags_.no_title_bar):
|
||||
imgui.text_colored(imgui.ImVec4(1, 0, 0, 1), "HOT RELOAD ERROR")
|
||||
imgui.text_colored(theme.get_color("status_error"), "HOT RELOAD ERROR")
|
||||
imgui.text_wrapped(HotReloader.last_error or "Unknown error")
|
||||
|
||||
|
||||
@@ -4651,14 +4651,14 @@ def render_project_stale_tint(app: App) -> None:
|
||||
if not app.controller.is_project_stale(): return
|
||||
draw_list = imgui.get_background_draw_list()
|
||||
display_size = imgui.get_io().display_size
|
||||
tint_col = imgui.get_color_u32(imgui.ImVec4(1.0, 0.85, 0.2, 0.15))
|
||||
tint_col = imgui.get_color_u32(theme.get_color("status_warning", alpha=0.15))
|
||||
draw_list.add_rect_filled(imgui.ImVec2(0, 0), display_size, tint_col)
|
||||
pending = app.controller._project_switch_pending_path or app.controller.active_project_path
|
||||
imgui.set_next_window_pos(imgui.ImVec2(10, 50))
|
||||
with imscope.window("Project Stale", None,
|
||||
imgui.WindowFlags_.always_auto_resize | imgui.WindowFlags_.no_title_bar |
|
||||
imgui.WindowFlags_.no_resize | imgui.WindowFlags_.no_move):
|
||||
imgui.text_colored(imgui.ImVec4(1.0, 0.85, 0.2, 1.0), "PROJECT SWITCHING")
|
||||
imgui.text_colored(theme.get_color("status_warning"), "PROJECT SWITCHING")
|
||||
imgui.text_wrapped(f"Loading: {Path(pending).stem if pending else '?'}")
|
||||
imgui.text_wrapped("UI is read-only until the switch completes. You can still browse tabs.")
|
||||
|
||||
@@ -4701,7 +4701,7 @@ def render_mma_dashboard(app: App) -> None:
|
||||
render_mma_focus_selector(app)
|
||||
imgui.separator()
|
||||
if app.is_viewing_prior_session:
|
||||
c = vec4(255, 152, 48) if theme.is_nerv_active() else vec4(255, 200, 100)
|
||||
c = theme.get_color("status_warning") if theme.is_nerv_active() else theme.get_color("status_warning")
|
||||
imgui.text_colored(c, "HISTORICAL VIEW - READ ONLY")
|
||||
if app.perf_profiling_enabled: app.perf_monitor.end_component("_render_mma_dashboard")
|
||||
return
|
||||
@@ -4739,7 +4739,7 @@ def render_mma_modals(app: App) -> None:
|
||||
if not app._pending_ask_dialog or app._ask_tool_data is None: imgui.close_current_popup()
|
||||
else:
|
||||
tool_name = app._ask_tool_data.get("tool", "unknown"); tool_args = app._ask_tool_data.get("args", {})
|
||||
imgui.text("The AI wants to execute a tool:"); imgui.text_colored(vec4(200, 200, 100), f"Tool: {tool_name}"); imgui.separator()
|
||||
imgui.text("The AI wants to execute a tool:"); imgui.text_colored(theme.get_color("status_warning"), f"Tool: {tool_name}"); imgui.separator()
|
||||
imgui.text("Arguments:"); imgui.begin_child("ask_args_child", imgui.ImVec2(400, 200), True); imgui.text_unformatted(json.dumps(tool_args, indent=2)); imgui.end_child()
|
||||
imgui.separator()
|
||||
if imgui.button("Approve", imgui.ImVec2(120, 0)): app._handle_approve_ask(); imgui.close_current_popup()
|
||||
@@ -4796,7 +4796,7 @@ def render_mma_modals(app: App) -> None:
|
||||
imgui.end_popup()
|
||||
# Cycle Detection
|
||||
if imgui.begin_popup_modal("Cycle Detected!", None, imgui.WindowFlags_.always_auto_resize)[0]:
|
||||
imgui.text_colored(imgui.ImVec4(1, 0.3, 0.3, 1), "The dependency graph contains a cycle!")
|
||||
imgui.text_colored(theme.get_color("status_error", alpha=1), "The dependency graph contains a cycle!")
|
||||
imgui.text("Please remove the circular dependency.")
|
||||
if imgui.button("OK"): imgui.close_current_popup()
|
||||
imgui.end_popup()
|
||||
@@ -4812,16 +4812,16 @@ def render_mma_track_summary(app: App) -> None:
|
||||
total_cost = sum(cost_tracker.estimate_cost(u.get('model','unknown'), u.get('input',0), u.get('output',0)) for u in app.mma_tier_usage.values())
|
||||
imgui.text("Track:"); imgui.same_line(); imgui.text_colored(C_VAL, track_name); imgui.same_line(); imgui.text(" | Status:"); imgui.same_line()
|
||||
if app.mma_status == "paused":
|
||||
imgui.text_colored(vec4(255, 152, 48) if is_nerv else imgui.ImVec4(1, 0.5, 0, 1), "PIPELINE PAUSED"); imgui.same_line()
|
||||
imgui.text_colored(theme.get_color("status_warning") if is_nerv else theme.get_color("status_warning"), "PIPELINE PAUSED"); imgui.same_line()
|
||||
status_col = imgui.ImVec4(1, 1, 1, 1)
|
||||
if app.mma_status == "idle": status_col = imgui.ImVec4(0.7, 0.7, 0.7, 1)
|
||||
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 == "done": status_col = imgui.ImVec4(0, 1, 0, 1)
|
||||
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 == "paused": status_col = imgui.ImVec4(1, 0.5, 0, 1)
|
||||
imgui.text_colored(status_col, app.mma_status.upper()); imgui.same_line(); imgui.text(" | Cost:"); imgui.same_line(); imgui.text_colored(imgui.ImVec4(0, 1, 0, 1), f"${total_cost:,.4f}")
|
||||
if app.mma_status == "idle": status_col = theme.get_color("text_disabled")
|
||||
elif app.mma_status == "running": status_col = theme.get_color("status_success") if is_nerv else theme.get_color("status_warning")
|
||||
elif app.mma_status == "done": status_col = theme.get_color("status_success")
|
||||
elif app.mma_status == "error": status_col = theme.get_color("status_error") if is_nerv else theme.get_color("status_error")
|
||||
elif app.mma_status == "paused": status_col = theme.get_color("status_warning")
|
||||
imgui.text_colored(status_col, app.mma_status.upper()); imgui.same_line(); imgui.text(" | Cost:"); imgui.same_line(); imgui.text_colored(theme.get_color("status_success"), f"${total_cost:,.4f}")
|
||||
perc = track_stats["percentage"] / 100.0
|
||||
p_color = imgui.ImVec4(1, 0, 0, 1) if track_stats["percentage"] < 33 else (imgui.ImVec4(1, 1, 0, 1) if track_stats["percentage"] < 66 else imgui.ImVec4(0, 1, 0, 1))
|
||||
p_color = theme.get_color("status_error") if track_stats["percentage"] < 33 else (theme.get_color("status_warning") if track_stats["percentage"] < 66 else theme.get_color("status_success"))
|
||||
imgui.push_style_color(imgui.Col_.plot_histogram, p_color); imgui.progress_bar(perc, imgui.ImVec2(-1, 0), f"{track_stats['percentage']:.1f}%"); imgui.pop_style_color()
|
||||
if imgui.begin_table("ticket_stats_breakdown", 4):
|
||||
for lbl, val in [("Completed:", track_stats["completed"]), ("In Progress:", track_stats["in_progress"]), ("Blocked:", track_stats["blocked"]), ("Todo:", track_stats["todo"])]:
|
||||
@@ -4857,10 +4857,10 @@ def render_mma_track_browser(app: App) -> None:
|
||||
for track in app.tracks:
|
||||
imgui.table_next_row(); imgui.table_next_column(); imgui.text(track.get("title", "Untitled")); imgui.table_next_column()
|
||||
status = track.get("status", "unknown").lower()
|
||||
c = imgui.ImVec4(0.7, 0.7, 0.7, 1) if status == "new" else (vec4(80, 255, 80) if status == "active" and theme.is_nerv_active() else (imgui.ImVec4(1, 1, 0, 1) if status == "active" else (imgui.ImVec4(0, 1, 0, 1) if status == "done" else (imgui.ImVec4(1, 0, 0, 1) if status == "blocked" else imgui.ImVec4(1, 1, 1, 1)))))
|
||||
c = theme.get_color("text_disabled") if status == "new" else (theme.get_color("status_success") if status == "active" and theme.is_nerv_active() else (theme.get_color("status_warning") if status == "active" else (theme.get_color("status_success") if status == "done" else (theme.get_color("status_error") if status == "blocked" else imgui.ImVec4(1, 1, 1, 1)))))
|
||||
imgui.text_colored(c, status.upper()); imgui.table_next_column()
|
||||
prog = track.get("progress", 0.0)
|
||||
p_c = imgui.ImVec4(1, 0, 0, 1) if prog < 0.33 else (imgui.ImVec4(1, 1, 0, 1) if prog < 0.66 else imgui.ImVec4(0, 1, 0, 1))
|
||||
p_c = theme.get_color("status_error") if prog < 0.33 else (theme.get_color("status_warning") if prog < 0.66 else theme.get_color("status_success"))
|
||||
imgui.push_style_color(imgui.Col_.plot_histogram, p_c); imgui.progress_bar(prog, imgui.ImVec2(-1, 0), f"{int(prog*100)}%"); imgui.pop_style_color(); imgui.table_next_column()
|
||||
if imgui.button(f"Load##{track.get('id')}"): app._cb_load_track(str(track.get("id") or ""))
|
||||
imgui.end_table()
|
||||
@@ -4902,9 +4902,9 @@ def render_mma_global_controls(app: App) -> None:
|
||||
if imgui.button("Reload GUI"):
|
||||
success = app._trigger_hot_reload()
|
||||
if success:
|
||||
imgui.text_colored(imgui.ImVec4(0, 1, 0, 1), "Reloaded!")
|
||||
imgui.text_colored(theme.get_color("status_success"), "Reloaded!")
|
||||
else:
|
||||
imgui.text_colored(imgui.ImVec4(1, 0, 0, 1), f"Error: {app._hot_reload_error or 'Unknown'}")
|
||||
imgui.text_colored(theme.get_color("status_error"), f"Error: {app._hot_reload_error or 'Unknown'}")
|
||||
imgui.same_line(); imgui.text_disabled("(Ctrl+Alt+R)")
|
||||
|
||||
def render_mma_usage_section(app: App) -> None:
|
||||
@@ -4999,7 +4999,7 @@ def render_tier_stream_panel(app: App, tier_key: str, stream_key: str | None) ->
|
||||
"""
|
||||
if app.perf_profiling_enabled: app.perf_monitor.start_component("_render_tier_stream_panel")
|
||||
if app.is_viewing_prior_session:
|
||||
imgui.text_colored(vec4(255, 200, 100), "HISTORICAL VIEW - READ ONLY")
|
||||
imgui.text_colored(theme.get_color("status_warning"), "HISTORICAL VIEW - READ ONLY")
|
||||
if app.perf_profiling_enabled: app.perf_monitor.end_component("_render_tier_stream_panel")
|
||||
return
|
||||
if stream_key is not None:
|
||||
@@ -5024,11 +5024,11 @@ def render_tier_stream_panel(app: App, tier_key: str, stream_key: str | None) ->
|
||||
ticket_id = key.split(": ", 1)[-1] if ": " in key else key
|
||||
status = worker_status.get(key, "unknown")
|
||||
if status == "running":
|
||||
imgui.text_colored(imgui.ImVec4(1, 1, 0, 1), f"{ticket_id} [{status}]")
|
||||
imgui.text_colored(theme.get_color("status_warning"), f"{ticket_id} [{status}]")
|
||||
elif status == "completed":
|
||||
imgui.text_colored(imgui.ImVec4(0, 1, 0, 1), f"{ticket_id} [{status}]")
|
||||
imgui.text_colored(theme.get_color("status_success"), f"{ticket_id} [{status}]")
|
||||
elif status == "failed":
|
||||
imgui.text_colored(imgui.ImVec4(1, 0, 0, 1), f"{ticket_id} [{status}]")
|
||||
imgui.text_colored(theme.get_color("status_error"), f"{ticket_id} [{status}]")
|
||||
else:
|
||||
imgui.text(f"{ticket_id} [{status}]")
|
||||
imgui.begin_child(f"##tier3_{ticket_id}_scroll", imgui.ImVec2(-1, 150), True)
|
||||
@@ -5156,9 +5156,9 @@ def render_ticket_queue(app: App) -> None:
|
||||
|
||||
imgui.table_next_column()
|
||||
prio = t.get('priority', 'medium')
|
||||
p_col = vec4(180, 180, 180) # gray
|
||||
if prio == 'high': _col = vec4(255, 100, 100) # red
|
||||
elif prio == 'medium': p_col = vec4(255, 255, 100) # yellow
|
||||
p_col = theme.get_color("text_disabled") # gray
|
||||
if prio == 'high': _col = theme.get_color("status_error") # red
|
||||
elif prio == 'medium': p_col = theme.get_color("status_warning") # yellow
|
||||
|
||||
imgui.push_style_color(imgui.Col_.text, p_col)
|
||||
if imgui.begin_combo(f"##prio_{tid}", prio, imgui.ComboFlags_.height_small):
|
||||
@@ -5184,7 +5184,7 @@ def render_ticket_queue(app: App) -> None:
|
||||
# Status
|
||||
imgui.table_next_column()
|
||||
status = t.get('status', 'todo')
|
||||
if t.get('model_override'): imgui.text_colored(imgui.ImVec4(1, 0.5, 0, 1), f"{status} [{t.get('model_override')}]")
|
||||
if t.get('model_override'): imgui.text_colored(theme.get_color("status_warning"), f"{status} [{t.get('model_override')}]")
|
||||
else: imgui.text(t.get('status', 'todo'))
|
||||
|
||||
# Description
|
||||
@@ -5223,14 +5223,14 @@ def render_task_dag_panel(app: App) -> None: # 4. Task DAG Visualizer
|
||||
int_id = abs(hash(tid))
|
||||
ed.begin_node(ed.NodeId(int_id))
|
||||
if getattr(app, "ui_project_execution_mode", "native") == "beads":
|
||||
imgui.text_colored(imgui.ImVec4(0, 1, 1, 1), "[B] ")
|
||||
imgui.text_colored(theme.get_color("status_info"), "[B] ")
|
||||
imgui.same_line()
|
||||
imgui.text_colored(C_KEY, f"Ticket: {tid}")
|
||||
status = t.get('status', 'todo')
|
||||
s_col = C_VAL
|
||||
if status == 'done' or status == 'complete': s_col = C_IN
|
||||
elif status == 'in_progress' or status == 'running': s_col = C_OUT
|
||||
elif status == 'error': s_col = imgui.ImVec4(1, 0.4, 0.4, 1)
|
||||
elif status == 'error': s_col = theme.get_color("status_error")
|
||||
imgui.text("Status: ")
|
||||
imgui.same_line()
|
||||
imgui.text_colored(s_col, status)
|
||||
@@ -5359,7 +5359,7 @@ def render_beads_tab(app: App) -> None:
|
||||
missing = []
|
||||
if not dolt_path: missing.append("'dolt'")
|
||||
if not bd_path: missing.append("'bd'")
|
||||
imgui.text_colored(imgui.ImVec4(1, 0.5, 0, 1), f"Warning: {', '.join(missing)} not found in PATH.")
|
||||
imgui.text_colored(theme.get_color("status_warning"), f"Warning: {', '.join(missing)} not found in PATH.")
|
||||
imgui.text_wrapped("Beads mode requires Dolt and the Beads (bd) CLI tools.")
|
||||
|
||||
if getattr(app, "ui_project_execution_mode", "native") == "beads":
|
||||
@@ -5385,7 +5385,7 @@ def render_beads_tab(app: App) -> None:
|
||||
imgui.text(str(b.title))
|
||||
imgui.end_table()
|
||||
except Exception as e:
|
||||
imgui.text_colored(imgui.ImVec4(1, 0, 0, 1), f"Error loading beads: {e}")
|
||||
imgui.text_colored(theme.get_color("status_error"), f"Error loading beads: {e}")
|
||||
|
||||
def render_mma_focus_selector(app: App) -> None:
|
||||
"""
|
||||
@@ -5409,7 +5409,7 @@ def render_empty_context_modal(app: App) -> None:
|
||||
app.show_empty_context_modal = False
|
||||
|
||||
if imgui.begin_popup_modal("Empty Context Warning", True, imgui.WindowFlags_.always_auto_resize)[0]:
|
||||
imgui.text_colored(imgui.ImVec4(1.0, 1.0, 0.0, 1.0), "WARNING: Empty Context Composition")
|
||||
imgui.text_colored(theme.get_color("status_warning"), "WARNING: Empty Context Composition")
|
||||
imgui.text("You are attempting to generate a response without any files selected.")
|
||||
imgui.text("This may result in poor AI performance or loss of project context.")
|
||||
imgui.separator()
|
||||
@@ -5436,7 +5436,7 @@ def render_context_modals(app: App) -> None:
|
||||
imgui.separator()
|
||||
imgui.begin_child("missing_files_list", imgui.ImVec2(0, 150), True)
|
||||
for f in app.missing_context_files:
|
||||
imgui.text_colored(imgui.ImVec4(1, 0.4, 0.4, 1), f)
|
||||
imgui.text_colored(theme.get_color("status_error"), f)
|
||||
imgui.end_child()
|
||||
imgui.separator()
|
||||
|
||||
|
||||
+101
-81
@@ -10,6 +10,7 @@ Scale uses imgui.get_style().font_scale_main.
|
||||
|
||||
from imgui_bundle import imgui, hello_imgui
|
||||
from typing import Any, Optional
|
||||
import typing
|
||||
from contextlib import nullcontext
|
||||
from src import imgui_scopes as imscope
|
||||
import src.theme_nerv
|
||||
@@ -22,22 +23,12 @@ from src.theme_models import ThemeFile, load_themes_from_dir, load_themes_from_t
|
||||
|
||||
# Each palette maps imgui color enum values to (R, G, B, A) floats [0..1].
|
||||
# Only keys that differ from the ImGui dark defaults need to be listed.
|
||||
# ------------------------------------------------------------------ internal helpers
|
||||
|
||||
def _c(r: int, g: int, b: int, a: int = 255) -> tuple[float, float, float, float]:
|
||||
"""
|
||||
Convert 0-255 RGBA to 0.0-1.0 floats.
|
||||
[C: src/theme_nerv.py:module]
|
||||
"""
|
||||
"""Convert 0-255 RGBA to 0.0-1.0 floats."""
|
||||
return (r / 255.0, g / 255.0, b / 255.0, a / 255.0)
|
||||
|
||||
_BUILTIN_PALETTES: dict[str, dict[int, tuple]] = {
|
||||
"ImGui Dark": {}, # empty = use imgui dark defaults
|
||||
"NERV": {},
|
||||
}
|
||||
|
||||
_TOML_PALETTES: dict[str, ThemeFile] = {}
|
||||
_TOML_COLOUR_CACHE: dict[str, dict[int, tuple[float, float, float, float]]] = {}
|
||||
|
||||
def _hex(rgb: tuple[int, int, int]) -> tuple[float, float, float, float]:
|
||||
return (rgb[0] / 255.0, rgb[1] / 255.0, rgb[2] / 255.0, 1.0)
|
||||
|
||||
@@ -52,19 +43,26 @@ def _build_imgui_colour_dict(theme: ThemeFile) -> dict[int, tuple[float, float,
|
||||
out[enum_val] = _hex(rgb)
|
||||
return out
|
||||
|
||||
|
||||
def get_palette_names() -> list[str]:
|
||||
"""Returns a list of all available palettes, including hello_imgui built-ins
|
||||
and TOML-loaded themes."""
|
||||
names = list(_BUILTIN_PALETTES.keys())
|
||||
names.extend(sorted(_TOML_PALETTES.keys()))
|
||||
hi_themes = [name for name in dir(hello_imgui.ImGuiTheme_) if not name.startswith('_') and name != 'count']
|
||||
hi_themes = [n for n in hi_themes if not hasattr(int, n)]
|
||||
names.extend(sorted(hi_themes))
|
||||
return names
|
||||
def _build_semantic_colour_dict(theme: ThemeFile) -> dict[str, tuple[float, float, float, float]]:
|
||||
out: dict[str, tuple[float, float, float, float]] = {}
|
||||
palette_dict = theme.palette.to_dict()
|
||||
from imgui_bundle import imgui
|
||||
for col_name, rgb in palette_dict.items():
|
||||
if not hasattr(imgui.Col_, col_name):
|
||||
out[col_name] = _hex(rgb)
|
||||
return out
|
||||
|
||||
# ------------------------------------------------------------------ state
|
||||
|
||||
_BUILTIN_PALETTES: dict[str, dict[int, tuple]] = {
|
||||
"ImGui Dark": {},
|
||||
"NERV": {},
|
||||
}
|
||||
|
||||
_TOML_PALETTES: dict[str, ThemeFile] = {}
|
||||
_TOML_COLOUR_CACHE: dict[str, dict[int, tuple[float, float, float, float]]] = {}
|
||||
_TOML_SEMANTIC_CACHE: dict[str, dict[str, tuple[float, float, float, float]]] = {}
|
||||
|
||||
_current_palette: str = "10x Dark"
|
||||
_current_font_path: str = "fonts/Inter-Regular.ttf"
|
||||
_current_font_size: float = 16.0
|
||||
@@ -141,13 +139,50 @@ def set_child_transparency(val: float) -> None:
|
||||
_child_transparency = val
|
||||
apply(_current_palette)
|
||||
|
||||
def apply(palette_name: str) -> None:
|
||||
"""
|
||||
def get_color(name: str, alpha: float = 1.0) -> imgui.ImVec4:
|
||||
"""Return a tone-mapped semantic color from the current palette."""
|
||||
palette_name = _current_palette
|
||||
if palette_name in _TOML_SEMANTIC_CACHE:
|
||||
d = _TOML_SEMANTIC_CACHE[palette_name]
|
||||
if name in d:
|
||||
rgba = list(d[name])
|
||||
rgba[3] = alpha
|
||||
return imgui.ImVec4(*_tone_map(tuple(rgba), palette_name))
|
||||
|
||||
|
||||
Apply a named palette by setting all ImGui style colors and applying global professional styling.
|
||||
[C: tests/test_theme.py:test_theme_apply_sets_rounding_and_padding]
|
||||
"""
|
||||
# Hardcoded fallbacks if not in TOML (matches ThemePalette defaults)
|
||||
fallbacks = {
|
||||
"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),
|
||||
}
|
||||
if name in fallbacks:
|
||||
rgb = fallbacks[name]
|
||||
return imgui.ImVec4(*_tone_map((rgb[0]/255.0, rgb[1]/255.0, rgb[2]/255.0, alpha), palette_name))
|
||||
|
||||
return imgui.ImVec4(1, 1, 1, alpha)
|
||||
|
||||
def get_role_tint(role: str) -> imgui.ImVec4:
|
||||
"""Returns a subtle background tint color based on the message role."""
|
||||
mapping = {
|
||||
"User": "bubble_user",
|
||||
"AI": "bubble_ai",
|
||||
"Vendor API": "bubble_vendor",
|
||||
}
|
||||
return get_color(mapping.get(role, "bubble_system"), alpha=0.6)
|
||||
|
||||
def apply(palette_name: str) -> None:
|
||||
"""Apply a named palette by setting all ImGui style colors and professional styling."""
|
||||
global _current_palette
|
||||
_current_palette = palette_name
|
||||
if palette_name == 'NERV':
|
||||
@@ -175,13 +210,10 @@ def apply(palette_name: str) -> None:
|
||||
elif hasattr(hello_imgui.ImGuiTheme_, palette_name):
|
||||
theme_enum = getattr(hello_imgui.ImGuiTheme_, palette_name)
|
||||
hello_imgui.apply_theme(theme_enum)
|
||||
# hello_imgui doesn't expose the underlying dict easily to tone-map after-the-fact
|
||||
# without re-reading every enum. For now, BUILTIN and TOML themes get full TM.
|
||||
else:
|
||||
# Fallback
|
||||
imgui.style_colors_dark()
|
||||
|
||||
# 2. Apply our "Subtle Rounding" professional tweaks on top of ANY theme
|
||||
# 2. Professional tweaks
|
||||
style = imgui.get_style()
|
||||
style.window_rounding = 6.0
|
||||
style.child_rounding = 4.0
|
||||
@@ -194,44 +226,50 @@ def apply(palette_name: str) -> None:
|
||||
style.frame_border_size = 1.0
|
||||
style.popup_border_size = 1.0
|
||||
|
||||
# Apply transparency to WindowBg
|
||||
win_bg = style.color_(imgui.Col_.window_bg)
|
||||
win_bg.w = _transparency
|
||||
style.set_color_(imgui.Col_.window_bg, win_bg)
|
||||
|
||||
# Apply child/frame transparency
|
||||
for col_idx in [imgui.Col_.child_bg, imgui.Col_.frame_bg, imgui.Col_.popup_bg]:
|
||||
c = style.color_(col_idx)
|
||||
c.w = _child_transparency
|
||||
style.set_color_(col_idx, c)
|
||||
|
||||
# Spacing & Padding
|
||||
style.window_padding = imgui.ImVec2(8.0, 8.0)
|
||||
style.frame_padding = imgui.ImVec2(8.0, 4.0)
|
||||
style.item_spacing = imgui.ImVec2(8.0, 4.0)
|
||||
style.item_inner_spacing = imgui.ImVec2(4.0, 4.0)
|
||||
style.scrollbar_size = 14.0
|
||||
|
||||
# Rendering anti-aliasing (Shaders/Quality)
|
||||
style.anti_aliased_lines = True
|
||||
style.anti_aliased_fill = True
|
||||
style.anti_aliased_lines_use_tex = True
|
||||
|
||||
# 3. Sync syntax palette and clear markdown render cache
|
||||
apply_syntax_palette(get_syntax_palette_for_theme(palette_name))
|
||||
import src.markdown_helper
|
||||
src.markdown_helper.get_renderer().clear_cache()
|
||||
try:
|
||||
import src.markdown_helper
|
||||
src.markdown_helper.get_renderer().clear_cache()
|
||||
except (ImportError, AttributeError):
|
||||
pass
|
||||
|
||||
def set_scale(factor: float) -> None:
|
||||
"""Set the global font/UI scale factor."""
|
||||
global _current_scale
|
||||
_current_scale = factor
|
||||
style = imgui.get_style()
|
||||
style.font_scale_main = factor
|
||||
def apply_current() -> None:
|
||||
"""Apply the loaded palette and scale."""
|
||||
apply(_current_palette)
|
||||
set_scale(_current_scale)
|
||||
|
||||
def get_palette_names() -> list[str]:
|
||||
"""Returns a list of all available palettes."""
|
||||
names = list(_BUILTIN_PALETTES.keys())
|
||||
names.extend(sorted(_TOML_PALETTES.keys()))
|
||||
hi_themes = [name for name in dir(hello_imgui.ImGuiTheme_) if not name.startswith('_') and name != 'count']
|
||||
hi_themes = [n for n in hi_themes if not hasattr(int, n)]
|
||||
names.extend(sorted(hi_themes))
|
||||
return names
|
||||
|
||||
# ------------------------------------------------------------------ persistence
|
||||
|
||||
def save_to_config(config: dict) -> None:
|
||||
"""Persist theme settings into the config dict under [theme]."""
|
||||
import sys
|
||||
"""Persist theme settings into the config dict."""
|
||||
config.setdefault("theme", {})
|
||||
config["theme"]["palette"] = _current_palette
|
||||
config["theme"]["font_path"] = _current_font_path
|
||||
@@ -239,7 +277,6 @@ def save_to_config(config: dict) -> None:
|
||||
config["theme"]["scale"] = _current_scale
|
||||
config["theme"]["transparency"] = _transparency
|
||||
config["theme"]["child_transparency"] = _child_transparency
|
||||
# Tone mapping
|
||||
tm = {}
|
||||
for p in set(list(_brightness.keys()) + list(_contrast.keys()) + list(_gamma.keys())):
|
||||
tm[p] = {
|
||||
@@ -248,49 +285,37 @@ def save_to_config(config: dict) -> None:
|
||||
"gamma": _gamma.get(p, 1.0)
|
||||
}
|
||||
config["theme"]["tone_mapping"] = tm
|
||||
sys.stderr.write(f"[DEBUG theme_2] save_to_config: palette={_current_palette}\n")
|
||||
sys.stderr.flush()
|
||||
|
||||
def load_from_config(config: dict) -> None:
|
||||
"""Read [theme] from config. Font is handled separately at startup."""
|
||||
"""Read [theme] from config."""
|
||||
import sys
|
||||
global _current_font_path, _current_font_size, _current_scale, _current_palette, _transparency, _child_transparency, _brightness, _contrast, _gamma
|
||||
t = config.get("theme", {})
|
||||
_current_palette = t.get("palette", "10x Dark")
|
||||
if _current_palette in ("", "DPG Default"):
|
||||
_current_palette = "10x Dark"
|
||||
|
||||
_current_font_path = t.get("font_path", "fonts/Inter-Regular.ttf")
|
||||
_current_font_size = float(t.get("font_size", 16.0))
|
||||
_current_scale = float(t.get("scale", 1.0))
|
||||
_transparency = float(t.get("transparency", 1.0))
|
||||
_child_transparency = float(t.get("child_transparency", 1.0))
|
||||
# Tone mapping
|
||||
tm = t.get("tone_mapping", {})
|
||||
_brightness = {p: float(v.get("brightness", 1.0)) for p, v in tm.items()}
|
||||
_contrast = {p: float(v.get("contrast", 1.0)) for p, v in tm.items()}
|
||||
_gamma = {p: float(v.get("gamma", 1.0)) for p, v in tm.items()}
|
||||
sys.stderr.write(f"[DEBUG theme_2] load_from_config: palette={_current_palette}\n")
|
||||
sys.stderr.flush()
|
||||
|
||||
def apply_current() -> None:
|
||||
"""Apply the loaded palette and scale. Call after imgui context exists."""
|
||||
apply(_current_palette)
|
||||
set_scale(_current_scale)
|
||||
|
||||
# ------------------------------------------------------------------ external themes
|
||||
|
||||
def load_themes_from_disk() -> None:
|
||||
"""Load all themes from the global themes directory. Each *.toml file
|
||||
in the directory is one theme. Idempotent - safe to call repeatedly.
|
||||
Broken entries are logged and skipped."""
|
||||
global _TOML_PALETTES, _TOML_COLOUR_CACHE
|
||||
"""Load all themes from the global themes directory."""
|
||||
global _TOML_PALETTES, _TOML_COLOUR_CACHE, _TOML_SEMANTIC_CACHE
|
||||
themes_dir = get_global_themes_path()
|
||||
loaded: dict[str, ThemeFile] = {}
|
||||
if themes_dir.exists() and themes_dir.is_dir():
|
||||
loaded.update(load_themes_from_dir(themes_dir, scope="global"))
|
||||
_TOML_PALETTES = loaded
|
||||
_TOML_COLOUR_CACHE = {name: _build_imgui_colour_dict(t) for name, t in loaded.items()}
|
||||
|
||||
_TOML_SEMANTIC_CACHE = {name: _build_semantic_colour_dict(t) for name, t in loaded.items()}
|
||||
|
||||
def get_syntax_palette_for_theme(theme_name: str) -> str:
|
||||
"""Return the syntax palette name (one of dark/light/mariana/retro_blue)
|
||||
@@ -300,7 +325,6 @@ def get_syntax_palette_for_theme(theme_name: str) -> str:
|
||||
return _TOML_PALETTES[theme_name].syntax_palette
|
||||
return "dark"
|
||||
|
||||
|
||||
def apply_syntax_palette(palette_name: str) -> None:
|
||||
"""Set the default imgui_color_text_edit palette. palette_name must
|
||||
be one of: dark, light, mariana, retro_blue. No-op for unknown names."""
|
||||
@@ -312,46 +336,42 @@ def apply_syntax_palette(palette_name: str) -> None:
|
||||
return
|
||||
ed.TextEditor.set_default_palette(palette_id)
|
||||
|
||||
# ------------------------------------------------------------------ font & scaling
|
||||
|
||||
load_themes_from_disk()
|
||||
def set_scale(factor: float) -> None:
|
||||
global _current_scale
|
||||
_current_scale = factor
|
||||
imgui.get_style().font_scale_main = factor
|
||||
|
||||
def get_font_loading_params() -> tuple[str, float]:
|
||||
"""Return (font_path, font_size) for use during hello_imgui font loading callback."""
|
||||
return _current_font_path, _current_font_size
|
||||
|
||||
def get_tweaked_theme() -> hello_imgui.ImGuiTweakedTheme:
|
||||
"""Returns an ImGuiTweakedTheme object reflecting the current state."""
|
||||
tt = hello_imgui.ImGuiTweakedTheme()
|
||||
if hasattr(hello_imgui.ImGuiTheme_, _current_palette):
|
||||
tt.theme = getattr(hello_imgui.ImGuiTheme_, _current_palette)
|
||||
else:
|
||||
tt.theme = hello_imgui.ImGuiTheme_.imgui_colors_dark
|
||||
|
||||
# Sync tweaks
|
||||
tt.tweaks.rounding = 6.0
|
||||
return tt
|
||||
|
||||
# ------------------------------------------------------------------ specialized colors
|
||||
|
||||
def ai_text_color() -> imgui.ImVec4:
|
||||
"""Returns DATA_GREEN if NERV is active, otherwise standard text color."""
|
||||
if is_nerv_active():
|
||||
return imgui.ImVec4(*DATA_GREEN)
|
||||
return imgui.get_style().color_(imgui.Col_.text)
|
||||
|
||||
def ai_text_style():
|
||||
"""Context manager for AI response text styling."""
|
||||
return imscope.style_color(imgui.Col_.text, ai_text_color())
|
||||
|
||||
def get_role_tint(role: str) -> imgui.ImVec4:
|
||||
"""Returns a subtle background tint color based on the message role."""
|
||||
# Deep, low-saturation tints for distinct role hierarchy
|
||||
if role == "User": return imgui.ImVec4(0.12, 0.18, 0.30, 0.6) # Midnight Blue
|
||||
elif role == "AI": return imgui.ImVec4(0.14, 0.25, 0.18, 0.6) # Forest Green
|
||||
elif role == "Vendor API": return imgui.ImVec4(0.25, 0.22, 0.12, 0.5) # Bronze
|
||||
return imgui.ImVec4(0.1, 0.1, 0.1, 0.4) # Neutral System
|
||||
|
||||
def render_post_fx(width: float, height: float, ai_status: str, crt_enabled: bool) -> None:
|
||||
"""Updates and renders the alert and CRT filters."""
|
||||
_alert_pulsing.update(ai_status)
|
||||
_alert_pulsing.render(width, height)
|
||||
_crt_filter.enabled = crt_enabled
|
||||
_crt_filter.render(width, height)
|
||||
_crt_filter.render(width, height)
|
||||
|
||||
# ------------------------------------------------------------------ init
|
||||
load_themes_from_disk()
|
||||
|
||||
+18
-1
@@ -9,7 +9,6 @@ from typing import Any
|
||||
VALID_SYNTAX_PALETTES: tuple[str, ...] = ("dark", "light", "mariana", "retro_blue")
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass
|
||||
class ThemePalette:
|
||||
window_bg: tuple[int, int, int] = (0, 0, 0)
|
||||
@@ -75,6 +74,24 @@ class ThemePalette:
|
||||
tree_lines: tuple[int, int, int] = (60, 60, 60)
|
||||
unsaved_marker: tuple[int, int, int] = (200, 200, 200)
|
||||
|
||||
# Semantic colors
|
||||
status_success: tuple[int, int, int] = (80, 255, 80)
|
||||
status_warning: tuple[int, int, int] = (255, 152, 48)
|
||||
status_error: tuple[int, int, int] = (255, 72, 64)
|
||||
status_info: tuple[int, int, int] = (0, 255, 255)
|
||||
bubble_user: tuple[int, int, int] = (30, 45, 75)
|
||||
bubble_ai: tuple[int, int, int] = (35, 65, 45)
|
||||
bubble_vendor: tuple[int, int, int] = (65, 55, 30)
|
||||
bubble_system: tuple[int, int, int] = (25, 25, 25)
|
||||
slice_manual: tuple[int, int, int] = (255, 165, 0)
|
||||
slice_auto: tuple[int, int, int] = (0, 255, 0)
|
||||
slice_selection: tuple[int, int, int] = (100, 100, 255)
|
||||
|
||||
# Diff colors
|
||||
diff_added: tuple[int, int, int] = (51, 230, 51)
|
||||
diff_removed: tuple[int, int, int] = (230, 51, 51)
|
||||
diff_header: tuple[int, int, int] = (77, 178, 255)
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict[str, Any]) -> ThemePalette:
|
||||
kwargs: dict[str, Any] = {}
|
||||
|
||||
+48
-34
@@ -3,53 +3,67 @@ syntax_palette = "dark"
|
||||
description = "10x Dark Theme"
|
||||
|
||||
[colors]
|
||||
window_bg = [ 34, 32, 28]
|
||||
child_bg = [ 30, 28, 24]
|
||||
popup_bg = [ 35, 30, 20]
|
||||
border = [ 60, 55, 50]
|
||||
border_shadow = [ 0, 0, 0]
|
||||
bubble_ai = [ 35, 65, 45]
|
||||
bubble_system = [ 25, 25, 25]
|
||||
bubble_user = [ 30, 45, 75]
|
||||
bubble_vendor = [ 65, 55, 30]
|
||||
button = [ 83, 76, 60]
|
||||
button_active = [115, 90, 70]
|
||||
button_hovered = [126, 78, 14]
|
||||
check_mark = [194, 164, 74]
|
||||
child_bg = [ 30, 28, 24]
|
||||
diff_added = [ 51, 230, 51]
|
||||
diff_header = [ 77, 178, 255]
|
||||
diff_removed = [230, 51, 51]
|
||||
docking_empty_bg = [ 20, 20, 20]
|
||||
docking_preview = [126, 78, 14]
|
||||
frame_bg = [ 45, 42, 38]
|
||||
frame_bg_hovered = [ 60, 56, 50]
|
||||
frame_bg_active = [ 75, 70, 62]
|
||||
title_bg = [ 40, 35, 25]
|
||||
title_bg_active = [ 60, 45, 15]
|
||||
title_bg_collapsed = [ 30, 27, 20]
|
||||
frame_bg_hovered = [ 60, 56, 50]
|
||||
header = [ 83, 76, 60]
|
||||
header_active = [115, 90, 70]
|
||||
header_hovered = [126, 78, 14]
|
||||
menu_bar_bg = [ 35, 30, 20]
|
||||
modal_window_dim_bg = [ 10, 10, 10]
|
||||
nav_cursor = [126, 78, 14]
|
||||
nav_windowing_dim_bg = [ 20, 20, 20]
|
||||
nav_windowing_highlight = [194, 164, 74]
|
||||
popup_bg = [ 35, 30, 20]
|
||||
resize_grip = [ 60, 55, 44]
|
||||
resize_grip_active = [194, 164, 74]
|
||||
resize_grip_hovered = [126, 78, 14]
|
||||
scrollbar_bg = [ 30, 28, 24]
|
||||
scrollbar_grab = [ 80, 78, 72]
|
||||
scrollbar_grab_hovered = [100, 100, 92]
|
||||
scrollbar_grab_active = [120, 118, 110]
|
||||
check_mark = [194, 164, 74]
|
||||
scrollbar_grab_hovered = [100, 100, 92]
|
||||
separator = [ 70, 65, 55]
|
||||
separator_active = [194, 164, 74]
|
||||
separator_hovered = [126, 78, 14]
|
||||
slice_auto = [ 0, 255, 0]
|
||||
slice_manual = [255, 165, 0]
|
||||
slice_selection = [100, 100, 255]
|
||||
slider_grab = [126, 78, 14]
|
||||
slider_grab_active = [194, 140, 30]
|
||||
button = [ 83, 76, 60]
|
||||
button_hovered = [126, 78, 14]
|
||||
button_active = [115, 90, 70]
|
||||
header = [ 83, 76, 60]
|
||||
header_hovered = [126, 78, 14]
|
||||
header_active = [115, 90, 70]
|
||||
separator = [ 70, 65, 55]
|
||||
separator_hovered = [126, 78, 14]
|
||||
separator_active = [194, 164, 74]
|
||||
resize_grip = [ 60, 55, 44]
|
||||
resize_grip_hovered = [126, 78, 14]
|
||||
resize_grip_active = [194, 164, 74]
|
||||
status_error = [255, 72, 64]
|
||||
status_info = [ 0, 255, 255]
|
||||
status_success = [ 80, 255, 80]
|
||||
status_warning = [255, 152, 48]
|
||||
tab = [ 83, 83, 70]
|
||||
tab_hovered = [126, 77, 25]
|
||||
tab_selected = [126, 77, 25]
|
||||
tab_dimmed = [ 60, 58, 50]
|
||||
tab_dimmed_selected = [ 90, 80, 55]
|
||||
docking_preview = [126, 78, 14]
|
||||
docking_empty_bg = [ 20, 20, 20]
|
||||
tab_hovered = [126, 77, 25]
|
||||
tab_selected = [126, 77, 25]
|
||||
table_border_light = [ 50, 47, 42]
|
||||
table_border_strong = [ 70, 65, 55]
|
||||
table_header_bg = [ 55, 50, 38]
|
||||
table_row_bg = [ 0, 0, 0]
|
||||
table_row_bg_alt = [ 40, 38, 34]
|
||||
text = [200, 200, 200]
|
||||
text_disabled = [130, 130, 120]
|
||||
text_selected_bg = [ 59, 86, 142]
|
||||
table_header_bg = [ 55, 50, 38]
|
||||
table_border_strong = [ 70, 65, 55]
|
||||
table_border_light = [ 50, 47, 42]
|
||||
table_row_bg = [ 0, 0, 0]
|
||||
table_row_bg_alt = [ 40, 38, 34]
|
||||
nav_cursor = [126, 78, 14]
|
||||
nav_windowing_highlight = [194, 164, 74]
|
||||
nav_windowing_dim_bg = [ 20, 20, 20]
|
||||
modal_window_dim_bg = [ 10, 10, 10]
|
||||
title_bg = [ 40, 35, 25]
|
||||
title_bg_active = [ 60, 45, 15]
|
||||
title_bg_collapsed = [ 30, 27, 20]
|
||||
window_bg = [ 34, 32, 28]
|
||||
|
||||
+51
-37
@@ -3,40 +3,54 @@ syntax_palette = "light"
|
||||
description = "Binks Theme"
|
||||
|
||||
[colors]
|
||||
text = [ 0, 0, 0]
|
||||
text_disabled = [153, 153, 153]
|
||||
window_bg = [240, 240, 240]
|
||||
child_bg = [ 0, 0, 0]
|
||||
popup_bg = [255, 255, 255]
|
||||
border = [ 0, 0, 0]
|
||||
border_shadow = [255, 255, 255]
|
||||
frame_bg = [255, 255, 255]
|
||||
frame_bg_hovered = [ 66, 150, 250]
|
||||
frame_bg_active = [ 66, 150, 250]
|
||||
title_bg = [245, 245, 245]
|
||||
title_bg_collapsed = [255, 255, 255]
|
||||
title_bg_active = [209, 209, 209]
|
||||
menu_bar_bg = [219, 219, 219]
|
||||
scrollbar_bg = [250, 250, 250]
|
||||
scrollbar_grab = [176, 176, 176]
|
||||
scrollbar_grab_hovered = [150, 150, 150]
|
||||
scrollbar_grab_active = [125, 125, 125]
|
||||
check_mark = [ 66, 150, 250]
|
||||
slider_grab = [ 61, 133, 224]
|
||||
slider_grab_active = [ 66, 150, 250]
|
||||
button = [ 66, 150, 250]
|
||||
button_hovered = [ 66, 150, 250]
|
||||
button_active = [ 15, 135, 250]
|
||||
header = [ 66, 150, 250]
|
||||
header_hovered = [ 66, 150, 250]
|
||||
header_active = [ 66, 150, 250]
|
||||
separator = [100, 100, 100]
|
||||
resize_grip = [255, 255, 255]
|
||||
resize_grip_hovered = [ 66, 150, 250]
|
||||
resize_grip_active = [ 66, 150, 250]
|
||||
plot_lines = [ 99, 99, 99]
|
||||
plot_lines_hovered = [255, 110, 89]
|
||||
plot_histogram = [230, 178, 0]
|
||||
plot_histogram_hovered = [255, 153, 0]
|
||||
text_selected_bg = [ 66, 150, 250]
|
||||
modal_window_dim_bg = [ 51, 51, 51]
|
||||
border = [ 0, 0, 0]
|
||||
border_shadow = [255, 255, 255]
|
||||
bubble_ai = [220, 255, 220]
|
||||
bubble_system = [240, 240, 240]
|
||||
bubble_user = [220, 230, 255]
|
||||
bubble_vendor = [255, 240, 200]
|
||||
button = [ 66, 150, 250]
|
||||
button_active = [ 15, 135, 250]
|
||||
button_hovered = [ 66, 150, 250]
|
||||
check_mark = [ 66, 150, 250]
|
||||
child_bg = [ 0, 0, 0]
|
||||
diff_added = [ 40, 180, 40]
|
||||
diff_header = [ 40, 100, 200]
|
||||
diff_removed = [200, 40, 40]
|
||||
frame_bg = [255, 255, 255]
|
||||
frame_bg_active = [ 66, 150, 250]
|
||||
frame_bg_hovered = [ 66, 150, 250]
|
||||
header = [ 66, 150, 250]
|
||||
header_active = [ 66, 150, 250]
|
||||
header_hovered = [ 66, 150, 250]
|
||||
menu_bar_bg = [219, 219, 219]
|
||||
modal_window_dim_bg = [ 51, 51, 51]
|
||||
plot_histogram = [230, 178, 0]
|
||||
plot_histogram_hovered = [255, 153, 0]
|
||||
plot_lines = [ 99, 99, 99]
|
||||
plot_lines_hovered = [255, 110, 89]
|
||||
popup_bg = [255, 255, 255]
|
||||
resize_grip = [255, 255, 255]
|
||||
resize_grip_active = [ 66, 150, 250]
|
||||
resize_grip_hovered = [ 66, 150, 250]
|
||||
scrollbar_bg = [250, 250, 250]
|
||||
scrollbar_grab = [176, 176, 176]
|
||||
scrollbar_grab_active = [125, 125, 125]
|
||||
scrollbar_grab_hovered = [150, 150, 150]
|
||||
separator = [100, 100, 100]
|
||||
slice_auto = [ 80, 255, 80]
|
||||
slice_manual = [255, 200, 0]
|
||||
slice_selection = [180, 180, 255]
|
||||
slider_grab = [ 61, 133, 224]
|
||||
slider_grab_active = [ 66, 150, 250]
|
||||
status_error = [200, 40, 40]
|
||||
status_info = [ 40, 100, 200]
|
||||
status_success = [ 40, 180, 40]
|
||||
status_warning = [200, 140, 0]
|
||||
text = [ 0, 0, 0]
|
||||
text_disabled = [153, 153, 153]
|
||||
text_selected_bg = [ 66, 150, 250]
|
||||
title_bg = [245, 245, 245]
|
||||
title_bg_active = [209, 209, 209]
|
||||
title_bg_collapsed = [255, 255, 255]
|
||||
window_bg = [240, 240, 240]
|
||||
|
||||
+47
-33
@@ -1,38 +1,52 @@
|
||||
# Gruvbox Dark — Pavel Pertsev's warm retro palette
|
||||
name = "gruvbox_dark"
|
||||
syntax_palette = "retro_blue"
|
||||
description = "Gruvbox Dark by Pavel Pertsev (github.com/morhetz/gruvbox)"
|
||||
|
||||
[colors]
|
||||
window_bg = [ 40, 40, 40] # bg
|
||||
child_bg = [ 50, 48, 47] # bg1
|
||||
popup_bg = [ 50, 48, 47]
|
||||
border = [ 60, 56, 54]
|
||||
frame_bg = [ 50, 48, 47]
|
||||
frame_bg_hovered = [ 80, 80, 80]
|
||||
frame_bg_active = [ 90, 90, 90]
|
||||
title_bg = [ 40, 40, 40]
|
||||
title_bg_active = [ 80, 80, 80]
|
||||
menu_bar_bg = [ 40, 40, 40]
|
||||
scrollbar_bg = [ 40, 40, 40]
|
||||
scrollbar_grab = [ 80, 80, 80]
|
||||
scrollbar_grab_hovered = [251, 241, 199]
|
||||
border = [ 60, 56, 54]
|
||||
bubble_ai = [ 35, 65, 45]
|
||||
bubble_system = [ 25, 25, 25]
|
||||
bubble_user = [ 30, 45, 75]
|
||||
bubble_vendor = [ 65, 55, 30]
|
||||
button = [ 60, 56, 54]
|
||||
button_active = [200, 140, 0]
|
||||
button_hovered = [180, 120, 40]
|
||||
check_mark = [184, 187, 38]
|
||||
child_bg = [ 50, 48, 47]
|
||||
diff_added = [ 51, 230, 51]
|
||||
diff_header = [ 77, 178, 255]
|
||||
diff_removed = [230, 51, 51]
|
||||
frame_bg = [ 50, 48, 47]
|
||||
frame_bg_active = [ 90, 90, 90]
|
||||
frame_bg_hovered = [ 80, 80, 80]
|
||||
header = [ 60, 56, 54]
|
||||
header_active = [251, 73, 52]
|
||||
header_hovered = [180, 120, 40]
|
||||
menu_bar_bg = [ 40, 40, 40]
|
||||
popup_bg = [ 50, 48, 47]
|
||||
scrollbar_bg = [ 40, 40, 40]
|
||||
scrollbar_grab = [ 80, 80, 80]
|
||||
scrollbar_grab_active = [251, 241, 199]
|
||||
button = [ 60, 56, 54]
|
||||
button_hovered = [180, 120, 40] # orange
|
||||
button_active = [200, 140, 0] # bright orange
|
||||
header = [ 60, 56, 54]
|
||||
header_hovered = [180, 120, 40]
|
||||
header_active = [251, 73, 52] # red
|
||||
separator = [ 80, 80, 80]
|
||||
separator_hovered = [180, 120, 40]
|
||||
separator_active = [251, 241, 199]
|
||||
tab = [ 60, 56, 54]
|
||||
tab_hovered = [180, 120, 40]
|
||||
tab_selected = [ 80, 80, 80]
|
||||
text = [251, 241, 199] # fg
|
||||
text_disabled = [146, 131, 116] # comment
|
||||
text_selected_bg = [180, 120, 40]
|
||||
check_mark = [184, 187, 38] # green
|
||||
slider_grab = [184, 187, 38]
|
||||
slider_grab_active = [184, 187, 38]
|
||||
table_header_bg = [ 60, 56, 54]
|
||||
scrollbar_grab_hovered = [251, 241, 199]
|
||||
separator = [ 80, 80, 80]
|
||||
separator_active = [251, 241, 199]
|
||||
separator_hovered = [180, 120, 40]
|
||||
slice_auto = [ 0, 255, 0]
|
||||
slice_manual = [255, 165, 0]
|
||||
slice_selection = [100, 100, 255]
|
||||
slider_grab = [184, 187, 38]
|
||||
slider_grab_active = [184, 187, 38]
|
||||
status_error = [255, 72, 64]
|
||||
status_info = [ 0, 255, 255]
|
||||
status_success = [ 80, 255, 80]
|
||||
status_warning = [255, 152, 48]
|
||||
tab = [ 60, 56, 54]
|
||||
tab_hovered = [180, 120, 40]
|
||||
tab_selected = [ 80, 80, 80]
|
||||
table_header_bg = [ 60, 56, 54]
|
||||
text = [251, 241, 199]
|
||||
text_disabled = [146, 131, 116]
|
||||
text_selected_bg = [180, 120, 40]
|
||||
title_bg = [ 40, 40, 40]
|
||||
title_bg_active = [ 80, 80, 80]
|
||||
window_bg = [ 40, 40, 40]
|
||||
|
||||
+62
-48
@@ -3,51 +3,65 @@ syntax_palette = "dark"
|
||||
description = "Monokai Theme"
|
||||
|
||||
[colors]
|
||||
window_bg = [ 39, 40, 34]
|
||||
child_bg = [ 34, 35, 29]
|
||||
popup_bg = [ 39, 40, 34]
|
||||
border = [ 60, 61, 52]
|
||||
border_shadow = [ 0, 0, 0]
|
||||
frame_bg = [ 50, 51, 44]
|
||||
frame_bg_hovered = [ 65, 67, 56]
|
||||
frame_bg_active = [ 80, 82, 68]
|
||||
title_bg = [ 39, 40, 34]
|
||||
title_bg_active = [ 73, 72, 62]
|
||||
title_bg_collapsed = [ 30, 31, 26]
|
||||
menu_bar_bg = [ 50, 51, 44]
|
||||
scrollbar_bg = [ 34, 35, 29]
|
||||
scrollbar_grab = [ 80, 80, 72]
|
||||
scrollbar_grab_hovered = [102, 217, 39]
|
||||
scrollbar_grab_active = [166, 226, 46]
|
||||
check_mark = [166, 226, 46]
|
||||
slider_grab = [102, 217, 39]
|
||||
slider_grab_active = [166, 226, 46]
|
||||
button = [ 73, 72, 62]
|
||||
button_hovered = [249, 38, 114]
|
||||
button_active = [198, 30, 92]
|
||||
header = [ 73, 72, 62]
|
||||
header_hovered = [249, 38, 114]
|
||||
header_active = [198, 30, 92]
|
||||
separator = [ 60, 61, 52]
|
||||
separator_hovered = [249, 38, 114]
|
||||
separator_active = [166, 226, 46]
|
||||
resize_grip = [ 73, 72, 62]
|
||||
resize_grip_hovered = [249, 38, 114]
|
||||
resize_grip_active = [166, 226, 46]
|
||||
tab = [ 73, 72, 62]
|
||||
tab_hovered = [249, 38, 114]
|
||||
tab_selected = [249, 38, 114]
|
||||
tab_dimmed = [ 50, 51, 44]
|
||||
tab_dimmed_selected = [ 90, 88, 76]
|
||||
docking_preview = [249, 38, 114]
|
||||
docking_empty_bg = [ 20, 20, 18]
|
||||
text = [248, 248, 242]
|
||||
text_disabled = [117, 113, 94]
|
||||
text_selected_bg = [249, 38, 114]
|
||||
table_header_bg = [ 60, 61, 52]
|
||||
table_border_strong = [ 73, 72, 62]
|
||||
table_border_light = [ 55, 56, 48]
|
||||
table_row_bg = [ 0, 0, 0]
|
||||
table_row_bg_alt = [ 50, 51, 44]
|
||||
nav_cursor = [166, 226, 46]
|
||||
modal_window_dim_bg = [ 10, 10, 8]
|
||||
border = [ 60, 61, 52]
|
||||
border_shadow = [ 0, 0, 0]
|
||||
bubble_ai = [ 35, 65, 45]
|
||||
bubble_system = [ 25, 25, 25]
|
||||
bubble_user = [ 30, 45, 75]
|
||||
bubble_vendor = [ 65, 55, 30]
|
||||
button = [ 73, 72, 62]
|
||||
button_active = [198, 30, 92]
|
||||
button_hovered = [249, 38, 114]
|
||||
check_mark = [166, 226, 46]
|
||||
child_bg = [ 34, 35, 29]
|
||||
diff_added = [ 51, 230, 51]
|
||||
diff_header = [ 77, 178, 255]
|
||||
diff_removed = [230, 51, 51]
|
||||
docking_empty_bg = [ 20, 20, 18]
|
||||
docking_preview = [249, 38, 114]
|
||||
frame_bg = [ 50, 51, 44]
|
||||
frame_bg_active = [ 80, 82, 68]
|
||||
frame_bg_hovered = [ 65, 67, 56]
|
||||
header = [ 73, 72, 62]
|
||||
header_active = [198, 30, 92]
|
||||
header_hovered = [249, 38, 114]
|
||||
menu_bar_bg = [ 50, 51, 44]
|
||||
modal_window_dim_bg = [ 10, 10, 8]
|
||||
nav_cursor = [166, 226, 46]
|
||||
popup_bg = [ 39, 40, 34]
|
||||
resize_grip = [ 73, 72, 62]
|
||||
resize_grip_active = [166, 226, 46]
|
||||
resize_grip_hovered = [249, 38, 114]
|
||||
scrollbar_bg = [ 34, 35, 29]
|
||||
scrollbar_grab = [ 80, 80, 72]
|
||||
scrollbar_grab_active = [166, 226, 46]
|
||||
scrollbar_grab_hovered = [102, 217, 39]
|
||||
separator = [ 60, 61, 52]
|
||||
separator_active = [166, 226, 46]
|
||||
separator_hovered = [249, 38, 114]
|
||||
slice_auto = [ 0, 255, 0]
|
||||
slice_manual = [255, 165, 0]
|
||||
slice_selection = [100, 100, 255]
|
||||
slider_grab = [102, 217, 39]
|
||||
slider_grab_active = [166, 226, 46]
|
||||
status_error = [255, 72, 64]
|
||||
status_info = [ 0, 255, 255]
|
||||
status_success = [ 80, 255, 80]
|
||||
status_warning = [255, 152, 48]
|
||||
tab = [ 73, 72, 62]
|
||||
tab_dimmed = [ 50, 51, 44]
|
||||
tab_dimmed_selected = [ 90, 88, 76]
|
||||
tab_hovered = [249, 38, 114]
|
||||
tab_selected = [249, 38, 114]
|
||||
table_border_light = [ 55, 56, 48]
|
||||
table_border_strong = [ 73, 72, 62]
|
||||
table_header_bg = [ 60, 61, 52]
|
||||
table_row_bg = [ 0, 0, 0]
|
||||
table_row_bg_alt = [ 50, 51, 44]
|
||||
text = [248, 248, 242]
|
||||
text_disabled = [117, 113, 94]
|
||||
text_selected_bg = [249, 38, 114]
|
||||
title_bg = [ 39, 40, 34]
|
||||
title_bg_active = [ 73, 72, 62]
|
||||
title_bg_collapsed = [ 30, 31, 26]
|
||||
window_bg = [ 39, 40, 34]
|
||||
|
||||
+47
-33
@@ -1,38 +1,52 @@
|
||||
# Moss — green-tinted dark theme
|
||||
name = "moss"
|
||||
syntax_palette = "mariana"
|
||||
description = "Moss — green-tinted dark theme"
|
||||
|
||||
[colors]
|
||||
window_bg = [ 40, 47, 49] # green-gray
|
||||
child_bg = [ 24, 32, 30]
|
||||
popup_bg = [ 20, 35, 35]
|
||||
border = [ 60, 80, 90]
|
||||
frame_bg = [ 50, 70, 80]
|
||||
frame_bg_hovered = [ 60, 90, 100]
|
||||
frame_bg_active = [ 70, 100, 110]
|
||||
title_bg = [ 40, 47, 49]
|
||||
title_bg_active = [ 42, 77, 50] # mossy green
|
||||
menu_bar_bg = [ 40, 47, 49]
|
||||
scrollbar_bg = [ 40, 47, 49]
|
||||
scrollbar_grab = [ 80, 80, 80]
|
||||
scrollbar_grab_hovered = [100, 100, 100]
|
||||
border = [ 60, 80, 90]
|
||||
bubble_ai = [ 35, 65, 45]
|
||||
bubble_system = [ 25, 25, 25]
|
||||
bubble_user = [ 30, 45, 75]
|
||||
bubble_vendor = [ 65, 55, 30]
|
||||
button = [ 60, 80, 90]
|
||||
button_active = [120, 80, 200]
|
||||
button_hovered = [105, 101, 255]
|
||||
check_mark = [120, 160, 130]
|
||||
child_bg = [ 24, 32, 30]
|
||||
diff_added = [ 51, 230, 51]
|
||||
diff_header = [ 77, 178, 255]
|
||||
diff_removed = [230, 51, 51]
|
||||
frame_bg = [ 50, 70, 80]
|
||||
frame_bg_active = [ 70, 100, 110]
|
||||
frame_bg_hovered = [ 60, 90, 100]
|
||||
header = [ 60, 80, 90]
|
||||
header_active = [ 42, 77, 50]
|
||||
header_hovered = [120, 160, 130]
|
||||
menu_bar_bg = [ 40, 47, 49]
|
||||
popup_bg = [ 20, 35, 35]
|
||||
scrollbar_bg = [ 40, 47, 49]
|
||||
scrollbar_grab = [ 80, 80, 80]
|
||||
scrollbar_grab_active = [120, 120, 120]
|
||||
button = [ 60, 80, 90]
|
||||
button_hovered = [105, 101, 255] # blue accent
|
||||
button_active = [120, 80, 200]
|
||||
header = [ 60, 80, 90]
|
||||
header_hovered = [120, 160, 130] # green
|
||||
header_active = [ 42, 77, 50] # mossy green
|
||||
separator = [ 60, 80, 90]
|
||||
separator_hovered = [120, 160, 130]
|
||||
separator_active = [105, 101, 255]
|
||||
tab = [ 60, 80, 90]
|
||||
tab_hovered = [ 80, 100, 110]
|
||||
tab_selected = [ 42, 77, 50] # mossy green
|
||||
text = [255, 255, 255]
|
||||
text_disabled = [208, 208, 208]
|
||||
text_selected_bg = [105, 101, 255]
|
||||
check_mark = [120, 160, 130] # green
|
||||
slider_grab = [120, 160, 130]
|
||||
slider_grab_active = [120, 160, 130]
|
||||
table_header_bg = [ 50, 70, 80]
|
||||
scrollbar_grab_hovered = [100, 100, 100]
|
||||
separator = [ 60, 80, 90]
|
||||
separator_active = [105, 101, 255]
|
||||
separator_hovered = [120, 160, 130]
|
||||
slice_auto = [ 0, 255, 0]
|
||||
slice_manual = [255, 165, 0]
|
||||
slice_selection = [100, 100, 255]
|
||||
slider_grab = [120, 160, 130]
|
||||
slider_grab_active = [120, 160, 130]
|
||||
status_error = [255, 72, 64]
|
||||
status_info = [ 0, 255, 255]
|
||||
status_success = [ 80, 255, 80]
|
||||
status_warning = [255, 152, 48]
|
||||
tab = [ 60, 80, 90]
|
||||
tab_hovered = [ 80, 100, 110]
|
||||
tab_selected = [ 42, 77, 50]
|
||||
table_header_bg = [ 50, 70, 80]
|
||||
text = [255, 255, 255]
|
||||
text_disabled = [208, 208, 208]
|
||||
text_selected_bg = [105, 101, 255]
|
||||
title_bg = [ 40, 47, 49]
|
||||
title_bg_active = [ 42, 77, 50]
|
||||
window_bg = [ 40, 47, 49]
|
||||
|
||||
+62
-48
@@ -3,51 +3,65 @@ syntax_palette = "dark"
|
||||
description = "Nord Dark Theme"
|
||||
|
||||
[colors]
|
||||
window_bg = [ 36, 41, 49]
|
||||
child_bg = [ 30, 34, 42]
|
||||
popup_bg = [ 36, 41, 49]
|
||||
border = [ 59, 66, 82]
|
||||
border_shadow = [ 0, 0, 0]
|
||||
frame_bg = [ 46, 52, 64]
|
||||
frame_bg_hovered = [ 59, 66, 82]
|
||||
frame_bg_active = [ 67, 76, 94]
|
||||
title_bg = [ 36, 41, 49]
|
||||
title_bg_active = [ 59, 66, 82]
|
||||
title_bg_collapsed = [ 30, 34, 42]
|
||||
menu_bar_bg = [ 46, 52, 64]
|
||||
scrollbar_bg = [ 30, 34, 42]
|
||||
scrollbar_grab = [ 76, 86, 106]
|
||||
scrollbar_grab_hovered = [ 94, 129, 172]
|
||||
scrollbar_grab_active = [129, 161, 193]
|
||||
check_mark = [136, 192, 208]
|
||||
slider_grab = [ 94, 129, 172]
|
||||
slider_grab_active = [129, 161, 193]
|
||||
button = [ 59, 66, 82]
|
||||
button_hovered = [ 94, 129, 172]
|
||||
button_active = [129, 161, 193]
|
||||
header = [ 59, 66, 82]
|
||||
header_hovered = [ 94, 129, 172]
|
||||
header_active = [129, 161, 193]
|
||||
separator = [ 59, 66, 82]
|
||||
separator_hovered = [ 94, 129, 172]
|
||||
separator_active = [136, 192, 208]
|
||||
resize_grip = [ 59, 66, 82]
|
||||
resize_grip_hovered = [ 94, 129, 172]
|
||||
resize_grip_active = [136, 192, 208]
|
||||
tab = [ 46, 52, 64]
|
||||
tab_hovered = [ 94, 129, 172]
|
||||
tab_selected = [ 76, 86, 106]
|
||||
tab_dimmed = [ 36, 41, 49]
|
||||
tab_dimmed_selected = [ 59, 66, 82]
|
||||
docking_preview = [ 94, 129, 172]
|
||||
docking_empty_bg = [ 20, 22, 28]
|
||||
text = [216, 222, 233]
|
||||
text_disabled = [116, 128, 150]
|
||||
text_selected_bg = [ 94, 129, 172]
|
||||
table_header_bg = [ 59, 66, 82]
|
||||
table_border_strong = [ 76, 86, 106]
|
||||
table_border_light = [ 59, 66, 82]
|
||||
table_row_bg = [ 0, 0, 0]
|
||||
table_row_bg_alt = [ 46, 52, 64]
|
||||
nav_cursor = [136, 192, 208]
|
||||
modal_window_dim_bg = [ 10, 12, 16]
|
||||
border = [ 59, 66, 82]
|
||||
border_shadow = [ 0, 0, 0]
|
||||
bubble_ai = [ 35, 65, 45]
|
||||
bubble_system = [ 25, 25, 25]
|
||||
bubble_user = [ 30, 45, 75]
|
||||
bubble_vendor = [ 65, 55, 30]
|
||||
button = [ 59, 66, 82]
|
||||
button_active = [129, 161, 193]
|
||||
button_hovered = [ 94, 129, 172]
|
||||
check_mark = [136, 192, 208]
|
||||
child_bg = [ 30, 34, 42]
|
||||
diff_added = [ 51, 230, 51]
|
||||
diff_header = [ 77, 178, 255]
|
||||
diff_removed = [230, 51, 51]
|
||||
docking_empty_bg = [ 20, 22, 28]
|
||||
docking_preview = [ 94, 129, 172]
|
||||
frame_bg = [ 46, 52, 64]
|
||||
frame_bg_active = [ 67, 76, 94]
|
||||
frame_bg_hovered = [ 59, 66, 82]
|
||||
header = [ 59, 66, 82]
|
||||
header_active = [129, 161, 193]
|
||||
header_hovered = [ 94, 129, 172]
|
||||
menu_bar_bg = [ 46, 52, 64]
|
||||
modal_window_dim_bg = [ 10, 12, 16]
|
||||
nav_cursor = [136, 192, 208]
|
||||
popup_bg = [ 36, 41, 49]
|
||||
resize_grip = [ 59, 66, 82]
|
||||
resize_grip_active = [136, 192, 208]
|
||||
resize_grip_hovered = [ 94, 129, 172]
|
||||
scrollbar_bg = [ 30, 34, 42]
|
||||
scrollbar_grab = [ 76, 86, 106]
|
||||
scrollbar_grab_active = [129, 161, 193]
|
||||
scrollbar_grab_hovered = [ 94, 129, 172]
|
||||
separator = [ 59, 66, 82]
|
||||
separator_active = [136, 192, 208]
|
||||
separator_hovered = [ 94, 129, 172]
|
||||
slice_auto = [ 0, 255, 0]
|
||||
slice_manual = [255, 165, 0]
|
||||
slice_selection = [100, 100, 255]
|
||||
slider_grab = [ 94, 129, 172]
|
||||
slider_grab_active = [129, 161, 193]
|
||||
status_error = [255, 72, 64]
|
||||
status_info = [ 0, 255, 255]
|
||||
status_success = [ 80, 255, 80]
|
||||
status_warning = [255, 152, 48]
|
||||
tab = [ 46, 52, 64]
|
||||
tab_dimmed = [ 36, 41, 49]
|
||||
tab_dimmed_selected = [ 59, 66, 82]
|
||||
tab_hovered = [ 94, 129, 172]
|
||||
tab_selected = [ 76, 86, 106]
|
||||
table_border_light = [ 59, 66, 82]
|
||||
table_border_strong = [ 76, 86, 106]
|
||||
table_header_bg = [ 59, 66, 82]
|
||||
table_row_bg = [ 0, 0, 0]
|
||||
table_row_bg_alt = [ 46, 52, 64]
|
||||
text = [216, 222, 233]
|
||||
text_disabled = [116, 128, 150]
|
||||
text_selected_bg = [ 94, 129, 172]
|
||||
title_bg = [ 36, 41, 49]
|
||||
title_bg_active = [ 59, 66, 82]
|
||||
title_bg_collapsed = [ 30, 34, 42]
|
||||
window_bg = [ 36, 41, 49]
|
||||
|
||||
+47
-33
@@ -1,38 +1,52 @@
|
||||
# Solarized Dark — Ethan Schoonover's canonical dark palette
|
||||
name = "solarized_dark"
|
||||
syntax_palette = "dark"
|
||||
description = "Solarized Dark by Ethan Schoonover"
|
||||
|
||||
[colors]
|
||||
window_bg = [ 0, 43, 54] # base03
|
||||
child_bg = [ 7, 54, 66] # base02
|
||||
popup_bg = [ 0, 43, 54]
|
||||
border = [ 88, 110, 117] # base01
|
||||
frame_bg = [ 7, 54, 66]
|
||||
frame_bg_hovered = [ 88, 110, 117]
|
||||
frame_bg_active = [101, 123, 131]
|
||||
title_bg = [ 7, 54, 66]
|
||||
title_bg_active = [ 88, 110, 117]
|
||||
menu_bar_bg = [ 0, 43, 54]
|
||||
scrollbar_bg = [ 7, 54, 66]
|
||||
scrollbar_grab = [ 88, 110, 117]
|
||||
scrollbar_grab_hovered = [131, 148, 150]
|
||||
border = [ 88, 110, 117]
|
||||
bubble_ai = [ 35, 65, 45]
|
||||
bubble_system = [ 25, 25, 25]
|
||||
bubble_user = [ 30, 45, 75]
|
||||
bubble_vendor = [ 65, 55, 30]
|
||||
button = [ 7, 54, 66]
|
||||
button_active = [ 38, 139, 210]
|
||||
button_hovered = [ 38, 139, 210]
|
||||
check_mark = [ 38, 139, 210]
|
||||
child_bg = [ 7, 54, 66]
|
||||
diff_added = [ 51, 230, 51]
|
||||
diff_header = [ 77, 178, 255]
|
||||
diff_removed = [230, 51, 51]
|
||||
frame_bg = [ 7, 54, 66]
|
||||
frame_bg_active = [101, 123, 131]
|
||||
frame_bg_hovered = [ 88, 110, 117]
|
||||
header = [ 7, 54, 66]
|
||||
header_active = [ 38, 139, 210]
|
||||
header_hovered = [ 38, 139, 210]
|
||||
menu_bar_bg = [ 0, 43, 54]
|
||||
popup_bg = [ 0, 43, 54]
|
||||
scrollbar_bg = [ 7, 54, 66]
|
||||
scrollbar_grab = [ 88, 110, 117]
|
||||
scrollbar_grab_active = [253, 246, 227]
|
||||
button = [ 7, 54, 66]
|
||||
button_hovered = [ 38, 139, 210] # blue
|
||||
button_active = [ 38, 139, 210]
|
||||
header = [ 7, 54, 66]
|
||||
header_hovered = [ 38, 139, 210]
|
||||
header_active = [ 38, 139, 210]
|
||||
separator = [ 88, 110, 117]
|
||||
separator_hovered = [ 38, 139, 210]
|
||||
separator_active = [203, 75, 22] # orange
|
||||
tab = [ 7, 54, 66]
|
||||
tab_hovered = [ 38, 139, 210]
|
||||
tab_selected = [ 88, 110, 117]
|
||||
text = [147, 161, 161] # base1
|
||||
text_disabled = [ 88, 110, 117] # base01
|
||||
text_selected_bg = [ 38, 139, 210]
|
||||
check_mark = [ 38, 139, 210]
|
||||
slider_grab = [ 38, 139, 210]
|
||||
slider_grab_active = [ 38, 139, 210]
|
||||
table_header_bg = [ 7, 54, 66]
|
||||
scrollbar_grab_hovered = [131, 148, 150]
|
||||
separator = [ 88, 110, 117]
|
||||
separator_active = [203, 75, 22]
|
||||
separator_hovered = [ 38, 139, 210]
|
||||
slice_auto = [ 0, 255, 0]
|
||||
slice_manual = [255, 165, 0]
|
||||
slice_selection = [100, 100, 255]
|
||||
slider_grab = [ 38, 139, 210]
|
||||
slider_grab_active = [ 38, 139, 210]
|
||||
status_error = [255, 72, 64]
|
||||
status_info = [ 0, 255, 255]
|
||||
status_success = [ 80, 255, 80]
|
||||
status_warning = [255, 152, 48]
|
||||
tab = [ 7, 54, 66]
|
||||
tab_hovered = [ 38, 139, 210]
|
||||
tab_selected = [ 88, 110, 117]
|
||||
table_header_bg = [ 7, 54, 66]
|
||||
text = [147, 161, 161]
|
||||
text_disabled = [ 88, 110, 117]
|
||||
text_selected_bg = [ 38, 139, 210]
|
||||
title_bg = [ 7, 54, 66]
|
||||
title_bg_active = [ 88, 110, 117]
|
||||
window_bg = [ 0, 43, 54]
|
||||
|
||||
+47
-33
@@ -1,38 +1,52 @@
|
||||
# Solarized Light — Ethan Schoonover's canonical light palette
|
||||
name = "solarized_light"
|
||||
syntax_palette = "light"
|
||||
description = "Solarized Light by Ethan Schoonover"
|
||||
|
||||
[colors]
|
||||
window_bg = [238, 232, 213] # base2
|
||||
child_bg = [253, 246, 227] # base3
|
||||
popup_bg = [253, 246, 227]
|
||||
border = [147, 161, 161] # base1
|
||||
frame_bg = [253, 246, 227]
|
||||
frame_bg_hovered = [238, 232, 213]
|
||||
frame_bg_active = [238, 232, 213]
|
||||
title_bg = [238, 232, 213]
|
||||
title_bg_active = [147, 161, 161]
|
||||
menu_bar_bg = [238, 232, 213]
|
||||
scrollbar_bg = [238, 232, 213]
|
||||
scrollbar_grab = [147, 161, 161]
|
||||
scrollbar_grab_hovered = [131, 148, 150]
|
||||
border = [147, 161, 161]
|
||||
bubble_ai = [220, 255, 220]
|
||||
bubble_system = [240, 240, 240]
|
||||
bubble_user = [220, 230, 255]
|
||||
bubble_vendor = [255, 240, 200]
|
||||
button = [253, 246, 227]
|
||||
button_active = [ 38, 139, 210]
|
||||
button_hovered = [ 38, 139, 210]
|
||||
check_mark = [ 38, 139, 210]
|
||||
child_bg = [253, 246, 227]
|
||||
diff_added = [ 40, 180, 40]
|
||||
diff_header = [ 40, 100, 200]
|
||||
diff_removed = [200, 40, 40]
|
||||
frame_bg = [253, 246, 227]
|
||||
frame_bg_active = [238, 232, 213]
|
||||
frame_bg_hovered = [238, 232, 213]
|
||||
header = [253, 246, 227]
|
||||
header_active = [ 38, 139, 210]
|
||||
header_hovered = [ 38, 139, 210]
|
||||
menu_bar_bg = [238, 232, 213]
|
||||
popup_bg = [253, 246, 227]
|
||||
scrollbar_bg = [238, 232, 213]
|
||||
scrollbar_grab = [147, 161, 161]
|
||||
scrollbar_grab_active = [ 7, 54, 66]
|
||||
button = [253, 246, 227]
|
||||
button_hovered = [ 38, 139, 210] # blue
|
||||
button_active = [ 38, 139, 210]
|
||||
header = [253, 246, 227]
|
||||
header_hovered = [ 38, 139, 210]
|
||||
header_active = [ 38, 139, 210]
|
||||
separator = [147, 161, 161]
|
||||
separator_hovered = [181, 137, 0] # yellow
|
||||
separator_active = [203, 75, 22] # orange
|
||||
tab = [238, 232, 213]
|
||||
tab_hovered = [ 38, 139, 210]
|
||||
tab_selected = [147, 161, 161]
|
||||
text = [ 7, 54, 66] # base02
|
||||
text_disabled = [147, 161, 161] # base1
|
||||
text_selected_bg = [ 38, 139, 210]
|
||||
check_mark = [ 38, 139, 210]
|
||||
slider_grab = [ 38, 139, 210]
|
||||
slider_grab_active = [ 38, 139, 210]
|
||||
table_header_bg = [238, 232, 213]
|
||||
scrollbar_grab_hovered = [131, 148, 150]
|
||||
separator = [147, 161, 161]
|
||||
separator_active = [203, 75, 22]
|
||||
separator_hovered = [181, 137, 0]
|
||||
slice_auto = [ 80, 255, 80]
|
||||
slice_manual = [255, 200, 0]
|
||||
slice_selection = [180, 180, 255]
|
||||
slider_grab = [ 38, 139, 210]
|
||||
slider_grab_active = [ 38, 139, 210]
|
||||
status_error = [200, 40, 40]
|
||||
status_info = [ 40, 100, 200]
|
||||
status_success = [ 40, 180, 40]
|
||||
status_warning = [200, 140, 0]
|
||||
tab = [238, 232, 213]
|
||||
tab_hovered = [ 38, 139, 210]
|
||||
tab_selected = [147, 161, 161]
|
||||
table_header_bg = [238, 232, 213]
|
||||
text = [ 7, 54, 66]
|
||||
text_disabled = [147, 161, 161]
|
||||
text_selected_bg = [ 38, 139, 210]
|
||||
title_bg = [238, 232, 213]
|
||||
title_bg_active = [147, 161, 161]
|
||||
window_bg = [238, 232, 213]
|
||||
|
||||
Reference in New Issue
Block a user