diff options
author | Alexey Yakovenko <wakeroid@gmail.com> | 2009-10-23 19:47:29 +0200 |
---|---|---|
committer | Alexey Yakovenko <wakeroid@gmail.com> | 2009-10-23 19:47:29 +0200 |
commit | 57c3e22114062dfdfe00944e93bc07476d45137f (patch) | |
tree | 906f0ab20cb30521096165c391e0f9699c361165 /gtkplaylist.c | |
parent | cb169a518b82993cd50ba11cb91a7aea4ef0dae2 (diff) |
animation effects WIP
Diffstat (limited to 'gtkplaylist.c')
-rw-r--r-- | gtkplaylist.c | 118 |
1 files changed, 112 insertions, 6 deletions
diff --git a/gtkplaylist.c b/gtkplaylist.c index 5dcd6792..a4fe67c7 100644 --- a/gtkplaylist.c +++ b/gtkplaylist.c @@ -45,6 +45,7 @@ #include "session.h" #include "deadbeef.h" #include "conf.h" +#include "timeline.h" //#define trace(...) { fprintf(stderr, __VA_ARGS__); } #define trace(fmt,...) @@ -97,6 +98,78 @@ static int header_dragging = -1; static int header_sizing = -1; static int header_dragpt[2]; +#define COLHDR_ANIM_TIME 0.2f + +typedef struct { + int c1; + int c2; + int x1, x2; + int dx1, dx2; + // animated values + int ax1, ax2; + timeline_t *timeline; + int anim_active; + gtkplaylist_t *pl; +} colhdr_animator_t; + +static colhdr_animator_t colhdr_anim; + +static gboolean +redraw_header (colhdr_animator_t *anim) { + gtkpl_header_draw (anim->pl); + gtkpl_expose_header (anim->pl, 0, 0, anim->pl->header->allocation.width, anim->pl->header->allocation.height); + return FALSE; +} + + +static int +colhdr_anim_cb (float _progress, int _last, void *_ctx) { + colhdr_animator_t *anim = (colhdr_animator_t *)_ctx; + anim->ax1 = anim->x1 + (float)(anim->dx1 - anim->x1) * _progress; + anim->ax2 = anim->x2 + (float)(anim->dx2 - anim->x2) * _progress; +// printf ("%f %d %d\n", _progress, anim->ax1, anim->ax2); + g_idle_add (redraw_header, anim); + if (_last) { + anim->anim_active = 0; + } + return 0; +} + +static void +colhdr_anim_swap (gtkplaylist_t *pl, int c1, int c2, int x1, int x2) { + // interrupt previous anim + if (!colhdr_anim.timeline) { + colhdr_anim.timeline = timeline_create (); + } + colhdr_anim.pl = pl; + + colhdr_anim.c1 = c1; + colhdr_anim.c2 = c2; + + // find c1 and c2 in column list and setup coords + // note: columns are already swapped, so their coords must be reversed, + // as if before swap + gtkpl_column_t *c; + int idx = 0; + int x = 0; + for (c = pl->columns; c; c = c->next, idx++) { + if (idx == c1) { + colhdr_anim.x1 = x1; + colhdr_anim.dx2 = x; + } + else if (idx == c2) { + colhdr_anim.x2 = x2; + colhdr_anim.dx1 = x; + } + x += c->width; + } + colhdr_anim.anim_active = 1; + timeline_stop (colhdr_anim.timeline, 0); + timeline_init (colhdr_anim.timeline, COLHDR_ANIM_TIME, 100, colhdr_anim_cb, &colhdr_anim); + printf ("timeline_start\n"); + timeline_start (colhdr_anim.timeline); +} + // that must be called before gtk_init void gtkpl_init (void) { @@ -110,6 +183,10 @@ gtkpl_init (void) { void gtkpl_free (gtkplaylist_t *pl) { + if (colhdr_anim.timeline) { + timeline_free (colhdr_anim.timeline, 1); + colhdr_anim.timeline = 0; + } while (pl->columns) { gtkpl_column_t *next = pl->columns->next; gtkpl_column_free (pl->columns); @@ -1176,16 +1253,25 @@ gtkpl_header_draw (gtkplaylist_t *ps) { int idx = 0; for (c = ps->columns; c; c = c->next, idx++) { w = c->width; + int xx = x; + if (colhdr_anim.anim_active) { + if (idx == colhdr_anim.c2) { + xx = colhdr_anim.ax1; + } + else if (idx == colhdr_anim.c1) { + xx = colhdr_anim.ax2; + } + } if (header_dragging < 0 || idx != header_dragging) { - if (x >= widget->allocation.width) { + if (xx >= widget->allocation.width) { continue; } if (w > 0) { - gtk_paint_vline (widget->style, ps->backbuf_header, GTK_STATE_NORMAL, NULL, NULL, NULL, 0, h, x+w - 2); + gtk_paint_vline (widget->style, ps->backbuf_header, GTK_STATE_NORMAL, NULL, NULL, NULL, 0, h, xx+w - 2); GdkColor *gdkfg = &widget->style->fg[0]; float fg[3] = {(float)gdkfg->red/0xffff, (float)gdkfg->green/0xffff, (float)gdkfg->blue/0xffff}; draw_set_fg_color (fg); - draw_text (x + 5, h/2-draw_get_font_size()/2, c->width-10, 0, c->title); + draw_text (xx + 5, h/2-draw_get_font_size()/2, c->width-10, 0, c->title); } } else { @@ -1199,6 +1285,14 @@ gtkpl_header_draw (gtkplaylist_t *ps) { for (c = ps->columns; c; c = c->next, idx++) { w = c->width; if (idx == header_dragging) { + if (colhdr_anim.anim_active) { + if (idx == colhdr_anim.c2) { + x = colhdr_anim.ax1; + } + else if (idx == colhdr_anim.c1) { + x = colhdr_anim.ax2; + } + } // draw empty slot if (x < widget->allocation.width) { gtk_paint_box (widget->style, ps->backbuf_header, GTK_STATE_ACTIVE, GTK_SHADOW_ETCHED_IN, NULL, NULL, "button", x, 0, w, h); @@ -1214,6 +1308,7 @@ gtkpl_header_draw (gtkplaylist_t *ps) { draw_set_fg_color (fg); draw_text (x + 5, h/2-draw_get_font_size()/2, c->width-10, 0, c->title); } + break; } x += w; } @@ -1281,13 +1376,20 @@ on_header_motion_notify_event (GtkWidget *widget, gtkpl_column_t *cc; int x = 0; int idx = 0; + int x1 = -1, x2 = -1; for (cc = ps->columns; cc; cc = cc->next, idx++) { if (x < c->movepos && x + c->width > c->movepos) { inspos = idx; + x1 = x; + } + else if (idx == header_dragging) { + x2 = x; } x += cc->width; } if (inspos >= 0 && inspos != header_dragging) { + int c1 = inspos; + int c2 = header_dragging; // remove c from list if (c == ps->columns) { ps->columns = c->next; @@ -1318,14 +1420,18 @@ on_header_motion_notify_event (GtkWidget *widget, } } } +// colhdr_anim_swap (ps, c1, c2, x1, x2); // force redraw of everything - gtkpl_setup_hscrollbar (ps); +// gtkpl_setup_hscrollbar (ps); gtkpl_draw_playlist (ps, 0, 0, ps->playlist->allocation.width, ps->playlist->allocation.height); gtkpl_expose (ps, 0, 0, ps->playlist->allocation.width, ps->playlist->allocation.height); gtkpl_column_update_config (ps, c, i); } - gtkpl_header_draw (ps); - gtkpl_expose_header (ps, 0, 0, ps->header->allocation.width, ps->header->allocation.height); + else { + // only redraw that if not animating + gtkpl_header_draw (ps); + gtkpl_expose_header (ps, 0, 0, ps->header->allocation.width, ps->header->allocation.height); + } } else if (header_sizing >= 0) { // limit event rate |