started animation implementation

This commit is contained in:
Felix Kratz 2022-05-16 15:00:39 +02:00
parent 985d51c930
commit 4d860a8c9c
9 changed files with 179 additions and 11 deletions

View file

@ -5,7 +5,8 @@ SRC = src
_OBJ = alias.o background.o bar_item.o custom_events.o event.o graph.o \ _OBJ = alias.o background.o bar_item.o custom_events.o event.o graph.o \
image.o mouse.o shadow.o text.o message.o mouse.o ax.o bar.o window.o \ image.o mouse.o shadow.o text.o message.o mouse.o ax.o bar.o window.o \
bar_manager.o display.o event_loop.o group.o mach.o popup.o workspace.om bar_manager.o display.o event_loop.o group.o mach.o popup.o \
animation.o workspace.om
OBJ = $(patsubst %, $(ODIR)/%, $(_OBJ)) OBJ = $(patsubst %, $(ODIR)/%, $(_OBJ))
.PHONY: all clean arm x86 profile leak universal .PHONY: all clean arm x86 profile leak universal

113
src/animation.c Normal file
View file

@ -0,0 +1,113 @@
#include "animation.h"
#include "event.h"
uint32_t function_linear(uint32_t x, double m, uint32_t b) {
return ((double)m)*((int)x) + (int)b;
}
static ANIMATOR_CALLBACK(animator_handler) {
struct event *event = event_create(&g_event_loop, ANIMATOR_REFRESH, NULL);
event_loop_post(&g_event_loop, event);
}
struct animation* animation_create() {
struct animation* animation = malloc(sizeof(struct animation));
memset(animation, 0, sizeof(struct animation));
return animation;
}
void animation_destroy(struct animation* animation) {
if (animation) free(animation);
}
void animation_setup(struct animation* animation, uint32_t* property, uint32_t final_value, uint32_t duration) {
animation->counter = 1;
animation->duration = duration;
animation->initial_value = *property;
animation->final_value = final_value;
animation->target = property;
}
bool animation_update(struct animation* animation) {
if (!animation->target || animation->counter > animation->duration) {
return false;
}
*animation->target = function_linear(animation->counter,
((double)(animation->final_value)
- ((double)animation->initial_value))
/ ((double)animation->duration),
animation->initial_value );
animation->counter++;
return animation->counter <= animation->duration;
}
void animator_init(struct animator* animator) {
animator->animations = NULL;
animator->animation_count = 0;
}
void animator_add(struct animator* animator, struct animation* animation) {
animator->animations = realloc(animator->animations,
sizeof(struct animaton*)
* ++animator->animation_count);
animator->animations[animator->animation_count - 1] = animation;
if (animator->animation_count == 1) {
animator->clock = CFRunLoopTimerCreate(NULL,
CFAbsoluteTimeGetCurrent()+1./60.,
1./60.,
0,
0,
animator_handler,
NULL );
CFRunLoopAddTimer(CFRunLoopGetMain(),
animator->clock,
kCFRunLoopCommonModes);
}
}
void animator_remove(struct animator* animator, struct animation* animation) {
if (animator->animation_count == 1) {
free(animator->animations);
animator->animations = NULL;
animator->animation_count = 0;
} else {
struct animation* tmp[animator->animation_count - 1];
int count = 0;
for (int i = 0; i < animator->animation_count; i++) {
if (animator->animations[i] == animation) continue;
tmp[count++] = animator->animations[i];
}
animator->animation_count--;
animator->animations = realloc(animator->animations,
sizeof(struct animation*)
*animator->animation_count);
memcpy(animator->animations,
tmp,
sizeof(struct animation*)*animator->animation_count);
}
animation_destroy(animation);
if (animator->animation_count == 0) {
CFRunLoopRemoveTimer(CFRunLoopGetMain(),
animator->clock,
kCFRunLoopCommonModes);
CFRelease(animator->clock);
}
}
void animator_update(struct animator* animator) {
for (uint32_t i = 0; i < animator->animation_count; i++) {
if (!animation_update(animator->animations[i])) {
animator_remove(animator, animator->animations[i]);
i--;
}
}
}

35
src/animation.h Normal file
View file

@ -0,0 +1,35 @@
#pragma once
#include "misc/helpers.h"
struct animation {
uint32_t duration;
uint32_t counter;
uint32_t initial_value;
uint32_t final_value;
uint32_t* target;
};
struct animation* animation_create();
void animation_destroy(struct animation* animation);
void animation_setup(struct animation* animation, uint32_t* property, uint32_t final_value, uint32_t duration);
bool animation_update(struct animation* animation);
extern struct event_loop g_event_loop;
#define ANIMATOR_CALLBACK(name) void name(CFRunLoopTimerRef timer, void *context)
typedef ANIMATOR_CALLBACK(animator_callback);
struct animator {
CFRunLoopTimerRef clock;
struct animation** animations;
uint32_t animation_count;
};
void animator_init(struct animator* animator);
void animator_add(struct animator* animator, struct animation* animation);
void animator_remove(struct animator* animator, struct animation* animation);
void animator_update(struct animator* animator);

View file

@ -106,6 +106,9 @@ void bar_draw(struct bar* bar) {
void bar_calculate_bounds(struct bar* bar) { void bar_calculate_bounds(struct bar* bar) {
if (bar->hidden) return; if (bar->hidden) return;
if (bar->sid == 0) return; if (bar->sid == 0) return;
uint32_t notch_width = CGDisplayIsBuiltin(bar->did)
? g_bar_manager.notch_width
: 0;
uint32_t center_length = bar_manager_length_for_bar_side(&g_bar_manager, uint32_t center_length = bar_manager_length_for_bar_side(&g_bar_manager,
bar, bar,
@ -120,10 +123,10 @@ void bar_calculate_bounds(struct bar* bar) {
- center_length) / 2 - 1; - center_length) / 2 - 1;
uint32_t bar_center_right_first_item_x = (bar->window.frame.size.width uint32_t bar_center_right_first_item_x = (bar->window.frame.size.width
+ bar->notch_width) / 2 - 1; + notch_width) / 2 - 1;
uint32_t bar_center_left_first_item_x = (bar->window.frame.size.width uint32_t bar_center_left_first_item_x = (bar->window.frame.size.width
- bar->notch_width) / 2 - 1; - notch_width) / 2 - 1;
uint32_t* next_position = NULL; uint32_t* next_position = NULL;
uint32_t y = bar->window.frame.size.height / 2; uint32_t y = bar->window.frame.size.height / 2;
@ -231,7 +234,6 @@ struct bar *bar_create(uint32_t did) {
bar->hidden = false; bar->hidden = false;
bar->did = did; bar->did = did;
bar->sid = mission_control_index(display_space_id(did)); bar->sid = mission_control_index(display_space_id(did));
bar->notch_width = CGDisplayIsBuiltin(did) ? g_bar_manager.notch_width : 0;
bar->shown = true; bar->shown = true;
bar_create_window(bar); bar_create_window(bar);
return bar; return bar;

View file

@ -17,7 +17,6 @@ struct bar {
uint32_t did; uint32_t did;
uint32_t sid; uint32_t sid;
uint32_t adid; uint32_t adid;
uint32_t notch_width;
struct window window; struct window window;
}; };

View file

@ -42,6 +42,8 @@ void bar_manager_init(struct bar_manager* bar_manager) {
bar_item_set_name(&bar_manager->default_item, string_copy("defaults")); bar_item_set_name(&bar_manager->default_item, string_copy("defaults"));
custom_events_init(&bar_manager->custom_events); custom_events_init(&bar_manager->custom_events);
animator_init(&bar_manager->animator);
int shell_refresh_frequency = 1; int shell_refresh_frequency = 1;
bar_manager->clock = CFRunLoopTimerCreate(NULL, bar_manager->clock = CFRunLoopTimerCreate(NULL,
@ -195,11 +197,8 @@ bool bar_manager_set_shadow(struct bar_manager* bar_manager, bool shadow) {
bool bar_manager_set_notch_width(struct bar_manager* bar_manager, uint32_t width) { bool bar_manager_set_notch_width(struct bar_manager* bar_manager, uint32_t width) {
if (bar_manager->notch_width == width) return false; if (bar_manager->notch_width == width) return false;
bar_manager->notch_width = width;
for (int i = 0; i < bar_manager->bar_count; ++i)
bar_destroy(bar_manager->bars[i]);
bar_manager_begin(bar_manager); bar_manager->notch_width = width;
return true; return true;
} }
@ -374,6 +373,11 @@ void bar_manager_update_space_components(struct bar_manager* bar_manager, bool f
} }
} }
void bar_manager_animator_refresh(struct bar_manager* bar_manager) {
animator_update(&bar_manager->animator);
bar_manager_refresh(bar_manager, true);
}
void bar_manager_update(struct bar_manager* bar_manager, bool forced) { void bar_manager_update(struct bar_manager* bar_manager, bool forced) {
if ((bar_manager->frozen && !forced) || bar_manager->sleeps) return; if ((bar_manager->frozen && !forced) || bar_manager->sleeps) return;
bool needs_refresh = false; bool needs_refresh = false;

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "bar.h" #include "bar.h"
#include "bar_item.h" #include "bar_item.h"
#include "animation.h"
#define CLOCK_CALLBACK(name) void name(CFRunLoopTimerRef timer, void *context) #define CLOCK_CALLBACK(name) void name(CFRunLoopTimerRef timer, void *context)
typedef CLOCK_CALLBACK(clock_callback); typedef CLOCK_CALLBACK(clock_callback);
@ -27,14 +28,16 @@ struct bar_manager {
uint32_t window_level; uint32_t window_level;
struct bar** bars; struct bar** bars;
int bar_count; uint32_t bar_count;
struct bar_item** bar_items; struct bar_item** bar_items;
struct bar_item default_item; struct bar_item default_item;
int bar_item_count; uint32_t bar_item_count;
struct background background; struct background background;
struct custom_events custom_events; struct custom_events custom_events;
struct animator animator;
}; };
struct bar_manager g_bar_manager; struct bar_manager g_bar_manager;
@ -46,6 +49,7 @@ void bar_manager_remove_item(struct bar_manager* bar_manager, struct bar_item* b
void bar_manager_move_item(struct bar_manager* bar_manager, struct bar_item* item, struct bar_item* reference, bool before); void bar_manager_move_item(struct bar_manager* bar_manager, struct bar_item* item, struct bar_item* reference, bool before);
void bar_manager_handle_notification(struct bar_manager* bar_manager, struct notification* notification); void bar_manager_handle_notification(struct bar_manager* bar_manager, struct notification* notification);
void bar_manager_animator_refresh(struct bar_manager* bar_manager);
void bar_manager_update(struct bar_manager* bar_manager, bool forced); void bar_manager_update(struct bar_manager* bar_manager, bool forced);
void bar_manager_update_space_components(struct bar_manager* bar_manager, bool forced); void bar_manager_update_space_components(struct bar_manager* bar_manager, bool forced);
bool bar_manager_set_background_blur(struct bar_manager* bar_manager, uint32_t radius); bool bar_manager_set_background_blur(struct bar_manager* bar_manager, uint32_t radius);

View file

@ -96,6 +96,12 @@ EVENT_CALLBACK(EVENT_HANDLER_SHELL_REFRESH) {
return EVENT_SUCCESS; return EVENT_SUCCESS;
} }
EVENT_CALLBACK(EVENT_HANDLER_ANIMATOR_REFRESH) {
debug("%s\n", __FUNCTION__);
bar_manager_animator_refresh(&g_bar_manager);
return EVENT_SUCCESS;
}
EVENT_CALLBACK(EVENT_HANDLER_MACH_MESSAGE) { EVENT_CALLBACK(EVENT_HANDLER_MACH_MESSAGE) {
debug("%s\n", __FUNCTION__); debug("%s\n", __FUNCTION__);

View file

@ -24,6 +24,7 @@ EVENT_CALLBACK(EVENT_HANDLER_MENU_BAR_HIDDEN_CHANGED);
EVENT_CALLBACK(EVENT_HANDLER_SYSTEM_WOKE); EVENT_CALLBACK(EVENT_HANDLER_SYSTEM_WOKE);
EVENT_CALLBACK(EVENT_HANDLER_SYSTEM_WILL_SLEEP); EVENT_CALLBACK(EVENT_HANDLER_SYSTEM_WILL_SLEEP);
EVENT_CALLBACK(EVENT_HANDLER_SHELL_REFRESH); EVENT_CALLBACK(EVENT_HANDLER_SHELL_REFRESH);
EVENT_CALLBACK(EVENT_HANDLER_ANIMATOR_REFRESH);
EVENT_CALLBACK(EVENT_HANDLER_MACH_MESSAGE); EVENT_CALLBACK(EVENT_HANDLER_MACH_MESSAGE);
EVENT_CALLBACK(EVENT_HANDLER_MOUSE_UP); EVENT_CALLBACK(EVENT_HANDLER_MOUSE_UP);
EVENT_CALLBACK(EVENT_HANDLER_MOUSE_ENTERED); EVENT_CALLBACK(EVENT_HANDLER_MOUSE_ENTERED);
@ -53,6 +54,7 @@ enum event_type {
SYSTEM_WOKE, SYSTEM_WOKE,
SYSTEM_WILL_SLEEP, SYSTEM_WILL_SLEEP,
SHELL_REFRESH, SHELL_REFRESH,
ANIMATOR_REFRESH,
MACH_MESSAGE, MACH_MESSAGE,
MOUSE_UP, MOUSE_UP,
MOUSE_ENTERED, MOUSE_ENTERED,
@ -76,6 +78,7 @@ static const char *event_type_str[] = {
[SYSTEM_WOKE] = "system_woke", [SYSTEM_WOKE] = "system_woke",
[SYSTEM_WILL_SLEEP] = "system_will_sleep", [SYSTEM_WILL_SLEEP] = "system_will_sleep",
[SHELL_REFRESH] = "shell_refresh", [SHELL_REFRESH] = "shell_refresh",
[ANIMATOR_REFRESH] = "animator_refresh",
[MACH_MESSAGE] = "mach_message", [MACH_MESSAGE] = "mach_message",
[MOUSE_UP] = "mouse_up", [MOUSE_UP] = "mouse_up",
[MOUSE_ENTERED] = "mouse_entered", [MOUSE_ENTERED] = "mouse_entered",
@ -102,6 +105,7 @@ static event_callback *event_handler[] = {
[SYSTEM_WOKE] = EVENT_HANDLER_SYSTEM_WOKE, [SYSTEM_WOKE] = EVENT_HANDLER_SYSTEM_WOKE,
[SYSTEM_WILL_SLEEP] = EVENT_HANDLER_SYSTEM_WILL_SLEEP, [SYSTEM_WILL_SLEEP] = EVENT_HANDLER_SYSTEM_WILL_SLEEP,
[SHELL_REFRESH] = EVENT_HANDLER_SHELL_REFRESH, [SHELL_REFRESH] = EVENT_HANDLER_SHELL_REFRESH,
[ANIMATOR_REFRESH] = EVENT_HANDLER_ANIMATOR_REFRESH,
[MACH_MESSAGE] = EVENT_HANDLER_MACH_MESSAGE, [MACH_MESSAGE] = EVENT_HANDLER_MACH_MESSAGE,
}; };