Created
February 12, 2025 12:53
-
-
Save medovina/0ad9da73d3c0972f058cc1b726a18eed to your computer and use it in GitHub Desktop.
demo GTK 4 program with a GtkColumnView
This file contains hidden or 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
// This demo GTK 4 program creates a GtkColumnView that shows a list of movies, each with | |
// a year and title. You can click column headers to sort by year or title. The | |
// sorting is implemented using GtkCustomSorter objects. | |
// | |
// To keep things simple, I haven't bothered to deref or free any allocated objects. | |
// | |
// To build, run | |
// $ gcc -Wall `pkg-config --cflags gtk4` -o column_view column_view.c `pkg-config --libs gtk4` | |
#include <gtk/gtk.h> | |
// Use GObject black magic to define a GObject subclass called DemoMovie. | |
// A DemoMovie contains a year (an int) plus a title (a string). | |
#define DEMO_TYPE_MOVIE (demo_movie_get_type ()) | |
G_DECLARE_FINAL_TYPE (DemoMovie, demo_movie, DEMO, MOVIE, GObject) | |
struct _DemoMovie { | |
GObject parent_instance; | |
int year; | |
const char *title; | |
}; | |
struct _DemoMovieClass { | |
GObjectClass parent_class; | |
}; | |
G_DEFINE_TYPE (DemoMovie, demo_movie, G_TYPE_OBJECT) | |
void demo_movie_init(DemoMovie *movie) { | |
} | |
void demo_movie_class_init(DemoMovieClass *class) { | |
} | |
// end black magic | |
DemoMovie *demo_movie_new(int year, const char *title) { | |
DemoMovie *movie = g_object_new(DEMO_TYPE_MOVIE, NULL); | |
movie->year = year; | |
movie->title = title; | |
return movie; | |
} | |
void setup_label(GtkSignalListItemFactory *factory, GtkListItem *listitem) { | |
GtkLabel *label = (GtkLabel *) gtk_label_new(""); | |
gtk_list_item_set_child(listitem, GTK_WIDGET(label)); | |
} | |
void bind_year(GtkSignalListItemFactory *factory, GtkListItem *listitem) { | |
GtkLabel *label = GTK_LABEL(gtk_list_item_get_child(listitem)); | |
DemoMovie *movie = DEMO_MOVIE(gtk_list_item_get_item(listitem)); | |
char buffer[16]; | |
g_snprintf(buffer, 16, "%d", movie->year); | |
gtk_label_set_text(label, buffer); | |
} | |
void bind_title(GtkSignalListItemFactory *factory, GtkListItem *listitem) { | |
GtkLabel *label = GTK_LABEL(gtk_list_item_get_child(listitem)); | |
gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_START); | |
DemoMovie *movie = DEMO_MOVIE(gtk_list_item_get_item(listitem)); | |
gtk_label_set_text(label, movie->title); | |
} | |
gint sort_by_year(gconstpointer a, gconstpointer b, gpointer user_data) { | |
DemoMovie *movie_a = (DemoMovie *) a; | |
DemoMovie *movie_b = (DemoMovie *) b; | |
return movie_a->year - movie_b->year; | |
} | |
gint sort_by_title(gconstpointer a, gconstpointer b, gpointer user_data) { | |
DemoMovie *movie_a = (DemoMovie *) a; | |
DemoMovie *movie_b = (DemoMovie *) b; | |
return g_strcmp0(movie_a->title, movie_b->title); | |
} | |
void activate (GtkApplication* app, gpointer user_data) { | |
GtkApplicationWindow *window = (GtkApplicationWindow *) gtk_application_window_new(app); | |
gtk_window_set_title(GTK_WINDOW(window), "column demo"); | |
GListStore *store = g_list_store_new(DEMO_TYPE_MOVIE); | |
g_list_store_append(store, demo_movie_new(1981, "Raiders of the Lost Ark")); | |
g_list_store_append(store, demo_movie_new(1994, "The Shawshank Redemption")); | |
g_list_store_append(store, demo_movie_new(1995, "Clueless")); | |
g_list_store_append(store, demo_movie_new(2001, "Memento")); | |
GtkColumnView *view = (GtkColumnView *) gtk_column_view_new(NULL); | |
// add column "year" with sorter | |
GtkListItemFactory *factory = gtk_signal_list_item_factory_new(); | |
g_signal_connect(factory, "setup", G_CALLBACK(setup_label), NULL); | |
g_signal_connect(factory, "bind", G_CALLBACK(bind_year), NULL); | |
GtkColumnViewColumn *column = gtk_column_view_column_new ("year", factory); | |
GtkCustomSorter *sorter = gtk_custom_sorter_new(sort_by_year, NULL, NULL); | |
gtk_column_view_column_set_sorter(column, GTK_SORTER(sorter)); | |
gtk_column_view_append_column(view, column); | |
// add column "title" with sorter | |
factory = gtk_signal_list_item_factory_new(); | |
g_signal_connect(factory, "setup", G_CALLBACK(setup_label), NULL); | |
g_signal_connect(factory, "bind", G_CALLBACK(bind_title), NULL); | |
column = gtk_column_view_column_new ("title", factory); | |
sorter = gtk_custom_sorter_new(sort_by_title, NULL, NULL); | |
gtk_column_view_column_set_sorter(column, GTK_SORTER(sorter)); | |
gtk_column_view_append_column(view, column); | |
// enable sorting using a GtkSortListModel | |
GtkSorter *view_sorter = gtk_column_view_get_sorter(view); | |
GtkSortListModel *model = gtk_sort_list_model_new(G_LIST_MODEL(store), view_sorter); | |
GtkSingleSelection *selection = gtk_single_selection_new(G_LIST_MODEL(model)); | |
gtk_column_view_set_model(view, GTK_SELECTION_MODEL(selection)); | |
gtk_window_set_child(GTK_WINDOW(window), GTK_WIDGET(view)); | |
gtk_window_set_default_size(GTK_WINDOW(window), 400, 200); | |
gtk_window_present(GTK_WINDOW(window)); | |
} | |
int main (int argc, char **argv) { | |
GtkApplication *app = gtk_application_new("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS); | |
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); | |
return g_application_run(G_APPLICATION(app), argc, argv); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment