WIP: Christian Hegert code <<< before inclusion

This commit is contained in:
Jean Sirmai 2024-02-11 08:52:30 +01:00
parent 13cb8099aa
commit 0c711b570b
Signed by: jean
GPG Key ID: FB3115C340E057E3
2 changed files with 198 additions and 114 deletions

View File

@ -69,7 +69,10 @@ int main()
return 0;
}
Le résultat de ce code est donc : "Je suis une fonction A". Comme en JavaScript, une fonction de rappel est appelée chaque fois quun certain événement se produit. En C, ces fonctions sont utilisées pour créer diverses nouvelles bibliothèques pour des travaux de programmation ultérieurs, et pour émettre les signaux du noyau qui sont nécessaires à la gestion des événements asynchrones.
Le résultat de ce code est donc : "Je suis une fonction A".
Comme en JavaScript, une fonction de rappel est appelée chaque fois quun certain événement se produit.
En C, ces fonctions sont utilisées pour créer diverses nouvelles bibliothèques pour des travaux de programmation ultérieurs,
et pour émettre les signaux du noyau qui sont nécessaires à la gestion des événements asynchrones.
//---------------------------------------------------------------------------------------------------------------------------
@ -86,7 +89,8 @@ kriptolix Diego C Sampaio answer > You will need:
4 - Gtk.NoSelection, Gtk.SingleSelection or Gtk.MultiSelection - will determine whether the items displayed in Gtk.ListView can be selected and how.
5 - Gtk.SignalListItemFactory or Gtk.BuildListItemFactory - a function that will build a widget to be displayed as a row in the Gtk.ListView. This widget will be populated with the information contained in the Gio.ListStore objects.
5 - Gtk.SignalListItemFactory or Gtk.BuildListItemFactory - a function that will build a widget to be displayed as a row in the Gtk.ListView.
This widget will be populated with the information contained in the Gio.ListStore objects.
6 - GtkTreeExpander - widget that must be included in the widget built by Gtk.SignalListItemFactory to allow row expansion.
@ -295,5 +299,53 @@ That said, GtkTreeListModelCreateModelFunc serves to create Models on demand to
* GListModel is an interface that represents a mutable list of GObjects.
*
*............................................................................*/
https://docs.gtk.org/gio/iface.ListModel.html
Gio
ListModel
[]
Description
interface Gio.ListModel : GObject.Object
GListModel is an interface that represents a mutable list of GObject.
Its main intention is as a model for various widgets in user interfaces, such as list views,
but it can also be used as a convenient method of returning lists of data, with support for updates.
Each object in the list may also report changes in itself via some mechanism (normally the GObject::notify signal).
Taken together with the GListModel::items-changed signal, this provides for a list that can change its membership,
and in which the members can change their individual properties.
A good example would be the list of visible wireless network access points,
where each access point can report dynamic properties such as signal strength.
It is important to note that the GListModel itself does not report changes to the individual items.
It only reports changes to the list membership.
If you want to observe changes to the objects themselves then you need to connect signals to the objects that you are interested in.
All items in a GListModel are of (or derived from) the same type. g_list_model_get_item_type() returns that type.
The type may be an interface, in which case all objects in the list must implement it.
The semantics are close to that of an array: g_list_model_get_n_items() returns the number of items in the list
and g_list_model_get_item() returns an item at a (0-based) position.
In order to allow implementations to calculate the list length lazily, you can also iterate over items:
starting from 0, repeatedly call g_list_model_get_item() until it returns NULL.
An implementation may create objects lazily, but must take care to return the same object for a given position until all references to it are gone.
On the other side, a consumer is expected only to hold references on objects that are currently user visible,
in order to facilitate the maximum level of laziness in the implementation of the list and to reduce the required number of signal connections at a given time.
This interface is intended only to be used from a single thread.
The thread in which it is appropriate to use it depends on the particular implementation,
but typically it will be from the thread that owns the thread-default main context
(see g_main_context_push_thread_default()) in effect at the time that the model was created.
Over time, it has established itself as good practice for list model implementations to provide properties item-type and n-items
to ease working with them. While it is not required, it is recommended that implementations provide these two properties.
They should return the values of g_list_model_get_item_type() and g_list_model_get_n_items() respectively and be defined as such:

View File

@ -29,19 +29,19 @@
#include "../../include/ui.h"
static void and_now_let_s_climb_that_tree (GtkWidget *in_that_box);
static void on_destroy (GtkWidget *widget, gpointer data) {if (data) g_print (data); exit(0);}
static void on_destroy (GtkWidget *widget, gpointer data) {if (data) g_print (data); exit (0);}
void on_activate_window_creation (GtkApplication *app, gpointer data)
{
GtkWidget *that_window = gtk_application_window_new (gtk_application_new ("org.gtk.test", 0));
g_signal_connect (G_OBJECT (that_window), "destroy", G_CALLBACK(on_destroy),
"sand_box.c / on_activate_window_creation() > exit(0) closes window\n");
gtk_window_set_title (GTK_WINDOW(that_window), "In the lab ");
gtk_window_set_default_size (GTK_WINDOW(that_window), 180, 140);
g_signal_connect (G_OBJECT (that_window), "destroy", G_CALLBACK (on_destroy),
"sand_box.c / on_activate_window_creation () > exit (0) closes window\n");
gtk_window_set_title (GTK_WINDOW (that_window), "In the lab ");
gtk_window_set_default_size (GTK_WINDOW (that_window), 180, 140);
GtkWidget *my_scrolling_thing = gtk_scrolled_window_new ();
gtk_window_set_child (GTK_WINDOW (that_window), my_scrolling_thing);
gtk_widget_show (that_window);
and_now_let_s_climb_that_tree (my_scrolling_thing);
if (data) {g_print (data); g_print (" and is displayed by : sand_box.c / on_activate_window_creation()\n");}
if (data) {g_print (data); g_print (" and is displayed by : sand_box.c / on_activate_window_creation ()\n");}
}
//-------------------------------------------------------------------------------------------------------------------------------------------
@ -53,11 +53,11 @@ GListModel *my_item_create_func (gpointer item, gpointer user_data) {return NUL
static void on_setup_cb (GtkSignalListItemFactory *self, GtkListItem *my_list_item, gpointer user_data)
/* Setup the widget to show in the Gtk.Listview << adapted from the kriptolix example */
{
// printf("...\n", gtk_string_list_get_string (GTK_STRING_LIST(user_data), 0));
// printf ("...\n", gtk_string_list_get_string (GTK_STRING_LIST (user_data), 0));
GtkWidget *my_label = gtk_label_new (NULL), *my_child_label = gtk_label_new (NULL);
GtkWidget *my_expander = gtk_expander_new (NULL); // ? = gtk_expander_new (GTK_LABEL(my_list_item));
GtkWidget *my_expander = gtk_expander_new (NULL); // ? = gtk_expander_new (GTK_LABEL (my_list_item));
gtk_list_item_set_child (my_list_item, my_label);
gtk_expander_set_child (GTK_EXPANDER(my_expander), my_label);
gtk_expander_set_child (GTK_EXPANDER (my_expander), my_label);
gtk_list_item_set_child (my_list_item, my_child_label); // ? gtk_list_item_set_child (my_list_item, my_expander);
}
@ -65,10 +65,10 @@ static void on_bind_cb (GtkSignalListItemFactory *self, GtkListItem *my_list_ite
/* Bind data from the store object to the widget << adapting from the kriptolix example */
{
GtkWidget *my_expander = gtk_expander_new (NULL);
gtk_expander_set_child (GTK_EXPANDER(my_expander), gtk_list_item_get_child (my_list_item));
GtkWidget *my_label = gtk_list_item_get_child (my_list_item); // GtkWidget *my_label = gtk_expander_get_child(my_expander);
gtk_expander_set_child (GTK_EXPANDER (my_expander), gtk_list_item_get_child (my_list_item));
GtkWidget *my_label = gtk_list_item_get_child (my_list_item); // GtkWidget *my_label = gtk_expander_get_child (my_expander);
// >>> row = item.get_item() <<< GtkTreeListRow instances are created by a GtkTreeListModel ----------------------------
// >>> row = item.get_item () <<< GtkTreeListRow instances are created by a GtkTreeListModel --------------------------
// https://docs.gtk.org/gtk4/class.TreeListRow.html GtkTreeListRow is used by GtkTreeListModel to represent items.
// It allows navigating the model as a tree and modify the state of rows.
// GtkTreeListRow instances are created by a GtkTreeListModel
@ -77,12 +77,12 @@ static void on_bind_cb (GtkSignalListItemFactory *self, GtkListItem *my_list_ite
// >>> void gtk_tree_expander_set_list_row (GtkTreeExpander *self, GtkTreeListRow *list_row);
// https://docs.gtk.org/gtk4/callback.TreeListModelCreateModelFunc.html
// in add_tree_node(item){} >>> if (type(item) == Gtk.TreeListRow) item = item.get_item(); <<< à 'traduire' +++
// --------------------------------------------------------------------------------------------------------------------------
// in add_tree_node (item){} >>> if (type (item) == Gtk.TreeListRow) item = item.get_item (); <<< à 'traduire' +++
// ---------------------------------------------------------------------------------------------------------------------------
// GObject *my_object = gtk_tree_list_row_get_item (GTK_TREE_LIST_ROW(self)); // GListModel *gtk_tree_list_row_get_children(GtkTreeListRow *self)
// GObject *my_object = gtk_tree_list_row_get_item (GTK_TREE_LIST_ROW (self)); // GListModel *gtk_tree_list_row_get_children (GtkTreeListRow *self)
// GtkStringObject *my_string_object = gtk_list_item_get_item (my_list_item);
// gtk_tree_expander_set_list_row (GTK_TREE_LIST_ROW(self), my_string_object);
// gtk_tree_expander_set_list_row (GTK_TREE_LIST_ROW (self), my_string_object);
/* my_string_object is owned by the instance. Caller mustn't change or destroy it. */
GtkStringObject *my_string_object = gtk_list_item_get_item (my_list_item);
@ -92,11 +92,11 @@ static void on_bind_cb (GtkSignalListItemFactory *self, GtkListItem *my_list_ite
static void on_selection_change (GtkStringList *my_selection_model, guint position, guint n_items, gpointer user_data)
{
printf("list size = %d item type = %ld\
printf ("list size = %d item type = %ld\
position (premier élement ayant changé d'état) = %2d %7s\
nombre d'éléments ayant changé d'état = %2d\n",
g_list_model_get_n_items (G_LIST_MODEL (my_selection_model)),
g_list_model_get_item_type(G_LIST_MODEL (my_selection_model)),
g_list_model_get_item_type (G_LIST_MODEL (my_selection_model)),
position,
gtk_string_object_get_string (g_list_model_get_item (G_LIST_MODEL (my_selection_model), position)),
n_items);
@ -107,11 +107,13 @@ static void on_selection_change (GtkStringList *my_selection_model, guint posit
static void and_now_let_s_climb_that_tree (GtkWidget *in_that_box)
{
const gchar *my_array[] = {"zero", "one", "two", "three", "four", NULL};
GtkStringList *my_string_list = gtk_string_list_new ((const char * const *) my_array);
GtkStringList *my_string_list = gtk_string_list_new ( (const char * const *) my_array);
gtk_string_list_append (my_string_list, "five");
// GType *my_item_type = g_list_model_get_item_type (G_LIST_MODEL (my_string_list));
GListStore *my_list_store = g_list_store_new (80); // = g_list_store_new (my_item_type);
g_list_store_append (my_list_store, my_string_list); // Et maintenant ?
// use my_list_store to implement my_tree_list_model ?... WTF !
GtkMultiSelection *my_selection_model = gtk_multi_selection_new (G_LIST_MODEL (my_string_list));
GtkListItemFactory *my_list_item_factory = gtk_signal_list_item_factory_new ();
@ -123,112 +125,142 @@ static void and_now_let_s_climb_that_tree (GtkWidget *in_that_box)
GtkWidget *my_list_view = gtk_list_view_new (GTK_SELECTION_MODEL (my_selection_model), my_list_item_factory);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (in_that_box), my_list_view);
srand(time(NULL)); int rank = rand() % g_list_model_get_n_items (G_LIST_MODEL (my_selection_model));
printf("in : GListModel *item_create_func (gpointer item,...) (line 80) (item n°%d is %s)\n",
srand (time (NULL)); int rank = rand () % g_list_model_get_n_items (G_LIST_MODEL (my_selection_model));
printf ("in : GListModel *item_create_func (gpointer item,...) (line 80) (item n°%d is %s)\n",
rank, gtk_string_list_get_string (my_string_list, rank));
}
//-----------------------------------------| mes notes. |------------------------------------------
/* trying to copy : https://github.com/kriptolix/gtk4_python3_exemples/blob/main/ListView/tree_view.py
* ? contact : kriptolix Fortaleza Diego C Sampaio Universidade Federal do Céara +5585996713935
* UNIDADE FORTALEZA: ZAP: (85) 99671-3935 Avenida Santos Dumont, Aldeota
-------------------------------------------------------------------------------------------------------
/* On 07/02/2024 04:48, Christian Hegert wrote:
*
* Hi Adrien, and thanks for your message. I really understand the issue and I'm really sorry there is no documentation here,
* for many reasons that I can't overlook, especially unstability in the API that still needs to be addressed.
import gi
* However, I can help you a bit to understand the current state of the API.
* Creating a tree of strings with `GtkTreeListModel` in GTK4 requires a structured approach
* since `GtkTreeListModel` is designed to flatten hierarchical data into a form that `GtkListView` can display.
* However, GTK4 does not provide a direct, ready-made tree structure like `GtkTreeStore` from GTK3.
* Instead, you would typically manage the hierarchical relationships yourself and use `GtkTreeListModel` to present this data in a `GtkListView`.
gi.require_version("Gtk", "4.0")
from gi.repository import Gtk, Gio, GObject # noqa
* To simulate a simple tree of strings, we can create a custom data structure that represents our tree.
* For the sake of simplicity, this example will not implement a fully dynamic tree
* but will show how to set up a basic static hierarchical structure suitable for display with `GtkTreeListModel` and `GtkListView`.
* ### Step 1: Define the Data Structure
* For this example, we'll define a simple tree structure. However, to keep things straightforward and focus on the GTK4 part,
* we'll skip creating a complex tree structure and directly use `GtkStringList` for parent items and assume child items are statically defined.
* ### Step 2: Create the Tree Model
* Since `GtkTreeListModel` needs a function to determine if an item has children and another function to provide those children,
* we'll simulate this with predefined data.
* ### Step 3: Display in `GtkListView`
* We'll use `GtkListView` with `GtkTreeListModel` to display the tree.
* Each item will be represented by a `GtkTreeExpander` to show the parent-child relationship visually.
* Here's how you might structure the code:
class DataObject(GObject.GObject):
def __init__(self, txt: str, children=None):
super(DataObject, self).__init__()
self.data = txt
self.children = children
#include <gtk/gtk.h>
// Prototype for simplicity, implement these based on your application's needs
static GListModel* create_child_model (const gchar* parent);
static void on_bind_list_item_cb (GtkListItemFactory* factory, GtkListItem* list_item, gpointer user_data)
{
GObject* item = gtk_list_item_get_item (list_item);
if (!item) return; // Necessary check
const gchar* text = gtk_string_object_get_string (GTK_STRING_OBJECT (item));
GtkWidget* label = gtk_label_new (text);
GtkWidget* expander = gtk_list_item_get_child (list_item);
gtk_tree_expander_set_child (GTK_TREE_EXPANDER (expander), label);
// Determine if this item should have an expander (i.e., if it has children)
GListModel* child_model = create_child_model (text);
if (child_model) gtk_tree_expander_set_expanded (GTK_TREE_EXPANDER (expander), TRUE);
g_object_unref (child_model); // Cleanup
}
static void on_setup_list_item_cb (GtkListItemFactory* factory, GtkListItem* list_item, gpointer user_data) {
GtkWidget* expander = gtk_tree_expander_new ();
gtk_list_item_set_child (list_item, expander);
}
// This function is a placeholder. You need to implement the logic based on your tree structure.
static GListModel* create_child_model (const gchar* parent) {
GtkStringList* list = gtk_string_list_new (NULL);
if (g_strcmp0 (parent, "Parent Item 1") == 0) {
gtk_string_list_append (list, "Child 1.1");
gtk_string_list_append (list, "Child 1.2");
} else if (g_strcmp0 (parent, "Parent Item 2") == 0) {
gtk_string_list_append (list, "Child 2.1");
}
return G_LIST_MODEL (list);
}
static GtkTreeListModel* create_tree_list_model () {
// Initial parent items
GtkStringList* base_model = gtk_string_list_new (NULL);
gtk_string_list_append (base_model, "Parent Item 1");
gtk_string_list_append (base_model, "Parent Item 2");
// Create a GtkTreeListModel that uses our function to fetch children for each parent
GtkTreeListModel* tree_model = gtk_tree_list_model_new (
GTK_SELECTION_MODEL (gtk_no_selection_new (G_LIST_MODEL (base_model))),
TRUE, // True to check for child items
(GtkTreeListModelCreateModelFunc)create_child_model,
NULL, // user data
g_object_unref);
// cleanup function for user data
return tree_model;
}
static void on_app_activate (GApplication* app, gpointer user_data) {
GtkWidget* window = gtk_application_window_new (GTK_APPLICATION (app));
gtk_window_set_title (GTK_WINDOW (window), "GTK4 Tree Example");
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
GtkTreeListModel* tree_model = create_tree_list_model ();
GtkListItemFactory* factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (on_setup_list_item_cb), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (on_bind_list_item_cb), NULL);
GtkSelectionModel* selection_model = gtk_tree_list_model_get_model (tree_model);
GtkWidget* list_view = gtk_list_view_new (selection_model, factory);
gtk_window_set_child (GTK_WINDOW (window), list_view);
}
int main (int argc, char** argv) {
GtkApplication* app = gtk_application_new ("org.example.gtk4tree", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (on_app_activate), NULL);
int status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app); // use : on_destroy (GtkWidget *widget, gpointer data) {...} ?
g_signal_connect (G_OBJECT (that_window), "destroy", G_CALLBACK (on_destroy),
"sand_box.c Christian Hegert / on_activate_window_creation () > exit (0) closes window\n");
return status;
}
def add_tree_node(item):
* This example demonstrates a basic structure for displaying hierarchical string data in a GTK4 application using `GtkTreeListModel` and `GtkListView`.
* The `create_child_model` function is a simplistic approach to simulating child item generation based on a parent item's text.
* In a real application, you would likely have a more complex mechanism for managing and traversing your hierarchical data.
if not (item):
print("no item")
return model
else:
if type(item) == Gtk.TreeListRow:
item = item.get_item()
* Keep in mind, this example assumes a static relationship between parents and children for demonstration purposes.
* Depending on your application's needs, you may need to implement more sophisticated logic for dynamically managing hierarchical data.
* But I hope it would help you a bit.
* Thanks again.
print("converteu")
print(item)
if not item.children:
return None
store = Gio.ListStore.new(DataObject)
for child in item.children:
store.append(child)
return store
GListStore is a simple implementation of GListModel that stores all items in memory.
It provides insertions, deletions, and lookups in logarithmic time
with a fast path for the common case of iterating the list linearly.
def setup(widget, item):
"""Setup the widget to show in the Gtk.Listview"""
label = Gtk.Label()
expander = Gtk.TreeExpander.new()
expander.set_child(label)
item.set_child(expander)
def bind(widget, item):
"""bind data from the store object to the widget"""
expander = item.get_child()
label = expander.get_child()
row = item.get_item()
expander.set_list_row(row)
obj = row.get_item()
label.set_label(obj.data)
def on_activate(app):
win = Gtk.ApplicationWindow(
application=app,
title="Gtk4 is Awesome !!!",
default_height=400,
default_width=400,
)
sw = Gtk.ScrolledWindow()
list_view = Gtk.ListView()
factory = Gtk.SignalListItemFactory()
factory.connect("setup", setup)
factory.connect("bind", bind)
list_view.set_factory(factory)
selection = Gtk.SingleSelection()
store = Gio.ListStore.new(DataObject)
model = Gtk.TreeListModel.new(store, False, False, add_tree_node)
selection.set_model(model)
list_view.set_model(selection)
v1 = [DataObject("entrada 01")]
v2 = [DataObject("entrada 01", v1)]
store.append(DataObject("entrada 01", v2))
# store.append(DataObject("entrada 02"))
sw.set_child(list_view)
win.set_child(sw)
win.present()
app = Gtk.Application(application_id="org.gtk.Example")
app.connect("activate", on_activate)
app.run(None)
*/
* All the best,
*/
//-------------------------------------------------------------------------------------------------