From 93c4dc6893e733f563e70c315537922d55adfab2 Mon Sep 17 00:00:00 2001 From: Federico Angelilli Date: Thu, 14 Mar 2024 02:00:21 +0100 Subject: Refactor code and start adding shine animation --- src/animate.c | 42 ++++++++++++++++++++++++++++++++++++++---- src/animate.h | 12 +++++++++++- src/button.c | 2 ++ src/button.h | 7 +++---- src/connect.c | 12 +++++++++++- src/draw.h | 7 +++++-- src/state.c | 30 +++++++++++++++--------------- 7 files changed, 85 insertions(+), 27 deletions(-) diff --git a/src/animate.c b/src/animate.c index 7b95e9c..33b4e8f 100644 --- a/src/animate.c +++ b/src/animate.c @@ -1,6 +1,9 @@ #include +#include #include "animate.h" +#include "state.h" +#include "log.h" double quadratic_bezier(double x, double a, double b, double c) { @@ -25,15 +28,46 @@ double cubic_bezier(double x, double a, double b, double c, double d) return a * (t * t * t) + 3 * b * (t * t * x) + 3 * c * (t * x * x) + d * (x * x * x); } -Animation *animation_create() +typedef struct { + Animation anim; + State *state; + gint64 start; + gint64 duration; + double x; +} AnimationShine; + +static gboolean shine_handler(AnimationShine *anim) +{ + gint64 now = g_get_monotonic_time(); + if (anim->start == 0) + anim->start = now; + + gint64 end = anim->start + anim->duration; + if (now > end) { + anim->x = 1.0; + state_redraw(anim->state, false); + return G_SOURCE_REMOVE; + } + + double t = (double)(now - anim->start) / (end - anim->start); + anim->x = cubic_bezier(t, 0.19, 1.0, 0.22, 1.0); + state_redraw(anim->state, false); + return G_SOURCE_CONTINUE; +} + +Animation *animation_shine_create(State *state, gint64 duration) { - Animation *anim = g_malloc0(sizeof(Animation)); - // TODO - return anim; + AnimationShine *anim = g_malloc0(sizeof(AnimationShine)); + anim->anim.type = ANIM_SHINE; + anim->anim.handler = G_SOURCE_FUNC(shine_handler); + anim->state = state; + anim->duration = duration; + return (gpointer)anim; } void animation_destroy(Animation *anim) { + //XXX g_free(anim); } diff --git a/src/animate.h b/src/animate.h index 3f8d4a6..3bfa87f 100644 --- a/src/animate.h +++ b/src/animate.h @@ -1,18 +1,28 @@ #ifndef COMET_ANIMATE_H #define COMET_ANIMATE_H +#include + +#include "draw.h" + +// TODO: Custom drawing for animations +typedef void (* DrawFunc)(cairo_t *cr, const Layout *layout); + +typedef struct State State; + typedef struct { enum { ANIM_SHINE, } type; GSourceFunc handler; + DrawFunc paint; } Animation; double quadratic_bezier(double x, double a, double b, double c); double cubic_bezier(double x, double a, double b, double c, double d); -Animation *animation_create(); +Animation *animation_shine_create(State *state, gint64 duration); void animation_destroy(Animation *anim); diff --git a/src/button.c b/src/button.c index 01d4e36..b313f8a 100644 --- a/src/button.c +++ b/src/button.c @@ -94,6 +94,8 @@ void button_start_animation(Button *btn) const int fps = 60; if (btn->anim->handler(btn->anim)) g_timeout_add(1000 / 60, anim_handler, btn); + + log_debug("Started animation [type=%d, button=%p]", btn->anim->type, btn); } void button_destroy(Button *btn) diff --git a/src/button.h b/src/button.h index 923321e..5492599 100644 --- a/src/button.h +++ b/src/button.h @@ -5,6 +5,7 @@ #include #include +#include "draw.h" #include "animate.h" // For pointers only @@ -14,10 +15,6 @@ typedef struct Button Button; typedef void (* ButtonAction)(Button *btn); -typedef struct { - double r, g, b, a; -} Color; - struct Button { bool simple; int padding; @@ -62,6 +59,8 @@ void button_set_padding(Button *btn, int padding); bool button_set_animation(Button *btn, Animation *anim); +void button_start_animation(Button *btn); + void button_destroy(Button *btn); #endif diff --git a/src/connect.c b/src/connect.c index 24f6463..d5d4f12 100644 --- a/src/connect.c +++ b/src/connect.c @@ -95,7 +95,17 @@ static void button_action(State *state, const char *event, int x, int y) if (in_capsule(x, y, layout->x, layout->y, layout->width, layout->height)) { log_debug("Triggering action for button"); ButtonAction action = button_simple_get_action(layout->btn); - if (action != NULL) action(layout->btn); + + if (action != NULL) { + action(layout->btn); + + Animation *shine = animation_shine_create(state, 500 * G_TIME_SPAN_MILLISECOND); + if (button_set_animation(layout->btn, shine)) + button_start_animation(layout->btn); + else + animation_destroy(shine); + } + return; } } else { diff --git a/src/draw.h b/src/draw.h index 26bda6b..8d8a806 100644 --- a/src/draw.h +++ b/src/draw.h @@ -6,7 +6,10 @@ #include #include "window.h" -#include "button.h" + +typedef struct { + double r, g, b, a; +} Color; // The one who draws ('o')7 @@ -22,7 +25,7 @@ typedef struct { } Drawer; typedef struct { - Button *btn; + struct Button *btn; int x, y; int width, height; int text_w, text_h; diff --git a/src/state.c b/src/state.c index 2051652..134e644 100644 --- a/src/state.c +++ b/src/state.c @@ -25,6 +25,21 @@ void state_remove_button(State *state, Button *btn) state->btns = g_list_remove(state->btns, btn); } +static gint align_compare(gconstpointer a, gconstpointer b) +{ + PangoAlignment a_align = CAST(a, Button)->align; + PangoAlignment b_align = CAST(b, Button)->align; + + if (a_align < b_align) return -1; + if (a_align > b_align) return 1; + return 0; +} + +void state_order_button(State *state) +{ + state->btns = g_list_sort(state->btns, align_compare); +} + static gboolean redraw_handler(gpointer data) { State *state = data; @@ -54,21 +69,6 @@ void state_redraw(State *state, bool changed_layout) state->id = g_idle_add_full(G_PRIORITY_HIGH_IDLE, redraw_handler, state, NULL); } -static gint align_compare(gconstpointer a, gconstpointer b) -{ - PangoAlignment a_align = ((Button *)a)->align; - PangoAlignment b_align = ((Button *)b)->align; - - if (a_align < b_align) return -1; - if (a_align > b_align) return 1; - return 0; -} - -void state_order_button(State *state) -{ - state->btns = g_list_sort(state->btns, align_compare); -} - void state_destroy(State *state) { g_list_free_full(state->btns, (void *)button_destroy); -- cgit v1.2.3