99import customtkinter as ctk
1010from styles import *
1111from matplotlib .ticker import MaxNLocator
12- from notifypy import Notify
12+ from win11toast import toast
1313import random
14+ from matplotlib .ticker import FuncFormatter
1415
1516APPNAME = "Timer App"
1617FILENAME = "Timer Data.xlsx"
@@ -128,9 +129,7 @@ def create_time_spent_graph(date_list, duration_list):
128129 grouped_data = df .groupby ("Date" )["Duration" ].sum ().reset_index ()
129130 fig1 , ax1 = plt .subplots ()
130131 ax1 .bar (grouped_data ["Date" ], grouped_data ["Duration" ], color = graph_color )
131- ax1 .set_xlabel ("Date" , color = font_color )
132- ax1 .set_ylabel ("Duration in minutes" , color = font_color )
133- ax1 .set_title ("Time Spent by Date" , color = font_color )
132+ ax1 .set_title ("Duration of Study Sessions by Date" , color = font_color )
134133 ax1 .tick_params (colors = "white" )
135134 ax1 .set_facecolor (graph_fg_color )
136135 fig1 .set_facecolor (graph_bg_color )
@@ -141,6 +140,10 @@ def create_time_spent_graph(date_list, duration_list):
141140 fig1 .set_size_inches (graph_width / 100 , graph_height / 100 , forward = True )
142141 ax1 .set_xticklabels (grouped_data ["Date" ], rotation = 45 , ha = 'right' )
143142
143+ def format_func (value , tick_number ):
144+ return f"{ int (value )} m"
145+
146+ plt .gca ().yaxis .set_major_formatter (FuncFormatter (format_func ))
144147 date_format = mdates .DateFormatter ("%d/%m" )
145148 ax1 .xaxis .set_major_formatter (date_format )
146149 ax1 .xaxis .set_major_locator (MaxNLocator (integer = True , prune = 'both' ))
@@ -215,19 +218,18 @@ def save_weekday():
215218 print ("Weekday saved." )
216219
217220
218- def autopct_format (values ):
219- def my_format (pct ):
220- total = sum (values )
221- val = int (round (pct * total / 100.0 ))
222- return "{v:d}" .format (v = val )
223- return my_format
224-
225-
226221def create_weekday_graph (day_duration_list , day_name_list ):
227222 global pie_color_1 , pie_color_2 , pie_color_3 , pie_color_4 , pie_color_5 , pie_color_6 , pie_color_7
228223 non_zero_durations = [duration for duration in day_duration_list if duration != 0 ]
229224 non_zero_names = [name for name , duration in zip (day_name_list , day_duration_list ) if duration != 0 ]
230225
226+ def autopct_format (values ):
227+ def my_format (pct ):
228+ total = sum (values )
229+ val = int (round (pct * total / 100.0 ))
230+ return "{v:d} m" .format (v = val )
231+ return my_format
232+
231233 fig2 , ax2 = plt .subplots ()
232234 ax2 .pie (non_zero_durations , labels = non_zero_names , autopct = autopct_format (non_zero_durations ),
233235 colors = [pie_color_1 , pie_color_2 , pie_color_3 , pie_color_4 , pie_color_5 , pie_color_6 , pie_color_7 ],
@@ -236,7 +238,7 @@ def create_weekday_graph(day_duration_list, day_name_list):
236238 fig2 .set_facecolor (graph_bg_color )
237239 ax2 .tick_params (colors = "white" )
238240 ax2 .set_facecolor (graph_fg_color )
239- ax2 .set_title ("Time Spent by Weekday " , color = font_color )
241+ ax2 .set_title ("Duration of Study Sessions by Day of the Week " , color = font_color )
240242 ax2 .spines ["top" ].set_color (spine_color )
241243 ax2 .spines ["bottom" ].set_color (spine_color )
242244 ax2 .spines ["left" ].set_color (spine_color )
@@ -376,13 +378,12 @@ def save_data():
376378 global timer_running , timer_time , start_time , timer_btn , timer_label
377379 global break_running , break_time , break_btn , break_label
378380
379- notification_limit = False
380-
381- progressbar .set (0 )
382-
383381 if timer_time < 60 :
384382 print ("No data to save." )
385383 return
384+
385+ progressbar .set (0 )
386+ notification_limit = False
386387 timer_running , break_running = False , False
387388
388389 duration = calculate_duration ()
@@ -453,9 +454,7 @@ def reset_data():
453454
454455def send_notification (title , message ):
455456 global notification_limit
456- notification = Notify ()
457- notification .title (title )
458- notification .message (message )
457+ toast (title , message )
459458 notification_limit = True
460459 print ("Notification " + title + " sent." )
461460
@@ -541,7 +540,7 @@ def load_history():
541540 break_text .configure (text = "-" )
542541
543542
544- def get_goal ():
543+ def set_goal ():
545544 global goal , goal_dropdown
546545 x = 0
547546 choice = goal_dropdown .get ()
@@ -560,14 +559,13 @@ def update_slider(timer_time):
560559 goal = 60
561560 if (timer_time / 60 ) < goal :
562561 progressbar .set ((timer_time / 60 )/ goal )
563- if not notification_limit and timer_time / 60 >= goal :
564- message = random .randint (1 ,10 )
565- messages = {1 : "Congratulations! You've reached your study goal. Take a well-deserved break and recharge!" , 2 : "Study session complete! Great job on reaching your goal. Time for a quick break!" ,
566- 3 : "You did it! Study session accomplished. Treat yourself to a moment of relaxation!" , 4 : "Well done! You've met your study goal. Now, take some time to unwind and reflect on your progress." ,
567- 5 : "Study session over! You've achieved your goal. Reward yourself with a brief pause before your next task." , 6 : "Goal achieved! Take a breather and pat yourself on the back for your hard work." ,
568- 7 : "Mission accomplished! You've hit your study target. Enjoy a short break before diving back in." , 8 : "Study session complete. Nicely done! Use this time to relax and rejuvenate before your next endeavor." ,
569- 9 : "You've reached your study goal! Treat yourself to a well-deserved break. You've earned it!" , 10 : "Goal achieved! Take a moment to celebrate your success. Your dedication is paying off!" }
570- #send_notification("Study Goal Reached", messages[message])
562+ elif not notification_limit and timer_time / 60 >= goal :
563+ message = random .choice (["Congratulations! You've reached your study goal. Take a well-deserved break and recharge!" , "Study session complete! Great job on reaching your goal. Time for a quick break!" ,
564+ "You did it! Study session accomplished. Treat yourself to a moment of relaxation!" , "Well done! You've met your study goal. Now, take some time to unwind and reflect on your progress." ,
565+ "Study session over! You've achieved your goal. Reward yourself with a brief pause before your next task." , "Goal achieved! Take a breather and pat yourself on the back for your hard work." ,
566+ "Mission accomplished! You've hit your study target. Enjoy a short break before diving back in." , "Study session complete. Nicely done! Use this time to relax and rejuvenate before your next endeavor." ,
567+ "You've reached your study goal! Treat yourself to a well-deserved break. You've earned it!" , "Goal achieved! Take a moment to celebrate your success. Your dedication is paying off!" ])
568+ send_notification ("Study Goal Reached" , message )
571569
572570
573571def load_color (color , widget_list , progressbar ):
@@ -638,7 +636,7 @@ def change_focus(event):
638636 font = (font_family , int (font_size )), fg_color = border_frame_color , button_color = border_frame_color )
639637goal_dropdown .place (anchor = "center" , relx = 0.5 , rely = 0.45 )
640638goal_btn = ctk .CTkButton (goal_frame , text = "Save" , font = (font_family , font_size ), text_color = button_font_color , fg_color = button_color , hover_color = button_highlight_color ,
641- height = button_height , command = get_goal )
639+ height = button_height , command = set_goal )
642640goal_btn .place (anchor = "s" , relx = 0.5 , rely = 0.9 )
643641
644642progress_frame = ctk .CTkFrame (goal_progress_frame , fg_color = frame_color , width = frame_width , corner_radius = 10 , height = 100 )
@@ -730,37 +728,45 @@ def change_focus(event):
730728 fg_color = tab_color , width = int (tab_frame_width * 0.95 ), height = int (tab_height * 0.7 ), hover_color = tab_highlight_color , anchor = "w" , command = lambda : switch_tab ("history" ))
731729history_btn .place (relx = 0.5 , rely = 0.5 , anchor = "center" )
732730
733- last_sessions_frame = ctk .CTkFrame (history_frame , fg_color = frame_color , corner_radius = 10 , height = (HEIGHT + ((widget_padding_x )* 2 ))/ 2 , width = WIDTH - (frame_padding * 2 ),)
734- last_sessions_frame .grid (padx = frame_padding , pady = frame_padding )
735- last_sessions_frame .grid_propagate (False )
736-
737- start_frame = ctk .CTkFrame (last_sessions_frame , fg_color = "transparent" )
738- start_frame .grid (row = 0 , column = 0 , padx = frame_padding , pady = frame_padding )
739- start_label = ctk .CTkLabel (start_frame , text = "Start" , font = (font_family , font_size ), text_color = font_color )
740- start_label .pack (padx = widget_padding_x , pady = widget_padding_y )
741- start_text = ctk .CTkLabel (start_frame , font = (font_family , font_size ), text_color = font_color )
742- start_text .pack (padx = widget_padding_x , pady = widget_padding_y )
743-
744- end_frame = ctk .CTkFrame (last_sessions_frame , fg_color = "transparent" )
745- end_frame .grid (row = 0 , column = 1 , padx = frame_padding , pady = frame_padding )
746- end_label = ctk .CTkLabel (end_frame , text = "End" , font = (font_family , font_size ), text_color = font_color )
747- end_label .pack (padx = widget_padding_x , pady = widget_padding_y )
748- end_text = ctk .CTkLabel (end_frame , text = "" , font = (font_family , font_size ), text_color = font_color )
749- end_text .pack (padx = widget_padding_x , pady = widget_padding_y )
750-
751- duration_frame = ctk .CTkFrame (last_sessions_frame , fg_color = "transparent" )
752- duration_frame .grid (row = 0 , column = 2 , padx = frame_padding , pady = frame_padding )
753- duration_label = ctk .CTkLabel (duration_frame , text = "Duration" , font = (font_family , font_size ), text_color = font_color )
754- duration_label .pack (padx = widget_padding_x , pady = widget_padding_y )
755- duration_text = ctk .CTkLabel (duration_frame , text = "" , font = (font_family , font_size ), text_color = font_color )
756- duration_text .pack (padx = widget_padding_x , pady = widget_padding_y )
757-
758- break_frame = ctk .CTkFrame (last_sessions_frame , fg_color = "transparent" )
759- break_frame .grid (row = 0 , column = 3 , padx = frame_padding , pady = frame_padding )
760- break_label = ctk .CTkLabel (break_frame , text = "Break" , font = (font_family , font_size ), text_color = font_color )
761- break_label .pack (padx = widget_padding_x , pady = widget_padding_y )
762- break_text = ctk .CTkLabel (break_frame , text = "" , font = (font_family , font_size ), text_color = font_color )
763- break_text .pack (padx = widget_padding_x , pady = widget_padding_y )
731+
732+ history_frame_frame = ctk .CTkFrame (history_frame , fg_color = frame_color , corner_radius = 10 , height = (HEIGHT + ((widget_padding_x )* 2 )), width = WIDTH - frame_padding * 2 )
733+ history_frame_frame .grid (row = 0 , column = 0 , padx = frame_padding , pady = frame_padding )
734+ history_frame_frame .pack_propagate (False )
735+
736+ history_label_frame = ctk .CTkFrame (history_frame_frame , fg_color = "transparent" , width = WIDTH - (frame_padding * 4 ))
737+ history_label_frame .pack ()
738+
739+ history_data_frame = ctk .CTkScrollableFrame (history_frame_frame , fg_color = "transparent" , width = WIDTH - (frame_padding * 4 ), height = 520 + frame_padding * 2 )
740+ history_data_frame .pack (padx = frame_padding , pady = frame_padding )
741+
742+ start_label = ctk .CTkLabel (history_label_frame , text = "Start" , font = (font_family , int (font_size * 1.5 )), text_color = font_color , fg_color = "transparent" )
743+ start_label .grid (row = 0 , column = 0 , padx = widget_padding_x , pady = widget_padding_y )
744+ end_label = ctk .CTkLabel (history_label_frame , text = "End" , font = (font_family , int (font_size * 1.5 )), text_color = font_color , fg_color = "transparent" )
745+ end_label .grid (row = 0 , column = 1 , padx = widget_padding_x , pady = widget_padding_y )
746+ duration_label = ctk .CTkLabel (history_label_frame , text = "Duration" , font = (font_family , int (font_size * 1.5 )), text_color = font_color , fg_color = "transparent" )
747+ duration_label .grid (row = 0 , column = 2 , padx = widget_padding_x , pady = widget_padding_y )
748+ break_label = ctk .CTkLabel (history_label_frame , text = "Break" , font = (font_family , int (font_size * 1.5 )), text_color = font_color , fg_color = "transparent" )
749+ break_label .grid (row = 0 , column = 3 , padx = widget_padding_x , pady = widget_padding_y )
750+
751+ start_frame = ctk .CTkFrame (history_data_frame , fg_color = "transparent" )
752+ start_frame .grid (row = 1 , column = 0 , padx = frame_padding , pady = frame_padding )
753+ start_text = ctk .CTkLabel (start_frame , font = (font_family , int (font_size * 1.25 )), text_color = font_color )
754+ start_text .pack (padx = widget_padding_x * 3 , pady = widget_padding_y )
755+
756+ end_frame = ctk .CTkFrame (history_data_frame , fg_color = "transparent" )
757+ end_frame .grid (row = 1 , column = 1 , padx = frame_padding , pady = frame_padding )
758+ end_text = ctk .CTkLabel (end_frame , text = "" , font = (font_family , int (font_size * 1.25 )), text_color = font_color )
759+ end_text .pack (padx = widget_padding_x * 3 , pady = widget_padding_y )
760+
761+ duration_frame = ctk .CTkFrame (history_data_frame , fg_color = "transparent" )
762+ duration_frame .grid (row = 1 , column = 2 , padx = frame_padding , pady = frame_padding )
763+ duration_text = ctk .CTkLabel (duration_frame , text = "" , font = (font_family , int (font_size * 1.25 )), text_color = font_color )
764+ duration_text .pack (padx = widget_padding_x * 3 , pady = widget_padding_y )
765+
766+ break_frame = ctk .CTkFrame (history_data_frame , fg_color = "transparent" )
767+ break_frame .grid (row = 1 , column = 3 , padx = frame_padding , pady = frame_padding )
768+ break_text = ctk .CTkLabel (break_frame , text = "" , font = (font_family , int (font_size * 1.25 )), text_color = font_color )
769+ break_text .pack (padx = widget_padding_x * 3 , pady = widget_padding_y )
764770
765771settings_tab = ctk .CTkFrame (tab_frame , width = tab_frame_width , height = tab_height * 0.8 , fg_color = tab_color )
766772settings_tab .place (relx = 0.5 , rely = 1 , anchor = "s" )
0 commit comments