From d8d47a5f83e80c05a1ac4c92bd538f1a8e89d00c Mon Sep 17 00:00:00 2001 From: Alexander Rosenberg Date: Thu, 8 Sep 2022 01:18:05 -0700 Subject: [PATCH] Mostly implement mini window --- .gitignore | 4 +- CMakeLists.txt | 2 +- TimerMainWindow.c | 70 +++++++++++++++++++++++++++++ TimerMainWindow.h | 3 +- TimerMiniWindow.c | 56 +++++++++++++++++++++++ TimerMiniWindow.h | 20 +++++++++ practicetimer.gresource.xml | 1 + ui/main-window.glade | 51 ++++++++++++++++----- ui/mini-window.glade | 88 +++++++++++++++++++++++++++++++++++++ 9 files changed, 279 insertions(+), 16 deletions(-) create mode 100644 TimerMiniWindow.c create mode 100644 TimerMiniWindow.h create mode 100644 ui/mini-window.glade diff --git a/.gitignore b/.gitignore index c2bf56d..6e5ea9c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ compile_commands.json build -ui/edit-window.glade~ -ui/settings-window.glade~ -ui/main-window.glade~ +ui/*.glade~ resources.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 45fcae1..64d14e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,7 @@ add_custom_command(OUTPUT ${G_RESOURCE_C} MAIN_DEPENDENCY ${G_RESOURCE} DEPENDS add_custom_target(resource_target DEPENDS ${G_REOSURCE_C}) -add_executable(Practice_Timer main.c TimerApplication.c TimerMainWindow.c TimerEditWindow.c TimerSettingsWindow.c TimerClock.c TimerTaskTree.c TimerGraphWindow.c TimerGraph.c TimerFileWatcher.c ${G_RESOURCE_C}) +add_executable(Practice_Timer main.c TimerApplication.c TimerMainWindow.c TimerMiniWindow.c TimerEditWindow.c TimerSettingsWindow.c TimerClock.c TimerTaskTree.c TimerGraphWindow.c TimerGraph.c TimerFileWatcher.c ${G_RESOURCE_C}) set_source_files_properties(${G_RESOURCE_C} PROPERTIES GENERATED TRUE) diff --git a/TimerMainWindow.c b/TimerMainWindow.c index fc9b633..52d50a4 100644 --- a/TimerMainWindow.c +++ b/TimerMainWindow.c @@ -2,6 +2,7 @@ #include "TimerClock.h" #include "TimerEditWindow.h" #include "TimerSettingsWindow.h" +#include "TimerMiniWindow.h" #include @@ -17,11 +18,15 @@ struct _TimerMainWindow { GtkWidget *optionsButton; GtkWidget *taskTreeBox; GtkWidget *taskTree; + GtkWidget *shrinkButton; TimerClock *timerClock; TimerClock *updateClock; GKeyFile *keyFile; + TimerMiniWindow *miniWindow; + int miniWindowFirstOpen; + char *labelColorString; GDateTime *lastUpdateTime; @@ -194,6 +199,7 @@ static gboolean timer_main_window_update_time(TimerMainWindow *self) { timer_clock_is_running(self->timerClock) ? "red" : self->labelColorString, hour, minute, second); gtk_label_set_markup(GTK_LABEL(self->timerLabel), time); + gtk_label_set_markup(timer_mini_window_get_timer_label(self->miniWindow), time); g_free(time); return FALSE; } @@ -239,11 +245,14 @@ static void start_stop_button_callback(GtkButton *btn, TimerMainWindow *win) { if (timer_clock_is_running(win->timerClock)) { timer_clock_stop(win->timerClock); gtk_button_set_label(GTK_BUTTON(win->startStopButton), "Start"); + gtk_button_set_label(timer_mini_window_get_start_stop_button(win->miniWindow), "Start"); timer_main_window_update_time(win); } else { timer_clock_start(win->timerClock); gtk_button_set_label(GTK_BUTTON(win->startStopButton), "Stop"); + gtk_button_set_label(timer_mini_window_get_start_stop_button(win->miniWindow), "Stop"); gtk_widget_set_sensitive(win->resetButton, TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(timer_mini_window_get_reset_button(win->miniWindow)), TRUE); gtk_widget_set_sensitive(win->saveButton, TRUE); win->startTime = g_date_time_new_now_local(); timer_main_window_update_time(win); @@ -257,7 +266,9 @@ static void reset_button_callback(GtkButton *btn, TimerMainWindow *win) { win->currentTime = 0; timer_main_window_update_time(win); gtk_button_set_label(GTK_BUTTON(win->startStopButton), "Start"); + gtk_button_set_label(timer_mini_window_get_start_stop_button(win->miniWindow), "Start"); gtk_widget_set_sensitive(win->resetButton, FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(timer_mini_window_get_reset_button(win->miniWindow)), FALSE); gtk_widget_set_sensitive(win->saveButton, FALSE); g_date_time_unref(win->startTime); win->startTime = NULL; @@ -345,6 +356,16 @@ static void timer_main_window_get_defualt_label_color(TimerMainWindow *self) { (int)round(color.blue * 255)); } +void timer_main_window_save_mini_window_pos(TimerMainWindow *self, int x, int y) { + g_key_file_set_integer(self->keyFile, "Cache", "smallX", x); + g_key_file_set_integer(self->keyFile, "Cache", "smallY", y); +} + +void timer_main_window_read_mini_window_pos(TimerMainWindow *self, int *x, int *y) { + *x = g_key_file_get_integer(self->keyFile, "Cache", "smallX", NULL); + *y = g_key_file_get_integer(self->keyFile, "Cache", "smallY", NULL); +} + static gboolean window_configure_callback(TimerMainWindow *win) { int x, y, w, h; gtk_window_get_size(GTK_WINDOW(win), &w, &h); @@ -386,6 +407,50 @@ static gboolean window_delete_event(TimerMainWindow *win, GdkEvent *evt) { return FALSE; } +static gboolean mini_window_configure_callback(TimerMiniWindow *win) { + int x, y; + gtk_window_get_position(GTK_WINDOW(win), &x, &y); + timer_main_window_save_mini_window_pos( + TIMER_MAIN_WINDOW(timer_mini_window_get_parent(win)), x, y); + return FALSE; +} + +static gboolean mini_window_delete_event(TimerMiniWindow *win, GdkEvent *evt) { + gtk_widget_hide(GTK_WIDGET(win)); + gtk_widget_show_all(GTK_WIDGET(timer_mini_window_get_parent(win))); + return FALSE; +} + +static void mini_window_expand_callback(GtkButton *btn, TimerMainWindow *win) { + gtk_widget_hide(GTK_WIDGET(win->miniWindow)); + gtk_widget_show_all(GTK_WIDGET(win)); +} + +static void init_mini_window(TimerMainWindow *self) { + self->miniWindowFirstOpen = TRUE; + self->miniWindow = timer_mini_window_new(GTK_WINDOW(self)); + g_signal_connect(self->miniWindow, "configure-event", G_CALLBACK(mini_window_configure_callback), NULL); + g_signal_connect(self->miniWindow, "delete-event", G_CALLBACK(mini_window_delete_event), NULL); + g_signal_connect(timer_mini_window_get_start_stop_button(self->miniWindow), + "clicked", G_CALLBACK(start_stop_button_callback), self); + g_signal_connect(timer_mini_window_get_reset_button(self->miniWindow), + "clicked", G_CALLBACK(reset_button_callback), self); + g_signal_connect(timer_mini_window_get_expand_button(self->miniWindow), + "clicked", G_CALLBACK(mini_window_expand_callback), self); +} + +static void main_window_collapse_callback(GtkButton *btn, TimerMainWindow *win) { + gtk_widget_hide(GTK_WIDGET(win)); + gtk_widget_show_all(GTK_WIDGET(win->miniWindow)); + if (win->miniWindowFirstOpen) { + gtk_window_set_keep_above(GTK_WINDOW(win->miniWindow), TRUE); + int x, y; + timer_main_window_read_mini_window_pos(win, &x, &y); + gtk_window_move(GTK_WINDOW(win->miniWindow), x, y); + win->miniWindowFirstOpen = FALSE; + } +} + static void timer_main_window_finalize(GObject *self) { g_free(TIMER_MAIN_WINDOW(self)->labelColorString); g_object_unref(TIMER_MAIN_WINDOW(self)->timerClock); @@ -415,6 +480,8 @@ static void timer_main_window_class_init(TimerMainWindowClass *class) { TimerMainWindow, resetButton); gtk_widget_class_bind_template_child_internal(GTK_WIDGET_CLASS(class), TimerMainWindow, saveButton); + gtk_widget_class_bind_template_child_internal(GTK_WIDGET_CLASS(class), + TimerMainWindow, shrinkButton); gtk_widget_class_bind_template_child_internal( GTK_WIDGET_CLASS(class), TimerMainWindow, optionsButton); gtk_widget_class_bind_template_child_internal(GTK_WIDGET_CLASS(class), @@ -440,8 +507,11 @@ static void timer_main_window_init(TimerMainWindow *self) { G_CALLBACK(save_button_callback), self); g_signal_connect(self->timerButton, "clicked", G_CALLBACK(timer_button_callback), self); + g_signal_connect(self->shrinkButton, "clicked", + G_CALLBACK(main_window_collapse_callback), self); g_signal_connect(self, "destroy", G_CALLBACK(window_destroy_callback), NULL); g_signal_connect(self, "configure-event", G_CALLBACK(window_configure_callback), NULL); g_signal_connect(self, "delete-event", G_CALLBACK(window_delete_event), NULL); timer_main_window_get_defualt_label_color(self); + init_mini_window(self); } diff --git a/TimerMainWindow.h b/TimerMainWindow.h index a49c97a..a72e71a 100644 --- a/TimerMainWindow.h +++ b/TimerMainWindow.h @@ -17,7 +17,8 @@ TimerDataPoint *timer_main_window_get_task_data(TimerMainWindow *self, gsize *le TimerDataPoint *timer_main_window_get_day_data(TimerMainWindow *self, gsize *len); gboolean timer_main_window_is_always_on_top(TimerMainWindow *self); GDateTime *timer_main_window_get_last_task_end(TimerMainWindow *self); - +void timer_main_window_save_mini_window_pos(TimerMainWindow *self, int x, int y); +void timer_main_window_read_mini_window_pos(TimerMainWindow *self, int *x, int *y); G_END_DECLS diff --git a/TimerMiniWindow.c b/TimerMiniWindow.c new file mode 100644 index 0000000..6d34da0 --- /dev/null +++ b/TimerMiniWindow.c @@ -0,0 +1,56 @@ +#include "TimerMiniWindow.h" + +struct _TimerMiniWindow { + GtkWindow parent; + + GtkWindow *parentWindow; + GtkWidget *startStopButton; + GtkWidget *resetButton; + GtkWidget *expandButton; + GtkWidget *timerLabel; +}; + +G_DEFINE_TYPE(TimerMiniWindow, timer_mini_window, GTK_TYPE_WINDOW); + +TimerMiniWindow *timer_mini_window_new(GtkWindow *parent) { + TimerMiniWindow *self = g_object_new(TIMER_TYPE_MINI_WINDOW, NULL); + self->parentWindow = parent; + return self; +} + +GtkWindow *timer_mini_window_get_parent(TimerMiniWindow *self) { + return self->parentWindow; +} + +GtkLabel *timer_mini_window_get_timer_label(TimerMiniWindow *self) { + return GTK_LABEL(self->timerLabel); +} + +GtkButton *timer_mini_window_get_start_stop_button(TimerMiniWindow *self) { + return GTK_BUTTON(self->startStopButton); +} + +GtkButton *timer_mini_window_get_reset_button(TimerMiniWindow *self) { + return GTK_BUTTON(self->resetButton); +} + +GtkButton *timer_mini_window_get_expand_button(TimerMiniWindow *self) { + return GTK_BUTTON(self->expandButton); +} + +void timer_mini_window_class_init(TimerMiniWindowClass *class) { + gtk_widget_class_set_template_from_resource( + GTK_WIDGET_CLASS(class), "/zander/practicetimer/ui/mini-window.glade"); + gtk_widget_class_bind_template_child_internal(GTK_WIDGET_CLASS(class), + TimerMiniWindow, startStopButton); + gtk_widget_class_bind_template_child_internal(GTK_WIDGET_CLASS(class), + TimerMiniWindow, resetButton); + gtk_widget_class_bind_template_child_internal(GTK_WIDGET_CLASS(class), + TimerMiniWindow, expandButton); + gtk_widget_class_bind_template_child_internal(GTK_WIDGET_CLASS(class), + TimerMiniWindow, timerLabel); +} + +void timer_mini_window_init(TimerMiniWindow *self) { + gtk_widget_init_template(GTK_WIDGET(self)); +} diff --git a/TimerMiniWindow.h b/TimerMiniWindow.h new file mode 100644 index 0000000..d15c1ff --- /dev/null +++ b/TimerMiniWindow.h @@ -0,0 +1,20 @@ +#ifndef INCLUDED_TIMER_MINI_WINDOW_H +#define INCLUDED_TIMER_MINI_WINDOW_H + +#include + +G_BEGIN_DECLS + +#define TIMER_TYPE_MINI_WINDOW timer_mini_window_get_type() +G_DECLARE_FINAL_TYPE(TimerMiniWindow, timer_mini_window, TIMER, MINI_WINDOW, GtkWindow) + +TimerMiniWindow *timer_mini_window_new(GtkWindow *parent); +GtkWindow *timer_mini_window_get_parent(TimerMiniWindow *self); +GtkLabel *timer_mini_window_get_timer_label(TimerMiniWindow *self); +GtkButton *timer_mini_window_get_start_stop_button(TimerMiniWindow *self); +GtkButton *timer_mini_window_get_reset_button(TimerMiniWindow *self); +GtkButton *timer_mini_window_get_expand_button(TimerMiniWindow *self); + +G_END_DECLS + +#endif /* INCLUDED_TIMER_MINI_WINDOW_H */ diff --git a/practicetimer.gresource.xml b/practicetimer.gresource.xml index 97acd8e..e0452ba 100644 --- a/practicetimer.gresource.xml +++ b/practicetimer.gresource.xml @@ -4,5 +4,6 @@ ui/main-window.glade ui/edit-window.glade ui/settings-window.glade + ui/mini-window.glade diff --git a/ui/main-window.glade b/ui/main-window.glade index f83b6ae..e4b967a 100644 --- a/ui/main-window.glade +++ b/ui/main-window.glade @@ -1,12 +1,12 @@ - +