import tkinter as tk from tkinter import messagebox from controller.Frames import Frames from controller.MainController import MainController class MainWindow(tk.Tk): """ View - MainWindow This view is the main view of the application, it manages the different frames/views of the application, captures the events to send them to the main controller. @author Jérémi Nihart / EndMove @link https://git.endmove.eu/EndMove/WebPicDownloader @version 1.0.1 @since 2022-09-04 """ # Variables __controller: MainController = None __views: dict = None __frame_id: int = None # Constructor def __init__(self, controller: MainController) -> None: """ Constructor * :controller: -> The main application cpntroller. """ super().__init__() # Init view repository self.__views = {} # Save and setup main controller self.__controller = controller controller.set_view(self) # Init view components & more self.__init_window() self.__init_top_menu() self.__init_bind_protocol() # START Internal methods def __init_window(self) -> None: """ [internal function] => Initialize window parameters """ self.iconbitmap(f"{self.__controller.get_config('sys_directory')}\\assets\logo.ico") # App logo window_width = 430 # App width window_height = 305 # App height x_cordinate = int((self.winfo_screenwidth()/2) - (window_width/2)) y_cordinate = int((self.winfo_screenheight()/2) - (window_height/2)) self.geometry(f"{window_width}x{window_height}+{x_cordinate}+{y_cordinate}") # App size and middle centering self.resizable(False, False) # Disable app resizing def __init_top_menu(self) -> None: """ [internal function] => Initialize top menu of the window. """ main_menu = tk.Menu(self) # Top menu File item col1_menu = tk.Menu(main_menu, tearoff=0) col1_menu.add_command(label="Open app folder", command=self.__controller.on_open_folder) col1_menu.add_separator() col1_menu.add_command(label="Quit", command=self.__controller.on_quite) main_menu.add_cascade(label="File", menu=col1_menu) # Top menu Help item col2_menu = tk.Menu(main_menu, tearoff=0) col2_menu.add_command(label="Check for update", command=self.__controller.on_check_for_update) col2_menu.add_command(label="About", command=self.__controller.on_about) main_menu.add_cascade(label="Help", menu=col2_menu) self.config(menu=main_menu) def __init_bind_protocol(self) -> None: """ [internal function] => Initialize the function bindding on events of the main window. """ self.protocol("WM_DELETE_WINDOW", self.__controller.on_quite) # END Internal methods # START App methods def add_view(self, frame, view) -> None: """ [function for app] * :frame: -> the frame id of the view to add. """ self.__views[frame] = view # END App methods # START Controller methods def set_window_title(self, title: str) -> None: """ [function for controller] => Sets the title of the main window. * :title: -> Window title. """ self.title(title) def show_frame(self, frame: Frames) -> None: """ [function for app & controller] => Allows to display the selected frame provided that it has been previously added to the frame dictionary. * :frame: -> the frame if of the view to display. """ if self.__views.get(frame): if self.__frame_id: self.__views.get(self.__frame_id).pack_forget() self.__views.get(frame).pack(fill=tk.BOTH, expand=False) self.__frame_id = frame else: raise ValueError("Unable to find the requested Frame") def close_window(self) -> None: """ [function for controller] => Closes the main window and stops the program from the controller. """ self.destroy() def show_question_dialog(self, title: str, message: str, icon: str='question') -> bool: """ [function for controller] => Display a question dialog to the user, which he can answer with yes or no. * :title: -> Title of the dialogue. * :message: -> Message of the dialogue displayed to the user. * :icon: -> Icon of the dialogue displayed to the user. * RETURN -> True id the user selected yes, False else. """ return True if (messagebox.askquestion(title, message, icon=icon) == "yes") else False def show_information_dialog(self, title: str, message: str, icon: str='info') -> None: """ [function for controller] => Display an information dialog to the user. * :title: -> Title of the dialogue. * :message: -> Message of the dialogue displayed to the user. * :icon: -> Icon of the dialogue displayed to the user. """ messagebox.showinfo(title, message, icon=icon) # END Controller methods