aboutsummaryrefslogtreecommitdiff
path: root/src/state.c
diff options
context:
space:
mode:
authorFederico Angelilli <code@fedang.net>2024-03-14 15:44:41 +0100
committerFederico Angelilli <code@fedang.net>2024-03-14 15:44:41 +0100
commitc7a8b75933b3bd963e19f1a9d85f3b610a08e669 (patch)
tree91de053f1caaf655eaeb1bbd3458c49362b22e2a /src/state.c
parent93c4dc6893e733f563e70c315537922d55adfab2 (diff)
Change animation code and refactor state
Diffstat (limited to 'src/state.c')
-rw-r--r--src/state.c63
1 files changed, 47 insertions, 16 deletions
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 <glib.h>
#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)