diff options
| -rw-r--r-- | src/animate.c | 72 | ||||
| -rw-r--r-- | src/connect.c | 2 | ||||
| -rw-r--r-- | src/draw.c | 7 |
3 files changed, 58 insertions, 23 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); } diff --git a/src/connect.c b/src/connect.c index ae9f295..71552da 100644 --- a/src/connect.c +++ b/src/connect.c @@ -97,7 +97,7 @@ static void button_action(State *state, const char *event, int x, int y) ButtonAction action = button_simple_get_action(layout->btn); if (action != NULL) { - Animation *shine = animation_shine_create(200 * G_TIME_SPAN_MILLISECOND); + Animation *shine = animation_shine_create(300 * G_TIME_SPAN_MILLISECOND); if (button_set_animation(layout->btn, shine)) state_request_animation(state); @@ -54,7 +54,7 @@ void draw_paint(Drawer *draw, Window *win) cairo_t *cr = cairo_create(surface); cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); - cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); double degree = M_PI / 180.0; @@ -70,6 +70,8 @@ void draw_paint(Drawer *draw, Window *win) int radius = layout->height / 2; + cairo_push_group(cr); + Color color = layout->btn->color; cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); cairo_new_sub_path(cr); @@ -104,6 +106,9 @@ void draw_paint(Drawer *draw, Window *win) animation_destroy(layout->btn->anim); layout->btn->anim = NULL; } + + cairo_pop_group_to_source(cr); + cairo_paint(cr); } cairo_destroy(cr); |
