Files
path-juggler/create_icon.py

135 lines
3.8 KiB
Python

#!/usr/bin/env python3
"""
Generate a simple icon for Path Juggler.
Creates an .icns file for use with the macOS app bundle.
Requires: pip install Pillow
"""
import subprocess
import tempfile
from pathlib import Path
try:
from PIL import Image, ImageDraw
except ImportError:
print("Pillow not installed. Install with: pip3 install Pillow")
print("Or skip icon generation - the app will use a default icon.")
exit(1)
def create_icon_image(size: int) -> Image.Image:
"""Create a single icon image at the given size."""
img = Image.new('RGBA', (size, size), (0, 0, 0, 0))
draw = ImageDraw.Draw(img)
# Background - purple/blue gradient-like color (juggler theme)
margin = int(size * 0.08)
radius = int(size * 0.18)
# Draw rounded rectangle background
draw.rounded_rectangle(
[margin, margin, size - margin, size - margin],
radius=radius,
fill=(88, 86, 214, 255) # Purple-blue
)
center_x = size // 2
center_y = size // 2
# Draw three "juggling balls" in an arc
ball_radius = int(size * 0.09)
arc_radius = int(size * 0.22)
# Ball positions (arc above center)
balls = [
(center_x - arc_radius, center_y - int(size * 0.08)), # Left
(center_x, center_y - int(size * 0.18)), # Top center
(center_x + arc_radius, center_y - int(size * 0.08)), # Right
]
ball_colors = [
(255, 107, 107, 255), # Red/coral
(78, 205, 196, 255), # Teal
(255, 230, 109, 255), # Yellow
]
for (bx, by), color in zip(balls, ball_colors):
draw.ellipse(
[bx - ball_radius, by - ball_radius, bx + ball_radius, by + ball_radius],
fill=color
)
# Draw path arrows (two crossing paths)
arrow_color = (255, 255, 255, 200)
line_width = max(2, int(size * 0.025))
# Left-to-right arrow
arrow_y = center_y + int(size * 0.15)
arrow_start = margin + int(size * 0.1)
arrow_end = size - margin - int(size * 0.1)
draw.line(
[(arrow_start, arrow_y), (arrow_end - int(size * 0.08), arrow_y)],
fill=arrow_color,
width=line_width
)
# Arrow head
head_size = int(size * 0.06)
draw.polygon([
(arrow_end, arrow_y),
(arrow_end - head_size, arrow_y - head_size // 2),
(arrow_end - head_size, arrow_y + head_size // 2),
], fill=arrow_color)
return img
def create_icns(output_path: Path):
"""Create an .icns file with all required sizes."""
sizes = [16, 32, 64, 128, 256, 512, 1024]
with tempfile.TemporaryDirectory() as tmpdir:
iconset_path = Path(tmpdir) / "icon.iconset"
iconset_path.mkdir()
for size in sizes:
img = create_icon_image(size)
img.save(iconset_path / f"icon_{size}x{size}.png")
if size <= 512:
img_2x = create_icon_image(size * 2)
img_2x.save(iconset_path / f"icon_{size}x{size}@2x.png")
result = subprocess.run(
["iconutil", "-c", "icns", str(iconset_path), "-o", str(output_path)],
capture_output=True,
text=True
)
if result.returncode != 0:
print(f"iconutil failed: {result.stderr}")
return False
return True
def main():
script_dir = Path(__file__).parent
output_path = script_dir / "AppIcon.icns"
print("Generating Path Juggler icon...")
if create_icns(output_path):
print(f"Icon created: {output_path}")
print("\nTo use this icon in the build:")
print("1. Edit build_app.sh")
print("2. Find the line: icon=None,")
print("3. Change it to: icon='AppIcon.icns',")
else:
print("Failed to create icon")
if __name__ == "__main__":
main()