11import os
22import random
3- import time
4- import threading
53from PIL import Image
64
75import 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