Last active
May 27, 2024 15:31
-
-
Save angstyloop/efc0a73bfbb8481ad1018260a056e5e8 to your computer and use it in GitHub Desktop.
An example of how to use GtkColumnView with GtkSignalListItemFactory for each column, where each list item in each column is a GtkLabel. This is basically a table with headers.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
ABOUT | |
An example of how to use GtkColumnView with GtkSignalListItemFactory for each | |
column, where each list item in each column is a GtkLabel. This is basically | |
a table with headers. | |
COMPILE | |
gcc `pkg-config --cflags gtk4` -o columnview columnview.c `pkg-config --libs gtk4` | |
RUN | |
./columnview | |
*/ | |
#include <gtk/gtk.h> | |
/* We could play the same game with the setup function, to produce a custom | |
* widget type for the items in each column, but for now we'll just use a | |
* GtkLabel for all items in the view. | |
*/ | |
static void | |
factory_setup( GtkListItemFactory *factory, GtkListItem *list_item ) | |
{ | |
GtkWidget *label = gtk_label_new( "" ); | |
gtk_list_item_set_child( list_item, label ); | |
} | |
/* The bind function for the primary key factory, corresponding to the first | |
* column. | |
*/ | |
static void | |
primary_key_factory_bind( GtkListItemFactory *factory, GtkListItem *list_item ) | |
{ | |
GtkWidget *label; | |
GtkStringObject *string_object; | |
const char *primary_key; | |
label = gtk_list_item_get_child( list_item ); | |
string_object = GTK_STRING_OBJECT( gtk_list_item_get_item( list_item ) ); | |
primary_key = gtk_string_object_get_string( string_object ); | |
gtk_label_set_label( GTK_LABEL( label ), primary_key ); | |
} | |
/* The bind function for the other factories, corresponding to columns after | |
* the primary key column. | |
*/ | |
static void | |
value_factory_bind( GtkListItemFactory *factory, GtkListItem *list_item, gpointer user_data ) | |
{ | |
GtkWidget *label; | |
GtkStringObject *string_object; | |
const char *primary_key, *value, *column_name = (const char *) user_data; | |
label = gtk_list_item_get_child( list_item ); | |
string_object = GTK_STRING_OBJECT( gtk_list_item_get_item( list_item ) ); | |
primary_key = gtk_string_object_get_string( string_object ); | |
// In a real application, do some complicated lookup here to get value. | |
// For this example, just concatenate the primary key and the column | |
// name that was passed as user_data. | |
value = g_strdup_printf( "%s-%s", column_name, primary_key ); | |
gtk_label_set_label( GTK_LABEL( label ), value ); | |
} | |
/* Callback that starts the application. | |
*/ | |
static void | |
activate (GtkApplication *app, gpointer user_data) | |
{ | |
GtkWidget *window, *view; | |
GtkColumnViewColumn* column; | |
char *column_names[] = { "PrimaryKey", "Apple", "Banana" }; | |
/* Create the application window. | |
*/ | |
window = gtk_application_window_new( app ); | |
gtk_window_set_title( GTK_WINDOW( window ), "Window" ); | |
gtk_window_set_default_size( GTK_WINDOW( window ), 200, 200 ); | |
/* Define the list items of the first column. In practice, these will be the | |
* unique string keys identifying a row, and showing the primary key column | |
* will be optional ( simply skip it when adding columns ). | |
*/ | |
char* primary_keys[] = { "0", "1", "2", NULL }; | |
GtkStringList *list_model = gtk_string_list_new( (const char* const*) primary_keys ); | |
/* Create simple selection model, which does not have any selection | |
* logic. Curiously, you can still see the mouseover highlight effect | |
* and onclick highlight effect even for GtkNoSelection, perhaps for | |
* accessibility reasons. | |
*/ | |
GtkNoSelection *selection_model = gtk_no_selection_new( G_LIST_MODEL( list_model ) ); | |
/* Initialize the array of GtkListItemFactory - one for each column. | |
*/ | |
GtkListItemFactory *factories[3]; | |
for ( int i = 0; i < 3; i++ ) | |
factories[i] = gtk_signal_list_item_factory_new(); | |
/* Connect handlers to the primary key factory. | |
*/ | |
g_signal_connect( factories[0], "setup", G_CALLBACK( factory_setup ), NULL ); | |
g_signal_connect( factories[0], "bind", G_CALLBACK( primary_key_factory_bind ), column_names[0] ); | |
/* Connect handlers to the other factories. | |
*/ | |
for ( int i = 1; i < 3; i++ ) { | |
g_signal_connect( factories[i], "setup", G_CALLBACK( factory_setup ), NULL ); | |
g_signal_connect( factories[i], "bind", G_CALLBACK( value_factory_bind ), column_names[i] ); | |
} | |
/* Create the column view. | |
*/ | |
view = gtk_column_view_new( GTK_SELECTION_MODEL( selection_model ) ); | |
gtk_window_set_child( GTK_WINDOW( window ), view ); | |
/* Create the columns. | |
*/ | |
for ( int i = 0; i < 3; i++ ) { | |
column = gtk_column_view_column_new( column_names[i], factories[i] ); | |
gtk_column_view_append_column( GTK_COLUMN_VIEW( view ), column ); | |
} | |
/* Show everything. | |
*/ | |
gtk_widget_show (window); | |
} | |
/* The main just function sets up a signal handler for "activate". | |
*/ | |
int | |
main (int argc, char **argv) { | |
GtkApplication *app; | |
int status; | |
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE); | |
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); | |
status = g_application_run (G_APPLICATION (app), argc, argv); | |
g_object_unref (app); | |
return status; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for sharing. Can you add a little example about how to edit the cells and update the list store with the new value?