Skip to content

Commit 6a731a1

Browse files
committed
Added auto-break
1 parent f1f8dd2 commit 6a731a1

3 files changed

Lines changed: 105 additions & 40 deletions

File tree

Package/data_management.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,35 @@ def save_weekday_data(self) -> None:
239239
self.worksheet["W8"].value = self.sunday_duration
240240

241241

242-
def save_autobreak(self, frequency: str, duration: str) -> None:
243-
frequency = int(frequency)
244-
duration = int(duration)
245-
print(frequency, duration)
242+
def save_autobreak(self, frequency: str, duration: str, switch: str) -> None:
243+
self.worksheet["P2"].value = switch
244+
self.worksheet["P3"].value = int(frequency)
245+
self.worksheet["P4"].value = int(duration)
246+
247+
self.workbook.save(self.app.data_file)
248+
249+
self.load_autobreak()
250+
251+
252+
def load_autobreak(self):
253+
self.autobreak_on = self.worksheet["P2"].value
254+
self.autobreak_frequency = self.worksheet["P3"].value
255+
self.autobreak_duration = self.worksheet["P4"].value
256+
257+
if self.worksheet["P2"].value == None:
258+
self.autobreak_on = "Off"
259+
260+
if self.autobreak_frequency == None:
261+
self.autobreak_frequency = 25
262+
263+
if self.autobreak_duration == None:
264+
self.autobreak_duration = 5
265+
266+
self.app.frequency_input.configure(placeholder_text=self.autobreak_frequency)
267+
self.app.duration_input.configure(placeholder_text=self.autobreak_duration)
268+
self.app.autobreak_switch.configure(variable=ctk.StringVar(value=self.autobreak_on))
269+
270+
self.app.WINDOW.after(0, self.app.auto_break)
246271

247272

248273
def set_color(self, color_dropdown) -> None:
@@ -382,4 +407,4 @@ def load_eye_care(self) -> None:
382407

383408
self.app.eye_care_checkbox.configure(variable=ctk.StringVar(value=checkbox))
384409

385-
self.app.t1.start()
410+
self.app.WINDOW.after(0, self.app.eye_protection) # Schedule initial iteration for eye_protection

Package/timer_management.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ def initialize_variables(self):
1717
def timer_mechanism(self, timer_button, break_button, time_display_label):
1818
self.time_display_label = time_display_label
1919
if not self.timer_running:
20+
self.app.frequency_input.configure(state="disabled")
21+
self.app.frequency_input.insert("end", self.app.data_manager.autobreak_frequency)
22+
self.app.duration_input.configure(state="disabled")
23+
self.app.duration_input.insert("end", self.app.data_manager.autobreak_duration)
24+
self.app.autobreak_button.configure(state="readonly")
25+
2026
self.timer_running = True
2127
self.break_running = False
2228
timer_button.configure(text="Stop")
@@ -32,6 +38,7 @@ def _update_time(self):
3238
if self.timer_running:
3339
self.timer_time += 1
3440
self.time_display_label.configure(text=str(datetime.timedelta(seconds=self.timer_time)))
41+
self.app.progressbar.set(self.timer_time/60/self.app.goal)
3542
self.app.reach_goal(self.timer_time)
3643
self.window.after(1000, self._update_time)
3744

main.py

Lines changed: 68 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import os
22
import random
3-
import time
4-
import threading
53
from PIL import Image
64

75
import openpyxl as op
@@ -29,11 +27,9 @@ def __init__(self):
2927
self.create_gui()
3028
self._file_setup()
3129

32-
self.t1 = threading.Thread(target=self.eye_protection)
33-
self.stop_event = threading.Event()
34-
3530
self.data_manager.load_subject()
3631
self.data_manager.load_eye_care()
32+
self.data_manager.load_autobreak()
3733

3834
self.WINDOW.bind_all("<Button>", self.change_focus)
3935
self.WINDOW.protocol("WM_DELETE_WINDOW", self.save_on_quit)
@@ -172,7 +168,7 @@ def _initialize_tab(tab_name: str, icon: ctk.CTkImage) -> None:
172168

173169
#Place settings tab frame on the bottom of tab frame
174170
if tab_name == "Settings":
175-
tab.place(relx=0.5, rely=1, anchor="s")
171+
tab.place(relx=0.5, rely=0.995, anchor="s")
176172
else:
177173
tab.pack(pady=tab_padding_y)
178174
tab_button.place(relx=0.5, rely=0.5, anchor="center")
@@ -456,9 +452,9 @@ def _autobreak_gui_setup(self) -> None:
456452
font=(font_family, int(font_size)), fg_color=(light_border_frame_color, border_frame_color), button_color=(light_border_frame_color, border_frame_color), border_color=(light_border_frame_color, border_frame_color))
457453
self.autobreak_switch.pack()
458454

459-
autobreak_button = ctk.CTkButton(autobreak_frame, text="Save", font=(font_family, font_size), fg_color=button_color, text_color=button_font_color,
455+
self.autobreak_button = ctk.CTkButton(autobreak_frame, text="Save", font=(font_family, font_size), fg_color=button_color, text_color=button_font_color,
460456
border_color=frame_border_color, hover_color=button_highlight_color, height=button_height, command=self.save_autobreak)
461-
autobreak_button.place(anchor="s", relx=0.5, rely=0.925)
457+
self.autobreak_button.place(anchor="s", relx=0.5, rely=0.925)
462458

463459

464460
def _notes_gui_setup(self) -> None:
@@ -531,7 +527,7 @@ def _format_func(value, tick_number):
531527
ax.xaxis.set_major_formatter(date_format)
532528
ax.xaxis.set_major_locator(MaxNLocator(integer=True, prune='both'))
533529
time_spent_frame = FigureCanvasTkAgg(fig, master=frame)
534-
plt.subplots_adjust(bottom=0.2)
530+
plt.subplots_adjust(bottom=0.15)
535531

536532
time_spent_graph = time_spent_frame.get_tk_widget()
537533
time_spent_graph.pack(padx=widget_padding_x, pady=widget_padding_y)
@@ -557,7 +553,7 @@ def _my_format(pct):
557553

558554
fig, ax = plt.subplots()
559555
ax.pie(non_zero_durations, labels=non_zero_names, autopct=_autopct_format(non_zero_durations), colors=self.data_manager.pie_colors,
560-
textprops={"fontsize": pie_font_size, "family": pie_font_family, "color": font_color}, counterclock=False, startangle=90)
556+
textprops={"fontsize": pie_font_size, "family": pie_font_family, "color": self.data_manager.font_color}, counterclock=False, startangle=90)
561557
fig.set_size_inches(graph_width/100, graph_height/100, forward=True)
562558
ax.set_facecolor(self.data_manager.graph_fg_color)
563559
fig.set_facecolor(self.data_manager.graph_bg_color)
@@ -567,6 +563,7 @@ def _my_format(pct):
567563
ax.spines["bottom"].set_color(self.data_manager.spine_color)
568564
ax.spines["left"].set_color(self.data_manager.spine_color)
569565
ax.spines["right"].set_color(self.data_manager.spine_color)
566+
plt.subplots_adjust(bottom=0.0)
570567

571568
weekday_frame = FigureCanvasTkAgg(fig, master=frame)
572569

@@ -719,6 +716,12 @@ def save_data(self) -> None:
719716

720717
#Only be able to save if time is higher than 1m
721718
if time_in_minutes >= 1:
719+
self.frequency_input.configure(state="normal")
720+
self.frequency_input.delete("end")
721+
self.duration_input.configure(state="normal")
722+
self.duration_input.delete("end")
723+
self.autobreak_button.configure(state="normal")
724+
722725
if time_in_minutes >= self.goal:
723726
self.data_manager.increase_goal_streak()
724727

@@ -739,40 +742,72 @@ def save_data(self) -> None:
739742
def save_autobreak(self) -> None:
740743
frequency_input = self.frequency_input.get()[:2]
741744
if len(frequency_input) == 0:
742-
frequency_input = "30"
743-
elif not frequency_input.isdigit():
744-
return
745+
frequency_input = self.data_manager.autobreak_frequency
746+
else:
747+
if self.data_manager.autobreak_frequency != self.frequency_input.cget("placeholder_text"):
748+
if len(frequency_input) == 0 or int(frequency_input) < 1:
749+
frequency_input = "25"
750+
elif not frequency_input.isdigit():
751+
return
745752

746753
duration_input = self.duration_input.get()[:2]
747754
if len(duration_input) == 0:
748-
duration_input = "30"
749-
elif not duration_input.isdigit():
750-
return
755+
duration_input = self.data_manager.autobreak_duration
756+
else:
757+
if self.data_manager.autobreak_duration != self.duration_input.cget("placeholder_text"):
758+
if len(duration_input) == 0 or int(duration_input) < 1:
759+
duration_input = "5"
760+
elif not duration_input.isdigit():
761+
return
762+
751763

752-
self.frequency_input.delete("2", "end")
753-
self.duration_input.delete("2", "end")
764+
self.frequency_input.delete("0", "end")
765+
self.duration_input.delete("0", "end")
766+
self.frequency_input.insert("0", frequency_input)
767+
self.duration_input.insert("0", duration_input)
768+
769+
if self.autobreak_switch.get() == "On":
770+
switch = "On"
771+
else:
772+
switch = "Off"
754773

755-
self.data_manager.save_autobreak(frequency_input, duration_input)
774+
print(frequency_input, duration_input)
775+
self.data_manager.save_autobreak(frequency_input, duration_input, switch)
756776

757777

758778
def eye_protection(self):
759779
checkbox = self.eye_care_checkbox.get()
760780
time_between = 60 * 20
761-
while not self.stop_event.is_set():
762-
if self.eye_care_selection.get() == "On":
763-
if checkbox == "On" and self.timer_manager.timer_running:
764-
time.sleep(time_between)
765-
if checkbox == "On" and self.timer_manager.timer_running:
766-
self.send_notification("Eye Protection", "Look away 20ft for 20 seconds")
767-
self.eye_protection()
768-
else:
769-
time.sleep(time_between)
770-
if self.eye_care_selection.get() == "On" and checkbox == "Off":
771-
self.send_notification("Eye Protection", "Look away 20ft for 20 seconds")
772-
self.eye_protection()
781+
782+
if self.eye_care_selection.get() == "On":
783+
if checkbox == "On" and self.timer_manager.timer_running:
784+
self.send_notification("Eye Protection", "It's time for a 20/20/20 break! Look away for 20 seconds at something 20 feet away.")
785+
elif checkbox == "Off":
786+
self.send_notification("Eye Protection", "It's time for a 20/20/20 break! Look away for 20 seconds at something 20 feet away.")
787+
788+
# Schedule the next iteration
789+
if self.eye_care_selection.get() == "On":
790+
self.WINDOW.after(time_between * 1000, self.eye_protection)
791+
else:
792+
self.WINDOW.after(10 * 1000, self.eye_protection)
793+
794+
795+
def auto_break(self):
796+
time_between = self.data_manager.autobreak_frequency * 60
797+
798+
def try_timer():
799+
if self.timer_manager.break_time % self.data_manager.autobreak_duration == 0:
800+
self.timer_manager.timer_mechanism(self.timer_button, self.break_button, self.time_display_label)
773801
else:
774-
time.sleep(10)
775-
self.eye_protection()
802+
self.WINDOW.after(1000, try_timer)
803+
804+
if self.autobreak_switch.get() == "On" and self.timer_manager.timer_running and self.timer_manager.timer_time % time_between == 0:
805+
self.timer_manager.break_mechanism(self.break_button, self.timer_button, self.break_display_label)
806+
self.send_notification("Auto-break", f"Time for a {self.data_manager.autobreak_duration}-minute")
807+
self.WINDOW.after(self.data_manager.autobreak_duration * 60 * 1000, try_timer)
808+
round(self.timer_manager.break_time, -1)
809+
810+
self.WINDOW.after(100, self.auto_break) # Schedule next iteration
776811

777812

778813
def load_history(self):
@@ -870,8 +905,6 @@ def save_on_quit(self) -> None:
870905
self.save_data()
871906
print("Data saved on exit.")
872907

873-
self.stop_event.set()
874-
875908
self.workbook.save(self.data_file)
876909

877910
self.WINDOW.destroy()

0 commit comments

Comments
 (0)