From c7a8b75933b3bd963e19f1a9d85f3b610a08e669 Mon Sep 17 00:00:00 2001 From: Federico Angelilli Date: Thu, 14 Mar 2024 15:44:41 +0100 Subject: Change animation code and refactor state --- src/state.c | 63 +++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 16 deletions(-) (limited to 'src/state.c') diff --git a/src/state.c b/src/state.c index 134e644..0f17695 100644 --- a/src/state.c +++ b/src/state.c @@ -1,17 +1,14 @@ #include #include "state.h" +#include "log.h" State *state_create(Window *win, Drawer *draw) { - State *state = g_malloc(sizeof(State)); + State *state = g_malloc0(sizeof(State)); g_assert_nonnull(state); - state->win = win; state->draw = draw; - state->btns = NULL; - state->id = 0; - return state; } @@ -40,9 +37,9 @@ void state_order_button(State *state) state->btns = g_list_sort(state->btns, align_compare); } -static gboolean redraw_handler(gpointer data) +static gboolean redraw_handler(State *state) { - State *state = data; + log_debug("Redrawing once [relayout=%d]", state->relayout); if (state->relayout) { draw_compute_layout(state->draw, state->win, state->btns); @@ -51,22 +48,56 @@ static gboolean redraw_handler(gpointer data) draw_paint(state->draw, state->win); - state->id = 0; + state->idle_id = 0; return G_SOURCE_REMOVE; } -void state_redraw(State *state, bool changed_layout) +void state_request_redraw(State *state, bool relayout) { - if (state->id != 0) { - if (!changed_layout || state->relayout) - return; + // Override old redraw + if (state->idle_id != 0) + g_source_remove(state->idle_id); + + state->relayout = relayout; + + if (state->anim_id != 0) return; + + state->idle_id = g_idle_add(G_SOURCE_FUNC(redraw_handler), state); +} + +static gboolean anim_handler(State *state) +{ + //log_debug("Animating [relayout=%d]", state->relayout); + + if (state->relayout) { + draw_compute_layout(state->draw, state->win, state->btns); + state->relayout = false; + } + + draw_paint(state->draw, state->win); - // If we should relayout override old redraw - g_source_remove(state->id); + for (GList *it = state->btns; it != NULL; it = it->next) { + Button *btn = it->data; + if (btn->anim != NULL) + return G_SOURCE_CONTINUE; } - state->relayout = changed_layout; - state->id = g_idle_add_full(G_PRIORITY_HIGH_IDLE, redraw_handler, state, NULL); + state->anim_id = 0; + return G_SOURCE_REMOVE; +} + +void state_request_animation(State *state) +{ + if (state->idle_id != 0) { + g_source_remove(state->idle_id); + state->idle_id = 0; + } + + if (state->anim_id != 0) return; + if (!anim_handler(state)) return; + + const int fps = 60; + state->anim_id = g_timeout_add(1000 / fps, G_SOURCE_FUNC(anim_handler), state); } void state_destroy(State *state) -- cgit v1.2.3