commit 74
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -29,6 +29,7 @@ class AnimatedIcon(tk.Canvas):
|
|||||||
self.use_pillow = use_pillow and PIL_AVAILABLE
|
self.use_pillow = use_pillow and PIL_AVAILABLE
|
||||||
self.running = False
|
self.running = False
|
||||||
self.angle = 0
|
self.angle = 0
|
||||||
|
self.pulse_animation = False
|
||||||
|
|
||||||
self.color_rgb = _hex_to_rgb(self.color)
|
self.color_rgb = _hex_to_rgb(self.color)
|
||||||
self.highlight_color_rgb = _hex_to_rgb(self.highlight_color)
|
self.highlight_color_rgb = _hex_to_rgb(self.highlight_color)
|
||||||
@@ -46,13 +47,44 @@ class AnimatedIcon(tk.Canvas):
|
|||||||
|
|
||||||
def _draw_canvas_frame(self):
|
def _draw_canvas_frame(self):
|
||||||
self.delete("all")
|
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()
|
self._draw_canvas_line()
|
||||||
elif self.animation_type == "double_arc":
|
elif self.animation_type == "double_arc":
|
||||||
self._draw_canvas_double_arc()
|
self._draw_canvas_double_arc()
|
||||||
elif self.animation_type == "counter_arc":
|
elif self.animation_type == "counter_arc":
|
||||||
self._draw_canvas_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):
|
def _draw_canvas_line(self):
|
||||||
center_x, center_y = self.width / 2, self.height / 2
|
center_x, center_y = self.width / 2, self.height / 2
|
||||||
for i in range(8):
|
for i in range(8):
|
||||||
@@ -98,7 +130,9 @@ class AnimatedIcon(tk.Canvas):
|
|||||||
|
|
||||||
def _draw_pillow_frame(self):
|
def _draw_pillow_frame(self):
|
||||||
self.draw.rectangle([0, 0, self.width * 4, self.height * 4], fill=(0, 0, 0, 0))
|
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()
|
self._draw_pillow_line()
|
||||||
elif self.animation_type == "double_arc":
|
elif self.animation_type == "double_arc":
|
||||||
self._draw_pillow_double_arc()
|
self._draw_pillow_double_arc()
|
||||||
@@ -110,6 +144,34 @@ class AnimatedIcon(tk.Canvas):
|
|||||||
self.delete("all")
|
self.delete("all")
|
||||||
self.create_image(0, 0, anchor="nw", image=self.photo_image)
|
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):
|
def _draw_pillow_line(self):
|
||||||
center_x, center_y = self.width * 2, self.height * 2
|
center_x, center_y = self.width * 2, self.height * 2
|
||||||
for i in range(12):
|
for i in range(12):
|
||||||
@@ -239,17 +301,20 @@ class AnimatedIcon(tk.Canvas):
|
|||||||
self._draw_frame()
|
self._draw_frame()
|
||||||
self.after(30, self._animate)
|
self.after(30, self._animate)
|
||||||
|
|
||||||
def start(self):
|
def start(self, pulse=False):
|
||||||
if not self.running:
|
if not self.running:
|
||||||
|
self.pulse_animation = pulse
|
||||||
self.running = True
|
self.running = True
|
||||||
self._animate()
|
self._animate()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.running = False
|
self.running = False
|
||||||
|
self.pulse_animation = False
|
||||||
self._draw_stopped_frame()
|
self._draw_stopped_frame()
|
||||||
|
|
||||||
def hide(self):
|
def hide(self):
|
||||||
self.running = False
|
self.running = False
|
||||||
|
self.pulse_animation = False
|
||||||
self.delete("all")
|
self.delete("all")
|
||||||
|
|
||||||
def show_full_circle(self):
|
def show_full_circle(self):
|
||||||
|
@@ -251,10 +251,6 @@ class CustomFileDialog(tk.Toplevel):
|
|||||||
self.widget_manager.path_entry.bind(
|
self.widget_manager.path_entry.bind(
|
||||||
"<Return>", self.handle_path_entry_return)
|
"<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)
|
self.bind("<Key>", self.show_search_bar)
|
||||||
|
|
||||||
# Bind the delete key only in "save" mode
|
# Bind the delete key only in "save" mode
|
||||||
@@ -283,7 +279,7 @@ class CustomFileDialog(tk.Toplevel):
|
|||||||
# If not animating, activate search entry
|
# If not animating, activate search entry
|
||||||
self.widget_manager.filename_entry.focus_set()
|
self.widget_manager.filename_entry.focus_set()
|
||||||
self.search_mode = True # Ensure search mode is active
|
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("<Return>", self.execute_search)
|
||||||
self.widget_manager.filename_entry.bind("<Escape>", self.hide_search_bar)
|
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>")
|
self.widget_manager.filename_entry.unbind("<Escape>")
|
||||||
if self.dialog_mode == "save":
|
if self.dialog_mode == "save":
|
||||||
self.widget_manager.filename_entry.bind("<Return>", lambda e: self.on_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.populate_files()
|
||||||
self.widget_manager.search_animation.hide()
|
self.widget_manager.search_animation.hide()
|
||||||
|
|
||||||
@@ -317,7 +315,7 @@ class CustomFileDialog(tk.Toplevel):
|
|||||||
self.hide_search_bar()
|
self.hide_search_bar()
|
||||||
return
|
return
|
||||||
self.widget_manager.search_status_label.config(text=f"Suche nach '{search_term}'...")
|
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.update_idletasks()
|
||||||
self.search_thread = threading.Thread(target=self._perform_search_in_thread, args=(search_term,))
|
self.search_thread = threading.Thread(target=self._perform_search_in_thread, args=(search_term,))
|
||||||
self.search_thread.start()
|
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.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("<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:
|
if is_running:
|
||||||
self.widget_manager.search_animation.start()
|
self.widget_manager.search_animation.start()
|
||||||
@@ -1124,6 +1124,7 @@ class CustomFileDialog(tk.Toplevel):
|
|||||||
self.selected_item_frame = item_frame
|
self.selected_item_frame = item_frame
|
||||||
self.selected_file = path
|
self.selected_file = path
|
||||||
self.update_status_bar(path) # Pass selected path
|
self.update_status_bar(path) # Pass selected path
|
||||||
|
self.show_search_ready()
|
||||||
if not os.path.isdir(path):
|
if not os.path.isdir(path):
|
||||||
self.widget_manager.filename_entry.delete(0, tk.END)
|
self.widget_manager.filename_entry.delete(0, tk.END)
|
||||||
self.widget_manager.filename_entry.insert(0, os.path.basename(path))
|
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)
|
path = os.path.join(self.current_dir, item_text)
|
||||||
self.selected_file = path
|
self.selected_file = path
|
||||||
self.update_status_bar(path) # Pass selected path
|
self.update_status_bar(path) # Pass selected path
|
||||||
|
self.show_search_ready()
|
||||||
if not os.path.isdir(self.selected_file):
|
if not os.path.isdir(self.selected_file):
|
||||||
self.widget_manager.filename_entry.delete(0, tk.END)
|
self.widget_manager.filename_entry.delete(0, tk.END)
|
||||||
self.widget_manager.filename_entry.insert(0, item_text)
|
self.widget_manager.filename_entry.insert(0, item_text)
|
||||||
@@ -1417,6 +1419,22 @@ class CustomFileDialog(tk.Toplevel):
|
|||||||
self.navigate_to(directory)
|
self.navigate_to(directory)
|
||||||
self.after(100, lambda: self._select_file_in_view(filename))
|
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):
|
def start_rename(self, item_widget, item_path):
|
||||||
if self.view_mode.get() == "icons":
|
if self.view_mode.get() == "icons":
|
||||||
self._start_rename_icon_view(item_widget, item_path)
|
self._start_rename_icon_view(item_widget, item_path)
|
||||||
|
@@ -33,7 +33,7 @@ class GlotzMol(tk.Tk):
|
|||||||
dialog = CustomFileDialog(self,
|
dialog = CustomFileDialog(self,
|
||||||
initial_dir=os.path.expanduser("~"),
|
initial_dir=os.path.expanduser("~"),
|
||||||
filetypes=[("All Files", "*.*")
|
filetypes=[("All Files", "*.*")
|
||||||
])
|
], dialog_mode="save")
|
||||||
|
|
||||||
# This is the crucial part: wait for the dialog to be closed
|
# This is the crucial part: wait for the dialog to be closed
|
||||||
self.wait_window(dialog)
|
self.wait_window(dialog)
|
||||||
@@ -55,7 +55,7 @@ if __name__ == "__main__":
|
|||||||
style = ttk.Style(root)
|
style = ttk.Style(root)
|
||||||
root.tk.call('source', f"{theme_path}/water.tcl")
|
root.tk.call('source', f"{theme_path}/water.tcl")
|
||||||
try:
|
try:
|
||||||
root.tk.call('set_theme', 'dark')
|
root.tk.call('set_theme', 'light')
|
||||||
except tk.TclError:
|
except tk.TclError:
|
||||||
pass
|
pass
|
||||||
root.mainloop()
|
root.mainloop()
|
||||||
|
Reference in New Issue
Block a user