Re: 3000 toggle buttons in a table?



On Mon, Apr 03, 2006 at 01:40:25PM -0400, Tristan Van Berkom wrote:

Why not use GtkCellRendererToggle w/ GtkTreeView & GtkListStore ?

Or use a GtkListStore to select your data item and some togglebuttons
and whatever other control widgets below your treeview (i.e. the single
toggle button applies only to the selected row) ?

(Sure; writing treeview code is a pain, but its perfect for these
"large dataset" situations).

It is not so much pain -- if your code actually does
something, the treeview bureaucracy is not substantial.
What bugs me more is the extra requested space at the right
side of the tree view when one goes mad and simply creates
a large grid of GtkCellRendererToggles.  Is it a bug?  Does
anyone observe it too?

Yeti


--
That's enough.



===========================================================================
#include <stdlib.h>
#include <gtk/gtk.h>

/* Someone put this into GLib... */
static guint64
g_rand_int64(GRand *rand)
{
    guint64 low, hi;

    low = g_rand_int(rand);
    hi = g_rand_int(rand);

    return low | (hi << 32);
}

static void
render_cell(G_GNUC_UNUSED GtkCellLayout *layout,
            GtkCellRenderer *renderer,
            GtkTreeModel *model,
            GtkTreeIter *iter,
            gpointer user_data)
{
    guint i = GPOINTER_TO_UINT(user_data);
    guint64 x;

    gtk_tree_model_get(model, iter, 0, &x, -1);
    g_object_set(G_OBJECT(renderer), "active", (gboolean)((x >> i) & 1), NULL);
}

static void
toggle_cell(GtkCellRendererToggle *renderer,
            gchar *path,
            GtkListStore *store)
{
    GtkTreeModel *model;
    GtkTreeIter iter;
    guint64 x, bit = 1;

    g_print("Setting (%u, %u) to %s\n",
            GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(renderer), "id")),
            atoi(path),
            !gtk_cell_renderer_toggle_get_active(renderer) ? "On" : "Off");

    model = GTK_TREE_MODEL(store);
    gtk_tree_model_iter_nth_child(model, &iter, NULL, atoi(path));

    gtk_tree_model_get(model, &iter, 0, &x, -1);
    bit = bit << GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(renderer), "id"));
    if (gtk_cell_renderer_toggle_get_active(renderer))
        x &= ~bit;
    else
        x |= bit;
    gtk_list_store_set(store, &iter, 0, x, -1);
}

int
main(int argc, char *argv[])
{
    GtkWidget *window, *treewidget;
    GtkTreeView *treeview;
    GtkListStore *store;
    GtkCellRenderer *renderer;
    GtkTreeViewColumn *column;
    GtkCellLayout *layout;
    GtkTreeSelection *selection;
    GtkTreeIter iter;
    GRand *rng;
    guint i, nrows = 50;

    gtk_init(&argc, &argv);

    rng = g_rand_new();
    store = gtk_list_store_new(1, G_TYPE_UINT64);
    for (i = 0; i < nrows; i++) {
        gtk_list_store_append(store, &iter);
        gtk_list_store_set(store, &iter, 0, g_rand_int64(rng), -1);
    }
    g_rand_free(rng);

    treewidget = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
    treeview = GTK_TREE_VIEW(treewidget);
    g_object_unref(store);

    column = gtk_tree_view_column_new();
    layout = GTK_CELL_LAYOUT(column);
    for (i = 0; i < 64; i++) {
        renderer = gtk_cell_renderer_toggle_new();
        g_object_set_data(G_OBJECT(renderer), "id", GUINT_TO_POINTER(i));
        gtk_cell_layout_pack_start(layout, renderer, FALSE);
        gtk_cell_layout_set_cell_data_func(layout, renderer,
                                           render_cell, GUINT_TO_POINTER(i),
                                           NULL);
        g_object_set(renderer, "activatable", TRUE, NULL);
        g_signal_connect(renderer, "toggled", G_CALLBACK(toggle_cell), store);
    }
    gtk_tree_view_append_column(treeview, column);
    gtk_tree_view_set_headers_visible(treeview, FALSE);

    selection = gtk_tree_view_get_selection(treeview);
    gtk_tree_selection_set_mode(selection, GTK_SELECTION_NONE);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_container_add(GTK_CONTAINER(window), treewidget);

    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]