diff --git a/Makefile b/Makefile index 7012b2b..16a2d63 100644 --- a/Makefile +++ b/Makefile @@ -41,10 +41,15 @@ NTHREADS= $(shell nproc) CC=gcc WARNINGS= -Wall + +# applications should be compiled with the -Wl,--export-dynamic argument inside their compiler flags, < ? +# and linked against gmodule-export-2.0. < ? TODO + DEBUG= -ggdb -fno-omit-frame-pointer -fdiagnostics-color=always -fsanitize=bounds -fstack-check #-fsanitize=address \ #-fsanitize=pointer-compare -fsanitize=pointer-subtract \ #-fsanitize=leak -fsanitize=undefined -fsanitize=null -fsanitize=bounds + OPTIMIZE= -O3 INCLUDE= $(shell pkg-config --cflags glib-2.0 libxml-2.0 gtk4) LIBS= $(shell pkg-config --libs glib-2.0 libxml-2.0 gtk4) -lGL -lGLU -lm -lepoxy -lX11 -lGLEW diff --git a/include/base.h b/include/base.h index 5e49fe3..2718dd6 100644 --- a/include/base.h +++ b/include/base.h @@ -28,7 +28,7 @@ /* E coli by David S. Goodsell (2009) */ /* --- */ /* Knowing that only a dynamic model can explain this phenomenon, */ -/* let's let this beautiful freeze frame be our guide. */ +/* let this beautiful freeze frame be our guide. */ /* */ /******************************************************************************/ @@ -58,11 +58,6 @@ #define W_IMAGE_LOCAL W / 16 #define H_IMAGE_LOCAL H / 16 -//GtkWidget *get_selected_rules_vpaned_new(); - -//void activate (GtkApplication *app, gpointer user_data); - - // Graphical axis enum { diff --git a/include/contain.h b/include/contain.h index e1c089c..4b5967f 100644 --- a/include/contain.h +++ b/include/contain.h @@ -2,8 +2,8 @@ /* */ /* E coli by David S. Goodsell (2009) */ /* --- */ -/* Knowing that only a dynamic model can explain this phenomenon, */ -/* let's let this beautiful freeze frame be our guide. */ +/* Knowing that only a dynamic model can explore this phenomenon, */ +/* let this beautiful freeze frame be our guide. */ /* */ /******************************************************************************/ diff --git a/include/display.h b/include/display.h index 9367a1a..62b5e1b 100644 --- a/include/display.h +++ b/include/display.h @@ -2,8 +2,8 @@ /* */ /* E coli by David S. Goodsell (2009) */ /* --- */ -/* Let this freeze frame guide us towards the model */ -/* that alone can account for the phenomenon ! */ +/* Knowing that only a dynamic model can explain this phenomenon, */ +/* let this beautiful freeze frame be our guide. */ /* */ /******************************************************************************/ diff --git a/include/tree.h b/include/tree.h index b1d95d7..5ef9ef6 100644 --- a/include/tree.h +++ b/include/tree.h @@ -3,7 +3,7 @@ /* E coli by David S. Goodsell (2009) */ /* --- */ /* Knowing that only a dynamic model can explain this phenomenon, */ -/* let's let this beautiful freeze frame be our guide. */ +/* let this beautiful freeze frame be our guide. */ /* */ /******************************************************************************/ diff --git a/include/ui.h b/include/ui.h index 3d7d740..d17fc0e 100644 --- a/include/ui.h +++ b/include/ui.h @@ -130,6 +130,16 @@ void on_glarea_realize(GtkWidget *widget); void on_glarea_unrealize(GtkWidget *widget); void on_close_window(GtkWidget *widget); +/* + * A GtkBuilder holds a reference to all objects that it has constructed + * and drops these references when it is finalized. + * This finalization can cause the destruction of non-widget objects or widgets + * which are not contained in a toplevel window. + * For toplevel windows constructed by a builder, it is the responsibility of the user + * to call gtk_window_destroy() to get rid of them and all the widgets they contain. + * https://docs.gtk.org/gtk4/class.Builder.html + */ +void gtk_window_destroy (GtkWindow* window); // (in application.c) TODO ? // // Tree-related events diff --git a/src/main.c b/src/main.c index 11e2a60..d6d7688 100644 --- a/src/main.c +++ b/src/main.c @@ -28,7 +28,31 @@ #include "../include/base.h" #include "../include/ui.h" +/* ----------------------- DOCUMENTATION ---------------------------------- */ + +// https://docs.gtk.org/gio/class.Application.html +// https://docs.gtk.org/glib/main-loop.html +// https://developer.gnome.org/documentation/tutorials/main-contexts.html +// https://developer.gnome.org/documentation/tutorials/lists.html +// https://developer.gnome.org/documentation/tutorials/application.html +// https://developer.gnome.org/documentation/introduction.html +// https://docs.gtk.org/gtk3/getting_started.html < WARNING Gtk3 + /* -------------------------------------------------------------------------- */ +/* The main entry point for your application should only create a GtkApplication instance, + * set up the signal handlers, and then call g_application_run(). + * When saving and Loading Window State, you will need a GSettings schema, + * to define the keys, the type of the values, and default value for each key. + * Once you have a schema, you can map window properties to the GSettings keys defined by that schema + * To use GAction you should be using GtkApplication. + * GSimpleAction has two interesting signals: activate and change-state. + * You can add a GAction to anything implementing the GActionMap interface, including GtkApplication. + * This is done with g_action_map_add_action() and g_action_map_add_action_entries(). + * Pre- and post-condition assertions are implemented using g_return_if_fail() and g_return_val_if_fail(). + * + * https://docs.gtk.org/gtk4/class.Builder.html + * https://developer.gnome.org/documentation/tutorials/widget-templates.html + */ int main(int argc, char **argv) { diff --git a/src/ui/application.c b/src/ui/application.c index 519e291..8745389 100644 --- a/src/ui/application.c +++ b/src/ui/application.c @@ -24,8 +24,8 @@ #include "../../include/ui.h" -#define COMMUTE 1 // 0 first design (2023) based on XML data - // 1 2024 May design, free of the XML encryption mechanism +#define COMMUTE 0 // 0 first design (2023) based on XML data + // 1 2024 May design, free of Builder & templates /* Window actual presentation on screen */ static void gem_graph_client_application_activate (GApplication *app) @@ -41,16 +41,15 @@ static void gem_graph_client_application_activate (GApplication *app) NULL)); switch(COMMUTE) { // enum {...} in ui.h - case GG_2023: - // Launch with sidebar of gtk_notebook_append_pagef + case GG_2023: // Launch with sidebar of gtk_notebook_append_pagef ui_toggle_sidebar(); ui_set_stack (HOME_MODE); ui_debug_model_loading (window, "data/models/dimers random walk.xml"); // XXX the window closes when a leaf expander is clicked (Erreur de segmentation) break; - case GG_2024_05: - // see > in contain.c + case GG_2024_05: // see > in contain.c experimental_activate_00 (app, window); + // ui_debug_model_loading (window, "data/models/dimers random walk.xml"); break; default: break; @@ -127,7 +126,7 @@ void ui_send_notification(const char *message) static void gem_graph_client_application_class_init (GemGraphClientApplicationClass *klass) { GApplicationClass *app_class = G_APPLICATION_CLASS(klass); - + // app_class->activate = experimental_activate_00;// (app, window); < ?? XXX app_class->activate = gem_graph_client_application_activate; } @@ -142,3 +141,5 @@ GemGraphClientApplication *gem_graph_client_application_new( "flags", flags, NULL); } + +void gtk_window_destroy (GtkWindow* window) {printf("gtk_window_destroy() < TODO");} diff --git a/src/ui/contain.c b/src/ui/contain.c index 136b167..a001284 100644 --- a/src/ui/contain.c +++ b/src/ui/contain.c @@ -45,11 +45,11 @@ GtkWidget *get_edit_help_page_new(){ GtkWidget *get_run_measures_page_new(){ GtkWidget *measures_grid = gtk_grid_new(); - gtk_grid_attach (GTK_GRID (measures_grid), gtk_button_new_with_label ("movements"), 0, 0, 1, 1); - gtk_grid_attach (GTK_GRID (measures_grid), gtk_button_new_with_label ("transports"), 1, 0, 1, 1); - gtk_grid_attach (GTK_GRID (measures_grid), gtk_button_new_with_label ("transformations"), 2, 0, 1, 1); - gtk_grid_attach (GTK_GRID (measures_grid), gtk_button_new_with_label ("objects"), 0, 1, 1, 1); - gtk_grid_attach (GTK_GRID (measures_grid), gtk_button_new_with_label ("situations"), 1, 1, 1, 1); + gtk_grid_attach (GTK_GRID (measures_grid), gtk_button_new_with_label ("movements"), 0, 0, 1, 1); + gtk_grid_attach (GTK_GRID (measures_grid), gtk_button_new_with_label ("transports"), 1, 0, 1, 1); + gtk_grid_attach (GTK_GRID (measures_grid), gtk_button_new_with_label ("transformations"), 2, 0, 1, 1); + gtk_grid_attach (GTK_GRID (measures_grid), gtk_button_new_with_label ("objects"), 0, 1, 1, 1); + gtk_grid_attach (GTK_GRID (measures_grid), gtk_button_new_with_label ("situations"), 1, 1, 1, 1); return measures_grid; } @@ -102,7 +102,7 @@ GtkWidget *get_selected_rules_vpaned_new(){ GtkBox *up_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2)); gtk_box_append (up_box, GTK_WIDGET (get_image_GLUTAMATE())); - gtk_box_append (up_box, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_VERTICAL))); + gtk_box_append (up_box, GTK_WIDGET (gtk_separator_new (GTK_ORIENTATION_VERTICAL))); gtk_box_append (up_box, GTK_WIDGET (get_image_GLUTAMINE())); /* GtkBox *bottom_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2)); @@ -112,7 +112,7 @@ GtkWidget *get_selected_rules_vpaned_new(){ */ GtkBox *bottom_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2)); gtk_box_append (bottom_box, GTK_WIDGET (get_image_ATP())); - gtk_box_append (bottom_box, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_VERTICAL))); + gtk_box_append (bottom_box, GTK_WIDGET (gtk_separator_new (GTK_ORIENTATION_VERTICAL))); gtk_box_append (bottom_box, GTK_WIDGET (get_image_AMP())); gtk_paned_set_start_child (V_selected_1_vs_2, GTK_WIDGET (up_box)); @@ -132,7 +132,7 @@ GtkWidget *get_selected_rules_vpaned_new(){ GtkWidget *get_run_space_top_box(){ GtkBox *top_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2)); gtk_box_append (top_box, GTK_WIDGET (get_ELAPSED_TIME_ProgressBar())); - gtk_box_append (top_box, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_VERTICAL))); + gtk_box_append (top_box, GTK_WIDGET (gtk_separator_new (GTK_ORIENTATION_VERTICAL))); gtk_box_append (top_box, GTK_WIDGET (get_RUN_STOP_box())); return GTK_WIDGET (top_box); } @@ -180,8 +180,8 @@ void window_bar(GtkWindow *window, char *title){ void experimental_activate_00 (GtkApplication *app, GtkWindow *window) { window_bar (window, "E coli (with permission from David S. Goodsell, 2009)"); - GtkNotebook *run_notebook = GTK_NOTEBOOK(gtk_notebook_new()); - gtk_notebook_set_tab_pos (GTK_NOTEBOOK(run_notebook), GTK_POS_TOP); // GTK_POS_LEFT + GtkNotebook *run_notebook = GTK_NOTEBOOK (gtk_notebook_new()); + gtk_notebook_set_tab_pos (run_notebook, GTK_POS_TOP); // GTK_POS_LEFT gtk_notebook_append_page (run_notebook, get_run_space_page_new(), gtk_label_new ("space")); gtk_notebook_append_page (run_notebook, get_run_rules_page_new(), gtk_label_new ("rules")); @@ -190,8 +190,8 @@ void experimental_activate_00 (GtkApplication *app, GtkWindow *window) { gtk_notebook_append_page (run_notebook, get_run_discuss_page_new(), gtk_label_new ("interpret")); gtk_notebook_append_page (run_notebook, get_run_help_page_new(), gtk_label_new ("help")); - GtkNotebook *edit_notebook = GTK_NOTEBOOK(gtk_notebook_new()); - gtk_notebook_set_tab_pos (GTK_NOTEBOOK(edit_notebook), GTK_POS_TOP); // GTK_POS_RIGHT + GtkNotebook *edit_notebook = GTK_NOTEBOOK (gtk_notebook_new()); + gtk_notebook_set_tab_pos (edit_notebook, GTK_POS_TOP); // GTK_POS_RIGHT gtk_notebook_append_page (edit_notebook, get_edit_space_page_new(), gtk_label_new ("space")); gtk_notebook_append_page (edit_notebook, get_edit_rules_page_new(), gtk_label_new ("rules")); @@ -202,10 +202,10 @@ void experimental_activate_00 (GtkApplication *app, GtkWindow *window) { GtkWidget *run_xor_edit_horizontal_pane = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL); gtk_widget_set_size_request (run_xor_edit_horizontal_pane, 0, 0); - gtk_paned_set_start_child (GTK_PANED(run_xor_edit_horizontal_pane), GTK_WIDGET (run_notebook)); + gtk_paned_set_start_child (GTK_PANED (run_xor_edit_horizontal_pane), GTK_WIDGET (run_notebook)); gtk_paned_set_end_child (GTK_PANED(run_xor_edit_horizontal_pane), GTK_WIDGET (edit_notebook)); gtk_paned_set_position (GTK_PANED (run_xor_edit_horizontal_pane), W_IMAGE + 350); // '350' : AD HOC - gtk_window_set_child (window, GTK_WIDGET(run_xor_edit_horizontal_pane)); + gtk_window_set_child (window, GTK_WIDGET (run_xor_edit_horizontal_pane)); 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/src/ui/display.c b/src/ui/display.c index 1bad14f..58fbb64 100644 --- a/src/ui/display.c +++ b/src/ui/display.c @@ -3,7 +3,7 @@ /* E coli by David S. Goodsell (2009) */ /* --- */ /* Knowing that only a dynamic model can explain this phenomenon, */ -/* let's let this beautiful freeze frame be our guide. */ +/* let this beautiful freeze frame be our guide. */ /* */ /******************************************************************************/ @@ -25,6 +25,7 @@ GtkWidget *get_image_ALL_SPACE(){ image = gtk_image_new_from_file("data/image/aXoris.png"); image = gtk_picture_new_for_filename ("data/image/gg sketch.png"); image = gtk_picture_new_for_filename ("data/image/E coli (Goodsell).png"); + // ui_setup_glarea (RUN_MODE, GTK_WIDGET(image)); < un essai... gtk_widget_set_size_request (GTK_WIDGET (image), W_IMAGE, H_IMAGE); return image; } diff --git a/src/ui/gemgraph.ui b/src/ui/gemgraph.ui index 0194639..35a855a 100644 --- a/src/ui/gemgraph.ui +++ b/src/ui/gemgraph.ui @@ -33,7 +33,8 @@ sidebar-show-symbolic Display/hide sidebar app.togglesidebar - + + diff --git a/src/ui/views.c b/src/ui/views.c index 0ef9ff5..bbe2792 100644 --- a/src/ui/views.c +++ b/src/ui/views.c @@ -108,20 +108,26 @@ char* ui_tree_create_model_func (GObject *item, gpointer root) return ui_tree_get_children_model (cur); } +static void print_widget_hierarchy(GtkWidget *widget){ + assert(widget); + printf("[src/ui/views.ui_create_tree (GtkWidget *w)] widgets hiercharchy : %s > %s > %s > %s > %s > %s > %s > %s\n",\ + gtk_widget_get_name (GTK_WIDGET (gtk_widget_get_root (widget))),\ + gtk_widget_get_name (gtk_widget_get_parent (gtk_widget_get_parent (gtk_widget_get_parent (gtk_widget_get_parent (gtk_widget_get_parent (widget)))))),\ + gtk_widget_get_name (gtk_widget_get_parent (gtk_widget_get_parent (gtk_widget_get_parent (gtk_widget_get_parent (widget))))),\ + gtk_widget_get_name (gtk_widget_get_parent (gtk_widget_get_parent (gtk_widget_get_parent (widget)))),\ + gtk_widget_get_name (gtk_widget_get_parent (gtk_widget_get_parent (widget))),\ + gtk_widget_get_name (gtk_widget_get_parent (widget)),\ + gtk_widget_get_name (widget),\ + gtk_widget_get_name (gtk_widget_get_first_child (widget)) + ); +} + // Application activation callback void ui_create_tree (GtkWidget *target_widget) { assert(target_widget); - printf("[src/ui/views.ui_create_tree (GtkWidget *w)] widgets hiercharchy : %s > %s > %s > %s > %s > %s > %s > %s\n",\ - gtk_widget_get_name (GTK_WIDGET (gtk_widget_get_root (target_widget))),\ - gtk_widget_get_name (gtk_widget_get_parent (gtk_widget_get_parent (gtk_widget_get_parent (gtk_widget_get_parent (gtk_widget_get_parent (target_widget)))))),\ - gtk_widget_get_name (gtk_widget_get_parent (gtk_widget_get_parent (gtk_widget_get_parent (gtk_widget_get_parent (target_widget))))),\ - gtk_widget_get_name (gtk_widget_get_parent (gtk_widget_get_parent (gtk_widget_get_parent (target_widget)))),\ - gtk_widget_get_name (gtk_widget_get_parent (gtk_widget_get_parent (target_widget))),\ - gtk_widget_get_name (gtk_widget_get_parent (target_widget)),\ - gtk_widget_get_name (target_widget),\ - gtk_widget_get_name (gtk_widget_get_first_child (target_widget)) - ); + print_widget_hierarchy(target_widget); + // We don't want to add another tree in another scrolled_window into the current GtkBox, so : if (gtk_widget_get_first_child (target_widget)) return;