Add application icon for all platforms
- Created icon generation script (create_icon.py) - Generated PNG icon (512x512) with word search grid design - Generated ICO file for Windows (multi-resolution) - Updated PyInstaller spec to use platform-appropriate icons - Updated .gitignore to exclude generated icon size variants Icon features: - Light blue gradient background - 5x5 grid with letters spelling WORD, SEARCH, etc. - Highlighted "WORD" in green to show found word - Professional, clean design Windows: icon.ico macOS: icon.icns (generate on macOS with provided commands) Linux: icon.png 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -42,3 +42,9 @@ Thumbs.db
|
|||||||
|
|
||||||
# Generated PDF files (optional - uncomment if you don't want to track PDFs)
|
# Generated PDF files (optional - uncomment if you don't want to track PDFs)
|
||||||
# *.pdf
|
# *.pdf
|
||||||
|
|
||||||
|
# Generated icon files (sizes)
|
||||||
|
icon_*.png
|
||||||
|
|
||||||
|
# macOS icon set directory
|
||||||
|
icon.iconset/
|
||||||
|
|||||||
145
create_icon.py
Normal file
145
create_icon.py
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Script to create the Word Search application icon.
|
||||||
|
Creates a PNG icon that can be converted to ICO/ICNS for different platforms.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
import os
|
||||||
|
|
||||||
|
def create_icon():
|
||||||
|
# Icon sizes to generate
|
||||||
|
sizes = [16, 32, 48, 64, 128, 256, 512]
|
||||||
|
|
||||||
|
# Create the largest size first
|
||||||
|
size = 512
|
||||||
|
img = Image.new('RGB', (size, size), color='white')
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
|
||||||
|
# Draw background gradient (light blue to white)
|
||||||
|
for y in range(size):
|
||||||
|
# Gradient from light blue to white
|
||||||
|
blue_value = int(220 + (35 * y / size))
|
||||||
|
color = (blue_value, blue_value, 255)
|
||||||
|
draw.line([(0, y), (size, y)], fill=color)
|
||||||
|
|
||||||
|
# Draw a grid pattern (simplified word search grid)
|
||||||
|
grid_size = 5
|
||||||
|
cell_size = size // (grid_size + 2)
|
||||||
|
margin = cell_size
|
||||||
|
|
||||||
|
# Draw grid lines
|
||||||
|
for i in range(grid_size + 1):
|
||||||
|
x = margin + i * cell_size
|
||||||
|
y = margin + i * cell_size
|
||||||
|
# Vertical lines
|
||||||
|
draw.line([(x, margin), (x, margin + grid_size * cell_size)],
|
||||||
|
fill=(100, 100, 150), width=3)
|
||||||
|
# Horizontal lines
|
||||||
|
draw.line([(margin, y), (margin + grid_size * cell_size, y)],
|
||||||
|
fill=(100, 100, 150), width=3)
|
||||||
|
|
||||||
|
# Add some letters to make it look like a word search
|
||||||
|
letters = [
|
||||||
|
['W', 'O', 'R', 'D', 'S'],
|
||||||
|
['X', 'S', 'E', 'A', 'R'],
|
||||||
|
['P', 'U', 'Z', 'Z', 'L'],
|
||||||
|
['G', 'A', 'M', 'E', 'F'],
|
||||||
|
['F', 'I', 'N', 'D', 'X']
|
||||||
|
]
|
||||||
|
|
||||||
|
# Try to use a bold font, fallback to default
|
||||||
|
try:
|
||||||
|
# Try common font paths
|
||||||
|
font_size = cell_size // 2
|
||||||
|
font_paths = [
|
||||||
|
'/usr/share/fonts/liberation/LiberationSans-Bold.ttf',
|
||||||
|
'/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf',
|
||||||
|
'/System/Library/Fonts/Helvetica.ttc',
|
||||||
|
'C:\\Windows\\Fonts\\arialbd.ttf'
|
||||||
|
]
|
||||||
|
font = None
|
||||||
|
for path in font_paths:
|
||||||
|
if os.path.exists(path):
|
||||||
|
font = ImageFont.truetype(path, font_size)
|
||||||
|
break
|
||||||
|
if font is None:
|
||||||
|
font = ImageFont.load_default()
|
||||||
|
except:
|
||||||
|
font = ImageFont.load_default()
|
||||||
|
|
||||||
|
# Draw letters
|
||||||
|
for i in range(grid_size):
|
||||||
|
for j in range(grid_size):
|
||||||
|
letter = letters[i][j]
|
||||||
|
x = margin + j * cell_size + cell_size // 2
|
||||||
|
y = margin + i * cell_size + cell_size // 2
|
||||||
|
|
||||||
|
# Get text bounding box for centering
|
||||||
|
bbox = draw.textbbox((0, 0), letter, font=font)
|
||||||
|
text_width = bbox[2] - bbox[0]
|
||||||
|
text_height = bbox[3] - bbox[1]
|
||||||
|
|
||||||
|
draw.text((x - text_width // 2, y - text_height // 2),
|
||||||
|
letter, fill=(50, 50, 100), font=font)
|
||||||
|
|
||||||
|
# Highlight "WORD" in the first row with a green overlay
|
||||||
|
highlight_color = (100, 255, 100, 100) # Light green with transparency
|
||||||
|
overlay = Image.new('RGBA', (size, size), (255, 255, 255, 0))
|
||||||
|
overlay_draw = ImageDraw.Draw(overlay)
|
||||||
|
|
||||||
|
# Draw highlight rectangle for "WORD"
|
||||||
|
x1 = margin + 5
|
||||||
|
y1 = margin + 5
|
||||||
|
x2 = margin + 4 * cell_size - 5
|
||||||
|
y2 = margin + cell_size - 5
|
||||||
|
overlay_draw.rounded_rectangle([x1, y1, x2, y2], radius=10,
|
||||||
|
fill=highlight_color, outline=(50, 200, 50, 200), width=3)
|
||||||
|
|
||||||
|
# Convert to RGBA and composite with overlay
|
||||||
|
img = img.convert('RGBA')
|
||||||
|
img = Image.alpha_composite(img, overlay)
|
||||||
|
|
||||||
|
# Save main PNG icon
|
||||||
|
img.save('icon.png', 'PNG')
|
||||||
|
print("Created: icon.png (512x512)")
|
||||||
|
|
||||||
|
# Create smaller sizes
|
||||||
|
for new_size in sizes:
|
||||||
|
if new_size < 512:
|
||||||
|
resized = img.resize((new_size, new_size), Image.Resampling.LANCZOS)
|
||||||
|
resized.save(f'icon_{new_size}.png', 'PNG')
|
||||||
|
print(f"Created: icon_{new_size}.png")
|
||||||
|
|
||||||
|
# Create ICO file for Windows (contains multiple sizes)
|
||||||
|
try:
|
||||||
|
icon_sizes = [(16, 16), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)]
|
||||||
|
images = []
|
||||||
|
for icon_size in icon_sizes:
|
||||||
|
resized = img.resize(icon_size, Image.Resampling.LANCZOS)
|
||||||
|
images.append(resized)
|
||||||
|
|
||||||
|
images[0].save('icon.ico', format='ICO', sizes=icon_sizes, append_images=images[1:])
|
||||||
|
print("Created: icon.ico (multi-resolution)")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Note: Could not create ICO file: {e}")
|
||||||
|
|
||||||
|
# Create ICNS for macOS (requires pillow with ICNS support or iconutil)
|
||||||
|
print("\nFor macOS .icns file, use the following command on macOS:")
|
||||||
|
print(" mkdir icon.iconset")
|
||||||
|
print(" sips -z 16 16 icon.png --out icon.iconset/icon_16x16.png")
|
||||||
|
print(" sips -z 32 32 icon.png --out icon.iconset/icon_16x16@2x.png")
|
||||||
|
print(" sips -z 32 32 icon.png --out icon.iconset/icon_32x32.png")
|
||||||
|
print(" sips -z 64 64 icon.png --out icon.iconset/icon_32x32@2x.png")
|
||||||
|
print(" sips -z 128 128 icon.png --out icon.iconset/icon_128x128.png")
|
||||||
|
print(" sips -z 256 256 icon.png --out icon.iconset/icon_128x128@2x.png")
|
||||||
|
print(" sips -z 256 256 icon.png --out icon.iconset/icon_256x256.png")
|
||||||
|
print(" sips -z 512 512 icon.png --out icon.iconset/icon_256x256@2x.png")
|
||||||
|
print(" sips -z 512 512 icon.png --out icon.iconset/icon_512x512.png")
|
||||||
|
print(" iconutil -c icns icon.iconset")
|
||||||
|
print(" rm -rf icon.iconset")
|
||||||
|
|
||||||
|
print("\nIcon creation complete!")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
create_icon()
|
||||||
@@ -1,7 +1,18 @@
|
|||||||
# -*- mode: python ; coding: utf-8 -*-
|
# -*- mode: python ; coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
block_cipher = None
|
block_cipher = None
|
||||||
|
|
||||||
|
# Determine icon path based on platform
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
icon_file = 'icon.ico'
|
||||||
|
elif sys.platform == 'darwin':
|
||||||
|
icon_file = 'icon.icns' # Will need to be created on macOS
|
||||||
|
else:
|
||||||
|
icon_file = 'icon.png'
|
||||||
|
|
||||||
a = Analysis(
|
a = Analysis(
|
||||||
['word_search_generator.py'],
|
['word_search_generator.py'],
|
||||||
pathex=[],
|
pathex=[],
|
||||||
@@ -40,12 +51,13 @@ exe = EXE(
|
|||||||
target_arch=None,
|
target_arch=None,
|
||||||
codesign_identity=None,
|
codesign_identity=None,
|
||||||
entitlements_file=None,
|
entitlements_file=None,
|
||||||
|
icon=icon_file if os.path.exists(icon_file) else None,
|
||||||
)
|
)
|
||||||
|
|
||||||
# macOS app bundle
|
# macOS app bundle
|
||||||
app = BUNDLE(
|
app = BUNDLE(
|
||||||
exe,
|
exe,
|
||||||
name='WordSearch.app',
|
name='WordSearch.app',
|
||||||
icon=None,
|
icon=icon_file if sys.platform == 'darwin' and os.path.exists(icon_file) else None,
|
||||||
bundle_identifier='com.firebugit.wordsearch',
|
bundle_identifier='com.firebugit.wordsearch',
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user