From aa347b093c8381acc05eceec46d014521867f72d Mon Sep 17 00:00:00 2001 From: Shikiryu Date: Thu, 25 May 2023 01:19:10 +0200 Subject: [PATCH 1/7] :bug: Close the window --- src/window/image.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/window/image.py b/src/window/image.py index 24f54e8..3394bb2 100644 --- a/src/window/image.py +++ b/src/window/image.py @@ -37,6 +37,7 @@ class ImageWindow: def on_closing(self): self.countdown_sound.stop() + self.window.destroy() def next_image(self): if self.toolbar.timer_check is not None: -- 2.30.2 From 95392cc6e06991b34505e479fae90981ee5182a5 Mon Sep 17 00:00:00 2001 From: Shikiryu Date: Thu, 25 May 2023 01:19:38 +0200 Subject: [PATCH 2/7] :construction: Starts sessions --- src/window/app.py | 11 +++++++++++ src/window/session.py | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/window/session.py diff --git a/src/window/app.py b/src/window/app.py index 358cfcd..f685a11 100644 --- a/src/window/app.py +++ b/src/window/app.py @@ -4,11 +4,13 @@ from pathlib import Path from src.util import Util from functools import partial from src.window.image import ImageWindow +from src.window.session import SessionWindow class App: def __init__(self, root): super().__init__() + self.session_window = None self.image_window = None self.root = root self.selected_folder = "" @@ -41,6 +43,11 @@ class App: self.button_frame.columnconfigure(i, weight=1) new_button.grid(row=0, column=i, sticky=W + E) i += 1 + + new_button = Button(self.button_frame, text="Custom", command=self.custom_session) + self.buttons.append(new_button) + self.button_frame.columnconfigure(i, weight=1) + new_button.grid(row=0, column=i, sticky=W + E) self.launch_button = Button(root, text="Let's draw!", command=self.lets_draw, state="disabled") self.launch_button.pack(side="bottom") @@ -49,6 +56,10 @@ class App: self.image_window = ImageWindow(self) self.image_window.lets_draw(self.found_images.copy(), self.timer) + def custom_session(self): + self.session_window = SessionWindow(self) + self.session_window.open(self) + def select_folder(self): self.selected_folder = filedialog.askdirectory() self.found_images = list( diff --git a/src/window/session.py b/src/window/session.py new file mode 100644 index 0000000..1fb99d6 --- /dev/null +++ b/src/window/session.py @@ -0,0 +1,25 @@ +from tkinter import * + + +class SessionWindow: + def __init__(self, app): + self.app = app + + self.window = Toplevel(app.root) + self.window.title("Custom session") + self.window.geometry("600x600") + self.window.protocol("WM_DELETE_WINDOW", self.save_on_closing) + + self.list_in_session = [] + + self.update_session_list() + + + def update_session_list(self): + for i, session in enumerate(self.list_in_session): + new_session = Button(text="") + new_session.grid(row=i, column=0) + + def save_on_closing(self): + # TODO save + self.window.destroy() -- 2.30.2 From 658e96c6d31f1ed25dbddcd1de25ffa60f3c7005 Mon Sep 17 00:00:00 2001 From: Shikiryu Date: Thu, 25 May 2023 01:19:38 +0200 Subject: [PATCH 3/7] :construction: Starts sessions --- src/window/app.py | 6 +++--- src/window/session.py | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/window/app.py b/src/window/app.py index f685a11..872e778 100644 --- a/src/window/app.py +++ b/src/window/app.py @@ -43,7 +43,7 @@ class App: self.button_frame.columnconfigure(i, weight=1) new_button.grid(row=0, column=i, sticky=W + E) i += 1 - + new_button = Button(self.button_frame, text="Custom", command=self.custom_session) self.buttons.append(new_button) self.button_frame.columnconfigure(i, weight=1) @@ -58,8 +58,8 @@ class App: def custom_session(self): self.session_window = SessionWindow(self) - self.session_window.open(self) - + self.session_window.open() + def select_folder(self): self.selected_folder = filedialog.askdirectory() self.found_images = list( diff --git a/src/window/session.py b/src/window/session.py index 1fb99d6..d10c026 100644 --- a/src/window/session.py +++ b/src/window/session.py @@ -1,8 +1,12 @@ +from functools import partial from tkinter import * class SessionWindow: def __init__(self, app): + self.selected_element_index = 0 + self.delete_button = None + self.add_button = None self.app = app self.window = Toplevel(app.root) @@ -10,16 +14,51 @@ class SessionWindow: self.window.geometry("600x600") self.window.protocol("WM_DELETE_WINDOW", self.save_on_closing) + self.left_column = Frame(self.window, width=300, height=600) + self.right_column = Frame(self.window, width=300, height=600) + + self.left_column.grid(row=0, column=0, sticky="ns") + self.right_column.grid(row=0, column=1, sticky="ns") + self.list_in_session = [] + def open(self): self.update_session_list() + self.add_button = Button(self.left_column, text="+", command=self.add_element) + self.add_button.pack() + + self.delete_button = Button(self.left_column, text="-", command=self.remove_element) + self.delete_button.pack() def update_session_list(self): for i, session in enumerate(self.list_in_session): - new_session = Button(text="") + new_session = Button(self.left_column, text="element " + str(i), command=partial(self.edit_element, i)) new_session.grid(row=i, column=0) + def remove_element(self): + self.list_in_session.pop(self.selected_element_index) + + def edit_element(self, i): + self.selected_element_index = i + element = self.list_in_session[self.selected_element_index] + + number_of_drawings_label = Text(self.right_column) + number_of_drawings_label.insert(INSERT, "Nombre de dessins :") + number_of_drawings_label.pack() + + number_of_drawings_input = Entry(self.right_column) + number_of_drawings_input.insert(INSERT, element.number_of_drawings) + number_of_drawings_input.pack() + + def add_element(self): + number_of_drawings_label = Text(self.right_column) + number_of_drawings_label.insert(INSERT, "Nombre de dessins :") + number_of_drawings_label.pack() + + number_of_drawings_input = Entry(self.right_column) + number_of_drawings_input.pack() + def save_on_closing(self): # TODO save self.window.destroy() -- 2.30.2 From 0cca0b05ed178ffcbbb9c31134594c3a42a93682 Mon Sep 17 00:00:00 2001 From: Clement Desmidt Date: Wed, 31 May 2023 16:47:22 +0200 Subject: [PATCH 4/7] :construction: Allow CRUD of session --- src/entity/session/drawing.py | 6 +++ src/window/session.py | 93 ++++++++++++++++++++++++++--------- 2 files changed, 77 insertions(+), 22 deletions(-) create mode 100644 src/entity/session/drawing.py diff --git a/src/entity/session/drawing.py b/src/entity/session/drawing.py new file mode 100644 index 0000000..bbe4899 --- /dev/null +++ b/src/entity/session/drawing.py @@ -0,0 +1,6 @@ + + +class DrawingElement: + def __init__(self): + self.timer = 0 + self.number_of_drawings = 0 diff --git a/src/window/session.py b/src/window/session.py index d10c026..88ec349 100644 --- a/src/window/session.py +++ b/src/window/session.py @@ -1,10 +1,14 @@ from functools import partial from tkinter import * +from src.entity.session.drawing import DrawingElement + class SessionWindow: def __init__(self, app): - self.selected_element_index = 0 + self.timer_input = None + self.number_of_drawings_input = None + self.selected_element_index = -1 self.delete_button = None self.add_button = None self.app = app @@ -25,39 +29,84 @@ class SessionWindow: def open(self): self.update_session_list() + def update_session_list(self): + self.reset_list() + for i, session in enumerate(self.list_in_session): + new_session = Button(self.left_column, + text=session.number_of_drawings + " drawings of "+session.timer+"s each", + command=partial(self.edit_element, i) + ) + new_session.grid(row=i, column=0) + self.add_button = Button(self.left_column, text="+", command=self.add_element) - self.add_button.pack() + self.add_button.grid() self.delete_button = Button(self.left_column, text="-", command=self.remove_element) - self.delete_button.pack() + self.delete_button.grid() - def update_session_list(self): - for i, session in enumerate(self.list_in_session): - new_session = Button(self.left_column, text="element " + str(i), command=partial(self.edit_element, i)) - new_session.grid(row=i, column=0) + def reset_element(self): + for widget in self.right_column.winfo_children(): + widget.destroy() + + def reset_list(self): + for widget in self.left_column.winfo_children(): + widget.destroy() + + def update_element(self, index=None): + if index is not None: + self.selected_element_index = index + element = self.list_in_session[self.selected_element_index] + else: + element = DrawingElement() + + number_of_drawings_label = Label(self.right_column, text="Number of drawings") + number_of_drawings_label.pack() + + self.number_of_drawings_input = Entry(self.right_column) + self.number_of_drawings_input.insert(INSERT, element.number_of_drawings) + self.number_of_drawings_input.pack() + + timer_label = Label(self.right_column, text="Time per drawing in seconds") + timer_label.pack() + + self.timer_input = Entry(self.right_column) + self.timer_input.insert(INSERT, element.timer) + self.timer_input.pack() + + row_time = IntVar() + total_row_time_label = Label(self.right_column, text="Total row time") + total_row_time_label.pack() + total_row_time_value_label = Label(self.right_column, textvariable=row_time) + total_row_time_value_label.pack() + + save_button = Button(self.right_column, text="Save", command=self.save) + save_button.pack() def remove_element(self): self.list_in_session.pop(self.selected_element_index) + self.selected_element_index = -1 + self.update_session_list() def edit_element(self, i): - self.selected_element_index = i - element = self.list_in_session[self.selected_element_index] - - number_of_drawings_label = Text(self.right_column) - number_of_drawings_label.insert(INSERT, "Nombre de dessins :") - number_of_drawings_label.pack() - - number_of_drawings_input = Entry(self.right_column) - number_of_drawings_input.insert(INSERT, element.number_of_drawings) - number_of_drawings_input.pack() + self.update_element(i) def add_element(self): - number_of_drawings_label = Text(self.right_column) - number_of_drawings_label.insert(INSERT, "Nombre de dessins :") - number_of_drawings_label.pack() + self.update_element() - number_of_drawings_input = Entry(self.right_column) - number_of_drawings_input.pack() + def save(self): + element = DrawingElement() if self.selected_element_index < 0 \ + else self.list_in_session[self.selected_element_index] + element.timer = self.timer_input.get() + element.number_of_drawings = self.number_of_drawings_input.get() + + if self.selected_element_index < 0: + self.list_in_session.append(element) + else: + self.list_in_session[self.selected_element_index] = element + + self.update_session_list() + self.selected_element_index = -1 + self.reset_element() def save_on_closing(self): # TODO save -- 2.30.2 From 25314fde080b7567ce9ba6ebd9a3b79c7a1af01e Mon Sep 17 00:00:00 2001 From: Clement Desmidt Date: Thu, 1 Jun 2023 17:36:25 +0200 Subject: [PATCH 5/7] :construction: Add up, down and config --- .gitignore | 1 + src/entity/config.py | 49 ++++++++++++++++++++++++++++++++ src/window/app.py | 3 ++ src/window/session.py | 66 +++++++++++++++++++++++++++++++++++++------ 4 files changed, 110 insertions(+), 9 deletions(-) create mode 100644 src/entity/config.py diff --git a/.gitignore b/.gitignore index cbcdc08..6233d3c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ theme.py !/dist/drawingtraining /*.spec /build/ +/config.json diff --git a/src/entity/config.py b/src/entity/config.py new file mode 100644 index 0000000..b90ae42 --- /dev/null +++ b/src/entity/config.py @@ -0,0 +1,49 @@ +import json +import os +from pathlib import Path + +from configparser import * +import typing + + +class Config(object): + + _CONFIG_FILE: typing.Optional[str] = None + _CONFIG: typing.Optional[dict] = None + + def __init__(self, config_file=None): + if config_file is None: + config_file = "config.json" + + # Check that specified config file exists + if not os.path.exists(config_file): + Path(config_file).touch() + with open(config_file, 'w') as configfile: + json.dump({"session": []}, configfile) + + Config._CONFIG_FILE = config_file + + with open(config_file, 'r') as f: + Config._CONFIG = json.load(f) + + @staticmethod + def save(): + with open(Config._CONFIG_FILE, 'w') as configfile: + json.dump(Config._CONFIG, configfile) + + @staticmethod + def get_config_file() -> str: + return Config._CONFIG_FILE + + @staticmethod + def get_required_env_var(env_var: str) -> str: + if env_var not in os.environ: + raise Exception(f"Please set the {env_var} environment variable") + return os.environ[env_var] + + @staticmethod + def get_required_config_var(config_var: str) -> str: + assert Config._CONFIG + if config_var not in Config._CONFIG: + raise Exception(f"Please set the {config_var} variable in the config file {Config._CONFIG_FILE}") + return Config._CONFIG[config_var] diff --git a/src/window/app.py b/src/window/app.py index 872e778..a665a17 100644 --- a/src/window/app.py +++ b/src/window/app.py @@ -1,6 +1,8 @@ from tkinter import * from tkinter import filedialog from pathlib import Path + +from src.entity.config import Config from src.util import Util from functools import partial from src.window.image import ImageWindow @@ -10,6 +12,7 @@ from src.window.session import SessionWindow class App: def __init__(self, root): super().__init__() + self.config = Config() self.session_window = None self.image_window = None self.root = root diff --git a/src/window/session.py b/src/window/session.py index 88ec349..f2d574c 100644 --- a/src/window/session.py +++ b/src/window/session.py @@ -1,11 +1,16 @@ from functools import partial from tkinter import * +from src.entity.config import Config from src.entity.session.drawing import DrawingElement +from src.util import Util class SessionWindow: def __init__(self, app): + self.total_row_time_value_label = None + self.down_button = None + self.up_button = None self.timer_input = None self.number_of_drawings_input = None self.selected_element_index = -1 @@ -32,17 +37,30 @@ class SessionWindow: def update_session_list(self): self.reset_list() for i, session in enumerate(self.list_in_session): + bg = "blue" if i == self.selected_element_index else "grey85" new_session = Button(self.left_column, - text=session.number_of_drawings + " drawings of "+session.timer+"s each", - command=partial(self.edit_element, i) + text=session.number_of_drawings + " drawings of " + session.timer + "s each", + command=partial(self.edit_element, i), + bg=bg ) new_session.grid(row=i, column=0) - self.add_button = Button(self.left_column, text="+", command=self.add_element) - self.add_button.grid() + button_frame = Frame(self.left_column) + self.add_button = Button(button_frame, text="+", command=self.add_element) + self.add_button.pack(side=LEFT, padx=0, pady=0) - self.delete_button = Button(self.left_column, text="-", command=self.remove_element) - self.delete_button.grid() + self.delete_button = Button(button_frame, text="-", command=self.remove_element) + self.delete_button.pack(side=LEFT, padx=0, pady=0) + + self.up_button = Button(button_frame, text="^", command=self.up_element) + self.up_button.pack(side=LEFT, padx=0, pady=0) + + self.down_button = Button(button_frame, text="v", command=self.down_element) + self.down_button.pack(side=LEFT, padx=0, pady=0) + + self.save_session_button = Button(button_frame, text="v", command=self.save_session) + self.save_session_button.pack(side=LEFT, padx=0, pady=0) + button_frame.grid() def reset_element(self): for widget in self.right_column.winfo_children(): @@ -53,9 +71,11 @@ class SessionWindow: widget.destroy() def update_element(self, index=None): + self.reset_element() if index is not None: self.selected_element_index = index element = self.list_in_session[self.selected_element_index] + self.update_session_list() else: element = DrawingElement() @@ -64,24 +84,32 @@ class SessionWindow: self.number_of_drawings_input = Entry(self.right_column) self.number_of_drawings_input.insert(INSERT, element.number_of_drawings) + self.number_of_drawings_input.bind("", lambda e: self.update_local_timer(e)) self.number_of_drawings_input.pack() + self.number_of_drawings_input.focus_set() timer_label = Label(self.right_column, text="Time per drawing in seconds") timer_label.pack() self.timer_input = Entry(self.right_column) self.timer_input.insert(INSERT, element.timer) + self.timer_input.bind("", lambda e: self.update_local_timer(e)) self.timer_input.pack() - row_time = IntVar() total_row_time_label = Label(self.right_column, text="Total row time") total_row_time_label.pack() - total_row_time_value_label = Label(self.right_column, textvariable=row_time) - total_row_time_value_label.pack() + self.total_row_time_value_label = Label(self.right_column, text="") + self.total_row_time_value_label.pack() + self.update_local_timer() save_button = Button(self.right_column, text="Save", command=self.save) save_button.pack() + def update_local_timer(self, event=None): + self.total_row_time_value_label.config( + text=Util.format_seconds(int(self.timer_input.get()) * int(self.number_of_drawings_input.get())) + ) + def remove_element(self): self.list_in_session.pop(self.selected_element_index) self.selected_element_index = -1 @@ -91,8 +119,22 @@ class SessionWindow: self.update_element(i) def add_element(self): + self.selected_element_index = -1 + self.update_session_list() self.update_element() + def up_element(self): + self.list_in_session.insert(self.selected_element_index - 1, + self.list_in_session.pop(self.selected_element_index)) + self.selected_element_index -= 1 + self.update_session_list() + + def down_element(self): + self.list_in_session.insert(self.selected_element_index + 1, + self.list_in_session.pop(self.selected_element_index)) + self.selected_element_index += 1 + self.update_session_list() + def save(self): element = DrawingElement() if self.selected_element_index < 0 \ else self.list_in_session[self.selected_element_index] @@ -111,3 +153,9 @@ class SessionWindow: def save_on_closing(self): # TODO save self.window.destroy() + + def save_session(self): + for element in self.list_in_session: + Config._CONFIG['session'].append(element) + Config.save() + self.window.destroy() -- 2.30.2 From e2546c7bfb1b7e1203272d8200d8e51e4fbb5325 Mon Sep 17 00:00:00 2001 From: Shikiryu Date: Fri, 2 Jun 2023 09:38:35 +0200 Subject: [PATCH 6/7] :construction: Save session to app --- src/window/app.py | 9 +++++++-- src/window/session.py | 7 ++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/window/app.py b/src/window/app.py index a665a17..65b70c7 100644 --- a/src/window/app.py +++ b/src/window/app.py @@ -12,7 +12,9 @@ from src.window.session import SessionWindow class App: def __init__(self, root): super().__init__() + self.custom = False self.config = Config() + self.session = None self.session_window = None self.image_window = None self.root = root @@ -41,7 +43,6 @@ class App: t = i new_button = Button(self.button_frame, text=Util.format_seconds(t), command=partial(self.set_timer_in_seconds, t)) - self.buttons.append(new_button) self.button_frame.columnconfigure(i, weight=1) new_button.grid(row=0, column=i, sticky=W + E) @@ -72,7 +73,7 @@ class App: self.check_lets_draw() def check_lets_draw(self): - if self.selected_folder != "" and len(self.found_images) > 0 and self.timer != 0: + if self.selected_folder != "" and len(self.found_images) > 0 and (self.timer != 0 or self.custom): self.launch_button.config(state="normal") else: self.launch_button.config(state="disabled") @@ -85,3 +86,7 @@ class App: else: button.config(bg="gray85") self.check_lets_draw() + + def set_custom(self, list_in_session): + self.custom = True + self.list_in_session = list_in_session diff --git a/src/window/session.py b/src/window/session.py index f2d574c..1c83a65 100644 --- a/src/window/session.py +++ b/src/window/session.py @@ -58,8 +58,8 @@ class SessionWindow: self.down_button = Button(button_frame, text="v", command=self.down_element) self.down_button.pack(side=LEFT, padx=0, pady=0) - self.save_session_button = Button(button_frame, text="v", command=self.save_session) - self.save_session_button.pack(side=LEFT, padx=0, pady=0) + save_session_button = Button(button_frame, text="v", command=self.save_session) + save_session_button.pack(side=LEFT, padx=0, pady=0) button_frame.grid() def reset_element(self): @@ -156,6 +156,7 @@ class SessionWindow: def save_session(self): for element in self.list_in_session: - Config._CONFIG['session'].append(element) + Config._CONFIG['session'].append(element.__dict__) Config.save() + self.app.set_custom(self.list_in_session) self.window.destroy() -- 2.30.2 From a149ab71bba26696524834bf96144f1afa92ac6b Mon Sep 17 00:00:00 2001 From: Clement Desmidt Date: Fri, 2 Jun 2023 12:21:12 +0200 Subject: [PATCH 7/7] :sparkles: Add sessions --- src/element/toolbar.py | 4 +++- src/entity/session/drawing.py | 10 +++++++--- src/window/app.py | 6 ++++++ src/window/image.py | 11 ++++++++++- src/window/session.py | 4 ++++ 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/element/toolbar.py b/src/element/toolbar.py index eadf2c8..fa270e4 100644 --- a/src/element/toolbar.py +++ b/src/element/toolbar.py @@ -8,6 +8,7 @@ from src.util import Util class Toolbar: def __init__(self, image_window, timer): + self.timers = [] self.current_image = None self.current_original_image = None self.image_window = image_window @@ -47,6 +48,7 @@ class Toolbar: self.timer_label.pack(side=RIGHT, ipadx=20) def display_new_timer(self): + 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) @@ -59,7 +61,7 @@ class Toolbar: 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.images) == 0: + if len(self.image_window.image.images) == 0 or len(self.timers) == 0: self.image_window.window.destroy() self.image_window.window.update() return diff --git a/src/entity/session/drawing.py b/src/entity/session/drawing.py index bbe4899..d98e5e7 100644 --- a/src/entity/session/drawing.py +++ b/src/entity/session/drawing.py @@ -1,6 +1,10 @@ class DrawingElement: - def __init__(self): - self.timer = 0 - self.number_of_drawings = 0 + def __init__(self, data=None): + if data is not None: + for key, value in data.items(): + setattr(self, key, value) + else: + self.timer = 0 + self.number_of_drawings = 0 diff --git a/src/window/app.py b/src/window/app.py index 65b70c7..1b435a0 100644 --- a/src/window/app.py +++ b/src/window/app.py @@ -12,6 +12,7 @@ from src.window.session import SessionWindow class App: def __init__(self, root): super().__init__() + self.list_in_session = None self.custom = False self.config = Config() self.session = None @@ -79,6 +80,7 @@ class App: self.launch_button.config(state="disabled") def set_timer_in_seconds(self, user_data): + self.custom = False self.timer = user_data for button in self.buttons: if button['text'] == Util.format_seconds(self.timer): @@ -90,3 +92,7 @@ class App: def set_custom(self, list_in_session): self.custom = True self.list_in_session = list_in_session + self.check_lets_draw() + for button in self.buttons: + button.config(bg="gray85") + self.buttons[-1].config(bg="blue") diff --git a/src/window/image.py b/src/window/image.py index 3394bb2..2c654d2 100644 --- a/src/window/image.py +++ b/src/window/image.py @@ -47,8 +47,17 @@ class ImageWindow: def lets_draw(self, images, timer): random.shuffle(images) + timers = [] + if self.app.custom: + for element in self.app.list_in_session: + for number in range(int(element.number_of_drawings)): + timers.append(int(element.timer)) + else: + for i in images: + timers.append(timer) + self.image.images = images - self.toolbar.timer = timer + self.toolbar.timers = timers self.next_image() def play_countdown(self): diff --git a/src/window/session.py b/src/window/session.py index 1c83a65..58298a9 100644 --- a/src/window/session.py +++ b/src/window/session.py @@ -32,6 +32,9 @@ class SessionWindow: self.list_in_session = [] def open(self): + list = Config._CONFIG['session'] + if list: + self.list_in_session = [DrawingElement(e) for e in list] self.update_session_list() def update_session_list(self): @@ -155,6 +158,7 @@ class SessionWindow: self.window.destroy() def save_session(self): + Config._CONFIG['session'] = [] for element in self.list_in_session: Config._CONFIG['session'].append(element.__dict__) Config.save() -- 2.30.2