un point sur la répartition client/serveur (à lire dans 'main')
This commit is contained in:
parent
754230cd71
commit
16bfcdd4df
|
@ -52,6 +52,7 @@ typedef struct tool_list {int value; struct tool_list *suiv;} tool_list ;
|
||||||
typedef struct data_list {int value; struct data_list *suiv;} data_list ;
|
typedef struct data_list {int value; struct data_list *suiv;} data_list ;
|
||||||
typedef struct disp_list {int value; struct disp_list *suiv;} disp_list ;
|
typedef struct disp_list {int value; struct disp_list *suiv;} disp_list ;
|
||||||
typedef struct journal {int value; struct journal *prev;} journal;
|
typedef struct journal {int value; struct journal *prev;} journal;
|
||||||
|
// ref: sudo cat /var/log/messages
|
||||||
|
|
||||||
void fsm_init(); // def: fsm/dispatch; call: main;
|
void fsm_init(); // def: fsm/dispatch; call: main;
|
||||||
void fsm_preferences_init(); // def: fsm/prefer; call: fsm/dispatch;
|
void fsm_preferences_init(); // def: fsm/prefer; call: fsm/dispatch;
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* A journal (a pile) stores chronologically the fsm events */
|
/* A journal (a pile) stores chronologically the fsm events */
|
||||||
/* during a session run (rules exec, mainly) */
|
/* during a session run (rules exec, mainly) */
|
||||||
|
/* */
|
||||||
|
/* A session starts when the main window opens and ends when it closes. */
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -60,13 +60,13 @@
|
||||||
|
|
||||||
void fsm_init()
|
void fsm_init()
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
fsm_measures_list_init();
|
fsm_measures_list_init();
|
||||||
fsm_results_list_init();
|
fsm_results_list_init();
|
||||||
fsm_displayable_list_init();
|
fsm_displayable_list_init();
|
||||||
fsm_preferences_init();
|
fsm_preferences_init();
|
||||||
*/
|
|
||||||
fsm_engine_init(); // pour avancer, en attendant... 😇️
|
// fsm_engine_init(); // pour avancer, en attendant... 😇️
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -62,39 +62,40 @@ static void proto_proto_proto_engine()
|
||||||
(milliseconds % 1000) * 1000000 /* nano (Must be in range of 0 to 999999999) */
|
(milliseconds % 1000) * 1000000 /* nano (Must be in range of 0 to 999999999) */
|
||||||
};
|
};
|
||||||
while (true) {
|
while (true) {
|
||||||
printf("x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf("x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("-O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("---O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("--- -O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("- - - O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" - - O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("- O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" x. \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" O. \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" .x \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" .O \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" . x \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" . O \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" . x \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" . O \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" . x \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" . O \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" . x \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" . O \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" . x \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" . O \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" . x \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" . O \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" . x \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" . O \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" . x \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" . O \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" x \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" O \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("- O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf(" -O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("-O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf("x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf("x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf("x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf("x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf(" x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("-O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf("x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf("x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
printf("x . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
printf("O . \n\x1b[1F\x1b[2K"); nanosleep(&req , &rem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,12 @@
|
||||||
/* ? */
|
/* ? */
|
||||||
/* */
|
/* */
|
||||||
/* (1) create/edit some mesurement tools and/or activate existing ones */
|
/* (1) create/edit some mesurement tools and/or activate existing ones */
|
||||||
/* (2) apply a mesurement tool to a situation to create a new data flow */
|
/* (2) apply a mesurement tool to a situation to create a new data list */
|
||||||
|
/* data list = x, f(x), g(x),... */
|
||||||
|
/* ces data sont collectées par le serveur et envoyées au client */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
/* and possibly carry out any operations on these results */
|
/* and possibly carry out any operations on these results */
|
||||||
/* (3) display (plot) the results and adjust the appearance of the tables */
|
/* (3) display (plot) the results and adjust the appearance of the tables */
|
||||||
/* - - - */
|
/* - - - */
|
||||||
|
@ -68,6 +73,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* (4) a journal (a pile) stores chronologically the fsm events */
|
/* (4) a journal (a pile) stores chronologically the fsm events */
|
||||||
/* during a session run (rules exec, mainly) */
|
/* during a session run (rules exec, mainly) */
|
||||||
|
/* dans un fichier journal (.log) un par session */
|
||||||
/* - - - */
|
/* - - - */
|
||||||
/* */
|
/* */
|
||||||
/* When a rule is adequately tagged, it triggers a measure : */
|
/* When a rule is adequately tagged, it triggers a measure : */
|
||||||
|
@ -88,3 +94,56 @@ void fsm_add_measure (char *measure_name) {fsm_msg (2, 0, measure_name, 2);}
|
||||||
void fsm_measures_list_init() {if (0) fsm_tools_list_test();}
|
void fsm_measures_list_init() {if (0) fsm_tools_list_test();}
|
||||||
void fsm_rule_trig_measure (int rule_id, int object_id, int measure_id) {}
|
void fsm_rule_trig_measure (int rule_id, int object_id, int measure_id) {}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Qu'est-ce qui est envoyé par le serveur lors des "pollings" ?
|
||||||
|
*
|
||||||
|
* - chaque exécution d'une règle d'intérêt avec
|
||||||
|
* . time stamp
|
||||||
|
* . identité de la règle
|
||||||
|
* . lieu d'application
|
||||||
|
*
|
||||||
|
* -
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* An editable list of measurements is defined and maintained */
|
||||||
|
/* (see : fsm/measure/manage.c) */
|
||||||
|
/* - - - */
|
||||||
|
/* Each possible measurement can be activated or silenced */
|
||||||
|
/* - - - */
|
||||||
|
/* The measures relate to */
|
||||||
|
/* - the number of occurrences of a rule or group of rules, */
|
||||||
|
/* - the number of objects or situations before/after the rule was applied, */
|
||||||
|
/* - the time (date) of the event, */
|
||||||
|
/* - the time elapsed between two events, */
|
||||||
|
/* - the occurrence of events C between events A and B, */
|
||||||
|
/* NB This list is non limitative. ex : pattern recognition tools */
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// structure de données : chaque "item" doit comporter :
|
||||||
|
//
|
||||||
|
// - identifiant (clé) (+/- pointeur vers : date de création, auteur,...)
|
||||||
|
//
|
||||||
|
// - type de mesure
|
||||||
|
// les 6 items suivants peuvent documenter l'ensemble de toutes les valeurs
|
||||||
|
// à recueillir pour documenter tous les types de mesure possibles;
|
||||||
|
// tous ces items ne doivent pas être simultanément complétés
|
||||||
|
// mais, si un tableau etait utilisé, il y aurait peu de place perdue;
|
||||||
|
//
|
||||||
|
// - pointeur vers le premier groupe de règles (une au moins)
|
||||||
|
// - pointeur vers un second groupe de règles (une au moins)
|
||||||
|
// - pointeur vers des objets ou situations (un au moins)
|
||||||
|
// - pointeur vers un ensemble d'évènements intercurrents
|
||||||
|
// - date de l'évènement
|
||||||
|
// - durée entre deux évènements
|
||||||
|
//
|
||||||
|
// - mesure active ? + / -
|
||||||
|
// - pointeur vers une liste de mesures similaires
|
||||||
|
// - pointeur vers des données, des représentations de données ?
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
64
src/main.c
64
src/main.c
|
@ -126,18 +126,6 @@
|
||||||
* les traductions, les 'disabilities'; etc.
|
* les traductions, les 'disabilities'; etc.
|
||||||
* mais aussi concernant les méthodes de travail, l'usage des outils d'analyse, etc.
|
* mais aussi concernant les méthodes de travail, l'usage des outils d'analyse, etc.
|
||||||
* >> des 'scripts' pour des 'méta-fonctions' (des 'macros') ?
|
* >> des 'scripts' pour des 'méta-fonctions' (des 'macros') ?
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* L I S T E D E S F O N C T I O N S A P P E L É E S *
|
|
||||||
*******************************************************************************
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* L I S T E D E S A P P E L S D E F O N C T I O N S *
|
|
||||||
*******************************************************************************
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -151,13 +139,17 @@ int main (int argc, char **argv)
|
||||||
GtkApplication *app;
|
GtkApplication *app;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
printf("exemple de format de journal : 2024-08-31 [%s()] %s\
|
||||||
|
< NB ce printf() se trouve dans 'main'\n", __func__, "message"); // logging TODO TODO
|
||||||
|
// un exemple : $ sudo cat /var/log/messages
|
||||||
|
|
||||||
app = gtk_application_new ("org.gem-graph", G_APPLICATION_DEFAULT_FLAGS);
|
app = gtk_application_new ("org.gem-graph", G_APPLICATION_DEFAULT_FLAGS);
|
||||||
|
|
||||||
|
fsm_init (); // fsm = finite state machine (see : src/fsm/dispatch.c)
|
||||||
|
|
||||||
g_signal_connect (app, "activate", G_CALLBACK (on_windows_activation), NULL);
|
g_signal_connect (app, "activate", G_CALLBACK (on_windows_activation), NULL);
|
||||||
// on_windows_activation <> see : src/widget/dispatch
|
// on_windows_activation <> see : src/widget/dispatch
|
||||||
|
|
||||||
fsm_init (); // fsm = finite state machine (see : src/fsm/dispatch.c)
|
|
||||||
|
|
||||||
status = g_application_run (G_APPLICATION (app), argc, argv);
|
status = g_application_run (G_APPLICATION (app), argc, argv);
|
||||||
g_object_unref (app);
|
g_object_unref (app);
|
||||||
|
|
||||||
|
@ -175,3 +167,47 @@ int main (int argc, char **argv)
|
||||||
// property gtk-error-bell: gboolean [ read, write ]
|
// property gtk-error-bell: gboolean [ read, write ]
|
||||||
// When TRUE, keyboard navigation and other input-related errors will cause a beep.
|
// When TRUE, keyboard navigation and other input-related errors will cause a beep.
|
||||||
|
|
||||||
|
/*
|
||||||
|
2024-08-31 Un point sur l'état d'avancement du client:
|
||||||
|
|
||||||
|
TODO (bottlenecks)
|
||||||
|
- images (++)
|
||||||
|
- arbres (et listes) (++)
|
||||||
|
- logging (ref : /var/log/messages)
|
||||||
|
- menus (pas indispensables à ce stade))
|
||||||
|
|
||||||
|
À redéfinir: répartition des tâches (mesures) client/serveur.
|
||||||
|
Comment traiter le cas extrême où *toutes* les règles
|
||||||
|
sont des règles d'intérêt ?
|
||||||
|
(cas d'une erreur rare, non systématique où il faut "remonter le temps",
|
||||||
|
pas à pas, à partir du premier état qui met l'erreur en évidence)
|
||||||
|
|
||||||
|
Pour effectuer cette "remontée", il faut une liste complète
|
||||||
|
de toutes les règles appliquées.
|
||||||
|
Cette liste doit comporter, pour chaque item (= chaque exécution d'une règle):
|
||||||
|
- identité de la règle
|
||||||
|
- lieu d'exécution (dans l'espace global)
|
||||||
|
- date d'exécution
|
||||||
|
NB Il ne peut y avoir d'ambiguité ou d'erreur due au parallélisme
|
||||||
|
car, si les espaces locaux de deux exécutions de règles se recouvrent,
|
||||||
|
elles ne peuvent avoir été exécutées simultanément.
|
||||||
|
|
||||||
|
À mon avis, le serveur ne peut effectuer cette tâche car
|
||||||
|
la "remontée dans le temps" nécessite l'inspection 'de visu' de chaque état.
|
||||||
|
|
||||||
|
Inspection veut dire ici: reconnaissance de formes
|
||||||
|
et ce travail (visuel) ne peut être pré-programmé
|
||||||
|
(bien qu'il doive être systématique), car le concepteur du modèle
|
||||||
|
ne sait pas quelle est l'erreur et ne peut prévoir ce qu'il va découvrir.
|
||||||
|
|
||||||
|
Ceci n'exclut pas qu'il puisse - qu'il doive - effectuer plusieurs essais
|
||||||
|
(de "remontée dans le temps") en sélectionnant, par exemple,
|
||||||
|
différentes règles d'intérêt à chaque fois
|
||||||
|
ni qu'il puisse se programmer des outils d'aide
|
||||||
|
(mais tout ceci ne semble pas avoir sa place dans le serveur).
|
||||||
|
|
||||||
|
NB À ce stade de la conception d'un modèle, les erreurs sont encore fréquentes
|
||||||
|
et les 'runs' sont nécessairement de brève durée.
|
||||||
|
Des 'runs' de longue durée n'ont de sens qu'une fois ce débuggage effectué.
|
||||||
|
Il y a donc peu de problèmes à craindre du fait de la limite de la bande passante.
|
||||||
|
*/
|
||||||
|
|
|
@ -60,18 +60,18 @@ void on_windows_activation (GtkApplication *app)
|
||||||
{
|
{
|
||||||
// g_application_activate (G_APPLICATION (app)); < how ? > in main.c is
|
// g_application_activate (G_APPLICATION (app)); < how ? > in main.c is
|
||||||
// g_signal_connect (app, "activate", G_CALLBACK (on_windows_activation), NULL);
|
// g_signal_connect (app, "activate", G_CALLBACK (on_windows_activation), NULL);
|
||||||
|
/*
|
||||||
printf(" We apologise for the temporary interruption to the window. 😇️\n\
|
printf(" We apologise for the temporary interruption to the window. 😇️\n\
|
||||||
Please, ask 'src/widget/dispatch.c on_windows_activation (GtkApplication *app)'\n\
|
Please, ask 'src/widget/dispatch.c on_windows_activation (GtkApplication *app)'\n\
|
||||||
to call: widget_design_main_window (main_window)\n");
|
to call: widget_design_main_window (main_window)\n");
|
||||||
/*
|
*/
|
||||||
main_window = GTK_WINDOW (gtk_application_window_new (app));
|
main_window = GTK_WINDOW (gtk_application_window_new (app));
|
||||||
dialog_window = GTK_WINDOW (gtk_application_window_new (app));
|
dialog_window = GTK_WINDOW (gtk_application_window_new (app));
|
||||||
text_window = GTK_WINDOW (gtk_application_window_new (app));
|
text_window = GTK_WINDOW (gtk_application_window_new (app));
|
||||||
|
|
||||||
widget_design_main_window (main_window); // def: widget/topbar/dispatch
|
widget_design_main_window (main_window); // def: widget/topbar/dispatch
|
||||||
widget_design_dialog_window (main_window, dialog_window);
|
widget_design_dialog_window (main_window, dialog_window);
|
||||||
widget_design_text_window (main_window, text_window);*/
|
widget_design_text_window (main_window, text_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
|
@ -37,6 +37,11 @@ void *widget_get_time_results_box () {
|
||||||
intended to\n modulate\n the look of\n the various\n represented\n flows\n")));
|
intended to\n modulate\n the look of\n the various\n represented\n flows\n")));
|
||||||
gtk_box_append (time_box, GTK_WIDGET (gtk_picture_new_for_filename
|
gtk_box_append (time_box, GTK_WIDGET (gtk_picture_new_for_filename
|
||||||
("/home/jean/Gem-Graph/gem-graph-client/data/image/data évolutions parallèles (n > 30) étendu.png")));
|
("/home/jean/Gem-Graph/gem-graph-client/data/image/data évolutions parallèles (n > 30) étendu.png")));
|
||||||
|
// https://gitlab.gnome.org/GNOME/gnome-system-monitor/-/blob/master/src/load-graph.cpp?ref_type=heads
|
||||||
|
// https://gitlab.gnome.org/GNOME/gnome-system-monitor/-/blob/master/src/gsm-graph.c?ref_type=heads
|
||||||
|
// https://gitlab.gnome.org/GNOME/gnome-system-monitor/-/tree/master/src?ref_type=heads
|
||||||
|
|
||||||
|
|
||||||
return GTK_WIDGET (time_box);
|
return GTK_WIDGET (time_box);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +63,7 @@ void *widget_get_display_results_box () {
|
||||||
gtk_box_append (scroll_bar_box, GTK_WIDGET (gtk_progress_bar_new ()));
|
gtk_box_append (scroll_bar_box, GTK_WIDGET (gtk_progress_bar_new ()));
|
||||||
GtkAdjustment *adjust = gtk_adjustment_new (30, 0, 100, 1, 0, 0);
|
GtkAdjustment *adjust = gtk_adjustment_new (30, 0, 100, 1, 0, 0);
|
||||||
gtk_box_append (data_box, GTK_WIDGET (widget_get_time_results_box ()));
|
gtk_box_append (data_box, GTK_WIDGET (widget_get_time_results_box ()));
|
||||||
|
// https://gitlab.gnome.org/GNOME/gnome-system-monitor/-/blob/master/src/load-graph.cpp?ref_type=heads
|
||||||
gtk_box_append (scroll_bar_box,
|
gtk_box_append (scroll_bar_box,
|
||||||
GTK_WIDGET (gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, adjust)));
|
GTK_WIDGET (gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, adjust)));
|
||||||
gtk_box_append (data_box, GTK_WIDGET (scroll_bar_box));
|
gtk_box_append (data_box, GTK_WIDGET (scroll_bar_box));
|
||||||
|
|
Loading…
Reference in New Issue