diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/animate.c | 48 | ||||
| -rw-r--r-- | src/animate.h | 4 | ||||
| -rw-r--r-- | src/comet.c | 36 | ||||
| -rw-r--r-- | src/draw.c | 4 |
4 files changed, 73 insertions, 19 deletions
diff --git a/src/animate.c b/src/animate.c index 8bd09b5..313cfa7 100644 --- a/src/animate.c +++ b/src/animate.c @@ -129,8 +129,54 @@ Animation *animation_pulse_create(gint64 duration) pulse->type = ANIM_PULSE; pulse->before_func = (DrawFunc)pulse_func; pulse->duration = duration; + return pulse; +} + +static bool shrink_func(Animation *shrink, Layout *layout) +{ + g_assert_false(layout->btn->simple); + ButtonGroup *group = (gpointer)layout->btn; + + gint64 end = shrink->start + shrink->duration; + gint64 now = g_get_monotonic_time(); + + if (now > end) { + // NOTE: Actually remove the buttons from the group after the animation's end + // This part is quite rough around the edges... + if (group->children->next) { + g_list_free(g_list_remove_link(group->children, group->children)); + g_list_free(g_list_remove_link(layout->children, layout->children)); + layout->width = CAST(layout->children->data, Layout)->width; + return true; + } + + return false; + } + + double t = (double)(now - shrink->start) / (end - shrink->start); + double pos = smoothstep(t, 0, 1); - return (gpointer)pulse; + int target_w = CAST(layout->children->data, Layout)->width; + int width = layout->width - pos * (layout->width - target_w); + layout->width = width; + + for (GList *it = layout->children, *next = it->next; it; it = next, next = it ? it->next : NULL) { + Layout *child = it->data; + if (child->x + child->width > layout->x + width) + layout->children = g_list_delete_link(layout->children, it); + } + + return true; +} + +Animation *animation_group_shrink_create(gint64 duration) +{ + // Note the 0 initialization + Animation *shrink = g_malloc0(sizeof(Animation)); + shrink->type = ANIM_GROUP_SHRINK; + shrink->layout_func = (LayoutFunc)shrink_func; + shrink->duration = duration; + return shrink; } void animation_destroy(Animation *anim) diff --git a/src/animate.h b/src/animate.h index b296723..d153cda 100644 --- a/src/animate.h +++ b/src/animate.h @@ -15,6 +15,8 @@ struct Animation { enum { ANIM_SHINE, ANIM_PULSE, + ANIM_GROUP_SHRINK, + //ANIM_GROUP_GROW, } type; gint64 start; gint64 duration; @@ -36,6 +38,8 @@ Animation *animation_shine_create(gint64 duration); Animation *animation_pulse_create(gint64 duration); +Animation *animation_group_shrink_create(gint64 duration); + void animation_destroy(Animation *anim); #endif diff --git a/src/comet.c b/src/comet.c index b8cce7d..9c552f5 100644 --- a/src/comet.c +++ b/src/comet.c @@ -194,26 +194,32 @@ static void quit_action(Button *btn) static void menu_action(Button *btn) { - ButtonSimple *sbtn = CAST(btn, ButtonSimple); struct { + State *state; ButtonGroup *group; char *strings[2]; GList *toggled; - State *state; - } *menu_ctx = sbtn->data; + } *menu_ctx = CAST(btn, ButtonSimple)->data; - // NOTE: To close the menu the toggle button must be inside + bool to_open = menu_ctx->group->children->next == NULL; - GList *temp = menu_ctx->group->children; - menu_ctx->group->children = menu_ctx->toggled; - menu_ctx->toggled = temp; + if (to_open) + menu_ctx->group->children = g_list_copy(menu_ctx->toggled); - bool closed = menu_ctx->group->children->next == NULL; + log_debug("%s menu", to_open ? "Opened" : "Closed"); - button_simple_set_text(btn, g_strdup(menu_ctx->strings[!closed]), sbtn->text_color); + button_simple_set_text(btn, g_strdup(menu_ctx->strings[to_open]), CAST(btn, ButtonSimple)->text_color); - log_debug("%s menu", closed ? "Closed" : "Opened"); - state_request_redraw(menu_ctx->state, true); + if (!to_open) { + Animation *shrink = animation_group_shrink_create(600 * G_TIME_SPAN_MILLISECOND); + + if (button_set_animation((gpointer)menu_ctx->group, shrink)) + state_request_animation(menu_ctx->state); + else + animation_destroy(shrink); + } else { + state_request_redraw(menu_ctx->state, true); + } } static void register_buttons(State *state, Color color, Color text_color, Color line_color, int line_w) @@ -358,11 +364,11 @@ int main(int argc, char **argv) button_simple_set_action(child3, show_action, NULL); struct { + State *state; ButtonGroup *group; char *strings[2]; GList *toggled; - State *state; - } menu_ctx = { (gpointer)group, {"", ""}, NULL, state }; + } menu_ctx = { state, (gpointer)group, {"", ""}, NULL }; Button *menu = button_simple_create(PANGO_ALIGN_LEFT, color); button_simple_set_text(menu, g_strdup(menu_ctx.strings[0]), text_color); @@ -398,8 +404,8 @@ int main(int argc, char **argv) g_source_remove(source_int); // NOTE: Skip the first element (the open/close button) - g_list_free_full(menu_ctx.toggled->next, (GDestroyNotify)button_destroy); - g_free(menu_ctx.toggled); + //g_list_free_full(menu_ctx.toggled->next, (GDestroyNotify)button_destroy); + //g_free(menu_ctx.toggled); timer_delete(date_ctx.timer); // NOTE: Buttons are freed by state_destroy @@ -175,9 +175,7 @@ static void layout_set_text(Layout *layout, PangoFontDescription *desc, int heig // If there is only one glyph the button should be round size_t text_l = g_utf8_strlen(text, -1); - layout->width = text_l == 1 ? height : layout->text_w + height; - layout->height = height; } static void compute_width(Drawer *draw, Window *win) @@ -208,6 +206,7 @@ static GList *compute_group_layout(Drawer *draw, GList *btns, int bx, bool root) layouts = g_list_prepend(layouts, layout); layout->btn = btn; + layout->height = draw->height; layout->line_w = btn->line_width; layout->x_pad = btn->x_pad; layout->y_pad = btn->y_pad; @@ -234,7 +233,6 @@ retry: Layout *last = g_list_last(layout->children)->data; layout->width = last->x + last->width - bx; - layout->height = draw->height; // FIXME: Temporary solution to make the antialiasing (or the circles not // overlapping correctly) problem less noticeable |
