I’m trying to figure out how to setup GtkGridView to display an array of images and managed to get it working. But it would display the directory to the file instead of the image file itself.
Below is a part of my code. Please help me figure this out.
#include <gtk-4.0/gtk/gtk.h>
#include <gtk-4.0/gtk/gtknoselection.h>
#include <gtk-4.0/gtk/gtkexpression.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
#include <stdlib.h>
#define GAME_HOME_DIR "/home/theeast/Games/"
#define GAME_COVER "cover.png"
static void print_error(const char *function_name,
GError **ptr_error) {
GError *error = ptr_error ? *ptr_error : NULL;
g_print("%s failed", function_name);
if(error) {
g_print(": %s", error->message);
g_clear_error(ptr_error);
}
g_print("\n");
}
static GList *enumerate_child_dirs(const char *dirs) {
GFile *dir = NULL;
GFileEnumerator *direnum = NULL;
GList *results = NULL;
GError *error = NULL;
dir = g_file_new_for_path(dirs);
direnum = g_file_enumerate_children(dir,
"standard::*",
G_FILE_QUERY_INFO_NONE,
NULL, &error);
if(!direnum) {
print_error("g_file_enumerate_children", &error);
goto cleanup;
}
while(TRUE) {
GFileInfo *info;
if(!g_file_enumerator_iterate(direnum, &info,
NULL, NULL, &error)) {
print_error("g_file_enumerator_iterate", &error);
goto cleanup;
}
if(!info)
break;
if(g_file_info_get_file_type(info) == G_FILE_TYPE_DIRECTORY)
results = g_list_prepend(results, g_strdup(g_file_info_get_name(info)));
}
cleanup:
g_clear_object(&direnum);
g_clear_object(&dir);
return g_list_reverse(results);
}
static GListModel *create_cover_model(void) {
GList *child_dirs = enumerate_child_dirs(GAME_HOME_DIR);
GListStore *result;
GtkWidget *box, *cover;
char *cover_file, *start_script, *stop_script;
result = g_list_store_new(GTK_TYPE_IMAGE);
for(GList *l = child_dirs; l != NULL; l = l->next) {
box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_set_homogeneous(GTK_BOX(box), TRUE);
cover_file = g_build_filename(GAME_HOME_DIR,
(const char*) l->data,
"cover.png", NULL);
cover = gtk_image_new_from_file(cover_file);
gtk_image_set_pixel_size(GTK_IMAGE(cover), 256);
gtk_box_append(GTK_BOX(box), cover);
g_list_store_append(result, cover);
g_object_ref_sink(cover);
g_clear_pointer(&cover_file, g_free);
}
g_list_free_full(child_dirs, g_free);
return G_LIST_MODEL(result);
}
static void setup_cover_cb(GtkListItemFactory *factory,
GtkListItem *list_item) {
GtkWidget *box, *cover, *label;
GtkExpression *cover_expression, *expression;
box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_list_item_set_child(list_item, box);
expression = gtk_constant_expression_new(GTK_TYPE_LIST_ITEM, list_item);
cover_expression = gtk_property_expression_new(GTK_TYPE_LIST_ITEM, expression, "item");
expression = gtk_property_expression_new(GTK_TYPE_IMAGE,
gtk_expression_ref(cover_expression),
"file");
label = gtk_label_new(NULL);
gtk_expression_bind(expression, label, "label", label);
gtk_box_append(GTK_BOX(box), label);
expression = gtk_expression_ref(cover_expression);
cover = gtk_image_new();
gtk_expression_bind(expression, cover, "paintable", cover);
gtk_box_append(GTK_BOX(box), cover);
expression = gtk_property_expression_new(GTK_TYPE_IMAGE,
gtk_expression_ref(cover_expression),
"file");
expression = gtk_cclosure_expression_new(G_TYPE_STRING,
NULL,
1, (GtkExpression *[1]) {expression},
G_CALLBACK(print_error),
NULL, NULL);
gtk_expression_unref(cover_expression);
}
GtkWidget *brewery_catalog(void) {
GtkWidget *swin;
GtkWidget *grid;
GtkListItemFactory *factory;
GtkSelectionModel *model;
swin = gtk_scrolled_window_new();
gtk_scrolled_window_set_has_frame(GTK_SCROLLED_WINDOW(swin), TRUE);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_widget_set_vexpand(swin, TRUE);
model = GTK_SELECTION_MODEL(gtk_no_selection_new(create_cover_model()));
factory = gtk_signal_list_item_factory_new();
g_signal_connect(factory, "setup", G_CALLBACK(setup_cover_cb), NULL);
grid = gtk_grid_view_new(model, factory);
// gtk_grid_view_set_enable_rubberband(GTK_GRID_VIEW(grid), FALSE);
gtk_scrollable_set_hscroll_policy(GTK_SCROLLABLE(grid), GTK_SCROLL_NATURAL);
gtk_scrollable_set_vscroll_policy(GTK_SCROLLABLE(grid), GTK_SCROLL_NATURAL);
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(swin), grid);
return swin;
}