Initial commit: first state machine and interactive dialog window
This commit implements the first state machine crossing EXEC_EDIT with STATE_RULES_DATA. A dialog window is available to use. TODO: - get OpenGL view - get a GTK4 tree view
|
@ -0,0 +1,239 @@
|
|||
|
||||
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 (
|
||||
"<interface>"
|
||||
" <menu id='menubar'>"
|
||||
" <submenu>"
|
||||
" <attribute name='label' translatable='yes'>_Edit</attribute>"
|
||||
" <item>"
|
||||
" <attribute name='label' translatable='yes'>_Copy</attribute>"
|
||||
" <attribute name='action'>win.copy</attribute>"
|
||||
" </item>"
|
||||
" <item>"
|
||||
" <attribute name='label' translatable='yes'>_Paste</attribute>"
|
||||
" <attribute name='action'>win.paste</attribute>"
|
||||
" </item>"
|
||||
" </submenu>"
|
||||
" </menu>"
|
||||
"</interface>",
|
||||
-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 <stdio.h>
|
||||
#include <gtk-4.0/gtk/gtk.h>
|
||||
#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 = "<span style=\"oblique\">\%s</span>";
|
||||
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;
|
||||
}
|
||||
*/
|
158
Makefile
|
@ -1,24 +1,158 @@
|
|||
all: Getting_Started_with_GTK
|
||||
.PHONY: run clean install all
|
||||
.DELETE_ON_ERROR: $(BINDIR)/Getting_Started_with_GTK
|
||||
.DEFAULT_GOAL: all
|
||||
|
||||
NTHREADS= $(shell nproc)
|
||||
|
||||
CC=gcc
|
||||
CFLAGS=`pkg-config --cflags gtk4 gl glib-2.0 libxml-2.0`
|
||||
LDFLAGS=`pkg-config --libs gtk4 gl glib-2.0 libxml-2.0` -lGL -lGLU -lm -lepoxy -lX11 -lGLEW
|
||||
WARNINGS = -Wall
|
||||
DEBUG = -ggdb -fno-omit-frame-pointer
|
||||
OPTIMIZE = -O2
|
||||
DEBUG = -ggdb -fno-omit-frame-pointer #-fdiagnostics-color=always -fsanitize=bounds -fstack-check
|
||||
OPTIMIZE = -O3
|
||||
|
||||
BINDIR=bin
|
||||
BUILDDIR=build
|
||||
SRCDIR=src
|
||||
|
||||
Getting_Started_with_GTK: Makefile main.c
|
||||
$(CC) -o $@ $(WARNINGS) $(DEBUG) $(OPTIMIZE) main.c
|
||||
sources = $(shell find . -maxdepth 1 -type f -name "*.c")
|
||||
objects = $(patsubst %.c,%.o,$(sources))
|
||||
dependencies = $(patsubst %.c,%.d,$(sources))
|
||||
|
||||
clean:
|
||||
rm -f Getting_Started_with_GTK
|
||||
all: myprogram
|
||||
|
||||
-include $(dependencies)
|
||||
|
||||
myprogram: $(objects)
|
||||
$(CC) $(LDFLAGS) $(WARNINGS) $(DEBUG) $(OPTIMIZE) $^ -o $@
|
||||
|
||||
%.o: %.c Makefile
|
||||
$(CC) $(CFLAGS) $(WARNINGS) $(DEBUG) $(OPTIMIZE) -c $< -o $@
|
||||
|
||||
%.d: %.c Makefile
|
||||
$(CC) $(CFLAGS) -MM -MT $(@:%.d=%.o) -MF $@ $<
|
||||
|
||||
# Builder will call this to install the application before running.
|
||||
install:
|
||||
echo "Installing is not supported"
|
||||
|
||||
# Builder uses this target to run your application.
|
||||
run:
|
||||
./main
|
||||
run: myprogram
|
||||
./myprogram
|
||||
|
||||
# gcc $( pkg-config --cflags gtk4 ) -o main main.c $( pkg-config --libs gtk4 )
|
||||
clean:
|
||||
rm -f myprogram
|
||||
rm -f *.o
|
||||
rm -f *.d
|
||||
|
||||
# /!\ erreur fatale: GL/glu.h <?>
|
||||
# gcc -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -g -Wall -Wextra
|
||||
# -std=c99 -lm *.c -o formattage `pkg-config --cflags --libs glib-2.0`
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# 'make' has an implicit rule for updating a ‘.o’ file #
|
||||
# from a correspondingly named ‘.c’ file #
|
||||
# using a ‘cc -c’ command. #
|
||||
# Implicit rules are listed and applied in a predefined order (C before P...) #
|
||||
# Predefined implicit rules are implemented in make as suffix rules #
|
||||
# The default suffix list is: .out, .a, .ln, .o, .c, .cc, .C, .cpp, .p,... #
|
||||
# Rules whose suffixes fail to be on the list are disabled. #
|
||||
# You can define your own implicit rules by writing pattern rules. #
|
||||
#------------------------------------------------------------------------------#
|
||||
|
||||
# If there are many implicit rules with the same target pattern,
|
||||
# the rule that actually applies is the one whose prerequisites exist or can be made
|
||||
# ex: a .o can be made from a .c (C compiler) or a .p (Pascal compiler)
|
||||
|
||||
# Variables allow a text string to be defined once
|
||||
# and substituted in multiple places later.
|
||||
# (see Chapter 6 [How to Use Variables], page 65)
|
||||
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# To study : how can the following commands be modified ? #
|
||||
#------------------------------------------------------------------------------#
|
||||
|
||||
#SHELL = /bin/sh
|
||||
#.SUFFIXES:
|
||||
#.SUFFIXES: .c .o .h # is .h useful ?
|
||||
#.PHONY = run
|
||||
#.PHONY = clean
|
||||
#.PHONY: Makefile
|
||||
|
||||
#CC=gcc
|
||||
#CFLAGS=`pkg-config --cflags gtk4 --libs gtk4`
|
||||
#WARNINGS = -Wall
|
||||
#DEBUG = -ggdb -fno-omit-frame-pointer
|
||||
#OPTIMIZE = -O2
|
||||
|
||||
# in exec.o:
|
||||
# $(WARNINGS) $(DEBUG) $(OPTIMIZE) < ne sont pas indispensables
|
||||
# si le $@ est supprimé, main.cest modifié
|
||||
#all:
|
||||
# exec
|
||||
|
||||
#install:
|
||||
# echo "Installing is not supported"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# Personnal notes & links #
|
||||
#------------------------------------------------------------------------------#
|
||||
|
||||
|
||||
# gcc $( pkg-config --cflags gtk4 ) -o exec main.c $( pkg-config --libs gtk4 )
|
||||
|
||||
# https://www.gnu.org/software/make/manual/
|
||||
|
||||
# Makefiles contain five kinds of things:
|
||||
# explicit rules, implicit rules, variable definitions, directives and comments.
|
||||
|
||||
|
||||
# Variables automatiques --------------------------------------------------
|
||||
# $@ fait référence à la cible de la règle (au nom de la cible).
|
||||
# $< fait référence à la première dépendance.
|
||||
# $? fait référence aux noms de touess les dépendances plus récentes que la cible.
|
||||
# = les fichiers qui ont été modifiés après la compilation de code la plus récente
|
||||
# $^ fait référence aux noms de touess les dépendances avec des espaces entre eux.
|
||||
|
||||
# Variables implicites -------------------------------------------------
|
||||
# VPATH Équivalent utilitaire de la variable PATH de Bash. Vide par défaut.
|
||||
# Les chemins sont séparés par le signe deux-points (:).
|
||||
# CC Le programme pour compiler des fichiers C.
|
||||
# La valeur par défaut est cc. (Habituellement, cc pointe vers gcc.)
|
||||
# CPP Le programme qui exécute le préprocesseur C.
|
||||
# La valeur par défaut est $ (CC) -E.
|
||||
# LEX Le programme qui transforme les grammaires lexicales en code source.
|
||||
# La valeur par défaut est lex. (Vous devriez remplacer cela par flex.)
|
||||
# LINT Le programme qui lint votre code source. La valeur par défaut est lint.
|
||||
# RM La commande pour supprimer un fichier. La valeur par défaut est rm -f.
|
||||
# CFLAGS Contient tous les indicateurs du compilateur C (cc).
|
||||
# CPPFLAGS tous les indicateurs du préprocesseur C.
|
||||
# .PHONY Spécifie des cibles qui ne ressemblent pas au nom d'un fichier.
|
||||
# Un exemple est la cible "make clean" ; où clean est une valeur de .PHONY
|
||||
|
||||
# Syntaxe de Base
|
||||
# Règles : Une règle se compose d'une cible, des dépendances et des commandes.
|
||||
# Elle est généralement structurée comme suit :
|
||||
# cible: dépendances
|
||||
# commande
|
||||
#
|
||||
# La cible (target) est le fichier à générer,
|
||||
# les dépendances (prerequisites) sont les fichiers requis pour construire la cible
|
||||
# et les commandes (recipe) sont les instructions exécutées pour créer la cible.
|
||||
#
|
||||
# A simple makefile consists of “rules” with the following shape:
|
||||
# target ... : prerequisites ...
|
||||
# recipe
|
||||
# ...
|
||||
# A target is usually the name of a file that is generated by a program;
|
||||
# examples of targets are executable or object files.
|
||||
# A target can also be the name of an action to carry out, such as ‘clean’
|
||||
|
||||
|
||||
# accessoirement : https://blog.stephane-robert.info/docs/makefile/ & /docs/task/
|
||||
|
||||
|
|
|
@ -1,132 +0,0 @@
|
|||
##
|
||||
## Gem-graph OpenGL experiments
|
||||
##
|
||||
## Desc: Makefile
|
||||
##
|
||||
## Copyright (C) 2023 Arthur Menges <arthur.menges@a-lec.org>
|
||||
## Copyright (C) 2023 Adrien Bourmault <neox@a-lec.org>
|
||||
##
|
||||
## This file is part of Gem-graph.
|
||||
##
|
||||
## This program is free software: you can redistribute it and/or modify
|
||||
## it under the terms of the GNU Affero General Public License as published by
|
||||
## the Free Software Foundation, either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU Affero General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU Affero General Public License
|
||||
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
##
|
||||
|
||||
.PHONY: all clean install run build_system
|
||||
.DELETE_ON_ERROR: $(BINDIR)/gem-graph-client
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
#
|
||||
# Color codes
|
||||
#
|
||||
CL='\033[0;32m'
|
||||
CL2='\033[1;36m'
|
||||
CL3='\033[0m'
|
||||
NC='\033[1;37m'
|
||||
|
||||
#
|
||||
# Variables & constants
|
||||
#
|
||||
NTHREADS= $(shell nproc)
|
||||
|
||||
CC=gcc
|
||||
WARNINGS= -Wall
|
||||
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
|
||||
|
||||
BINDIR=bin
|
||||
BUILDDIR=build
|
||||
SRCDIR=src
|
||||
#vpath %.c $(SRCDIR)
|
||||
|
||||
SOURCES= $(shell find $(SRCDIR) -type f -name "*.c")
|
||||
BUILDBINS=$(patsubst %.c,$(BUILDDIR)/%.o,$(SOURCES))
|
||||
BUILDDEPS=$(patsubst %.c,$(BUILDDIR)/%.d,$(SOURCES))
|
||||
|
||||
-include /etc/os-release
|
||||
|
||||
#
|
||||
# Directories
|
||||
#
|
||||
$(BUILDDIR):
|
||||
@mkdir -p $@
|
||||
@echo -e ${CL2}[$@] ${CL}folder generated.${CL3}
|
||||
|
||||
$(BINDIR):
|
||||
@mkdir -p $@
|
||||
@echo -e ${CL2}[$@] ${CL}folder generated.${CL3}
|
||||
|
||||
#
|
||||
# Dependencies
|
||||
#
|
||||
-include $(BUILDDEPS)
|
||||
|
||||
$(BUILDDIR)/%.d: %.c | $(BUILDDIR)
|
||||
@mkdir -p $(shell dirname $@)
|
||||
@$(CC) -MM -MT $(@:%.d=%.o) -MF $@ $<
|
||||
@echo -e ${CL2}[$@] ${CL}dependencies generated.${CL3}
|
||||
|
||||
#
|
||||
# Compilation
|
||||
#
|
||||
$(BINDIR)/gem-graph-client: $(BUILDBINS) | $(BINDIR)
|
||||
@$(CC) -o $@ $(WARNINGS) $(DEBUG) $(OPTIMIZE) $^ $(INCLUDE) $(LIBS)
|
||||
@echo -e ${CL2}[$@] ${CL}built.${CL3}
|
||||
|
||||
|
||||
$(BUILDDIR)/%.o: %.c | $(BUILDDIR)
|
||||
@mkdir -p $(shell dirname $@)
|
||||
@$(CC) $(WARNINGS) $(DEBUG) $(OPTIMIZE) $(INCLUDE) -c $< -o $@
|
||||
@echo -e ${CL2}[$@] ${CL}compiled.${CL3}
|
||||
|
||||
|
||||
#
|
||||
# Virtual recipes
|
||||
#
|
||||
clean:
|
||||
@rm -rf $(BINDIR)
|
||||
@rm -rf $(BUILDDIR)
|
||||
@echo -e ${CL2}[$@] ${CL}done.${CL3}
|
||||
|
||||
install:
|
||||
echo "Installing is not supported"
|
||||
|
||||
build_system:
|
||||
@echo -e ${CL2}[$@] ${CL}building...${CL3}
|
||||
@make $(BINDIR)/gem-graph-client -j $(NTHREADS)
|
||||
@echo -e ${CL2}[$@] ${CL}done.${CL3}
|
||||
|
||||
run: build_system
|
||||
@echo -e ${CL2}[$@] ${CL}executing...${CL3}
|
||||
@$(BINDIR)/gem-graph-client
|
||||
@echo -e ${CL2}[$@] ${CL}done.${CL3}
|
||||
|
||||
debug: build_system
|
||||
@echo -e ${CL2}[$@] ${CL}executing...${CL3}
|
||||
@gdb $(BINDIR)/gem-graph-client
|
||||
@echo -e ${CL2}[$@] ${CL}done.${CL3}
|
||||
|
||||
valgrind: build_system
|
||||
@echo -e ${CL2}[$@] ${CL}executing...${CL3}
|
||||
@valgrind $(BINDIR)/gem-graph-client
|
||||
@echo -e ${CL2}[$@] ${CL}done.${CL3}
|
||||
|
||||
all: build_system
|
||||
@echo -e ${CL2}[$@] ${CL}done.${CL3}
|
||||
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
#include <gtk-4.0/gtk/gtk.h>
|
||||
#include <assert.h>
|
||||
#include "callback.h"
|
||||
#include "automaton.h"
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* S T A T E S */
|
||||
/******************************************************************************/
|
||||
|
||||
static int choice_EXEC_EDIT = EXEC;
|
||||
static int choice_STATE_RULES_DATA = STATE;
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* T R A N S I T I O N S */
|
||||
/******************************************************************************/
|
||||
|
||||
static void debug_printing (int prescribed, int sub_automaton);
|
||||
|
||||
void set_EXEC_EDIT (int prescribed) {
|
||||
if (choice_EXEC_EDIT != prescribed) {
|
||||
debug_printing (prescribed, 0); // EXEC_EDIT is sub_automaton 0
|
||||
choice_EXEC_EDIT = prescribed;
|
||||
}
|
||||
}
|
||||
|
||||
void set_STATE_RULES_DATA (int prescribed) {
|
||||
if (choice_STATE_RULES_DATA != prescribed) {
|
||||
debug_printing (prescribed, 1); // STATE_RULES_DATA is sub_automaton 1
|
||||
choice_STATE_RULES_DATA = prescribed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* G E T T E R S & D E B U G G E R S */
|
||||
/******************************************************************************/
|
||||
|
||||
int get_EXEC_EDIT () {return choice_EXEC_EDIT;}
|
||||
int get_STATE_RULES_DATA () {return choice_STATE_RULES_DATA;}
|
||||
|
||||
static char *get_str_EXEC_EDIT (int value) {
|
||||
switch (value) {
|
||||
case (EXEC) : return "EXEC";
|
||||
case (EDIT) : return "EDIT";
|
||||
default : printf("default in automaton.get_EXEC_EDIT ()\n"); return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static char *get_str_STATE_RULES_DATA (int value) {
|
||||
switch (value) {
|
||||
case (STATE) : return "STATE";
|
||||
case (RULES) : return "RULES";
|
||||
case (DATA) : return "DATA";
|
||||
default : printf("default in automaton.get_STATE_RULES_DATA ()\n"); return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void debug_printing (int prescribed, int sub_automaton) {
|
||||
switch (sub_automaton) { // sub_automaton 0 is EXEC_EDIT and
|
||||
// sub_automaton 1 is STATE_RULES_DATA
|
||||
case (0) : printf("switch > %5s X %5s <> %5s X %5s\n",
|
||||
get_str_EXEC_EDIT (choice_EXEC_EDIT),
|
||||
get_str_STATE_RULES_DATA (choice_STATE_RULES_DATA),
|
||||
get_str_EXEC_EDIT (prescribed),
|
||||
get_str_STATE_RULES_DATA (choice_STATE_RULES_DATA));
|
||||
break;
|
||||
case (1) : printf("switch > %5s X %5s <> %5s X %5s\n",
|
||||
get_str_EXEC_EDIT (choice_EXEC_EDIT),
|
||||
get_str_STATE_RULES_DATA (choice_STATE_RULES_DATA),
|
||||
get_str_EXEC_EDIT (choice_EXEC_EDIT),
|
||||
get_str_STATE_RULES_DATA (prescribed));
|
||||
break;
|
||||
default : printf("default in automaton.debug_printing()\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#include <gtk-4.0/gtk/gtk.h>
|
||||
#include <assert.h>
|
||||
|
||||
enum choice_EXEC_EDIT { EXEC, EDIT };
|
||||
enum choice_STATE_RULES_DATA { STATE, RULES, DATA };
|
||||
// MEASURE, OBSERVE, INTERPRET, HELP, CONFIGURE }; ?
|
||||
|
||||
void set_EXEC_EDIT (int prescribed);
|
||||
void set_STATE_RULES_DATA (int prescribed);
|
||||
|
||||
int get_EXEC_EDIT ();
|
||||
int get_STATE_RULES_DATA ();
|
||||
|
||||
// char *get_str_EXEC_EDIT (int value);
|
||||
// char *get_str_STATE_RULES_DATA (int value);
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Gem-graph OpenGL experiments
|
||||
*
|
||||
* Desc: Base header
|
||||
*
|
||||
* Copyright (C) 2023 Arthur Menges <arthur.menges@a-lec.org>
|
||||
* Copyright (C) 2023 Adrien Bourmault <neox@a-lec.org>
|
||||
*
|
||||
* This file is part of Gem-graph.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <glib-2.0/glib.h>
|
||||
//#define G_APPLICATION_DEFAULT_FLAGS 0
|
||||
|
||||
enum { X_AXIS, Y_AXIS, Z_AXIS, N_AXIS }; // < used by : graph_area.h
|
||||
enum { HOME_MODE, RUN_MODE, EDIT_MODE, PRESENTATION_MODE, N_MODE }; // Gem-graph modes
|
||||
struct arrow_t { uint load; uint site; uint x; uint y; uint z; }; // describes an arrow
|
||||
static inline char *read_file(char *filename); // < used by : init.c
|
||||
|
||||
/* I'm standing on Earth (or any spinning spheroid) and looking towards its North pole, then :
|
||||
X - X = EAST - WEST = rouge - cyan
|
||||
Y - Y = ZENITH - NADIR = vert - magenta (fuschia)
|
||||
Z - Z = NORTH - SOUTH = bleu - jaune */
|
||||
|
||||
#define EAST 0 // + x rouge
|
||||
#define WEST 1 // - x cyan
|
||||
#define ZENITH 2 // + y vert
|
||||
#define NADIR 3 // - y magenta
|
||||
#define SOUTH 4 // + z bleu
|
||||
#define NORTH 5 // - z jaune
|
||||
|
||||
|
||||
/*
|
||||
* char *read_file(char *filename) reads a file from filename into a provided buffer
|
||||
*
|
||||
* @param filename, file name
|
||||
* contents, target ptr
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
static inline char *read_file(char *filename)
|
||||
{
|
||||
int fd;
|
||||
int filesize;
|
||||
char *contents;
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if(fd < 0) {
|
||||
printf("Couldn't read file: %s\n",filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
filesize = lseek(fd, 0, SEEK_END) + 1 ;
|
||||
contents = g_malloc(filesize * sizeof(char));
|
||||
assert (contents);
|
||||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
read(fd,contents,filesize);
|
||||
|
||||
contents[filesize-1] = '\0';
|
||||
|
||||
close(fd);
|
||||
|
||||
return contents;
|
||||
}
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
#include <stdio.h>
|
||||
#include <gtk-4.0/gtk/gtk.h>
|
||||
|
||||
#include "callback.h"
|
||||
#include "contain.h"
|
||||
#include "tree.h"
|
||||
#include "contain.h"
|
||||
#include "dialog.h"
|
||||
#include "texts.h"
|
||||
#include "automaton.h"
|
||||
#include "parsing.h"
|
||||
#include "graph_area.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* W I N D O W S A C T I V A T I O N */
|
||||
/******************************************************************************/
|
||||
|
||||
static GtkWindow *main_window, *dialog_window;
|
||||
|
||||
void on_main_window_activation (GtkApplication *app, gpointer no_user_data)
|
||||
{
|
||||
main_window = GTK_WINDOW (gtk_application_window_new (app));
|
||||
main_window_design (main_window);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (on_dialog_window_activation), main_window);
|
||||
}
|
||||
|
||||
void on_dialog_window_activation (GtkApplication *app, gpointer no_user_data)
|
||||
{
|
||||
dialog_window = GTK_WINDOW (gtk_application_window_new (app));
|
||||
dialog_window_design (main_window, dialog_window);
|
||||
}
|
||||
|
||||
|
||||
void on_auto_notification (const char *message)
|
||||
{
|
||||
/* Ignored (2024-06-06) because I don't know how to get "main_window" easily
|
||||
|
||||
if (window->toast_revealer == NULL) {
|
||||
g_printerr("Can't find app->toast_overlay !\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (window->toast_text == NULL) {
|
||||
g_printerr("Can't find app->toast_overlay !\n");
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_label_set_label(window->toast_text, message);
|
||||
gtk_revealer_set_reveal_child(window->toast_revealer, true);
|
||||
*/
|
||||
g_printerr("%s\n", message);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* T R E E */
|
||||
/******************************************************************************/
|
||||
void on_user_tree_expander_toggled (GtkExpander *expander, gpointer user_data)
|
||||
{
|
||||
GtkTreeListRow *row = GTK_TREE_LIST_ROW (user_data);
|
||||
gboolean is_expanded = gtk_tree_list_row_get_expanded(row);
|
||||
gtk_tree_list_row_set_expanded (row, !is_expanded);
|
||||
}
|
||||
|
||||
void on_bind_user_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);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* G L A R E A */
|
||||
/******************************************************************************/
|
||||
gboolean on_glarea_render(GtkGLArea *area, GdkGLContext *context)
|
||||
{
|
||||
// Check if the widget is a glarea
|
||||
if(gtk_gl_area_get_error(area) != NULL) {
|
||||
on_auto_notification("An OpenGL error occured !");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ui_render_stack(gtk_widget_get_parent(GTK_WIDGET(area))) == false) {
|
||||
on_auto_notification("Failed to render corresponding graphic stack !");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* We need to set up our state when we realize the GtkGLArea widget */
|
||||
void on_glarea_realize(GtkWidget *widget)
|
||||
{
|
||||
GError *internal_error = NULL;
|
||||
|
||||
// Make the GL context current to be able to call the GL API
|
||||
gtk_gl_area_make_current(GTK_GL_AREA(widget));
|
||||
|
||||
// Check if the widget is a glarea
|
||||
if(gtk_gl_area_get_error(GTK_GL_AREA(widget)) != NULL) {
|
||||
on_auto_notification("An OpenGL error occured !");
|
||||
return;
|
||||
}
|
||||
|
||||
// Link graphical stack to widget
|
||||
if (ui_init_graphic_stack(gtk_widget_get_parent(widget),
|
||||
internal_error) == false) {
|
||||
on_auto_notification(
|
||||
"Failed to link the graphic stack to widgets !");
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_gl_area_set_auto_render(GTK_GL_AREA(widget), true);
|
||||
}
|
||||
|
||||
/* We should tear down the state when unrealizing */
|
||||
void on_glarea_unrealize(GtkWidget *widget)
|
||||
{
|
||||
GError *internal_error = NULL;
|
||||
|
||||
// Make the GL context current to be able to call the GL API
|
||||
gtk_gl_area_make_current(GTK_GL_AREA(widget));
|
||||
|
||||
// Check if the widget is a glarea
|
||||
if(gtk_gl_area_get_error(GTK_GL_AREA(widget)) != NULL) {
|
||||
on_auto_notification("An OpenGL error occured !");
|
||||
return;
|
||||
}
|
||||
|
||||
// Destroy graphic stack
|
||||
if (ui_shutdown_graphic_stack(gtk_widget_get_parent(widget),
|
||||
internal_error) == false) {
|
||||
on_auto_notification(
|
||||
"Failed to shutdown the graphic stack !");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void on_axis_value_change(GtkAdjustment *adjustment, gpointer data)
|
||||
{
|
||||
|
||||
GtkWidget *slider = gtk_widget_get_parent(GTK_WIDGET(data));
|
||||
GtkWidget *container_widget = gtk_widget_get_parent(GTK_WIDGET(slider));
|
||||
|
||||
const gchar *label_text = gtk_label_get_label(GTK_LABEL(data));
|
||||
|
||||
// THANKS ASCIIIII/Unicode/Whateverrr !
|
||||
int axis = label_text[0] - 'X';
|
||||
|
||||
g_assert(axis >= 0 && axis < N_AXIS);
|
||||
|
||||
/* Update the rotation angle */
|
||||
ui_update_axis_stack(container_widget,
|
||||
axis,
|
||||
gtk_adjustment_get_value(adjustment));
|
||||
|
||||
/* Update the contents of the GL drawing area */
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* B U T T O N S */
|
||||
/******************************************************************************/
|
||||
|
||||
void on_toggle_EXEC_EDIT (GtkWidget *toggled_button, gpointer user_data) {
|
||||
|
||||
if (get_EXEC_EDIT ()) {
|
||||
gtk_button_set_icon_name (GTK_BUTTON (toggled_button), "power-profile-balanced-rtl-symbolic");
|
||||
set_EXEC_EDIT (EXEC);
|
||||
} else {
|
||||
gtk_button_set_icon_name (GTK_BUTTON (toggled_button), "text-editor-symbolic");
|
||||
set_EXEC_EDIT (EDIT);
|
||||
}
|
||||
switch (get_STATE_RULES_DATA()) {
|
||||
case (STATE) : gtk_window_set_child (main_window, GTK_WIDGET (get_window_child_STATE())); break;
|
||||
case (RULES) : gtk_window_set_child (main_window, GTK_WIDGET (get_window_child_RULES())); break;
|
||||
case (DATA) : gtk_window_set_child (main_window, GTK_WIDGET (get_window_child_DATA())); break;
|
||||
default : printf("default in callback.on_toggle_STATE_RULES_DATA()\n");
|
||||
}
|
||||
}
|
||||
|
||||
void on_toggle_STATE_RULES_DATA (GtkWidget *toggled_button, gpointer user_data) {
|
||||
|
||||
const char *toggled_button_name = gtk_check_button_get_label (GTK_CHECK_BUTTON (toggled_button));
|
||||
int is_active = gtk_check_button_get_active (GTK_CHECK_BUTTON (toggled_button));
|
||||
|
||||
if (! strcmp (toggled_button_name, "state")) set_STATE_RULES_DATA (STATE);
|
||||
if (! strcmp (toggled_button_name, "rules")) set_STATE_RULES_DATA (RULES);
|
||||
if (! strcmp (toggled_button_name, "data analysis")) set_STATE_RULES_DATA (DATA);
|
||||
|
||||
if (is_active)
|
||||
switch (get_STATE_RULES_DATA()) {
|
||||
case (STATE) : gtk_window_set_child (main_window, GTK_WIDGET (get_window_child_STATE())); break;
|
||||
case (RULES) : gtk_window_set_child (main_window, GTK_WIDGET (get_window_child_RULES())); break;
|
||||
case (DATA) : gtk_window_set_child (main_window, GTK_WIDGET (get_window_child_DATA())); break;
|
||||
default : printf("default in callback.on_toggle_STATE_RULES_DATA()\n");
|
||||
}
|
||||
}
|
||||
|
||||
void on_SAVE_CURRENT_MODEL_BEFORE_EDITING (GtkWidget *btt_SAVE_CURRENT_MODEL, gpointer data) {
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (data), TRUE);
|
||||
printf ("callback.c (line 201) - SAVE_CURRENT_MODEL_BEFORE_EDITING\n");
|
||||
}
|
||||
|
||||
void on_DISCARD_CURRENT_MODEL_AND_START_EDITING (GtkWidget *btt_SAVE_CURRENT_MODEL, gpointer data) {
|
||||
gtk_window_close (GTK_WINDOW (data));
|
||||
printf ("callback.c (line 206) - DISCARD_CURRENT_MODEL_AND_START_EDITING\n");
|
||||
}
|
||||
|
||||
void on_WRITE_CURRENT_MODEL (GtkWidget *btt_WRITE_CURRENT_MODEL, gpointer data) {
|
||||
gtk_window_close (GTK_WINDOW (data));
|
||||
printf ("callback.c (line 211) - WRITE_CURRENT_MODEL\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#include <gtk-4.0/gtk/gtk.h>
|
||||
|
||||
|
||||
void on_main_window_activation (GtkApplication *app, gpointer user_data);
|
||||
void on_dialog_window_activation (GtkApplication *app, gpointer user_data);
|
||||
void on_auto_notification (const char *message);
|
||||
|
||||
void on_user_tree_expander_toggled (GtkExpander *expander, gpointer user_data);
|
||||
void on_bind_user_tree_factory (GtkSignalListItemFactory *factory, GObject* object, gpointer user_data);
|
||||
|
||||
gboolean on_glarea_render (GtkGLArea *area, GdkGLContext *context);
|
||||
void on_glarea_realize (GtkWidget *widget);
|
||||
void on_glarea_unrealize (GtkWidget *widget);
|
||||
|
||||
void on_axis_value_change (GtkAdjustment *adjustment, gpointer data);
|
||||
|
||||
void on_toggle_EXEC_EDIT (GtkWidget *btt_XOR_EXEC_EDIT, gpointer user_data);
|
||||
void on_toggle_MODEL_RUN_STOP (GtkWidget *btt_MODEL_RUN_STOP, gpointer data);
|
||||
|
||||
void on_open_STATE (GtkWidget *btt_open_STATE, gpointer data);
|
||||
void on_open_RULES (GtkWidget *btt_open_RULES, gpointer data);
|
||||
void on_open_DATA (GtkWidget *btt_open_DATA, gpointer data);
|
||||
|
||||
void on_SAVE_CURRENT_MODEL_BEFORE_EDITING (GtkWidget *btt_SAVE_CURRENT_MODEL, gpointer data);
|
||||
void on_DISCARD_CURRENT_MODEL_AND_START_EDITING (GtkWidget *btt_SAVE_CURRENT_MODEL, gpointer data);
|
||||
void on_WRITE_CURRENT_MODEL (GtkWidget *btt_WRITE_CURRENT_MODEL, gpointer data);
|
||||
void on_toggle_STATE_RULES_DATA (GtkWidget *btt, gpointer user_data);
|
|
@ -0,0 +1,426 @@
|
|||
#include <stdio.h>
|
||||
#include <gtk-4.0/gtk/gtk.h>
|
||||
|
||||
#include "graph_area.h"
|
||||
#include "callback.h"
|
||||
#include "automaton.h"
|
||||
#include "display.h"
|
||||
#include "tree.h"
|
||||
#include "texts.h"
|
||||
|
||||
// https://blog.gtk.org/2020/09/08/on-list-models/ < TODO
|
||||
// https://docs.gtk.org/gtk4/visual_index.html < widgets gallery
|
||||
|
||||
|
||||
GtkFrame *get_frame_with_label(){ // EN ATTENDANT DE SAVOIR UTILISER : GtkTextTagTable , GtkTextBuffer
|
||||
GtkFrame *space_specif = GTK_FRAME(gtk_frame_new ("Space (run / edit) specifications"));
|
||||
GtkWidget *any_Label = GTK_WIDGET (gtk_label_new (get_space_run_edit_specif()));
|
||||
gtk_frame_set_child (GTK_FRAME (space_specif), GTK_WIDGET (any_Label));
|
||||
return space_specif;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
GtkWidget *get_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_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_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_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;
|
||||
}
|
||||
|
||||
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);
|
||||
return space_grid;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
GtkWidget *get_selected_rules_vpaned_new(){
|
||||
GtkPaned *V_selected_1_vs_2 = GTK_PANED (gtk_paned_new (GTK_ORIENTATION_VERTICAL));
|
||||
|
||||
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_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));
|
||||
|
||||
return GTK_WIDGET (V_selected_1_vs_2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
GtkWidget *get_TIME_EXEC_controls_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_SPACE_VIEW_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()));
|
||||
|
||||
GtkBox *middle_box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2));
|
||||
gtk_box_append (middle_box, GTK_WIDGET (get_image_ALL_SPACE()));
|
||||
// ui_setup_glarea (0, GTK_WIDGET (middle_box));
|
||||
|
||||
gtk_box_append (middle_box, GTK_WIDGET (gtk_separator_new (GTK_ORIENTATION_VERTICAL)));
|
||||
gtk_box_append (middle_box, GTK_WIDGET (right_box));
|
||||
return GTK_WIDGET (middle_box);
|
||||
}
|
||||
|
||||
GtkWidget *get_SPACE_EDIT_controls_box() {
|
||||
GtkWidget *label_ad_hoc = gtk_label_new ("_____________\n\
|
||||
SPACE EDIT\n controls\n_____________");
|
||||
return GTK_WIDGET (label_ad_hoc);
|
||||
}
|
||||
|
||||
|
||||
static void icons_for_fun (GtkHeaderBar *header_bar);
|
||||
|
||||
static GtkButton *btt_open_STATE;
|
||||
static GtkButton *btt_open_RULES;
|
||||
static GtkButton *btt_open_DATA;
|
||||
|
||||
GtkButton *get_GtkButton (char *btt_name) {
|
||||
if (strcmp (btt_name, "state")) return btt_open_STATE;
|
||||
if (strcmp (btt_name, "rules")) return btt_open_RULES;
|
||||
if (strcmp (btt_name, "data analysis")) return btt_open_DATA;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void set_check_button_active (GtkButton *button, int active){
|
||||
const char *lab = gtk_button_get_label (button);
|
||||
if (strcmp (lab, "state")) printf("set_check_button_active > %s\n", lab);
|
||||
}
|
||||
|
||||
|
||||
void window_header_bar (GtkWindow *window, char *title){
|
||||
GtkWidget *header_bar = GTK_WIDGET (gtk_header_bar_new ());
|
||||
gtk_header_bar_set_title_widget (GTK_HEADER_BAR (header_bar), gtk_label_new (title));
|
||||
gtk_window_set_titlebar (window, header_bar);
|
||||
|
||||
gpointer no_local_data = NULL;
|
||||
|
||||
GtkButton *btt_XOR_EXEC_EDIT = GTK_BUTTON (gtk_toggle_button_new ());
|
||||
gtk_button_set_icon_name (btt_XOR_EXEC_EDIT, "system-run-symbolic");
|
||||
gtk_button_set_icon_name (btt_XOR_EXEC_EDIT, "process-stop-symbolic");
|
||||
gtk_button_set_icon_name (btt_XOR_EXEC_EDIT, "power-profile-balanced-rtl-symbolic");
|
||||
g_signal_connect (btt_XOR_EXEC_EDIT, "clicked", G_CALLBACK (on_toggle_EXEC_EDIT), no_local_data);
|
||||
|
||||
GtkWidget *any_Label = GTK_WIDGET (gtk_label_new (" | "));
|
||||
|
||||
GtkCheckButton *group_STATE_RULES_DATA = GTK_CHECK_BUTTON (gtk_check_button_new ());
|
||||
|
||||
btt_open_STATE = GTK_BUTTON (gtk_check_button_new_with_label ("state"));
|
||||
g_signal_connect (btt_open_STATE, "toggled", G_CALLBACK (on_toggle_STATE_RULES_DATA), no_local_data);
|
||||
gtk_check_button_set_group (GTK_CHECK_BUTTON (btt_open_STATE), group_STATE_RULES_DATA);
|
||||
|
||||
btt_open_RULES = GTK_BUTTON (gtk_check_button_new_with_label ("rules"));
|
||||
g_signal_connect (btt_open_RULES, "toggled", G_CALLBACK (on_toggle_STATE_RULES_DATA), no_local_data);
|
||||
gtk_check_button_set_group (GTK_CHECK_BUTTON (btt_open_RULES), group_STATE_RULES_DATA);
|
||||
|
||||
btt_open_DATA = GTK_BUTTON (gtk_check_button_new_with_label ("data analysis"));
|
||||
g_signal_connect (btt_open_DATA, "toggled", G_CALLBACK (on_toggle_STATE_RULES_DATA), no_local_data);
|
||||
gtk_check_button_set_group (GTK_CHECK_BUTTON (btt_open_DATA), group_STATE_RULES_DATA);
|
||||
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header_bar), GTK_WIDGET (btt_XOR_EXEC_EDIT));
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header_bar), GTK_WIDGET (any_Label));
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header_bar), GTK_WIDGET (btt_open_STATE));
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header_bar), GTK_WIDGET (btt_open_RULES));
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header_bar), GTK_WIDGET (btt_open_DATA));
|
||||
|
||||
|
||||
icons_for_fun (GTK_HEADER_BAR (header_bar)); // https://iconduck.com/sets/adwaita-icon-theme
|
||||
// https://iconduck.com/sets/carbon-icons < pas mal ...
|
||||
// https://thenounproject.com/icon/train-134324/
|
||||
// ma préférée : Transport Steam Engine Icon mais : [ process icon ] semble un bon choix...
|
||||
}
|
||||
|
||||
void main_window_design (GtkWindow *main_window){
|
||||
window_header_bar (main_window,
|
||||
"E coli (with permission from David S. Goodsell, 2009)");
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (btt_open_STATE), TRUE);
|
||||
gtk_window_present (GTK_WINDOW (main_window));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
GtkWidget *get_window_child_STATE() {
|
||||
if (0) printf("contain.get_window_child_STATE (line 235)\n");
|
||||
GtkBox *page_box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 2));
|
||||
gtk_box_append (page_box, GTK_WIDGET (get_OBJECTS_and_SITUATIONS()));
|
||||
gtk_box_append (page_box, GTK_WIDGET (gtk_separator_new (GTK_ORIENTATION_HORIZONTAL)));
|
||||
gtk_box_append (page_box, GTK_WIDGET (get_SPACE_VIEW_box()));
|
||||
gtk_box_append (page_box, GTK_WIDGET (gtk_separator_new (GTK_ORIENTATION_HORIZONTAL)));
|
||||
if (get_EXEC_EDIT ()) gtk_box_append (page_box, GTK_WIDGET (get_SPACE_EDIT_controls_box()));
|
||||
else gtk_box_append (page_box, GTK_WIDGET (get_TIME_EXEC_controls_box()));
|
||||
return GTK_WIDGET (page_box);
|
||||
}
|
||||
|
||||
GtkWidget *get_window_child_RULES(){
|
||||
if (0) printf("contain.get_window_child_RULES (line 246)\n");
|
||||
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, 400); // WARNING : c'est une position "absolue"
|
||||
gtk_paned_set_wide_handle (H_tree_vs_selected, TRUE);
|
||||
return GTK_WIDGET (H_tree_vs_selected);
|
||||
}
|
||||
|
||||
GtkWidget *get_window_child_DATA (){
|
||||
if (0) printf("contain.get_window_child_DATA (line 259)\n");
|
||||
GtkBox *data_box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 32));
|
||||
|
||||
GtkWidget* frame_rule_effect = gtk_frame_new ("rule effect\n-----------");
|
||||
gtk_frame_set_label_align (GTK_FRAME (frame_rule_effect), 0.5);
|
||||
GtkBox *rule_effect_box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 8));
|
||||
gtk_frame_set_child (GTK_FRAME (frame_rule_effect), GTK_WIDGET (rule_effect_box));
|
||||
|
||||
GtkWidget* frame_rule_topic = gtk_frame_new ("rule topic\n----------");
|
||||
gtk_frame_set_label_align (GTK_FRAME (frame_rule_topic), 0.5);
|
||||
GtkBox *rule_topic_box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 8));
|
||||
gtk_frame_set_child (GTK_FRAME (frame_rule_topic), GTK_WIDGET (rule_topic_box));
|
||||
|
||||
GtkWidget* frame_data_type = gtk_frame_new ("data type\n----------");
|
||||
gtk_frame_set_label_align (GTK_FRAME (frame_data_type), 0.5);
|
||||
GtkBox *data_type_box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 8));
|
||||
gtk_frame_set_child (GTK_FRAME (frame_data_type), GTK_WIDGET (data_type_box));
|
||||
|
||||
GtkWidget* frame_interpretations = gtk_frame_new ("interpretation\n---------------");
|
||||
gtk_frame_set_label_align (GTK_FRAME (frame_interpretations), 0.5);
|
||||
GtkBox *interpretations_box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 8));
|
||||
gtk_frame_set_child (GTK_FRAME (frame_interpretations), GTK_WIDGET (interpretations_box));
|
||||
|
||||
GtkWidget* frame_discussions = gtk_frame_new ("discussion\n------------");
|
||||
gtk_frame_set_label_align (GTK_FRAME (frame_discussions), 0.5);
|
||||
GtkBox *discussions_box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 8));
|
||||
gtk_frame_set_child (GTK_FRAME (frame_discussions), GTK_WIDGET (discussions_box));
|
||||
|
||||
GtkWidget* frame_separator = gtk_frame_new ("\n");
|
||||
|
||||
GtkWidget* frame_game = gtk_frame_new ("game\n------");
|
||||
gtk_frame_set_label_align (GTK_FRAME (frame_game), 0.5);
|
||||
GtkBox *game_box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 8));
|
||||
gtk_frame_set_child (GTK_FRAME (frame_game), GTK_WIDGET (game_box));
|
||||
|
||||
GtkWidget* frame_help = gtk_frame_new ("help\n-----");
|
||||
gtk_frame_set_label_align (GTK_FRAME (frame_help), 0.5);
|
||||
GtkBox *help_box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 8));
|
||||
gtk_frame_set_child (GTK_FRAME (frame_help), GTK_WIDGET (help_box));
|
||||
|
||||
gtk_box_append (data_box, GTK_WIDGET (frame_rule_effect));
|
||||
gtk_box_append (data_box, GTK_WIDGET (frame_rule_topic));
|
||||
gtk_box_append (data_box, GTK_WIDGET (frame_data_type));
|
||||
gtk_box_append (data_box, GTK_WIDGET (frame_interpretations));
|
||||
gtk_box_append (data_box, GTK_WIDGET (frame_discussions));
|
||||
gtk_box_append (data_box, GTK_WIDGET (frame_separator));
|
||||
gtk_box_append (data_box, GTK_WIDGET (frame_game));
|
||||
gtk_box_append (data_box, GTK_WIDGET (frame_help));
|
||||
|
||||
gtk_box_append (rule_effect_box, gtk_button_new_with_label ("movement"));
|
||||
gtk_box_append (rule_effect_box, gtk_button_new_with_label ("transport"));
|
||||
gtk_box_append (rule_effect_box, gtk_button_new_with_label ("transformation"));
|
||||
|
||||
gtk_box_append (rule_topic_box, gtk_button_new_with_label ("objects"));
|
||||
gtk_box_append (rule_topic_box, gtk_button_new_with_label ("situations"));
|
||||
|
||||
gtk_box_append (rule_topic_box, GTK_WIDGET (gtk_separator_new (GTK_ORIENTATION_HORIZONTAL)));
|
||||
gtk_box_append (rule_topic_box, GTK_WIDGET (gtk_separator_new (GTK_ORIENTATION_HORIZONTAL)));
|
||||
gtk_box_append (rule_topic_box, gtk_button_new_with_label ("accuracy"));
|
||||
gtk_box_append (rule_topic_box, gtk_button_new_with_label ("pattern recognition"));
|
||||
|
||||
gtk_box_append (data_type_box, gtk_button_new_with_label ("repartitions"));
|
||||
gtk_box_append (data_type_box, gtk_button_new_with_label ("evolutions"));
|
||||
gtk_box_append (data_type_box, gtk_button_new_with_label ("correlations"));
|
||||
|
||||
gtk_box_append (interpretations_box, gtk_button_new_with_label ("stochastic"));
|
||||
gtk_box_append (interpretations_box, gtk_button_new_with_label ("deterministic"));
|
||||
|
||||
gtk_box_append (interpretations_box, GTK_WIDGET (gtk_separator_new (GTK_ORIENTATION_HORIZONTAL)));
|
||||
gtk_box_append (interpretations_box, GTK_WIDGET (gtk_separator_new (GTK_ORIENTATION_HORIZONTAL)));
|
||||
gtk_box_append (interpretations_box, gtk_button_new_with_label ("physical"));
|
||||
gtk_box_append (interpretations_box, gtk_button_new_with_label ("chemical"));
|
||||
gtk_box_append (interpretations_box, gtk_button_new_with_label ("biological"));
|
||||
gtk_box_append (interpretations_box, gtk_button_new_with_label ("social"));
|
||||
gtk_box_append (interpretations_box, GTK_WIDGET (gtk_separator_new (GTK_ORIENTATION_HORIZONTAL)));
|
||||
|
||||
gtk_box_append (discussions_box, gtk_button_new_with_label ("context"));
|
||||
gtk_box_append (discussions_box, gtk_button_new_with_label ("methodology"));
|
||||
gtk_box_append (discussions_box, gtk_button_new_with_label ("comparisons"));
|
||||
gtk_box_append (discussions_box, gtk_button_new_with_label ("to improve"));
|
||||
gtk_box_append (discussions_box, gtk_button_new_with_label ("summary"));
|
||||
|
||||
gtk_box_append (game_box, gtk_button_new_with_label ("single player"));
|
||||
gtk_box_append (game_box, gtk_button_new_with_label ("multiple players"));
|
||||
gtk_box_append (game_box, gtk_button_new_with_label ("edition facilities"));
|
||||
|
||||
gtk_box_append (help_box, gtk_button_new_with_label ("modelization"));
|
||||
gtk_box_append (help_box, gtk_button_new_with_label ("measurements"));
|
||||
gtk_box_append (help_box, gtk_button_new_with_label ("results"));
|
||||
gtk_box_append (help_box, gtk_button_new_with_label ("data analysis"));
|
||||
|
||||
gtk_box_append (help_box, GTK_WIDGET (gtk_separator_new (GTK_ORIENTATION_HORIZONTAL)));
|
||||
gtk_box_append (help_box, GTK_WIDGET (gtk_separator_new (GTK_ORIENTATION_HORIZONTAL)));
|
||||
gtk_box_append (help_box, gtk_button_new_with_label ("preferences"));
|
||||
|
||||
//SWITCH_TO (DATA);
|
||||
return GTK_WIDGET (data_box);
|
||||
}
|
||||
|
||||
static void icons_for_fun (GtkHeaderBar *header_bar)
|
||||
{
|
||||
GtkButton *go_home = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (go_home, "go-home-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (go_home));
|
||||
|
||||
GtkButton *user_trash = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (user_trash, "user-trash-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (user_trash));
|
||||
|
||||
GtkButton *help_biblio = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (help_biblio, "accessories-dictionary-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (help_biblio));
|
||||
|
||||
GtkButton *help_doc = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (help_doc, "emblem-documents-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (help_doc));
|
||||
|
||||
GtkButton *help_about = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (help_about, "help-about-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (help_about));
|
||||
|
||||
GtkButton *help_faq = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (help_faq, "help-faq-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (help_faq));
|
||||
|
||||
GtkButton *terminal = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (terminal, "utilities-terminal-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (terminal));
|
||||
|
||||
GtkButton *search = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (search, "folder-saved-search-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (search));
|
||||
|
||||
GtkButton *preferences_desktop_appearance = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (preferences_desktop_appearance, "preferences-desktop-appearance-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (preferences_desktop_appearance));
|
||||
|
||||
GtkButton *preferences_system = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (preferences_system, "preferences-system-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (preferences_system));
|
||||
|
||||
GtkButton *document_properties = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (document_properties, "document-properties-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (document_properties));
|
||||
|
||||
GtkButton *text_edit = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (text_edit, "text-editor-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (text_edit));
|
||||
|
||||
GtkButton *applications_utilities = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (applications_utilities, "applications-utilities-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (applications_utilities));
|
||||
|
||||
GtkButton *open_menu = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (open_menu, "open-menu-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (open_menu));
|
||||
|
||||
GtkButton *power_max = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (power_max, "power-profile-performance-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (power_max));
|
||||
|
||||
GtkButton *power_middle = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (power_middle, "power-profile-balanced-rtl-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (power_middle));
|
||||
|
||||
GtkButton *power_low = GTK_BUTTON (gtk_button_new ());
|
||||
gtk_button_set_icon_name (power_low, "power-profile-power-saver-symbolic");
|
||||
gtk_header_bar_pack_end (header_bar, GTK_WIDGET (power_low));
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
//******************************************************************************/
|
||||
/* */
|
||||
/* E coli by David S. Goodsell (2009) */
|
||||
/* --- */
|
||||
/* Let this freeze frame guide us towards the model */
|
||||
/* that alone can account for the phenomenon ! */
|
||||
/* */
|
||||
/******************************************************************************/
|
||||
|
||||
#include <gtk-4.0/gtk/gtk.h>
|
||||
|
||||
#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
|
||||
|
||||
/*
|
||||
G_BEGIN_DECLS
|
||||
#define MY_TYPE_WINDOW (my_window_get_type())
|
||||
G_DECLARE_FINAL_TYPE (MyWindow, my_window, MY, WINDOW, GtkApplicationWindow)
|
||||
G_END_DECLS
|
||||
|
||||
G_BEGIN_DECLS
|
||||
#define MY_TYPE_APPLICATION (my_application_get_type())
|
||||
G_DECLARE_FINAL_TYPE (MyApplication, my_application, MY, APPLICATION, GtkApplication)
|
||||
MyApplication *my_application_new (const char *application_id, GApplicationFlags flags);
|
||||
G_END_DECLS
|
||||
*/
|
||||
|
||||
void main_window_design (GtkWindow *main_window);
|
||||
void set_check_button_active (GtkButton *button, int active);
|
||||
void two_notebooks_in_two_panes (GtkWindow *window);
|
||||
|
||||
GtkFrame *get_frame_with_label();
|
||||
GtkWidget *get_selected_rules_vpaned_new();
|
||||
GtkWidget *get_TIME_EXEC_controls_box();
|
||||
GtkWidget *get_SPACE_EDIT_controls_box();
|
||||
GtkButton *get_GtkButton (char *btt_name);
|
||||
GtkWidget *get_window_child_STATE();
|
||||
GtkWidget *get_window_child_RULES();
|
||||
GtkWidget *get_window_child_DATA();
|
|
@ -0,0 +1,37 @@
|
|||
#include "callback.h"
|
||||
|
||||
void dialog_window_design (GtkWindow *main_window, GtkWindow *dialog_window){
|
||||
char *title = " Save the current model before modifying it? ";
|
||||
GtkWidget *header_bar = GTK_WIDGET (gtk_header_bar_new ());
|
||||
gtk_header_bar_set_title_widget (GTK_HEADER_BAR (header_bar), gtk_label_new (title));
|
||||
gtk_window_set_titlebar (dialog_window, header_bar);
|
||||
|
||||
GtkWidget *dialog_window_grid = gtk_grid_new ();
|
||||
|
||||
const char *txt = " SAVE CURRENT MODEL ";
|
||||
GtkButton *action_save_current_model = GTK_BUTTON (gtk_button_new_with_label (txt));
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (action_save_current_model), FALSE);
|
||||
g_signal_connect (action_save_current_model, "clicked",
|
||||
G_CALLBACK (on_WRITE_CURRENT_MODEL), dialog_window);
|
||||
|
||||
GtkButton *click_yes = GTK_BUTTON (gtk_button_new_with_label ("YES"));
|
||||
g_signal_connect (click_yes, "clicked",
|
||||
G_CALLBACK (on_SAVE_CURRENT_MODEL_BEFORE_EDITING), action_save_current_model);
|
||||
|
||||
GtkButton *click_no = GTK_BUTTON (gtk_button_new_with_label ("NO"));
|
||||
g_signal_connect (click_no, "clicked",
|
||||
G_CALLBACK (on_DISCARD_CURRENT_MODEL_AND_START_EDITING), dialog_window);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (dialog_window_grid), GTK_WIDGET (click_yes), 0, 0, 1, 1) ;
|
||||
gtk_grid_attach (GTK_GRID (dialog_window_grid), GTK_WIDGET (click_no), 1, 0, 1, 1) ;
|
||||
gtk_grid_attach (GTK_GRID (dialog_window_grid), GTK_WIDGET (action_save_current_model), 0, 2, 2, 1) ;
|
||||
gtk_window_set_child (GTK_WINDOW (dialog_window), GTK_WIDGET (dialog_window_grid));
|
||||
|
||||
gtk_window_set_transient_for (GTK_WINDOW (dialog_window), GTK_WINDOW (main_window));
|
||||
gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog_window), TRUE);
|
||||
gtk_window_set_deletable (GTK_WINDOW (dialog_window), FALSE); // FALSE
|
||||
gtk_window_set_modal (GTK_WINDOW (dialog_window), TRUE);
|
||||
// gtk_window_present (GTK_WINDOW (dialog_window)); see button...
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
void dialog_window_design (GtkWindow *main_window, GtkWindow *dialog_window);
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gem-graph-model version="0.2.1">
|
||||
|
||||
<identity>
|
||||
<name>Modèle de test</name>
|
||||
|
||||
<owner>Léontine Patinette</owner>
|
||||
|
||||
<owner_id>2</owner_id>
|
||||
|
||||
<date>1630000000</date>
|
||||
|
||||
<version>1.0</version>
|
||||
|
||||
<g_ref id="Cause" date="1630000000" author="toujours" lang="en">Ref</g_ref>
|
||||
</identity>
|
||||
|
||||
<parameters id="texte" date="0" author="Léontine Trottine.">
|
||||
<simulation>
|
||||
<max_thread>0</max_thread>
|
||||
<max_cycles>9</max_cycles>
|
||||
|
||||
</simulation>
|
||||
|
||||
<space-param>
|
||||
<!-- loop_on_zero="true" anything moved before zero reenters at the end of space-->
|
||||
<!-- loop_on_zero="false" anything moved before zero is lost-->
|
||||
<!-- loop_on_max="true" anything moved beyond max reenters at the zero of space-->
|
||||
<!-- loop_on_max="false" anything moved beyond max is lost-->
|
||||
|
||||
<dimension x="29"/>
|
||||
|
||||
<!-- Site_multiplicity = number of sites in a space unit. -->
|
||||
<!-- Each site points towards a neighbouring space unit. -->
|
||||
<!-- Several arrows can be stacked in the same site. -->
|
||||
|
||||
<site_multiplicity>3</site_multiplicity>
|
||||
|
||||
</space-param>
|
||||
|
||||
</parameters>
|
||||
|
||||
<!-- Model objects definition -->
|
||||
|
||||
<objects id="only dimers in this model" date="1630000000" author="inanimés,... âme ?">
|
||||
<object id="a dimer" date="1630000000" author="Alphonse">
|
||||
<arrow site="1" weight="1" x="0"/>
|
||||
<arrow site="2" weight="1" x="1"/>
|
||||
</object>
|
||||
|
||||
</objects>
|
||||
|
||||
|
||||
<!-- Saved space description (initial space is sequence 0) -->
|
||||
|
||||
<savedstates id="texte" date="1630000000" author="Qui courrait dans l'herbe'">
|
||||
<state id="initial" date="1630000000" author="Une souris verte">
|
||||
<arrow site="0" weight="1" x="0"/>
|
||||
<arrow site="1" weight="1" x="1"/>
|
||||
<arrow site="0" weight="1" x="10"/>
|
||||
<arrow site="1" weight="1" x="11"/>
|
||||
<arrow site="0" weight="1" x="20"/>
|
||||
<arrow site="1" weight="1" x="21"/>
|
||||
|
||||
<!-- Three dimers 1-1 are drawn in the global space
|
||||
at locations (0,1) (10,11) and (20,21) -->
|
||||
|
||||
</state>
|
||||
|
||||
</savedstates>
|
||||
|
||||
<!-- Model transitions definition (rules) -->
|
||||
<!-- In this version : <xs:sequence minOccurs="0" maxOccurs="unbounded">-->
|
||||
<!-- Transitions should be edited by hand and written in a 'human-readable' format -->
|
||||
|
||||
<conditions id="random walk of dimers" date="1630000000" author="Zazard le lézard !">
|
||||
|
||||
<condition site="1" weight="1" node_id="1" parent="0" x="0"/>
|
||||
<condition site="2" weight="1" node_id="2" parent="1" x="1"/>
|
||||
<!-- as soon as conditions 1 and 2 are satisfied, a dimer is identified at atation (0,1). -->
|
||||
|
||||
<condition site="1" weight="0" node_id="3" parent="2" x="2"/>
|
||||
<!-- as soon as condition 3 is satisfied,
|
||||
the neighbouring space unit to East of the dimer is empty
|
||||
and the dimer identified by conditions (1,2) can be moved to East. -->
|
||||
|
||||
<condition site="2" weight="0" node_id="4" parent="2" x="-1"/>
|
||||
<!-- as soon as condition 4 is satisfied,
|
||||
the neighbouring space unit to West of the dimer is empty
|
||||
and the dimer identified by conditions (1,2) can be moved to West. -->
|
||||
|
||||
</conditions>
|
||||
|
||||
<transitions>
|
||||
|
||||
<transition id="move_a_dimer_to_east" date="1630000000" author="Pas moi..."
|
||||
parent="3" probability="1">
|
||||
|
||||
<arrow site="1" weight="0" x="0"/>
|
||||
<arrow site="2" weight="0" x="1"/>
|
||||
<arrow site="1" weight="1" x="1"/>
|
||||
<arrow site="2" weight="1" x="2"/>
|
||||
|
||||
</transition>
|
||||
|
||||
<transition id="move_a_dimer_to_west" date="1630000000" author="Ni moi !"
|
||||
parent="4" probability="1">
|
||||
|
||||
<arrow site="1" weight="0" x="0"/>
|
||||
<arrow site="2" weight="0" x="1"/>
|
||||
<arrow site="2" weight="1" x="0"/>
|
||||
<arrow site="1" weight="1" x="1"/>
|
||||
|
||||
</transition>
|
||||
|
||||
</transitions>
|
||||
|
||||
</gem-graph-model>
|
|
@ -0,0 +1,280 @@
|
|||
#include <stdio.h>
|
||||
#include <gtk-4.0/gtk/gtk.h>
|
||||
|
||||
#include "contain.h"
|
||||
#include "tree.h"
|
||||
#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("/home/jean/01/Gtk4/Getting_Started_with_GTK/image/aXoris.png");
|
||||
image = gtk_picture_new_for_filename ("/home/jean/01/Gtk4/Getting_Started_with_GTK/image/gg sketch.png");
|
||||
image = gtk_picture_new_for_filename ("/home/jean/01/Gtk4/Getting_Started_with_GTK/image/E coli (Goodsell) 2.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 ("/home/jean/01/Gtk4/Getting_Started_with_GTK/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 ("/home/jean/01/Gtk4/Getting_Started_with_GTK/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 ("/home/jean/01/Gtk4/Getting_Started_with_GTK/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 ("/home/jean/01/Gtk4/Getting_Started_with_GTK/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 ("/home/jean/01/Gtk4/Getting_Started_with_GTK/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 ("/home/jean/01/Gtk4/Getting_Started_with_GTK/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 ("/home/jean/01/Gtk4/Getting_Started_with_GTK/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 ("/home/jean/01/Gtk4/Getting_Started_with_GTK/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 ("/home/jean/01/Gtk4/Getting_Started_with_GTK/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 ---\n orient\n state\n in space\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_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);
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/******************************************************************************/
|
||||
/* */
|
||||
/* 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_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();
|
||||
GtkWidget *get_rules_tree_hpaned_new();
|
||||
|
||||
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();
|
||||
|
||||
GtkButton *get_btt_run_xor_edit();
|
||||
|
||||
void window_bar(GtkWindow *window, char *title);
|
||||
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Gem-graph OpenGL experiments
|
||||
*
|
||||
* Desc: GL functions
|
||||
*
|
||||
* Copyright (C) 2023 Adrien Bourmault <neox@a-lec.org>
|
||||
* Copyright (C) 2023 Jean Sirmai <jean@a-lec.org>
|
||||
*
|
||||
* This file is part of Gem-graph.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Writes values to describe a vertex at (x,y,z) intoq the vertex buffer
|
||||
*
|
||||
* @param coords GLfloat(x,y,z)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <cglm/cglm.h>
|
||||
#include "base.h"
|
||||
//#include "ui.h"
|
||||
#include "graph_area.h"
|
||||
|
||||
void graphics_draw_vertex (const int stack_id,
|
||||
GLfloat x,
|
||||
GLfloat y,
|
||||
GLfloat z)
|
||||
{
|
||||
//g_printerr("stack_id is %d\n", stack_id);
|
||||
//g_printerr("stack_id is %d\n", stack_id);
|
||||
//g_printerr("graphic_stack is at %p\n", graphic_stack);
|
||||
//g_printerr("graphic_stack[stack_id] is at %p\n", graphic_stack + stack_id);
|
||||
volatile struct graphic_stack_t *stack = &graphic_stack[stack_id];
|
||||
|
||||
//g_printerr("Currently stack->buffer_vertex_origin @ %p\n", stack->buffer_vertex_origin);
|
||||
|
||||
//assert (stack->buffer_vertex_origin);
|
||||
|
||||
stack->buffer_vertex_origin =
|
||||
g_realloc (stack->buffer_vertex_origin,
|
||||
(stack->buffer_vertex_size + 3) * sizeof(GLfloat));
|
||||
//print_stack(stack_id);
|
||||
|
||||
stack->buffer_vertex_origin[stack->buffer_vertex_size + 0] = x;
|
||||
stack->buffer_vertex_origin[stack->buffer_vertex_size + 1] = y;
|
||||
stack->buffer_vertex_origin[stack->buffer_vertex_size + 2] = z;
|
||||
|
||||
stack->buffer_vertex_size += 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* Writes values to describe a color (r,g,b) into the color buffer
|
||||
*
|
||||
* @param color GLfloat(r,g,b)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void graphics_draw_color (const int stack_id,
|
||||
GLfloat r,
|
||||
GLfloat g,
|
||||
GLfloat b)
|
||||
{
|
||||
struct graphic_stack_t *stack = &graphic_stack[stack_id];
|
||||
|
||||
stack->buffer_colors_origin = g_realloc (stack->buffer_colors_origin,
|
||||
(stack->buffer_colors_size + 3) * sizeof(GLfloat));
|
||||
|
||||
assert (stack->buffer_colors_origin);
|
||||
|
||||
stack->buffer_colors_origin[stack->buffer_colors_size + 0] = r;
|
||||
stack->buffer_colors_origin[stack->buffer_colors_size + 1] = g;
|
||||
stack->buffer_colors_origin[stack->buffer_colors_size + 2] = b;
|
||||
|
||||
stack->buffer_colors_size += 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* Writes values to describe a line from a to b into the line buffer
|
||||
*
|
||||
* @param coords GLuint (a,b)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void graphics_draw_line (const int stack_id,
|
||||
GLuint a,
|
||||
GLuint b)
|
||||
{
|
||||
struct graphic_stack_t *stack = &graphic_stack[stack_id];
|
||||
|
||||
stack->buffer_lines_origin = g_realloc (stack->buffer_lines_origin,
|
||||
(stack->buffer_lines_size + 2) * sizeof(GLuint));
|
||||
|
||||
assert (stack->buffer_lines_origin);
|
||||
|
||||
stack->buffer_lines_origin[stack->buffer_lines_size + 0] = a;
|
||||
stack->buffer_lines_origin[stack->buffer_lines_size + 1] = b;
|
||||
|
||||
stack->buffer_lines_size += 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Writes values to describe an (a,b,c) plan (triangle) into the plan buffer
|
||||
*
|
||||
* @param coords GLuint (a,b,c)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void graphics_draw_plan (const int stack_id,
|
||||
GLuint a,
|
||||
GLuint b,
|
||||
GLuint c)
|
||||
{
|
||||
struct graphic_stack_t *stack = &graphic_stack[stack_id];
|
||||
|
||||
stack->buffer_plans_origin = g_realloc (stack->buffer_plans_origin,
|
||||
(stack->buffer_plans_size + 3) * sizeof(GLuint));
|
||||
|
||||
assert (stack->buffer_plans_origin);
|
||||
|
||||
stack->buffer_plans_origin[stack->buffer_plans_size + 0] = a;
|
||||
stack->buffer_plans_origin[stack->buffer_plans_size + 1] = b;
|
||||
stack->buffer_plans_origin[stack->buffer_plans_size + 2] = c;
|
||||
|
||||
stack->buffer_plans_size += 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* Draws the current buffer to a gl_area
|
||||
*
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void graphics_draw(const int stack_id)
|
||||
{
|
||||
struct graphic_stack_t *stack = &graphic_stack[stack_id];
|
||||
|
||||
g_printerr("[debug] graphics_draw() started\n");
|
||||
|
||||
print_stack(stack_id);
|
||||
|
||||
GLint cur_viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, cur_viewport);
|
||||
|
||||
mat4 m = GLM_MAT4_IDENTITY_INIT;
|
||||
glm_rotate_x(m, glm_rad(stack->rotation_angles[X_AXIS]), m);
|
||||
glm_rotate_y(m, glm_rad(stack->rotation_angles[Y_AXIS]), m);
|
||||
glm_rotate_z(m, glm_rad(stack->rotation_angles[Z_AXIS]), m);
|
||||
|
||||
mat4 v = GLM_MAT4_IDENTITY_INIT; // XXX define zoom and translations here ?
|
||||
|
||||
mat4 p = GLM_MAT4_IDENTITY_INIT;
|
||||
glm_ortho(-1.0f, +1.0f, -1.0f, +1.0f, -1.0f, +1.0f, p);
|
||||
glm_ortho_default((float)cur_viewport[2] / (float)cur_viewport[3], p);
|
||||
glm_perspective_default((float)cur_viewport[2] / (float)cur_viewport[3], p);
|
||||
|
||||
/* Use our shaders */
|
||||
glUseProgram(stack->program);
|
||||
|
||||
glClearColor(0, 0, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
/* Update the "mvp" matrix we use in the shader */
|
||||
glUniformMatrix4fv(stack->m, 1, GL_FALSE, (float *)m);
|
||||
glUniformMatrix4fv(stack->v, 1, GL_FALSE, (float *)v);
|
||||
glUniformMatrix4fv(stack->p, 1, GL_FALSE, (float *)p);
|
||||
|
||||
/* Use the vertices in our buffer */
|
||||
glEnableVertexAttribArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, stack->position_buffer);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0,(void*)0);
|
||||
|
||||
// couleurs
|
||||
glEnableVertexAttribArray(1);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, stack->color_buffer);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0,(void*)0);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glDrawElements(GL_LINES, stack->buffer_lines_size, GL_UNSIGNED_INT, stack->buffer_lines_origin);
|
||||
glDrawElements(GL_TRIANGLES, stack->buffer_plans_size, GL_UNSIGNED_INT, stack->buffer_plans_origin);
|
||||
|
||||
/* We finished using the buffers and program */
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glUseProgram(0);
|
||||
|
||||
glFlush();
|
||||
g_printerr("[debug] graphics_draw() ended\n");
|
||||
}
|
|
@ -0,0 +1,332 @@
|
|||
/*
|
||||
* Gem-graph OpenGL experiments
|
||||
*
|
||||
* Desc: User interface functions
|
||||
*
|
||||
* Copyright (C) 2023 Adrien Bourmault <neox@a-lec.org>
|
||||
*
|
||||
* This file is part of Gem-graph.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <gtk-4.0/gtk/gtk.h>
|
||||
#include <glib-2.0/glib.h>
|
||||
|
||||
#include "contain.h"
|
||||
#include "graph_area.h"
|
||||
#include "callback.h"
|
||||
|
||||
struct stack_index_t {
|
||||
long stack_id;
|
||||
void *container_widget;
|
||||
void *gl_area;
|
||||
};
|
||||
|
||||
static struct stack_index_t *stack_index = NULL;
|
||||
size_t stack_index_size = 0;
|
||||
|
||||
|
||||
int set_arrow (int stack_id, // 2024-06-27 DEBUG !
|
||||
int arrows_nb,
|
||||
int space_X,
|
||||
int space_Y,
|
||||
int space_Z,
|
||||
int requested_weight,
|
||||
int site,
|
||||
int arrow_x,
|
||||
int arrow_y,
|
||||
int arrow_z) {
|
||||
printf("graph_area.c > int set_arrow (...) 2024-06-27 DEBUG\n");
|
||||
return 0;
|
||||
|
||||
} // 2024-06-27 DEBUG !
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Look for stack entry and returns stack_id
|
||||
*
|
||||
* @params container_widget, generally the GtkBox that contains the GLArea
|
||||
*
|
||||
* @returns stack_id
|
||||
*/
|
||||
long ui_get_graphic_stack(void *container_widget)
|
||||
{
|
||||
// look for stack_index entry
|
||||
for (int i = 0; i < stack_index_size; i++) {
|
||||
if (stack_index[i].container_widget == (void *)container_widget) {
|
||||
return stack_index[i].stack_id;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for stack entry and returns stack_id
|
||||
*
|
||||
* @params container_widget, generally the GtkBox that contains the GLArea
|
||||
*
|
||||
* @returns stack_id
|
||||
*/
|
||||
long ui_is_graphic_stack_ready(void *container_widget)
|
||||
{
|
||||
// look for stack_index entry
|
||||
for (int i = 0; i < stack_index_size; i++) {
|
||||
if (stack_index[i].container_widget == (void *)container_widget) {
|
||||
return stack_index[i].stack_id;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for stack entry and initializes OpenGL for it
|
||||
*
|
||||
* @params container_widget, generally the GtkBox that contains the GLArea
|
||||
*
|
||||
* @returns bool, true if success
|
||||
*/
|
||||
bool ui_init_graphic_stack(void *container_widget, GError *error_buffer)
|
||||
{
|
||||
g_printerr("[debug] ui_init_graphic_stack()\n");
|
||||
|
||||
g_printerr("[debug] ui_init_graphic_stack() : target is %p\n", container_widget);
|
||||
|
||||
// look for stack_index entry
|
||||
for (int i = 0; i < stack_index_size; i++) {
|
||||
g_printerr("[debug] ui_init_graphic_stack() : i is %d\n", i);
|
||||
g_printerr("[debug] ui_init_graphic_stack() : target would be %p\n",
|
||||
stack_index[i].container_widget);
|
||||
if (stack_index[i].container_widget == (void *)container_widget) {
|
||||
stack_index[i].stack_id = graphics_init(&error_buffer);
|
||||
g_printerr("[debug] ui_init_graphic_stack() : stack_id is %ld\n",
|
||||
stack_index[i].stack_id);
|
||||
if (stack_index[i].stack_id >= 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for stack entry and shutdowns OpenGL for it
|
||||
*
|
||||
* @params container_widget, generally the GtkBox that contains the GLArea
|
||||
*
|
||||
* @returns bool, true if success
|
||||
*/
|
||||
bool ui_shutdown_graphic_stack(void *container_widget, GError *error_buffer)
|
||||
{
|
||||
// look for stack_index entry
|
||||
for (int i = 0; i < stack_index_size; i++) {
|
||||
if (stack_index[i].container_widget == (void *)container_widget) {
|
||||
if (graphics_shutdown(stack_index[i].stack_id,
|
||||
&error_buffer) == false) {
|
||||
return false;
|
||||
}
|
||||
stack_index[i].stack_id = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ui_clean_stack_index(void)
|
||||
{
|
||||
// look for stack_index entry
|
||||
for (int i = 0; i < stack_index_size; i++) {
|
||||
stack_index[i].stack_id = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for stack entry and triggers OpenGL for drawing
|
||||
*
|
||||
* @params container_widget, generally the GtkBox that contains the GLArea
|
||||
*
|
||||
* @returns bool, true if success
|
||||
*/
|
||||
bool ui_render_stack(GtkWidget *container_widget)
|
||||
{
|
||||
// look for stack_index entry
|
||||
for (int i = 0; i < stack_index_size; i++) {
|
||||
if (stack_index[i].container_widget == (void *)container_widget) {
|
||||
graphics_draw (stack_index[i].stack_id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//void graphics_draw(const int stack_id) {printf("graph_area.c > void graphics_draw(const int stack_id) (161)\n");}
|
||||
|
||||
/*
|
||||
* Look for stack entry and triggers OpenGL for drawing
|
||||
*
|
||||
* @params container_widget, generally the GtkBox that contains the GLArea
|
||||
*
|
||||
* @returns bool, true if success
|
||||
*/
|
||||
bool ui_update_axis_stack(GtkWidget *container_widget, int axis, int value)
|
||||
{
|
||||
// look for stack_index entry
|
||||
for (int i = 0; i < stack_index_size; i++) {
|
||||
if (stack_index[i].container_widget == (void *)container_widget) {
|
||||
graphic_stack[stack_index[i].stack_id].rotation_angles[axis] = value;
|
||||
gtk_widget_queue_draw((GtkWidget*)(stack_index[i].gl_area));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for every stack entry and shutdowns OpenGL for it
|
||||
*
|
||||
* @params void
|
||||
*
|
||||
* @returns bool, true if success
|
||||
*/
|
||||
void ui_shutdown_all_graphic_stacks(void)
|
||||
{
|
||||
// look for stack_index entry
|
||||
for (int i = 0; i < stack_index_size; i++) {
|
||||
graphics_shutdown(stack_index[i].stack_id, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a slider widget
|
||||
*
|
||||
* @params axis, meaning which axis we're building (for label)
|
||||
*
|
||||
* @returns GtkWidget*, pointer to the new widget
|
||||
*/
|
||||
GtkWidget *create_axis_slider(int axis)
|
||||
{
|
||||
GtkWidget *box, *label, *slider;
|
||||
GtkAdjustment *adj;
|
||||
const char *text;
|
||||
|
||||
box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
|
||||
switch (axis) {
|
||||
case X_AXIS:
|
||||
text = "X";
|
||||
break;
|
||||
|
||||
case Y_AXIS:
|
||||
text = "Y";
|
||||
break;
|
||||
|
||||
case Z_AXIS:
|
||||
text = "Z";
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
label = gtk_label_new(text);
|
||||
gtk_box_append(GTK_BOX(box), label);
|
||||
gtk_widget_set_visible (label, TRUE);
|
||||
|
||||
adj = gtk_adjustment_new(0.0, 0.0, 360.0, 1.0, 12.0, 0.0);
|
||||
g_signal_connect (adj, "value-changed", G_CALLBACK(on_axis_value_change), (gpointer) label);
|
||||
slider = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, adj);
|
||||
gtk_box_append(GTK_BOX(box), slider);
|
||||
gtk_widget_set_hexpand(slider, TRUE);
|
||||
gtk_widget_set_visible (slider, TRUE);
|
||||
|
||||
gtk_widget_set_visible (box, TRUE);
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates GLArea and indexes it
|
||||
*
|
||||
* @params target_mode, meaning which ui_stack we're on
|
||||
* target_widget, meaning the box that will host the GLArea
|
||||
*
|
||||
* @returns bool, true if success
|
||||
*/
|
||||
bool ui_setup_glarea(int target_mode, GtkWidget *target_widget)
|
||||
{
|
||||
GtkWidget *gl_area;
|
||||
|
||||
g_printerr("[debug] ui_setup_glarea()\n");
|
||||
|
||||
assert(target_widget);
|
||||
|
||||
g_printerr("[debug] ui_setup_glarea() : target is %p\n", target_widget);
|
||||
|
||||
if (stack_index == NULL) {
|
||||
stack_index = g_malloc(sizeof(struct stack_index_t));
|
||||
stack_index_size = 1;
|
||||
} else {
|
||||
// look for stack_index entry
|
||||
for (int i = 0; i < stack_index_size; i++) {
|
||||
if (stack_index[i].container_widget == (void *)target_widget) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// create entry
|
||||
stack_index =
|
||||
g_realloc(stack_index,
|
||||
++stack_index_size * sizeof(struct stack_index_t));
|
||||
}
|
||||
|
||||
gl_area = GTK_WIDGET(gtk_gl_area_new());
|
||||
assert(gl_area);
|
||||
|
||||
gtk_widget_set_size_request(gl_area, 1000, 1000);
|
||||
gtk_gl_area_set_auto_render(GTK_GL_AREA(gl_area), true);
|
||||
gtk_widget_set_hexpand(gl_area, TRUE);
|
||||
gtk_widget_set_vexpand(gl_area, TRUE);
|
||||
gtk_widget_set_halign(gl_area, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign(gl_area, GTK_ALIGN_CENTER);
|
||||
|
||||
// The main "draw" call for GtkGLArea
|
||||
g_signal_connect(GTK_GL_AREA(gl_area), "render", G_CALLBACK(on_glarea_render), NULL);
|
||||
g_signal_connect(gl_area, "realize", G_CALLBACK(on_glarea_realize), NULL);
|
||||
g_signal_connect(gl_area, "unrealize", G_CALLBACK(on_glarea_unrealize), NULL);
|
||||
|
||||
stack_index[stack_index_size-1].container_widget =
|
||||
(void*)target_widget;
|
||||
|
||||
stack_index[stack_index_size-1].gl_area = (void*)gl_area;
|
||||
|
||||
g_printerr("[debug] ui_setup_glarea() : set target to %p\n", target_widget);
|
||||
|
||||
g_printerr("[debug] ui_setup_glarea() : stack_index (@0x%p) had %ld elements\n",
|
||||
stack_index,
|
||||
stack_index_size);
|
||||
|
||||
gtk_box_append (GTK_BOX (target_widget), gl_area);
|
||||
gtk_widget_set_visible (GTK_WIDGET (gl_area), TRUE);
|
||||
|
||||
// Create sliders
|
||||
for(int i = 0; i < N_AXIS; i++)
|
||||
gtk_box_append(GTK_BOX(target_widget), create_axis_slider(i));
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* Gem-graph OpenGL experiments
|
||||
*
|
||||
* Desc: OpenGL utils header
|
||||
*
|
||||
* Copyright (C) 2023 Arthur Menges <arthur.menges@a-lec.org>
|
||||
* Copyright (C) 2023 Adrien Bourmault <neox@a-lec.org>
|
||||
* Copyright (C) 2023 Jean Sirmai <jean@a-lec.org>
|
||||
*
|
||||
* This file is part of Gem-graph.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <unistd.h>
|
||||
#include <gtk-4.0/gtk/gtk.h>
|
||||
#include <glib-2.0/glib.h>
|
||||
#include <stdbool.h>
|
||||
#include <epoxy/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GL/glext.h>
|
||||
#include <cglm/cglm.h>
|
||||
|
||||
#include "base.h"
|
||||
//#include "draw.c"
|
||||
|
||||
// #define VERTEX_SHADER_FILE "src/graphics/shaders/shader.vert"
|
||||
// #define FRAG_SHADER_FILE "src/graphics/shaders/shader.frag"
|
||||
#define VERTEX_SHADER_FILE "shader.vert"
|
||||
#define FRAG_SHADER_FILE "shader.frag"
|
||||
#define GL_TARGET_MAJOR_VERSION 0
|
||||
#define GL_TARGET_MINOR_VERSION 4
|
||||
|
||||
/*
|
||||
* Structure describing a gl_area and its parameters, used to create a table
|
||||
* of Gem-graph client current gl_areas
|
||||
*/
|
||||
struct graphic_stack_t {
|
||||
|
||||
int id;
|
||||
int mode;
|
||||
|
||||
float rotation_angles[N_AXIS]; // Rotation angles on each axis
|
||||
|
||||
GLuint vao; // init_buffers
|
||||
GLuint position_buffer; // shutdown, draw
|
||||
GLuint color_buffer; // shutdown, draw
|
||||
GLuint program; // shutdown, init_shaders, draw
|
||||
GLuint m; // init_shaders, draw
|
||||
GLuint v; // init_shaders, draw
|
||||
GLuint p; // init_shaders, draw
|
||||
|
||||
struct arrow_t *arrows_ptr;
|
||||
long arrows_nb;
|
||||
|
||||
GLfloat *buffer_vertex_origin;
|
||||
GLfloat *buffer_colors_origin;
|
||||
GLuint *buffer_lines_origin;
|
||||
GLuint *buffer_plans_origin;
|
||||
|
||||
long buffer_vertex_size;
|
||||
long buffer_colors_size;
|
||||
long buffer_lines_size;
|
||||
long buffer_plans_size;
|
||||
|
||||
long buffer_vertex_0_arrow;
|
||||
long buffer_colors_0_arrow;
|
||||
long buffer_lines_0_arrow;
|
||||
long buffer_plans_0_arrow;
|
||||
};
|
||||
|
||||
bool ui_render_stack(GtkWidget *container_widget);
|
||||
|
||||
bool ui_setup_glarea(int target_mode, GtkWidget *target_widget);
|
||||
|
||||
/*
|
||||
* Dynamic array of ptrs to dynamically allocated gl_area_entry
|
||||
*/
|
||||
extern struct graphic_stack_t *graphic_stack;
|
||||
|
||||
/*
|
||||
* Initializes a gl_area
|
||||
*
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
*
|
||||
* @return true if initialized
|
||||
*/
|
||||
int graphics_init(void *error_buffer);
|
||||
|
||||
/*
|
||||
* Draws the current buffer to a gl_area
|
||||
*
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void graphics_draw(const int stack_id);
|
||||
|
||||
/*
|
||||
* Shutdowns a gl_area
|
||||
*
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
*
|
||||
* @return true if success
|
||||
*/
|
||||
bool graphics_shutdown(const int stack_id, void *error_buffer);
|
||||
|
||||
/*
|
||||
* Initializes the shaders of a gl_area and link them to a program
|
||||
*
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
*
|
||||
* @return true if initialized
|
||||
*/
|
||||
bool graphics_init_shaders(const int stack_id);
|
||||
|
||||
bool ui_init_graphic_stack(void *container_widget, GError *error_buffer);
|
||||
bool ui_shutdown_graphic_stack(void *container_widget, GError *error_buffer);
|
||||
bool ui_update_axis_stack(GtkWidget *container_widget, int axis, int value);
|
||||
|
||||
/* Initializes the buffer of a gl_area
|
||||
* Calls according to the user preferences
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
* @return void
|
||||
*/
|
||||
void graphics_init_buffers(const int stack_id);
|
||||
|
||||
/*
|
||||
* Draws a vertex (x, y, z)
|
||||
* if (console) prints (x, y, z) values to console
|
||||
*
|
||||
* @param GLfloat x, GLfloat y, GLfloat z
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void graphics_draw_vertex (const int stack_id,
|
||||
GLfloat x,
|
||||
GLfloat y,
|
||||
GLfloat z);
|
||||
|
||||
/*
|
||||
* Draws the color (r, g, b) associated to a vertex
|
||||
* if (console) prints (r, g, b) values to console
|
||||
*
|
||||
* @param GLfloat r, GLfloat g, GLfloat b
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void graphics_draw_color (const int stack_id, GLfloat r, GLfloat g, GLfloat b);
|
||||
|
||||
/*
|
||||
* Writes values to describe a line from a to b into the line buffer
|
||||
*
|
||||
* @param coords GLuint (a,b)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void graphics_draw_line (const int stack_id, GLuint a, GLuint b);
|
||||
|
||||
/*
|
||||
* Writes values to describe an (a,b,c) plan (triangle) into the plan buffer
|
||||
*
|
||||
* @param coords GLuint (a,b,c)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void graphics_draw_plan (const int stack_id, GLuint a, GLuint b, GLuint c);
|
||||
|
||||
/*
|
||||
* Created and compile a shader
|
||||
*
|
||||
* @param type, shader type
|
||||
* src, source code of shader
|
||||
*
|
||||
* @return shader id
|
||||
*/
|
||||
static inline GLuint create_shader(const int stack_id, int type, const char *src)
|
||||
{
|
||||
GLuint shader;
|
||||
int status;
|
||||
|
||||
shader = glCreateShader(type);
|
||||
glShaderSource(shader, 1, &src, NULL);
|
||||
glCompileShader(shader);
|
||||
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
if(status == GL_FALSE) {
|
||||
int log_len;
|
||||
char *buffer;
|
||||
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_len);
|
||||
|
||||
buffer = g_malloc(log_len + 1);
|
||||
assert (buffer);
|
||||
glGetShaderInfoLog(shader, log_len, NULL, buffer);
|
||||
|
||||
g_warning("Compile failure in %s shader:\n%s",
|
||||
type == GL_VERTEX_SHADER ? "vertex" : "fragment",
|
||||
buffer);
|
||||
|
||||
g_free(buffer);
|
||||
|
||||
glDeleteShader(shader);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
static inline void print_stack(int stack_id)
|
||||
{
|
||||
static int n = 0;
|
||||
|
||||
printf("\n[n=%d]***************", n);
|
||||
|
||||
printf("id = %d\tmode = %d\n",
|
||||
graphic_stack[stack_id].id,
|
||||
graphic_stack[stack_id].mode);
|
||||
|
||||
printf("rotation_angles = ");
|
||||
for (int i = 0; i < N_AXIS; i++) {
|
||||
printf("%f\t", graphic_stack[stack_id].rotation_angles[i]); // Rotation angles on each axis
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("vao = %d\n", graphic_stack[stack_id].vao);
|
||||
printf("position_buffer = %d\n", graphic_stack[stack_id].position_buffer);
|
||||
printf("color_buffer = %d\n", graphic_stack[stack_id].color_buffer);
|
||||
printf("program = %d\n", graphic_stack[stack_id].program);
|
||||
printf("m = %d\n", graphic_stack[stack_id].m);
|
||||
printf("v = %d\n", graphic_stack[stack_id].v);
|
||||
printf("p = %d\n", graphic_stack[stack_id].p);
|
||||
|
||||
printf("arrows_ptr = %p\n", graphic_stack[stack_id].arrows_ptr);
|
||||
printf("arrows_nb = %ld\n", graphic_stack[stack_id].arrows_nb);
|
||||
|
||||
printf("buffer_vertex_origin = %p\n", graphic_stack[stack_id].buffer_vertex_origin);
|
||||
printf("buffer_colors_origin = %p\n", graphic_stack[stack_id].buffer_colors_origin);
|
||||
printf("buffer_lines_origin = %p\n", graphic_stack[stack_id].buffer_lines_origin);
|
||||
printf("buffer_plans_origin = %p\n", graphic_stack[stack_id].buffer_plans_origin);
|
||||
|
||||
printf("buffer_vertex_size = %ld\n", graphic_stack[stack_id].buffer_vertex_size);
|
||||
printf("buffer_colors_size = %ld\n", graphic_stack[stack_id].buffer_colors_size);
|
||||
printf("buffer_lines_size = %ld\n", graphic_stack[stack_id].buffer_lines_size);
|
||||
printf("buffer_plans_size = %ld\n", graphic_stack[stack_id].buffer_plans_size);
|
||||
|
||||
printf("buffer_vertex_0_arrow = %ld\n", graphic_stack[stack_id].buffer_vertex_0_arrow);
|
||||
printf("buffer_colors_0_arrow = %ld\n", graphic_stack[stack_id].buffer_colors_0_arrow);
|
||||
printf("buffer_lines_0_arrow = %ld\n", graphic_stack[stack_id].buffer_lines_0_arrow);
|
||||
printf("buffer_plans_0_arrow = %ld\n", graphic_stack[stack_id].buffer_plans_0_arrow);
|
||||
|
||||
printf("********************\n");
|
||||
n++;
|
||||
}
|
||||
|
||||
|
||||
void graphics_model_setup (const int stack_id);
|
||||
|
||||
int draw_one_arrow_vertex (const int stack_id,
|
||||
int space_X,
|
||||
int space_Y,
|
||||
int space_Z,
|
||||
int weight,
|
||||
int site,
|
||||
int x,
|
||||
int y,
|
||||
int z);
|
||||
|
||||
int draw_one_arrow_line(const int stack_id,
|
||||
int offset_vertex);
|
||||
|
||||
/*
|
||||
* Writes grid ridges to vertex and color buffers
|
||||
*
|
||||
* @param coords long (x,y,z), step_x, step_y, step_z
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
int draw_space_ridges_vertex (const int stack_id,
|
||||
long offset_vertex,
|
||||
long x,
|
||||
long y,
|
||||
long z);
|
||||
|
||||
int draw_space_ridges_lines (const int stack_id);
|
||||
|
||||
/*
|
||||
* Writes grid lines on space faces
|
||||
*
|
||||
* @param coords long (x,y,z)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
long draw_grids_on_space_faces_vertex (const int stack_id,
|
||||
long x,
|
||||
long y,
|
||||
long z);
|
||||
|
||||
long draw_grids_on_space_faces_lines (const int stack_id,
|
||||
long offset_vertex,
|
||||
long x,
|
||||
long y,
|
||||
long z);
|
||||
|
||||
int set_arrow (int stack_id,
|
||||
int arrows_nb,
|
||||
int space_X,
|
||||
int space_Y,
|
||||
int space_Z,
|
||||
int requested_weight,
|
||||
int site,
|
||||
int arrow_x,
|
||||
int arrow_y,
|
||||
int arrow_z);
|
||||
|
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* Gem-graph OpenGL experiments
|
||||
*
|
||||
* Desc: GL functions
|
||||
*
|
||||
* Copyright (C) 2023 Arthur Menges <arthur.menges@a-lec.org>
|
||||
* Copyright (C) 2023 Adrien Bourmault <neox@a-lec.org>
|
||||
* Copyright (C) 2023 Jean Sirmai <jean@a-lec.org>
|
||||
*
|
||||
* This file is part of Gem-graph.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "contain.h"
|
||||
#include "graph_area.h"
|
||||
#include "parsing.h"
|
||||
|
||||
#define TEST 0
|
||||
|
||||
struct graphic_stack_t *graphic_stack = NULL;
|
||||
size_t graphic_stack_size = 0;
|
||||
int *free_stack_slot = NULL;
|
||||
size_t free_stack_slot_size = 0;
|
||||
|
||||
/*
|
||||
* Prints verbose human-readable debug messages
|
||||
*
|
||||
* @param source, XXX
|
||||
* type, XXX
|
||||
* id, XXX
|
||||
* severity, XXX
|
||||
* length, XXX
|
||||
* msg, XXX
|
||||
* data, XXX
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
static void graphics_debug_callback(GLenum source, GLenum type, GLuint id,
|
||||
GLenum severity, GLsizei length,
|
||||
const GLchar *msg, const void *data)
|
||||
{
|
||||
const char *errsource;
|
||||
const char *errtype;
|
||||
const char *errseverity;
|
||||
const GLubyte *string;
|
||||
GLenum code;
|
||||
|
||||
switch (source) {
|
||||
case GL_DEBUG_SOURCE_API: errsource = "API"; break;
|
||||
case GL_DEBUG_SOURCE_WINDOW_SYSTEM: errsource = "WINDOW SYSTEM"; break;
|
||||
case GL_DEBUG_SOURCE_SHADER_COMPILER: errsource = "SHADER COMPILER"; break;
|
||||
case GL_DEBUG_SOURCE_THIRD_PARTY: errsource = "THIRD PARTY"; break;
|
||||
case GL_DEBUG_SOURCE_APPLICATION: errsource = "APPLICATION"; break;
|
||||
case GL_DEBUG_SOURCE_OTHER: errsource = "UNKNOWN"; break;
|
||||
default: errsource = "UNKNOWN"; break;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case GL_DEBUG_TYPE_ERROR: errtype = "ERROR"; break;
|
||||
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: errtype = "DEPRECATED BEHAVIOR";break;
|
||||
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: errtype = "UNDEFINED BEHAVIOR"; break;
|
||||
case GL_DEBUG_TYPE_PORTABILITY: errtype = "PORTABILITY"; break;
|
||||
case GL_DEBUG_TYPE_PERFORMANCE: errtype = "PERFORMANCE"; break;
|
||||
case GL_DEBUG_TYPE_OTHER: errtype = "OTHER"; break;
|
||||
case GL_DEBUG_TYPE_MARKER: errtype = "MARKER"; break;
|
||||
default: errtype = "UNKNOWN"; break;
|
||||
}
|
||||
|
||||
switch (severity) {
|
||||
case GL_DEBUG_SEVERITY_HIGH: errseverity = "CRITICAL"; break;
|
||||
case GL_DEBUG_SEVERITY_MEDIUM: errseverity = "ERROR"; break;
|
||||
case GL_DEBUG_SEVERITY_LOW: errseverity = "WARNING"; break;
|
||||
case GL_DEBUG_SEVERITY_NOTIFICATION: errseverity = "INFO"; break;
|
||||
default: errseverity = "UNKNOWN"; break;
|
||||
}
|
||||
|
||||
code = glGetError();
|
||||
string = gluErrorString(code);
|
||||
|
||||
g_printerr("[%s] %s (%s) from %s: %s\n",
|
||||
errseverity, string, errtype, errsource, msg);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initializes graphical stack
|
||||
*
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
*
|
||||
* @return id if initialized
|
||||
*/
|
||||
int graphics_init(void *error_buffer)
|
||||
{
|
||||
int cur_id = 0;
|
||||
struct graphic_stack_t *stack;
|
||||
|
||||
g_printerr("[debug] graphics_init()\n");
|
||||
|
||||
if (graphic_stack == NULL) {
|
||||
graphic_stack = g_malloc0(sizeof(struct graphic_stack_t));
|
||||
graphic_stack_size = 1;
|
||||
g_printerr("[debug] graphics_init(): init graphic_stack @ %p\n", graphic_stack);
|
||||
} else {
|
||||
// Check if there are free slots
|
||||
if (free_stack_slot_size) {
|
||||
// We get the last free slot registered
|
||||
cur_id = free_stack_slot[free_stack_slot_size-1];
|
||||
// Unregister it (ofc)
|
||||
free_stack_slot = g_realloc(free_stack_slot,
|
||||
free_stack_slot_size-- *
|
||||
sizeof(int));
|
||||
} else {
|
||||
cur_id = graphic_stack_size;
|
||||
graphic_stack = g_realloc(graphic_stack,
|
||||
++graphic_stack_size *
|
||||
sizeof(struct graphic_stack_t));
|
||||
}
|
||||
}
|
||||
|
||||
memset(&graphic_stack[cur_id], 0, sizeof(struct graphic_stack_t));
|
||||
|
||||
g_printerr("[debug] graphics_init() : graphic_stack (@0x%p) has %ld elements\n",
|
||||
graphic_stack,
|
||||
graphic_stack_size);
|
||||
|
||||
stack = &graphic_stack[cur_id];
|
||||
stack->id = cur_id;
|
||||
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
|
||||
if (!graphics_init_shaders(cur_id)) return -1;
|
||||
|
||||
print_stack(cur_id);
|
||||
|
||||
graphics_init_buffers(cur_id);
|
||||
|
||||
glDebugMessageCallback(graphics_debug_callback, NULL);
|
||||
|
||||
//print_stack(cur_id);
|
||||
|
||||
return cur_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Shutdowns a gl_area
|
||||
*
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
*
|
||||
* @return true if success
|
||||
*/
|
||||
bool graphics_shutdown(const int id, void *error_buffer)
|
||||
{
|
||||
struct graphic_stack_t *stack;
|
||||
|
||||
if (id >= graphic_stack_size ||
|
||||
graphic_stack_size == 0 ||
|
||||
graphic_stack == NULL)
|
||||
return false;
|
||||
|
||||
stack = &graphic_stack[id];
|
||||
|
||||
//XXX
|
||||
free(stack->arrows_ptr);
|
||||
stack->arrows_ptr = NULL;
|
||||
stack->arrows_nb = 0;
|
||||
|
||||
glDeleteBuffers(1, &stack->position_buffer);
|
||||
glDeleteBuffers(1, &stack->color_buffer);
|
||||
glDeleteProgram(stack->program);
|
||||
|
||||
g_free(stack->buffer_vertex_origin);
|
||||
g_free(stack->buffer_colors_origin);
|
||||
g_free(stack->buffer_lines_origin);
|
||||
g_free(stack->buffer_plans_origin);
|
||||
|
||||
if (graphic_stack_size == 1) {
|
||||
free(graphic_stack);
|
||||
graphic_stack = NULL;
|
||||
graphic_stack_size = 0;
|
||||
} else {
|
||||
memset(&graphic_stack[id], 0, sizeof(struct graphic_stack_t));
|
||||
free_stack_slot = g_realloc(free_stack_slot,
|
||||
++free_stack_slot_size *
|
||||
sizeof(int));
|
||||
free_stack_slot[free_stack_slot_size-1] = id;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* TODO
|
||||
* #pragma omp parallel schedule(static, 12)
|
||||
* void __attribute__((optimize("no-unroll-loops"))) main_test_graphics (void) {}
|
||||
*
|
||||
// assert : space dimensions (x,y,z) > 0
|
||||
// assert : arrows localization within space and sites
|
||||
// assert : no more than one arrow per address
|
||||
// notify : weights are replaced, NOT added (could be !)
|
||||
*
|
||||
* Init space and arrows (= initial state)
|
||||
* and allows ulterior creations, suppressions or modifications of the arrows[] array
|
||||
*
|
||||
* draws the space()
|
||||
* triggers set_arrows() that modifies the list () and draws arrows
|
||||
*
|
||||
* Initialisation du générateur pseudo-aléatoire
|
||||
* Attention, les vertex centraux de chaque unité d'espace (cube)
|
||||
* peuvent être redondants (max 6)
|
||||
*/
|
||||
void graphics_model_setup (const int stack_id)
|
||||
{
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/* I N I T I A L D A T A S P E C I F I C A T I O N */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
struct graphic_stack_t *stack = &graphic_stack[stack_id];
|
||||
char dimension;
|
||||
long space_X;
|
||||
long space_Y;
|
||||
long space_Z;
|
||||
long announced_arrows_nb;
|
||||
int density_max;
|
||||
char multiplicity;
|
||||
|
||||
dimension = model_get_dim();
|
||||
|
||||
g_print("[GRAPH DEBUG] dim = %d\n", dimension);
|
||||
|
||||
space_X = 1;
|
||||
space_Y = 1;
|
||||
space_Z = 1;
|
||||
|
||||
switch(dimension) {
|
||||
case 3:
|
||||
space_Z = model_get_dim_value("z");
|
||||
;
|
||||
case 2:
|
||||
space_Y = model_get_dim_value("y");
|
||||
;
|
||||
// even in 1D, we must be able to see a grid (or not !)
|
||||
if (!space_Y)
|
||||
space_Y = 1;
|
||||
case 1:
|
||||
space_X = model_get_dim_value("x");
|
||||
;
|
||||
if (!space_X)
|
||||
space_X = 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_print("[GRAPH DEBUG] x = %ld\n", space_X);
|
||||
g_print("[GRAPH DEBUG] y = %ld\n", space_Y);
|
||||
g_print("[GRAPH DEBUG] z = %ld\n", space_Z);
|
||||
|
||||
density_max = space_X * space_Y * space_Z;
|
||||
stack->arrows_nb = 0;
|
||||
|
||||
multiplicity = model_get_multiplicity();
|
||||
g_print("[GRAPH DEBUG] site_multiplicity = %d, density_max = %d\n", multiplicity, density_max);
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/* S P A C E D R A W I N G */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
draw_space_ridges_vertex (stack_id, stack->buffer_vertex_size, space_X, space_Y, space_Z);
|
||||
draw_space_ridges_lines (stack_id);
|
||||
draw_grids_on_space_faces_vertex (stack_id, space_X, space_Y, space_Z);
|
||||
draw_grids_on_space_faces_lines (stack_id, stack->buffer_lines_size, space_X, space_Y, space_Z);
|
||||
|
||||
stack->buffer_vertex_0_arrow = stack->buffer_vertex_size;
|
||||
stack->buffer_colors_0_arrow = stack->buffer_colors_size;
|
||||
stack->buffer_lines_0_arrow = stack->buffer_lines_size;
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/* A R R O W S D R A W I N G */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
char state_id[30] = {0};
|
||||
struct arrow_t arrow = {0};
|
||||
|
||||
assert(model_get_next_state((char *)&state_id));
|
||||
|
||||
g_print("[GRAPH DEBUG] first state is = %s\n", state_id);
|
||||
|
||||
announced_arrows_nb = model_get_state_arrows_count(state_id);
|
||||
|
||||
g_print("[GRAPH DEBUG] announced_arrows_nb is = %ld\n", announced_arrows_nb);
|
||||
|
||||
while (model_get_next_arrow(&arrow, (char *)&state_id, dimension)) {
|
||||
g_print("[GRAPH DEBUG] cur arrow has x = %d\n", arrow.x);
|
||||
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);
|
||||
}
|
||||
|
||||
if (stack->arrows_nb != announced_arrows_nb)
|
||||
g_printerr("ARGH : not all arrows have been parsed !\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
* Gem-graph OpenGL experiments
|
||||
*
|
||||
* Desc: OpenGL utils header
|
||||
*
|
||||
* Copyright (C) 2023 Arthur Menges <arthur.menges@a-lec.org>
|
||||
* Copyright (C) 2023 Adrien Bourmault <neox@a-lec.org>
|
||||
* Copyright (C) 2023 Jean Sirmai <jean@a-lec.org>
|
||||
*
|
||||
* This file is part of Gem-graph.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "base.h"
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <epoxy/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GL/glext.h>
|
||||
#include <cglm/cglm.h>
|
||||
|
||||
#define VERTEX_SHADER_FILE "src/graphics/shaders/shader.vert"
|
||||
#define FRAG_SHADER_FILE "src/graphics/shaders/shader.frag"
|
||||
#define GL_TARGET_MAJOR_VERSION 0
|
||||
#define GL_TARGET_MINOR_VERSION 4
|
||||
|
||||
/*
|
||||
* Structure describing a gl_area and its parameters, used to create a table
|
||||
* of Gem-graph client current gl_areas
|
||||
*/
|
||||
struct graphic_stack_t {
|
||||
|
||||
int id;
|
||||
int mode;
|
||||
|
||||
float rotation_angles[N_AXIS]; // Rotation angles on each axis
|
||||
|
||||
GLuint vao; // init_buffers
|
||||
GLuint position_buffer; // shutdown, draw
|
||||
GLuint color_buffer; // shutdown, draw
|
||||
GLuint program; // shutdown, init_shaders, draw
|
||||
GLuint m; // init_shaders, draw
|
||||
GLuint v; // init_shaders, draw
|
||||
GLuint p; // init_shaders, draw
|
||||
|
||||
struct arrow_t *arrows_ptr;
|
||||
long arrows_nb;
|
||||
|
||||
GLfloat *buffer_vertex_origin;
|
||||
GLfloat *buffer_colors_origin;
|
||||
GLuint *buffer_lines_origin;
|
||||
GLuint *buffer_plans_origin;
|
||||
|
||||
long buffer_vertex_size;
|
||||
long buffer_colors_size;
|
||||
long buffer_lines_size;
|
||||
long buffer_plans_size;
|
||||
|
||||
long buffer_vertex_0_arrow;
|
||||
long buffer_colors_0_arrow;
|
||||
long buffer_lines_0_arrow;
|
||||
long buffer_plans_0_arrow;
|
||||
};
|
||||
|
||||
/*
|
||||
* Dynamic array of ptrs to dynamically allocated gl_area_entry
|
||||
*/
|
||||
extern struct graphic_stack_t *graphic_stack;
|
||||
|
||||
/*
|
||||
* Initializes a gl_area
|
||||
*
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
*
|
||||
* @return true if initialized
|
||||
*/
|
||||
int graphics_init(void *error_buffer);
|
||||
|
||||
/*
|
||||
* Draws the current buffer to a gl_area
|
||||
*
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
//void graphics_draw(const int stack_id);
|
||||
|
||||
/*
|
||||
* Shutdowns a gl_area
|
||||
*
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
*
|
||||
* @return true if success
|
||||
*/
|
||||
bool graphics_shutdown(const int stack_id, void *error_buffer);
|
||||
|
||||
/*
|
||||
* Initializes the shaders of a gl_area and link them to a program
|
||||
*
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
*
|
||||
* @return true if initialized
|
||||
*/
|
||||
bool graphics_init_shaders(const int stack_id);
|
||||
|
||||
/* Initializes the buffer of a gl_area
|
||||
* Calls according to the user preferences
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
* @return void
|
||||
*/
|
||||
void graphics_init_buffers(const int stack_id);
|
||||
|
||||
/*
|
||||
* Draws a vertex (x, y, z)
|
||||
* if (console) prints (x, y, z) values to console
|
||||
*
|
||||
* @param GLfloat x, GLfloat y, GLfloat z
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void graphics_draw_vertex (const int stack_id,
|
||||
GLfloat x,
|
||||
GLfloat y,
|
||||
GLfloat z);
|
||||
|
||||
/*
|
||||
* Draws the color (r, g, b) associated to a vertex
|
||||
* if (console) prints (r, g, b) values to console
|
||||
*
|
||||
* @param GLfloat r, GLfloat g, GLfloat b
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void graphics_draw_color (const int stack_id, GLfloat r, GLfloat g, GLfloat b);
|
||||
|
||||
/*
|
||||
* Writes values to describe a line from a to b into the line buffer
|
||||
*
|
||||
* @param coords GLuint (a,b)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void graphics_draw_line (const int stack_id, GLuint a, GLuint b);
|
||||
|
||||
/*
|
||||
* Writes values to describe an (a,b,c) plan (triangle) into the plan buffer
|
||||
*
|
||||
* @param coords GLuint (a,b,c)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void graphics_draw_plan (const int stack_id, GLuint a, GLuint b, GLuint c);
|
||||
|
||||
/*
|
||||
* Created and compile a shader
|
||||
*
|
||||
* @param type, shader type
|
||||
* src, source code of shader
|
||||
*
|
||||
* @return shader id
|
||||
*/
|
||||
static inline GLuint create_shader(const int stack_id, int type, const char *src)
|
||||
{
|
||||
GLuint shader;
|
||||
int status;
|
||||
|
||||
shader = glCreateShader(type);
|
||||
glShaderSource(shader, 1, &src, NULL);
|
||||
glCompileShader(shader);
|
||||
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
if(status == GL_FALSE) {
|
||||
int log_len;
|
||||
char *buffer;
|
||||
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_len);
|
||||
|
||||
buffer = g_malloc(log_len + 1);
|
||||
assert (buffer);
|
||||
glGetShaderInfoLog(shader, log_len, NULL, buffer);
|
||||
|
||||
g_warning("Compile failure in %s shader:\n%s",
|
||||
type == GL_VERTEX_SHADER ? "vertex" : "fragment",
|
||||
buffer);
|
||||
|
||||
g_free(buffer);
|
||||
|
||||
glDeleteShader(shader);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
static inline void print_stack(int stack_id)
|
||||
{
|
||||
static int n = 0;
|
||||
|
||||
printf("\n[n=%d]***************", n);
|
||||
|
||||
printf("id = %d\tmode = %d\n",
|
||||
graphic_stack[stack_id].id,
|
||||
graphic_stack[stack_id].mode);
|
||||
|
||||
printf("rotation_angles = ");
|
||||
for (int i = 0; i < N_AXIS; i++) {
|
||||
printf("%f\t", graphic_stack[stack_id].rotation_angles[i]); // Rotation angles on each axis
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("vao = %d\n", graphic_stack[stack_id].vao);
|
||||
printf("position_buffer = %d\n", graphic_stack[stack_id].position_buffer);
|
||||
printf("color_buffer = %d\n", graphic_stack[stack_id].color_buffer);
|
||||
printf("program = %d\n", graphic_stack[stack_id].program);
|
||||
printf("m = %d\n", graphic_stack[stack_id].m);
|
||||
printf("v = %d\n", graphic_stack[stack_id].v);
|
||||
printf("p = %d\n", graphic_stack[stack_id].p);
|
||||
|
||||
printf("arrows_ptr = %p\n", graphic_stack[stack_id].arrows_ptr);
|
||||
printf("arrows_nb = %ld\n", graphic_stack[stack_id].arrows_nb);
|
||||
|
||||
printf("buffer_vertex_origin = %p\n", graphic_stack[stack_id].buffer_vertex_origin);
|
||||
printf("buffer_colors_origin = %p\n", graphic_stack[stack_id].buffer_colors_origin);
|
||||
printf("buffer_lines_origin = %p\n", graphic_stack[stack_id].buffer_lines_origin);
|
||||
printf("buffer_plans_origin = %p\n", graphic_stack[stack_id].buffer_plans_origin);
|
||||
|
||||
printf("buffer_vertex_size = %ld\n", graphic_stack[stack_id].buffer_vertex_size);
|
||||
printf("buffer_colors_size = %ld\n", graphic_stack[stack_id].buffer_colors_size);
|
||||
printf("buffer_lines_size = %ld\n", graphic_stack[stack_id].buffer_lines_size);
|
||||
printf("buffer_plans_size = %ld\n", graphic_stack[stack_id].buffer_plans_size);
|
||||
|
||||
printf("buffer_vertex_0_arrow = %ld\n", graphic_stack[stack_id].buffer_vertex_0_arrow);
|
||||
printf("buffer_colors_0_arrow = %ld\n", graphic_stack[stack_id].buffer_colors_0_arrow);
|
||||
printf("buffer_lines_0_arrow = %ld\n", graphic_stack[stack_id].buffer_lines_0_arrow);
|
||||
printf("buffer_plans_0_arrow = %ld\n", graphic_stack[stack_id].buffer_plans_0_arrow);
|
||||
|
||||
printf("********************\n");
|
||||
n++;
|
||||
}
|
||||
|
||||
|
||||
void graphics_model_setup (const int stack_id);
|
||||
|
||||
int draw_one_arrow_vertex (const int stack_id,
|
||||
int space_X,
|
||||
int space_Y,
|
||||
int space_Z,
|
||||
int weight,
|
||||
int site,
|
||||
int x,
|
||||
int y,
|
||||
int z);
|
||||
|
||||
int draw_one_arrow_line(const int stack_id,
|
||||
int offset_vertex);
|
||||
|
||||
/*
|
||||
* Writes grid ridges to vertex and color buffers
|
||||
*
|
||||
* @param coords long (x,y,z), step_x, step_y, step_z
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
int draw_space_ridges_vertex (const int stack_id,
|
||||
long offset_vertex,
|
||||
long x,
|
||||
long y,
|
||||
long z);
|
||||
|
||||
int draw_space_ridges_lines (const int stack_id);
|
||||
|
||||
/*
|
||||
* Writes grid lines on space faces
|
||||
*
|
||||
* @param coords long (x,y,z)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
long draw_grids_on_space_faces_vertex (const int stack_id,
|
||||
long x,
|
||||
long y,
|
||||
long z);
|
||||
|
||||
long draw_grids_on_space_faces_lines (const int stack_id,
|
||||
long offset_vertex,
|
||||
long x,
|
||||
long y,
|
||||
long z);
|
||||
|
||||
int set_arrow (int stack_id,
|
||||
int arrows_nb,
|
||||
int space_X,
|
||||
int space_Y,
|
||||
int space_Z,
|
||||
int requested_weight,
|
||||
int site,
|
||||
int arrow_x,
|
||||
int arrow_y,
|
||||
int arrow_z);
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Gem-graph
|
||||
*
|
||||
* Desc: OpenGL grid functions
|
||||
*
|
||||
* Copyright (C) 2023 Jean Sirmai <jean@a-lec.org>
|
||||
* Copyright (C) 2023 Adrien Bourmault <neox@a-lec.org>
|
||||
*
|
||||
* This file is part of Gem-graph.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "base.h"
|
||||
//#include "ui.h"
|
||||
#include "graphics.h"
|
||||
|
||||
int draw_space_ridges_vertex (const int stack_id,
|
||||
long offset_vertex,
|
||||
long x,
|
||||
long y,
|
||||
long z)
|
||||
{
|
||||
GLfloat max = fmax(x, y); max = fmax(max, z);
|
||||
|
||||
graphics_draw_vertex (stack_id, offset_vertex - x / max, offset_vertex - y / max, - z / max);
|
||||
|
||||
graphics_draw_vertex (stack_id, offset_vertex + x / max, offset_vertex - y / max, - z / max);
|
||||
graphics_draw_vertex (stack_id, offset_vertex - x / max, offset_vertex + y / max, - z / max);
|
||||
graphics_draw_vertex (stack_id, offset_vertex - x / max, offset_vertex - y / max, + z / max);
|
||||
|
||||
graphics_draw_vertex (stack_id, offset_vertex + x / max, offset_vertex + y / max, - z / max);
|
||||
graphics_draw_vertex (stack_id, offset_vertex + x / max, offset_vertex - y / max, + z / max);
|
||||
graphics_draw_vertex (stack_id, offset_vertex - x / max, offset_vertex + y / max, + z / max);
|
||||
|
||||
graphics_draw_vertex (stack_id, offset_vertex + x / max, + y / max, + z / max);
|
||||
|
||||
graphics_draw_color (stack_id, 0.8f, 0.6f, 0.5f);
|
||||
graphics_draw_color (stack_id, 0.8f, 0.6f, 0.5f);
|
||||
graphics_draw_color (stack_id, 0.8f, 0.6f, 0.5f);
|
||||
graphics_draw_color (stack_id, 0.8f, 0.6f, 0.5f);
|
||||
graphics_draw_color (stack_id, 0.8f, 0.6f, 0.5f);
|
||||
graphics_draw_color (stack_id, 0.8f, 0.6f, 0.5f);
|
||||
graphics_draw_color (stack_id, 0.8f, 0.6f, 0.5f);
|
||||
graphics_draw_color (stack_id, 0.8f, 0.6f, 0.5f);
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
int draw_space_ridges_lines (const int stack_id)
|
||||
{
|
||||
graphics_draw_line (stack_id, 0, 1); graphics_draw_line (stack_id, 7, 4);
|
||||
graphics_draw_line (stack_id, 0, 2); graphics_draw_line (stack_id, 7, 5);
|
||||
graphics_draw_line (stack_id, 0, 3); graphics_draw_line (stack_id, 7, 6);
|
||||
|
||||
graphics_draw_line (stack_id, 1, 4); graphics_draw_line (stack_id, 2, 4);
|
||||
graphics_draw_line (stack_id, 1, 5); graphics_draw_line (stack_id, 3, 5);
|
||||
graphics_draw_line (stack_id, 2, 6); graphics_draw_line (stack_id, 3, 6);
|
||||
|
||||
return 12;
|
||||
}
|
||||
|
||||
long draw_grids_on_space_faces_vertex (const int stack_id,
|
||||
long x,
|
||||
long y,
|
||||
long z)
|
||||
{
|
||||
float i, max = fmax(x, y); max = fmax(max, z);
|
||||
|
||||
for (i = 1; i < x; i++) {
|
||||
|
||||
graphics_draw_vertex (stack_id, (2 * i / x - 1) * x / max, - y / max, - z / max);
|
||||
graphics_draw_vertex (stack_id, (2 * i / x - 1) * x / max, - y / max, z / max);
|
||||
graphics_draw_vertex (stack_id, (2 * i / x - 1) * x / max, y / max, z / max);
|
||||
graphics_draw_vertex (stack_id, (2 * i / x - 1) * x / max, y / max, - z / max);
|
||||
|
||||
graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f);
|
||||
graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f);
|
||||
graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f);
|
||||
graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f);
|
||||
}
|
||||
|
||||
/* offset_vertex += (x - 1) * 4; */ /* offset_colors += (x - 1) * 4; */
|
||||
|
||||
for (i = 1; i < y; i++) {
|
||||
|
||||
graphics_draw_vertex (stack_id, - x / max, (2 * i / y - 1) * y / max, - z / max);
|
||||
graphics_draw_vertex (stack_id, - x / max, (2 * i / y - 1) * y / max, z / max);
|
||||
graphics_draw_vertex (stack_id, x / max, (2 * i / y - 1) * y / max, z / max);
|
||||
graphics_draw_vertex (stack_id, x / max, (2 * i / y - 1) * y / max, - z / max);
|
||||
|
||||
graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f);
|
||||
graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f);
|
||||
graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f);
|
||||
graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f);
|
||||
}
|
||||
|
||||
/* offset_vertex += (y - 1) * 4; */ /* offset_colors += (y - 1) * 4; */
|
||||
|
||||
for (i = 1; i < z; i++) {
|
||||
|
||||
graphics_draw_vertex (stack_id, - x / max, - y / max, (2 * i / z - 1) * z / max);
|
||||
graphics_draw_vertex (stack_id, - x / max, y / max, (2 * i / z - 1) * z / max);
|
||||
graphics_draw_vertex (stack_id, x / max, y / max, (2 * i / z - 1) * z / max);
|
||||
graphics_draw_vertex (stack_id, x / max, - y / max, (2 * i / z - 1) * z / max);
|
||||
|
||||
graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f);
|
||||
graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f);
|
||||
graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f);
|
||||
graphics_draw_color (stack_id, 0.55f, 0.55f, 0.55f);
|
||||
}
|
||||
|
||||
return (x + y + z - 3) * 3;
|
||||
}
|
||||
|
||||
|
||||
long draw_grids_on_space_faces_lines (const int stack_id,
|
||||
long offset_vertex,
|
||||
long x,
|
||||
long y,
|
||||
long z)
|
||||
{
|
||||
offset_vertex = offset_vertex / 3;
|
||||
|
||||
for (int i = 0; i < x - 1; i ++) {
|
||||
|
||||
graphics_draw_line (stack_id, offset_vertex + i * 4 + 1, offset_vertex + i * 4 + 2);
|
||||
graphics_draw_line (stack_id, offset_vertex + i * 4 + 2, offset_vertex + i * 4 + 3);
|
||||
}
|
||||
|
||||
offset_vertex += (x - 1) * 4;
|
||||
|
||||
for (int i = 0; i < y - 1; i ++) {
|
||||
|
||||
graphics_draw_line (stack_id, offset_vertex + i * 4 + 2, offset_vertex + i * 4 + 3);
|
||||
graphics_draw_line (stack_id, offset_vertex + i * 4 + 3, offset_vertex + i * 4 + 0);
|
||||
}
|
||||
|
||||
offset_vertex += (y - 1) * 4;
|
||||
|
||||
for (int i = 0; i < z - 1; i ++) {
|
||||
|
||||
graphics_draw_line (stack_id, offset_vertex + i * 4 + 0, offset_vertex + i * 4 + 1);
|
||||
graphics_draw_line (stack_id, offset_vertex + i * 4 + 3, offset_vertex + i * 4 + 0);
|
||||
}
|
||||
|
||||
return (x + y + z - 3) * 4;
|
||||
}
|
||||
|
After Width: | Height: | Size: 370 KiB |
After Width: | Height: | Size: 285 KiB |
After Width: | Height: | Size: 1.5 MiB |
After Width: | Height: | Size: 1.7 MiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 148 KiB |
After Width: | Height: | Size: 153 KiB |
After Width: | Height: | Size: 128 KiB |
After Width: | Height: | Size: 167 KiB |
After Width: | Height: | Size: 707 KiB |
After Width: | Height: | Size: 702 KiB |
After Width: | Height: | Size: 256 KiB |
After Width: | Height: | Size: 151 KiB |
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* Gem-graph OpenGL experiments
|
||||
*
|
||||
* Desc: GL functions
|
||||
*
|
||||
* Copyright (C) 2023 Arthur Menges <arthur.menges@a-lec.org>
|
||||
* Copyright (C) 2023 Adrien Bourmault <neox@a-lec.org>
|
||||
*
|
||||
* This file is part of Gem-graph.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "base.h"
|
||||
#include "contain.h" // instead of "ui.h"
|
||||
#include "graph_area.h"
|
||||
|
||||
/* Initializes the buffer of a gl_area
|
||||
* Calls according to the user preferences
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
* @return void
|
||||
*/
|
||||
void graphics_init_buffers(const int stack_id)
|
||||
{
|
||||
struct graphic_stack_t *stack = &graphic_stack[stack_id];
|
||||
|
||||
//XXX
|
||||
graphics_model_setup(stack_id);
|
||||
|
||||
GLuint vao, vertex_buffer, color_buffer;
|
||||
|
||||
glGenBuffers(1, &vertex_buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
stack->buffer_vertex_size *
|
||||
sizeof(stack->buffer_vertex_origin[0]),
|
||||
stack->buffer_vertex_origin,
|
||||
GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
|
||||
// colors
|
||||
glGenBuffers(1, &color_buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, color_buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, stack->buffer_colors_size *
|
||||
sizeof(stack->buffer_colors_origin[0]),
|
||||
stack->buffer_colors_origin,
|
||||
GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// We only use one VAO, so we always keep it bound
|
||||
glGenVertexArrays(1, &vao);
|
||||
glBindVertexArray(vao);
|
||||
|
||||
stack->vao = vao;
|
||||
stack->position_buffer = vertex_buffer;
|
||||
stack->color_buffer = color_buffer;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes the shaders of a gl_area and link them to a program
|
||||
*
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
*
|
||||
* @return true if initialized
|
||||
*/
|
||||
bool graphics_init_shaders(const int stack_id)
|
||||
{
|
||||
struct graphic_stack_t *stack = &graphic_stack[stack_id];
|
||||
char *vertex_shader;
|
||||
char *fragment_shader;
|
||||
int status;
|
||||
GLuint vertex = 0, fragment; // 2024-06-05 j'initialise vertex à 0 (au pif !)
|
||||
GLuint program = 0;
|
||||
GLuint m = 0;
|
||||
GLuint v = 0;
|
||||
GLuint p = 0;
|
||||
|
||||
// Load vertex shader file
|
||||
vertex_shader = read_file(VERTEX_SHADER_FILE);
|
||||
if (vertex_shader == NULL)
|
||||
return false;
|
||||
vertex = create_shader(stack_id, GL_VERTEX_SHADER, vertex_shader);
|
||||
|
||||
if(vertex == 0) {
|
||||
stack->program = 0;
|
||||
g_free(vertex_shader);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load fragment shader file
|
||||
fragment_shader = read_file(FRAG_SHADER_FILE);
|
||||
if (fragment_shader == NULL)
|
||||
return false;
|
||||
fragment = create_shader(stack_id, GL_FRAGMENT_SHADER, fragment_shader);
|
||||
|
||||
if(fragment == 0) {
|
||||
glDeleteShader(vertex);
|
||||
stack->program = 0;
|
||||
g_free(vertex_shader);
|
||||
g_free(fragment_shader);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Link shaders to program
|
||||
program = glCreateProgram();
|
||||
printf("\n------------------------------------------------------------------------------------------\n");
|
||||
printf("[debug] graphics_init_shaders() : program = %d, vertex = %d, fragment = %d\n\
|
||||
exec > ** (myprogram:-----): WARNING ** : --:--:--:---: Linking failure: (address)\n",
|
||||
program, vertex, fragment);
|
||||
|
||||
/* (myprogram:11732): WARNING **: 10:37:34.233: v plusieurs 'run' successifs
|
||||
* (myprogram:11883): WARNING **: 10:38:22.979: glLinkProgram(program); < commenté
|
||||
* (myprogram:11953): WARNING **: 10:38:46.170:
|
||||
* (myprogram:12034): WARNING **: 10:39:14.709:
|
||||
* (myprogram:12182): WARNING **: 10:40:49.788:
|
||||
* > probablement la même adresse dans la librairie 'mesa' d'OpenGL (?) */
|
||||
|
||||
glAttachShader(program, vertex);
|
||||
glAttachShader(program, fragment);
|
||||
|
||||
printf("Failed to link the graphic stack to widgets ! <> see init.c graphics_init_shaders()\n");
|
||||
printf("the error in not : vertex shader lacks `main' but : failed to link... (comment line 140)\n");
|
||||
// https://registry.khronos.org/OpenGL-Refpages/gl4/html/glLinkProgram.xhtml
|
||||
// glLinkProgram(program); // Linking failure: (address)
|
||||
printf("------------------------------------------------------------------------------------------\n");
|
||||
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &status); // Linking failure: (address)
|
||||
|
||||
if(status == GL_FALSE) {
|
||||
int log_len;
|
||||
char *buffer;
|
||||
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_len);
|
||||
|
||||
buffer = g_malloc(log_len + 1);
|
||||
assert(buffer);
|
||||
glGetProgramInfoLog(program, log_len, NULL, buffer);
|
||||
|
||||
g_warning("Linking failure:\n%s", buffer);
|
||||
|
||||
g_free(buffer);
|
||||
|
||||
glDeleteProgram(program);
|
||||
program = 0;
|
||||
|
||||
glDeleteShader(vertex);
|
||||
glDeleteShader(fragment);
|
||||
|
||||
g_free(vertex_shader);
|
||||
g_free(fragment_shader);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get the location of the "mvp" uniform */
|
||||
m = glGetUniformLocation(program, "model_matrix");
|
||||
v = glGetUniformLocation(program, "view_matrix");
|
||||
p = glGetUniformLocation(program, "projection_matrix");
|
||||
|
||||
glDetachShader(program, vertex);
|
||||
glDetachShader(program, fragment);
|
||||
|
||||
glDeleteShader(vertex);
|
||||
glDeleteShader(fragment);
|
||||
|
||||
stack->program = program;
|
||||
stack->m = m;
|
||||
stack->v = v;
|
||||
stack->p = p;
|
||||
|
||||
g_free(vertex_shader);
|
||||
g_free(fragment_shader);
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Gem-graph OpenGL experiments
|
||||
*
|
||||
* Desc: GL functions
|
||||
*
|
||||
* Copyright (C) 2023 Arthur Menges <arthur.menges@a-lec.org>
|
||||
* Copyright (C) 2023 Adrien Bourmault <neox@a-lec.org>
|
||||
*
|
||||
* This file is part of Gem-graph.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "base.h"
|
||||
#include "contain.h" // instead of "ui.h"
|
||||
#include "graph_area.h"
|
||||
|
||||
/* Initializes the buffer of a gl_area
|
||||
* Calls according to the user preferences
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
* @return void
|
||||
*/
|
||||
void graphics_init_buffers(const int stack_id)
|
||||
{
|
||||
struct graphic_stack_t *stack = &graphic_stack[stack_id];
|
||||
|
||||
//XXX
|
||||
graphics_model_setup(stack_id);
|
||||
|
||||
GLuint vao, vertex_buffer, color_buffer;
|
||||
|
||||
glGenBuffers(1, &vertex_buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
stack->buffer_vertex_size *
|
||||
sizeof(stack->buffer_vertex_origin[0]),
|
||||
stack->buffer_vertex_origin,
|
||||
GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
|
||||
// colors
|
||||
glGenBuffers(1, &color_buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, color_buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, stack->buffer_colors_size *
|
||||
sizeof(stack->buffer_colors_origin[0]),
|
||||
stack->buffer_colors_origin,
|
||||
GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// We only use one VAO, so we always keep it bound
|
||||
glGenVertexArrays(1, &vao);
|
||||
glBindVertexArray(vao);
|
||||
|
||||
stack->vao = vao;
|
||||
stack->position_buffer = vertex_buffer;
|
||||
stack->color_buffer = color_buffer;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes the shaders of a gl_area and link them to a program
|
||||
*
|
||||
* @param gl_area, ptr to the gl_area widget
|
||||
*
|
||||
* @return true if initialized
|
||||
*/
|
||||
bool graphics_init_shaders(const int stack_id)
|
||||
{
|
||||
struct graphic_stack_t *stack = &graphic_stack[stack_id];
|
||||
char *vertex_shader;
|
||||
char *fragment_shader;
|
||||
int status;
|
||||
GLuint vertex = 0, fragment; // 2024-06-05 j'initialise vertex à 0 (au pif !)
|
||||
GLuint program = 0;
|
||||
GLuint m = 0;
|
||||
GLuint v = 0;
|
||||
GLuint p = 0;
|
||||
|
||||
// Load vertex shader file
|
||||
vertex_shader = read_file(VERTEX_SHADER_FILE);
|
||||
if (vertex_shader == NULL)
|
||||
return false;
|
||||
vertex = create_shader(stack_id, GL_VERTEX_SHADER, vertex_shader);
|
||||
|
||||
if(vertex == 0) {
|
||||
stack->program = 0;
|
||||
g_free(vertex_shader);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load fragment shader file
|
||||
fragment_shader = read_file(FRAG_SHADER_FILE);
|
||||
if (fragment_shader == NULL)
|
||||
return false;
|
||||
fragment = create_shader(stack_id, GL_FRAGMENT_SHADER, fragment_shader);
|
||||
|
||||
if(fragment == 0) {
|
||||
glDeleteShader(vertex);
|
||||
stack->program = 0;
|
||||
g_free(vertex_shader);
|
||||
g_free(fragment_shader);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Link shaders to program
|
||||
program = glCreateProgram();
|
||||
glAttachShader(program, vertex);
|
||||
glAttachShader(program, fragment);
|
||||
|
||||
glLinkProgram(program);
|
||||
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &status);
|
||||
|
||||
if(status == GL_FALSE) {
|
||||
int log_len;
|
||||
char *buffer;
|
||||
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_len);
|
||||
|
||||
buffer = g_malloc(log_len + 1);
|
||||
assert(buffer);
|
||||
glGetProgramInfoLog(program, log_len, NULL, buffer);
|
||||
|
||||
g_warning("Linking failure:\n%s", buffer);
|
||||
|
||||
g_free(buffer);
|
||||
|
||||
glDeleteProgram(program);
|
||||
program = 0;
|
||||
|
||||
glDeleteShader(vertex);
|
||||
glDeleteShader(fragment);
|
||||
|
||||
g_free(vertex_shader);
|
||||
g_free(fragment_shader);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get the location of the "mvp" uniform */
|
||||
m = glGetUniformLocation(program, "model_matrix");
|
||||
v = glGetUniformLocation(program, "view_matrix");
|
||||
p = glGetUniformLocation(program, "projection_matrix");
|
||||
|
||||
glDetachShader(program, vertex);
|
||||
glDetachShader(program, fragment);
|
||||
|
||||
glDeleteShader(vertex);
|
||||
glDeleteShader(fragment);
|
||||
|
||||
stack->program = program;
|
||||
stack->m = m;
|
||||
stack->v = v;
|
||||
stack->p = p;
|
||||
|
||||
g_free(vertex_shader);
|
||||
g_free(fragment_shader);
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,73 +1,26 @@
|
|||
/* main.c
|
||||
*
|
||||
* Copyright 2024 Jean
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
/******************************************************************************/
|
||||
/* */
|
||||
/* E coli by David S. Goodsell (2009) */
|
||||
/* --- */
|
||||
/* Let this freeze frame guide us towards the model */
|
||||
/* that alone can account for the phenomenon ! */
|
||||
/* */
|
||||
/******************************************************************************/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "callback.h"
|
||||
|
||||
static void
|
||||
print_hello (GtkWidget *widget,
|
||||
gpointer data)
|
||||
{
|
||||
g_print ("Hello World\n");
|
||||
}
|
||||
|
||||
static void
|
||||
activate (GtkApplication *app,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *button;
|
||||
GtkWidget *box;
|
||||
|
||||
window = gtk_application_window_new (app);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Window");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_set_halign (box, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (box, GTK_ALIGN_CENTER);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
|
||||
button = gtk_button_new_with_label ("Hello World");
|
||||
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window);
|
||||
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char **argv)
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
GtkApplication *app;
|
||||
int status;
|
||||
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
|
||||
app = gtk_application_new ("org.jean.GTK4_GG_hack", G_APPLICATION_DEFAULT_FLAGS);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (on_main_window_activation), NULL);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (on_dialog_window_activation), NULL);
|
||||
status = g_application_run (G_APPLICATION (app), argc, argv);
|
||||
g_object_unref (app);
|
||||
|
||||
printf("in contain.get_SPACE_VIEW_box() (line 138) > ui_setup_glarea (0, GTK_WIDGET (middle_box)); < commented 2024/06/27 > TODO\n");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
;;
|
||||
;; Dépendances sous GNU Guix
|
||||
;;
|
||||
|
||||
|
||||
(specifications->manifest
|
||||
(list
|
||||
"bash"
|
||||
"coreutils"
|
||||
"gcc-toolchain"
|
||||
"pkg-config"
|
||||
"valgrind"
|
||||
"findutils"
|
||||
"gdb"
|
||||
"make"
|
||||
"gtk"
|
||||
"libxml2"
|
||||
"glu"
|
||||
"glew"
|
||||
"glfw"
|
||||
"cglm"
|
||||
"libepoxy"
|
||||
"pango@1.90.0"
|
||||
"xorgproto"
|
||||
"glib"
|
||||
"mesa-headers"
|
||||
"mesa"
|
||||
"libadwaita"
|
||||
)
|
||||
)
|
|
@ -0,0 +1,481 @@
|
|||
/*
|
||||
* Gem-graph client
|
||||
*
|
||||
* Desc: Model parsing functions
|
||||
*
|
||||
* Copyright (C) 2023 Jean Sirmai <jean@a-lec.org>
|
||||
* Copyright (C) 2024 Adrien Bourmault <neox@a-lec.org>
|
||||
*
|
||||
* This file is part of Gem-graph.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/xmlreader.h> // http://xmlsoft.org/examples/#parse1.c
|
||||
// https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/general.html
|
||||
|
||||
#include "base.h"
|
||||
|
||||
#define READ_SITE 1 << 0
|
||||
#define READ_WEIGHT 1 << 1
|
||||
#define READ_X 1 << 2
|
||||
#define READ_Y 1 << 3
|
||||
#define READ_Z 1 << 4
|
||||
#define SUCCESSFUL_READ_ARROW_X (READ_SITE | READ_WEIGHT | READ_X)
|
||||
#define SUCCESSFUL_READ_ARROW_XY (READ_SITE | READ_WEIGHT | READ_X | READ_Y)
|
||||
#define SUCCESSFUL_READ_ARROW_XYZ (READ_SITE | READ_WEIGHT | READ_X | READ_Y | READ_Z)
|
||||
|
||||
static xmlDocPtr model;
|
||||
static xmlHashTablePtr model_hashtable;
|
||||
|
||||
bool model_init(const char *content, size_t length, const char *basename)
|
||||
{
|
||||
xmlNode *node;
|
||||
|
||||
/*
|
||||
* this initialize the library and check potential ABI mismatches
|
||||
* between the version it was compiled for and the actual shared
|
||||
* library used.
|
||||
*/
|
||||
LIBXML_TEST_VERSION
|
||||
|
||||
model = xmlReadMemory(content, length, basename, NULL, 0);
|
||||
|
||||
if (model == NULL ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
node = xmlDocGetRootElement(model);
|
||||
|
||||
if (node == NULL) {
|
||||
g_printerr("Empty XML model !\n");
|
||||
xmlFreeDoc(model);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xmlStrcmp(node->name, (xmlChar *) "gem-graph-model")) {
|
||||
g_printerr("document of the wrong type, root node != gem-graph-model\n");
|
||||
xmlFreeDoc(model);
|
||||
return false;
|
||||
}
|
||||
|
||||
model_hashtable = xmlHashCreate(0);
|
||||
|
||||
if (model_hashtable == NULL) {
|
||||
g_printerr("Can't create model hash table !\n");
|
||||
xmlFreeDoc(model);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool model_shutdown(void)
|
||||
{
|
||||
xmlFreeDoc(model);
|
||||
xmlHashFree(model_hashtable, NULL);
|
||||
|
||||
// Cleanup function for the XML library
|
||||
xmlCleanupParser();
|
||||
|
||||
// This is to debug memory for regression tests
|
||||
xmlMemoryDump();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static inline xmlNodePtr getNextChild(xmlNodePtr node, xmlChar *last)
|
||||
{
|
||||
while (node != NULL && xmlStrcmp(node->name, last)) {
|
||||
// //printf(" <>--- line n°%lu <%s>\n", xmlGetLineNo(node), node->name);
|
||||
node = node->next;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
static inline xmlChar* splitStrAtSlash(xmlChar *toSplit)
|
||||
{
|
||||
toSplit = (xmlChar *)xmlStrchr(toSplit, '/');
|
||||
toSplit = xmlStrsub (toSplit, 1, xmlStrlen(toSplit));
|
||||
return toSplit;
|
||||
}
|
||||
|
||||
static inline xmlChar* getFirstTag(xmlChar *path)
|
||||
{
|
||||
xmlChar *preop = path;
|
||||
path = (xmlChar *)xmlStrchr(path, '/');
|
||||
path = xmlStrsub (path, 1, xmlStrlen(path));
|
||||
|
||||
//printf("%s = %s + / + %s\n", preop, xmlStrsub (preop, 0, xmlStrlen(preop) - xmlStrlen(path) - 1), path);
|
||||
|
||||
return xmlStrsub (preop, 0, xmlStrlen(preop) - xmlStrlen(path) - 1);
|
||||
}
|
||||
|
||||
static inline xmlChar* getLastTag(xmlChar *path)
|
||||
{
|
||||
while ((ulong)xmlStrchr (path, '/'))
|
||||
path = splitStrAtSlash((xmlChar *)path);
|
||||
|
||||
// //printf("last tag in the path = <%s>\n", path);
|
||||
return path; // which is no more the given path but only its last tag !
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static xmlNodePtr model_get_node(xmlChar *path)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
xmlChar *extrait;
|
||||
xmlChar *reste, *last;
|
||||
|
||||
// Lookup for node from path in hash table
|
||||
node = xmlHashLookup(model_hashtable, path);
|
||||
|
||||
// Found a node in hash table
|
||||
if (node) {
|
||||
return node;
|
||||
|
||||
// no node found in hash table
|
||||
} else {
|
||||
reste = path;
|
||||
last = getLastTag(reste);
|
||||
node = xmlDocGetRootElement(model);
|
||||
|
||||
while (xmlStrchr (reste, '/')) {
|
||||
extrait = getFirstTag(reste);
|
||||
reste = splitStrAtSlash((xmlChar *)reste);
|
||||
node = node->xmlChildrenNode;
|
||||
node = getNextChild(node, extrait);
|
||||
}
|
||||
|
||||
if(node && xmlStrcmp(node->name, last)) {
|
||||
node = node->xmlChildrenNode;
|
||||
|
||||
while (node && xmlStrcmp(node->name, last)) {
|
||||
node = node->next;
|
||||
}
|
||||
xmlHashAddEntry (model_hashtable, path, node);
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static inline long model_get_node_long_attrib(xmlNodePtr node, char *id)
|
||||
{
|
||||
xmlAttr *attribute;
|
||||
xmlChar* value;
|
||||
long ret_value;
|
||||
|
||||
if (node && node->properties) {
|
||||
attribute = node->properties;
|
||||
while(attribute && attribute->name && attribute->children) {
|
||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)id)) {
|
||||
value = xmlNodeListGetString(node->doc, attribute->children, 1);
|
||||
ret_value = strtol((char *)value, NULL, 0);
|
||||
xmlFree(value);
|
||||
return ret_value;
|
||||
}
|
||||
attribute = attribute->next;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool model_get_node_str_attrib(xmlNodePtr node,
|
||||
char *id,
|
||||
char *dest)
|
||||
{
|
||||
xmlAttr *attribute;
|
||||
xmlChar* value;
|
||||
|
||||
if (node && node->properties) {
|
||||
attribute = node->properties;
|
||||
while(attribute && attribute->name && attribute->children) {
|
||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)id)) {
|
||||
value = xmlNodeListGetString(node->doc, attribute->children, 1);
|
||||
strcpy(dest, (char *)value);
|
||||
xmlFree(value);
|
||||
return true;
|
||||
}
|
||||
attribute = attribute->next;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
char model_get_dim(void)
|
||||
{
|
||||
// xmlAttr *attribute;
|
||||
// xmlChar* value;
|
||||
xmlNodePtr node = model_get_node(
|
||||
(xmlChar *)"parameters/space-param/dimension");
|
||||
|
||||
if (xmlHasProp (node, (xmlChar *) "z")) return 3;
|
||||
if (xmlHasProp (node, (xmlChar *) "y")) return 2;
|
||||
if (xmlHasProp (node, (xmlChar *) "x")) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
long model_get_dim_value(const char *axis)
|
||||
{
|
||||
// xmlAttr *attribute;
|
||||
// xmlChar *value;
|
||||
// long ret_value;
|
||||
xmlNodePtr node = model_get_node(
|
||||
(xmlChar *)"parameters/space-param/dimension");
|
||||
|
||||
return model_get_node_long_attrib(node, (char *)axis);
|
||||
}
|
||||
|
||||
char model_get_multiplicity(void)
|
||||
{
|
||||
// xmlAttr *attribute;
|
||||
// xmlChar* value;
|
||||
xmlNodePtr node = model_get_node(
|
||||
(xmlChar *)"parameters/space-param/site_multiplicity");
|
||||
|
||||
if (node->children)
|
||||
if (node->children->content)
|
||||
return (char)strtol((char *)node->children->content, NULL, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool model_get_next_state(char *new_state_id)
|
||||
{
|
||||
static xmlNodePtr cur_node = NULL;
|
||||
// xmlAttr *attribute;
|
||||
// xmlChar *value;
|
||||
|
||||
if (cur_node == NULL) {
|
||||
// Get first state
|
||||
cur_node = model_get_node((xmlChar *)"savedstates/state");
|
||||
|
||||
} else {
|
||||
// Get next state
|
||||
if (cur_node->next)
|
||||
cur_node = cur_node->next;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// Lookup in properties
|
||||
if (model_get_node_str_attrib(cur_node, "id", new_state_id))
|
||||
return true;
|
||||
|
||||
cur_node = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
long model_get_state_arrows_count(const char *state_id)
|
||||
{
|
||||
xmlNodePtr cur_node = NULL;
|
||||
// xmlAttr *attribute;
|
||||
long value = 0;
|
||||
bool found = false;
|
||||
char temp_char[25];
|
||||
// uint check = 0; // bit field checker
|
||||
|
||||
//printf("NEW CALL : cur_node = %p\n", cur_node);
|
||||
|
||||
assert(state_id);
|
||||
|
||||
// Get first state node
|
||||
cur_node = model_get_node((xmlChar *)"savedstates/state");
|
||||
|
||||
// Lookup in properties
|
||||
while (cur_node && cur_node->properties) {
|
||||
// attribute = cur_node->properties; < usage ?
|
||||
|
||||
// Look for the id attribute
|
||||
if (model_get_node_str_attrib(cur_node, "id", (char *)&temp_char)) {
|
||||
if (!xmlStrcmp((const xmlChar *)temp_char, (const xmlChar *)state_id)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cur_node = cur_node->next;
|
||||
}
|
||||
|
||||
// Check if the state has been found
|
||||
if (!found) {
|
||||
cur_node = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Count arrows
|
||||
if (cur_node->children) {
|
||||
cur_node = cur_node->children;
|
||||
while (cur_node) {
|
||||
if (!xmlStrcmp(cur_node->name, (const xmlChar *)"arrow"))
|
||||
value++;
|
||||
cur_node = cur_node->next;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool model_get_next_arrow(struct arrow_t *new_arrow,
|
||||
const char *state_id,
|
||||
char dimension)
|
||||
{
|
||||
static xmlNodePtr cur_node = NULL;
|
||||
xmlAttr *attribute;
|
||||
xmlChar *value;
|
||||
bool found = false;
|
||||
char temp_char[25];
|
||||
uint check = 0; // bit field checker
|
||||
|
||||
//printf("NEW CALL : cur_node = %p\n", cur_node);
|
||||
|
||||
assert(new_arrow);
|
||||
assert(state_id);
|
||||
|
||||
if (cur_node == NULL) {
|
||||
// Get first state node
|
||||
cur_node = model_get_node((xmlChar *)"savedstates/state");
|
||||
|
||||
// Lookup in properties
|
||||
while (cur_node && cur_node->properties) {
|
||||
attribute = cur_node->properties;
|
||||
|
||||
// Look for the id attribute
|
||||
if (model_get_node_str_attrib(cur_node, "id", (char *)&temp_char)) {
|
||||
if (!xmlStrcmp((xmlChar *)temp_char, (const xmlChar *)state_id)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cur_node = cur_node->next;
|
||||
}
|
||||
|
||||
// Check if the state has been found
|
||||
if (!found) {
|
||||
cur_node = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get first arrow
|
||||
if (cur_node->children) {
|
||||
cur_node = cur_node->children;
|
||||
|
||||
found = false;
|
||||
while (cur_node && cur_node->name) {
|
||||
if (!xmlStrcmp(cur_node->name, (const xmlChar *)"arrow")) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
cur_node = cur_node->next;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the state has been found
|
||||
if (!found) {
|
||||
cur_node = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Get next arrow
|
||||
found = false;
|
||||
while (cur_node->next) {
|
||||
cur_node = cur_node->next;
|
||||
if (!xmlStrcmp(cur_node->name, (const xmlChar *)"arrow")) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the state has been found
|
||||
if (!found) {
|
||||
cur_node = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//printf("DURING CALL : cur_node = %p\n", cur_node);
|
||||
//printf("DURING CALL : cur_node->name = %s\n", cur_node->name);
|
||||
|
||||
// Lookup in properties
|
||||
if (cur_node && cur_node->properties) {
|
||||
attribute = cur_node->properties;
|
||||
|
||||
while(attribute && attribute->name && attribute->children) {
|
||||
//printf("attr name : %s\n", attribute->name);
|
||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"site")) {
|
||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
||||
new_arrow->site = strtol((char *)value, NULL, 0);
|
||||
xmlFree(value);
|
||||
check |= READ_SITE;
|
||||
}
|
||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"weight")) {
|
||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
||||
new_arrow->load = strtol((char *)value, NULL, 0);
|
||||
xmlFree(value);
|
||||
check |= READ_WEIGHT;
|
||||
}
|
||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"x")) {
|
||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
||||
new_arrow->x = strtol((char *)value, NULL, 0);
|
||||
xmlFree(value);
|
||||
check |= READ_X;
|
||||
}
|
||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"y")) {
|
||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
||||
new_arrow->y = strtol((char *)value, NULL, 0);
|
||||
xmlFree(value);
|
||||
check |= READ_Y;
|
||||
}
|
||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"z")) {
|
||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
||||
new_arrow->z = strtol((char *)value, NULL, 0);
|
||||
xmlFree(value);
|
||||
check |= READ_Z;
|
||||
}
|
||||
attribute = attribute->next;
|
||||
}
|
||||
|
||||
switch(dimension) {
|
||||
case 3:
|
||||
return (bool)(check & SUCCESSFUL_READ_ARROW_XYZ);
|
||||
case 2:
|
||||
return (bool)(check & SUCCESSFUL_READ_ARROW_XY);
|
||||
case 1:
|
||||
return (bool)(check & SUCCESSFUL_READ_ARROW_X);
|
||||
}
|
||||
}
|
||||
cur_node = NULL;
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Gem-graph OpenGL experiments
|
||||
*
|
||||
* Desc: Model parsing header
|
||||
*
|
||||
* Copyright (C) 2023 Arthur Menges <arthur.menges@a-lec.org>
|
||||
* Copyright (C) 2023 Adrien Bourmault <neox@a-lec.org>
|
||||
*
|
||||
* This file is part of Gem-graph.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <unistd.h>
|
||||
#include "base.h"
|
||||
|
||||
bool model_init(const char *content, size_t length, const char *basename);
|
||||
bool model_shutdown(void);
|
||||
|
||||
char model_get_dim(void);
|
||||
long model_get_dim_value(const char *axis);
|
||||
char model_get_multiplicity(void);
|
||||
bool model_get_next_state(char *new_state_id);
|
||||
bool model_get_next_arrow(struct arrow_t *new_arrow,
|
||||
const char *state_id,
|
||||
char dimension);
|
||||
|
||||
long model_get_state_arrows_count(const char *state_id);
|
||||
bool model_get_next_arrow(struct arrow_t *new_arrow,
|
||||
const char *state_id,
|
||||
char dimension);
|
|
@ -0,0 +1,9 @@
|
|||
#version 330 core
|
||||
|
||||
in vec4 color;
|
||||
out vec4 out_frag_color;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
out_frag_color = color;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#version 330 core
|
||||
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat4 model_matrix;
|
||||
uniform mat4 view_matrix;
|
||||
|
||||
layout(location=0) in vec3 in_position;
|
||||
layout(location=1) in vec3 in_color;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
float zoom = 1.1f, chrominance = 1, luminance = 1;
|
||||
gl_Position =
|
||||
projection_matrix * view_matrix * model_matrix * vec4(in_position, zoom);
|
||||
color = vec4 (chrominance * in_color.rgb, luminance);
|
||||
}
|
||||
|
||||
// https://learnopengl.com/Getting-started/Shaders
|
|
@ -0,0 +1,48 @@
|
|||
/******************************************************************************/
|
||||
/* */
|
||||
/* E coli by David S. Goodsell (2009) */
|
||||
/* --- */
|
||||
/* Let this freeze frame guide us towards the model */
|
||||
/* that alone can account for the phenomenon ! */
|
||||
/* */
|
||||
/******************************************************************************/
|
||||
|
||||
char *get_space_run_edit_specif(){ return "\n\
|
||||
>>> Dans : [space_page - mode RUN] doivent être : ------------------------------------------------------\n\n\
|
||||
(1) les commandes de mouvement:\n\
|
||||
- run/stop, slow down/speed up, step by step, do/undo/redo\n\
|
||||
+ le buffer [elapsed time] qui montre le temps de simulation écoulé\n\n\
|
||||
(2) les commandes qui modifient la perception de l'espace (la caméra)\n\
|
||||
- son orientation (X,Y,Z),\n\
|
||||
+ l'orientation (X,Y,Z) de l'état dans l'espace (six possibilités),\n\
|
||||
+ le zoom,\n\
|
||||
+ les paramètres qui définissent la perspective (distances oeil/écran, écran/objet virtuel) \n\n\
|
||||
(3) les commandes qui modifient les apparences des objets et des situations d'intérêt\n\
|
||||
(+/- transparents, colorés, etc.)\n\n\
|
||||
(4) les commandes qui modifient l'apparence de l'espace (grilles, +/- surfaces, aspect des flèches, etc.)\n\n\
|
||||
(0) NB >>> AUCUNE COMMANDE NE DOIT PERMETTRE D'ÉDITER L'ESPACE ! <<<\n\n\n\
|
||||
>>> Dans : [space_page - mode EDIT] doivent être : ------------------------------------------------------\n\n\
|
||||
(1) les commandes qui modifient la perception de l'espace (la caméra)\n\
|
||||
- son orientation (X,Y,Z),\n\
|
||||
+ l'orientation (X,Y,Z) de l'état dans l'espace (six possibilités),\n\
|
||||
+ le zoom,\n\
|
||||
+ les paramètres qui définissent la perspective (distances oeil/écran, écran/objet virtuel) \n\n\
|
||||
(2) les commandes qui modifient les apparences des objets et des situations d'intérêt\n\
|
||||
(+/- transparents, colorés, etc.)\n\n\
|
||||
(3) les commandes qui modifient l'apparence de l'espace (grilles, +/- surfaces, aspect des flèches, etc.)\n\n\
|
||||
(4) les commandes d'édition locales (drag and drop une flèche)\n\
|
||||
('faire de la place' pour insérer)\n\
|
||||
(sélectionner pour déplacer ou enlever...)\n\
|
||||
NB ces commandes doivent être graphiques et/ou accessibles par raccourcis ou en ligne\n\n\
|
||||
(5) les commandes d'édition globales\n\
|
||||
(ex: introduire, retirer, transformer +/-aléatoirement (n) objets dans l'espace)\n\n\n\
|
||||
NB une action effectuée sur une zone d'intérêt devrait pouvoir être automatiquement appliquée\n\
|
||||
à d'autres zones d'intérêt identifiées comme similaires\n\n\
|
||||
(0) NB >>> AUCUNE COMMANDE NE DOIT PERMETTRE D'EXÉCUTER UN RUN ! <<<\n\n\n\
|
||||
>>> L'objectif est que l'utilisateur ait accès à une organsisation aussi ergonomique que possible -----\n\n\
|
||||
i.e : chaque utilisateur devrait disposer de 'préférences'\n\
|
||||
c'est-à-dire avoir la possiblité de faire des choix ergonomiques personnalisés.\n\
|
||||
";}
|
||||
|
||||
char *get_rules_run_edit_specif(){ return "\n\
|
||||
";}
|
|
@ -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.
|
||||
*/
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
#include <stdio.h>
|
||||
#include <gtk-4.0/gtk/gtk.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "contain.h"
|
||||
#include "texts.h"
|
||||
#include "callback.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
|
||||
|
||||
struct TreeNode_t {gchar *text; struct TreeNode_t *child, *next;};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 let_us_create_a_complex_useless_and_expensive_tree (struct TreeNode_t *tree_root) {
|
||||
struct TreeNode_t *a = create_user_tree_node("We, the people");add_child_node(tree_root, a);
|
||||
struct TreeNode_t *b = create_user_tree_node("in Order to"); add_child_node(tree_root, b);
|
||||
struct TreeNode_t *c = create_user_tree_node("do establish"); add_child_node(tree_root, c);
|
||||
struct TreeNode_t *aa = create_user_tree_node("aware of"); add_child_node(a, aa);
|
||||
struct TreeNode_t *aaa = create_user_tree_node("our rights"); add_child_node(aa, aaa);
|
||||
struct TreeNode_t *aab = create_user_tree_node("our duties"); add_child_node(aa, aab);
|
||||
struct TreeNode_t *aaaa = create_user_tree_node("read"); add_child_node(aaa, aaaa);
|
||||
struct TreeNode_t *aaab = create_user_tree_node("write"); add_child_node(aaa, aaab);
|
||||
struct TreeNode_t *aaac = create_user_tree_node("copy"); add_child_node(aaa, aaac);
|
||||
struct TreeNode_t *aaad = create_user_tree_node("edit"); add_child_node(aaa, aaad);
|
||||
struct TreeNode_t *aaaba= create_user_tree_node("code"); add_child_node(aaab, aaaba);
|
||||
struct TreeNode_t *aaabb= create_user_tree_node("language"); add_child_node(aaab, aaabb);
|
||||
struct TreeNode_t *aaabc= create_user_tree_node("any art..."); add_child_node(aaab, aaabc);
|
||||
struct TreeNode_t *aaadb= create_user_tree_node("publish"); add_child_node(aaac, aaadb);
|
||||
struct TreeNode_t *aaada= create_user_tree_node("create"); add_child_node(aaad, aaada);
|
||||
struct TreeNode_t *aaba = create_user_tree_node("learn"); add_child_node(aab, aaba);
|
||||
struct TreeNode_t *aabb = create_user_tree_node("help"); add_child_node(aab, aabb);
|
||||
struct TreeNode_t *ba = create_user_tree_node("promote"); add_child_node(b, ba);
|
||||
struct TreeNode_t *bb = create_user_tree_node("individual"); add_child_node(b, bb);
|
||||
struct TreeNode_t *bc = create_user_tree_node("and common"); add_child_node(b, bc);
|
||||
struct TreeNode_t *bca = create_user_tree_node("education"); add_child_node(bc, bca);
|
||||
struct TreeNode_t *bcb = create_user_tree_node("mutual"); add_child_node(bc, bcb);
|
||||
struct TreeNode_t *bcc = create_user_tree_node("support"); add_child_node(bc, bcc);
|
||||
struct TreeNode_t *bcd = create_user_tree_node("health"); add_child_node(bc, bcd);
|
||||
struct TreeNode_t *bcda = create_user_tree_node("mental"); add_child_node(bcd, bcda);
|
||||
struct TreeNode_t *bcdb = create_user_tree_node("physical"); add_child_node(bcd, bcdb);
|
||||
struct TreeNode_t *ca = create_user_tree_node("free"); add_child_node(c, ca);
|
||||
struct TreeNode_t *cb = create_user_tree_node("code"); add_child_node(c, cb);
|
||||
struct TreeNode_t *cc = create_user_tree_node("access"); add_child_node(c, cc);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
GtkScrolledWindow *get_user_rules_tree ()
|
||||
{
|
||||
struct TreeNode_t *tree_root = create_user_tree_node("root");
|
||||
let_us_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;
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/******************************************************************************/
|
||||
/* */
|
||||
/* 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 // < WTF !?
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <glib-2.0/glib.h>
|
||||
#include <gtk-4.0/gtk/gtk.h>
|
||||
|
||||
//#include "cold.h"
|
||||
#include "display.h"
|
||||
#include "contain.h"
|
||||
|
||||
|
||||
// https://blog.gtk.org/2020/09/08/on-list-models/ < TODO
|
||||
|
||||
GtkScrolledWindow *get_user_rules_tree ();
|
||||
void set_run_edit_mode(int prescribed_mode);
|
||||
int get_run_edit_mode();
|
||||
GListModel* get_user_tree_model (GObject *item, gpointer root);
|
||||
void on_setup_user_tree_factory (GtkSignalListItemFactory *factory,
|
||||
GObject* object, gpointer user_data);
|
||||
|