72 lines
2.4 KiB
Python
72 lines
2.4 KiB
Python
import os
|
|
import subprocess
|
|
from PIL import Image
|
|
import customtkinter as ctk
|
|
|
|
def parse_float(val_str: str) -> float:
|
|
"""Safely parse a string to float, handling both '.' and ',' as decimal separators."""
|
|
if not val_str:
|
|
return None
|
|
clean_val = val_str.replace(',', '.')
|
|
try:
|
|
return float(clean_val)
|
|
except ValueError:
|
|
return None
|
|
|
|
def format_float(val: float, precision: int = 1) -> str:
|
|
"""Format a float for display."""
|
|
if val is None:
|
|
return ""
|
|
return f"{val:.{precision}f}"
|
|
|
|
def get_bmi_status(bmi):
|
|
if bmi < 16: return "Severely Underweight", "bmi_severely_underweight.svg", "#3498db"
|
|
if bmi < 18.5: return "Underweight", "bmi_underweight.svg", "#3498db"
|
|
if bmi < 25: return "Normal", "bmi_normal.svg", "#2ecc71"
|
|
if bmi < 30: return "Overweight", "bmi_overweight.svg", "#f1c40f"
|
|
return "Obese", "bmi_severely_obese.svg", "#e74c3c"
|
|
|
|
def get_bmi_icon(bmi: float, size: tuple = (100, 100)) -> ctk.CTkImage:
|
|
"""
|
|
Returns a CTkImage for the given BMI.
|
|
Converts SVG to PNG using rsvg-convert if needed.
|
|
"""
|
|
if bmi is None: return None
|
|
|
|
_, filename, _ = get_bmi_status(bmi)
|
|
|
|
base_dir = os.path.dirname(os.path.abspath(__file__))
|
|
assets_dir = os.path.join(base_dir, "assets", "bmi_icons")
|
|
cache_dir = os.path.join(assets_dir, "png_cache")
|
|
|
|
svg_path = os.path.join(assets_dir, filename)
|
|
png_filename = filename.replace(".svg", f"_{size[0]}x{size[1]}.png")
|
|
png_path = os.path.join(cache_dir, png_filename)
|
|
|
|
if not os.path.exists(svg_path):
|
|
print(f"Warning: Icon not found at {svg_path}")
|
|
return None
|
|
|
|
if not os.path.exists(cache_dir):
|
|
os.makedirs(cache_dir)
|
|
|
|
# Convert if PNG doesn't exist
|
|
if not os.path.exists(png_path):
|
|
try:
|
|
subprocess.run([
|
|
"rsvg-convert",
|
|
"-w", str(size[0]),
|
|
"-h", str(size[1]),
|
|
"-o", png_path,
|
|
svg_path
|
|
], check=True)
|
|
except (subprocess.CalledProcessError, FileNotFoundError) as e:
|
|
print(f"Error converting SVG: {e}")
|
|
return None
|
|
|
|
try:
|
|
img = Image.open(png_path)
|
|
return ctk.CTkImage(light_image=img, dark_image=img, size=size)
|
|
except Exception as e:
|
|
print(f"Error loading image: {e}")
|
|
return None |