#include int shortcut_ui_open(const char *title, const char **groups, const char **labels, const char **keys, int count) { if (!gtk_init_check(NULL, NULL)) return 0; GtkWidget *dialog = gtk_dialog_new_with_buttons(title, NULL, GTK_DIALOG_MODAL, "_Close", GTK_RESPONSE_CLOSE, NULL); gtk_window_set_default_size(GTK_WINDOW(dialog), 900, 700); GtkWidget *scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_widget_set_vexpand(scrolled, TRUE); gtk_widget_set_hexpand(scrolled, TRUE); gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), scrolled); GtkTreeStore *store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING); GtkWidget *tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); gtk_widget_set_can_focus(tree, TRUE); atk_object_set_name(gtk_widget_get_accessible(tree), "Cthulhu shortcuts"); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), TRUE); const char *headers[] = {"Function", "Key binding"}; for (int column = 0; column < 2; column++) { GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); GtkTreeViewColumn *view = gtk_tree_view_column_new_with_attributes(headers[column], renderer, "text", column, NULL); gtk_tree_view_column_set_sort_column_id(view, column); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), view); } gtk_container_add(GTK_CONTAINER(scrolled), tree); GtkTreeIter parent, child, first; gboolean have_first = FALSE; const char *previous = NULL; for (int i = 0; i < count; i++) { if (!previous || g_strcmp0(previous, groups[i]) != 0) { gtk_tree_store_append(store, &parent, NULL); gtk_tree_store_set(store, &parent, 0, groups[i], 1, "", -1); previous = groups[i]; } gtk_tree_store_append(store, &child, &parent); gtk_tree_store_set(store, &child, 0, labels[i], 1, keys[i], -1); if (!have_first) { first = child; have_first = TRUE; } } gtk_tree_view_expand_all(GTK_TREE_VIEW(tree)); gtk_widget_show_all(dialog); if (have_first) { GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &first); gtk_tree_view_set_cursor(GTK_TREE_VIEW(tree), path, NULL, FALSE); gtk_tree_path_free(path); } gtk_widget_grab_focus(tree); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); g_object_unref(store); return 1; }