diff --git a/include/base.h b/include/base.h index 85d6d77..1bea733 100644 --- a/include/base.h +++ b/include/base.h @@ -22,6 +22,18 @@ * along with this program. If not, see . */ + +/******************************************************************************/ +/* */ +/* E coli by David S. Goodsell (2009) */ +/* --- */ +/* Let this freeze frame guide us towards the model */ +/* that alone can account for the phenomenon ! */ +/* */ +/******************************************************************************/ + + + #pragma once #include #include @@ -37,6 +49,20 @@ #include //#define G_APPLICATION_DEFAULT_FLAGS 0 + +#define W 1920 +#define H 960 +#define W_IMAGE W - 320 +#define H_IMAGE H - 126 +#define H_STYLES_PANE 30 +#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 new file mode 100644 index 0000000..f19141e --- /dev/null +++ b/include/contain.h @@ -0,0 +1,22 @@ +//******************************************************************************/ +/* */ +/* E coli by David S. Goodsell (2009) */ +/* --- */ +/* Let this freeze frame guide us towards the model */ +/* that alone can account for the phenomenon ! */ +/* */ +/******************************************************************************/ + +#include + +#define W 1920 +#define H 960 +#define W_IMAGE W - 320 +#define H_IMAGE H - 126 +#define H_STYLES_PANE 30 +#define W_IMAGE_LOCAL W / 16 +#define H_IMAGE_LOCAL H / 16 + +GtkWidget *get_selected_rules_vpaned_new(); +void experimental_activate (GtkApplication *app, gpointer user_data); +void window_bar(GtkWindow *window, char *title); diff --git a/include/display.h b/include/display.h new file mode 100644 index 0000000..9367a1a --- /dev/null +++ b/include/display.h @@ -0,0 +1,33 @@ +/******************************************************************************/ +/* */ +/* E coli by David S. Goodsell (2009) */ +/* --- */ +/* Let this freeze frame guide us towards the model */ +/* that alone can account for the phenomenon ! */ +/* */ +/******************************************************************************/ + +GtkWidget *get_text_view(); +GtkFrame *get_frame_with_label(); +GtkWidget *get_run_rules_page_new(); +GtkBox *get_rules_user_tree_new(); + +GtkWidget *get_image_ALL_SPACE(); +GtkWidget *get_image_GLUTAMATE(); +GtkWidget *get_image_GLUTAMINE(); +GtkWidget *get_image_HISTIDINE(); +GtkWidget *get_image_HISTAMINE(); +GtkWidget *get_image_PHENYLALANINE(); +GtkWidget *get_image_DOPAMINE(); +GtkWidget *get_image_ATP(); +GtkWidget *get_image_AMP(); + +GtkProgressBar *get_ELAPSED_TIME_ProgressBar(); +GtkBox *get_RUN_STOP_box(); +GtkBox *get_ZOOM_box(); +GtkBox *get_edit_TOOL_box(); +GtkBox *get_XYZ_box(); +GtkWidget *get_OBJECTS_and_SITUATIONS(); +GtkBox *get_ELAPSED_TIME_box(); + +void window_bar(GtkWindow *window, char *title); diff --git a/include/hot.h b/include/hot.h new file mode 100644 index 0000000..6534c4e --- /dev/null +++ b/include/hot.h @@ -0,0 +1,14 @@ +/******************************************************************************/ +/* */ +/* E coli by David S. Goodsell (2009) */ +/* --- */ +/* Let this freeze frame guide us towards the model */ +/* that alone can account for the phenomenon ! */ +/* */ +/******************************************************************************/ + +#include "display.h" +#include "contain.h" +#include + +GtkScrolledWindow *get_user_rules_tree (); diff --git a/include/texts.h b/include/texts.h new file mode 100644 index 0000000..43a7437 --- /dev/null +++ b/include/texts.h @@ -0,0 +1,39 @@ +char *get_space_run_edit_specif(); +char *get_rules_run_edit_specif(); + +/* +>>> Dans : [space_page - mode RUN] doivent être : ------------------------------------------------------ + +(1) les commandes de mouvement: + - run/stop, slow down/speed up, step by step, do/undo/redo + + le buffer [elapsed time] qui montre le temps de simulation écoulé +(2) les commandes qui modifient la perception de l'espace (la caméra) + - son orientation (X,Y,Z), + + le zoom, + + les paramètres qui définissent la perspective (distances oeil/écran, écran/objet virtuel) +(3) les commandes qui modifient les apparences des objets et des situations d'intérêt + (+/- transparents, colorés, etc.) +(4) les commandes qui modifient l'apparence de l'espace (grilles, +/- surfaces, aspect des flèches, etc.) +(0) NB >>> AUCUNE COMMANDE NE DOIT PERMETTRE D'ÉDITER L'ESPACE ! <<< +>>> Dans : [space_page - mode EDIT] doivent être : ------------------------------------------------------ +(1) les commandes qui modifient la perception de l'espace (la caméra) + - son orientation (X,Y,Z), + + le zoom, + + les paramètres qui définissent la perspective (distances oeil/écran, écran/objet virtuel) +(2) les commandes qui modifient les apparences des objets et des situations d'intérêt + (+/- transparents, colorés, etc.) +(3) les commandes qui modifient l'apparence de l'espace (grilles, +/- surfaces, aspect des flèches, etc.) +(4) les commandes d'édition locales (drag and drop une flèche) + ('faire de la place' pour insérer) + (sélectionner pour déplacer ou enlever...) + NB ces commandes doivent être graphiques et/ou accessibles par raccourcis ou en ligne +(5) les commandes d'édition globales + (ex: introduire, retirer, transformer +/-aléatoirement (n) objets dans l'espace) + NB une action effectuée sur une zone d'intérêt devrait pouvoir être automatiquement appliquée + à d'autres zones d'intérêt identifiées comme similaires +(0) NB >>> AUCUNE COMMANDE NE DOIT PERMETTRE D'EXÉCUTER UN RUN ! <<< +>>> L'objectif est que l'utilisateur ait accès à une organsisation aussi ergonomique que possible ----- + i.e : chaque utilisateur devrait disposer de 'préférences' + c'est-à-dire avoir la possiblité de faire des choix ergonomiques personnalisés. +*/ + diff --git a/src/ui/application.c b/src/ui/application.c index c34fedd..845c321 100644 --- a/src/ui/application.c +++ b/src/ui/application.c @@ -61,12 +61,12 @@ void ui_disable_action(const char *name) { */ static void gem_graph_client_application_activate(GApplication *app) { - GtkWindow *window; - int commute_XML_ui_based_window = 1; if (commute_XML_ui_based_window) { + GtkWindow *window; + g_assert(GEM_GRAPH_CLIENT_IS_APPLICATION(app)); window = gtk_application_get_active_window(GTK_APPLICATION (app)); @@ -80,13 +80,16 @@ static void gem_graph_client_application_activate(GApplication *app) ui_set_stack(HOME_MODE); ui_debug_model_loading (window, "data/models/dimers random walk.xml"); + gtk_window_present(window); + } else { - window = GTK_WINDOW (gtk_application_window_new (app)); - + char *user_data = NULL; + experimental_activate (app, user_data); + // in experimental_activate () are : + // window = GTK_WINDOW (gtk_application_window_new (GTK_APPLICATION (app))); and + // gtk_window_present(window); } - - gtk_window_present(window); } /* diff --git a/src/ui/contain.c b/src/ui/contain.c new file mode 100644 index 0000000..55764a0 --- /dev/null +++ b/src/ui/contain.c @@ -0,0 +1,215 @@ +#include +#include + +#include "../../include/hot.h" +#include "../../include/display.h" +#include "../../include/contain.h" +#include "../../include/texts.h" + + +GtkWidget *get_edit_rules_page_new(){ + GtkPaned *hpaned = 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 = gtk_frame_new ("Édition de la règle sélectionnée"); + + gtk_paned_set_start_child (hpaned, GTK_WIDGET (arbre_des_règles)); + gtk_paned_set_end_child (hpaned, GTK_WIDGET (édition_de_la_règle_sélectionnée)); + // gtk_widget_set_size_request (GTK_WIDGET (hpaned), W, H); + gtk_paned_set_wide_handle (hpaned, TRUE); + + return GTK_WIDGET (hpaned); +} + +GtkWidget *get_edit_measures_page_new(){ + GtkWidget *measures_grid = gtk_grid_new(); + return measures_grid; +} + +GtkWidget *get_edit_results_page_new(){ + GtkWidget *xxx_grid = gtk_grid_new(); + return xxx_grid; +} + +GtkWidget *get_edit_discuss_page_new(){ + GtkWidget *xxx_grid = gtk_grid_new(); + return xxx_grid; +} + +GtkWidget *get_edit_help_page_new(){ +// GtkWidget *edit_help_grid = gtk_grid_new(); +// gtk_grid_attach (GTK_GRID(edit_help_grid), GTK_WIDGET(get_frame_with_label()), 0, 0, 1, 1); +// return edit_help_grid; + return NULL; +} + +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); + return measures_grid; +} + +GtkWidget *get_run_results_page_new(){ + GtkWidget *results_grid = gtk_grid_new(); + gtk_grid_attach (GTK_GRID(results_grid), gtk_button_new_with_label ("Repartitions"), 0, 0, 1, 1); + gtk_grid_attach (GTK_GRID(results_grid), gtk_button_new_with_label ("Correlations"), 0, 1, 1, 1); + gtk_grid_attach (GTK_GRID(results_grid), gtk_button_new_with_label ("Evolutions"), 0, 2, 1, 1); + return results_grid; +} + +GtkWidget *get_run_discuss_page_new(){ + GtkWidget *discuss_grid = gtk_grid_new(); + gtk_grid_attach (GTK_GRID (discuss_grid), gtk_button_new_with_label ("Interpretations"), 0, 0, 1, 1); + gtk_grid_attach (GTK_GRID (discuss_grid), gtk_button_new_with_label ("Discussions"), 0, 1, 1, 1); + return discuss_grid; +} + +GtkWidget *get_run_help_page_new(){ +// GtkWidget *run_help_grid = gtk_grid_new(); +// gtk_grid_attach (GTK_GRID(run_help_grid), GTK_WIDGET(get_frame_with_label()), 0, 0, 1, 1); +// return run_help_grid; + return NULL; +} + +/* +GtkWidget *get_run_rules_page_new(){ @see hot.c 2024-05-11 } (line 166) +*/ + +GtkWidget *get_edit_space_page_new(){ + GtkWidget *space_grid = gtk_grid_new(); + gtk_grid_attach (GTK_GRID(space_grid), get_image_ALL_SPACE(), 0, 0, 1, 3); + gtk_grid_attach (GTK_GRID(space_grid), get_OBJECTS_and_SITUATIONS(), 0, 4, 1, 1); + gtk_grid_attach (GTK_GRID(space_grid), GTK_WIDGET(get_XYZ_box()), 1, 0, 1, 2); + gtk_grid_attach (GTK_GRID(space_grid), GTK_WIDGET(get_ZOOM_box()), 1, 2, 1, 2); + gtk_grid_attach (GTK_GRID(space_grid), GTK_WIDGET(get_edit_TOOL_box()), 1, 3, 1, 2); + gtk_widget_set_size_request (space_grid, W, H); +// How to use gtk_separators ? +// gtk_grid_attach (GTK_GRID(space_grid), GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL)), 1, 1, 1, 1); + return space_grid; +} + +//------------------------------------------------------------------------------ + +GtkWidget *get_selected_rules_vpaned_new(){ + GtkPaned *V_selected_1_vs_2 = GTK_PANED (gtk_paned_new (GTK_ORIENTATION_VERTICAL)); + +// GtkWidget *règle_sélectionnée_n_1 = gtk_frame_new ("(1)"); +// GtkWidget *règle_sélectionnée_n_2 = gtk_frame_new ("(2)"); + + 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 (get_image_GLUTAMINE())); +/* + GtkBox *bottom_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2)); + gtk_box_append (bottom_box, GTK_WIDGET (get_image_PHENYLALANINE())); + gtk_box_append (bottom_box, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_VERTICAL))); + gtk_box_append (bottom_box, GTK_WIDGET (get_image_DOPAMINE())); +*/ + 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 (get_image_AMP())); + + gtk_paned_set_start_child (V_selected_1_vs_2, GTK_WIDGET (up_box)); + gtk_paned_set_end_child (V_selected_1_vs_2, GTK_WIDGET (bottom_box)); + +// gtk_paned_set_start_child (V_selected_1_vs_2, GTK_WIDGET (règle_sélectionnée_n_1)); +// gtk_paned_set_end_child (V_selected_1_vs_2, GTK_WIDGET (règle_sélectionnée_n_2)); + +// gtk_box_append ( GTK_BOX(règle_sélectionnée_n_1), GTK_WIDGET (up_box));//, GTK_WIDGET (get_image_GLUTAMATE())); +// gtk_box_append ( GTK_BOX(règle_sélectionnée_n_2), GTK_WIDGET (bottom_box));//, GTK_WIDGET (get_image_GLUTAMATE())); + + return GTK_WIDGET (V_selected_1_vs_2); +} + + + +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 (get_RUN_STOP_box())); + return GTK_WIDGET (top_box); +} + +GtkWidget *get_run_space_left_box(){ + GtkBox *left_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_VERTICAL, 2)); + gtk_box_append (left_box, GTK_WIDGET (get_image_ALL_SPACE())); + gtk_box_append (left_box, GTK_WIDGET (get_OBJECTS_and_SITUATIONS())); + return GTK_WIDGET (left_box); +} + +GtkWidget *get_run_space_right_box(){ + GtkBox *right_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_VERTICAL, 2)); + gtk_box_append (right_box, GTK_WIDGET (get_XYZ_box())); + gtk_box_append (right_box, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); + gtk_box_append (right_box, GTK_WIDGET (get_ZOOM_box())); + return GTK_WIDGET (right_box); +} + +GtkWidget *get_run_space_bottom_box(){ + GtkBox *bottom_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2)); + gtk_box_append (bottom_box, GTK_WIDGET (get_run_space_left_box())); + gtk_box_append (bottom_box, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_VERTICAL))); + gtk_box_append (bottom_box, GTK_WIDGET (gtk_label_new (" "))); // AD HOC (pour "centrer") + gtk_box_append (bottom_box, GTK_WIDGET (get_run_space_right_box())); + return GTK_WIDGET (bottom_box); +} + +GtkWidget *get_run_space_page_new(){ + GtkBox *page_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_VERTICAL, 2)); + gtk_box_append (page_box, GTK_WIDGET (get_run_space_top_box())); + gtk_box_append (page_box, GTK_WIDGET(gtk_separator_new (GTK_ORIENTATION_HORIZONTAL))); + gtk_box_append (page_box, GTK_WIDGET (get_run_space_bottom_box())); + return GTK_WIDGET (page_box); +} + +void window_bar(GtkWindow *window, char *title){ + GtkWidget *titlebar = gtk_header_bar_new(); + gtk_window_set_title (window, title); + gtk_window_set_titlebar (window, titlebar); // header_bar +// GtkWidget my_window_controls = *gtk_window_controls_new (GTK_PACK_END); // _START +// gtk_window_controls_set_decoration_layout (GTK_WINDOW_CONTROLS(my_window_controls), NULL); // const char* layout); +} + +void experimental_activate (GtkApplication *app, gpointer user_data) { + GtkWindow *window = GTK_WINDOW (gtk_application_window_new (app)); + 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 + + 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")); + gtk_notebook_append_page (run_notebook, get_run_measures_page_new(),gtk_label_new ("measures")); + gtk_notebook_append_page (run_notebook, get_run_results_page_new(), gtk_label_new ("results")); + 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 + + 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")); + gtk_notebook_append_page (edit_notebook, get_edit_measures_page_new(),gtk_label_new ("measures")); + gtk_notebook_append_page (edit_notebook, get_edit_results_page_new(), gtk_label_new ("results")); + gtk_notebook_append_page (edit_notebook, get_edit_discuss_page_new(), gtk_label_new ("interpret")); + gtk_notebook_append_page (edit_notebook, get_edit_help_page_new(), gtk_label_new ("help")); + + 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_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_present (GTK_WINDOW (window)); + + 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 new file mode 100644 index 0000000..aa46004 --- /dev/null +++ b/src/ui/display.c @@ -0,0 +1,281 @@ +#include +#include + +#include "../../include/hot.h" +#include "../../include/display.h" +#include "../../include/contain.h" +#include "../../include/texts.h" + +//------------------------------------------------------------------------------ + +GtkWidget *get_image_ALL_SPACE(){ + GtkWidget *image; + // forget > GTK_WIDGET(get_scrolled_gl_area()); + // Use GtkImage if you want to display a fixed-size icon + // and GtkPicture if you want to display a (maybe) scaled picture. + 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"); + gtk_widget_set_size_request (GTK_WIDGET (image), W_IMAGE, H_IMAGE); + return image; +} + +GtkWidget *get_image_GLUTAMATE(){ + GtkWidget *image = gtk_picture_new_for_filename ("data/image/glutamate.png"); + gtk_widget_set_size_request (GTK_WIDGET (image), W_IMAGE_LOCAL, H_IMAGE_LOCAL); + return image; +} + +GtkWidget *get_image_GLUTAMINE(){ + GtkWidget *image = gtk_picture_new_for_filename ("data/image/glutamine.png"); + gtk_widget_set_size_request (GTK_WIDGET (image), W_IMAGE_LOCAL, H_IMAGE_LOCAL); + return image; +} + +GtkWidget *get_image_HISTIDINE(){ + GtkWidget *image = gtk_picture_new_for_filename ("data/image/histidine.png"); + gtk_widget_set_size_request (GTK_WIDGET (image), W_IMAGE_LOCAL, H_IMAGE_LOCAL); + return image; +} + +GtkWidget *get_image_HISTAMINE(){ + GtkWidget *image = gtk_picture_new_for_filename ("data/image/histamine.png"); + gtk_widget_set_size_request (GTK_WIDGET (image), W_IMAGE_LOCAL, H_IMAGE_LOCAL); + return image; +} + +GtkWidget *get_image_PHENYLALANINE(){ + GtkWidget *image = gtk_picture_new_for_filename ("data/image/phénylalanine.png"); + gtk_widget_set_size_request (GTK_WIDGET (image), W_IMAGE_LOCAL, H_IMAGE_LOCAL); + return image; +} + +GtkWidget *get_image_DOPAMINE(){ + GtkWidget *image = gtk_picture_new_for_filename ("data/image/dopamine.png"); + gtk_widget_set_size_request (GTK_WIDGET (image), W_IMAGE_LOCAL, H_IMAGE_LOCAL); + return image; +} + +GtkWidget *get_image_ATP(){ + GtkWidget *image = gtk_picture_new_for_filename ("data/image/ATP.png"); + gtk_widget_set_size_request (GTK_WIDGET (image), W_IMAGE_LOCAL, H_IMAGE_LOCAL); + return image; +} + +GtkWidget *get_image_AMP(){ + GtkWidget *image = gtk_picture_new_for_filename ("data/image/AMP.png"); + gtk_widget_set_size_request (GTK_WIDGET (image), W_IMAGE_LOCAL, H_IMAGE_LOCAL); + return image; +} + +GtkWidget *get_user_tree(){ + GtkWidget *image = gtk_picture_new_for_filename ("data/image/arbre utilisateur.png"); + gtk_widget_set_size_request (GTK_WIDGET (image), W_IMAGE_LOCAL, H_IMAGE_LOCAL); + return image; +} + +//------------------------------------------------------------------------------ + +// TODO cliquer sur "RUN" --> affiche "STOP" (et inversement) +static GtkWidget *get_scroll_speed(){ + GtkAdjustment *speed_adjust = gtk_adjustment_new (100, 0, 100, 1, 0, 0); + GtkWidget *scroll_speed = gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, speed_adjust); + gtk_widget_set_size_request (GTK_WIDGET (scroll_speed), 120, 2); + return 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, 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, 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_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"))); + return RUN_STOP_box; +} +//------------------------------------------------------------------------------ + +GtkBox *get_ZOOM_box(){ + GtkBox *ZOOM_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0)); + GtkWidget *ZOOM_Label = GTK_WIDGET (gtk_label_new (\ + "\n TOOLS\n ---\n zoom\n ---\n (space\n struct.)\n\ + ---\n (arrows\n struct.)\n")); + gtk_widget_set_size_request (GTK_WIDGET (ZOOM_box), 10, 80); + gtk_box_append (ZOOM_box, ZOOM_Label); + return ZOOM_box; +} + +//------------------------------------------------------------------------------ + +GtkBox *get_edit_TOOL_box(){ + GtkBox *TOOL_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0)); + GtkWidget *ZOOM_Label = GTK_WIDGET (gtk_label_new ("TOOLS\n ---\n(space\nstruct.)")); + gtk_widget_set_size_request (GTK_WIDGET (TOOL_box), 10, 120); + gtk_box_append (TOOL_box, ZOOM_Label); + return TOOL_box; +} + +//------------------------------------------------------------------------------ + +GtkBox *get_XYZ_box(){ + GtkBox *XYZ_labels_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_VERTICAL, 2)); // spacing = 2 + GtkBox *XYZ_scrollbar_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2)); // spacing = 2q + // GtkWidget *scale_X = gtk_scale_button_new (0, 360, 10, NULL); < à étudier + // (double min, double max, double step, const char** icons) + GtkAdjustment *X_adjust = gtk_adjustment_new (0, 0, 380, 1, 0, 0); + GtkAdjustment *Y_adjust = gtk_adjustment_new (0, 0, 380, 1, 0, 0); + GtkAdjustment *Z_adjust = gtk_adjustment_new (0, 0, 380, 1, 0, 0); + GtkWidget *scroll_X = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, X_adjust); + GtkWidget *scroll_Y = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, Y_adjust); + GtkWidget *scroll_Z = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, Z_adjust); + gtk_widget_set_size_request (GTK_WIDGET (scroll_X), 1, 500); + + gtk_box_append (XYZ_scrollbar_box, GTK_WIDGET (gtk_label_new (" "))); // AD HOC (pour "centrer") + gtk_box_append (XYZ_scrollbar_box, scroll_X); + gtk_box_append (XYZ_scrollbar_box, scroll_Y); + gtk_box_append (XYZ_scrollbar_box, scroll_Z); + + gtk_box_append (XYZ_labels_box, GTK_WIDGET (gtk_label_new ("\nX Y Z"))); + gtk_box_append (XYZ_labels_box, GTK_WIDGET (XYZ_scrollbar_box)); + gtk_box_append (XYZ_labels_box, GTK_WIDGET (gtk_label_new (""))); + return XYZ_labels_box; +} + +//------------------------------------------------------------------------------ + +GtkProgressBar *get_ELAPSED_TIME_ProgressBar(){ // To rename : DO - UNDO - REDO ? + GtkProgressBar *buffer = GTK_PROGRESS_BAR (gtk_progress_bar_new ()); + gtk_progress_bar_set_text (buffer,\ + "\n<--- [buffer] (simulation extensive time) --->\n\ + supports DO - UNDO - REDO functions\n"); + gtk_progress_bar_set_show_text (buffer, TRUE); + gtk_widget_set_size_request (GTK_WIDGET (buffer), W - 560, 0); + return buffer; +} + +//------------------------------------------------------------------------------ + +// Chaque label "objet" ou "situation" sera remplacé par un curseur "transparence" (vertical) + +static GtkBox *get_objects_box(){ + GtkBox *objects_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0)); + GtkAdjustment *adjust = gtk_adjustment_new (0, 0, 255, 1, 0, 0); + if (0) for (int i = 0; i < 10; i++) + gtk_box_append (objects_box, gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, adjust)); + char string[7]; + for (int i = 0; i < 16; i++){ + sprintf(string, "[%d] ", i); + if (0) printf("%s\n", string); // répété deux fois ! pourquoi ? + gtk_box_append (objects_box, GTK_WIDGET (gtk_label_new (string))); + } + gtk_box_append (objects_box, GTK_WIDGET (gtk_label_new (" membrane "))); + gtk_box_append (objects_box, GTK_WIDGET (gtk_label_new (" co-enzyme A "))); + gtk_box_append (objects_box, GTK_WIDGET (gtk_label_new (" ribosome "))); + gtk_box_append (objects_box, GTK_WIDGET (gtk_label_new (" ATP synthase "))); + return objects_box; +} + +static GtkBox *get_situations_box(){ + GtkBox *situations_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0)); + char string[7]; + for (int i = 0; i < 64; i++){ + sprintf(string, "[%d] ", i); + if (0) printf("%s\n", string); // répété deux fois ! pourquoi ? + gtk_box_append (situations_box, GTK_WIDGET (gtk_label_new (string))); + } + gtk_box_append (situations_box, GTK_WIDGET (gtk_label_new (" transcription "))); + gtk_box_append (situations_box, GTK_WIDGET (gtk_label_new (" transport Na/K "))); + gtk_box_append (situations_box, GTK_WIDGET (gtk_label_new (" ubiquitination "))); + gtk_box_append (situations_box, GTK_WIDGET (gtk_label_new (" rotation moteur flagellaire "))); + return situations_box; +} + +static GtkWidget *get_frame_objects(){ + GtkWidget *scroll = gtk_scrolled_window_new (); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER); + GtkWidget *frame_objects = gtk_frame_new (" Objects"); // defines each class of object transparence + gtk_widget_set_size_request (frame_objects, 0, H_STYLES_PANE); // < utile seulement pour la largeur min/max + gtk_frame_set_child (GTK_FRAME (frame_objects), GTK_WIDGET (get_objects_box())); + gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scroll), frame_objects); + return scroll; +} + +static GtkWidget *get_frame_situations(){ + GtkWidget *scroll = gtk_scrolled_window_new (); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER); + GtkWidget *frame_situations = gtk_frame_new (" Situations"); // facilitates each situation identification + gtk_widget_set_size_request (GTK_WIDGET (frame_situations), 0, H_STYLES_PANE); // < utile seulement pour la largeur min/max + gtk_frame_set_child (GTK_FRAME (frame_situations), GTK_WIDGET (get_situations_box())); + gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scroll), frame_situations); + return scroll; +} + +GtkWidget *get_OBJECTS_and_SITUATIONS(){ + GtkWidget *objects_and_situations_horizontal_pane = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL); + gtk_paned_set_start_child (GTK_PANED(objects_and_situations_horizontal_pane), GTK_WIDGET (get_frame_objects())); + gtk_paned_set_end_child (GTK_PANED(objects_and_situations_horizontal_pane), GTK_WIDGET (get_frame_situations())); + return objects_and_situations_horizontal_pane; +} + + +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_user_rules_tree())); + 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/src/ui/hot.c b/src/ui/hot.c new file mode 100644 index 0000000..937469a --- /dev/null +++ b/src/ui/hot.c @@ -0,0 +1,156 @@ +#include +#include + +#include "../../include/display.h" +#include "../../include/contain.h" +#include "../../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 + + +static struct TreeNode_t {gchar *text; struct TreeNode_t *child, *next;}; +static void add_child_node (struct TreeNode_t *parent, struct TreeNode_t *child); +static struct TreeNode_t *create_user_tree_node (const gchar* text){ + struct TreeNode_t *node = g_malloc0 (sizeof(struct TreeNode_t)); + node->text = g_strdup (text); + node->child = NULL; // if (0) printf("create_user_tree_node %s\n", text); + return node; +} + +static void create_a_complex_useless_and_expensive_tree (struct TreeNode_t *tree_root){ +/* struct TreeNode_t *move_random = create_user_tree_node("move random"); add_child_node(tree_root, move_random); + struct TreeNode_t *move_determ = create_user_tree_node("move determ"); add_child_node(tree_root, move_determ); + struct TreeNode_t *transport = create_user_tree_node("transport"); add_child_node(tree_root, transport);*/ + struct TreeNode_t *transform = create_user_tree_node("transform"); add_child_node(tree_root, transform); + struct TreeNode_t *regulate = create_user_tree_node("regulate"); add_child_node(tree_root, regulate); +/* struct TreeNode_t *isole = create_user_tree_node("isolated object"); add_child_node(move_random, isole); + struct TreeNode_t *relie = create_user_tree_node("part of object"); add_child_node(move_random, relie); + struct TreeNode_t *no_payload = create_user_tree_node("free"); add_child_node(transport, no_payload); + struct TreeNode_t *charged = create_user_tree_node("charged"); add_child_node(transport, charged); + struct TreeNode_t *spontaneous = create_user_tree_node("spontaneous"); add_child_node(transform, spontaneous);*/ + struct TreeNode_t *catalysed = create_user_tree_node("catalysed"); add_child_node(transform, catalysed); +/* struct TreeNode_t *isole_1D = create_user_tree_node("isolated object move 1D"); add_child_node(isole, isole_1D); + struct TreeNode_t *isole_2D = create_user_tree_node("isolated object move 2D"); add_child_node(isole, isole_2D); + struct TreeNode_t *isole_3D = create_user_tree_node("isolated object move 3D"); add_child_node(isole, isole_3D); + struct TreeNode_t *translat_2D = create_user_tree_node("translation"); add_child_node(isole_2D, translat_2D); + struct TreeNode_t *rotat_2D = create_user_tree_node("rotation"); add_child_node(isole_2D, rotat_2D); + struct TreeNode_t *rotat_X_2D = create_user_tree_node("rotation axe X"); add_child_node(rotat_2D, rotat_X_2D); + struct TreeNode_t *rotat_Y_2D = create_user_tree_node("rotation axe Y"); add_child_node(rotat_2D, rotat_Y_2D); + struct TreeNode_t *translat_3D = create_user_tree_node("translation"); add_child_node(isole_3D, translat_3D); + struct TreeNode_t *rotat_3D = create_user_tree_node("rotation"); add_child_node(isole_3D, rotat_3D); + struct TreeNode_t *rotat_X_3D = create_user_tree_node("rotation axe X"); add_child_node(rotat_3D, rotat_X_3D); + struct TreeNode_t *rotat_Y_3D = create_user_tree_node("rotation axe Y"); add_child_node(rotat_3D, rotat_Y_3D); + struct TreeNode_t *rotat_Z_3D = create_user_tree_node("rotation axe Z"); add_child_node(rotat_3D, rotat_Z_3D); + struct TreeNode_t *control = create_user_tree_node("negative feedback (control)"); add_child_node(regulate, control); + struct TreeNode_t *enhance = create_user_tree_node("positive feedback (enhance)"); add_child_node(regulate, enhance);*/ + struct TreeNode_t *n_importe = create_user_tree_node("n'importe"); add_child_node(catalysed, n_importe); + struct TreeNode_t *quoi = create_user_tree_node("quoi"); add_child_node(n_importe, quoi); + struct TreeNode_t *ma_qué = create_user_tree_node("ma_qué"); add_child_node(quoi, ma_qué); +} + +void on_user_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); +} + +static void on_bind_user_tree_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) { + 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_tree_expander_toggled), row); + g_signal_connect(expander, "activate", G_CALLBACK (on_user_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); + if (0) printf("[on_bind_user_tree_factory] row content is [%s] and expander is [%d]\n", text, is_expanded); +// } else if (0) printf("[on_bind_user_tree_factory] row == NULL\n"); +} + +void on_setup_user_tree_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_tree_factory] here is an expander\n"); +} + +static GListModel* get_user_tree_model_child (struct TreeNode_t *parent){ + GtkStringList *list = NULL; + if (parent) { + if (0) printf("[get_user_tree_model_child] here is %s content : ", parent->text); + struct TreeNode_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_tree_model_child (struct TreeNode_t *parent) child = %d \n", parent); + if (0) printf("\n"); + return G_LIST_MODEL(list); +} + +GListModel* get_user_tree_model (GObject *item, gpointer root){ + struct TreeNode_t *cur = (struct TreeNode_t *)root; + struct TreeNode_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_tree_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_tree_model_child (cur); +} + +static void add_child_node (struct TreeNode_t *parent, struct TreeNode_t *child){ + if (parent->child) { + struct TreeNode_t *cur = parent->child; + while (cur && cur->next) {cur = cur->next;} + cur->next = child; + } else parent->child = child; +} + +GtkScrolledWindow *get_user_rules_tree (){ + struct TreeNode_t *tree_root = create_user_tree_node("root"); + create_a_complex_useless_and_expensive_tree (tree_root); + + GtkStringList *model = gtk_string_list_new(NULL); + gtk_string_list_append (model, tree_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_tree_factory), NULL); + g_signal_connect (factory, "bind", G_CALLBACK(on_bind_user_tree_factory), NULL); + + GtkTreeListModel *tree_model = gtk_tree_list_model_new( + G_LIST_MODEL (model), + FALSE, // Passthrough - False in actual usage with dynamic children retrieval + TRUE, // FALSE, // autoexpand + (GtkTreeListModelCreateModelFunc) &get_user_tree_model, + tree_root, + NULL // (GDestroyNotify) free_user_tree_node + ); + + GtkSingleSelection *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); + GtkWidget *list_view = gtk_list_view_new (GTK_SELECTION_MODEL (selection_model), GTK_LIST_ITEM_FACTORY (factory)); + 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; +} + + diff --git a/src/ui/views.c b/src/ui/views.c index ea24ab5..f57e3e0 100644 --- a/src/ui/views.c +++ b/src/ui/views.c @@ -64,7 +64,7 @@ static void add_child_node (struct TreeNode_t *parent, struct TreeNode_t *child) } } -static void create_experimental_tree (struct TreeNode_t *tree_root) // AD HOC XXX & no free() +void create_experimental_tree (struct TreeNode_t *tree_root) // AD HOC XXX & no free() { struct TreeNode_t *a = create_tree_node("We, the people");add_child_node(tree_root, a); struct TreeNode_t *b = create_tree_node("in Order to"); add_child_node(tree_root, b);