aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Angelilli <code@fedang.net>2024-03-14 02:00:21 +0100
committerFederico Angelilli <code@fedang.net>2024-03-14 02:00:21 +0100
commit93c4dc6893e733f563e70c315537922d55adfab2 (patch)
tree245e84a64fed1dd56cc9e91b4fa415384caf9322
parent398fdbaa5c02bbd138c59004053d2e8ad0082ead (diff)
Refactor code and start adding shine animation
-rw-r--r--src/animate.c42
-rw-r--r--src/animate.h12
-rw-r--r--src/button.c2
-rw-r--r--src/button.h7
-rw-r--r--src/connect.c12
-rw-r--r--src/draw.h7
-rw-r--r--src/state.c30
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 <glib.h>
+#include <stdbool.h>
#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 <glib.h>
+
+#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 <glib.h>
#include <pango/pangocairo.h>
+#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 <pango/pangocairo.h>
#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);