diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lxtools_installer.py b/lxtools_installer.py index 9477eab..77735e9 100755 --- a/lxtools_installer.py +++ b/lxtools_installer.py @@ -14,7 +14,7 @@ from manager import ( System, Image, AppManager, - Center, + LxTools, ) from network import NetworkChecker from message import MessageDialog @@ -620,7 +620,7 @@ class LXToolsGUI: self.root.geometry( f"{LXToolsAppConfig.WINDOW_WIDTH}x{LXToolsAppConfig.WINDOW_HEIGHT}+100+100" ) - Center.center_window_cross_platform( + LxTools.center_window_cross_platform( self.root, LXToolsAppConfig.WINDOW_WIDTH, LXToolsAppConfig.WINDOW_HEIGHT ) self.root.configure(bg=self.colors["bg"]) diff --git a/manager.py b/manager.py index 6448fa4..472343b 100644 --- a/manager.py +++ b/manager.py @@ -403,7 +403,7 @@ class AppManager: ) -class Center: +class LxTools: @staticmethod def center_window_cross_platform(window, width, height): """ diff --git a/message.py b/message.py index 342483b..b953563 100644 --- a/message.py +++ b/message.py @@ -2,155 +2,104 @@ import os from typing import List, Optional, Dict import tkinter as tk from tkinter import ttk -from manager import Center -""" -#################################################### -Attention! MessageDialog returns different values. -From 3 buttons with Cancel, Cancel and the Close (x) -None returns. otherwise always False. -#################################################### -Usage Examples -1. Basic Info Dialog -from tkinter import Tk - -root = Tk() -dialog = MessageDialog( - message_type="info", - text="This is an information message.", - buttons=["OK"], - master=root, -) -result = dialog.show() -print("User clicked OK:", result) - ------------------------------------------------------ -My Favorite Example, -for simply information message: - -MessageDialog(text="This is an information message.") -result = MessageDialog(text="This is an information message.").show() ------------------------------------------------------ -Explanation: if you need the return value e.g. in the vaiable result, -you need to add .show(). otherwise only if no root.mainloop z.b is used to test the window. -##################################################### - -2. Error Dialog with Custom Icon and Command -def on_cancel(): - print("User canceled the operation.") - -root = Tk() -result = MessageDialog( - message_type="error", - text="An error occurred during processing.", - buttons=["Retry", "Cancel"], - commands=[None, on_cancel], - icon="/path/to/custom/error_icon.png", - title="Critical Error" -).show() - -print("User clicked Retry:", result) - ------------------------------------------------------ -My Favorite Example, -for simply Error message: - -MessageDialog( - "error", - text="An error occurred during processing.", -).show() - -##################################################### - -3. Confirmation Dialog with Yes/No Buttons -def on_confirm(): - print("User confirmed the action.") - -root = Tk() -dialog = MessageDialog( - message_type="ask", - text="Are you sure you want to proceed?", - buttons=["Yes", "No"], - commands=[on_confirm, None], # Either use comando or work with the values True and False -) -result = dialog.show() -print("User confirmed:", result) ------------------------------------------------------ - -My Favorite Example, -for simply Question message: - -dialog = MessageDialog( - "ask", - text="Are you sure you want to proceed?", - buttons=["Yes", "No"] - ).show() -##################################################### - -4. Warning Dialog with Custom Title - -root = Tk() -dialog = MessageDialog( - message_type="warning", - text="This action cannot be undone.", - buttons=["Proceed", "Cancel"], - title="Warning: Irreversible Action" -) -result = dialog.show() -print("User proceeded:", result) ------------------------------------------------------ -And a special example for a "open link" button: -Be careful not to forget to import it into the script in which this dialog is used!!! -import webbrowser -from functools import partial - -dialog = MessageDialog( - "ask", - text="Are you sure you want to proceed?", - buttons=["Yes", "Go to Exapmle"], - commands=[ - None, # Default on "OK" - partial(webbrowser.open, "https://exapmle.com"), - ], - icon="/pathh/to/custom/icon.png", - title="Example", -).show() - - -In all dialogues, a font can also be specified as a tuple. With font=("ubuntu", 11) -and wraplength=300, the text is automatically wrapped. -""" +try: + from manager import LxTools +except (ModuleNotFoundError, NameError): + from shared_libs.common_tools import LxTools class MessageDialog: """ - A customizable message dialog window using tkinter. + A customizable message dialog window using tkinter for user interaction. This class creates modal dialogs for displaying information, warnings, errors, - or questions to the user. It supports multiple button configurations and custom - icons. The dialog is centered on the screen and handles user interactions. + or questions to the user. It supports multiple button configurations, custom + icons, keyboard navigation, and command binding. The dialog is centered on the + screen and handles user interactions with focus management and accessibility. Attributes: message_type (str): Type of message ("info", "error", "warning", "ask"). - text (str): Main message content. + text (str): Main message content to display. buttons (List[str]): List of button labels (e.g., ["OK", "Cancel"]). - result (bool): True if the user clicked a positive button (like "Yes" or "OK"), else False. - icons: Dictionary mapping message types to tkinter.PhotoImage objects. + result (bool or None): + - True for positive actions (Yes, OK) + - False for negative actions (No, Cancel) + - None if "Cancel" was clicked with ≥3 buttons + icons: Dictionary mapping message types to tkinter.PhotoImage objects Parameters: - message_type: Type of message dialog (default: "info"). - text: Message content to display. - buttons: List of button labels (default: ["OK"]). - master: Parent tkinter window (optional). - commands: List of callables for each button (default: [None]). - icon: Custom icon path (overrides default icons if provided). - title: Window title (default: derived from message_type). + message_type: Type of message dialog (default: "info") + text: Message content to display + buttons: List of button labels (default: ["OK"]) + master: Parent tkinter window (optional) + commands: List of callables for each button (default: [None]) + icon: Custom icon path (overrides default icons if provided) + title: Window title (default: derived from message_type) + font: Font tuple for text styling + wraplength: Text wrapping width in pixels Methods: _get_title(): Returns the default window title based on message type. _load_icons(): Loads icons from system paths or fallback locations. _on_button_click(button_text): Sets result and closes the dialog. - show(): Displays the dialog and waits for user response (returns self.result). + show(): Displays the dialog and waits for user response. + + Example Usage: + + 1. Basic Info Dialog: + >>> MessageDialog( + ... text="This is an information message.") + >>> result = dialog.show() + >>> print("User clicked OK:", result) + + Notes: + My Favorite Example, + for simply information message: + + >>> MessageDialog(text="This is an information message.") + >>> result = MessageDialog(text="This is an information message.").show() + + Example Usage: + + 2. Error Dialog with Custom Command: + >>> def on_retry(): + ... print("User selected Retry") + + >>> dialog = MessageDialog( + ... message_type="error", + ... text="An error occurred during processing.", + ... buttons=["Retry", "Cancel"], + ... commands=[on_retry, None], + ... title="Critical Error" + ... ) + >>> result = dialog.show() + >>> print("User selected Retry:", result) + + Example Usage: + + 3. And a special example for a "open link" button: + Be careful not to forget to import it into the script in which + this dialog is used!!! import webbrowser from functools import partial + + >>> MessageDialog( + ... "info" + ... text="This is an information message.", + ... buttons=["Yes", "Go to Exapmle"], + ... commands=[ + ... None, # Default on "OK" + ... partial(webbrowser.open, "https://exapmle.com"), + ... ], + ... icon="/pathh/to/custom/icon.png", + ... title="Example", + ... ) + + Notes: + - Returns None if "Cancel" was clicked with ≥3 buttons + - Supports keyboard navigation (Left/Right arrows and Enter) + - Dialog automatically centers on screen + - Result is False for window close (X) with 2 buttons + - Font and wraplength parameters enable text styling """ DEFAULT_ICON_PATH = "/usr/share/icons/lx-icons" @@ -254,7 +203,7 @@ class MessageDialog: self.window.attributes("-alpha", 0.0) # 100% Transparencence self.window.after(200, lambda: self.window.attributes("-alpha", 100.0)) self.window.update() # Window update before centering! - Center.center_window_cross_platform( + LxTools.center_window_cross_platform( self.window, self.window.winfo_width(), self.window.winfo_height() ) @@ -309,7 +258,8 @@ class MessageDialog: if os.path.exists(icon_paths[key]): self.icons[key] = tk.PhotoImage(file=icon_paths[key]) else: - self.icons[key] = tk.PhotoImage(file=fallback_paths[key]) + if os.path.exists(fallback_paths[key]): + self.icons[key] = tk.PhotoImage(file=fallback_paths[key]) except Exception as e: print(f"Error on load Icon '{[key]}': {e}") self.icons[key] = tk.PhotoImage()