From 47aa3ac7498202393dbf6cfec7c43b605e084f93 Mon Sep 17 00:00:00 2001 From: punix Date: Sat, 28 Jun 2025 00:32:49 +0200 Subject: [PATCH] add class Image for icon managment --- Changelog | 2 ++ wirepy.py | 41 +++++++++++++------------- wp_app_config.py | 76 ++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 83 insertions(+), 36 deletions(-) diff --git a/Changelog b/Changelog index 7d99d8f..5ea5338 100644 --- a/Changelog +++ b/Changelog @@ -19,6 +19,8 @@ My standard System: Linux Mint 22 Cinnamon - ui works now better with rename button + - add Image class for manage Images + ### Added 23-06-2025 diff --git a/wirepy.py b/wirepy.py index 0ddfbce..2a82723 100755 --- a/wirepy.py +++ b/wirepy.py @@ -24,7 +24,7 @@ from shared_libs.common_tools import ( Tooltip, ) -from wp_app_config import AppConfig, Msg +from shared_libs.wp_app_config import AppConfig, Image, Msg class Wirepy(tk.Tk): @@ -39,6 +39,7 @@ class Wirepy(tk.Tk): self.withdraw() self.my_tool_tip = None + self.x_width = AppConfig.UI_CONFIG["window_size"][0] self.y_height = AppConfig.UI_CONFIG["window_size"][1] @@ -53,17 +54,19 @@ class Wirepy(tk.Tk): AppConfig.UI_CONFIG["window_size"][1], ) self.title(AppConfig.UI_CONFIG["window_title"]) - + self.image_manager = Image() self.tk.call("source", f"{AppConfig.SYSTEM_PATHS['tcl_path']}/water.tcl") ConfigManager.init(AppConfig.SETTINGS_FILE) theme = ConfigManager.get("theme") ThemeManager.change_theme(self, theme) - # Load the image file from the disk - self.wg_icon = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_vpn"]) - - # Set it as the window icon - self.iconphoto(True, self.wg_icon) + # Try to set icon + try: + icon = self.image_manager.load_image("icon_vpn") + if icon: + self.iconphoto(True, icon) + except: + pass # Add the widgets FrameWidgets(self).grid() @@ -91,13 +94,7 @@ class FrameWidgets(ttk.Frame): self.dns = None self.address = None self.auto_con = None - self.wg_vpn_start = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_start"]) - self.wg_vpn_stop = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_stop"]) - self.imp_pic = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_import"]) - self.tr_pic = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_trash"]) - self.exp_pic = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_export"]) - self.warning_pic = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_error"]) - self.wg_icon_header = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_header"]) + self.image_manager = Image() self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) self.columnconfigure(1, weight=1) @@ -211,7 +208,9 @@ class FrameWidgets(ttk.Frame): self.wg_icon_header_frame.grid(column=0, row=0, rowspan=2, sticky="w") self.wg_icon_header_label = tk.Label( - self.wg_icon_header_frame, image=self.wg_icon_header, bg="#2c3e50" + self.wg_icon_header_frame, + image=self.image_manager.load_image("icon_header"), + bg="#2c3e50", ) self.wg_icon_header_label.grid(column=0, row=0, sticky="e", ipadx=10) @@ -345,7 +344,7 @@ class FrameWidgets(ttk.Frame): # Button Import self.btn_i = ttk.Button( self.control_buttons_frame, - image=self.imp_pic, + image=self.image_manager.load_image("icon_import"), command=self.import_sl, padding=0, ) @@ -356,7 +355,7 @@ class FrameWidgets(ttk.Frame): # Button Trash self.btn_tr = ttk.Button( self.control_buttons_frame, - image=self.tr_pic, + image=self.image_manager.load_image("icon_trash"), command=self.delete, padding=0, ) @@ -370,7 +369,7 @@ class FrameWidgets(ttk.Frame): # Button Export self.btn_exp = ttk.Button( self.control_buttons_frame, - image=self.exp_pic, + image=self.image_manager.load_image("icon_export"), command=lambda: Tunnel.export(), padding=0, ) @@ -560,7 +559,7 @@ class FrameWidgets(ttk.Frame): None, partial(webbrowser.open, "https://git.ilunix.de/punix/Wire-Py"), ], - icon=AppConfig.IMAGE_PATHS["icon_vpn"], + icon="/usr/share/icons/lx-icons/64/wg_vpn.png", wraplength=420, ) @@ -655,7 +654,7 @@ class FrameWidgets(ttk.Frame): """ self.btn_stst = ttk.Button( self.control_buttons_frame, - image=self.wg_vpn_start, + image=self.image_manager.load_image("icon_start"), command=lambda: self.wg_switch("start"), padding=0, ) @@ -694,7 +693,7 @@ class FrameWidgets(ttk.Frame): """ self.btn_stst = ttk.Button( self.control_buttons_frame, - image=self.wg_vpn_stop, + image=self.image_manager.load_image("icon_stop"), command=lambda: self.wg_switch("stop"), padding=0, ) diff --git a/wp_app_config.py b/wp_app_config.py index b4ff7ed..5cbd337 100755 --- a/wp_app_config.py +++ b/wp_app_config.py @@ -3,6 +3,8 @@ import logging import gettext import locale +import tkinter as tk +import os from pathlib import Path from subprocess import CompletedProcess, run from typing import Dict, Any @@ -79,21 +81,6 @@ class AppConfig: "pkey_path": "/usr/local/etc/ssl/pwgk.pem", } - # Images and icons paths - IMAGE_PATHS: Dict[str, Path] = { - "icon_header": "/usr/share/icons/lx-icons/32/wg_vpn.png", - "icon_vpn": "/usr/share/icons/lx-icons/48/wg_vpn.png", - "icon_msg": "/usr/share/icons/lx-icons/48/wg_msg.png", - "icon_import": "/usr/share/icons/lx-icons/48/wg_import.png", - "icon_export": "/usr/share/icons/lx-icons/48/wg_export.png", - "icon_trash": "/usr/share/icons/lx-icons/48/wg_trash.png", - "icon_start": "/usr/share/icons/lx-icons/48/wg_vpn-start.png", - "icon_stop": "/usr/share/icons/lx-icons/48/wg_vpn-stop.png", - "icon_info": "/usr/share/icons/lx-icons/64/info.png", - "icon_error": "/usr/share/icons/lx-icons/64/error.png", - "icon_log": "/usr/share/icons/lx-icons/48/log.png", - } - @staticmethod def setup_translations() -> gettext.gettext: """ @@ -171,6 +158,65 @@ class AppConfig: _ = AppConfig.setup_translations() +class Image: + def __init__(self): + self.images = {} + + def load_image(self, image_key, fallback_paths=None) -> None | tk.PhotoImage: + """Load PNG image using tk.PhotoImage with fallback options""" + if image_key in self.images: + return self.images[image_key] + + # Define image paths based on key + image_paths = { + "icon_header": [ + "/usr/share/icons/lx-icons/32/wg_vpn.png", + ], + "icon_vpn": [ + "/usr/share/icons/lx-icons/48/wg_vpn.png", + ], + "icon_start": [ + "/usr/share/icons/lx-icons/48/wg_vpn-start.png", + ], + "icon_stop": [ + "/usr/share/icons/lx-icons/48/wg_vpn-stop.png", + ], + "icon_import": [ + "/usr/share/icons/lx-icons/48/wg_import.png", + ], + "icon_export": [ + "/usr/share/icons/lx-icons/48/wg_export.png", + ], + "icon_log": [ + "/usr/share/icons/lx-icons/48/log.png", + ], + "icon_trash": [ + "/usr/share/icons/lx-icons/48/wg_trash.png", + ], + } + + # Get paths to try + paths_to_try = image_paths.get(image_key, []) + + # Add fallback paths if provided + if fallback_paths: + paths_to_try.extend(fallback_paths) + + # Try to load image from paths + for path in paths_to_try: + try: + if os.path.exists(path): + photo = tk.PhotoImage(file=path) + self.images[image_key] = photo + return photo + except tk.TclError as e: + # print(f"{LocaleStrings.MSGP["fail_load_image"]}{path}: {e}") + continue + + # Return None if no image found + return None + + class Msg: """ A utility class that provides centralized access to translated message strings.