···87878888// --- Interface Functions (Pebble only) ---
89899090-TextLayer* clock_closest_noon_init(GRect bounds, Layer *window_layer) {
9191- TextLayer* layer = text_layer_util_create(bounds, window_layer, "Wait...", FONT_KEY_GOTHIC_18_BOLD);
9292-9090+// Initializes the city name TextLayer for Closest Noon
9191+TextLayer* clock_closest_noon_city_init(GRect bounds, Layer *window_layer) {
9292+ TextLayer* layer = text_layer_util_create(bounds, window_layer, "Wait...", FONT_KEY_GOTHIC_24_BOLD);
9393 // Initialize static vars
9494 s_selected_city_name = "Wait...";
9595- s_selected_offset_hours = 0.0f;
9695 s_last_update_time = -1;
9797- s_last_re_evaluation_time = -1; // Force re-evaluation on first update
9696+ s_last_re_evaluation_time = -1;
9797+ return layer;
9898+}
9899100100+// Initializes the hero time TextLayer for Closest Noon
101101+TextLayer* clock_closest_noon_time_init(GRect bounds, Layer *window_layer) {
102102+ TextLayer* layer = text_layer_util_create(bounds, window_layer, "--:--", FONT_KEY_LECO_42_NUMBERS);
103103+ s_selected_offset_hours = 0.0f;
99104 return layer;
100105}
101106···105110 }
106111}
107112108108-void clock_closest_noon_update(TextLayer *layer, time_t current_utc_t) {
109109- if (!layer) return;
113113+// Updates both the city and hero time TextLayers for Closest Noon
114114+void clock_closest_noon_update(TextLayer *city_layer, TextLayer *time_layer, time_t current_utc_t) {
115115+ if (!city_layer || !time_layer) return;
110116111117 // Avoid redundant updates for the same second
112118 if (current_utc_t == s_last_update_time) {
···115121 s_last_update_time = current_utc_t;
116122117123 // --- Check if it's time for re-evaluation ---
118118- struct tm *utc_tm_struct = gmtime(¤t_utc_t); // Use a different name to avoid shadowing
124124+ struct tm *utc_tm_struct = gmtime(¤t_utc_t);
119125 bool needs_re_evaluation = false;
120120-121121- // Check if gmtime succeeded and if it's a re-evaluation time point (:00, :15, :30)
122126 if (utc_tm_struct && (utc_tm_struct->tm_min % 15 == 0) && (utc_tm_struct->tm_min != 45) && (utc_tm_struct->tm_sec == 0)) {
123123- // Avoid re-evaluating multiple times within the same second if update is called rapidly
124124- if (current_utc_t != s_last_re_evaluation_time) {
127127+ if (current_utc_t != s_last_re_evaluation_time) {
125128 needs_re_evaluation = true;
126126- }
129129+ }
127130 } else if (s_last_re_evaluation_time == -1) {
128131 // Ensure initial evaluation happens if starting between intervals
129132 needs_re_evaluation = true;
···133136 update_selected_timezone_and_city(current_utc_t);
134137 }
135138139139+ // Format and set city name
140140+ text_layer_set_text(city_layer, s_selected_city_name ? s_selected_city_name : "ERR");
136141137137- // --- Calculate current local time based on selected zone ---
138138- // Use the stored offset from the last re-evaluation
139139- long current_offset_seconds = (long)(s_selected_offset_hours * 3600.0f);
140140- time_t local_time_epoch = current_utc_t + current_offset_seconds; // Use a distinct name
141141-142142- // --- Format and display the time ---
143143- struct tm *current_local_tm_struct = gmtime(&local_time_epoch); // Use gmtime to format based on the calculated local epoch time
144144-145145- // Check if a valid city was selected in the last evaluation or if it's fallback
146146- if (s_selected_city_name && strcmp(s_selected_city_name, "Wait...") != 0 &&
147147- strncmp(s_selected_city_name, "ERR:", 4) != 0)
148148- {
149149- if (current_local_tm_struct) {
150150- // Display format: CityName:MM:SS using actual local time
151151- snprintf(s_closest_noon_buffer, sizeof(s_closest_noon_buffer),
152152- "%s:%02d:%02d",
153153- s_selected_city_name, // Already checked for null/error states
154154- current_local_tm_struct->tm_min,
155155- current_local_tm_struct->tm_sec);
156156- } else {
157157- // Handle gmtime failure for a selected city
158158- snprintf(s_closest_noon_buffer, sizeof(s_closest_noon_buffer), "%s:ERR:TIME",
159159- s_selected_city_name);
160160- }
142142+ // Calculate and format hero time (MM:SS)
143143+ long offset_seconds = (long)(s_selected_offset_hours * 3600.0f);
144144+ time_t local_epoch = current_utc_t + offset_seconds;
145145+ struct tm *local_tm_struct = gmtime(&local_epoch);
146146+ static char s_time_buffer[10];
147147+ if (local_tm_struct) {
148148+ // Hero time: display minutes and seconds
149149+ snprintf(s_time_buffer, sizeof(s_time_buffer), "%02d:%02d",
150150+ local_tm_struct->tm_min,
151151+ local_tm_struct->tm_sec);
161152 } else {
162162- // Display the fallback/error name directly (e.g., "Wait...", "ERR:NOZONE")
163163- snprintf(s_closest_noon_buffer, sizeof(s_closest_noon_buffer), "%s",
164164- s_selected_city_name ? s_selected_city_name : "ERR:NULL");
153153+ snprintf(s_time_buffer, sizeof(s_time_buffer), "ERR");
165154 }
166166-167167-168168- text_layer_set_text(layer, s_closest_noon_buffer);
155155+ text_layer_set_text(time_layer, s_time_buffer);
169156}
+8-5
src/c/clock_closest_noon.h
···44#include <pebble.h> // Pebble time_t definition and UI types
55#include <stddef.h> // For size_t
6677-// Initializes the Closest Noon clock layer
88-TextLayer* clock_closest_noon_init(GRect bounds, Layer *window_layer);
77+// Initializes the city name TextLayer for the Closest Noon clock
88+TextLayer* clock_closest_noon_city_init(GRect bounds, Layer *window_layer);
99+1010+// Initializes the hero time TextLayer for the Closest Noon clock
1111+TextLayer* clock_closest_noon_time_init(GRect bounds, Layer *window_layer);
9121010-// Deinitializes the Closest Noon clock layer
1313+// Deinitializes a Closest Noon TextLayer (city or time)
1114void clock_closest_noon_deinit(TextLayer *layer);
12151313-// Updates the Closest Noon clock layer
1414-void clock_closest_noon_update(TextLayer *layer, time_t current_seconds_utc);
1616+// Updates the Closest Noon city and time TextLayers
1717+void clock_closest_noon_update(TextLayer *city_layer, TextLayer *time_layer, time_t current_seconds_utc);
15181619#endif // CLOCK_CLOSEST_NOON_H
+44-19
src/c/watchface.c
···10101111// --- Window and Layer Globals ---
1212static Window *s_main_window;
1313-static TextLayer *s_beat_layer;
1313+static TextLayer *s_closest_noon_city_layer;
1414+static TextLayer *s_closest_noon_time_layer;
1415static TextLayer *s_tid_layer;
1515-static TextLayer *s_closest_noon_layer;
1616-static TextLayer *s_decimal_layer;
1616+static TextLayer *s_beat_layer;
17171818// --- Pebble Window Management ---
1919···2222 time_t seconds;
2323 uint16_t milliseconds;
2424 time_ms(&seconds, &milliseconds);
2525-2626- // Update both time displays
2727- clock_beat_update(s_beat_layer, seconds);
2525+ // Hero: Closest Noon (update city and time layers)
2626+ clock_closest_noon_update(s_closest_noon_city_layer, s_closest_noon_time_layer, seconds);
2727+ // Footer: TID (larger) and Beat (smaller)
2828 clock_tid_update(s_tid_layer, seconds, milliseconds);
2929- clock_closest_noon_update(s_closest_noon_layer, seconds);
3030- clock_decimal_update(s_decimal_layer, seconds);
2929+ clock_beat_update(s_beat_layer, seconds);
3130}
32313332static void main_window_load(Window *window) {
3433 Layer *window_layer = window_get_root_layer(window);
3534 GRect bounds = layer_get_bounds(window_layer);
3636- const int16_t total_h = bounds.size.h;
3737- const int16_t layer_h = total_h / 4;
3535+ // Hero area for Closest Noon: split into city + large time
3636+ int footer_h = 48;
3737+ int hero_h = bounds.size.h - footer_h;
3838+ const int city_h = 24;
3939+ const int usable_h = hero_h - city_h;
4040+ const int time_font_h = 42;
4141+ // Create city name line
4242+ s_closest_noon_city_layer = clock_closest_noon_city_init(
4343+ GRect(0, 0, bounds.size.w, city_h), window_layer);
4444+ text_layer_set_text_alignment(s_closest_noon_city_layer, GTextAlignmentCenter);
4545+ // Create hero time line, vertically centered
4646+ int time_y = city_h + (usable_h - time_font_h) / 2;
4747+ s_closest_noon_time_layer = clock_closest_noon_time_init(
4848+ GRect(0, time_y, bounds.size.w, time_font_h), window_layer);
4949+5050+ // Setup footer area
5151+ int w = bounds.size.w;
5252+ int h = bounds.size.h;
5353+ int footer_y = h - footer_h;
5454+ // Two line heights to fit fonts without clipping
5555+ int tid_h = 26; // tall enough for 18px font + padding
5656+ int beat_h = footer_h - tid_h;
38573939- // Create layers
4040- s_beat_layer = clock_beat_init(GRect(0, 0, bounds.size.w, layer_h), window_layer);
4141- s_decimal_layer = clock_decimal_init(GRect(0, layer_h, bounds.size.w, layer_h), window_layer);
4242- s_closest_noon_layer = clock_closest_noon_init(GRect(0, 2 * layer_h, bounds.size.w, layer_h), window_layer);
4343- s_tid_layer = clock_tid_init(GRect(0, 3 * layer_h, bounds.size.w, layer_h), window_layer);
5858+ // Footer line 1: TID (bigger, center aligned)
5959+ s_tid_layer = clock_tid_init(GRect(0, footer_y, w, tid_h), window_layer);
6060+ text_layer_set_font(s_tid_layer, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD));
6161+ text_layer_set_text_alignment(s_tid_layer, GTextAlignmentCenter);
6262+6363+ // Footer line 2: Beat (smaller, center aligned)
6464+ s_beat_layer = clock_beat_init(GRect(0, footer_y + tid_h, w, beat_h), window_layer);
6565+ text_layer_set_font(s_beat_layer, fonts_get_system_font(FONT_KEY_GOTHIC_14));
6666+ text_layer_set_text_alignment(s_beat_layer, GTextAlignmentCenter);
4467}
45684669static void main_window_unload(Window *window) {
4747- // Destroy TextLayers
7070+ // Destroy Closest Noon layers
7171+ clock_closest_noon_deinit(s_closest_noon_city_layer);
7272+ clock_closest_noon_deinit(s_closest_noon_time_layer);
7373+ clock_tid_deinit(s_tid_layer);
4874 clock_beat_deinit(s_beat_layer);
4949- clock_closest_noon_deinit(s_closest_noon_layer);
5050- clock_tid_deinit(s_tid_layer);
5151- clock_decimal_deinit(s_decimal_layer);
5275}
53765477static void init() {
···56795780 // Create main Window element and assign to pointer
5881 s_main_window = window_create();
8282+ // Ensure text layers with clear background show up on white
8383+ window_set_background_color(s_main_window, GColorWhite);
59846085 // Set handlers to manage the elements inside the Window
6186 window_set_window_handlers(