diff --git a/include/calls.h b/include/calls.h index d375abe..687a9bb 100644 --- a/include/calls.h +++ b/include/calls.h @@ -47,11 +47,19 @@ void on_SAVE_CURRENT_MODEL_BEFORE_EDITING (GtkWidget *btt_SAVE_CURRENT_MODEL, gp void on_DISCARD_CURRENT_MODEL_AND_START_EDITING (GtkWidget *btt_SAVE_CURRENT_MODEL, gpointer data); void on_WRITE_CURRENT_MODEL (GtkWidget *btt_WRITE_CURRENT_MODEL, gpointer data); + +void on_setup_user_menu_factory (GtkSignalListItemFactory *factory, + GObject* object, gpointer user_data); +void on_bind_user_menu_factory (GtkSignalListItemFactory *factory, + GObject* object, gpointer user_data); + + void on_setup_user_tree_factory (GtkSignalListItemFactory *factory, GObject* object, gpointer user_data); void on_bind_user_tree_factory (GtkSignalListItemFactory *factory, GObject* object, gpointer user_data); + gboolean on_glarea_render (GtkGLArea *area, GdkGLContext *context); void on_glarea_realize (GtkWidget *widget); void on_glarea_unrealize (GtkWidget *widget); diff --git a/include/widgets.h b/include/widgets.h index b291392..1721447 100644 --- a/include/widgets.h +++ b/include/widgets.h @@ -41,9 +41,9 @@ void widget_head_set_TEXT_WINDOW (GtkApplication *app); void widget_head_MAIN_WINDOW_design (GtkWindow *main_window); void widget_head_DIALOG_WINDOW_design (GtkWindow *main_window, - GtkWindow *dialog_window); + GtkWindow *dialog_window); void widget_head_TEXT_WINDOW_design (GtkWindow *main_window, - GtkWindow *text_window); + GtkWindow *text_window); GtkWindow *widget_head_get_MAIN_WINDOW(); GtkWindow *widget_head_get_DIALOG_WINDOW(); @@ -54,7 +54,7 @@ GtkWindow *widget_head_get_TEXT_WINDOW(); /* W I D G E T S */ /******************************************************************************/ -GtkButton *get_GtkButton (char *btt_name); +GtkButton *widget_head_get_GtkButton (char *btt_name); GtkWidget *get_STATE_page(); GtkWidget *get_RULES_page(); @@ -63,6 +63,18 @@ GtkWidget *get_STOCK_page(); GtkWidget *get_STOCK_text (gchar *text_name); +/******************************************************************************/ +/* M E N U */ +/******************************************************************************/ + +struct MenuNode_t {gchar *text; struct MenuNode_t *child, *next;}; +struct MenuNode_t *create_user_menu_node (const gchar* text); + +void add_menu_item (struct MenuNode_t *parent, struct MenuNode_t *child); + +GtkWidget *get_menu_anchor(); + + /******************************************************************************/ /* T R E E */ /******************************************************************************/ @@ -104,17 +116,3 @@ gchar *get_text_address_ANY (); void learning_how_to_create_a_menu (GtkMenuButton* menu_button); - - - - - - - - - - - - - - diff --git a/src/calls.c b/src/calls.c index a03fece..67eeb09 100644 --- a/src/calls.c +++ b/src/calls.c @@ -62,7 +62,7 @@ static void on_auto_notification (const char *message) /******************************************************************************/ void on_windows_activation (GtkApplication *app, - gpointer no_user_data) + gpointer no_user_data) { widget_head_set_MAIN_WINDOW (app); widget_head_MAIN_WINDOW_design (widget_head_get_MAIN_WINDOW()); @@ -75,6 +75,53 @@ void on_windows_activation (GtkApplication *app, } +/******************************************************************************/ +/* M E N U */ +/******************************************************************************/ + +static void on_user_menu_expander_toggled (GtkExpander *expander, + gpointer user_data) +{ + GtkTreeListRow *row = GTK_TREE_LIST_ROW (user_data); + gboolean is_expanded = gtk_tree_list_row_get_expanded (row); + gtk_tree_list_row_set_expanded (row, + ! is_expanded); +} + + +void on_bind_user_menu_factory (GtkSignalListItemFactory *factory, + GObject* object, + gpointer user_data) +{ + GtkListItem *list_item = GTK_LIST_ITEM (object); + assert (list_item); + + GtkTreeListRow *row = gtk_list_item_get_item (list_item); + assert (row); // if (row != NULL) {...} do something ? TODO Check ! + + const gchar *text = gtk_string_object_get_string ( + GTK_STRING_OBJECT (gtk_tree_list_row_get_item (row))); + GtkWidget *expander = gtk_list_item_get_child (list_item); + gtk_expander_set_label (GTK_EXPANDER (expander), text); + g_signal_handlers_disconnect_by_func (expander, + G_CALLBACK (on_user_menu_expander_toggled), + row); + g_signal_connect (expander, + "activate", + G_CALLBACK (on_user_menu_expander_toggled), + row); + gtk_widget_set_margin_start (expander, + gtk_tree_list_row_get_depth(row) * 20); +} + +void on_setup_user_menu_factory (GtkSignalListItemFactory *factory, + GObject* object, gpointer user_data){ + GtkWidget* expander = gtk_expander_new (NULL); + gtk_list_item_set_child (GTK_LIST_ITEM (object), expander); + if (0) printf("[on_setup_user_menu_factory] here is an expander\n"); +} + + /******************************************************************************/ /* T R E E */ /******************************************************************************/ diff --git a/src/main.c b/src/main.c index 565125b..6fd56c7 100644 --- a/src/main.c +++ b/src/main.c @@ -205,7 +205,7 @@ * Ces fonctions peuvent être énumérées selon leur source ou leur destination. * Il y a, en tout, à ce jour : * - (86) fonctions appelées (dont 6 data) - * - (m) fonctions appelantes + * - (m) appels de fonction * - (e) enum * - (s) struct * - (d) define diff --git a/src/widget.c/heads.c b/src/widget.c/heads.c index e923278..6ad53bc 100644 --- a/src/widget.c/heads.c +++ b/src/widget.c/heads.c @@ -57,7 +57,7 @@ void widget_head_set_TEXT_WINDOW (GtkApplication *app) text_window = GTK_WINDOW (gtk_application_window_new (app)); } -GtkButton *get_GtkButton (char *btt_name) +GtkButton *widget_head_get_GtkButton (char *btt_name) { if (strcmp (btt_name, "state")) return btt_STATE; if (strcmp (btt_name, "rules")) return btt_RULES; @@ -183,6 +183,7 @@ static void window_header_bar (GtkWindow *window, char *title) g_signal_connect (open_menu, "clicked", G_CALLBACK (on_clicked_MENU), open_menu); gtk_header_bar_pack_end (GTK_HEADER_BAR (header_bar), GTK_WIDGET (open_menu)); + gtk_header_bar_pack_end (GTK_HEADER_BAR (header_bar), GTK_WIDGET (get_menu_anchor())); GtkWidget *menu_btt = gtk_menu_button_new (); diff --git a/src/widget.c/menu.c b/src/widget.c/menu.c new file mode 100644 index 0000000..47e3a1f --- /dev/null +++ b/src/widget.c/menu.c @@ -0,0 +1,124 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * +* * +* Gem-graph client * +* * +* Tree * +* * +* Copyright © 2021 Libre en Communs * +* Copyright © 2021 Adrien Bourmault * +* Copyright © 2021 Jean Sirmai * +* * +* This file is part of Gem-graph. * +* * +* This program is free software: you can redistribute it and/or modify it * +* under the terms of the GNU Affero General Public License * +* as published by the Free Software Foundation, * +* either version 3 of the License, * +* or (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; * +* without even the implied warranty of MERCHANTABILITY * +* or FITNESS FOR A PARTICULAR PURPOSE. * +* See the GNU Affero General Public License for more details. * +* * +* You should have received a copy of the GNU Affero General Public License * +* along with this program. If not, see . * +* * +* * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +#include "../../include/calls.h" +#include "../../include/widgets.h" + +// GTK_ORIENTATION_VERTICAL GTK_ORIENTATION_HORIZONTAL + + +void add_menu_item (struct MenuNode_t *parent, struct MenuNode_t *child){ + if (parent->child) { + struct MenuNode_t *cur = parent->child; + while (cur && cur->next) {cur = cur->next;} + cur->next = child; + } else parent->child = child; +} + +struct MenuNode_t *create_user_menu_node (const gchar* text){ + struct MenuNode_t *node = g_malloc0 (sizeof(struct MenuNode_t)); + node->text = g_strdup (text); + node->child = NULL; // if (0) printf("create_user_menu_node %s\n", text); + return node; +} + +static GListModel* get_user_menu_model_child (struct MenuNode_t *parent){ + GtkStringList *list = NULL; + if (parent) { + if (0) printf("[get_user_menu_model_child] here is %s content : ", parent->text); + struct MenuNode_t *child = parent->child; + if (child) {list = gtk_string_list_new(NULL);} + while(child) { + gtk_string_list_append(list, child->text); + if (0) printf("%s ", child->text); + child = child->next; + } + } // else printf("hot.c GListModel* get_user_menu_model_child (struct MenuNode_t *parent) child = %d \n", parent); + if (0) printf("\n"); + return G_LIST_MODEL(list); +} + +static GListModel* get_user_menu_model (GObject *item, gpointer root){ + struct MenuNode_t *cur = (struct MenuNode_t *)root; + struct MenuNode_t *parent = root; + const gchar *string = gtk_string_object_get_string (GTK_STRING_OBJECT (item)); + while (cur) { + if (strcmp(string, cur->text) == 0) break; + cur = cur->next; + if (cur == NULL) {cur = parent->child; parent = cur;} + } + if (0) printf("[get_user_user_menu_model] looked for %s in %s item\n", cur->text, string); +// ! WARNING ! TODO CUR EST L'ENFANT, MAINTENANT DONC, SI CUR EST UNE FEUILLE, JE N'ATTEINDRAI PAS SON ENFANT + return get_user_menu_model_child (cur); +} + +GtkWidget *get_menu_anchor() +{ + struct MenuNode_t *menu_root = create_user_menu_node("menu"); + struct MenuNode_t *item_a = create_user_menu_node("item_a");add_menu_item (menu_root, item_a); + struct MenuNode_t *item_b = create_user_menu_node("item_b");add_menu_item (menu_root, item_b); + struct MenuNode_t *item_c = create_user_menu_node("item_c");add_menu_item (menu_root, item_c); + + GtkStringList *model = gtk_string_list_new (NULL); + gtk_string_list_append (model, menu_root->text); + GtkSignalListItemFactory *factory = GTK_SIGNAL_LIST_ITEM_FACTORY (gtk_signal_list_item_factory_new()); + g_signal_connect (factory, "setup", G_CALLBACK(on_setup_user_menu_factory), NULL); + g_signal_connect (factory, "bind", G_CALLBACK(on_bind_user_menu_factory), NULL); + + GtkTreeListModel *menu_model = gtk_tree_list_model_new ( + G_LIST_MODEL (model), + FALSE, // Passthrough - False in actual usage with dynamic children retrieval + FALSE, // TRUE, // FALSE, // autoexpand + (GtkTreeListModelCreateModelFunc) &get_user_menu_model, + menu_root, + NULL // (GDestroyNotify) free_user_menu_node + ); + + GtkSingleSelection *selection_model = gtk_single_selection_new (G_LIST_MODEL (menu_model)); + gtk_single_selection_set_autoselect (selection_model, FALSE); + gtk_single_selection_set_can_unselect (selection_model, TRUE); + GtkWidget *list_view = gtk_list_view_new (GTK_SELECTION_MODEL (selection_model), + GTK_LIST_ITEM_FACTORY (factory)); + + return list_view; +} +/* + GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (gtk_scrolled_window_new()); +// Allocation height too small. Tried to allocate 1922x1030, but GtkNotebook 0x25cd4c0 needs at least 1922x1064. +// even if I remove (comment) the next line : + gtk_scrolled_window_set_child (scrolled_window, list_view); + gtk_scrolled_window_set_policy (scrolled_window, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_widget_set_vexpand (GTK_WIDGET (scrolled_window), TRUE); + gtk_widget_set_visible (GTK_WIDGET (scrolled_window), TRUE); + gtk_widget_set_visible (GTK_WIDGET (list_view), TRUE); + return scrolled_window; +} +*/ +