From 79b407869cce4c4b08321db3f66cc883e061c029 Mon Sep 17 00:00:00 2001 From: Randall Winkhart Date: Sat, 8 Aug 2026 01:18:18 -0400 Subject: [PATCH] Add stopwatch to alarm top bar --- src/c/main.c | 53 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/src/c/main.c b/src/c/main.c index 0a0d30a..70262b3 100644 --- a/src/c/main.c +++ b/src/c/main.c @@ -15,10 +15,10 @@ static Window *s_window; static Window *s_drop_window; static Layer *s_top_bar_layer; static Layer *s_bottom_bar_layer; +static TextLayer *s_counter_txt_layer; //// setter static BitmapLayer *s_clock_bmp_layer; static BitmapLayer *s_check_bmp_layer; -static TextLayer *s_countdown_txt_layer; static TextLayer *s_setter_txt_layer; static Layer *s_setter_highlight_layer; //// alarm @@ -59,6 +59,7 @@ static struct TheTime s_the_time; //// alarm static uint8_t s_solution_indices[3] = {8, 8, 8}; static uint8_t s_selected_indices[3] = {9, 9, 9}; +static uint8_t s_stopwatch_time[2] = {0, 0}; // constants static const uint8_t s_edge_bar_height = ((PBL_DISPLAY_HEIGHT / 7) * 2); @@ -88,7 +89,7 @@ static char *s_options_under[2]; static void glance_reload_callback(AppGlanceReloadSession *session, size_t limit, void *target) { static char s_glance_buffer[11]; - snprintf(s_glance_buffer, sizeof(s_glance_buffer), "Up @ %02d:%02d", s_the_time.HourSet, s_the_time.MinuteSet); + snprintf(s_glance_buffer, sizeof(s_glance_buffer), "Up @ %02u:%02u", s_the_time.HourSet, s_the_time.MinuteSet); AppGlanceSlice slice = { .expiration_time = (time_t)(uintptr_t)target, .layout.icon = APP_GLANCE_SLICE_DEFAULT_ICON, @@ -145,9 +146,8 @@ static void setter_seconds_handler(struct tm *tick_time, TimeUnits units_changed uint8_t seconds = diff % 60; static char s_countdown_buffer[9]; - snprintf(s_countdown_buffer, sizeof(s_countdown_buffer), - "%02d:%02d:%02d", hours, minutes, seconds); - text_layer_set_text(s_countdown_txt_layer, s_countdown_buffer); + snprintf(s_countdown_buffer, sizeof(s_countdown_buffer), "%02u:%02u:%02u", hours, minutes, seconds); + text_layer_set_text(s_counter_txt_layer, s_countdown_buffer); } static void update_countdown_display() { @@ -157,7 +157,7 @@ static void update_countdown_display() { static void update_setter_display() { static char s_setter_buffer[PBL_IF_ROUND_ELSE(8, 12)]; - snprintf(s_setter_buffer, sizeof(s_setter_buffer), PBL_IF_ROUND_ELSE("%02d : %02d", "%02d : %02d"), s_the_time.HourWIP, s_the_time.MinuteWIP); + snprintf(s_setter_buffer, sizeof(s_setter_buffer), PBL_IF_ROUND_ELSE("%02u : %02u", "%02u : %02u"), s_the_time.HourWIP, s_the_time.MinuteWIP); text_layer_set_text(s_setter_txt_layer, s_setter_buffer); } @@ -306,13 +306,12 @@ static void setter_window_load() { layer_add_child(window_layer, bitmap_layer_get_layer(s_check_bmp_layer)); // countdown - s_font_lecoish_small = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_LECOISH_MONO_BOLD_20)); - s_countdown_txt_layer = text_layer_create(GRect(PBL_IF_ROUND_ELSE(0, 39), (s_top_bar_grect.size.h / 2) + PBL_IF_ROUND_ELSE(10, -10), PBL_IF_ROUND_ELSE(s_top_bar_grect.size.w, s_top_bar_grect.size.w - 39), 32)); - text_layer_set_text_alignment(s_countdown_txt_layer, GTextAlignmentCenter); - text_layer_set_text_color(s_countdown_txt_layer, GColorWhite); - text_layer_set_background_color(s_countdown_txt_layer, GColorClear); - text_layer_set_font(s_countdown_txt_layer, s_font_lecoish_small); - layer_add_child(window_layer, text_layer_get_layer(s_countdown_txt_layer)); + s_counter_txt_layer = text_layer_create(GRect(PBL_IF_ROUND_ELSE(0, 39), (s_top_bar_grect.size.h / 2) + PBL_IF_ROUND_ELSE(10, -10), PBL_IF_ROUND_ELSE(s_top_bar_grect.size.w, s_top_bar_grect.size.w - 39), 32)); + text_layer_set_text_alignment(s_counter_txt_layer, GTextAlignmentCenter); + text_layer_set_text_color(s_counter_txt_layer, GColorWhite); + text_layer_set_background_color(s_counter_txt_layer, GColorClear); + text_layer_set_font(s_counter_txt_layer, s_font_lecoish_small); + layer_add_child(window_layer, text_layer_get_layer(s_counter_txt_layer)); update_countdown_display(); // highlighter @@ -335,7 +334,7 @@ static void setter_window_load() { static void setter_window_unload() { text_layer_destroy(s_setter_txt_layer); layer_destroy(s_setter_highlight_layer); - text_layer_destroy(s_countdown_txt_layer); + text_layer_destroy(s_counter_txt_layer); bitmap_layer_destroy(s_check_bmp_layer); bitmap_layer_destroy(s_clock_bmp_layer); gbitmap_destroy(s_check_bmp); @@ -343,7 +342,6 @@ static void setter_window_unload() { layer_destroy(s_bottom_bar_layer); layer_destroy(s_top_bar_layer); fonts_unload_custom_font(s_font_lecoish_big); - fonts_unload_custom_font(s_font_lecoish_small); } static void schedule_fallback_alarm() { @@ -360,9 +358,22 @@ static void schedule_fallback_alarm() { } static void alarm_seconds_handler(struct tm *tick_time, TimeUnits units_changed) { + // re-schedule fallback alarm every 15 seconds if (tick_time->tm_sec % 15 == 0) { schedule_fallback_alarm(); } + + // update stopwatch + if (s_stopwatch_time[1] == 59) { + s_stopwatch_time[1] = 0; + s_stopwatch_time[0]++; + } else { + s_stopwatch_time[1]++; + } + static char s_stopwatch_buffer[9]; + snprintf(s_stopwatch_buffer, sizeof(s_stopwatch_buffer), "%02u:%02u", s_stopwatch_time[0], s_stopwatch_time[1]); + text_layer_set_text(s_counter_txt_layer, s_stopwatch_buffer); + vibes_short_pulse(); } @@ -664,11 +675,21 @@ static void alarm_window_load() { s_drop_window, (WindowHandlers){.unload = drop_menu_window_unload}); + // stopwatch + s_counter_txt_layer = text_layer_create(GRect(0, (s_small_top_bar_height / 2) - PBL_IF_ROUND_ELSE(6, 10), PBL_DISPLAY_WIDTH, s_small_top_bar_height)); + text_layer_set_background_color(s_counter_txt_layer, GColorClear); + text_layer_set_text_color(s_counter_txt_layer, GColorWhite); + text_layer_set_text_alignment(s_counter_txt_layer, GTextAlignmentCenter); + text_layer_set_font(s_counter_txt_layer, s_font_lecoish_small); + text_layer_set_text(s_counter_txt_layer, "00:00"); + layer_add_child(window_layer, text_layer_get_layer(s_counter_txt_layer)); + schedule_fallback_alarm(); tick_timer_service_subscribe(SECOND_UNIT, alarm_seconds_handler); } static void alarm_window_unload() { + text_layer_destroy(s_counter_txt_layer); text_layer_destroy(s_side_a_txt_layer); text_layer_destroy(s_side_b_txt_layer); text_layer_destroy(s_side_c_txt_layer); @@ -760,6 +781,7 @@ static void alarm_click_config_provider(void *ctx) { static void init() { s_window = window_create(); + s_font_lecoish_small = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_LECOISH_MONO_BOLD_20)); s_the_time.HourWIP = persist_read_int(STORAGE_KEY_ALARM_HOUR); s_the_time.MinuteWIP = persist_read_int(STORAGE_KEY_ALARM_MINUTE); s_the_time.HourSet = s_the_time.HourWIP; @@ -784,6 +806,7 @@ static void init() { } static void deinit() { + fonts_unload_custom_font(s_font_lecoish_small); window_destroy(s_window); }