From 6bb04801bc8171d37472834aefd084c91dc2eae1 Mon Sep 17 00:00:00 2001 From: Bas Grolleman Date: Sat, 23 May 2026 17:44:03 +0200 Subject: [PATCH] Move countdown bar between time and date, split into 30 minute blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the single progress bar with 30 individual blocks — one per minute. Filled blocks show remaining time, outlined blocks show elapsed. Bar is now positioned between the time and date layers instead of at the top. Co-Authored-By: Claude Sonnet 4.6 --- countdown_watchface/src/c/watchface.c | 43 ++++++++++++++++----------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/countdown_watchface/src/c/watchface.c b/countdown_watchface/src/c/watchface.c index 766926e..18f3c84 100644 --- a/countdown_watchface/src/c/watchface.c +++ b/countdown_watchface/src/c/watchface.c @@ -7,7 +7,7 @@ static Layer *s_bar_layer; static Layer *s_battery_layer; static int s_battery_level = 100; -static int s_bar_fill = 100; // 0–100: 100 = 30 min remaining, 0 = event now +static int s_bar_fill = 30; // 0–30: minutes remaining static int s_appt_mins = -1; // minutes to next appointment, -1 = none within 30 min static int mins_to_next_half(void) { @@ -24,9 +24,9 @@ static void update_bar(void) { target = s_appt_mins; } - s_bar_fill = (target * 100) / 30; - if (s_bar_fill > 100) s_bar_fill = 100; - if (s_bar_fill < 0) s_bar_fill = 0; + s_bar_fill = target; + if (s_bar_fill > 30) s_bar_fill = 30; + if (s_bar_fill < 0) s_bar_fill = 0; layer_mark_dirty(s_bar_layer); } @@ -37,10 +37,21 @@ static void bar_draw(Layer *layer, GContext *ctx) { graphics_context_set_fill_color(ctx, GColorBlack); graphics_fill_rect(ctx, bounds, 0, GCornerNone); - int fill_w = (s_bar_fill * bounds.size.w) / 100; - if (fill_w > 0) { - graphics_context_set_fill_color(ctx, GColorWhite); - graphics_fill_rect(ctx, GRect(0, 0, fill_w, bounds.size.h), 0, GCornerNone); + // Fit 30 blocks with 1px gaps; centre the result + int block_w = (bounds.size.w - 29) / 30; + int total_w = 30 * block_w + 29; + int start_x = (bounds.size.w - total_w) / 2; + + for (int i = 0; i < 30; i++) { + int x = start_x + i * (block_w + 1); + GRect block = GRect(x, 0, block_w, bounds.size.h); + if (i < s_bar_fill) { + graphics_context_set_fill_color(ctx, GColorWhite); + graphics_fill_rect(ctx, block, 0, GCornerNone); + } else { + graphics_context_set_stroke_color(ctx, GColorWhite); + graphics_draw_rect(ctx, block); + } } } @@ -97,14 +108,8 @@ static void main_window_load(Window *window) { Layer *root = window_get_root_layer(window); GRect bounds = layer_get_bounds(root); - // Countdown bar — full width at top, 8px tall - s_bar_layer = layer_create(GRect(0, 0, bounds.size.w, 8)); - layer_set_update_proc(s_bar_layer, bar_draw); - layer_add_child(root, s_bar_layer); - // Time — Leco 42, centred - s_time_layer = text_layer_create( - GRect(0, PBL_IF_ROUND_ELSE(52, 44), bounds.size.w, 52)); + s_time_layer = text_layer_create(GRect(0, 30, bounds.size.w, 52)); text_layer_set_background_color(s_time_layer, GColorClear); text_layer_set_text_color(s_time_layer, GColorWhite); text_layer_set_font(s_time_layer, fonts_get_system_font(FONT_KEY_LECO_42_NUMBERS)); @@ -112,9 +117,13 @@ static void main_window_load(Window *window) { text_layer_set_text(s_time_layer, "00:00"); layer_add_child(root, text_layer_get_layer(s_time_layer)); + // Countdown bar — 30 blocks between time and date + s_bar_layer = layer_create(GRect(0, 90, bounds.size.w, 8)); + layer_set_update_proc(s_bar_layer, bar_draw); + layer_add_child(root, s_bar_layer); + // Date — Leco 38, right-aligned - s_date_layer = text_layer_create( - GRect(0, PBL_IF_ROUND_ELSE(110, 100), bounds.size.w, 44)); + s_date_layer = text_layer_create(GRect(0, 106, bounds.size.w, 44)); text_layer_set_background_color(s_date_layer, GColorClear); text_layer_set_text_color(s_date_layer, GColorWhite); text_layer_set_font(s_date_layer, fonts_get_system_font(FONT_KEY_LECO_38_BOLD_NUMBERS));