diff --git a/(notes) b/(notes) index 3edc8aa..9651f6b 100644 --- a/(notes) +++ b/(notes) @@ -2,6 +2,8 @@ https://docs.gtk.org/gtk4/visual_index.html widgets gallery https://forge.a-lec.org/gem-graph/gem-graph-client/src/branch/devel/Makefile https://docs.gtk.org/gtk4/class.Widget.html#height-for-width-geometry-management +// GtkSizeRequestMode get_request_mode (GtkWidget* widget); +// gtk_window_set_default_size (GTK_WINDOW (a_box), 30, 400); < TO STUDY https://docs.gtk.org/gtk4/section-text-widget.html texts https://docs.gtk.org/gtk4/drag-and-drop.html drag-and-drop https://docs.gtk.org/gtk4/class.GestureZoom.html GtkGestureZoom @@ -10,6 +12,8 @@ https://docs.gtk.org/gtk4/class.GestureZoom.html GtkGestureZoom GTK_ORIENTATION_VERTICAL GTK_ORIENTATION_HORIZONTAL +GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT GTK_SIZE_REQUEST_CONSTANT_SIZE + g_signal_connect (button, "clicked", G_CALLBACK (printf("%s\n", text)), text); g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window); diff --git a/contain.c b/contain.c index 776a771..88609a7 100644 --- a/contain.c +++ b/contain.c @@ -5,6 +5,7 @@ #include "display.h" #include "contain.h" #include "texts.h" +#include "tree.h" GtkWidget *get_edit_rules_page_new(){ @@ -207,7 +208,7 @@ void activate (GtkApplication *app, gpointer user_data) { gtk_window_set_child (window, GTK_WIDGET(run_xor_edit_horizontal_pane)); gtk_window_present (GTK_WINDOW (window)); - gtk_notebook_set_current_page (run_notebook, 0); // @see hot.c 2024-05-11 (line 68) - gtk_notebook_set_current_page (edit_notebook, 0); // @see hot.c 2024-05-11 (line 68) + gtk_notebook_set_current_page (run_notebook, 1); // @see hot.c 2024-05-11 (line 68) + gtk_notebook_set_current_page (edit_notebook, 1); // @see hot.c 2024-05-11 (line 68) } diff --git a/contain.d b/contain.d index 02e64ee..4bca4e9 100644 --- a/contain.d +++ b/contain.d @@ -1,3 +1,3 @@ contain.o: contain.c hot.h warm.h \ /gnu/store/fkmpkdav2zmz1k72989bdgpdrfac7rz1-glib-2.78.0/include/glib-2.0/glib.h \ - cold.h display.h contain.h texts.h + cold.h display.h contain.h texts.h tree.h diff --git a/contain.o b/contain.o index 7b1c36a..68869ea 100644 Binary files a/contain.o and b/contain.o differ diff --git a/display.c b/display.c index 3c0c275..72c8196 100644 --- a/display.c +++ b/display.c @@ -5,6 +5,7 @@ #include "display.h" #include "contain.h" #include "texts.h" +#include "tree.h" //------------------------------------------------------------------------------ @@ -86,27 +87,24 @@ static GtkWidget *get_scroll_speed(){ static GtkBox *get_UNDO_SPEED_box(){ GtkBox *SPEED_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_VERTICAL, 0)); - gtk_box_append (SPEED_box, GTK_WIDGET(gtk_label_new ("< UNDO <\n"))); + gtk_box_append (SPEED_box, GTK_WIDGET(gtk_label_new ("< UNDO <\n"))); gtk_box_append (SPEED_box, get_scroll_speed()); return SPEED_box; } static GtkBox *get_DO_SPEED_box(){ GtkBox *SPEED_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_VERTICAL, 0)); - gtk_box_append (SPEED_box, GTK_WIDGET(gtk_label_new ("> DO >\n"))); + gtk_box_append (SPEED_box, GTK_WIDGET(gtk_label_new ("> DO >\n"))); gtk_box_append (SPEED_box, get_scroll_speed()); return SPEED_box; } GtkBox *get_RUN_STOP_box(){ GtkBox *RUN_STOP_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 20)); -// gtk_box_append (RUN_STOP_box, gtk_label_new ("\n")); -// gtk_box_append (RUN_STOP_box, GTK_WIDGET(gtk_label_new (" <<<< \n UNDO "))); gtk_box_append (RUN_STOP_box, GTK_WIDGET (get_UNDO_SPEED_box())); gtk_box_append (RUN_STOP_box, GTK_WIDGET(gtk_label_new (" STEP\n(show active rule) "))); gtk_box_append (RUN_STOP_box, GTK_WIDGET (get_DO_SPEED_box())); gtk_box_append (RUN_STOP_box, GTK_WIDGET(gtk_label_new (" R U N\n S T O P"))); -// gtk_box_append (RUN_STOP_box, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_VERTICAL))); return RUN_STOP_box; } //------------------------------------------------------------------------------ @@ -234,3 +232,51 @@ GtkWidget *get_OBJECTS_and_SITUATIONS(){ } +GtkBox *get_rules_comparator_new(){ + GtkBox *comparator = GTK_BOX(gtk_box_new (GTK_ORIENTATION_VERTICAL, 2)); + gtk_box_append (comparator, GTK_WIDGET (get_image_ATP())); + gtk_box_append (comparator, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); + gtk_box_append (comparator, GTK_WIDGET (get_image_AMP())); + gtk_box_append (comparator, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); + gtk_box_append (comparator, GTK_WIDGET (get_image_GLUTAMATE())); + gtk_box_append (comparator, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); + gtk_box_append (comparator, GTK_WIDGET (get_image_GLUTAMINE())); + gtk_box_append (comparator, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); + gtk_box_append (comparator, GTK_WIDGET (get_image_HISTIDINE())); + gtk_box_append (comparator, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); + gtk_box_append (comparator, GTK_WIDGET (get_image_PHENYLALANINE())); + gtk_box_append (comparator, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); + gtk_box_append (comparator, GTK_WIDGET (get_image_DOPAMINE())); + gtk_box_append (comparator, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); + return comparator; +} + +GtkWidget *get_rules_tree_hpaned_new(){ + GtkPaned *H_tree_vs_comparison = GTK_PANED (gtk_paned_new (GTK_ORIENTATION_HORIZONTAL)); + +// GtkWidget *arbre_des_règles = gtk_frame_new ("Arbre"); +// GtkWidget *comparaison_des_règles_sélectionnées = gtk_frame_new ("Sélection"); + + gtk_paned_set_start_child (H_tree_vs_comparison, GTK_WIDGET (get_rules_user_tree_new())); + gtk_paned_set_end_child (H_tree_vs_comparison, GTK_WIDGET (get_rules_comparator_new())); + gtk_paned_set_position (H_tree_vs_comparison, 300); + gtk_paned_set_wide_handle (H_tree_vs_comparison, TRUE); + gtk_paned_set_shrink_start_child (H_tree_vs_comparison, FALSE); + gtk_paned_set_shrink_end_child (H_tree_vs_comparison, FALSE); + return GTK_WIDGET (H_tree_vs_comparison); +} + +GtkWidget *get_run_rules_page_new(){ + GtkPaned *H_tree_vs_selected = GTK_PANED (gtk_paned_new (GTK_ORIENTATION_HORIZONTAL)); + +// GtkWidget *arbre_des_règles = gtk_frame_new ("Arbre des règles"); +// GtkWidget *édition_de_la_règle_sélectionnée_n_1 = gtk_frame_new ("Inspection"); + + gtk_paned_set_start_child (H_tree_vs_selected, GTK_WIDGET (get_rules_tree_hpaned_new())); + gtk_paned_set_end_child (H_tree_vs_selected, GTK_WIDGET (get_selected_rules_vpaned_new())); + gtk_paned_set_position (H_tree_vs_selected, 600); // WARNING : c'est une position "absolue" + gtk_paned_set_wide_handle (H_tree_vs_selected, TRUE); + // gtk_widget_set_size_request (GTK_WIDGET (H_tree_vs_selected), W, H); // inutile... ? + return GTK_WIDGET (H_tree_vs_selected); +} + diff --git a/display.d b/display.d index 7d9c4d8..b8614e1 100644 --- a/display.d +++ b/display.d @@ -1 +1 @@ -display.o: display.c cold.h display.h contain.h texts.h +display.o: display.c cold.h display.h contain.h texts.h tree.h diff --git a/display.o b/display.o index 74b2ce7..1be9540 100644 Binary files a/display.o and b/display.o differ diff --git a/hot.c b/hot.c index b61ccc7..fd2811f 100644 --- a/hot.c +++ b/hot.c @@ -7,314 +7,9 @@ #include "contain.h" #include "texts.h" -// https://forge.a-lec.org/gem-graph/gem-graph-client/src/branch/devel/Makefile // https://docs.gtk.org/gtk4/visual_index.html < widgets gallery // https://docs.gtk.org/gtk4/section-text-widget.html // https://docs.gtk.org/gtk4/class.Widget.html#height-for-width-geometry-management // GTK_ORIENTATION_VERTICAL GTK_ORIENTATION_HORIZONTAL - -// Simplified TreeNode structure for demonstration purposes -// -------------------------------------------------------- - -/* - * Tree-related signals - */ - -void on_tree_expander_toggled(GtkExpander *expander, gpointer user_data) -{ - // This is a conceptual callback for when an expander is toggled - 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_tree_setup_factory (GtkSignalListItemFactory *factory, - GObject* object, - gpointer user_data) -{ - GtkWidget* expander = gtk_expander_new (NULL); - gtk_list_item_set_child (GTK_LIST_ITEM(object), expander); - printf("[on_tree_setup_factory] here is an expander\n"); -} - -void on_tree_bind_factory (GtkSignalListItemFactory *factory, - GObject* object, - gpointer user_data) -{ -// GObject *item; - const gchar *text; - GtkTreeListRow *row; - GtkListItem *list_item; - GtkWidget *expander; - - list_item= GTK_LIST_ITEM(object); - row = gtk_list_item_get_item(list_item); - if (row != NULL) { - text = gtk_string_object_get_string(GTK_STRING_OBJECT(gtk_tree_list_row_get_item(row))); - expander = gtk_list_item_get_child(list_item); - gtk_expander_set_label(GTK_EXPANDER(expander), text); - - // Disconnect previous signal handlers to avoid stacking them - g_signal_handlers_disconnect_by_func(expander, G_CALLBACK(on_tree_expander_toggled), row); - - // Connect the signal handler - g_signal_connect(expander, "activate", G_CALLBACK(on_tree_expander_toggled), row); - - gtk_widget_set_margin_start(expander, gtk_tree_list_row_get_depth(row)*20); - gboolean is_expanded = gtk_tree_list_row_get_expanded(row); - printf("[on_tree_bind_factory] here is %s content and expander is %d\n", - text, - is_expanded); - } else { - printf("[on_tree_bind_factory] here is NON content\n"); - } -} - -void on_tree_selection_changed (GtkSelectionModel* self, guint position, - guint n_items, gpointer user_data) -{ - printf("[on_tree_selection_changed]\n"); -} - -struct TreeNode_t -{ - gchar *text; - struct TreeNode_t *child; - struct TreeNode_t *next; -}; - -// Function to create a new TreeNode instance -static struct TreeNode_t *create_tree_node (const gchar* text) -{ - struct TreeNode_t *node = g_malloc0 (sizeof(struct TreeNode_t)); - node->text = g_strdup(text); - node->child = NULL; - return node; -} - -// Function to add a child node to a parent node -static void add_child_node (struct TreeNode_t *parent, struct TreeNode_t *child) -{ - struct TreeNode_t *cur; - - if (parent->child) { - cur = parent->child; - while (cur && cur->next) { - cur = cur->next; - } - cur->next = child; - } else { - parent->child = child; - } -} - -// Recursive function to free a TreeNode and its children -// attention: « free_tree_node » défini mais pas utilisé <<< TODO -static void free_tree_node (struct TreeNode_t *node) -{ - struct TreeNode_t *cur; - struct TreeNode_t *tmp; - - if (!node) return; - - // free siblings - cur = node; - while (cur) { - tmp = cur->next; - g_free(cur); - cur = tmp; - } - - // recursive free - free_tree_node(node->child); - g_free(node->text); - g_free(node); -} - -// Function to simulate getting a GListModel of children for a given TreeNode -GListModel* ui_tree_get_children_model (struct TreeNode_t *parent) -{ - struct TreeNode_t *child; - - GtkStringList *list = NULL; - - if (parent) { - printf("[ui_tree_get_children_model] here is %s content : ", parent->text); - - child = parent->child; - - if (child) { - list = gtk_string_list_new(NULL); - } - while(child) { - gtk_string_list_append(list, child->text); - printf("%s ", child->text); - child = child->next; - } - } - printf("\n"); - - return G_LIST_MODEL(list); -} - -// GtkTreeListModelCreateModelFunc callback implementation -GListModel* ui_tree_create_model_func(GObject *item, gpointer root) -{ - struct TreeNode_t *cur = (struct TreeNode_t *)root; - struct TreeNode_t *parent = NULL; - - const gchar *string = gtk_string_object_get_string(GTK_STRING_OBJECT(item)); - - parent = root; - while (cur) { - if (strcmp(string, cur->text) == 0) { - break; - } - - cur = cur->next; - if (cur == NULL) { - cur = parent->child; - parent = cur; - } - } - - printf("[ui_tree_create_model_func] looked for %s in %s item\n", - cur->text, - string); - - return ui_tree_get_children_model(cur); -} - -// Application activation callback -static void ui_create_tree (GtkWidget *target_widget) -{ - GtkStringList *model; - GtkTreeListModel *tree_model; - GtkSignalListItemFactory *factory; - GtkSingleSelection *selection_model; - GtkWidget *list_view; - GtkScrolledWindow *scrolled_window; - - assert(target_widget); - - // AD HOC XXX & no free() - struct TreeNode_t *tree_root = create_tree_node("Root"); - struct TreeNode_t *ATP = create_tree_node("ATP"); - struct TreeNode_t *ADP = create_tree_node("ADP"); - struct TreeNode_t *AMP = create_tree_node("AMP"); - struct TreeNode_t *adenine = create_tree_node("adénine"); - struct TreeNode_t *ribose = create_tree_node("ribose"); - struct TreeNode_t *PO4H3_1 = create_tree_node("phosphate 1"); - struct TreeNode_t *PO4H3_2 = create_tree_node("phosphate 2"); - struct TreeNode_t *PO4H3_3 = create_tree_node("phosphate 3"); - - add_child_node(tree_root, ATP); - add_child_node(tree_root, ADP); - add_child_node(tree_root, AMP); - add_child_node(ATP, adenine); - add_child_node(adenine, ribose); - add_child_node(ribose, PO4H3_1); - add_child_node(PO4H3_1, PO4H3_2); - add_child_node(PO4H3_3, PO4H3_3); - - model = gtk_string_list_new(NULL); - gtk_string_list_append(model, tree_root->text); - - // Create and setup the list view and item factory - factory = GTK_SIGNAL_LIST_ITEM_FACTORY (gtk_signal_list_item_factory_new ()); - g_signal_connect (factory, "setup", G_CALLBACK(on_tree_setup_factory), NULL); - g_signal_connect (factory, "bind", G_CALLBACK(on_tree_bind_factory), NULL); - - // Create a GtkTreeListModel - tree_model = gtk_tree_list_model_new( - G_LIST_MODEL(model), - FALSE, // Passthrough - False in actual usage with dynamic children retrieval - FALSE, // autoexpand - (GtkTreeListModelCreateModelFunc)ui_tree_create_model_func, - tree_root, - NULL //(GDestroyNotify)free_tree_node - ); - - selection_model = gtk_single_selection_new ( - G_LIST_MODEL (tree_model)); - - gtk_single_selection_set_autoselect (selection_model, FALSE); - gtk_single_selection_set_can_unselect (selection_model, TRUE); - /* g_signal_connect (selection_model, "selection-changed", */ - /* G_CALLBACK(on_tree_selection_changed), NULL); */ - - list_view = gtk_list_view_new (GTK_SELECTION_MODEL (selection_model), - GTK_LIST_ITEM_FACTORY (factory)); - - scrolled_window = GTK_SCROLLED_WINDOW (gtk_scrolled_window_new()); - 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_box_append(GTK_BOX(target_widget), GTK_WIDGET(scrolled_window)); - gtk_widget_set_visible(GTK_WIDGET(scrolled_window), TRUE); - gtk_widget_set_visible(GTK_WIDGET(list_view), TRUE); -} - -GtkBox *get_rules_user_tree_new(){ - GtkBox *tree_sketch = GTK_BOX(gtk_box_new (GTK_ORIENTATION_VERTICAL, 2)); -// gtk_box_append (tree_sketch, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); -// gtk_box_append (tree_sketch, GTK_WIDGET (get_user_tree())); -// gtk_box_append (tree_sketch, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); - ui_create_tree(GTK_WIDGET (tree_sketch)); - return tree_sketch; -} - -GtkBox *get_rules_comparator_new(){ - GtkBox *comparator = GTK_BOX(gtk_box_new (GTK_ORIENTATION_VERTICAL, 2)); - gtk_box_append (comparator, GTK_WIDGET (get_image_ATP())); - gtk_box_append (comparator, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); - gtk_box_append (comparator, GTK_WIDGET (get_image_AMP())); - gtk_box_append (comparator, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); - gtk_box_append (comparator, GTK_WIDGET (get_image_GLUTAMATE())); - gtk_box_append (comparator, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); - gtk_box_append (comparator, GTK_WIDGET (get_image_GLUTAMINE())); - gtk_box_append (comparator, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); - gtk_box_append (comparator, GTK_WIDGET (get_image_HISTIDINE())); - gtk_box_append (comparator, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); - gtk_box_append (comparator, GTK_WIDGET (get_image_PHENYLALANINE())); - gtk_box_append (comparator, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); - gtk_box_append (comparator, GTK_WIDGET (get_image_DOPAMINE())); - gtk_box_append (comparator, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); - return comparator; -} - -GtkWidget *get_rules_tree_hpaned_new(){ - GtkPaned *H_tree_vs_comparison = GTK_PANED (gtk_paned_new (GTK_ORIENTATION_HORIZONTAL)); - -// GtkWidget *arbre_des_règles = gtk_frame_new ("Arbre"); -// GtkWidget *comparaison_des_règles_sélectionnées = gtk_frame_new ("Sélection"); - - gtk_paned_set_start_child (H_tree_vs_comparison, GTK_WIDGET (get_rules_user_tree_new())); - gtk_paned_set_end_child (H_tree_vs_comparison, GTK_WIDGET (get_rules_comparator_new())); - gtk_paned_set_position (H_tree_vs_comparison, 300); - gtk_paned_set_wide_handle (H_tree_vs_comparison, TRUE); - gtk_paned_set_shrink_start_child (H_tree_vs_comparison, FALSE); - gtk_paned_set_shrink_end_child (H_tree_vs_comparison, FALSE); - return GTK_WIDGET (H_tree_vs_comparison); -} - -GtkWidget *get_run_rules_page_new(){ - GtkPaned *H_tree_vs_selected = GTK_PANED (gtk_paned_new (GTK_ORIENTATION_HORIZONTAL)); - -// GtkWidget *arbre_des_règles = gtk_frame_new ("Arbre des règles"); -// GtkWidget *édition_de_la_règle_sélectionnée_n_1 = gtk_frame_new ("Inspection"); - - gtk_paned_set_start_child (H_tree_vs_selected, GTK_WIDGET (get_rules_tree_hpaned_new())); - gtk_paned_set_end_child (H_tree_vs_selected, GTK_WIDGET (get_selected_rules_vpaned_new())); - gtk_paned_set_position (H_tree_vs_selected, 600); // WARNING : c'est une position "absolue" - gtk_paned_set_wide_handle (H_tree_vs_selected, TRUE); - // gtk_widget_set_size_request (GTK_WIDGET (H_tree_vs_selected), W, H); // inutile... ? - return GTK_WIDGET (H_tree_vs_selected); -} - diff --git a/hot.h b/hot.h index 348d3c3..9a6cce3 100644 --- a/hot.h +++ b/hot.h @@ -13,4 +13,4 @@ #include "contain.h" GtkWidget *get_run_rules_page_new(); -GtkWidget *get_image_GLUTAMATE(); + diff --git a/hot.o b/hot.o index 4aa6482..a1a8098 100644 Binary files a/hot.o and b/hot.o differ diff --git a/myprogram b/myprogram index fbe230d..d65bcce 100755 Binary files a/myprogram and b/myprogram differ diff --git a/tree.c b/tree.c new file mode 100644 index 0000000..8ebe8d4 --- /dev/null +++ b/tree.c @@ -0,0 +1,268 @@ +#include +#include + +#include "warm.h" +#include "cold.h" +#include "display.h" +#include "contain.h" +#include "texts.h" + +// https://docs.gtk.org/gtk4/visual_index.html < widgets gallery +// https://docs.gtk.org/gtk4/section-text-widget.html +// https://docs.gtk.org/gtk4/class.Widget.html#height-for-width-geometry-management +// GTK_ORIENTATION_VERTICAL GTK_ORIENTATION_HORIZONTAL + + + +// Simplified TreeNode structure for demonstration purposes +// -------------------------------------------------------- + +/* + * Tree-related signals + */ + +void on_tree_expander_toggled(GtkExpander *expander, gpointer user_data) +{ + // This is a conceptual callback for when an expander is toggled + 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_tree_setup_factory (GtkSignalListItemFactory *factory, + GObject* object, + gpointer user_data) +{ + GtkWidget* expander = gtk_expander_new (NULL); + gtk_list_item_set_child (GTK_LIST_ITEM(object), expander); + printf("[on_tree_setup_factory] here is an expander\n"); +} + +void on_tree_bind_factory (GtkSignalListItemFactory *factory, + GObject* object, + gpointer user_data) +{ +// GObject *item; + const gchar *text; + GtkTreeListRow *row; + GtkListItem *list_item; + GtkWidget *expander; + + list_item= GTK_LIST_ITEM(object); + row = gtk_list_item_get_item(list_item); + if (row != NULL) { + text = gtk_string_object_get_string(GTK_STRING_OBJECT(gtk_tree_list_row_get_item(row))); + expander = gtk_list_item_get_child(list_item); + gtk_expander_set_label(GTK_EXPANDER(expander), text); + + // Disconnect previous signal handlers to avoid stacking them + g_signal_handlers_disconnect_by_func(expander, G_CALLBACK(on_tree_expander_toggled), row); + + // Connect the signal handler + g_signal_connect(expander, "activate", G_CALLBACK(on_tree_expander_toggled), row); + + gtk_widget_set_margin_start(expander, gtk_tree_list_row_get_depth(row)*20); + gboolean is_expanded = gtk_tree_list_row_get_expanded(row); + printf("[on_tree_bind_factory] here is %s content and expander is %d\n", + text, + is_expanded); + } else { + printf("[on_tree_bind_factory] here is NON content\n"); + } +} + +void on_tree_selection_changed (GtkSelectionModel* self, guint position, + guint n_items, gpointer user_data) +{ + printf("[on_tree_selection_changed]\n"); +} + +struct TreeNode_t +{ + gchar *text; + struct TreeNode_t *child; + struct TreeNode_t *next; +}; + +// Function to create a new TreeNode instance +static struct TreeNode_t *create_tree_node (const gchar* text) +{ + struct TreeNode_t *node = g_malloc0 (sizeof(struct TreeNode_t)); + node->text = g_strdup(text); + node->child = NULL; + return node; +} + +// Function to add a child node to a parent node +static void add_child_node (struct TreeNode_t *parent, struct TreeNode_t *child) +{ + struct TreeNode_t *cur; + + if (parent->child) { + cur = parent->child; + while (cur && cur->next) { + cur = cur->next; + } + cur->next = child; + } else { + parent->child = child; + } +} + +// Recursive function to free a TreeNode and its children +// attention: « free_tree_node » défini mais pas utilisé <<< TODO +static void free_tree_node (struct TreeNode_t *node) +{ + struct TreeNode_t *cur; + struct TreeNode_t *tmp; + + if (!node) return; + + // free siblings + cur = node; + while (cur) { + tmp = cur->next; + g_free(cur); + cur = tmp; + } + + // recursive free + free_tree_node(node->child); + g_free(node->text); + g_free(node); +} + +// Function to simulate getting a GListModel of children for a given TreeNode +GListModel* ui_tree_get_children_model (struct TreeNode_t *parent) +{ + struct TreeNode_t *child; + + GtkStringList *list = NULL; + + if (parent) { + printf("[ui_tree_get_children_model] here is %s content : ", parent->text); + + child = parent->child; + + if (child) { + list = gtk_string_list_new(NULL); + } + while(child) { + gtk_string_list_append(list, child->text); + printf("%s ", child->text); + child = child->next; + } + } + printf("\n"); + + return G_LIST_MODEL(list); +} + +// GtkTreeListModelCreateModelFunc callback implementation +GListModel* ui_tree_create_model_func(GObject *item, gpointer root) +{ + struct TreeNode_t *cur = (struct TreeNode_t *)root; + struct TreeNode_t *parent = NULL; + + const gchar *string = gtk_string_object_get_string(GTK_STRING_OBJECT(item)); + + parent = root; + while (cur) { + if (strcmp(string, cur->text) == 0) { + break; + } + + cur = cur->next; + if (cur == NULL) { + cur = parent->child; + parent = cur; + } + } + + printf("[ui_tree_create_model_func] looked for %s in %s item\n", + cur->text, + string); + + return ui_tree_get_children_model(cur); +} + +// Application activation callback +static void ui_create_tree (GtkWidget *target_widget) +{ + GtkStringList *model; + GtkTreeListModel *tree_model; + GtkSignalListItemFactory *factory; + GtkSingleSelection *selection_model; + GtkWidget *list_view; + GtkScrolledWindow *scrolled_window; + + assert(target_widget); + + // AD HOC XXX & no free() + struct TreeNode_t *tree_root = create_tree_node("Root"); + struct TreeNode_t *ATP = create_tree_node("ATP"); + struct TreeNode_t *ADP = create_tree_node("ADP"); + struct TreeNode_t *AMP = create_tree_node("AMP"); + struct TreeNode_t *adenine = create_tree_node("adénine"); + struct TreeNode_t *ribose = create_tree_node("ribose"); + struct TreeNode_t *PO4H3_1 = create_tree_node("phosphate 1"); + struct TreeNode_t *PO4H3_2 = create_tree_node("phosphate 2"); + struct TreeNode_t *PO4H3_3 = create_tree_node("phosphate 3"); + + add_child_node(tree_root, ATP); + add_child_node(tree_root, ADP); + add_child_node(tree_root, AMP); + add_child_node(ATP, adenine); + add_child_node(adenine, ribose); + add_child_node(ribose, PO4H3_1); + add_child_node(PO4H3_1, PO4H3_2); + add_child_node(PO4H3_3, PO4H3_3); + + model = gtk_string_list_new(NULL); + gtk_string_list_append(model, tree_root->text); + + // Create and setup the list view and item factory + factory = GTK_SIGNAL_LIST_ITEM_FACTORY (gtk_signal_list_item_factory_new ()); + g_signal_connect (factory, "setup", G_CALLBACK(on_tree_setup_factory), NULL); + g_signal_connect (factory, "bind", G_CALLBACK(on_tree_bind_factory), NULL); + + // Create a GtkTreeListModel + tree_model = gtk_tree_list_model_new( + G_LIST_MODEL(model), + FALSE, // Passthrough - False in actual usage with dynamic children retrieval + FALSE, // autoexpand + (GtkTreeListModelCreateModelFunc)ui_tree_create_model_func, + tree_root, + NULL //(GDestroyNotify)free_tree_node + ); + + selection_model = gtk_single_selection_new ( + G_LIST_MODEL (tree_model)); + + gtk_single_selection_set_autoselect (selection_model, FALSE); + gtk_single_selection_set_can_unselect (selection_model, TRUE); + /* g_signal_connect (selection_model, "selection-changed", */ + /* G_CALLBACK(on_tree_selection_changed), NULL); */ + + list_view = gtk_list_view_new (GTK_SELECTION_MODEL (selection_model), + GTK_LIST_ITEM_FACTORY (factory)); + + scrolled_window = GTK_SCROLLED_WINDOW (gtk_scrolled_window_new()); + 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_box_append(GTK_BOX(target_widget), GTK_WIDGET(scrolled_window)); + gtk_widget_set_visible(GTK_WIDGET(scrolled_window), TRUE); + gtk_widget_set_visible(GTK_WIDGET(list_view), TRUE); +} + +GtkBox *get_rules_user_tree_new(){ + GtkBox *tree_sketch = GTK_BOX(gtk_box_new (GTK_ORIENTATION_VERTICAL, 0)); + ui_create_tree (GTK_WIDGET (tree_sketch)); + return tree_sketch; +} + diff --git a/tree.d b/tree.d new file mode 100644 index 0000000..517df2c --- /dev/null +++ b/tree.d @@ -0,0 +1,3 @@ +tree.o: tree.c warm.h \ + /gnu/store/fkmpkdav2zmz1k72989bdgpdrfac7rz1-glib-2.78.0/include/glib-2.0/glib.h \ + cold.h display.h contain.h texts.h diff --git a/tree.h b/tree.h new file mode 100644 index 0000000..38dc1b8 --- /dev/null +++ b/tree.h @@ -0,0 +1,10 @@ +/******************************************************************************/ +/* */ +/* E coli by David S. Goodsell (2009) */ +/* --- */ +/* Let this freeze frame guide us towards the model */ +/* that alone can account for the phenomenon ! */ +/* */ +/******************************************************************************/ + +GtkBox *get_rules_user_tree_new(); diff --git a/tree.o b/tree.o new file mode 100644 index 0000000..70527db Binary files /dev/null and b/tree.o differ