add class Image for icon managment

This commit is contained in:
2025-06-28 00:32:49 +02:00
parent ddae246d46
commit 47aa3ac749
3 changed files with 83 additions and 36 deletions

View File

@ -19,6 +19,8 @@ My standard System: Linux Mint 22 Cinnamon
- ui works now better with rename button - ui works now better with rename button
- add Image class for manage Images
### Added ### Added
23-06-2025 23-06-2025

View File

@ -24,7 +24,7 @@ from shared_libs.common_tools import (
Tooltip, Tooltip,
) )
from wp_app_config import AppConfig, Msg from shared_libs.wp_app_config import AppConfig, Image, Msg
class Wirepy(tk.Tk): class Wirepy(tk.Tk):
@ -39,6 +39,7 @@ class Wirepy(tk.Tk):
self.withdraw() self.withdraw()
self.my_tool_tip = None self.my_tool_tip = None
self.x_width = AppConfig.UI_CONFIG["window_size"][0] self.x_width = AppConfig.UI_CONFIG["window_size"][0]
self.y_height = AppConfig.UI_CONFIG["window_size"][1] self.y_height = AppConfig.UI_CONFIG["window_size"][1]
@ -53,17 +54,19 @@ class Wirepy(tk.Tk):
AppConfig.UI_CONFIG["window_size"][1], AppConfig.UI_CONFIG["window_size"][1],
) )
self.title(AppConfig.UI_CONFIG["window_title"]) self.title(AppConfig.UI_CONFIG["window_title"])
self.image_manager = Image()
self.tk.call("source", f"{AppConfig.SYSTEM_PATHS['tcl_path']}/water.tcl") self.tk.call("source", f"{AppConfig.SYSTEM_PATHS['tcl_path']}/water.tcl")
ConfigManager.init(AppConfig.SETTINGS_FILE) ConfigManager.init(AppConfig.SETTINGS_FILE)
theme = ConfigManager.get("theme") theme = ConfigManager.get("theme")
ThemeManager.change_theme(self, theme) ThemeManager.change_theme(self, theme)
# Load the image file from the disk # Try to set icon
self.wg_icon = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_vpn"]) try:
icon = self.image_manager.load_image("icon_vpn")
# Set it as the window icon if icon:
self.iconphoto(True, self.wg_icon) self.iconphoto(True, icon)
except:
pass
# Add the widgets # Add the widgets
FrameWidgets(self).grid() FrameWidgets(self).grid()
@ -91,13 +94,7 @@ class FrameWidgets(ttk.Frame):
self.dns = None self.dns = None
self.address = None self.address = None
self.auto_con = None self.auto_con = None
self.wg_vpn_start = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_start"]) self.image_manager = Image()
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.columnconfigure(0, weight=1) self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1) self.rowconfigure(0, weight=1)
self.columnconfigure(1, 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_frame.grid(column=0, row=0, rowspan=2, sticky="w")
self.wg_icon_header_label = tk.Label( 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) self.wg_icon_header_label.grid(column=0, row=0, sticky="e", ipadx=10)
@ -345,7 +344,7 @@ class FrameWidgets(ttk.Frame):
# Button Import # Button Import
self.btn_i = ttk.Button( self.btn_i = ttk.Button(
self.control_buttons_frame, self.control_buttons_frame,
image=self.imp_pic, image=self.image_manager.load_image("icon_import"),
command=self.import_sl, command=self.import_sl,
padding=0, padding=0,
) )
@ -356,7 +355,7 @@ class FrameWidgets(ttk.Frame):
# Button Trash # Button Trash
self.btn_tr = ttk.Button( self.btn_tr = ttk.Button(
self.control_buttons_frame, self.control_buttons_frame,
image=self.tr_pic, image=self.image_manager.load_image("icon_trash"),
command=self.delete, command=self.delete,
padding=0, padding=0,
) )
@ -370,7 +369,7 @@ class FrameWidgets(ttk.Frame):
# Button Export # Button Export
self.btn_exp = ttk.Button( self.btn_exp = ttk.Button(
self.control_buttons_frame, self.control_buttons_frame,
image=self.exp_pic, image=self.image_manager.load_image("icon_export"),
command=lambda: Tunnel.export(), command=lambda: Tunnel.export(),
padding=0, padding=0,
) )
@ -560,7 +559,7 @@ class FrameWidgets(ttk.Frame):
None, None,
partial(webbrowser.open, "https://git.ilunix.de/punix/Wire-Py"), 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, wraplength=420,
) )
@ -655,7 +654,7 @@ class FrameWidgets(ttk.Frame):
""" """
self.btn_stst = ttk.Button( self.btn_stst = ttk.Button(
self.control_buttons_frame, self.control_buttons_frame,
image=self.wg_vpn_start, image=self.image_manager.load_image("icon_start"),
command=lambda: self.wg_switch("start"), command=lambda: self.wg_switch("start"),
padding=0, padding=0,
) )
@ -694,7 +693,7 @@ class FrameWidgets(ttk.Frame):
""" """
self.btn_stst = ttk.Button( self.btn_stst = ttk.Button(
self.control_buttons_frame, self.control_buttons_frame,
image=self.wg_vpn_stop, image=self.image_manager.load_image("icon_stop"),
command=lambda: self.wg_switch("stop"), command=lambda: self.wg_switch("stop"),
padding=0, padding=0,
) )

View File

@ -3,6 +3,8 @@
import logging import logging
import gettext import gettext
import locale import locale
import tkinter as tk
import os
from pathlib import Path from pathlib import Path
from subprocess import CompletedProcess, run from subprocess import CompletedProcess, run
from typing import Dict, Any from typing import Dict, Any
@ -79,21 +81,6 @@ class AppConfig:
"pkey_path": "/usr/local/etc/ssl/pwgk.pem", "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 @staticmethod
def setup_translations() -> gettext.gettext: def setup_translations() -> gettext.gettext:
""" """
@ -171,6 +158,65 @@ class AppConfig:
_ = AppConfig.setup_translations() _ = 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: class Msg:
""" """
A utility class that provides centralized access to translated message strings. A utility class that provides centralized access to translated message strings.