aboutsummaryrefslogtreecommitdiff
path: root/src/animate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/animate.c')
-rw-r--r--src/animate.c72
1 files changed, 51 insertions, 21 deletions
diff --git a/src/animate.c b/src/animate.c
index ca5cbfe..7a6f77c 100644
--- a/src/animate.c
+++ b/src/animate.c
@@ -1,5 +1,6 @@
#include <glib.h>
#include <stdbool.h>
+#include <math.h>
#include "animate.h"
#include "state.h"
@@ -32,47 +33,76 @@ typedef struct {
Animation anim;
gint64 start;
gint64 duration;
+ int width;
+ cairo_pattern_t *gradient;
} AnimationShine;
-bool shine_paint(AnimationShine *anim, cairo_t *cr, const Layout *layout)
+// FIXME: Not working for button group
+bool shine_paint(AnimationShine *shine, cairo_t *cr, const Layout *layout)
{
gint64 now = g_get_monotonic_time();
- if (anim->start == 0)
- anim->start = now;
+ if (shine->start == 0)
+ shine->start = now;
- gint64 end = anim->start + anim->duration;
- double pos = 1.0;
+ gint64 end = shine->start + shine->duration;
+ if (now > end) return false;
- if (now <= end) {
- double t = (double)(now - anim->start) / (end - anim->start);
- pos = cubic_bezier(t, 0.19, 1.0, 0.22, 1.0);
- }
+ double t = (double)(now - shine->start) / (end - shine->start);
+ double pos = cubic_bezier(t, 0.19, 1.0, 0.22, 1.0);
- int w = 10;
- int x = layout->x + pos * layout->width - w;
+ double angle = atan((double)layout->height / layout->width);
+
+ // Make it double just to be sure
+ int h = 2 * (double)layout->height / cos(angle);
+ int x = layout->x + pos * layout->width - shine->width;
int y = layout->y;
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- cairo_set_source_rgba(cr, 1, 1, 1, 0.1);
- cairo_rectangle(cr, x, y, w, layout->height);
+ cairo_matrix_t matrix;
+ cairo_matrix_init_translate(&matrix, -x, -y);
+ cairo_pattern_set_matrix(shine->gradient, &matrix);
+
+ int dx = layout->x + layout->width / 2;
+ int dy = layout->y + layout->height / 2;
+
+ cairo_translate(cr, dx, dy);
+ cairo_rotate(cr, -angle);
+ cairo_translate(cr, -dx, -dy);
+
+ cairo_set_operator(cr, CAIRO_OPERATOR_ATOP);
+ cairo_set_source(cr, shine->gradient);
+ cairo_rectangle(cr, x, y - (h - layout->height) / 2, shine->width, h);
cairo_fill(cr);
- return pos < 1.0;
+ return true;
}
Animation *animation_shine_create(gint64 duration)
{
// Note the 0 initialization
- AnimationShine *anim = g_malloc0(sizeof(AnimationShine));
- anim->anim.type = ANIM_SHINE;
- anim->anim.paint = (DrawFunc)shine_paint;
- anim->duration = duration;
- return (gpointer)anim;
+ AnimationShine *shine = g_malloc0(sizeof(AnimationShine));
+ shine->anim.type = ANIM_SHINE;
+ shine->anim.paint = (DrawFunc)shine_paint;
+ shine->duration = duration;
+
+ // TODO: Change it depending on container size
+ shine->width = 20;
+
+ shine->gradient = cairo_pattern_create_linear(0, 0, shine->width, 0);
+ cairo_pattern_add_color_stop_rgba(shine->gradient, 0, 1, 1, 1, 0);
+ cairo_pattern_add_color_stop_rgba(shine->gradient, 0.5, 1, 1, 1, 0.333);
+ cairo_pattern_add_color_stop_rgba(shine->gradient, 1, 1, 1, 1, 0);
+
+ return (gpointer)shine;
}
+//XXX
void animation_destroy(Animation *anim)
{
- //XXX
+ if (anim == NULL) return;
+
+ if (anim->type == ANIM_SHINE)
+ cairo_pattern_destroy(CAST(anim, AnimationShine)->gradient);
+
g_free(anim);
}