#include #include #include #include #include #include "scheme.h" #include "../any_log.h" typedef struct { effect_t effect; unsigned int width; cairo_pattern_t *gradient; } effect_shine_t; extern double cubic_bezier(double x, double a, double b, double c, double d); static void effect_shine_post(effect_t *effect, layout_t *layout, cairo_t *cr) { struct timespec now; timespec_get(&now, TIME_UTC); struct timespec diff = timespec_diff(now, effect->start); double t = (double)timespec_to_ms(diff) / timespec_to_ms(effect->info->duration); double s = cubic_bezier(t, 0.19, 1.0, 0.22, 1.0); effect_shine_t *shine = (effect_shine_t *)effect; unsigned int x = layout->x + s * layout->width - shine->width; unsigned int y = layout->y; cairo_set_operator(cr, CAIRO_OPERATOR_ATOP); cairo_set_source(cr, shine->gradient); cairo_rectangle(cr, x, y - layout->height / 2, shine->width, layout->height); cairo_fill(cr); } static effect_t *effect_shine_allocate(const effect_info_t *info) { effect_shine_t *effect = malloc(sizeof(effect_shine_t)); effect_init((effect_t *)effect, info); effect->width = 20; effect->gradient = cairo_pattern_create_linear(0, 0, effect->width, 0); cairo_pattern_add_color_stop_rgba(effect->gradient, 1, 1, 1, 1, 0.1); cairo_pattern_add_color_stop_rgba(effect->gradient, 0.5, 1, 1, 1, 0.8); cairo_pattern_add_color_stop_rgba(effect->gradient, 1, 1, 1, 1, 0.1); return (effect_t *)effect; } static void effect_shine_finalize(effect_shine_t *effect) { cairo_pattern_destroy(effect->gradient); free(effect); } static bool effect_shine_validate(effect_info_t *info, const effect_scheme_t *scheme) { return true; } static const config_entry_t effect_shine_entries[] = { { 0 }, }; const effect_scheme_t effect_shine_scheme = { .name = "shine", .info = { .duration = { .tv_sec = 0, .tv_nsec = 200000000, }, .allocate = effect_shine_allocate, .finalize = (effect_finalize_t)effect_shine_finalize, .post = effect_shine_post, }, .size = sizeof(unsigned int), .entries = effect_shine_entries, .validate = effect_shine_validate, };