Re: Animation in GtkTreeView



Hello all,
      I try to create animation using GtkCellPixmap in GtkTreeView using next
code:

     angle += PIXMAP_ROTATE_STEP;
     rotated_pixbuf = pixmap_rotate (original_pixbuf, angle);

     gtk_list_store_set (GTK_LIST_STORE (tree_model), &iter,
             FILE_LIST_COL_FILE_ICON, rotated_pixbuf,
             -1);

this executes in g_timeout_add callback function.
I find that function gtk_list_store_set is very slow.
(cpu = 100% interval = 50 PIXMAP_ROTATE_STEP = 0.1f,
 cpu = 50% interval = 100 PIXMAP_ROTATE_STEP = 0.1f,
 cpu = 40% interval = 200 PIXMAP_ROTATE_STEP = 0.3f - this look bad)
pixmap_rotate function use cpu for 0%.
Maybe exists GtkCellRenderer that can halp me or another GtkTreeModel
implementation?

Thanks!

and sorry for my bad english.

I solve my problem!
I write my own cell renderer, some interesting code:

static void
cell_renderer_animate_render (GtkCellRenderer *cell,
        GdkWindow *window,
        GtkWidget *widget,
        GdkRectangle *background_area,
        GdkRectangle *cell_area,
        GdkRectangle *expose_area,
        guint flags)
{
    CellRendererAnimate *cell_animate = CELL_RENDERER_ANIMATE (cell);
    gint width, height, x_offset, y_offset;
    GdkDrawable *drawable = GDK_DRAWABLE (window);
    GdkGC *gc = NULL;
    int angel_step = 0;
    gboolean is_timeout_active = FALSE;
    GdkPixbuf *pixbuf = NULL;
    RotateStepInfo *rotate_step_info;

    if (cell_animate->pixbuf)
    {
        if (cell_animate->animate) {
            angel_step = (int)g_object_get_data (G_OBJECT
(cell_animate->pixbuf), "angel");
            is_timeout_active = (gboolean)g_object_get_data (G_OBJECT
(cell_animate->pixbuf), 
                    "timeout_acitve");

            pixbuf = cell_renderer_animate_rotate (cell_animate->pixbuf,
                    CELL_RENDERER_ANIMATE_ROTATE_STEP * angel_step);

            rotate_step_info = g_malloc (sizeof (RotateStepInfo));
            rotate_step_info->cell_area = *cell_area;
            rotate_step_info->widget = widget;
            rotate_step_info->pixbuf = cell_animate->pixbuf;
            if (is_timeout_active == FALSE)
            {
                g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE,
                        CELL_RENDERER_ANIMATE_ROTATE_INTERVAL,
                        cell_renderer_animate_rotate_step,
                        rotate_step_info,
                        g_free);
                g_object_set_data (G_OBJECT (cell_animate->pixbuf), "timeout_acitve",
                        (gpointer) TRUE);
            }
        }
        else
            pixbuf = g_object_ref (cell_animate->pixbuf);

        cell_renderer_animate_get_size (cell, widget, cell_area,
                &x_offset, &y_offset,
                &width, &height);

        width -= cell->xpad*2;
        height -= cell->ypad*2;

        gc = gdk_gc_new (drawable);
        gdk_draw_pixbuf (drawable, gc,
                pixbuf, 0, 0,
                cell_area->x + x_offset + cell->xpad,
                cell_area->y + y_offset + cell->ypad,
                width, height,
                GDK_RGB_DITHER_NONE,
                0, 0);
        g_object_unref (gc);
        g_object_unref (pixbuf);
    }
}

static gboolean
cell_renderer_animate_rotate_step (gpointer data)
{
    RotateStepInfo *rotate_step_info = (RotateStepInfo*)data;
    gint angel_step;

    angel_step = (int)g_object_get_data (G_OBJECT
(rotate_step_info->pixbuf), "angel");
    angel_step ++;
    if (angel_step * CELL_RENDERER_ANIMATE_ROTATE_STEP >= M_PI*2)
        angel_step = 1;
    g_object_set_data (G_OBJECT (rotate_step_info->pixbuf), "angel",
            (gpointer)angel_step);

    gtk_widget_queue_draw_area (rotate_step_info->widget,
            rotate_step_info->cell_area.x,
            // TODO: Why it is need to add
rotate_step_info->cell_area.height????
            rotate_step_info->cell_area.y + rotate_step_info->cell_area.height,
            rotate_step_info->cell_area.width,
            rotate_step_info->cell_area.height);

    g_object_set_data (G_OBJECT (rotate_step_info->pixbuf),
"timeout_acitve",
            (gpointer)FALSE);

    return FALSE;
}

This code work fine cpu load == 0% with ROTATE_STEP = 0.15f and with
ROTATE_INTERVAL = 30!

-- 
Dubravin Andrey <daa84 inbox ru>




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