#include "flashcardsappwin.h" #include #include "database.h" #include "create-card.h" #include "create-category.h" struct _FlashcardsAppWindow { AdwApplicationWindow parent; sqlite3 *db; GArray *categories; GQueue *cards; category current_category; card *current_card; AdwWindowTitle *title; GtkButton *add_card_button; GtkButton *delete_card_button; GtkButton *delete_category_button; AdwNavigationSplitView *split_view; AdwNavigationPage *sidebar; AdwNavigationPage *content; AdwViewStack *main_view; GtkWidget *placeholder_category; GtkWidget *placeholder_card; GtkWidget *flashcard; GtkListBox *topics; GtkLabel *card_title; bool started; }; G_DEFINE_TYPE (FlashcardsAppWindow, flashcards_app_window, ADW_TYPE_APPLICATION_WINDOW); static void load_categories (FlashcardsAppWindow *win) { gtk_list_box_remove_all (win->topics); win->categories = database_load_categories (win->db); for (guint i = 0; i < win->categories->len; i++) { category c = g_array_index (win->categories, category, i); printf ("%d: %s\n", c.id, c.name); GtkWidget *child = gtk_list_box_row_new (); GtkWidget *label = gtk_label_new (c.name); gtk_widget_set_halign (label, GTK_ALIGN_START); gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE); gtk_widget_set_tooltip_text (label, c.name); gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (child), label); gtk_list_box_append (win->topics, child); } } static void next_card (FlashcardsAppWindow *win) { if (win->cards->length <= 0) { adw_view_stack_set_visible_child (win->main_view, win->placeholder_card); gtk_widget_set_visible (GTK_WIDGET (win->delete_card_button), FALSE); return; } win->current_card = g_queue_pop_head (win->cards); gtk_label_set_label (win->card_title, win->current_card->title); gtk_widget_set_visible (GTK_WIDGET (win->delete_card_button), TRUE); } static void load_cards (FlashcardsAppWindow *win, category c) { GArray *card_array = database_load_cards (win->db, c.id); adw_view_stack_set_visible_child (win->main_view, win->flashcard); win->cards = g_queue_new (); for (guint i = 0; i < card_array->len; i++) { g_queue_push_tail (win->cards, &g_array_index (card_array, card, i)); } next_card (win); } static void on_select_category (__attribute__ ((unused)) GtkListBox *box, GtkListBoxRow *row, gpointer user_data) { FlashcardsAppWindow *win = user_data; adw_navigation_split_view_set_show_content ( ADW_NAVIGATION_SPLIT_VIEW (win->split_view), TRUE); const int id = gtk_list_box_row_get_index (row); category c = g_array_index (win->categories, category, id); win->current_category = c; adw_window_title_set_subtitle (ADW_WINDOW_TITLE (win->title), c.name); adw_view_stack_set_visible_child (win->main_view, win->flashcard); gtk_widget_set_visible (GTK_WIDGET (win->add_card_button), TRUE); gtk_widget_set_visible (GTK_WIDGET (win->delete_category_button), TRUE); load_cards (win, c); } static void on_add_category (__attribute__ ((unused)) GtkButton *self, gpointer user_data) { FlashcardsCreateCategoryDialog *dialog = flashcards_create_category_dialog_new (user_data); adw_dialog_present (ADW_DIALOG (dialog), GTK_WIDGET (user_data)); } static void on_delete_category (__attribute__ ((unused)) GtkButton *self, gpointer user_data) { FlashcardsAppWindow *win = user_data; database_delete_category (win->db, win->current_category.id); gtk_list_box_unselect_all (win->topics); adw_window_title_set_subtitle (ADW_WINDOW_TITLE (win->title), nullptr); adw_view_stack_set_visible_child (win->main_view, win->placeholder_category); gtk_widget_set_visible (GTK_WIDGET (win->add_card_button), FALSE); gtk_widget_set_visible (GTK_WIDGET (win->delete_card_button), FALSE); gtk_widget_set_visible (GTK_WIDGET (win->delete_category_button), FALSE); load_categories (win); } static void on_add_card (__attribute__ ((unused)) GtkButton *self, gpointer user_data) { FlashcardsAppWindow *win = user_data; FlashcardsCreateCardDialog *dialog = flashcards_create_card_dialog_new (win); adw_dialog_present (ADW_DIALOG (dialog), GTK_WIDGET (win)); } static void on_delete_card (__attribute__ ((unused)) GtkButton *self, gpointer user_data) { FlashcardsAppWindow *win = user_data; database_delete_card (win->db, win->current_card->id); next_card (win); } static void on_answer_easy (__attribute__ ((unused)) GtkButton *self, gpointer user_data) { FlashcardsAppWindow *win = user_data; card *c = win->current_card; database_schedule_card ( win->db, c->id, g_date_time_add_hours (g_date_time_new_now_utc (), 24)); next_card (win); } static void on_answer_medium (__attribute__ ((unused)) GtkButton *self, gpointer user_data) { FlashcardsAppWindow *win = user_data; card *c = win->current_card; database_schedule_card ( win->db, c->id, g_date_time_add_hours (g_date_time_new_now_utc (), 12)); next_card (win); } static void on_answer_hard (__attribute__ ((unused)) GtkButton *self, gpointer user_data) { FlashcardsAppWindow *win = user_data; card *c = win->current_card; database_schedule_card ( win->db, c->id, g_date_time_add_hours (g_date_time_new_now_utc (), 6)); next_card (win); } static void on_flip_card (__attribute__ ((unused)) GtkWidget *self, gpointer user_data) { FlashcardsAppWindow *win = user_data; gtk_label_set_text (GTK_LABEL (win->card_title), win->current_card->answer); } void flashcards_app_window_add_card (FlashcardsAppWindow *win, const gchar *title, const gchar *answer) { database_save_card (win->db, win->current_category.id, title, answer); load_cards (win, win->current_category); } void flashcards_app_window_add_category (FlashcardsAppWindow *win, const gchar *title) { database_save_category (win->db, title); load_categories (win); } static void on_flashcards_app_window_show (GtkWidget *self, gpointer user_data) { FlashcardsAppWindow *win = user_data; load_categories (win); gtk_list_box_unselect_all (win->topics); } static void flashcards_app_window_init (FlashcardsAppWindow *self) { gtk_widget_init_template (GTK_WIDGET (self)); self->db = database_connect (g_get_user_data_dir ()); } static void flashcards_app_window_class_init (FlashcardsAppWindowClass *class) { gtk_widget_class_set_template_from_resource ( GTK_WIDGET_CLASS (class), "/li/sopht/flashcards/window.ui"); gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FlashcardsAppWindow, title); gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FlashcardsAppWindow, add_card_button); gtk_widget_class_bind_template_child ( GTK_WIDGET_CLASS (class), FlashcardsAppWindow, delete_card_button); gtk_widget_class_bind_template_child ( GTK_WIDGET_CLASS (class), FlashcardsAppWindow, delete_category_button); gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FlashcardsAppWindow, split_view); gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FlashcardsAppWindow, sidebar); gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FlashcardsAppWindow, content); gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FlashcardsAppWindow, main_view); gtk_widget_class_bind_template_child ( GTK_WIDGET_CLASS (class), FlashcardsAppWindow, placeholder_category); gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FlashcardsAppWindow, placeholder_card); gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FlashcardsAppWindow, flashcard); gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FlashcardsAppWindow, topics); gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FlashcardsAppWindow, card_title); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), on_flashcards_app_window_show); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), on_select_category); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), on_add_category); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), on_delete_category); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), on_add_card); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), on_delete_card); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), on_answer_easy); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), on_answer_medium); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), on_answer_hard); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), on_flip_card); } FlashcardsAppWindow * flashcards_app_window_new (FlashcardsApp *app) { return g_object_new (FLASHCARDS_APP_WINDOW_TYPE, "application", app, NULL); }