WIP: cleaning, cleaning...

This commit is contained in:
Jean Sirmai 2024-01-07 21:52:17 +01:00
parent 601b7f0fa7
commit d96113c72b
Signed by: jean
GPG Key ID: FB3115C340E057E3
3 changed files with 277 additions and 219 deletions

View File

@ -122,13 +122,34 @@ void ui_toggle_sidebar ();
// Tree primitives // Tree primitives
void traverse_list_store (GtkListStore *liststore); // struct _GemGraphClientWindow
void onTreeViewRowActivated (GtkTreeView *view, GtkTreePath *path, // {
GtkTreeViewColumn *col, gpointer userdata); // GtkApplicationWindow parent_instance;
// /* Template widgets */
// GtkHeaderBar *main_titlebar;
// GtkStack *main_stack;
// GtkStack *side_stack;
// GtkPaned *main_paned;
// GtkMenuButton *main_button_mode;
// GtkToggleButton *main_button_sidebar;
// GtkRevealer *toast_revealer;
// GtkToggleButton *toast_close_button;
// GtkLabel *toast_text;
// GtkGLArea *run_glarea;
// GtkBox *run_controls;
// /* Stack objects */
// GtkStack *runlib_stack;
// GtkBox *runlib_objects;
// };
// G_DEFINE_FINAL_TYPE (GemGraphClientWindow,
// gem_graph_client_window,
// GTK_TYPE_APPLICATION_WINDOW)
void print_test_in_tree_dot_c(void); void print_test_in_tree_dot_c(void);
void print_test_in_tree_dot_c();
GtkWidget *create_tree_label(void);
GtkWidget *create_a_button_to_click_on(void);
//GtkWidget *create_tree_label(void);
//GtkWidget *create_a_button_to_click_on(void);
//GtkWidget *create_a_button_in_the_tab(GemGraphClientWindow *window);

View File

@ -21,6 +21,181 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/*----------------------------------------------------------------------------*/
/**************** 2024-01-06 À la chasse aux widgets ! ****************/
/* */
/* (1) Je recopie les fragments de code qui me semblent utiles */
/* tirés de demos/gtk-demo/main.c et de la liste suivante */
/*----------------------------------------------------------------------------*/
// https://www.gtk.org/
/******************************************************************************/
/* */
/* W I N D O W = D O _ S O M E _ A P P L I C A T I O N _ E X A M P L E */
/* */
// window = do_tree_store(NULL);
// window = do_listview_words(NULL);
// window = do_editable_cells(NULL);
// window = do_dnd(NULL); // drag and drop
// window = do_drawingarea(NULL);
// window = do_entry_undo(NULL);
// window = do_expander(NULL);
// window = do_textundo(NULL);
// window = do_search_entry2(NULL);
// window = do_scale(NULL); // scale entries from bars
// window = do_font_features(NULL);
// window = do_hypertext(NULL);
// window = do_iconview_edit(NULL); // drag and drop
// window = do_image_scaling(NULL);
// window = do_infobar(NULL);
// window = do_links(NULL);
// window = do_listbox_controls(NULL);
// window = do_list_store(NULL);
// window = do_listview_colors(NULL);
// window = do_listview_selections(NULL);
// window = do_mask(NULL);
/* */
/******************************************************************************/
/*
https://blog.gtk.org/2020/06/08/more-on-lists-in-gtk-4/
https://docs.gtk.org/gtk4/section-list-widget.html
https://en.wikibooks.org/wiki/GTK%2B_By_Example/Tree_View/Tree_Models
https://stackoverflow.com/questions/74556059/how-to-build-a-tree-in-gtk4-4-10
https://en.wikibooks.org/wiki/GTK%2B_By_Example/Tree_View/Columns_and_Renderer
*/
/******************************************** The basic ideas behind list views: ************************************************/
/* */
/* The data for items is provided in the form of a model (containing objects) */
/* Widgets are created just for the viewable range of items */
/* Widgets can be recycled by binding them to different items */
/* Avoid iterating over all items in the model as much as possible, */
/* and just deal with the items in the visible range which are bound to widgets */
/* from https://blog.gtk.org/2020/06/07/scalable-lists-in-gtk-4/ */
/* */
/****************************************************************************************************************************************/
// GtkListItemFactory is the object that is tasked with creating widgets for the items in the model.
// One implementations of this factory, GtkBuilderListItemFactory, is using ui files as templates for the list item widgets.
// https://gitlab.gnome.org/GNOME/gtk/-/blob/main/demos/gtk-demo/listview_settings.ui
/* Lists/Application launcher #Keywords: GtkListItemFactory, GListModel
* This demo uses the GtkListView widget as a fancy application launcher. It is also a very small introduction to listviews.
* https://gitlab.gnome.org/GNOME/gtk/-/blob/main/demos/gtk-demo/listview_applauncher.c */
/************************************************** W I D G E T S ********************************************************/
/* _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
/* _ _ _ _ _ _ _ _ _ _ _ _ _ E D I T A B L E _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
/* */
/* https://developer-old.gnome.org/gtk4/stable/ch03s02.html Which widget should I use ?... */
/* https://developer-old.gnome.org/gtk4/stable/GtkCellEditable.html#GtkCellEditable-struct */
/* The GtkCellEditable interface must be implemented for widgets to be usable to edit the contents of a GtkTreeView cell. */
/* It provides a way to specify how temporary widgets should be configured for editing, get the new value, etc. */
/* _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
/* _ _ _ _ _ _ _ _ _ _ _ _ _ _ T R E E _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
/* */
/* https://toshiocp.github.io/Gtk4-tutorial/sec29.html <<< TODO */
/* https://docs.gtk.org/gtk4/ */
/* https://docs.gtk.org/gtk4/section-list-widget.html << (see below the "quick comparison chart of equivalent functionalities") */
/* https://docs.gtk.org/gtk4/class.TreeListModel.html */
/* */
/* */
/* https://developer-old.gnome.org/gtk4/stable/GtkTreeView.html */
/* https://en.wikibooks.org/wiki/GTK%2B_By_Example/Tree_View/Custom_Models */
/* https://developer-old.gnome.org/gtk4/stable/GtkTreeSelection.html#GtkTreeSelection-struct */
/* https://developer-old.gnome.org/gtk4/stable/GtkTreeView.html#gtk-tree-view-get-path-at-pos << get-path-at-pos */
/* Finds the path at the point (x , y ), relative to bin_window coordinates. Use gtk_tree_view_convert_widget_to_bin_window_coords(). */
/* https://www.gnu.org/software/guile-gnome/docs/gtk/html/GtkCellRenderer.html */
/* GtkTreeSelection, GtkTreeView drag-and-drop, GtkTreeSortable, GtkTreeModelSort, GtkCellEditable, GtkCellRendererText,... */
/* gtk_tree_view_get_search_entry (treeview) https://blog.gtk.org/2020/09/08/on-list-models/ */
/* */
/****************************************************************************************************************************************/
// ? utile ?
// gtk_tree_model_foreach (model, TRUE, my_user_data); https://developer-old.gnome.org/gtk4/stable/GtkTreeModel.html#GtkTreeModelForeachFunc
/* ... Finally heres a quick comparison chart of equivalent functionalitqy
to look for when transitioning code:
Old New
..................................................................
GtkTreeModel GListModel
GtkTreePath guint position, GtkTreeListRow
GtkTreeIter guint position
GtkTreeRowReference GObject item
GtkListStore GListStore
GtkTreeStore GtkTreeListModel, GtkTreeExpander
GtkTreeSelection GtkSelectionModel
GtkTreeViewColumn GtkColumnView
GtkTreeView GtkListView, GtkColumnView
GtkCellView GtkListItem
GtkComboBox GtkDropDown
GtkIconView GtkGridView
GtkTreeSortable GtkColumnView
GtkTreeModelSort GtkSortListModel
GtkTreeModelFilter GtkFilterListModel
GtkCellLayout GtkListItemFactory
GtkCellArea GtkWidget
GtkCellRenderer GtkWidget
..............................................................................*/
/*..............................................................................
*
* >>> GtkStringList <<<
*
* GtkStringList is a list model that wraps an array of strings.
* The objects in the model are of type GtkStringObject
* and have a string property that can be used inside expressions.
* Use it where/when you would typically use a char*[], but need a list model.
*
* implements GtkBuildable interface
* <item> are GObject instances; support translatable, context and comments
*
* <object class="GtkStringList">
* <items>
* <item translatable="yes">Factory</item>
* <item translatable="yes">Home</item>
* <item translatable="yes">Subway</item>
* </items>
* </object>
*
* Every item in a model has a position (= unsigned integer)
* "factories" takes care of mapping the items of the model
* to widgets that can be shown in the view
* by creating a listitem for each item that is currently in use.
* List items are always GtkListItem instances. Widgets can be recycled.
*
* GtkStringList can only handle strings. It is backed by a dynamically allocated array.
* GListStore is backed by a balanced tree.
*
* GTK provides functionality to make lists look and behave like trees
* by using the GtkTreeListModel and the GtkTreeExpander widget.
*
* Widgets are styleable using GTK CSS. Use the .rich-list style class.
*
*
* GListModel is an interface that represents a mutable list of GObjects.
* https://gnome.pages.gitlab.gnome.org/libsoup/gio/GListModel.html
* https://docs.gtk.org/gio/iface.ListModel.html < +++
* https://blog.gtk.org/2020/09/08/on-list-models/
*
*............................................................................*/
#include <unistd.h> #include <unistd.h>
#include <gtk-4.0/gtk/gtk.h> #include <gtk-4.0/gtk/gtk.h>
#include <glib-2.0/glib.h> #include <glib-2.0/glib.h>
@ -29,230 +204,96 @@
#include "../../include/ui.h" #include "../../include/ui.h"
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <stdio.h>
//#include "config.h"
//#include "custom-list.h"
#include <gio/gio.h>
/* G_GNUC_BEGIN_IGNORE_DEPRECATIONS
* ! WARNING ! Ici règne le désordre le plus complet ! WARNING !
* Attention vous entrez à vos risques et périls dans un dangereux laboratoire.
* Ici, rien n'est balisé. Tout peut arriver. Le code est encombré de déchets inutiles.
* Les commentaires sont inadaptés, incompréhensibles et possiblement nuisibles.
* (en tout cas, inutilisables...)
* Nul ne sait ce qui s'y passe et l'auteur, possiblement frappé d'idiotie,
* ne sait dire lui-même ce qu'il veut, ce qu'il fait ou a fait et ce qu'il fera...
*/
enum enum
{ {
COL_FIRST_NAME = 0, STRING_COLUMN,
COL_LAST_NAME, NUM_COLUMNS
NUM_COLS };
} ;
GtkWidget *view;
GtkListStore *list_store;
GtkTreeStore *tree_store;
GtkTreeIter iter, child;
static GtkTreeModel *
create_and_fill_model (void) /* TreeItem structure */
typedef struct _TreeItem TreeItem;
struct _TreeItem
{ {
// GtkTreeStore *tree_store; const char *label;
GtkTreeIter toplevel;//, child; TreeItem *children;
};
tree_store = gtk_tree_store_new(NUM_COLS, G_TYPE_STRING, G_TYPE_STRING); /* tree data */
/* static TreeItem E[] = {NULL}, F[] = {NULL}, G[] = {NULL}, H[] = {NULL}; */
/* Append a top level row and leave it empty */ /* static TreeItem I[] = {NULL}, K[] = {NULL}, N[] = {NULL}, M[] = {NULL}; */
gtk_tree_store_append(tree_store, &toplevel, NULL); /* static TreeItem L[] = {{"M", M}, {"N", N}, {NULL }}, J[] = {{"L", L}, {NULL}}; */
gtk_tree_store_set(tree_store, &toplevel, /* static TreeItem D[] = {{"I", I}, {"J", J}, {"K", K}, {NULL}}; */
COL_FIRST_NAME, "RanTanPlan", /* static TreeItem C[] = {{"F", F}, {"G", G}, {"H", H}, {NULL}}; */
COL_LAST_NAME, "(a stupid dog)", /* static TreeItem A[] = {{"D", D}, {NULL}}, B[] = {{"E", E}, {NULL}}; */
-1); /* static TreeItem R[] = {{"A", A}, {"B", B}, {"C", C}, {NULL}}; */
/* static TreeItem O[] = {{"ROOT", R}, {NULL}}; // Artefact added for symmetry */
gtk_tree_store_append(tree_store, &toplevel, NULL);
gtk_tree_store_set(tree_store, &toplevel,
COL_FIRST_NAME, "Ma",
COL_LAST_NAME, "Dalton",
-1);
/* Append a second top level row, and fill it with some data */
gtk_tree_store_append(tree_store, &toplevel, NULL);
gtk_tree_store_set(tree_store, &toplevel,
COL_FIRST_NAME, "Joe",
COL_LAST_NAME, "Dalton",
-1);
gtk_tree_store_append(tree_store, &toplevel, NULL);
gtk_tree_store_set(tree_store, &toplevel,
COL_FIRST_NAME, "Jack",
COL_LAST_NAME, "Dalton",
-1);
gtk_tree_store_append(tree_store, &toplevel, NULL);
gtk_tree_store_set(tree_store, &toplevel,
COL_FIRST_NAME, "William",
COL_LAST_NAME, "Dalton",
-1);
/* Append a child to the second top level row, and fill in some data */
gtk_tree_store_append(tree_store, &child, &toplevel);
gtk_tree_store_set(tree_store, &child,
COL_FIRST_NAME, "Averell",
COL_LAST_NAME, "Dalton",
-1);
return GTK_TREE_MODEL(tree_store);
}
/***********************************************************
* *
* Going through every row in a list store *
* *
***********************************************************/
void
traverse_list_store (GtkListStore *liststore)
{
gboolean valid;
g_return_if_fail ( liststore != NULL );
/* Get first row in list store */
valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(liststore), &iter);
while (valid)
{
/* ... do something with that row using the iter ... */
/* (Here column 0 of the list store is of type G_TYPE_STRING) */
gtk_list_store_set(liststore, &iter, 0, "Joe", -1);
/* Make iter point to the next row in the list store */
valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(liststore), &iter);
}
}
/*************************************************************
* *
* Converting a GtkTreePath into a GtkTreeIter *
* *
*************************************************************/
/*************************************************************
* *
* onTreeViewRowActivated: a row has been double-clicked *
* *
*************************************************************/
void
onTreeViewRowActivated (GtkTreeView *view, GtkTreePath *path,
GtkTreeViewColumn *col, gpointer userdata)
{
GtkTreeModel *model;
model = gtk_tree_view_get_model(view);
if (gtk_tree_model_get_iter(model, &iter, path))
{
gchar *name;
gtk_tree_model_get(model, &iter, "ANY_COLUMN_NAME", &name, -1);
g_print ("The row containing the name '%s' has been double-clicked.\n", name);
g_free(name);
}
}
void
tree_c_test(void)
{
GtkTreeViewColumn *col;
GtkCellRenderer *renderer;
GtkWidget *view;
GtkTreeModel *model;
view = gtk_tree_view_new();
col = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(col, "First Name");
list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_UINT); /* static GListStore *create_node_recursive (GListModel *model, // GListStore* g_list_store_new (GType item_type) */
/* TreeItem *current_item, */
/* GtkTreeIter *iter_parent, */
/* int depth) */
/* { */
/* GtkTreeIter iter; */
gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(list_store)); /* if (model == NULL) */
/* model = gtk_tree_store_new (NUM_COLUMNS, G_TYPE_STRING); */
// g_object_unref(liststore); /* while (current_item->label) { */
/* if (0) printf("[%d] Current label : %s\n", depth, current_item->label); */
/* gtk_tree_store_append (model, &iter, iter_parent); */
/* gtk_tree_store_set (model, &iter, STRING_COLUMN, current_item->label, -1); */
/* Append empty rows to the list store. Iter will point to the new row */ /* if (current_item->children) */
gtk_list_store_append(list_store, &iter); /* create_node_recursive (model, current_item->children, &iter, depth + 1); */
gtk_list_store_append(list_store, &iter); /* else */
gtk_list_store_append(list_store, &iter); /* break; */
tree_store = gtk_tree_store_new(1, G_TYPE_STRING); /* current_item++; */
/* } */
/* Append an empty top-level row to the tree store. /* if (depth == 0) */
* Iter will point to the new row */ /* return G_LIST_MODEL(model); // can cast to GListModel or to GtkTreeStore ? */
gtk_tree_store_append(tree_store, &iter, NULL); /* else */
/* return NULL; */
/* } */
/* Append another empty top-level row to the tree store.
* Iter will point to the new row */
gtk_tree_store_append(tree_store, &iter, NULL);
/* Append a child to the row we just added.
* Child will point to the new row */
gtk_tree_store_append(tree_store, &child, &iter);
/* Get the first row, and add a child to it as well (could have been done /* static void */
* right away earlier of course, this is just for demonstration purposes) */ /* print_hello (GtkWidget *widget, */
if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(tree_store), &iter)) /* gpointer data) */
{ /* { */
/* Child will point to new row */ /* static int nb; */
gtk_tree_store_append(tree_store, &child, &iter); /* nb++; */
} /* printf("Button clicked (n = %d)\n", nb); */
else g_error("Oops, we should have a first row in the tree store!\n"); /* } */
}
void print_test_in_tree_dot_c(void) /* GtkWidget *create_a_button_to_click_on(GemGraphClientWindow *my_window) */
/* { */
/* GtkWidget *button; */
/* const char *text = "Hello ! I'm the new button. Click me !"; */
/* button = gtk_button_new_with_label(text); */
/* gtk_box_append(GTK_BOX(my_window->runlib_objects), button); */
/* gtk_widget_show(button); */
/* g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL); */
/* return button; */
/* } */
void print_test_in_tree_dot_c (void)
{ {
printf("tree.c > print test() \ printf("tree.c > print test() \
------------------------------------\n\ ------------------------------------\nClick the 'new button' in the GtkBox.\n");
A button is now in the GtkBox and an action is associated to it.\n\n");
} }
/*
https://mesonbuild.com/Manual.html
https://blog.gtk.org/2020/06/08/more-on-lists-in-gtk-4/
https://docs.gtk.org/gtk4/section-list-widget.html
https://en.wikibooks.org/wiki/GTK%2B_By_Example/Tree_View/Tree_Models
https://stackoverflow.com/questions/74556059/how-to-build-a-tree-in-gtk4-4-10
https://stackoverflow.com/questions/51002454/how-to-list-all-the-rows-of-a-gtk-treeview
https://en.wikibooks.org/wiki/GTK%2B_By_Example/Tree_View/Columns_and_Renderer
*/
static GListModel *
create_settings_model (gpointer item,
gpointer unused)
{
GSettings *settings = item;
char **schemas;
GListStore *result;
guint i;
schemas = g_settings_list_children (settings);
if (schemas == NULL || schemas[0] == NULL)
{
g_free (schemas);
return NULL;
}
result = g_list_store_new (G_TYPE_SETTINGS);
for (i = 0; schemas[i] != NULL; i++)
{
GSettings *child = g_settings_get_child (settings, schemas[i]);
g_list_store_append (result, child);
g_object_unref (child);
}
g_strfreev (schemas);
return G_LIST_MODEL (result);
}

View File

@ -123,7 +123,8 @@ static void gem_graph_client_window_init(GemGraphClientWindow *self)
} }
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
static void let_s_scroll_it_guys(void);
GtkWidget *create_a_button_to_click_on(void);
void ui_set_stack(const char *mode) void ui_set_stack(const char *mode)
{ {
@ -141,7 +142,7 @@ void ui_set_stack(const char *mode)
case 'r': case 'r':
gtk_menu_button_set_icon_name(window->main_button_mode, "system-run-symbolic"); gtk_menu_button_set_icon_name(window->main_button_mode, "system-run-symbolic");
create_a_button_to_click_on(); create_a_button_to_click_on();
let_s_scroll_it_guys(); // let_s_scroll_it_guys();
print_test_in_tree_dot_c(); print_test_in_tree_dot_c();
break; break;
@ -280,8 +281,3 @@ GtkWidget *create_a_button_to_click_on(void)
return button; return button;
} }
static void
let_s_scroll_it_guys(void){
GtkWidget scrolled_thing = *gtk_scrolled_window_new ();
// gtk_box_append(GTK_BOX(window->runlib_objects), scrolled_thing);
}