""" SaiCore Dark-Red Theme - Complete icon regeneration. All icons redesigned with dark-red palette: #dc2626 primary, #f87171 light, #991b1b dark, #fca5a5 accent, white on dark backgrounds. Icons are drawn as clean, modern flat designs with rounded shapes. """ import os, math from PIL import Image, ImageDraw, ImageFont BASE = os.path.join(os.path.dirname(__file__), "..", "resources", "images") # Dark-Red Theme Palette RED = (220, 38, 38) # #dc2626 - primary RED_LT = (248, 113, 113) # #f87171 - light variant RED_DK = (153, 27, 27) # #991b1b - dark variant RED_XL = (252, 165, 165) # #fca5a5 - accent light GOLD = (245, 158, 11) # #f59e0b - highlight WHITE = (255, 255, 255) CREAM = (250, 250, 249) # near-white for dark bg DARK = (26, 10, 10) # #1a0a0a - darkest bg SURFACE = (45, 21, 23) # #2d1517 - surface GRAY = (82, 82, 91) # #52525b - borders GREEN = (16, 185, 129) # success T = (0, 0, 0, 0) def font(sz): for n in ['C:/Windows/Fonts/segoeuib.ttf', 'C:/Windows/Fonts/arialbd.ttf']: try: return ImageFont.truetype(n, sz) except: pass return ImageFont.load_default() def new(sz=42): img = Image.new('RGBA', (sz, sz), T) return img, ImageDraw.Draw(img) def save(path, img): img.save(path, 'PNG') print(f" {os.path.basename(path)}") def svg(path, body, w=42, h=42): with open(path, 'w', encoding='utf-8') as f: f.write(f'\n\n{body}\n') print(f" {os.path.basename(path)}") def hx(c): return f'#{c[0]:02x}{c[1]:02x}{c[2]:02x}' R = hx(RED) RL = hx(RED_LT) RD = hx(RED_DK) RX = hx(RED_XL) G = hx(GOLD) W = hx(WHITE) CR = hx(CREAM) GR = hx(GRAY) SU = hx(SURFACE) DK = hx(DARK) # ============================================================ # STYLUS PALETTE # ============================================================ def gen_stylus(): print("=== Stylus Palette ===") d = os.path.join(BASE, "stylusPalette") sz = 42 def pen(color, arrow=False): img, dr = new(sz) # Pen body - diagonal with rounded cap dr.line([(10,32),(30,12)], fill=color, width=5) dr.ellipse([27,9,33,15], fill=color) # Nib dr.polygon([(7,35),(13,35),(10,31)], fill=color) # Highlight stripe dr.line([(12,30),(28,14)], fill=RED_LT, width=1) if arrow: dr.polygon([(34,34),(40,31),(40,37)], fill=RED) return img def marker(color, arrow=False): img, dr = new(sz) dr.line([(10,32),(30,12)], fill=color, width=7) dr.rounded_rectangle([27,5,35,13], radius=2, fill=color) dr.polygon([(6,36),(14,36),(10,40)], fill=color) dr.line([(12,30),(28,14)], fill=RED_LT, width=2) if arrow: dr.polygon([(34,34),(40,31),(40,37)], fill=RED) return img def eraser(color, arrow=False): img, dr = new(sz) dr.rounded_rectangle([10,14,32,28], radius=4, fill=color) dr.rounded_rectangle([10,23,32,28], radius=2, fill=RED) # Highlight dr.rounded_rectangle([12,16,30,18], radius=1, fill=RED_LT) if arrow: dr.polygon([(34,34),(40,31),(40,37)], fill=RED) return img for name, img in [ ("pen.png", pen(CREAM)), ("penOn.png", pen(RED)), ("penArrow.png", pen(CREAM, True)), ("penOnArrow.png", pen(RED, True)), ("marker.png", marker(CREAM)), ("markerOn.png", marker(RED)), ("markerArrow.png", marker(CREAM, True)), ("markerOnArrow.png", marker(RED, True)), ("eraser.png", eraser(CREAM)), ("eraserOn.png", eraser(RED)), ("eraserArrow.png", eraser(CREAM, True)), ("eraserOnArrow.png", eraser(RED, True)), ]: save(os.path.join(d, name), img) # SVGs for base, w in [("pen", 5), ("marker", 7), ("eraser", 0)]: for suffix, color in [("", CR), ("On", R)]: if base == "eraser": body = f'' else: body = f'' svg(os.path.join(d, f"{base}{suffix}.svg"), body) # Line for suffix, color in [("", CREAM), ("On", RED)]: img, dr = new(sz) dr.line([(8,32),(34,10)], fill=color, width=3) dr.ellipse([5,29,11,35], fill=color) dr.ellipse([31,7,37,13], fill=color) save(os.path.join(d, f"line{suffix}.png"), img) # Text for suffix, color in [("", CREAM), ("On", RED)]: img, dr = new(sz) dr.text((13,7), "T", fill=color, font=font(26)) save(os.path.join(d, f"text{suffix}.png"), img) # Hand for suffix, color, play in [("",CREAM,False),("On",RED,False),("Play",CREAM,True),("PlayOn",RED,True)]: img, dr = new(sz) dr.rounded_rectangle([14,18,28,32], radius=5, fill=color) for ox in [-6,-2,2,6]: dr.rounded_rectangle([20+ox-1,10,20+ox+1,20], radius=1, fill=color) dr.rounded_rectangle([10,22,14,28], radius=2, fill=color) if play: dr.polygon([(30,18),(30,28),(37,23)], fill=WHITE) save(os.path.join(d, f"hand{suffix}.png"), img) # Arrow for suffix, color in [("", CREAM), ("On", RED)]: img, dr = new(sz) dr.line([(8,34),(28,12)], fill=color, width=3) dr.polygon([(28,12),(22,12),(28,18)], fill=color) save(os.path.join(d, f"arrow{suffix}.png"), img) # Capture for suffix, color in [("", CREAM), ("On", RED)]: img, dr = new(sz) for i in range(8, 34, 6): dr.line([i,8,min(i+3,34),8], fill=color, width=2) dr.line([i,34,min(i+3,34),34], fill=color, width=2) dr.line([8,i,8,min(i+3,34)], fill=color, width=2) dr.line([34,i,34,min(i+3,34)], fill=color, width=2) save(os.path.join(d, f"captureArea{suffix}.png"), img) # Laser for suffix, color in [("", CREAM), ("On", RED)]: img, dr = new(sz) dr.rounded_rectangle([8,19,26,23], radius=2, fill=color) dr.ellipse([24,16,34,26], fill=RED) dr.line([26,21,34,21], fill=RED_LT, width=2) save(os.path.join(d, f"laser{suffix}.png"), img) # Zoom for suffix, direction in [("In",CREAM),("InOn",RED),("Out",CREAM),("OutOn",RED)]: img, dr = new(sz) dr.ellipse([8,8,28,28], outline=suffix_color, width=3) dr.line([26,26,36,36], fill=suffix_color, width=3) if "In" in suffix: dr.line([14,18,22,18], fill=suffix_color, width=3) dr.line([18,14,18,22], fill=suffix_color, width=3) else: dr.line([14,18,22,18], fill=suffix_color, width=3) save(os.path.join(d, f"zoom{suffix}.png"), img) # Restore zoom img, dr = new(sz) dr.ellipse([8,8,28,28], outline=CREAM, width=3) dr.line([26,26,36,36], fill=CREAM, width=3) dr.text((12,12), "1:1", fill=CREAM, font=font(8)) save(os.path.join(d, "restoreZoom.png"), img) # Snap for suffix, color in [("", CREAM), ("On", RED)]: svg(os.path.join(d, f"snap{suffix}.svg"), f'')