aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFederico Angelilli <code@fedang.net>2024-03-14 23:42:39 +0100
committerFederico Angelilli <code@fedang.net>2024-03-14 23:42:39 +0100
commit5765bea99e1d497063ab312d879390b0dd3d2efd (patch)
tree474befd6fa140801c5d48ce857eb4dc2462616aa /src
parent164a2559cbc9012194484fba767dcd127b36a993 (diff)
Add layout animations and refactor
Diffstat (limited to 'src')
-rw-r--r--src/animate.c32
-rw-r--r--src/animate.h13
-rw-r--r--src/comet.c2
-rw-r--r--src/draw.c33
4 files changed, 63 insertions, 17 deletions
diff --git a/src/animate.c b/src/animate.c
index 7a6f77c..73ca0eb 100644
--- a/src/animate.c
+++ b/src/animate.c
@@ -6,6 +6,18 @@
#include "state.h"
#include "log.h"
+double clamp(double x, double min, double max)
+{
+ const double t = x < min ? min : x;
+ return t > max ? max : t;
+}
+
+double smoothstep(double x, double edge0, double edge1)
+{
+ x = clamp((x - edge0) / (edge1 - edge0), 0, 1);
+ return x * x * (3.0 - 2.0 * x);
+}
+
double quadratic_bezier(double x, double a, double b, double c)
{
g_assert(x >= 0 && x <= 1);
@@ -31,8 +43,6 @@ double cubic_bezier(double x, double a, double b, double c, double d)
typedef struct {
Animation anim;
- gint64 start;
- gint64 duration;
int width;
cairo_pattern_t *gradient;
} AnimationShine;
@@ -40,14 +50,11 @@ typedef struct {
// FIXME: Not working for button group
bool shine_paint(AnimationShine *shine, cairo_t *cr, const Layout *layout)
{
+ gint64 end = shine->anim.start + shine->anim.duration;
gint64 now = g_get_monotonic_time();
- if (shine->start == 0)
- shine->start = now;
-
- gint64 end = shine->start + shine->duration;
if (now > end) return false;
- double t = (double)(now - shine->start) / (end - shine->start);
+ double t = (double)(now - shine->anim.start) / (end - shine->anim.start);
double pos = cubic_bezier(t, 0.19, 1.0, 0.22, 1.0);
double angle = atan((double)layout->height / layout->width);
@@ -81,8 +88,8 @@ Animation *animation_shine_create(gint64 duration)
// Note the 0 initialization
AnimationShine *shine = g_malloc0(sizeof(AnimationShine));
shine->anim.type = ANIM_SHINE;
- shine->anim.paint = (DrawFunc)shine_paint;
- shine->duration = duration;
+ shine->anim.paint_func = (DrawFunc)shine_paint;
+ shine->anim.duration = duration;
// TODO: Change it depending on container size
shine->width = 20;
@@ -95,7 +102,12 @@ Animation *animation_shine_create(gint64 duration)
return (gpointer)shine;
}
-//XXX
+Animation *animation_pulse_create(gint64 duration)
+{
+ // TODO
+ return NULL;
+}
+
void animation_destroy(Animation *anim)
{
if (anim == NULL) return;
diff --git a/src/animate.h b/src/animate.h
index c243287..a4ded33 100644
--- a/src/animate.h
+++ b/src/animate.h
@@ -9,20 +9,31 @@ typedef struct Animation Animation;
typedef struct State State;
typedef bool (* DrawFunc)(Animation *anim, cairo_t *cr, const Layout *layout);
+typedef bool (* LayoutFunc)(Animation *anim, Layout *layout);
struct Animation {
enum {
ANIM_SHINE,
+ ANIM_PULSE,
} type;
- DrawFunc paint;
+ DrawFunc paint_func;
+ LayoutFunc layout_func;
+ gint64 start;
+ gint64 duration;
};
+double clamp(double x, double min, double max);
+
+double smoothstep(double x, double edge0, double edge1);
+
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_shine_create(gint64 duration);
+Animation *animation_pulse_create(gint64 duration);
+
void animation_destroy(Animation *anim);
#endif
diff --git a/src/comet.c b/src/comet.c
index ea574cc..3ec6bc7 100644
--- a/src/comet.c
+++ b/src/comet.c
@@ -306,7 +306,7 @@ int main(int argc, char **argv)
// Date & time button
Button *date_btn = button_simple_create(PANGO_ALIGN_CENTER, color, line_color);
button_simple_set_text(date_btn, g_strdup("date"), text_color);
- button_simple_set_action(date_btn, show_action, &date_ctx);
+ button_simple_set_action(date_btn, NULL, &date_ctx);
state_add_button(state, date_btn);
struct sigevent sev = { 0 };
diff --git a/src/draw.c b/src/draw.c
index 9fcc54b..5171321 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -102,9 +102,23 @@ void draw_paint(Drawer *draw, Window *win)
pango_cairo_show_layout(cr, layout->pl);
}
- if (layout->btn->anim != NULL && !layout->btn->anim->paint(layout->btn->anim, cr, layout)) {
- animation_destroy(layout->btn->anim);
- layout->btn->anim = NULL;
+ if (layout->btn->anim != NULL) {
+ if (layout->btn->anim->paint_func != NULL) {
+ if (layout->btn->anim->start == 0) {
+ layout->btn->anim->start = g_get_monotonic_time();
+ log_debug("Starting animation [start=%ld, duration=%ld, button=%p]",
+ layout->btn->anim->start, layout->btn->anim->duration, layout->btn);
+ }
+
+ if (!layout->btn->anim->paint_func(layout->btn->anim, cr, layout))
+ layout->btn->anim->paint_func = NULL;
+
+ } else if (layout->btn->anim->paint_func == NULL) {
+ // Remove animation if both paint_func and layout_func finished
+ animation_destroy(layout->btn->anim);
+ layout->btn->anim = NULL;
+ log_debug("Removing animation [button=%p]", layout->btn);
+ }
}
cairo_pop_group_to_source(cr);
@@ -231,6 +245,17 @@ void draw_compute_layout(Drawer *draw, Window *win, GList *btns)
}
}
+ if (btn->anim != NULL && btn->anim->layout_func != NULL) {
+ if (layout->btn->anim->start == 0) {
+ layout->btn->anim->start = g_get_monotonic_time();
+ log_debug("Starting animation [start=%ld, duration=%ld, button=%p]",
+ layout->btn->anim->start, layout->btn->anim->duration, layout->btn);
+ }
+
+ if (!btn->anim->layout_func(btn->anim, layout))
+ btn->anim->layout_func = NULL;
+ }
+
if (layout->btn->simple) {
layout->pl = pango_cairo_create_layout(window_get_context(win));
layout_text(layout, draw->desc, height, radius);
@@ -246,8 +271,6 @@ void draw_compute_layout(Drawer *draw, Window *win, GList *btns)
draw->layouts = g_list_reverse(draw->layouts);
- // FIXME: BUG! Explodes if the buttons are not loaded with the left first!!!
-
int layout_width[3] = {
layout_end[PANGO_ALIGN_LEFT],
layout_end[PANGO_ALIGN_CENTER] - layout_end[PANGO_ALIGN_LEFT],