Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 0 additions & 36 deletions client/ui/connection_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,42 +16,6 @@ def __init__(self, parent=None):
self.setWindowTitle("Connect to LabLink Server")
self.setModal(True)

# Apply visual styling
self.setStyleSheet("""
QDialog {
background-color: #ecf0f1;
}
QGroupBox {
border: 2px solid #bdc3c7;
border-radius: 8px;
margin-top: 12px;
padding-top: 15px;
background-color: white;
font-weight: bold;
}
QGroupBox::title {
subcontrol-origin: margin;
left: 15px;
padding: 5px 10px;
background-color: white;
}
QPushButton {
background-color: #3498db;
color: white;
border: 2px solid #2471a3;
border-radius: 6px;
padding: 8px 15px;
min-height: 30px;
}
QPushButton:hover {
background-color: #2e86c1;
border: 2px solid #1f618d;
}
QPushButton:pressed {
background-color: #2471a3;
}
""")

self._setup_ui()
self._load_last_connection()

Expand Down
81 changes: 81 additions & 0 deletions generate_final_icons.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env python3
"""Generate final icons from LL.png (logo only, no text)"""

from PIL import Image
from pathlib import Path

# Paths
images_dir = Path(__file__).parent / "images"
source = images_dir / "LL.png"
output_ico = images_dir / "icon.ico"
output_favicon = images_dir / "favicon.png"

print("Loading LL.png (logo only, no text)...")
img = Image.open(source)
print(f"Source image: {img.size[0]}x{img.size[1]}")

# Convert to RGBA if not already
img = img.convert("RGBA")

# Check if we need to remove black background
# (LL.png might already have transparency)
data = img.getdata()
has_transparency = any(pixel[3] < 255 for pixel in data)

if has_transparency:
print("Source already has transparency - using as-is")
processed = img
else:
print("Removing black background and adding transparency...")
new_data = []
for pixel in data:
# If pixel is black or very dark (R,G,B all < 40), make it transparent
if pixel[0] < 40 and pixel[1] < 40 and pixel[2] < 40:
new_data.append((0, 0, 0, 0)) # Transparent
else:
new_data.append(pixel)

processed = Image.new("RGBA", img.size)
processed.putdata(new_data)
print("[OK] Black background removed")

# Generate multiple high-quality sizes
print("\nGenerating multiple icon sizes with maximum quality...")
# Windows 11 benefits from these specific sizes
sizes = [16, 20, 24, 32, 40, 48, 64, 96, 128, 256]
icons = []

for size in sizes:
print(f" Creating {size}x{size}...")
# Use LANCZOS for highest quality downsampling
icon = processed.resize((size, size), Image.Resampling.LANCZOS)
icons.append(icon)
print(f" [OK] {size}x{size}")

# Save favicon.png at 128x128
print("\nGenerating favicon.png...")
favicon = processed.resize((128, 128), Image.Resampling.LANCZOS)
favicon.save(output_favicon, "PNG", optimize=True)
print(f"[OK] Created {output_favicon} at 128x128")

# Save multi-resolution .ico with all sizes
print("\nGenerating icon.ico with all resolutions...")
# Important: Save largest to smallest for best Windows compatibility
icons_sorted = sorted(icons, key=lambda x: x.size[0], reverse=True)
icons_sorted[0].save(
output_ico,
format="ICO",
sizes=[icon.size for icon in icons_sorted],
append_images=icons_sorted[1:]
)

print(f"[OK] Created {output_ico}")
print(f" Sizes: 16, 20, 24, 32, 40, 48, 64, 96, 128, 256")
print(f" All with transparent backgrounds")

print("\n[SUCCESS] Icons generated from logo-only image (no text)!")
print("Icons now contain ONLY the logo symbol, no 'LabLink' text.")
print("\nTo update your desktop icon:")
print("1. Right-click shortcut -> Properties -> Change Icon")
print("2. Browse to icon.ico")
print("3. Click OK to apply")
39 changes: 39 additions & 0 deletions generate_icons.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env python3
"""Generate favicon.png and icon.ico from Splash.png"""

from PIL import Image
from pathlib import Path

# Paths
images_dir = Path(__file__).parent / "images"
source = images_dir / "Splash.png"
favicon_out = images_dir / "favicon.png"
ico_out = images_dir / "icon.ico"

print("Loading source image...")
img = Image.open(source)
print(f"Source image: {img.size[0]}x{img.size[1]}")

# Generate favicon.png at 128x128
print("\nGenerating favicon.png (128x128)...")
favicon = img.resize((128, 128), Image.Resampling.LANCZOS)
favicon.save(favicon_out, "PNG")
print(f"[OK] Created {favicon_out}")

# Generate icon.ico with multiple resolutions
print("\nGenerating icon.ico with multiple resolutions...")
sizes = [(16, 16), (32, 32), (48, 48), (256, 256)]
icons = []

for size in sizes:
icon = img.resize(size, Image.Resampling.LANCZOS)
icons.append(icon)
print(f" - {size[0]}x{size[1]}")

# Save all sizes to a single .ico file
icons[0].save(ico_out, format="ICO", sizes=[icon.size for icon in icons], append_images=icons[1:])
print(f"[OK] Created {ico_out}")

print("\n[SUCCESS] Icon generation complete!")
print(f" favicon.png: 128x128 (for window/taskbar)")
print(f" icon.ico: 16x16, 32x32, 48x48, 256x256 (for shortcuts)")
Binary file added images/LL.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/icon.ico
Binary file not shown.
83 changes: 83 additions & 0 deletions process_icon_transparency.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/env python3
"""Process lablink_multi.ico to remove black background and add transparency"""

from PIL import Image
import os
from pathlib import Path

# Paths
images_dir = Path(__file__).parent / "images"
source = images_dir / "lablink_multi.ico"
output_ico = images_dir / "icon.ico"
output_favicon = images_dir / "favicon.png"

def remove_black_background(img):
"""Remove black background from image and make it transparent"""
img = img.convert("RGBA")
data = img.getdata()
new_data = []

for pixel in data:
# If pixel is black or very dark (R,G,B all < 30), make it transparent
if pixel[0] < 30 and pixel[1] < 30 and pixel[2] < 30:
new_data.append((0, 0, 0, 0)) # Transparent
else:
new_data.append(pixel)

img.putdata(new_data)
return img

print("Loading lablink_multi.ico...")

# PIL's ICO loader doesn't always handle multi-resolution ICOs well
# Load and process the largest size, then create multiple resolutions
with Image.open(source) as img:
# Get the largest available size
print(f"Source size: {img.size[0]}x{img.size[1]}")

# Process the image to remove black background
print("Removing black background...")
processed = remove_black_background(img)

# Generate multiple sizes for the .ico file
print("\nGenerating multiple icon sizes...")
sizes = [16, 20, 24, 32, 40, 48, 64, 256]
icons = []
sizes_processed = []

for size in sizes:
if size <= processed.size[0]: # Only create sizes up to source size
icon = processed.resize((size, size), Image.Resampling.LANCZOS)
icons.append(icon)
sizes_processed.append((size, size))
print(f" [OK] Created {size}x{size}")

# Save the largest icon as favicon.png (128x128 preferred)
print("\nGenerating favicon.png...")
# Find or create 128x128 version
favicon = None
for icon in icons:
if icon.size[0] == 128:
favicon = icon
break

if favicon is None:
# Create 128x128 from processed image
favicon = processed.resize((128, 128), Image.Resampling.LANCZOS)

favicon.save(output_favicon, "PNG")
print(f"[OK] Created {output_favicon} at {favicon.size[0]}x{favicon.size[1]}")

# Save all icons as a multi-resolution .ico file
print("\nGenerating icon.ico with transparent background...")
if len(icons) > 1:
icons[0].save(output_ico, format="ICO", sizes=[icon.size for icon in icons], append_images=icons[1:])
else:
icons[0].save(output_ico, format="ICO")

print(f"[OK] Created {output_ico}")
print(f" Sizes included: {', '.join([f'{s[0]}x{s[1]}' for s in sizes_processed])}")

print("\n[SUCCESS] Icon processing complete!")
print("Black background removed, transparent icons created.")
print("Desktop shortcuts should now have transparent backgrounds and sharper icons.")
75 changes: 75 additions & 0 deletions regenerate_sharp_icons.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env python3
"""Regenerate ultra-sharp icons from high-res Splash.png"""

from PIL import Image
from pathlib import Path

# Paths
images_dir = Path(__file__).parent / "images"
source = images_dir / "Splash.png"
output_ico = images_dir / "icon.ico"
output_favicon = images_dir / "favicon.png"

print("Loading Splash.png (1024x1024 high-resolution source)...")
img = Image.open(source)
print(f"Source image: {img.size[0]}x{img.size[1]}")

# Convert to RGBA
img = img.convert("RGBA")

# Remove black background and make transparent
print("Removing black background...")
data = img.getdata()
new_data = []

for pixel in data:
# If pixel is black or very dark (R,G,B all < 30), make it transparent
# Also check for near-black pixels (< 40) for better edge cleanup
if pixel[0] < 40 and pixel[1] < 40 and pixel[2] < 40:
new_data.append((0, 0, 0, 0)) # Transparent
else:
new_data.append(pixel)

img.putdata(new_data)
print("[OK] Black background removed")

# Generate multiple high-quality sizes
print("\nGenerating multiple icon sizes with maximum quality...")
# Windows 11 benefits from these specific sizes
sizes = [16, 20, 24, 32, 40, 48, 64, 96, 128, 256]
icons = []

for size in sizes:
print(f" Creating {size}x{size}...")
# Use LANCZOS for highest quality downsampling
icon = img.resize((size, size), Image.Resampling.LANCZOS)
icons.append(icon)
print(f" [OK] {size}x{size}")

# Save favicon.png at 128x128
print("\nGenerating favicon.png...")
favicon = img.resize((128, 128), Image.Resampling.LANCZOS)
favicon.save(output_favicon, "PNG", optimize=True)
print(f"[OK] Created {output_favicon} at 128x128")

# Save multi-resolution .ico with all sizes
print("\nGenerating icon.ico with all resolutions...")
# Important: Save largest to smallest for best Windows compatibility
icons_sorted = sorted(icons, key=lambda x: x.size[0], reverse=True)
icons_sorted[0].save(
output_ico,
format="ICO",
sizes=[icon.size for icon in icons_sorted],
append_images=icons_sorted[1:]
)

print(f"[OK] Created {output_ico}")
print(f" Sizes: 16, 20, 24, 32, 40, 48, 64, 96, 128, 256")
print(f" All with transparent backgrounds")

print("\n[SUCCESS] Ultra-sharp icons generated from 1024x1024 source!")
print("These icons should be MUCH sharper on Windows 11.")
print("\nTo update your desktop icon:")
print("1. Right-click shortcut -> Properties -> Change Icon")
print("2. Browse to the icon.ico file")
print("3. Click OK to apply")
Loading