diff --git a/package.json b/package.json index 67e24aa..996a5be 100644 --- a/package.json +++ b/package.json @@ -58,13 +58,6 @@ "spaceOptimization": "storage", "type": "bitmap" }, - { - "file": "x.png", - "memoryFormat": "Smallest", - "name": "X", - "spaceOptimization": "storage", - "type": "bitmap" - }, { "file": "check.png", "memoryFormat": "Smallest", diff --git a/resources/x.png b/resources/x.png deleted file mode 100644 index b5bdd33..0000000 Binary files a/resources/x.png and /dev/null differ diff --git a/src/c/main.c b/src/c/main.c index 3cf46a3..6d0a1f5 100644 --- a/src/c/main.c +++ b/src/c/main.c @@ -23,8 +23,6 @@ static BitmapLayer *s_check_bmp_layer; static TextLayer *s_setter_txt_layer; static Layer *s_setter_highlight_layer; //// alarm -static BitmapLayer *s_x_bmp_layer; -static Animation *s_x_anim_master; static Layer *s_graph_layer; static TextLayer *s_theta_txt_layer; static TextLayer *s_parenthesis_txt_layer; @@ -44,6 +42,8 @@ static TextLayer *s_progress_txt_layer; static TextLayer *s_side_a_txt_layer; static TextLayer *s_side_b_txt_layer; static TextLayer *s_side_c_txt_layer; +static Layer *s_left_door_layer; +static Layer *s_right_door_layer; // fonts GFont s_font_lecoish_small; @@ -57,8 +57,6 @@ GFont s_font_mansalva_small; //// setter static GBitmap *s_clock_bmp; static GBitmap *s_check_bmp; -//// alarm -static GBitmap *s_x_bmp; // global vars static WakeupReason s_alarm_reason; @@ -91,6 +89,7 @@ static const GColor s_primary_color = GColorJaegerGreen; #define MAX_SECS_WITHOUT_INPUT 10 #define SHAKE_COOLDOWN_SECS 2 #define ZAP_COOLDOWN_SECS 4 +static const uint8_t s_small_top_bar_height = s_top_bar_grect.size.h / 2; static const uint8_t s_drop_height = 22; static const GRect s_drop_function_grect = GRect(PBL_IF_ROUND_ELSE(55, 45), s_bottom_bar_grect.origin.y + ((s_bottom_bar_grect.size.h / 2) - PBL_IF_ROUND_ELSE(s_drop_height - 1, s_drop_height / 2)), 50, s_drop_height); static const GRect s_drop_over_grect = GRect(s_drop_function_grect.origin.x + 78, s_drop_function_grect.origin.y - 13, s_drop_function_grect.size.w + 1, s_drop_function_grect.size.h); @@ -107,6 +106,10 @@ static const VibePattern s_first_triangle_vibe_pattern = { .num_segments = ARRAY_LENGTH(s_first_triangle_vibe_segments), }; +// animation stuff +static GRect s_left_door_starting_grect = GRect(-(PBL_DISPLAY_WIDTH / 2), s_small_top_bar_height, PBL_DISPLAY_WIDTH / 2, PBL_DISPLAY_HEIGHT - s_small_top_bar_height - s_bottom_bar_grect.size.h); +static GRect s_right_door_starting_grect = GRect(PBL_DISPLAY_WIDTH, s_small_top_bar_height, PBL_DISPLAY_WIDTH / 2, PBL_DISPLAY_HEIGHT - s_small_top_bar_height - s_bottom_bar_grect.size.h); + // alarm drop menu options static const char *s_options_function[3]; static char *s_options_over[2]; @@ -371,7 +374,8 @@ static void set_alarm_highlighter_frame() { } } -static void clear_selections() { +static void update_for_new_triangle() { + // clear selections for (int i = 0; i < 3; ++i) { s_selected_indices[i] = 9; } @@ -380,10 +384,6 @@ static void clear_selections() { text_layer_set_text(s_drop_txt_function_layer, ""); text_layer_set_text(s_drop_txt_over_layer, ""); text_layer_set_text(s_drop_txt_under_layer, ""); -} - -static void update_for_new_triangle() { - clear_selections(); // pick & display 2 side lengths to the user static char side_a_buffer[8], side_b_buffer[8], side_c_buffer[8]; @@ -505,6 +505,65 @@ static void update_for_new_triangle() { text_layer_set_text(s_progress_txt_layer, s_progress_buf); } +static void door_layer_red_update_proc(Layer *layer, GContext *ctx) { + graphics_context_set_fill_color(ctx, GColorMelon); + graphics_fill_rect(ctx, layer_get_bounds(layer), 0, GCornerNone); +} + +static void door_layer_green_update_proc(Layer *layer, GContext *ctx) { + graphics_context_set_fill_color(ctx, GColorMediumAquamarine); + graphics_fill_rect(ctx, layer_get_bounds(layer), 0, GCornerNone); +} + +static void door_closed_fail_animation_handler(Animation *animation, bool finished, void *context) { + if (s_current_triangle_num > 1) { + s_current_triangle_num--; + } + right_triangle_layer_regen(s_triangle_layer); + update_for_new_triangle(); +} + +static void door_closed_success_animation_handler(Animation *animation, bool finished, void *context) { + s_current_triangle_num++; + right_triangle_layer_regen(s_triangle_layer); + update_for_new_triangle(); +} + +static void destroy_animation_handler(Animation *animation, bool finished, void *context) { + animation_destroy(animation); +} + +// TODO: +// reuse some of these animations, if possible +// add iconography to door halves +static void play_door_animation(bool correct) { + PropertyAnimation *left_door_prop_anim = property_animation_create_layer_frame(s_left_door_layer, &s_left_door_starting_grect, &GRect(0, s_left_door_starting_grect.origin.y, s_left_door_starting_grect.size.w, s_left_door_starting_grect.size.h)); + PropertyAnimation *right_door_prop_anim = property_animation_create_layer_frame(s_right_door_layer, &s_right_door_starting_grect, &GRect(PBL_DISPLAY_WIDTH / 2, s_left_door_starting_grect.origin.y, s_left_door_starting_grect.size.w, s_left_door_starting_grect.size.h)); + Animation *left_door_close_anim = property_animation_get_animation(left_door_prop_anim); + Animation *right_door_close_anim = property_animation_get_animation(right_door_prop_anim); + animation_set_duration(left_door_close_anim, 500); + animation_set_duration(right_door_close_anim, 500); + Animation *left_door_open_anim = animation_clone(left_door_close_anim); + Animation *right_door_open_anim = animation_clone(right_door_close_anim); + animation_set_reverse(left_door_open_anim, true); + animation_set_reverse(right_door_open_anim, true); + Animation *door_close_spawn_anim = animation_spawn_create(left_door_close_anim, right_door_close_anim, NULL); + Animation *door_open_spawn_anim = animation_spawn_create(left_door_open_anim, right_door_open_anim, NULL); + animation_set_delay(door_open_spawn_anim, 100); + if (correct) { + layer_set_update_proc(s_left_door_layer, door_layer_green_update_proc); + layer_set_update_proc(s_right_door_layer, door_layer_green_update_proc); + animation_set_handlers(door_close_spawn_anim, (AnimationHandlers){.stopped = door_closed_success_animation_handler}, NULL); + } else { + layer_set_update_proc(s_left_door_layer, door_layer_red_update_proc); + layer_set_update_proc(s_right_door_layer, door_layer_red_update_proc); + animation_set_handlers(door_close_spawn_anim, (AnimationHandlers){.stopped = door_closed_fail_animation_handler}, NULL); + } + Animation *seq = animation_sequence_create(door_close_spawn_anim, door_open_spawn_anim, NULL); + animation_set_handlers(seq, (AnimationHandlers){.stopped = destroy_animation_handler}, NULL); + animation_schedule(seq); +}; + static void increment_secs_since_last_input() { if (s_secs_since_last_input < MAX_SECS_WITHOUT_INPUT) { s_secs_since_last_input++; @@ -536,12 +595,8 @@ static void alarm_tick_handler(struct tm *tick_time, TimeUnits units_changed) { if (s_countdown_int == 0) { s_continuous_zap_on_first_triangle = true; // begin zapping once the first countdown expires send_zap(); - if (s_current_triangle_num > 1) { - s_current_triangle_num--; - } s_secs_since_last_input = 10; - right_triangle_layer_regen(s_triangle_layer); - update_for_new_triangle(); + play_door_animation(false); } // minutes @@ -612,8 +667,7 @@ static void accel_tap_handler(AccelAxisType axis, int32_t direction) { // check solution for (int i = 0; i < 3; ++i) { if (s_selected_indices[i] != s_solution_indices[i]) { - animation_schedule(animation_clone(s_x_anim_master)); - clear_selections(); + play_door_animation(false); return; } } @@ -626,9 +680,7 @@ static void accel_tap_handler(AccelAxisType axis, int32_t direction) { push_status_window(STATUS_CONFIRMATION); } } else { - s_current_triangle_num++; - right_triangle_layer_regen(s_triangle_layer); - update_for_new_triangle(); + play_door_animation(true); } } @@ -705,16 +757,6 @@ static void live_wakeup_handler_for_alarm(WakeupId id, int32_t wakeup_reason) { } } -static void anim_handler_flash_x_start(Animation *animation, void *context) { - layer_set_hidden(bitmap_layer_get_layer(s_x_bmp_layer), false); -} -static void anim_handler_flash_x_end(Animation *animation, bool finished, void *context) { - layer_set_hidden(bitmap_layer_get_layer(s_x_bmp_layer), true); - animation_destroy(animation); -} -static void anim_update_flash_x(Animation *animation, const AnimationProgress progress) {} // dummy -static const AnimationImplementation s_x_anim_impl = {.update = anim_update_flash_x}; - static void alarm_window_load() { wakeup_service_subscribe(live_wakeup_handler_for_alarm); @@ -795,7 +837,6 @@ static void alarm_window_load() { layer_add_child(window_layer, s_alarm_highlight_layer); // triangle - static const uint8_t s_small_top_bar_height = s_top_bar_grect.size.h / 2; s_triangle_layer = right_triangle_layer_create(GRect(0, s_small_top_bar_height, PBL_DISPLAY_WIDTH, PBL_DISPLAY_HEIGHT - s_small_top_bar_height - s_bottom_bar_grect.size.h), GColorBlack); layer_add_child(window_layer, s_triangle_layer->layer); @@ -850,19 +891,11 @@ static void alarm_window_load() { text_layer_set_font(s_progress_txt_layer, fonts_get_system_font(FONT_KEY_LECO_20_BOLD_NUMBERS)); layer_add_child(window_layer, text_layer_get_layer(s_progress_txt_layer)); - // x (incorrect equation icon) - s_x_bmp = gbitmap_create_with_resource(RESOURCE_ID_X); - s_x_bmp_layer = bitmap_layer_create(GRect(20, 24, 160, 179)); - bitmap_layer_set_bitmap(s_x_bmp_layer, s_x_bmp); - bitmap_layer_set_compositing_mode(s_x_bmp_layer, GCompOpSet); - layer_set_hidden(bitmap_layer_get_layer(s_x_bmp_layer), true); // hide until needed - layer_add_child(window_layer, bitmap_layer_get_layer(s_x_bmp_layer)); - - // x flash animation init - s_x_anim_master = animation_create(); - animation_set_implementation(s_x_anim_master, &s_x_anim_impl); - animation_set_duration(s_x_anim_master, 1500); - animation_set_handlers(s_x_anim_master, (AnimationHandlers){.started = anim_handler_flash_x_start, .stopped = anim_handler_flash_x_end}, NULL); + // door layers + s_left_door_layer = layer_create(s_left_door_starting_grect); + s_right_door_layer = layer_create(s_right_door_starting_grect); + layer_add_child(window_layer, s_left_door_layer); + layer_add_child(window_layer, s_right_door_layer); // configure UI around current triangle in s_triangle_layer s_current_triangle_num = 1; @@ -880,9 +913,6 @@ static void alarm_window_load() { static void alarm_window_unload() { tick_timer_service_unsubscribe(); accel_tap_service_unsubscribe(); - animation_destroy(s_x_anim_master); - gbitmap_destroy(s_x_bmp); - bitmap_layer_destroy(s_x_bmp_layer); text_layer_destroy(s_progress_txt_layer); text_layer_destroy(s_countdown_txt_layer); window_destroy(s_drop_window);