Skip to content

Instantly share code, notes, and snippets.

@angstyloop
Last active May 27, 2024 15:31
Show Gist options
  • Save angstyloop/efc0a73bfbb8481ad1018260a056e5e8 to your computer and use it in GitHub Desktop.
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.
/*
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;
}
@aullidolunar
Copy link

Thanks for sharing. Can you add a little example about how to edit the cells and update the list store with the new value?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment