17 Commits

Author SHA1 Message Date
f68b3291b3 write Changelog and fix imports all 2025-08-11 00:42:06 +02:00
f5768d2118 gui fix with self.columnconfigure(1, weight=0) in class MainFrame (row 36) 2025-08-11 00:15:23 +02:00
65271a50d7 animation for updater and update notify works 2025-08-10 22:48:26 +02:00
1b4d4ad815 fix ui size 2025-08-10 21:48:45 +02:00
052ed0a828 ui fixes expand widget on x and y works 2025-08-10 20:51:12 +02:00
8fcad26789 new icons added and replace old icons and updated tk-themes 2025-08-10 15:44:28 +02:00
fa0fb7ae31 german translate update2 2025-07-09 16:51:30 +02:00
c509fdbd18 german translate file updatet header more pady and listbox less pady 2025-07-09 16:23:42 +02:00
fd957d9742 update german translete file 2025-07-09 11:46:35 +02:00
4e1c3a8e9c updater replace Downloadbutton with Lx Tools installer 2025-07-09 08:31:26 +02:00
7b8ec10e6c updater replace Downloadbutton with Lx Tools installer 2025-07-02 23:25:57 +02:00
47aa3ac749 add class Image for icon managment 2025-06-28 00:32:49 +02:00
ddae246d46 ui works now better with rename button 2025-06-27 23:09:21 +02:00
c8d439d428 part one of new modern design 2025-06-27 19:28:18 +02:00
2463d63c12 part one moden UI and reorganized Frames and Labels 2025-06-27 19:28:08 +02:00
70d973e9d7 all msg_window with MassageDialog replaced 2025-06-24 15:02:19 +02:00
54b62fd5d5 all msg_window with MassageDialog replaced 2025-06-23 07:44:16 +02:00
150 changed files with 3317 additions and 2287 deletions

View File

@@ -6,8 +6,62 @@ My standard System: Linux Mint 22 Cinnamon
- os import in common_tools.py replaced by other methods - os import in common_tools.py replaced by other methods
- If Wire-Py already runs, prevent further start - If Wire-Py already runs, prevent further start
- for loops with lists replaced by List Comprehensions - for loops with lists replaced by List Comprehensions
- Tunnel in tk.canvas for modern look
- Replace Download Button with Lx Tools installer ### Added
10.08.2025
- Wirepy divided into several scripts for better overview and maintenance
- Own file dialogue is now used to open Wireguard files for the import.
- New update notification. A canvas ring flashes when updates are available
- UI size change now grow all widgets with.
- Update Search at start of the app now starts in a thread to not stop the GUI
- Logviewer replaces with new button in the menu bar,
a new window opens in which the necessary infos stand when errors occur.
### Added
01.08.2025
- Replace Imagemanager with IconManager and remove ImageManager from wp_app_config.py
- Logging improved
### Added
02-07-2025
- Complete code for faulty f" string configuration dur addicted and fixed
- updater replace Downloadbutton with Lx Tools installer
- remove logviewer icon
- add settings.png icon for update button
### Added
27-06-2025
- Header added for more modern desing
- Sizes adjust the frames and labels improve
- More modern desing for listbox, Address, Dns and Endpoint
- ui works now better with rename button
- add Image class for manage Images
### Added
23-06-2025
- all msg_window with MassageDialog replaced
### Added ### Added
14-06-2025 14-06-2025

View File

@@ -1,6 +1,10 @@
# Copyright (c) 2021 rdbende <rdbende@gmail.com> # Copyright (c) 2021 rdbende <rdbende@gmail.com>
# inspired by rdbende modified azure to water by Désire Werner Menrath polunga40@unity-mail.de 2024 # inspired by rdbende modified azure to water by Désire Werner Menrath polunga40@unity-mail.de 2024
# Update add New Style TButton.Borderless for Buttons without edge and without rounded corners by
# Désire Werner Menrath 28-07-2025
# Add Update Progressbars Round ends on Horizontal and Vertikal + add small bars
# Désire Werner Menrath 30-07-2025
package require Tk 8.6 package require Tk 8.6
@@ -117,6 +121,14 @@ namespace eval ttk::theme::water-dark {
} }
} }
ttk::style layout TEntry {
Combobox.field -sticky nswe -children {
Combobox.padding -expand true -sticky nswe -children {
Combobox.textarea -sticky nswe
}
}
}
ttk::style layout TCombobox { ttk::style layout TCombobox {
Combobox.field -sticky nswe -children { Combobox.field -sticky nswe -children {
Combobox.padding -expand true -sticky nswe -children { Combobox.padding -expand true -sticky nswe -children {
@@ -199,15 +211,23 @@ namespace eval ttk::theme::water-dark {
# Button # Button
ttk::style configure TButton -padding {8 4 8 4} -width -10 -anchor center ttk::style configure TButton -padding {8 4 8 4} -width -10 -anchor center
ttk::style element create Button.button image \ ttk::style element create Button.button image [list $I(box-basic) {selected disabled} $I(box-basic) disabled $I(box-basic) pressed $I(box-basic) selected $I(box-basic) active $I(button-hover) focus $I(box-basic) ] -border 4 -sticky ewns
[list $I(box-basic) \
{selected disabled} $I(box-basic) \ # Borderless Button
disabled $I(box-basic) \ ttk::style configure TButton.Borderless -padding 0 -width -10 -anchor center
pressed $I(box-basic) \ ttk::style element create BorderlessButton.button image \
selected $I(box-basic) \ [list $I(empty) \
active $I(button-hover) \ active $I(button-borderless-hover) \
focus $I(button-hover) \ pressed $I(button-borderless-hover) \
] -border 4 -sticky ewns focus $I(button-borderless-hover) \
] -border 0 -sticky ewns
ttk::style layout TButton.Borderless {
BorderlessButton.button -children {
Button.padding -children {
Button.label -side left -expand true
}
}
}
# Toolbutton # Toolbutton
ttk::style configure Toolbutton -padding {8 4 8 4} -width -5 -anchor center ttk::style configure Toolbutton -padding {8 4 8 4} -width -5 -anchor center
@@ -221,6 +241,24 @@ namespace eval ttk::theme::water-dark {
active $I(rect-basic) \ active $I(rect-basic) \
] -border 4 -sticky ewns ] -border 4 -sticky ewns
# TButton Borderless Round
ttk::style configure TButton.Borderless.Round -padding 0 -width -10 -anchor center
ttk::style element create TButton.Borderless.Round.button image \
[list $I(empty) \
{selected disabled} $I(empty) \
disabled $I(empty) \
selected $I(rect-basic) \
pressed $I(rect-basic) \
active $I(rect-basic) \
] -border 4 -sticky ewns
ttk::style layout TButton.Borderless.Round {
TButton.Borderless.Round.button -children {
Button.padding -children {
Button.label -side left -expand true
}
}
}
# Menubutton # Menubutton
ttk::style configure TMenubutton -padding {8 4 4 4} ttk::style configure TMenubutton -padding {8 4 4 4}
@@ -265,7 +303,7 @@ namespace eval ttk::theme::water-dark {
pressed $I(rect-accent) \ pressed $I(rect-accent) \
selected $I(rect-accent) \ selected $I(rect-accent) \
active $I(rect-accent-hover) \ active $I(rect-accent-hover) \
focus $I(rect-accent-hover) \ focus $I(rect-accent) \
] -border 4 -sticky ewns ] -border 4 -sticky ewns
# Checkbutton # Checkbutton
@@ -394,17 +432,52 @@ namespace eval ttk::theme::water-dark {
] -sticky {} ] -sticky {}
# Progressbar # Progressbar
ttk::style element create Horizontal.Progressbar.trough image $I(hor-basic) \ ttk::style layout Horizontal.TProgressbar {
-sticky ew Horizontal.Progressbar.trough -children {
Horizontal.Progressbar.pbar
}
}
ttk::style layout Vertical.TProgressbar {
Vertical.Progressbar.trough -children {
Vertical.Progressbar.pbar
}
}
ttk::style element create Horizontal.Progressbar.pbar image $I(hor-accent) \ ttk::style element create Horizontal.Progressbar.trough image $I(hor-trough) \
-sticky ew -border 3 -padding 0 -sticky ew
ttk::style element create Vertical.Progressbar.trough image $I(vert-basic) \ ttk::style element create Horizontal.Progressbar.pbar image $I(hor-pbar) \
-sticky ns -border 3 -padding 0 -sticky ew
ttk::style element create Vertical.Progressbar.pbar image $I(vert-accent) \ ttk::style element create Vertical.Progressbar.trough image $I(vert-trough) \
-sticky ns -border 3 -padding 0 -sticky ns
ttk::style element create Vertical.Progressbar.pbar image $I(vert-pbar) \
-border 3 -padding 0 -sticky ns
# Small Progressbar
ttk::style layout Small.Horizontal.TProgressbar {
Small.Horizontal.Progressbar.trough -children {
Small.Horizontal.Progressbar.pbar
}
}
ttk::style layout Small.Vertical.TProgressbar {
Small.Vertical.Progressbar.trough -children {
Small.Vertical.Progressbar.pbar
}
}
ttk::style element create Small.Horizontal.Progressbar.trough image $I(hor-trough-small) \
-border 1 -padding 0 -sticky ew
ttk::style element create Small.Horizontal.Progressbar.pbar image $I(hor-pbar-small) \
-border 1 -padding 0 -sticky ew
ttk::style element create Small.Vertical.Progressbar.trough image $I(vert-trough-small) \
-border 1 -padding 0 -sticky ns
ttk::style element create Small.Vertical.Progressbar.pbar image $I(vert-pbar-small) \
-border 1 -padding 0 -sticky ns
# Entry # Entry
ttk::style element create Entry.field \ ttk::style element create Entry.field \
@@ -532,8 +605,17 @@ namespace eval ttk::theme::water-dark {
-background [list selected $colors(-selectbg)] \ -background [list selected $colors(-selectbg)] \
-foreground [list selected $colors(-selectfg)] -foreground [list selected $colors(-selectfg)]
ttk::style configure TEntry -foreground $colors(-fg) -fieldbackground $colors(-bg)
ttk::style map TLabelframe -foreground [list disabled $colors(-disabledfg)]
ttk::style map TLabel -foreground [list disabled $colors(-disabledfg)]
ttk::style map TButton -foreground [list disabled $colors(-disabledfg)]
ttk::style map TCheckbutton -foreground [list disabled $colors(-disabledfg)]
ttk::style map TRadiobutton -foreground [list disabled $colors(-disabledfg)]
ttk::style map TEntry -foreground [list disabled $colors(-disabledfg)] -fieldbackground [list disabled $colors(-disabledbg) readonly $colors(-disabledbg)]
# Panedwindow # Panedwindow
# Insane hack to remove clam's ugly sash # Insane hack to remove clam's ugly sash
ttk::style configure Sash -gripcount 0 ttk::style configure Sash -gripcount 0
ttk::style configure TPanedwindow -padding 0
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 346 B

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 B

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 B

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 286 B

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

View File

@@ -1,6 +1,10 @@
# Copyright (c) 2021 rdbende <rdbende@gmail.com> # Copyright (c) 2021 rdbende <rdbende@gmail.com>
# inspired by rdbende modified azure to water by Désire Werner Menrath polunga40@unity-mail.de 2024 # inspired by rdbende modified azure to water by Désire Werner Menrath polunga40@unity-mail.de 2024
# Update add New Style TButton.Borderless for Buttons without edge and without rounded corners by
# Désire Werner Menrath 28-07-2025
# Add Update Progressbars Round ends on Horizontal and Vertikal + add small bars
# Désire Werner Menrath 30-07-2025
package require Tk 8.6 package require Tk 8.6
@@ -23,7 +27,7 @@ namespace eval ttk::theme::water-light {
-fg "#000000" -fg "#000000"
-bg "#ffffff" -bg "#ffffff"
-disabledfg "#737373" -disabledfg "#737373"
-disabledbg "#ffffff" -disabledbg "#f0f0f0"
-selectfg "#ffffff" -selectfg "#ffffff"
-selectbg "#007fff" -selectbg "#007fff"
} }
@@ -44,6 +48,7 @@ namespace eval ttk::theme::water-light {
} }
} }
ttk::style layout TMenubutton { ttk::style layout TMenubutton {
Menubutton.button -children { Menubutton.button -children {
Menubutton.padding -children { Menubutton.padding -children {
@@ -117,6 +122,14 @@ namespace eval ttk::theme::water-light {
} }
} }
ttk::style layout TEntry {
Combobox.field -sticky nswe -children {
Combobox.padding -expand true -sticky nswe -children {
Combobox.textarea -sticky nswe
}
}
}
ttk::style layout TCombobox { ttk::style layout TCombobox {
Combobox.field -sticky nswe -children { Combobox.field -sticky nswe -children {
Combobox.padding -expand true -sticky nswe -children { Combobox.padding -expand true -sticky nswe -children {
@@ -199,15 +212,23 @@ namespace eval ttk::theme::water-light {
# Button # Button
ttk::style configure TButton -padding {8 4 8 4} -width -10 -anchor center ttk::style configure TButton -padding {8 4 8 4} -width -10 -anchor center
ttk::style element create Button.button image \ ttk::style element create Button.button image [list $I(box-basic) {selected disabled} $I(box-basic) disabled $I(box-basic) selected $I(box-basic) pressed $I(box-basic) active $I(button-hover) focus $I(box-basic) ] -border 4 -sticky ewns
[list $I(box-basic) \
{selected disabled} $I(box-basic) \ # Borderless Button
disabled $I(box-basic) \ ttk::style configure TButton.Borderless -padding 0 -width -10 -anchor center
selected $I(box-basic) \ ttk::style element create BorderlessButton.button image \
pressed $I(box-basic) \ [list $I(empty) \
active $I(button-hover) \ active $I(button-borderless-hover) \
focus $I(button-hover) \ pressed $I(button-borderless-hover) \
] -border 4 -sticky ewns focus $I(button-borderless-hover) \
] -border 0 -sticky ewns
ttk::style layout TButton.Borderless {
BorderlessButton.button -children {
Button.padding -children {
Button.label -side left -expand true
}
}
}
# Toolbutton # Toolbutton
ttk::style configure Toolbutton -padding {8 4 8 4} -width -5 -anchor center ttk::style configure Toolbutton -padding {8 4 8 4} -width -5 -anchor center
@@ -221,6 +242,25 @@ namespace eval ttk::theme::water-light {
active $I(rect-basic) \ active $I(rect-basic) \
] -border 4 -sticky ewns ] -border 4 -sticky ewns
# TButton Borderless Round
ttk::style configure TButton.Borderless.Round -padding 0 -width -10 -anchor center
ttk::style element create TButton.Borderless.Round.button image \
[list $I(empty) \
{selected disabled} $I(empty) \
disabled $I(empty) \
selected $I(rect-basic) \
pressed $I(rect-basic) \
active $I(rect-basic) \
] -border 4 -sticky ewns
ttk::style layout TButton.Borderless.Round {
TButton.Borderless.Round.button -children {
Button.padding -children {
Button.label -side left -expand true
}
}
}
# Menubutton # Menubutton
ttk::style configure TMenubutton -padding {8 4 4 4} ttk::style configure TMenubutton -padding {8 4 4 4}
@@ -265,7 +305,7 @@ namespace eval ttk::theme::water-light {
selected $I(rect-accent) \ selected $I(rect-accent) \
pressed $I(rect-accent) \ pressed $I(rect-accent) \
active $I(rect-accent-hover) \ active $I(rect-accent-hover) \
focus $I(rect-accent-hover) \ focus $I(rect-accent) \
] -border 4 -sticky ewns ] -border 4 -sticky ewns
# Checkbutton # Checkbutton
@@ -394,17 +434,52 @@ namespace eval ttk::theme::water-light {
] -sticky {} ] -sticky {}
# Progressbar # Progressbar
ttk::style element create Horizontal.Progressbar.trough image $I(hor-basic) \ ttk::style layout Horizontal.TProgressbar {
-sticky ew Horizontal.Progressbar.trough -children {
Horizontal.Progressbar.pbar
}
}
ttk::style layout Vertical.TProgressbar {
Vertical.Progressbar.trough -children {
Vertical.Progressbar.pbar
}
}
ttk::style element create Horizontal.Progressbar.pbar image $I(hor-accent) \ ttk::style element create Horizontal.Progressbar.trough image $I(hor-trough) \
-sticky ew -border 3 -padding 0 -sticky ew
ttk::style element create Vertical.Progressbar.trough image $I(vert-basic) \ ttk::style element create Horizontal.Progressbar.pbar image $I(hor-pbar) \
-sticky ns -border 3 -padding 0 -sticky ew
ttk::style element create Vertical.Progressbar.pbar image $I(vert-accent) \ ttk::style element create Vertical.Progressbar.trough image $I(vert-trough) \
-sticky ns -border 3 -padding 0 -sticky ns
ttk::style element create Vertical.Progressbar.pbar image $I(vert-pbar) \
-border 3 -padding 0 -sticky ns
# Small Progressbar
ttk::style layout Small.Horizontal.TProgressbar {
Small.Horizontal.Progressbar.trough -children {
Small.Horizontal.Progressbar.pbar
}
}
ttk::style layout Small.Vertical.TProgressbar {
Small.Vertical.Progressbar.trough -children {
Small.Vertical.Progressbar.pbar
}
}
ttk::style element create Small.Horizontal.Progressbar.trough image $I(hor-trough-small) \
-border 1 -padding 0 -sticky ew
ttk::style element create Small.Horizontal.Progressbar.pbar image $I(hor-pbar-small) \
-border 1 -padding 0 -sticky ew
ttk::style element create Small.Vertical.Progressbar.trough image $I(vert-trough-small) \
-border 1 -padding 0 -sticky ns
ttk::style element create Small.Vertical.Progressbar.pbar image $I(vert-pbar-small) \
-border 1 -padding 0 -sticky ns
# Entry # Entry
ttk::style element create Entry.field \ ttk::style element create Entry.field \
@@ -448,7 +523,7 @@ namespace eval ttk::theme::water-light {
image [list $I(combo-button-basic) \ image [list $I(combo-button-basic) \
{!readonly focus} $I(combo-button-focus) \ {!readonly focus} $I(combo-button-focus) \
{readonly focus} $I(combo-button-hover) \ {readonly focus} $I(combo-button-hover) \
{readonly hover} $I(combo-button-hover) {readonly hover} $I(combo-button-hover)\
] -border 5 -padding {2 6 6 6} ] -border 5 -padding {2 6 6 6}
ttk::style element create Combobox.arrow image $I(down) \ ttk::style element create Combobox.arrow image $I(down) \
@@ -481,7 +556,7 @@ namespace eval ttk::theme::water-light {
image [list $I(combo-button-basic) \ image [list $I(combo-button-basic) \
{!readonly focus} $I(combo-button-focus) \ {!readonly focus} $I(combo-button-focus) \
{readonly focus} $I(combo-button-hover) \ {readonly focus} $I(combo-button-hover) \
{readonly hover} $I(combo-button-hover) {readonly hover} $I(combo-button-hover)\
] -border 5 -padding {2 6 6 6} ] -border 5 -padding {2 6 6 6}
# Sizegrip # Sizegrip
@@ -517,7 +592,7 @@ namespace eval ttk::theme::water-light {
ttk::style element create Treeheading.cell \ ttk::style element create Treeheading.cell \
image [list $I(tree-basic) \ image [list $I(tree-basic) \
pressed $I(tree-pressed) pressed $I(tree-pressed)\
] -border 5 -padding 4 -sticky ewns ] -border 5 -padding 4 -sticky ewns
ttk::style element create Treeitem.indicator \ ttk::style element create Treeitem.indicator \
@@ -532,8 +607,17 @@ namespace eval ttk::theme::water-light {
-background [list selected #ccc] \ -background [list selected #ccc] \
-foreground [list selected $colors(-fg)] -foreground [list selected $colors(-fg)]
ttk::style map TLabelframe -foreground [list disabled $colors(-disabledfg)]
ttk::style map TLabel -foreground [list disabled $colors(-disabledfg)]
ttk::style map TButton -foreground [list disabled $colors(-disabledfg)]
ttk::style map TCheckbutton -foreground [list disabled $colors(-disabledfg)]
ttk::style map TRadiobutton -foreground [list disabled $colors(-disabledfg)]
ttk::style map TEntry -foreground [list disabled $colors(-disabledfg)] -fieldbackground [list disabled $colors(-disabledbg) readonly $colors(-disabledbg)]
ttk::style configure TEntry -foreground $colors(-fg) -fieldbackground $colors(-bg)
# Panedwindow # Panedwindow
# Insane hack to remove clam's ugly sash # Insane hack to remove clam's ugly sash
ttk::style configure Sash -gripcount 0 ttk::style configure Sash -gripcount 0
ttk::style configure TPanedwindow -padding 0
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 247 B

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 B

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 B

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 263 B

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

View File

@@ -1,5 +1,10 @@
# Copyright © 2021 rdbende <rdbende@gmail.com> # Copyright © 2021 rdbende <rdbende@gmail.com>
# inspired by rdbende modified azure to water by Désire Werner Menrath polunga40@unity-mail.de 2024 # inspired by rdbende modified azure to water by Désire Werner Menrath polunga40@unity-mail.de 2024
# Update add New Style TButton.Borderless for Buttons without edge and without rounded corners by
# Désire Werner Menrath 28-07-2025
# Add Update Progressbars Round ends on Horizontal and Vertikal + add small bars
# Désire Werner Menrath 30-07-2025
source [file join [file dirname [info script]] theme light.tcl] source [file join [file dirname [info script]] theme light.tcl]
source [file join [file dirname [info script]] theme dark.tcl] source [file join [file dirname [info script]] theme dark.tcl]
@@ -13,7 +18,7 @@ proc set_theme {mode} {
array set colors { array set colors {
-fg "#ffffff" -fg "#ffffff"
-bg "#333333" -bg "#333333"
-disabledfg "#ffffff" -disabledfg "#aaaaaa"
-disabledbg "#737373" -disabledbg "#737373"
-selectfg "#000000" -selectfg "#000000"
-selectbg "#00c4ff" -selectbg "#00c4ff"
@@ -53,7 +58,7 @@ proc set_theme {mode} {
-fg "#000000" -fg "#000000"
-bg "#ffffff" -bg "#ffffff"
-disabledfg "#737373" -disabledfg "#737373"
-disabledbg "#ffffff" -disabledbg "#f0f0f0"
-selectfg "#000000" -selectfg "#000000"
-selectbg "#00c4ff" -selectbg "#00c4ff"
} }

970
animated_icon.py Normal file
View File

@@ -0,0 +1,970 @@
"""
A Tkinter widget for displaying animated icons.
This module provides the AnimatedIcon class, a custom Tkinter Canvas widget
that can display various types of animations. It supports both native Tkinter
drawing and Pillow (PIL) for anti-aliased graphics if available.
"""
import tkinter as tk
from math import sin, cos, pi
from typing import Tuple, Optional
try:
from PIL import Image, ImageDraw, ImageTk
PIL_AVAILABLE = True
except ImportError:
PIL_AVAILABLE = False
def _hex_to_rgb(hex_color: str) -> Tuple[int, int, int]:
"""Converts a hex color string to an RGB tuple."""
hex_color = hex_color.lstrip('#')
return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
class AnimatedIcon(tk.Canvas):
"""A custom Tkinter Canvas widget for displaying animations."""
def __init__(self, master: tk.Misc, width: int = 20, height: int = 20, animation_type: str = "counter_arc", color: str = "#2a6fde", highlight_color: str = "#5195ff", use_pillow: bool = False, bg: Optional[str] = None) -> None:
"""
Initializes the AnimatedIcon widget.
Args:
master: The parent widget.
width (int): The width of the icon.
height (int): The height of the icon.
animation_type (str): The type of animation to display.
Options: "counter_arc", "double_arc", "line", "blink".
color (str): The primary color of the icon.
highlight_color (str): The highlight color of the icon.
use_pillow (bool): Whether to use Pillow for drawing if available.
bg (str): The background color of the canvas.
"""
if bg is None:
try:
bg = master.cget("background")
except tk.TclError:
bg = "#f0f0f0" # Fallback color
super().__init__(master, width=width, height=height, bg=bg, highlightthickness=0)
self.width = width
self.height = height
self.animation_type = animation_type
self.color = color
self.highlight_color = highlight_color
self.use_pillow = use_pillow and PIL_AVAILABLE
self.running = False
self.angle = 0
self.pulse_animation = False
self.color_rgb = _hex_to_rgb(self.color)
self.highlight_color_rgb = _hex_to_rgb(self.highlight_color)
if self.use_pillow:
self.image = Image.new(
"RGBA", (width * 4, height * 4), (0, 0, 0, 0))
self.draw = ImageDraw.Draw(self.image)
self.photo_image = None
def _draw_frame(self) -> None:
"""Draws a single frame of the animation."""
if self.use_pillow:
self._draw_pillow_frame()
else:
self._draw_canvas_frame()
def _draw_canvas_frame(self) -> None:
"""Draws a frame using native Tkinter canvas methods."""
self.delete("all")
if self.pulse_animation:
self._draw_canvas_pulse()
elif self.animation_type == "line":
self._draw_canvas_line()
elif self.animation_type == "double_arc":
self._draw_canvas_double_arc()
elif self.animation_type == "counter_arc":
self._draw_canvas_counter_arc()
elif self.animation_type == "blink":
self._draw_canvas_blink()
def _draw_canvas_pulse(self) -> None:
"""Draws the pulse animation using canvas methods."""
center_x, center_y = self.width / 2, self.height / 2
alpha = (sin(self.angle * 5) + 1) / 2 # Faster pulse
r = int(
alpha * (self.highlight_color_rgb[0] - self.color_rgb[0]) + self.color_rgb[0])
g = int(
alpha * (self.highlight_color_rgb[1] - self.color_rgb[1]) + self.color_rgb[1])
b = int(
alpha * (self.highlight_color_rgb[2] - self.color_rgb[2]) + self.color_rgb[2])
pulse_color = f"#{r:02x}{g:02x}{b:02x}"
if self.animation_type == "line":
for i in range(8):
angle = i * (pi / 4)
start_x = center_x + cos(angle) * (self.width * 0.2)
start_y = center_y + sin(angle) * (self.height * 0.2)
end_x = center_x + cos(angle) * (self.width * 0.4)
end_y = center_y + sin(angle) * (self.height * 0.4)
self.create_line(start_x, start_y, end_x,
end_y, fill=pulse_color, width=2)
elif self.animation_type == "double_arc":
radius = min(center_x, center_y) * 0.8
bbox = (center_x - radius, center_y - radius,
center_x + radius, center_y + radius)
self.create_arc(bbox, start=0, extent=359.9,
style=tk.ARC, outline=pulse_color, width=2)
elif self.animation_type == "counter_arc":
radius_outer = min(center_x, center_y) * 0.8
bbox_outer = (center_x - radius_outer, center_y - radius_outer,
center_x + radius_outer, center_y + radius_outer)
self.create_arc(bbox_outer, start=0, extent=359.9,
style=tk.ARC, outline=pulse_color, width=2)
radius_inner = min(center_x, center_y) * 0.6
bbox_inner = (center_x - radius_inner, center_y - radius_inner,
center_x + radius_inner, center_y + radius_inner)
self.create_arc(bbox_inner, start=0, extent=359.9,
style=tk.ARC, outline=self.color, width=2)
def _draw_canvas_line(self) -> None:
"""Draws the line animation using canvas methods."""
center_x, center_y = self.width / 2, self.height / 2
for i in range(8):
angle = self.angle + i * (pi / 4)
start_x = center_x + cos(angle) * (self.width * 0.2)
start_y = center_y + sin(angle) * (self.height * 0.2)
end_x = center_x + cos(angle) * (self.width * 0.4)
end_y = center_y + sin(angle) * (self.height * 0.4)
alpha = (cos(self.angle * 2 + i * (pi / 4)) + 1) / 2
r = int(
alpha * (self.highlight_color_rgb[0] - self.color_rgb[0]) + self.color_rgb[0])
g = int(
alpha * (self.highlight_color_rgb[1] - self.color_rgb[1]) + self.color_rgb[1])
b = int(
alpha * (self.highlight_color_rgb[2] - self.color_rgb[2]) + self.color_rgb[2])
color = f"#{r:02x}{g:02x}{b:02x}"
self.create_line(start_x, start_y, end_x,
end_y, fill=color, width=2)
def _draw_canvas_double_arc(self) -> None:
"""Draws the double arc animation using canvas methods."""
center_x, center_y = self.width / 2, self.height / 2
radius = min(center_x, center_y) * 0.8
bbox = (center_x - radius, center_y - radius,
center_x + radius, center_y + radius)
start_angle1 = -self.angle * 180 / pi
extent1 = 120 + 60 * sin(-self.angle)
self.create_arc(bbox, start=start_angle1, extent=extent1,
style=tk.ARC, outline=self.highlight_color, width=2)
start_angle2 = (-self.angle + pi) * 180 / pi
extent2 = 120 + 60 * sin(-self.angle + pi / 2)
self.create_arc(bbox, start=start_angle2, extent=extent2,
style=tk.ARC, outline=self.color, width=2)
def _draw_canvas_counter_arc(self) -> None:
"""Draws the counter arc animation using canvas methods."""
center_x, center_y = self.width / 2, self.height / 2
radius_outer = min(center_x, center_y) * 0.8
bbox_outer = (center_x - radius_outer, center_y - radius_outer,
center_x + radius_outer, center_y + radius_outer)
start_angle1 = -self.angle * 180 / pi
self.create_arc(bbox_outer, start=start_angle1, extent=150,
style=tk.ARC, outline=self.highlight_color, width=2)
radius_inner = min(center_x, center_y) * 0.6
bbox_inner = (center_x - radius_inner, center_y - radius_inner,
center_x + radius_inner, center_y + radius_inner)
start_angle2 = self.angle * 180 / pi + 60
self.create_arc(bbox_inner, start=start_angle2, extent=150,
style=tk.ARC, outline=self.color, width=2)
def _draw_canvas_blink(self) -> None:
"""Draws the blink animation using canvas methods."""
center_x, center_y = self.width / 2, self.height / 2
radius = min(center_x, center_y) * 0.8
alpha = (sin(self.angle * 2) + 1) / 2 # Slower blinking speed
r = int(
alpha * (self.highlight_color_rgb[0] - self.color_rgb[0]) + self.color_rgb[0])
g = int(
alpha * (self.highlight_color_rgb[1] - self.color_rgb[1]) + self.color_rgb[1])
b = int(
alpha * (self.highlight_color_rgb[2] - self.color_rgb[2]) + self.color_rgb[2])
blink_color = f"#{r:02x}{g:02x}{b:02x}"
self.create_arc(center_x - radius, center_y - radius, center_x + radius, center_y +
radius, start=0, extent=359.9, style=tk.ARC, outline=blink_color, width=4)
def _draw_pillow_frame(self) -> None:
"""Draws a frame using Pillow for anti-aliased graphics."""
self.draw.rectangle(
[0, 0, self.width * 4, self.height * 4], fill=(0, 0, 0, 0))
if self.pulse_animation:
self._draw_pillow_pulse()
elif self.animation_type == "line":
self._draw_pillow_line()
elif self.animation_type == "double_arc":
self._draw_pillow_double_arc()
elif self.animation_type == "counter_arc":
self._draw_pillow_counter_arc()
elif self.animation_type == "blink":
self._draw_pillow_blink()
resized_image = self.image.resize(
(self.width, self.height), Image.Resampling.LANCZOS)
self.photo_image = ImageTk.PhotoImage(resized_image)
self.delete("all")
self.create_image(0, 0, anchor="nw", image=self.photo_image)
def _draw_pillow_pulse(self) -> None:
"""Draws the pulse animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
alpha = (sin(self.angle * 5) + 1) / 2 # Faster pulse
r = int(
alpha * (self.highlight_color_rgb[0] - self.color_rgb[0]) + self.color_rgb[0])
g = int(
alpha * (self.highlight_color_rgb[1] - self.color_rgb[1]) + self.color_rgb[1])
b = int(
alpha * (self.highlight_color_rgb[2] - self.color_rgb[2]) + self.color_rgb[2])
pulse_color = (r, g, b)
if self.animation_type == "line":
for i in range(12):
angle = i * (pi / 6)
start_x = center_x + cos(angle) * (self.width * 0.8)
start_y = center_y + sin(angle) * (self.height * 0.8)
end_x = center_x + cos(angle) * (self.width * 1.6)
end_y = center_y + sin(angle) * (self.height * 1.6)
self.draw.line([(start_x, start_y), (end_x, end_y)],
fill=pulse_color, width=6, joint="curve")
elif self.animation_type == "double_arc":
radius = min(center_x, center_y) * 0.8
bbox = (center_x - radius, center_y - radius,
center_x + radius, center_y + radius)
self.draw.arc(bbox, start=0, end=360, fill=pulse_color, width=5)
elif self.animation_type == "counter_arc":
radius_outer = min(center_x, center_y) * 0.8
bbox_outer = (center_x - radius_outer, center_y - radius_outer,
center_x + radius_outer, center_y + radius_outer)
self.draw.arc(bbox_outer, start=0, end=360,
fill=pulse_color, width=7)
radius_inner = min(center_x, center_y) * 0.6
bbox_inner = (center_x - radius_inner, center_y - radius_inner,
center_x + radius_inner, center_y + radius_inner)
self.draw.arc(bbox_inner, start=0, end=360,
fill=self.color_rgb, width=7)
def _draw_pillow_line(self) -> None:
"""Draws the line animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
for i in range(12):
angle = self.angle + i * (pi / 6)
start_x = center_x + cos(angle) * (self.width * 0.8)
start_y = center_y + sin(angle) * (self.height * 0.8)
end_x = center_x + cos(angle) * (self.width * 1.6)
end_y = center_y + sin(angle) * (self.height * 1.6)
alpha = (cos(self.angle * 2.5 + i * (pi / 6)) + 1) / 2
r = int(
alpha * (self.highlight_color_rgb[0] - self.color_rgb[0]) + self.color_rgb[0])
g = int(
alpha * (self.highlight_color_rgb[1] - self.color_rgb[1]) + self.color_rgb[1])
b = int(
alpha * (self.highlight_color_rgb[2] - self.color_rgb[2]) + self.color_rgb[2])
color = (r, g, b)
self.draw.line([(start_x, start_y), (end_x, end_y)],
fill=color, width=6, joint="curve")
def _draw_pillow_double_arc(self) -> None:
"""Draws the double arc animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
radius = min(center_x, center_y) * 0.8
bbox = (center_x - radius, center_y - radius,
center_x + radius, center_y + radius)
start_angle1 = self.angle * 180 / pi
extent1 = 120 + 60 * sin(self.angle)
self.draw.arc(bbox, start=start_angle1, end=start_angle1 +
extent1, fill=self.highlight_color_rgb, width=5)
start_angle2 = (self.angle + pi) * 180 / pi
extent2 = 120 + 60 * sin(self.angle + pi / 2)
self.draw.arc(bbox, start=start_angle2, end=start_angle2 +
extent2, fill=self.color_rgb, width=5)
def _draw_pillow_counter_arc(self) -> None:
"""Draws the counter arc animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
radius_outer = min(center_x, center_y) * 0.8
bbox_outer = (center_x - radius_outer, center_y - radius_outer,
center_x + radius_outer, center_y + radius_outer)
start_angle1 = self.angle * 180 / pi
self.draw.arc(bbox_outer, start=start_angle1, end=start_angle1 +
150, fill=self.highlight_color_rgb, width=7)
radius_inner = min(center_x, center_y) * 0.6
bbox_inner = (center_x - radius_inner, center_y - radius_inner,
center_x + radius_inner, center_y + radius_inner)
start_angle2 = -self.angle * 180 / pi + 60
self.draw.arc(bbox_inner, start=start_angle2,
end=start_angle2 + 150, fill=self.color_rgb, width=7)
def _draw_pillow_blink(self) -> None:
"""Draws the blink animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
radius = min(center_x, center_y) * 0.8
alpha = (sin(self.angle * 2) + 1) / 2 # Slower blinking speed
r = int(
alpha * (self.highlight_color_rgb[0] - self.color_rgb[0]) + self.color_rgb[0])
g = int(
alpha * (self.highlight_color_rgb[1] - self.color_rgb[1]) + self.color_rgb[1])
b = int(
alpha * (self.highlight_color_rgb[2] - self.color_rgb[2]) + self.color_rgb[2])
blink_color = (r, g, b)
self.draw.arc((center_x - radius, center_y - radius, center_x + radius,
center_y + radius), start=0, end=360, fill=blink_color, width=10)
def _draw_stopped_frame(self) -> None:
"""Draws the icon in its stopped (static) state."""
self.delete("all")
if self.use_pillow:
self._draw_pillow_stopped_frame()
else:
self._draw_canvas_stopped_frame()
def _draw_canvas_stopped_frame(self) -> None:
"""Draws the stopped state using canvas methods."""
if self.animation_type == "line":
self._draw_canvas_line_stopped()
elif self.animation_type == "double_arc":
self._draw_canvas_double_arc_stopped()
elif self.animation_type == "counter_arc":
self._draw_canvas_counter_arc_stopped()
elif self.animation_type == "blink":
self._draw_canvas_blink_stopped()
def _draw_canvas_line_stopped(self) -> None:
"""Draws the stopped state for the line animation."""
center_x, center_y = self.width / 2, self.height / 2
for i in range(8):
angle = i * (pi / 4)
start_x = center_x + cos(angle) * (self.width * 0.2)
start_y = center_y + sin(angle) * (self.height * 0.2)
end_x = center_x + cos(angle) * (self.width * 0.4)
end_y = center_y + sin(angle) * (self.height * 0.4)
self.create_line(start_x, start_y, end_x, end_y,
fill=self.highlight_color, width=2)
def _draw_canvas_double_arc_stopped(self) -> None:
"""Draws the stopped state for the double arc animation."""
center_x, center_y = self.width / 2, self.height / 2
radius = min(center_x, center_y) * 0.8
bbox = (center_x - radius, center_y - radius,
center_x + radius, center_y + radius)
self.create_arc(bbox, start=0, extent=359.9, style=tk.ARC,
outline=self.highlight_color, width=2)
def _draw_canvas_counter_arc_stopped(self) -> None:
"""Draws the stopped state for the counter arc animation."""
center_x, center_y = self.width / 2, self.height / 2
radius_outer = min(center_x, center_y) * 0.8
bbox_outer = (center_x - radius_outer, center_y - radius_outer,
center_x + radius_outer, center_y + radius_outer)
self.create_arc(bbox_outer, start=0, extent=359.9,
style=tk.ARC, outline=self.highlight_color, width=2)
radius_inner = min(center_x, center_y) * 0.6
bbox_inner = (center_x - radius_inner, center_y - radius_inner,
center_x + radius_inner, center_y + radius_inner)
self.create_arc(bbox_inner, start=0, extent=359.9,
style=tk.ARC, outline=self.color, width=2)
def _draw_canvas_blink_stopped(self) -> None:
"""Draws the stopped state for the blink animation."""
center_x, center_y = self.width / 2, self.height / 2
radius = min(center_x, center_y) * 0.8
self.create_arc(center_x - radius, center_y - radius, center_x + radius, center_y +
radius, start=0, extent=359.9, style=tk.ARC, outline=self.highlight_color, width=4)
def _draw_pillow_stopped_frame(self) -> None:
"""Draws the stopped state using Pillow."""
self.draw.rectangle(
[0, 0, self.width * 4, self.height * 4], fill=(0, 0, 0, 0))
if self.animation_type == "line":
self._draw_pillow_line_stopped()
elif self.animation_type == "double_arc":
self._draw_pillow_double_arc_stopped()
elif self.animation_type == "counter_arc":
self._draw_pillow_counter_arc_stopped()
elif self.animation_type == "blink":
self._draw_pillow_blink_stopped()
resized_image = self.image.resize(
(self.width, self.height), Image.Resampling.LANCZOS)
self.photo_image = ImageTk.PhotoImage(resized_image)
self.create_image(0, 0, anchor="nw", image=self.photo_image)
def _draw_pillow_line_stopped(self) -> None:
"""Draws the stopped state for the line animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
for i in range(12):
angle = i * (pi / 6)
start_x = center_x + cos(angle) * (self.width * 0.8)
start_y = center_y + sin(angle) * (self.height * 0.8)
end_x = center_x + cos(angle) * (self.width * 1.6)
end_y = center_y + sin(angle) * (self.height * 1.6)
self.draw.line([(start_x, start_y), (end_x, end_y)],
fill=self.highlight_color_rgb, width=6, joint="curve")
def _draw_pillow_double_arc_stopped(self) -> None:
"""Draws the stopped state for the double arc animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
radius = min(center_x, center_y) * 0.8
bbox = (center_x - radius, center_y - radius,
center_x + radius, center_y + radius)
self.draw.arc(bbox, start=0, end=360,
fill=self.highlight_color_rgb, width=5)
def _draw_pillow_counter_arc_stopped(self) -> None:
"""Draws the stopped state for the counter arc animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
radius_outer = min(center_x, center_y) * 0.8
bbox_outer = (center_x - radius_outer, center_y - radius_outer,
center_x + radius_outer, center_y + radius_outer)
self.draw.arc(bbox_outer, start=0, end=360,
fill=self.highlight_color_rgb, width=7)
radius_inner = min(center_x, center_y) * 0.6
bbox_inner = (center_x - radius_inner, center_y - radius_inner,
center_x + radius_inner, center_y + radius_inner)
self.draw.arc(bbox_inner, start=0, end=360,
fill=self.color_rgb, width=7)
def _draw_pillow_blink_stopped(self) -> None:
"""Draws the stopped state for the blink animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
radius = min(center_x, center_y) * 0.8
self.draw.arc((center_x - radius, center_y - radius, center_x + radius,
center_y + radius), start=0, end=360, fill=self.highlight_color_rgb, width=10)
def _animate(self) -> None:
"""The main animation loop."""
if self.running:
self.angle += 0.1
if self.angle > 2 * pi:
self.angle -= 2 * pi
self._draw_frame()
self.after(30, self._animate)
def start(self, pulse: bool = False) -> None:
"""
Starts the animation.
Args:
pulse (bool): If True, plays a pulsing animation instead of the main one.
"""
if not self.running:
self.pulse_animation = pulse
self.running = True
self._animate()
def stop(self) -> None:
"""Stops the animation and shows the static 'stopped' frame."""
self.running = False
self.pulse_animation = False
self._draw_stopped_frame()
def hide(self) -> None:
"""Stops the animation and clears the canvas."""
self.running = False
self.pulse_animation = False
self.delete("all")
def show_full_circle(self) -> None:
"""Shows the static 'stopped' frame without starting the animation."""
if not self.running:
self._draw_stopped_frame()
try:
from PIL import Image, ImageDraw, ImageTk
PIL_AVAILABLE = True
except ImportError:
PIL_AVAILABLE = False
def _hex_to_rgb(hex_color):
"""Converts a hex color string to an RGB tuple."""
hex_color = hex_color.lstrip('#')
return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
class AnimatedIcon(tk.Canvas):
"""A custom Tkinter Canvas widget for displaying animations."""
def __init__(self, master, width=20, height=20, animation_type="counter_arc", color="#2a6fde", highlight_color="#5195ff", use_pillow=False, bg=None):
"""
Initializes the AnimatedIcon widget.
Args:
master: The parent widget.
width (int): The width of the icon.
height (int): The height of the icon.
animation_type (str): The type of animation to display.
Options: "counter_arc", "double_arc", "line", "blink".
color (str): The primary color of the icon.
highlight_color (str): The highlight color of the icon.
use_pillow (bool): Whether to use Pillow for drawing if available.
bg (str): The background color of the canvas.
"""
if bg is None:
try:
bg = master.cget("background")
except tk.TclError:
bg = "#f0f0f0" # Fallback color
super().__init__(master, width=width, height=height, bg=bg, highlightthickness=0)
self.width = width
self.height = height
self.animation_type = animation_type
self.color = color
self.highlight_color = highlight_color
self.use_pillow = use_pillow and PIL_AVAILABLE
self.running = False
self.angle = 0
self.pulse_animation = False
self.color_rgb = _hex_to_rgb(self.color)
self.highlight_color_rgb = _hex_to_rgb(self.highlight_color)
if self.use_pillow:
self.image = Image.new(
"RGBA", (width * 4, height * 4), (0, 0, 0, 0))
self.draw = ImageDraw.Draw(self.image)
self.photo_image = None
def _draw_frame(self):
"""Draws a single frame of the animation."""
if self.use_pillow:
self._draw_pillow_frame()
else:
self._draw_canvas_frame()
def _draw_canvas_frame(self):
"""Draws a frame using native Tkinter canvas methods."""
self.delete("all")
if self.pulse_animation:
self._draw_canvas_pulse()
elif self.animation_type == "line":
self._draw_canvas_line()
elif self.animation_type == "double_arc":
self._draw_canvas_double_arc()
elif self.animation_type == "counter_arc":
self._draw_canvas_counter_arc()
elif self.animation_type == "blink":
self._draw_canvas_blink()
def _draw_canvas_pulse(self):
"""Draws the pulse animation using canvas methods."""
center_x, center_y = self.width / 2, self.height / 2
alpha = (sin(self.angle * 5) + 1) / 2 # Faster pulse
r = int(
alpha * (self.highlight_color_rgb[0] - self.color_rgb[0]) + self.color_rgb[0])
g = int(
alpha * (self.highlight_color_rgb[1] - self.color_rgb[1]) + self.color_rgb[1])
b = int(
alpha * (self.highlight_color_rgb[2] - self.color_rgb[2]) + self.color_rgb[2])
pulse_color = f"#{r:02x}{g:02x}{b:02x}"
if self.animation_type == "line":
for i in range(8):
angle = i * (pi / 4)
start_x = center_x + cos(angle) * (self.width * 0.2)
start_y = center_y + sin(angle) * (self.height * 0.2)
end_x = center_x + cos(angle) * (self.width * 0.4)
end_y = center_y + sin(angle) * (self.height * 0.4)
self.create_line(start_x, start_y, end_x,
end_y, fill=pulse_color, width=2)
elif self.animation_type == "double_arc":
radius = min(center_x, center_y) * 0.8
bbox = (center_x - radius, center_y - radius,
center_x + radius, center_y + radius)
self.create_arc(bbox, start=0, extent=359.9,
style=tk.ARC, outline=pulse_color, width=2)
elif self.animation_type == "counter_arc":
radius_outer = min(center_x, center_y) * 0.8
bbox_outer = (center_x - radius_outer, center_y - radius_outer,
center_x + radius_outer, center_y + radius_outer)
self.create_arc(bbox_outer, start=0, extent=359.9,
style=tk.ARC, outline=pulse_color, width=2)
radius_inner = min(center_x, center_y) * 0.6
bbox_inner = (center_x - radius_inner, center_y - radius_inner,
center_x + radius_inner, center_y + radius_inner)
self.create_arc(bbox_inner, start=0, extent=359.9,
style=tk.ARC, outline=self.color, width=2)
def _draw_canvas_line(self):
"""Draws the line animation using canvas methods."""
center_x, center_y = self.width / 2, self.height / 2
for i in range(8):
angle = self.angle + i * (pi / 4)
start_x = center_x + cos(angle) * (self.width * 0.2)
start_y = center_y + sin(angle) * (self.height * 0.2)
end_x = center_x + cos(angle) * (self.width * 0.4)
end_y = center_y + sin(angle) * (self.height * 0.4)
alpha = (cos(self.angle * 2 + i * (pi / 4)) + 1) / 2
r = int(
alpha * (self.highlight_color_rgb[0] - self.color_rgb[0]) + self.color_rgb[0])
g = int(
alpha * (self.highlight_color_rgb[1] - self.color_rgb[1]) + self.color_rgb[1])
b = int(
alpha * (self.highlight_color_rgb[2] - self.color_rgb[2]) + self.color_rgb[2])
color = f"#{r:02x}{g:02x}{b:02x}"
self.create_line(start_x, start_y, end_x,
end_y, fill=color, width=2)
def _draw_canvas_double_arc(self):
"""Draws the double arc animation using canvas methods."""
center_x, center_y = self.width / 2, self.height / 2
radius = min(center_x, center_y) * 0.8
bbox = (center_x - radius, center_y - radius,
center_x + radius, center_y + radius)
start_angle1 = -self.angle * 180 / pi
extent1 = 120 + 60 * sin(-self.angle)
self.create_arc(bbox, start=start_angle1, extent=extent1,
style=tk.ARC, outline=self.highlight_color, width=2)
start_angle2 = (-self.angle + pi) * 180 / pi
extent2 = 120 + 60 * sin(-self.angle + pi / 2)
self.create_arc(bbox, start=start_angle2, extent=extent2,
style=tk.ARC, outline=self.color, width=2)
def _draw_canvas_counter_arc(self):
"""Draws the counter arc animation using canvas methods."""
center_x, center_y = self.width / 2, self.height / 2
radius_outer = min(center_x, center_y) * 0.8
bbox_outer = (center_x - radius_outer, center_y - radius_outer,
center_x + radius_outer, center_y + radius_outer)
start_angle1 = -self.angle * 180 / pi
self.create_arc(bbox_outer, start=start_angle1, extent=150,
style=tk.ARC, outline=self.highlight_color, width=2)
radius_inner = min(center_x, center_y) * 0.6
bbox_inner = (center_x - radius_inner, center_y - radius_inner,
center_x + radius_inner, center_y + radius_inner)
start_angle2 = self.angle * 180 / pi + 60
self.create_arc(bbox_inner, start=start_angle2, extent=150,
style=tk.ARC, outline=self.color, width=2)
def _draw_canvas_blink(self):
"""Draws the blink animation using canvas methods."""
center_x, center_y = self.width / 2, self.height / 2
radius = min(center_x, center_y) * 0.8
alpha = (sin(self.angle * 2) + 1) / 2 # Slower blinking speed
r = int(
alpha * (self.highlight_color_rgb[0] - self.color_rgb[0]) + self.color_rgb[0])
g = int(
alpha * (self.highlight_color_rgb[1] - self.color_rgb[1]) + self.color_rgb[1])
b = int(
alpha * (self.highlight_color_rgb[2] - self.color_rgb[2]) + self.color_rgb[2])
blink_color = f"#{r:02x}{g:02x}{b:02x}"
self.create_arc(center_x - radius, center_y - radius, center_x + radius, center_y +
radius, start=0, extent=359.9, style=tk.ARC, outline=blink_color, width=4)
def _draw_pillow_frame(self):
"""Draws a frame using Pillow for anti-aliased graphics."""
self.draw.rectangle(
[0, 0, self.width * 4, self.height * 4], fill=(0, 0, 0, 0))
if self.pulse_animation:
self._draw_pillow_pulse()
elif self.animation_type == "line":
self._draw_pillow_line()
elif self.animation_type == "double_arc":
self._draw_pillow_double_arc()
elif self.animation_type == "counter_arc":
self._draw_pillow_counter_arc()
elif self.animation_type == "blink":
self._draw_pillow_blink()
resized_image = self.image.resize(
(self.width, self.height), Image.Resampling.LANCZOS)
self.photo_image = ImageTk.PhotoImage(resized_image)
self.delete("all")
self.create_image(0, 0, anchor="nw", image=self.photo_image)
def _draw_pillow_pulse(self):
"""Draws the pulse animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
alpha = (sin(self.angle * 5) + 1) / 2 # Faster pulse
r = int(
alpha * (self.highlight_color_rgb[0] - self.color_rgb[0]) + self.color_rgb[0])
g = int(
alpha * (self.highlight_color_rgb[1] - self.color_rgb[1]) + self.color_rgb[1])
b = int(
alpha * (self.highlight_color_rgb[2] - self.color_rgb[2]) + self.color_rgb[2])
pulse_color = (r, g, b)
if self.animation_type == "line":
for i in range(12):
angle = i * (pi / 6)
start_x = center_x + cos(angle) * (self.width * 0.8)
start_y = center_y + sin(angle) * (self.height * 0.8)
end_x = center_x + cos(angle) * (self.width * 1.6)
end_y = center_y + sin(angle) * (self.height * 1.6)
self.draw.line([(start_x, start_y), (end_x, end_y)],
fill=pulse_color, width=6, joint="curve")
elif self.animation_type == "double_arc":
radius = min(center_x, center_y) * 0.8
bbox = (center_x - radius, center_y - radius,
center_x + radius, center_y + radius)
self.draw.arc(bbox, start=0, end=360, fill=pulse_color, width=5)
elif self.animation_type == "counter_arc":
radius_outer = min(center_x, center_y) * 0.8
bbox_outer = (center_x - radius_outer, center_y - radius_outer,
center_x + radius_outer, center_y + radius_outer)
self.draw.arc(bbox_outer, start=0, end=360,
fill=pulse_color, width=7)
radius_inner = min(center_x, center_y) * 0.6
bbox_inner = (center_x - radius_inner, center_y - radius_inner,
center_x + radius_inner, center_y + radius_inner)
self.draw.arc(bbox_inner, start=0, end=360,
fill=self.color_rgb, width=7)
def _draw_pillow_line(self):
"""Draws the line animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
for i in range(12):
angle = self.angle + i * (pi / 6)
start_x = center_x + cos(angle) * (self.width * 0.8)
start_y = center_y + sin(angle) * (self.height * 0.8)
end_x = center_x + cos(angle) * (self.width * 1.6)
end_y = center_y + sin(angle) * (self.height * 1.6)
alpha = (cos(self.angle * 2.5 + i * (pi / 6)) + 1) / 2
r = int(
alpha * (self.highlight_color_rgb[0] - self.color_rgb[0]) + self.color_rgb[0])
g = int(
alpha * (self.highlight_color_rgb[1] - self.color_rgb[1]) + self.color_rgb[1])
b = int(
alpha * (self.highlight_color_rgb[2] - self.color_rgb[2]) + self.color_rgb[2])
color = (r, g, b)
self.draw.line([(start_x, start_y), (end_x, end_y)],
fill=color, width=6, joint="curve")
def _draw_pillow_double_arc(self):
"""Draws the double arc animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
radius = min(center_x, center_y) * 0.8
bbox = (center_x - radius, center_y - radius,
center_x + radius, center_y + radius)
start_angle1 = self.angle * 180 / pi
extent1 = 120 + 60 * sin(self.angle)
self.draw.arc(bbox, start=start_angle1, end=start_angle1 +
extent1, fill=self.highlight_color_rgb, width=5)
start_angle2 = (self.angle + pi) * 180 / pi
extent2 = 120 + 60 * sin(self.angle + pi / 2)
self.draw.arc(bbox, start=start_angle2, end=start_angle2 +
extent2, fill=self.color_rgb, width=5)
def _draw_pillow_counter_arc(self):
"""Draws the counter arc animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
radius_outer = min(center_x, center_y) * 0.8
bbox_outer = (center_x - radius_outer, center_y - radius_outer,
center_x + radius_outer, center_y + radius_outer)
start_angle1 = self.angle * 180 / pi
self.draw.arc(bbox_outer, start=start_angle1, end=start_angle1 +
150, fill=self.highlight_color_rgb, width=7)
radius_inner = min(center_x, center_y) * 0.6
bbox_inner = (center_x - radius_inner, center_y - radius_inner,
center_x + radius_inner, center_y + radius_inner)
start_angle2 = -self.angle * 180 / pi + 60
self.draw.arc(bbox_inner, start=start_angle2,
end=start_angle2 + 150, fill=self.color_rgb, width=7)
def _draw_pillow_blink(self):
"""Draws the blink animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
radius = min(center_x, center_y) * 0.8
alpha = (sin(self.angle * 2) + 1) / 2 # Slower blinking speed
r = int(
alpha * (self.highlight_color_rgb[0] - self.color_rgb[0]) + self.color_rgb[0])
g = int(
alpha * (self.highlight_color_rgb[1] - self.color_rgb[1]) + self.color_rgb[1])
b = int(
alpha * (self.highlight_color_rgb[2] - self.color_rgb[2]) + self.color_rgb[2])
blink_color = (r, g, b)
self.draw.arc((center_x - radius, center_y - radius, center_x + radius,
center_y + radius), start=0, end=360, fill=blink_color, width=10)
def _draw_stopped_frame(self):
"""Draws the icon in its stopped (static) state."""
self.delete("all")
if self.use_pillow:
self._draw_pillow_stopped_frame()
else:
self._draw_canvas_stopped_frame()
def _draw_canvas_stopped_frame(self):
"""Draws the stopped state using canvas methods."""
if self.animation_type == "line":
self._draw_canvas_line_stopped()
elif self.animation_type == "double_arc":
self._draw_canvas_double_arc_stopped()
elif self.animation_type == "counter_arc":
self._draw_canvas_counter_arc_stopped()
elif self.animation_type == "blink":
self._draw_canvas_blink_stopped()
def _draw_canvas_line_stopped(self):
"""Draws the stopped state for the line animation."""
center_x, center_y = self.width / 2, self.height / 2
for i in range(8):
angle = i * (pi / 4)
start_x = center_x + cos(angle) * (self.width * 0.2)
start_y = center_y + sin(angle) * (self.height * 0.2)
end_x = center_x + cos(angle) * (self.width * 0.4)
end_y = center_y + sin(angle) * (self.height * 0.4)
self.create_line(start_x, start_y, end_x, end_y,
fill=self.highlight_color, width=2)
def _draw_canvas_double_arc_stopped(self):
"""Draws the stopped state for the double arc animation."""
center_x, center_y = self.width / 2, self.height / 2
radius = min(center_x, center_y) * 0.8
bbox = (center_x - radius, center_y - radius,
center_x + radius, center_y + radius)
self.create_arc(bbox, start=0, extent=359.9, style=tk.ARC,
outline=self.highlight_color, width=2)
def _draw_canvas_counter_arc_stopped(self):
"""Draws the stopped state for the counter arc animation."""
center_x, center_y = self.width / 2, self.height / 2
radius_outer = min(center_x, center_y) * 0.8
bbox_outer = (center_x - radius_outer, center_y - radius_outer,
center_x + radius_outer, center_y + radius_outer)
self.create_arc(bbox_outer, start=0, extent=359.9,
style=tk.ARC, outline=self.highlight_color, width=2)
radius_inner = min(center_x, center_y) * 0.6
bbox_inner = (center_x - radius_inner, center_y - radius_inner,
center_x + radius_inner, center_y + radius_inner)
self.create_arc(bbox_inner, start=0, extent=359.9,
style=tk.ARC, outline=self.color, width=2)
def _draw_canvas_blink_stopped(self):
"""Draws the stopped state for the blink animation."""
center_x, center_y = self.width / 2, self.height / 2
radius = min(center_x, center_y) * 0.8
self.create_arc(center_x - radius, center_y - radius, center_x + radius, center_y +
radius, start=0, extent=359.9, style=tk.ARC, outline=self.highlight_color, width=4)
def _draw_pillow_stopped_frame(self):
"""Draws the stopped state using Pillow."""
self.draw.rectangle(
[0, 0, self.width * 4, self.height * 4], fill=(0, 0, 0, 0))
if self.animation_type == "line":
self._draw_pillow_line_stopped()
elif self.animation_type == "double_arc":
self._draw_pillow_double_arc_stopped()
elif self.animation_type == "counter_arc":
self._draw_pillow_counter_arc_stopped()
elif self.animation_type == "blink":
self._draw_pillow_blink_stopped()
resized_image = self.image.resize(
(self.width, self.height), Image.Resampling.LANCZOS)
self.photo_image = ImageTk.PhotoImage(resized_image)
self.create_image(0, 0, anchor="nw", image=self.photo_image)
def _draw_pillow_line_stopped(self):
"""Draws the stopped state for the line animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
for i in range(12):
angle = i * (pi / 6)
start_x = center_x + cos(angle) * (self.width * 0.8)
start_y = center_y + sin(angle) * (self.height * 0.8)
end_x = center_x + cos(angle) * (self.width * 1.6)
end_y = center_y + sin(angle) * (self.height * 1.6)
self.draw.line([(start_x, start_y), (end_x, end_y)],
fill=self.highlight_color_rgb, width=6, joint="curve")
def _draw_pillow_double_arc_stopped(self):
"""Draws the stopped state for the double arc animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
radius = min(center_x, center_y) * 0.8
bbox = (center_x - radius, center_y - radius,
center_x + radius, center_y + radius)
self.draw.arc(bbox, start=0, end=360,
fill=self.highlight_color_rgb, width=5)
def _draw_pillow_counter_arc_stopped(self):
"""Draws the stopped state for the counter arc animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
radius_outer = min(center_x, center_y) * 0.8
bbox_outer = (center_x - radius_outer, center_y - radius_outer,
center_x + radius_outer, center_y + radius_outer)
self.draw.arc(bbox_outer, start=0, end=360,
fill=self.highlight_color_rgb, width=7)
radius_inner = min(center_x, center_y) * 0.6
bbox_inner = (center_x - radius_inner, center_y - radius_inner,
center_x + radius_inner, center_y + radius_inner)
self.draw.arc(bbox_inner, start=0, end=360,
fill=self.color_rgb, width=7)
def _draw_pillow_blink_stopped(self):
"""Draws the stopped state for the blink animation using Pillow."""
center_x, center_y = self.width * 2, self.height * 2
radius = min(center_x, center_y) * 0.8
self.draw.arc((center_x - radius, center_y - radius, center_x + radius,
center_y + radius), start=0, end=360, fill=self.highlight_color_rgb, width=10)
def _animate(self):
"""The main animation loop."""
if self.running:
self.angle += 0.1
if self.angle > 2 * pi:
self.angle -= 2 * pi
self._draw_frame()
self.after(30, self._animate)
def start(self, pulse=False):
"""
Starts the animation.
Args:
pulse (bool): If True, plays a pulsing animation instead of the main one.
"""
if not self.running:
self.pulse_animation = pulse
self.running = True
self._animate()
def stop(self):
"""Stops the animation and shows the static 'stopped' frame."""
self.running = False
self.pulse_animation = False
self._draw_stopped_frame()
def hide(self):
"""Stops the animation and clears the canvas."""
self.running = False
self.pulse_animation = False
self.delete("all")
def show_full_circle(self):
"""Shows the static 'stopped' frame without starting the animation."""
if not self.running:
self._draw_stopped_frame()

Binary file not shown.

13
logger.py Normal file
View File

@@ -0,0 +1,13 @@
class Logger:
def __init__(self):
self._log_func = print # Default to print if not initialized
def init_logger(self, log_func):
self._log_func = log_func
def log(self, message):
self._log_func(message)
# Global instance
app_logger = Logger()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 64 KiB

BIN
lx-icons/128/settings-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
lx-icons/128/settings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
lx-icons/16/settings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 B

BIN
lx-icons/256/settings-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

BIN
lx-icons/256/settings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

BIN
lx-icons/256/trash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

BIN
lx-icons/32/arrow-left.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

BIN
lx-icons/32/arrow-right.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B

BIN
lx-icons/32/arrow-up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
lx-icons/32/audio.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 969 B

BIN
lx-icons/32/carrel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

BIN
lx-icons/32/computer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
lx-icons/32/device.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 B

BIN
lx-icons/32/document.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 524 B

BIN
lx-icons/32/file-python.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 939 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1021 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

BIN
lx-icons/32/hide.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
lx-icons/32/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 B

BIN
lx-icons/32/list.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 906 B

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
lx-icons/32/lxtools_key.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
lx-icons/32/new-folder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
lx-icons/32/pdf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
lx-icons/32/picture.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
lx-icons/32/recursive.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
lx-icons/32/search.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 978 B

BIN
lx-icons/32/settings-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
lx-icons/32/settings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
lx-icons/32/tar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
lx-icons/32/trash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
lx-icons/32/unhide.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
lx-icons/32/usb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
lx-icons/32/video.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 760 B

BIN
lx-icons/48/arrow-left.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

BIN
lx-icons/48/arrow-right.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 816 B

BIN
lx-icons/48/arrow-up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
lx-icons/48/carrel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 818 B

BIN
lx-icons/48/computer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 708 B

BIN
lx-icons/48/device.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
lx-icons/48/hide.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

BIN
lx-icons/48/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

BIN
lx-icons/48/list.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

BIN
lx-icons/48/new-folder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

BIN
lx-icons/48/recursive.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

BIN
lx-icons/48/search.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
lx-icons/48/settings-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

BIN
lx-icons/48/settings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
lx-icons/48/trash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Some files were not shown because too many files have changed in this diff Show More