diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-12 15:31:54 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-12 15:31:54 +0300 |
| commit | bf1036fd6984de1253764078aedf2754d2be69f5 (patch) | |
| tree | 2ef26b6a14b6ae7ecfc2f33b5e0cef158f22d576 /src/c | |
| parent | c8cd9609904b6b04003934a9888a0eea08cd3eb4 (diff) | |
a2: implement fasting science screen
Diffstat (limited to 'src/c')
| -rw-r--r-- | src/c/fastforge.c | 148 |
1 files changed, 145 insertions, 3 deletions
diff --git a/src/c/fastforge.c b/src/c/fastforge.c index da74496..ca0fd59 100644 --- a/src/c/fastforge.c +++ b/src/c/fastforge.c @@ -42,6 +42,7 @@ static Window *s_menu_window; static Window *s_timer_window; static Window *s_goal_window; static Window *s_presets_window; +static Window *s_science_window; static Window *s_stats_window; static Window *s_detail_window; static Window *s_history_window; @@ -69,6 +70,10 @@ static TextLayer *s_goal_time_layer; static TextLayer *s_goal_stage_layer; static TextLayer *s_goal_hint_layer; +static TextLayer *s_science_title_layer; +static TextLayer *s_science_timeline_layer; +static TextLayer *s_science_showdown_layer; +static TextLayer *s_science_hint_layer; static TextLayer *s_placeholder_title_layer; static TextLayer *s_placeholder_body_layer; static TextLayer *s_placeholder_hint_layer; @@ -93,6 +98,9 @@ static char s_detail_text[48]; static char s_stage_text[32]; static char s_goal_time_text[24]; static char s_goal_stage_text[24]; +static char s_science_timeline_text[192]; +static char s_science_showdown_text[160]; +static char s_science_hint_text[80]; static char s_menu_stop_subtitle[32]; static char s_placeholder_title_text[24]; static char s_placeholder_body_text[160]; @@ -124,6 +132,7 @@ static void sync_main_menu_state(void); static void refresh_stats_window_content(void); static void history_menu_reload(void); static void refresh_running_edit_window_content(void); +static void refresh_science_window_content(void); static void recompute_streak_data_from_history(void); static time_t entry_duration_seconds(const FastEntry *entry); static void recompute_streak_data_for_today(void); @@ -692,6 +701,34 @@ static void show_placeholder_window(const char *title, const char *body, const c } } +static void set_science_content(void) { + snprintf(s_science_timeline_text, sizeof(s_science_timeline_text), + "0h Fed 4h insulin drop\n" + "8h Glycogen drop 12h fat burn\n" + "18h Ketones rise 24h deep keto\n" + "36h+ Adaptation peaks"); + snprintf(s_science_showdown_text, sizeof(s_science_showdown_text), + "5x20h = 100h/wk\n" + "2x24h+2x18h = 84h/wk\n" + "20h wins consistency.\n" + "24h anchor fits the mixed plan."); + snprintf(s_science_hint_text, sizeof(s_science_hint_text), + "SELECT 20h plan\nDOWN 24h anchor BACK Menu"); +} + +static void refresh_science_window_content(void) { + set_science_content(); + if (s_science_timeline_layer) { + text_layer_set_text(s_science_timeline_layer, s_science_timeline_text); + } + if (s_science_showdown_layer) { + text_layer_set_text(s_science_showdown_layer, s_science_showdown_text); + } + if (s_science_hint_layer) { + text_layer_set_text(s_science_hint_layer, s_science_hint_text); + } +} + static int progress_width_for_elapsed(time_t elapsed_seconds, uint32_t total_seconds, int width) { if (width <= 0 || total_seconds == 0 || elapsed_seconds <= 0) { return 0; @@ -871,6 +908,21 @@ static void start_fast_from_preset(uint16_t target_minutes, const char *label) { refresh_all_ui_state(); } +static void start_fast_from_science_preset(uint16_t target_minutes) { + if (!fast_start(target_minutes)) { + show_placeholder_window("FAST RUNNING", + "Stop the current fast before starting a new one.", + "BACK Menu"); + return; + } + + if (window_stack_contains_window(s_science_window)) { + window_stack_remove(s_science_window, false); + } + safe_push_window(s_timer_window, true); + refresh_all_ui_state(); +} + static uint16_t history_menu_get_num_sections(MenuLayer *menu_layer, void *data) { (void)menu_layer; (void)data; @@ -1215,9 +1267,8 @@ static void menu_statistics_callback(int index, void *context) { static void menu_science_callback(int index, void *context) { (void)index; (void)context; - show_placeholder_window("FASTING SCIENCE", - "Screen pending.\nTimeline + protocol comparison will live here.", - "BACK Menu"); + refresh_science_window_content(); + safe_push_window(s_science_window, true); } static void menu_settings_callback(int index, void *context) { @@ -1337,6 +1388,32 @@ static void placeholder_dismiss_handler(ClickRecognizerRef recognizer, void *con window_stack_remove(s_detail_window, true); } +static void science_select_click_handler(ClickRecognizerRef recognizer, void *context) { + (void)recognizer; + (void)context; + start_fast_from_science_preset(20 * 60); +} + +static void science_down_click_handler(ClickRecognizerRef recognizer, void *context) { + (void)recognizer; + (void)context; + start_fast_from_science_preset(24 * 60); +} + +static void science_back_click_handler(ClickRecognizerRef recognizer, void *context) { + (void)recognizer; + (void)context; + window_stack_remove(s_science_window, true); +} + +static void science_click_config_provider(void *context) { + (void)context; + window_single_click_subscribe(BUTTON_ID_SELECT, science_select_click_handler); + window_single_click_subscribe(BUTTON_ID_DOWN, science_down_click_handler); + window_single_click_subscribe(BUTTON_ID_BACK, science_back_click_handler); + window_single_click_subscribe(BUTTON_ID_UP, science_back_click_handler); +} + static void placeholder_click_config_provider(void *context) { (void)context; window_single_click_subscribe(BUTTON_ID_SELECT, placeholder_dismiss_handler); @@ -1715,6 +1792,62 @@ static void stats_window_appear(Window *window) { refresh_stats_window_content(); } +static void science_window_load(Window *window) { + Layer *window_layer = window_get_root_layer(window); + GRect bounds = layer_get_bounds(window_layer); + + s_science_title_layer = text_layer_create(GRect(0, 4, bounds.size.w, 24)); + text_layer_set_background_color(s_science_title_layer, GColorClear); + text_layer_set_text_color(s_science_title_layer, GColorBlack); + text_layer_set_text_alignment(s_science_title_layer, GTextAlignmentCenter); + text_layer_set_font(s_science_title_layer, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD)); + text_layer_set_text(s_science_title_layer, "FASTING SCIENCE"); + + s_science_timeline_layer = text_layer_create(GRect(4, 28, bounds.size.w - 8, 56)); + text_layer_set_background_color(s_science_timeline_layer, GColorClear); + text_layer_set_text_color(s_science_timeline_layer, GColorBlack); + text_layer_set_text_alignment(s_science_timeline_layer, GTextAlignmentLeft); + text_layer_set_overflow_mode(s_science_timeline_layer, GTextOverflowModeWordWrap); + text_layer_set_font(s_science_timeline_layer, fonts_get_system_font(FONT_KEY_GOTHIC_14)); + + s_science_showdown_layer = text_layer_create(GRect(4, 84, bounds.size.w - 8, 54)); + text_layer_set_background_color(s_science_showdown_layer, GColorClear); + text_layer_set_text_color(s_science_showdown_layer, GColorBlack); + text_layer_set_text_alignment(s_science_showdown_layer, GTextAlignmentLeft); + text_layer_set_overflow_mode(s_science_showdown_layer, GTextOverflowModeWordWrap); + text_layer_set_font(s_science_showdown_layer, fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD)); + + s_science_hint_layer = text_layer_create(GRect(0, 140, bounds.size.w, 28)); + text_layer_set_background_color(s_science_hint_layer, GColorClear); + text_layer_set_text_color(s_science_hint_layer, GColorBlack); + text_layer_set_text_alignment(s_science_hint_layer, GTextAlignmentCenter); + text_layer_set_overflow_mode(s_science_hint_layer, GTextOverflowModeWordWrap); + text_layer_set_font(s_science_hint_layer, fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD)); + + layer_add_child(window_layer, text_layer_get_layer(s_science_title_layer)); + layer_add_child(window_layer, text_layer_get_layer(s_science_timeline_layer)); + layer_add_child(window_layer, text_layer_get_layer(s_science_showdown_layer)); + layer_add_child(window_layer, text_layer_get_layer(s_science_hint_layer)); + refresh_science_window_content(); +} + +static void science_window_unload(Window *window) { + (void)window; + text_layer_destroy(s_science_title_layer); + s_science_title_layer = NULL; + text_layer_destroy(s_science_timeline_layer); + s_science_timeline_layer = NULL; + text_layer_destroy(s_science_showdown_layer); + s_science_showdown_layer = NULL; + text_layer_destroy(s_science_hint_layer); + s_science_hint_layer = NULL; +} + +static void science_window_appear(Window *window) { + (void)window; + refresh_science_window_content(); +} + static void detail_window_load(Window *window) { Layer *window_layer = window_get_root_layer(window); GRect bounds = layer_get_bounds(window_layer); @@ -1905,6 +2038,14 @@ static void init_windows(void) { .unload = stats_window_unload }); + s_science_window = window_create(); + window_set_click_config_provider(s_science_window, science_click_config_provider); + window_set_window_handlers(s_science_window, (WindowHandlers) { + .load = science_window_load, + .appear = science_window_appear, + .unload = science_window_unload + }); + s_detail_window = window_create(); window_set_click_config_provider(s_detail_window, placeholder_click_config_provider); window_set_window_handlers(s_detail_window, (WindowHandlers) { @@ -1915,6 +2056,7 @@ static void init_windows(void) { static void destroy_windows(void) { window_destroy(s_detail_window); + window_destroy(s_science_window); window_destroy(s_stats_window); window_destroy(s_running_edit_window); window_destroy(s_history_edit_window); |
