From 1dc5c626ec2f334647dcea973a983634ec76ebcd Mon Sep 17 00:00:00 2001 From: Randall Winkhart Date: Fri, 20 Mar 2026 17:34:42 -0400 Subject: [PATCH] Modularize animation code --- src/c/main.c | 132 ++++++++++++++++++++++----------------------------- 1 file changed, 58 insertions(+), 74 deletions(-) diff --git a/src/c/main.c b/src/c/main.c index 6fc3a39..a57b936 100644 --- a/src/c/main.c +++ b/src/c/main.c @@ -31,19 +31,11 @@ static GRect s_guy_butt_grect_on_screen_raised = GRect(PBL_IF_ROUND_ELSE(0, -30) static GRect s_guy_butt_grect_off_screen_raised = GRect(PBL_IF_ROUND_ELSE(260, 170), PBL_IF_ROUND_ELSE(160, 144), 260, 115); static GRect s_guy_butt_grect_on_screen_resting = GRect(PBL_IF_ROUND_ELSE(0, -30), PBL_IF_ROUND_ELSE(145, 129), 260, 115); -// declare animations -static Animation *s_head_raise_anim; -static Animation *s_head_out_anim; -static Animation *s_head_in_anim; -static Animation *s_head_rest_anim; -static PropertyAnimation *s_head_y_prop_anim; -static PropertyAnimation *s_head_x_prop_anim; -static Animation *s_butt_raise_anim; -static Animation *s_butt_out_anim; -static Animation *s_butt_in_anim; -static Animation *s_butt_rest_anim; -static PropertyAnimation *s_butt_y_prop_anim; -static PropertyAnimation *s_butt_x_prop_anim; +// declare animation templates +static Animation *s_head_raise_template; +static Animation *s_head_out_template; +static Animation *s_butt_raise_template; +static Animation *s_butt_out_template; // declare lookup tables static const uint8_t s_head_count = 25; @@ -105,6 +97,25 @@ static void update_minute_1() { text_layer_set_text(s_memory_layer, s_memory_buffer); } +static void destroy_animation_handler(Animation *animation, bool finished, void *context) { + animation_destroy(animation); +} + +static void schedule_guy_animation(Animation *raise_tmpl, Animation *out_tmpl, AnimationStoppedHandler out_handler) { + Animation *raise = animation_clone(raise_tmpl); + Animation *out = animation_clone(out_tmpl); + animation_set_handlers(out, (AnimationHandlers){.stopped = out_handler}, NULL); + Animation *in = animation_clone(out_tmpl); + animation_set_reverse(in, true); + Animation *rest = animation_clone(raise_tmpl); + animation_set_reverse(rest, true); + Animation *seq = animation_sequence_create(raise, out, in, rest, NULL); + // set the handler to destroy the sequence (and its children) when finished + animation_set_handlers(seq, (AnimationHandlers){.stopped = destroy_animation_handler}, NULL); + // run it + animation_schedule(seq); +} + static void update_minute_30_out_handler(Animation *animation, bool finished, void *context) { // destroy and reassign current gbitmap_destroy(s_butt_current); @@ -126,36 +137,7 @@ static void update_minute_30_out_handler(Animation *animation, bool finished, vo static void update_minute_30() { update_minute_1(); - - // raise - s_butt_y_prop_anim = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_butt_layer), &s_guy_butt_grect_on_screen_resting, &s_guy_butt_grect_on_screen_raised); - s_butt_raise_anim = property_animation_get_animation(s_butt_y_prop_anim); - animation_set_curve(s_butt_raise_anim, AnimationCurveEaseOut); - animation_set_duration(s_butt_raise_anim, 350); - // out - s_butt_x_prop_anim = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_butt_layer), &s_guy_butt_grect_on_screen_raised, &s_guy_butt_grect_off_screen_raised); - s_butt_out_anim = property_animation_get_animation(s_butt_x_prop_anim); - animation_set_curve(s_butt_out_anim, AnimationCurveEaseOut); - animation_set_duration(s_butt_out_anim, 350); - // back in - s_butt_in_anim = animation_clone(s_butt_out_anim); - animation_set_reverse(s_butt_in_anim, true); - // set handler on out (after clone) - animation_set_handlers(s_butt_out_anim, (AnimationHandlers){.stopped = update_minute_30_out_handler}, NULL); - // back to resting - s_butt_rest_anim = animation_clone(s_butt_raise_anim); - animation_set_reverse(s_butt_rest_anim, true); - - // run animations - animation_schedule(animation_sequence_create(s_butt_raise_anim, s_butt_out_anim, s_butt_in_anim, s_butt_rest_anim, NULL)); - - // cleanup - animation_destroy(s_butt_raise_anim); - animation_destroy(s_butt_out_anim); - animation_destroy(s_butt_in_anim); - animation_destroy(s_butt_rest_anim); - property_animation_destroy(s_butt_y_prop_anim); - property_animation_destroy(s_butt_x_prop_anim); + schedule_guy_animation(s_butt_raise_template, s_butt_out_template, update_minute_30_out_handler); } static void update_minute_60_out_handler(Animation *animation, bool finished, void *context) { @@ -179,36 +161,7 @@ static void update_minute_60_out_handler(Animation *animation, bool finished, vo static void update_minute_60() { update_minute_1(); - - // raise - s_head_y_prop_anim = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_head_layer), &s_guy_head_grect_on_screen_resting, &s_guy_head_grect_on_screen_raised); - s_head_raise_anim = property_animation_get_animation(s_head_y_prop_anim); - animation_set_curve(s_head_raise_anim, AnimationCurveEaseOut); - animation_set_duration(s_head_raise_anim, 350); - // out - s_head_x_prop_anim = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_head_layer), &s_guy_head_grect_on_screen_raised, &s_guy_head_grect_off_screen_raised); - s_head_out_anim = property_animation_get_animation(s_head_x_prop_anim); - animation_set_curve(s_head_out_anim, AnimationCurveEaseOut); - animation_set_duration(s_head_out_anim, 350); - // back in - s_head_in_anim = animation_clone(s_head_out_anim); - animation_set_reverse(s_head_in_anim, true); - // set handler on out (after clone) - animation_set_handlers(s_head_out_anim, (AnimationHandlers){.stopped = update_minute_60_out_handler}, NULL); - // back to resting - s_head_rest_anim = animation_clone(s_head_raise_anim); - animation_set_reverse(s_head_rest_anim, true); - - // run animations - animation_schedule(animation_sequence_create(s_head_raise_anim, s_head_out_anim, s_head_in_anim, s_head_rest_anim, NULL)); - - // cleanup - animation_destroy(s_head_raise_anim); - animation_destroy(s_head_out_anim); - animation_destroy(s_head_in_anim); - animation_destroy(s_head_rest_anim); - property_animation_destroy(s_head_y_prop_anim); - property_animation_destroy(s_head_x_prop_anim); + schedule_guy_animation(s_head_raise_template, s_head_out_template, update_minute_60_out_handler); } static void minute_handler(struct tm *tick_time, TimeUnits units_changed) { @@ -280,6 +233,28 @@ static void main_window_load(Window *window) { // DEBUG memory usage layer layer_add_child(window_layer, text_layer_get_layer(s_memory_layer)); + + // create animation templates + // butt Raise + PropertyAnimation *butt_raise_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_butt_layer), &s_guy_butt_grect_on_screen_resting, &s_guy_butt_grect_on_screen_raised); + s_butt_raise_template = property_animation_get_animation(butt_raise_prop); + animation_set_curve(s_butt_raise_template, AnimationCurveEaseOut); + animation_set_duration(s_butt_raise_template, 350); + // butt Out + PropertyAnimation *butt_out_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_butt_layer), &s_guy_butt_grect_on_screen_raised, &s_guy_butt_grect_off_screen_raised); + s_butt_out_template = property_animation_get_animation(butt_out_prop); + animation_set_curve(s_butt_out_template, AnimationCurveEaseOut); + animation_set_duration(s_butt_out_template, 350); + // head Raise + PropertyAnimation *head_raise_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_head_layer), &s_guy_head_grect_on_screen_resting, &s_guy_head_grect_on_screen_raised); + s_head_raise_template = property_animation_get_animation(head_raise_prop); + animation_set_curve(s_head_raise_template, AnimationCurveEaseOut); + animation_set_duration(s_head_raise_template, 350); + // head Out + PropertyAnimation *head_out_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_head_layer), &s_guy_head_grect_on_screen_raised, &s_guy_head_grect_off_screen_raised); + s_head_out_template = property_animation_get_animation(head_out_prop); + animation_set_curve(s_head_out_template, AnimationCurveEaseOut); + animation_set_duration(s_head_out_template, 350); } // free memory on Window close @@ -294,18 +269,27 @@ static void main_window_unload(Window *window) { // DEBUG memory usage layer text_layer_destroy(s_memory_layer); + + // Destroy animation templates + animation_destroy(s_butt_raise_template); + animation_destroy(s_butt_out_template); + animation_destroy(s_head_raise_template); + animation_destroy(s_head_out_template); } +// DEBUG buttons static void up_single_click_handler(ClickRecognizerRef recognizer, void *context) { Window *window = (Window *)context; update_minute_60(); } +// DEBUG buttons static void down_single_click_handler(ClickRecognizerRef recognizer, void *context) { Window *window = (Window *)context; update_minute_30(); } +// DEBUG buttons static void click_config_provider(Window *window) { window_single_click_subscribe(BUTTON_ID_UP, up_single_click_handler); window_single_click_subscribe(BUTTON_ID_DOWN, down_single_click_handler); @@ -352,7 +336,7 @@ static void init() { // register with TickTimerService tick_timer_service_subscribe(MINUTE_UNIT, minute_handler); - // register with ClickConfigProvider + // DEBUG buttons window_set_click_config_provider(s_main_window, (ClickConfigProvider)click_config_provider); }