commit 74

This commit is contained in:
2025-08-08 19:36:42 +02:00
parent 43ac132ec8
commit 482eaae591
5 changed files with 94 additions and 11 deletions

View File

@@ -29,6 +29,7 @@ class AnimatedIcon(tk.Canvas):
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)
@@ -46,13 +47,44 @@ class AnimatedIcon(tk.Canvas):
def _draw_canvas_frame(self):
self.delete("all")
if self.animation_type == "line":
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()
def _draw_canvas_pulse(self):
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):
center_x, center_y = self.width / 2, self.height / 2
for i in range(8):
@@ -98,7 +130,9 @@ class AnimatedIcon(tk.Canvas):
def _draw_pillow_frame(self):
self.draw.rectangle([0, 0, self.width * 4, self.height * 4], fill=(0, 0, 0, 0))
if self.animation_type == "line":
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()
@@ -110,6 +144,34 @@ class AnimatedIcon(tk.Canvas):
self.delete("all")
self.create_image(0, 0, anchor="nw", image=self.photo_image)
def _draw_pillow_pulse(self):
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):
center_x, center_y = self.width * 2, self.height * 2
for i in range(12):
@@ -239,17 +301,20 @@ class AnimatedIcon(tk.Canvas):
self._draw_frame()
self.after(30, self._animate)
def start(self):
def start(self, pulse=False):
if not self.running:
self.pulse_animation = pulse
self.running = True
self._animate()
def stop(self):
self.running = False
self.pulse_animation = False
self._draw_stopped_frame()
def hide(self):
self.running = False
self.pulse_animation = False
self.delete("all")
def show_full_circle(self):

View File

@@ -251,10 +251,6 @@ class CustomFileDialog(tk.Toplevel):
self.widget_manager.path_entry.bind(
"<Return>", self.handle_path_entry_return)
# Bind focus events to show the static animation
self.widget_manager.path_entry.bind("<FocusIn>", self.show_search_ready)
self.widget_manager.filename_entry.bind("<FocusIn>", self.show_search_ready)
self.bind("<Key>", self.show_search_bar)
# Bind the delete key only in "save" mode
@@ -283,7 +279,7 @@ class CustomFileDialog(tk.Toplevel):
# If not animating, activate search entry
self.widget_manager.filename_entry.focus_set()
self.search_mode = True # Ensure search mode is active
self.widget_manager.search_animation.show_full_circle()
self.widget_manager.search_animation.start(pulse=True)
self.widget_manager.filename_entry.bind("<Return>", self.execute_search)
self.widget_manager.filename_entry.bind("<Escape>", self.hide_search_bar)
@@ -306,6 +302,8 @@ class CustomFileDialog(tk.Toplevel):
self.widget_manager.filename_entry.unbind("<Escape>")
if self.dialog_mode == "save":
self.widget_manager.filename_entry.bind("<Return>", lambda e: self.on_save())
else:
self.widget_manager.filename_entry.bind("<Return>", self.execute_search)
self.populate_files()
self.widget_manager.search_animation.hide()
@@ -317,7 +315,7 @@ class CustomFileDialog(tk.Toplevel):
self.hide_search_bar()
return
self.widget_manager.search_status_label.config(text=f"Suche nach '{search_term}'...")
self.widget_manager.search_animation.start()
self.widget_manager.search_animation.start(pulse=False)
self.update_idletasks()
self.search_thread = threading.Thread(target=self._perform_search_in_thread, args=(search_term,))
self.search_thread.start()
@@ -466,6 +464,8 @@ class CustomFileDialog(tk.Toplevel):
)
self.widget_manager.search_animation.grid(row=0, column=0, sticky='w', padx=(0, 5), pady=(4,0))
self.widget_manager.search_animation.bind("<Button-1>", lambda e: self.activate_search())
self.widget_manager.search_animation.bind("<Enter>", self._show_tooltip)
self.widget_manager.search_animation.bind("<Leave>", self._hide_tooltip)
if is_running:
self.widget_manager.search_animation.start()
@@ -1124,6 +1124,7 @@ class CustomFileDialog(tk.Toplevel):
self.selected_item_frame = item_frame
self.selected_file = path
self.update_status_bar(path) # Pass selected path
self.show_search_ready()
if not os.path.isdir(path):
self.widget_manager.filename_entry.delete(0, tk.END)
self.widget_manager.filename_entry.insert(0, os.path.basename(path))
@@ -1136,6 +1137,7 @@ class CustomFileDialog(tk.Toplevel):
path = os.path.join(self.current_dir, item_text)
self.selected_file = path
self.update_status_bar(path) # Pass selected path
self.show_search_ready()
if not os.path.isdir(self.selected_file):
self.widget_manager.filename_entry.delete(0, tk.END)
self.widget_manager.filename_entry.insert(0, item_text)
@@ -1417,6 +1419,22 @@ class CustomFileDialog(tk.Toplevel):
self.navigate_to(directory)
self.after(100, lambda: self._select_file_in_view(filename))
def _show_tooltip(self, event):
if hasattr(self, 'tooltip_window') and self.tooltip_window.winfo_exists():
return
x = self.widget_manager.search_animation.winfo_rootx() + 25
y = self.widget_manager.search_animation.winfo_rooty() + 25
self.tooltip_window = tk.Toplevel(self)
self.tooltip_window.wm_overrideredirect(True)
self.tooltip_window.wm_geometry(f"+{x}+{y}")
label = tk.Label(self.tooltip_window, text="Klicken, um die Suche zu aktivieren",
background="#333333", foreground="#FFFFFF", relief="solid", borderwidth=1)
label.pack()
def _hide_tooltip(self, event):
if hasattr(self, 'tooltip_window') and self.tooltip_window.winfo_exists():
self.tooltip_window.destroy()
def start_rename(self, item_widget, item_path):
if self.view_mode.get() == "icons":
self._start_rename_icon_view(item_widget, item_path)

View File

@@ -33,7 +33,7 @@ class GlotzMol(tk.Tk):
dialog = CustomFileDialog(self,
initial_dir=os.path.expanduser("~"),
filetypes=[("All Files", "*.*")
])
], dialog_mode="save")
# This is the crucial part: wait for the dialog to be closed
self.wait_window(dialog)
@@ -55,7 +55,7 @@ if __name__ == "__main__":
style = ttk.Style(root)
root.tk.call('source', f"{theme_path}/water.tcl")
try:
root.tk.call('set_theme', 'dark')
root.tk.call('set_theme', 'light')
except tk.TclError:
pass
root.mainloop()