Initial development by Claude
This commit is contained in:
134
create_icon.py
Normal file
134
create_icon.py
Normal file
@@ -0,0 +1,134 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user