1
0
mirror of https://gitlab.cvh-server.de/skrause/flashcards.git synced 2025-12-12 06:41:38 +01:00
Files
flashcards/src/flashcardsappwin.c

301 lines
9.6 KiB
C

#include "flashcardsappwin.h"
#include <glib/gi18n.h>
#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);
}