summaryrefslogtreecommitdiff
path: root/gtkplaylist.c
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2009-10-23 19:47:29 +0200
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2009-10-23 19:47:29 +0200
commit57c3e22114062dfdfe00944e93bc07476d45137f (patch)
tree906f0ab20cb30521096165c391e0f9699c361165 /gtkplaylist.c
parentcb169a518b82993cd50ba11cb91a7aea4ef0dae2 (diff)
animation effects WIP
Diffstat (limited to 'gtkplaylist.c')
-rw-r--r--gtkplaylist.c118
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