import os import subprocess import sys from tkinter import * from tkinter.ttk import Progressbar, Style from tkinter.messagebox import * import customtkinter from CTkToolTip import * from PIL import ImageTk, Image from src.util import Util class Toolbar: def __init__(self, image_window, timer): self.timers = [] self.is_paused = False self.current_image = None self.current_original_image = None self.image_window = image_window self.timer = timer self.timer_check = None self.always_on_top_check = None toolbar = Frame(self.image_window.window, bd=1, relief=RAISED) toolbar.pack(side=BOTTOM, fill=X) next_button = customtkinter.CTkButton(toolbar, image=ImageTk.PhotoImage(Image.open("assets/icons/next.png")), text="", command=self.image_window.next_image) next_button.pack(side=LEFT, padx=0, pady=0) CTkToolTip(next_button, delay=0.1, message="Next", y_offset=-40, x_offset=-40) pause_button = customtkinter.CTkButton(toolbar, image=ImageTk.PhotoImage(Image.open("assets/icons/pause.png")), text="", command=self.pause) pause_button.pack(side=LEFT, padx=0, pady=0) CTkToolTip(pause_button, delay=0.1, message="Next", y_offset=-40, x_offset=-40) self.bw_button = customtkinter.CTkButton(toolbar, image=ImageTk.PhotoImage(Image.open("assets/icons/black-and" "-white.png")), text="", command=self.toggle_black_white) self.bw_button.pack(side=LEFT, padx=0, pady=0) CTkToolTip(self.bw_button, delay=0.1, message="Black and white image", y_offset=-40, x_offset=-40) self.mirror_button = customtkinter.CTkButton(toolbar, command=self.toggle_mirror, text="", image=ImageTk.PhotoImage(Image.open("assets/icons/flip.png"))) self.mirror_button.pack(side=LEFT, padx=0, pady=0) CTkToolTip(self.mirror_button, delay=0.1, message="Mirrored image", y_offset=-40, x_offset=-40) open_folder_button = customtkinter.CTkButton(toolbar, command=self.open_folder, text="", image=ImageTk.PhotoImage(Image.open("assets/icons/folder.png"))) open_folder_button.pack(side=LEFT, padx=0, pady=0) CTkToolTip(open_folder_button, delay=0.1, message="Open folder", y_offset=-40, x_offset=-40) self.always_on_top_button = customtkinter.CTkButton(toolbar, command=self.toggle_always_on_top, text="", image=ImageTk.PhotoImage( Image.open("assets/icons/copy.png"))) self.always_on_top_button.pack(side=LEFT, padx=0, pady=0) CTkToolTip(self.always_on_top_button, delay=0.1, message="Always on top", y_offset=-40, x_offset=-40) self.fullscreen_button = customtkinter.CTkButton(toolbar, command=self.toggle_fullscreen, text="", image=ImageTk.PhotoImage( Image.open("assets/icons/maximize.png"))) self.fullscreen_button.pack(side=LEFT, padx=0, pady=0) CTkToolTip(self.fullscreen_button, delay=0.1, message="Fullscreen", y_offset=-40, x_offset=-40) timer_button = customtkinter.CTkButton(toolbar, command=self.toggle_timer, text="", image=ImageTk.PhotoImage(Image.open("assets/icons/sand-clock.png"))) timer_button.pack(side=LEFT, padx=0, pady=0) CTkToolTip(timer_button, delay=0.1, message="Toggle timer", y_offset=-40, x_offset=-40) self.timer_label = customtkinter.CTkLabel(toolbar, text=str(self.timer), text_color=Util.get_default_button_color()) self.timer_label.pack(side=RIGHT, ipadx=20) style = Style() style.theme_use('default') style.configure("black.Horizontal.TProgressbar", background='black') self.progressbar = Progressbar(toolbar, length=280) self.progressbar.pack(side=RIGHT, ipadx=20) def display_new_timer(self): if len(self.timers) == 0: return self.timer = self.timers.pop(0) self.timer_label.configure(text=Util.format_seconds(self.timer)) self.timer_check = self.image_window.window.after(1000, self.update_timer, self.timer) def update_timer(self, current): current -= 1 self.progressbar['value'] = 100 - (current * 100 / self.timer) if current == 10: self.image_window.play_countdown() if current > 0: self.timer_label.configure(text=Util.format_seconds(current)) self.timer_check = self.image_window.window.after(1000, self.update_timer, current) else: self.image_window.window.after_cancel(self.timer_check) if len(self.image_window.image.images) == 0 or len(self.timers) == 0: self.image_window.window.destroy() self.image_window.window.update() return self.image_window.next_image() def toggle_black_white(self): self.image_window.option["bw"] = not self.image_window.option["bw"] self.bw_button.configure(fg_color=Util.get_default_active_button_color() if self.image_window.option[ "bw"] else Util.get_default_button_color()) self.image_window.image.apply_options() def toggle_mirror(self): self.image_window.option["mirror"] = not self.image_window.option["mirror"] self.mirror_button.configure(fg_color=Util.get_default_active_button_color() if self.image_window.option[ "mirror"] else Util.get_default_button_color()) self.image_window.image.apply_options() def toggle_timer(self): try: self.timer_label.pack_info() self.timer_label.pack_forget() self.progressbar.pack_info() self.progressbar.pack_forget() except TclError: self.timer_label.pack(side=RIGHT, ipadx=20) self.progressbar.pack(side=RIGHT, ipadx=20) def open_folder(self): if sys.platform == "win32": os.startfile(self.image_window.app.selected_folder) else: opener = "open" if sys.platform == "darwin" else "xdg-open" subprocess.call([opener, self.image_window.app.selected_folder]) def toggle_always_on_top(self): self.image_window.option["always_on_top"] = not self.image_window.option["always_on_top"] if self.image_window.option["always_on_top"]: self.always_on_top_button.configure(fg_color=Util.get_default_active_button_color()) self.stay_on_top() else: self.always_on_top_button.configure(fg_color=Util.get_default_active_button_color()) self.image_window.window.after_cancel(self.always_on_top_check) def stay_on_top(self): # self.window.lift() self.image_window.window.attributes('-topmost', True) self.always_on_top_check = self.image_window.window.after(2000, self.stay_on_top) def toggle_fullscreen(self): self.image_window.option["fullscreen"] = not self.image_window.option["fullscreen"] self.fullscreen_button.configure(fg_color=Util.get_default_active_button_color() if self.image_window.option[ "fullscreen"] else Util.get_default_button_color()) self.image_window.window.attributes("-fullscreen", self.image_window.option["fullscreen"]) def pause(self): cheating = False if not self.is_paused: cheating = askyesno("Pause", "Laisser l'image affichée ?") self.is_paused = True else: self.is_paused = False # timer is paused whatever happened if self.timer_check is not None: self.image_window.window.after_cancel(self.timer_check) self.timer_check = None else: self.timer_check = self.image_window.window.after( 1000, self.update_timer, int((100-self.progressbar['value'])*self.timer/100) ) self.image_window.image.pause(pause=self.is_paused, cheat=cheating)