// learning how to deal with events /* static void setup_listitem_cb (GtkListItemFactory *factory, GtkListItem *list_item) { GtkWidget *image; image = gtk_image_new (); gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE); gtk_list_item_set_child (list_item, image); } static void bind_listitem_cb (GtkListItemFactory *factory, GtkListItem *list_item) { GtkWidget *image; GAppInfo *app_info; image = gtk_list_item_get_child (list_item); app_info = gtk_list_item_get_item (list_item); gtk_image_set_from_gicon (GTK_IMAGE (image), g_app_info_get_icon (app_info)); } static void activate_cb (GtkListView *list, guint position, gpointer unused) { GAppInfo *app_info; app_info = g_list_model_get_item (G_LIST_MODEL (gtk_list_view_get_model (list)), position); g_app_info_launch (app_info, NULL, NULL, NULL); g_object_unref (app_info); } */ /* static void its_up_to_me_to_invent_now () { GtkStringList *my_model = gtk_string_list_new (NULL); // (const char * const *strings ); my_model = NULL; // create_application_list (); GtkSignalListItemFactory *factory = NULL; // gtk_signal_list_item_factory_new (); g_signal_connect (factory, "setup", G_CALLBACK (setup_listitem_cb), NULL); g_signal_connect (factory, "bind", G_CALLBACK (bind_listitem_cb), NULL); GtkWidget *list = gtk_list_view_new (GTK_SELECTION_MODEL (gtk_single_selection_new (G_LIST_MODEL (my_model))), *factory); g_signal_connect (list, "activate", G_CALLBACK (activate_cb), NULL); gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), list); } */ ----------------------------------------------------------------------- links > GNOME platform https://docs.gtk.org/gio/class.Application.html https://developer.gnome.org/documentation/tutorials/application.html https://docs.gtk.org/gtk3/getting_started.html < WARNING Gtk3 https://developer.gnome.org/documentation/introduction.html https://developer.gnome.org/documentation/index.html ----------------------------------------------------------------------------- https://fr.wikipedia.org/wiki/Disque_de_Poincar%C3%A9 //----------------------------- personal notes --------------------------- // TODO (ranger ça !) /* 2024-08-31 Un point sur l'état d'avancement du client: TODO (bottlenecks) - images (++) - arbres (et listes) (++) - logging (ref : /var/log/messages) - menus (pas indispensables à ce stade) À redéfinir: répartition des tâches (mesures) client/serveur. Comment traiter le cas extrême où *toutes* les règles sont des règles d'intérêt ? (cas d'une erreur rare, non systématique où il faut "remonter le temps", pas à pas, à partir du premier état qui met l'erreur en évidence) Pour effectuer cette "remontée", il faut une liste complète de toutes les règles appliquées. Cette liste doit comporter, pour chaque item (= chaque exécution d'une règle): - identité de la règle - lieu d'exécution (dans l'espace global) - date d'exécution NB Il ne peut y avoir d'ambiguité ou d'erreur due au parallélisme car, si les espaces locaux de deux exécutions de règles se recouvrent, elles ne peuvent avoir été exécutées simultanément. À mon avis, le serveur ne peut effectuer cette tâche car la "remontée dans le temps" nécessite l'inspection 'de visu' de chaque état. Inspection veut dire ici: reconnaissance de formes et ce travail (visuel) ne peut être pré-programmé (bien qu'il doive être systématique), car le concepteur du modèle ne sait pas quelle est l'erreur et ne peut prévoir ce qu'il va découvrir. Ceci n'exclut pas qu'il puisse - qu'il doive - effectuer plusieurs essais (de "remontée dans le temps") en sélectionnant, par exemple, différentes règles d'intérêt à chaque fois ni qu'il puisse se programmer des outils d'aide (mais tout ceci ne semble pas avoir sa place dans le serveur). NB À ce stade de la conception d'un modèle, les erreurs sont encore fréquentes et les 'runs' sont nécessairement de brève durée. Des 'runs' de longue durée n'ont de sens qu'une fois ce débuggage effectué. Il y a donc peu de problèmes à craindre du fait de la limite de la bande passante. */ ------- https://thevaluable.dev/sed-cli-practical-guide-examples/#the-basics-of-sed ******************************************************************************** /** * Comment gerer l'image du curseur ? * https://docs.gtk.org/gdk4/class.Cursor.html TODO */ ******************************************************************************** /* printf("voir à la fin de 'main: étude des limites de la fonction 'snprintf()'\n"); long num = 1234567891234567891; char str[20]; sprintf(str, "%ld", num); // integer to string printf("sprintf %ld > str %s\n", num, str); snprintf(str, sizeof(str), "%ld", num); printf("snprintf %ld > str %s\n", num, str); strtol(str, NULL, 0); // The strtol() function takes a char pointer as its first argument, followed by two ints. // The first int specifies the base of the number, // and the second int specifies the maximum number of characters to be converted. printf("strtol %ld > str %s\n", num, str); */ ******************************************************************************** pour les menus: https://discourse.gnome.org/t/when-do-we-really-have-to-use-gtk-popover-present-to-show-a-popover-at-a-given-widget/17566/5 https://stackoverflow.com/questions/69135934/creating-a-simple-menubar-menu-and-menu-item-in-c-using-gtk4 -------------------------------------------------------------------------------- https://www.man-linux-magique.net/man3/gets.html https://zestedesavoir.com/tutoriels/755/le-langage-c-1/1043_aggregats-memoire-et-fichiers/4911_les-fichiers/ ================================================= ttps://developer.gnome.org/hig/principles.html // https://docs.gtk.org/gio/class.MenuModel.html // https://www.geany.org/manual/gtk/gobject/index.html // https://developer.gnome.org/hig/patterns/controls/menus.html ================================================================================ jean@Project:~/Gem-Graph/gem-graph-client [env] $ nano ~/.gitconfig jean@Project:~/Gem-Graph/gem-graph-client [env] $ git commit -as < pour signer jean@Project:~/Gem-Graph/gem-graph-client [env] $ git config --global alias.commit commit - jean@Project:~/Gem-Graph/gem-graph-client [env] $ git config --global user.signingKey F37FE3F41D1463D56460400CFB3115C340E057E3 jean@Project:~/Gem-Graph/gem-graph-client [env] $ echo "b00fb7ba53841e7ff49a07f3f63fa45b2c5674f2b7b442eeafef1fa5e7b406fc" | gpg -a --default-key FB3115C340E057E3 --detach-sig jean@Project:~/Gem-Graph/gem-graph-client [env] $ gpg --export --armor F37FE3F41D1463D56460400CFB3115C340E057E3 jean@Project:~/Gem-Graph/gem-graph-client [env] $ gpg --edit-key jean@a-lec.org jean@Project:~/Gem-Graph/gem-graph-client [env] $ gpg --list-key jean@a-lec.org jean@Project:~/Gem-Graph/gem-graph-client [env] $ git rebase -i HEAD~6 jean@Project:~/Gem-Graph/gem-graph-client [env] $ git rebase -i a6845e9b2a622b5ec75317de3c3089f6a3fb3ab0 jean@Project:~/Gem-Graph/gem-graph-client [env] $ git commit --amend -S pour chercher : grep pour éditer : sed 2024-06-29 ------------------------------------------------------------------------------- contain.c: (136) gtk_box_append (middle_box, GTK_WIDGET (get_GLArea())); graphics.h: (177) static inline GLuint create_shader(const int stack_id, int type, const char *src) {...} graphics.c: (153) graphics_draw (stack_index[i].stack_id); graphics.c: (233) g_signal_connect (adj, "value-changed", G_CALLBACK(on_axis_value_change), (gpointer) label); graphics.c: (289) g_signal_connect(GTK_GL_AREA(gl_area), "render", G_CALLBACK(on_glarea_render), NULL); graphics.c: g_signal_connect(gl_area, "realize", G_CALLBACK(on_glarea_realize), NULL); graphics.c: g_signal_connect(gl_area, "unrealize", G_CALLBACK(on_glarea_unrealize), NULL); graph_stack.c: (149) if (!graphics_init_shaders(cur_id)) return -1; graph_stack.c: (153) graphics_init_buffers(cur_id); graph_stack.c: (288) draw_space_ridges_vertex (stack_id, stack->buffer_vertex_size, space_X, space_Y, space_Z); graph_stack.c: draw_space_ridges_lines (stack_id); graph_stack.c: draw_grids_on_space_faces_vertex (stack_id, space_X, space_Y, space_Z); graph_stack.c: draw_grids_on_space_faces_lines (stack_id, stack->buffer_lines_size, space_X, space_Y, space_Z); graph_stack.c: (316) stack->arrows_nb = set_arrow (stack_id, stack->arrows_nb, space_X, space_Y, space_Z, arrow.load, arrow.site, arrow.x, arrow.y, arrow.z); -------------------------------------------------------------------------------- contain is called (#included) in : callback, display, tree, graph_stack, graphics, init, -------------------------------------------------------------------------------- // 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 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 https://docs.gtk.org/gtk4/class.ListView.html https://blog.gtk.org/2020/09/08/on-list-models/ < TODO https://docs.gtk.org/gio/method.ActionMap.add_action_entries.html -------------------------------------------------------------------------------- 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); -------------------------------------------------------------------------------- GtkBox GtkGrid GtkRevealer GtkStack GtkOverlay GtkPaned GtkExpander GtkFixed box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_widget_set_halign (box, GTK_ALIGN_FILL); gtk_widget_set_valign (box, GTK_ALIGN_CENTER); // START CENTER END FILL gtk_window_set_child (GTK_WINDOW (window), box); puis, après déclaration du bouton, gtk_box_append (GTK_BOX (box), button); grid = gtk_grid_new (); gtk_window_set_child (GTK_WINDOW (window), grid); button = gtk_button_new_with_label (" I "); n fois gtk_grid_attach (GTK_GRID (grid), button, 0, 0, 1, 1); n fois -------------------------------------------------------------------------------- TODO (or NOT TODO) GtkWidget *get_text_view(){ // WTF ?!& @Grr #~! // https://docs.gtk.org/gtk4/section-text-widget.html GtkWidget *my_view = gtk_text_view_new (); GtkTextTagTable *my_table = gtk_text_tag_table_new (); GtkTextBuffer *my_buffer = gtk_text_buffer_new (my_table); gtk_text_buffer_set_text (my_buffer, "Hello, this is some text", -1); gtk_text_view_set_buffer (GTK_TEXT_VIEW (my_view), my_buffer); /* Now you might put the view in a container and display it on the * screen; when the user edits the text, signals on the buffer * will be emitted, such as "changed", "insert_text", and so on. */ return my_view; } // https://docs.gtk.org/gtk4/getting_started.html (m'aura bien servi, quand même !) //typedef anytype = {(int)(*fnct) {printf("typedef {(int)(*fnct) {printf("");}");} GtkModelFnct; https://blog.gtk.org/2020/06/07/scalable-lists-in-gtk-4/ https://docs.gtk.org/gtk4/section-list-widget.html A GtkListItemFactory creates widgets for the items taken from a GListModel. https://docs.gtk.org/gtk4/class.ListItemFactory.html GtkBuilderListItemFactory is a GtkListItemFactory that creates widgets by instantiating GtkBuilder UI templates. The templates must be extending GtkListItem, and typically use GtkExpressions to obtain data from the items in the model. https://docs.gtk.org/gtk4/class.BuilderListItemFactory.html GListModel is an interface that represents a mutable list of GObjects. Its main intention is as a model for various widgets in user interfaces, such as list views, but it can also be used as a convenient method of returning lists of data, with support for updates. https://docs.gtk.org/gio/iface.ListModel.html ---------------------------------------------------------------------------------------------------------------- https://docs.gtk.org/gtk4/getting_started.html https://docs.gtk.org/gtk4/overview.html https://flathub.org/apps/details/ar.xjuan.Cambalache https://github.com/Taiko2k/GTK4PythonTutorial https://github.com/ToshioCP/Gtk4-tutorial https://developer.gnome.org/documentation/tutorials/beginners/getting_started.html https://github.com/Taiko2k/GTK4PythonTutorial#readme ---------------------------------------------------------------------------------------------------------------- GTK Development Blog /* essai run-stop, speed et step by step dans une seule box controls ----------------------------------------------------------------- #include #include #include "cold.h" void print_text(GtkWidget *widget, gpointer data) {g_print (data);} GtkWidget *get_a_space_test_image(){ GtkWidget *image; image = GTK_WIDGET(get_scrolled_gl_area()); image = gtk_picture_new_for_filename ("/home/jean/01/Gtk4/images/aXoris.png"); image = gtk_picture_new_for_filename ("/home/jean/01/Gtk4/images/gg sketch.png"); image = gtk_picture_new_for_filename ("/home/jean/01/Gtk4/images/E coli.png"); image = gtk_picture_new_for_filename ("/home/jean/01/Gtk4/images/E coli resized.png"); image = gtk_picture_new_for_filename ("/home/jean/01/Gtk4/Getting_Started_with_GTK/E coli by David S. Goodsell (2009).png"); return image; } GtkWidget *get_scroll_speed(){ GtkAdjustment *speed_adjust = gtk_adjustment_new (0, 0, 100, 1, 0, 0); GtkWidget *scroll_speed = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, speed_adjust); return scroll_speed; } // TODO cliquer sur "RUN" --> affiche "STOP" (et inversement) GtkBox *get_RUN_STOP_box(){ GtkBox *RUN_STOP_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2)); // spacing = 2 GtkWidget *RUN_Label = GTK_WIDGET (gtk_label_new (NULL)); // "RUN")); const char *str = " RUN\n STOP"; const char *format = "\%s"; char *markup; markup = g_markup_printf_escaped (format, str); gtk_label_set_markup (GTK_LABEL (RUN_Label), markup); // Sets the labels text and attributes from markup. g_free (markup); gtk_label_set_max_width_chars (GTK_LABEL(RUN_Label), 12); gtk_label_set_wrap (GTK_LABEL(RUN_Label), TRUE); gtk_label_set_xalign (GTK_LABEL(RUN_Label), 0.5); // xalign value, between 0 and 1 gtk_label_set_yalign (GTK_LABEL(RUN_Label), 0.5); gtk_label_set_selectable (GTK_LABEL(RUN_Label), FALSE); // default = FALSE gtk_label_set_single_line_mode (GTK_LABEL(RUN_Label), TRUE); // default = TRUE // gtk_box_append (RUN_STOP_box, RUN_Label); return RUN_STOP_box; } GtkBox *get_STEP_by_STEP_box(){ GtkBox *STEP_by_STEP_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0)); GtkWidget *STEP_by_STEP_Label = GTK_WIDGET (gtk_label_new ("ONE\nSTEP")); gtk_box_append (STEP_by_STEP_box, STEP_by_STEP_Label); return STEP_by_STEP_box; } GtkBox *get_CONTROL_box(){ GtkBox *CONTROL_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_VERTICAL, 0)); gtk_box_append (CONTROL_box, GTK_WIDGET (get_RUN_STOP_box())); gtk_box_append (CONTROL_box, GTK_WIDGET (get_scroll_speed())); gtk_box_append (CONTROL_box, GTK_WIDGET (get_STEP_by_STEP_box())); return CONTROL_box; } */ Legacy, again... ///////////////////////////////////////////////////////////////////////////////////////////////////// void fsm_poetic_engine() // 2024-08-31 { int milliseconds = 100; struct timespec rem; struct timespec req= { (int)(milliseconds / 1000), /* secs (Must be Non-Negative) */ (milliseconds % 1000) * 1000000 /* nano (Must be in range of 0 to 999999999) */ }; while (true) { printf(" | O . |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | O . |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | DO * |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | D=-O * |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | D=-- -O * |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | =- - - O * |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | -- O * |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | - O (*) |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | O (*) |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | O (*) |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | O (*) |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | O*) |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | (*O |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | (*) O |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | (*) O |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | (*) O |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | * O |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | * O |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | * O |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | * O |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | * O |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | O |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | O * |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | O . |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | O . |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | O . .|\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | O . .|\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | D . . |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | D- . . |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | D =- . . |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | D = --- . . |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | D =-- . . |\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | D=- . .|\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); printf(" | D- . .|\n\x1b[1F\x1b[2K"); nanosleep(&req , &rem); } } /////////////////////////////////////////////////////////////////////////////////////////////////////// My old engine in java... /////////////// package engine; import java.lang.System.out; import measures.MeasuresManager; import resources.P; import rule.FormulasManager; import rule.FormulasManagerAccess; import session.ViewControls; import state.StateManager; import state.StateManagerLocal; import views.MODEL; import views.ViewsManagerAccess; /* 2020-11 [prototype 0.0] MonoThread executes a while(true) loop with two instructions: (1) search a place where a transition can be done (2) do the transition while (true) if (session.MainView.isStartStopButtonSelected()) { state.StateManagerLocal.chooseLocalOrigin(false); new SingleTransition(true); } */ public class SingleTransition { protected volatile boolean is_done = false; protected volatile String elapsed; public SingleTransition (boolean mono) {if (mono) perform_a_transition();} private synchronized static final void perform_a_transition() { // if (step_by_step) StateManagerLocal.circlePresentState(); if(ViewControls.isDoSelected()) SingleTransition.execute_do (SingleTransition.prepare_do (false)); else if(ViewControls.isUndoSelected()) SingleTransition.execute_undo(SingleTransition.prepare_undo(false)); else if(ViewControls.isRedoSelected()) SingleTransition.execute_redo(SingleTransition.prepare_redo(false)); // if (ViewControls.undo_buffer < UNDO_STACK_SIZE) ViewControls.setTimeBufferBar(ViewControls.undo_buffer); MainView.addElapsedTime(); } public static final int prepare_do (final boolean step_by_step) { // ThreadsManager.addCycle(); // {nb_cycles ++;} This cycle can be inefficient if no formula can be applied selected_formula = FormulasManager.iterateToFindAFormula(); // if(selected_formula > -1) out.println(" prepare_do "+ state.StateManagerLocal.getInfoDebug()); return selected_formula; } public static final void execute_do (final int formula_key) { // formula.doActions(); out.print(" execute_do: formula key=" + formula_key +" "); if (formula_key < 0) { if(StateManagerLocal.comment_origins) out.println("execute_do failure: formula key=" + formula_key); return;} MeasuresManager.startMeasuringAFormulaEffect(formula_key); // out.println("execute_do formula name = "+ FormulasManager.formula.get(formula_key).name); FormulasManager.getFormula().get (formula_key) .doActions(); // {for (i = 0; i < action.length; i++) action[i].doAction (); StateManagerLocal.endRule(action_swap, action_name);} MeasuresManager.endMeasuringAFormulaEffect(formula_key); writePresentState (formula_key); present ++; if (present == UNDO_STACK_SIZE) present = 0; // MainView.setStartStopButtonSelected(false);// if (present == 1); {MainView.setStartStopButtonSelected(false); } //out.println("MonoThread.execute_do > stop ! (present == 1)"); ViewControls .execDo(); doRepaint(); if (DO_UNDO_REDO_comment) comment_do(formula_key); // if (MonoThreadTest.present == 12) MainView.setStartStopButtonSelected(false); } public static final int prepare_undo (final boolean step_by_step) { // MonoThreadTest.present --; return MonoThreadTest. f [MonoThreadTest.present]; if (ViewControls.isUndoBufferEmpty()) {out.println("prepare_undo stop !");} // undo_buffer is always >= 0 else {present --; if (present == -1) present = UNDO_STACK_SIZE -1; ViewControls.execUndo();} final int formula_key = readPresentState(step_by_step); // if (step_by_step) StateManagerLocal.circlePresentState(); return formula_key; } public static final void execute_undo (final int formula_key) { // formula.unDoActions(); {for (i = 0; i < action.length; i++) ...} FormulasManager.getFormula().get (formula_key) .unDoActions(); // {for (i = 0; i < action.length; i++) action[i].doAction (); StateManagerLocal.endRule(action_swap, action_name);} ViewControls.setRedoSelected(); // StateManagerLocal.circlePresentState(); // ThreadsManager.removeEfficientCycle(); // {nb_effective_cycles --;} doRepaint(); if (DO_UNDO_REDO_comment) comment_undo(); } public static final int prepare_redo (final boolean step_by_step) { // return MonoThreadTest. f [MonoThreadTest.present]; final int formula_key = readPresentState(step_by_step); // ThreadsManager.addEfficientCycle(); // {nb_effective_cycles ++;} // if (step_by_step) StateManagerLocal.circlePresentState(); return formula_key; } public static final void execute_redo (final int formula_key) { // formula.doActions(); {for (i = 0; i < action.length; i++) ...} // the redo_buffer is always >= 0 (if the re_do buffer is empty, the re_do button is deactivated) if (! ViewControls.isRedoBufferEmpty()) { FormulasManager.getFormula().get (formula_key).doActions(); // {for (i = 0; i < action.length; i++) action[i].doAction (); StateManagerLocal.endRule(action_swap, action_name);} present ++; if (present == UNDO_STACK_SIZE) present = 0; ViewControls.execRedo(); } ViewControls.setUndoSelected(); doRepaint(); if (DO_UNDO_REDO_comment) comment_redo(); } public final static void writePresentState (final int formula_key) { // x [present] = StateManagerLocal.local_space_origin_X; ... formula [present] = (short) formula_key; o [present] = (byte) StateManagerLocal.getReferenceOrientation_1(); switch(StateManager.space_dimension) { case THREE: z [present] = (byte) StateManagerLocal.local_space_origin_Z; // no break; case TWO: y [present] = (byte) StateManagerLocal.local_space_origin_Y; // no break; case ONE: x [present] = (byte) StateManagerLocal.local_space_origin_X; // no break; default:;} } private final static int readPresentState (final boolean step_by_step) { // StateManagerLocal.local_space_origin_X = x [present]; ... switch(StateManager.space_dimension) { case THREE : StateManagerLocal.local_space_origin_Z = z [present]; // no break case TWO : StateManagerLocal.local_space_origin_Y = y [present]; // no break case ONE : StateManagerLocal.local_space_origin_X = x [present]; // no break; default:;} StateManagerLocal.setReferenceOrientation_1 (o [present]); return formula[present]; } private final static void doRepaint() {ViewsManagerAccess.getView(MODEL.SPACE, "MonoThread.execute_do_undo_redo()").repaint(); } public static int selected_formula; public static int present = 0; public final static int UNDO_STACK_SIZE = 3000; // resources.Parameters.UNDO_STACK_SIZE; // This parameter is also used by ViewControls to display the BufferProgressBarValue protected final static short[] formula = new short [UNDO_STACK_SIZE]; protected final static byte[] x = new byte [UNDO_STACK_SIZE]; protected final static byte[] y = new byte [UNDO_STACK_SIZE]; protected final static byte[] z = new byte [UNDO_STACK_SIZE]; protected final static byte[] o = new byte [UNDO_STACK_SIZE]; private final static byte s6 = 6, s2 = 2; public final static boolean DO_UNDO_REDO_comment = false; // true false protected final static void comment_do (int rank) { if (present == 0) present = UNDO_STACK_SIZE; out.println(" do -----> "+ P.aa(present,s6) + " ("+ P.aa(ViewControls.undo_buffer - 1,s2) +"+1="+ P.aa(ViewControls.undo_buffer,s2) +" /"+ P.aa(ViewControls.redo_buffer,s2) +" -"+ P.aa(ViewControls.redo_buffer,s2) +") "+ P.aa("xyzo ("+ P.aa(x[present - 1],2) +","+ P.aa(y[present - 1],2) +","+ P.aa(z[present - 1],2) +")",12) +" "+ o[present - 1] +" " + // "from:"+ P.aa(from[present - 1],4) +" to:"+ P.aa(to[present - 1],4) + " f="+ formula[present - 1] + ""); if (present == UNDO_STACK_SIZE) present = 0; } protected final static void comment_undo () { // present ++; if (present == stack_size) present = 0; // This comment is triggered after present was decreased of one unit out.println(" undo <--| "+ P.aa(present,s6) + " ("+ P.aa(ViewControls.undo_buffer + 1,s2) +"-1="+ P.aa(ViewControls.undo_buffer,s2) +" /"+ P.aa(ViewControls.redo_buffer - 1,s2) +"+1="+ P.aa(ViewControls.redo_buffer,s2) +") "+ P.aa("xyzo ("+ P.aa(x[present],2) +","+ P.aa(y[present],2) +","+ P.aa(z[present],2) +")",12) +" "+ o[present] +" " + // "from:"+ P.aa(from[present],4) +" to:"+ P.aa(to[present],4) + " f="+ formula[present] + ""); } protected final static void comment_redo () { if (present == 0) present = UNDO_STACK_SIZE; out.println(" redo |--> "+ P.aa(present,s6) + " ("+P.aa(ViewControls.undo_buffer - 1,s2) +"+1="+ P.aa(ViewControls.undo_buffer,s2) + " /"+ P.aa(ViewControls.redo_buffer + 1,s2) +"-1="+ P.aa(ViewControls.redo_buffer,s2) +") "+ P.aa("xyzo ("+ P.aa(x[present - 1],2) +","+ P.aa(y[present - 1],2) +","+ P.aa(z[present - 1],2) +")",12) +" "+ o[present - 1] +" " + // "from:"+ P.aa(from[present - 1],4) +" to:"+ P.aa(to[present - 1],4) + " f="+ formula[present - 1] + ""); if (present == UNDO_STACK_SIZE) present = 0; } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// contain.c: (136) gtk_box_append (middle_box, GTK_WIDGET (get_GLArea())); graph_area.h: (177) static inline GLuint create_shader(const int stack_id, int type, const char *src) {...} graph_area.c: (153) graphics_draw (stack_index[i].stack_id); graph_area.c: (233) g_signal_connect (adj, "value-changed", G_CALLBACK(on_axis_value_change), (gpointer) label); graph_area.c: (289) g_signal_connect(GTK_GL_AREA(gl_area), "render", G_CALLBACK(on_glarea_render), NULL); graph_area.c: g_signal_connect(gl_area, "realize", G_CALLBACK(on_glarea_realize), NULL); graph_area.c: g_signal_connect(gl_area, "unrealize", G_CALLBACK(on_glarea_unrealize), NULL); graph_stack.c: (149) if (!graphics_init_shaders(cur_id)) return -1; graph_stack.c: (153) graphics_init_buffers(cur_id); graph_stack.c: (288) draw_space_ridges_vertex (stack_id, stack->buffer_vertex_size, space_X, space_Y, space_Z); graph_stack.c: draw_space_ridges_lines (stack_id); graph_stack.c: draw_grids_on_space_faces_vertex (stack_id, space_X, space_Y, space_Z); graph_stack.c: draw_grids_on_space_faces_lines (stack_id, stack->buffer_lines_size, space_X, space_Y, space_Z); graph_stack.c: (316) stack->arrows_nb = set_arrow (stack_id, stack->arrows_nb, space_X, space_Y, space_Z, arrow.load, arrow.site, arrow.x, arrow.y, arrow.z); -------------------------------------------------------------------------------- contain is called (#included) in : callback, display, tree, graph_stack, graph_area, init, -------------------------------------------------------------------------------- // 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 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 https://docs.gtk.org/gtk4/class.ListView.html https://blog.gtk.org/2020/09/08/on-list-models/ < TODO https://docs.gtk.org/gio/method.ActionMap.add_action_entries.html -------------------------------------------------------------------------------- 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); -------------------------------------------------------------------------------- GtkBox GtkGrid GtkRevealer GtkStack GtkOverlay GtkPaned GtkExpander GtkFixed box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_widget_set_halign (box, GTK_ALIGN_FILL); gtk_widget_set_valign (box, GTK_ALIGN_CENTER); // START CENTER END FILL gtk_window_set_child (GTK_WINDOW (window), box); puis, après déclaration du bouton, gtk_box_append (GTK_BOX (box), button); grid = gtk_grid_new (); gtk_window_set_child (GTK_WINDOW (window), grid); button = gtk_button_new_with_label (" I "); n fois gtk_grid_attach (GTK_GRID (grid), button, 0, 0, 1, 1); n fois -------------------------------------------------------------------------------- TODO (or NOT TODO) GtkWidget *get_text_view(){ // WTF ?!& @Grr #~! // https://docs.gtk.org/gtk4/section-text-widget.html GtkWidget *my_view = gtk_text_view_new (); GtkTextTagTable *my_table = gtk_text_tag_table_new (); GtkTextBuffer *my_buffer = gtk_text_buffer_new (my_table); gtk_text_buffer_set_text (my_buffer, "Hello, this is some text", -1); gtk_text_view_set_buffer (GTK_TEXT_VIEW (my_view), my_buffer); /* Now you might put the view in a container and display it on the * screen; when the user edits the text, signals on the buffer * will be emitted, such as "changed", "insert_text", and so on. */ return my_view; } /* https://docs.gtk.org/gtk4/class.ApplicationWindow.html GtkApplication *app = gtk_application_new ("org.gtk.test", 0); GtkBuilder *builder = gtk_builder_new_from_string ( "" " " " " " _Edit" " " " _Copy" " win.copy" " " " " " _Paste" " win.paste" " " " " " " "", -1); GMenuModel *menubar = G_MENU_MODEL (gtk_builder_get_object (builder, "menubar")); gtk_application_set_menubar (GTK_APPLICATION (app), menubar); g_object_unref (builder); // ... GtkWidget *window = gtk_application_window_new (app); */ //------------------------------------------------------------------------------ GtkScrolledWindow *get_scrolled_gl_area(){ GtkScrolledWindow *scrolled = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new()); gtk_scrolled_window_set_min_content_width (scrolled, W_IMAGE); gtk_scrolled_window_set_min_content_height (scrolled, H_IMAGE); // GtkAdjustment *width = gtk_adjustment_new (600, 300, 1000, 1, 1, 1000); // GtkAdjustment *height = gtk_adjustment_new (600, 300, 1000, 1, 1, 1000); // (value, lower, upper, step_increment, page_increment, page_size) // GtkWidget *GLarea = gtk_gl_area_new(); // gtk_scrolled_window_set_child (scrolled, GLarea); // https://docs.gtk.org/gtk4/class.GLArea.html return scrolled; } // https://docs.gtk.org/gtk4/getting_started.html (m'aura bien servi, quand même !) //typedef anytype = {(int)(*fnct) {printf("typedef {(int)(*fnct) {printf("");}");} GtkModelFnct; /* essai run-stop, speed et step by step dans une seule box controls ----------------------------------------------------------------- #include #include #include "cold.h" void print_text(GtkWidget *widget, gpointer data) {g_print (data);} GtkWidget *get_a_space_test_image(){ GtkWidget *image; image = GTK_WIDGET(get_scrolled_gl_area()); image = gtk_picture_new_for_filename ("/home/jean/01/Gtk4/images/aXoris.png"); image = gtk_picture_new_for_filename ("/home/jean/01/Gtk4/images/gg sketch.png"); image = gtk_picture_new_for_filename ("/home/jean/01/Gtk4/images/E coli.png"); image = gtk_picture_new_for_filename ("/home/jean/01/Gtk4/images/E coli resized.png"); image = gtk_picture_new_for_filename ("/home/jean/01/Gtk4/Getting_Started_with_GTK/E coli by David S. Goodsell (2009).png"); return image; } GtkWidget *get_scroll_speed(){ GtkAdjustment *speed_adjust = gtk_adjustment_new (0, 0, 100, 1, 0, 0); GtkWidget *scroll_speed = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, speed_adjust); return scroll_speed; } // TODO cliquer sur "RUN" --> affiche "STOP" (et inversement) GtkBox *get_RUN_STOP_box(){ GtkBox *RUN_STOP_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2)); // spacing = 2 GtkWidget *RUN_Label = GTK_WIDGET (gtk_label_new (NULL)); // "RUN")); const char *str = " RUN\n STOP"; const char *format = "\%s"; char *markup; markup = g_markup_printf_escaped (format, str); gtk_label_set_markup (GTK_LABEL (RUN_Label), markup); // Sets the labels text and attributes from markup. g_free (markup); gtk_label_set_max_width_chars (GTK_LABEL(RUN_Label), 12); gtk_label_set_wrap (GTK_LABEL(RUN_Label), TRUE); gtk_label_set_xalign (GTK_LABEL(RUN_Label), 0.5); // xalign value, between 0 and 1 gtk_label_set_yalign (GTK_LABEL(RUN_Label), 0.5); gtk_label_set_selectable (GTK_LABEL(RUN_Label), FALSE); // default = FALSE gtk_label_set_single_line_mode (GTK_LABEL(RUN_Label), TRUE); // default = TRUE // gtk_box_append (RUN_STOP_box, RUN_Label); return RUN_STOP_box; } GtkBox *get_STEP_by_STEP_box(){ GtkBox *STEP_by_STEP_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0)); GtkWidget *STEP_by_STEP_Label = GTK_WIDGET (gtk_label_new ("ONE\nSTEP")); gtk_box_append (STEP_by_STEP_box, STEP_by_STEP_Label); return STEP_by_STEP_box; } GtkBox *get_CONTROL_box(){ GtkBox *CONTROL_box = GTK_BOX(gtk_box_new (GTK_ORIENTATION_VERTICAL, 0)); gtk_box_append (CONTROL_box, GTK_WIDGET (get_RUN_STOP_box())); gtk_box_append (CONTROL_box, GTK_WIDGET (get_scroll_speed())); gtk_box_append (CONTROL_box, GTK_WIDGET (get_STEP_by_STEP_box())); return CONTROL_box; } */