scene_timer_config.c (7342B)
1 #include "../timed_remote.h" 2 #include "timed_remote_scene.h" 3 4 enum { 5 TimerConfigIndexMode, 6 TimerConfigIndexHours, 7 TimerConfigIndexMinutes, 8 TimerConfigIndexSeconds, 9 TimerConfigIndexRepeat, 10 TimerConfigIndexConfirm, 11 }; 12 13 static void timer_config_mode_change(VariableItem *item) { 14 TimedRemoteApp *app = variable_item_get_context(item); 15 uint8_t index = variable_item_get_current_value_index(item); 16 app->timer_mode = (index == 0) ? TimerModeCountdown : TimerModeScheduled; 17 variable_item_set_current_value_text( 18 item, app->timer_mode == TimerModeCountdown ? "Countdown" : "Scheduled"); 19 20 /* Disable repeat in scheduled mode */ 21 if (app->timer_mode == TimerModeScheduled) { 22 app->repeat_count = 0; 23 } 24 25 /* Trigger rebuild to show/hide repeat options */ 26 view_dispatcher_send_custom_event(app->view_dispatcher, 27 TimedRemoteEventModeChanged); 28 } 29 30 static void timer_config_hours_change(VariableItem *item) { 31 TimedRemoteApp *app = variable_item_get_context(item); 32 uint8_t index = variable_item_get_current_value_index(item); 33 app->hours = index; 34 char buf[4]; 35 snprintf(buf, sizeof(buf), "%02d", app->hours); 36 variable_item_set_current_value_text(item, buf); 37 } 38 39 static void timer_config_minutes_change(VariableItem *item) { 40 TimedRemoteApp *app = variable_item_get_context(item); 41 uint8_t index = variable_item_get_current_value_index(item); 42 app->minutes = index; 43 char buf[4]; 44 snprintf(buf, sizeof(buf), "%02d", app->minutes); 45 variable_item_set_current_value_text(item, buf); 46 } 47 48 static void timer_config_seconds_change(VariableItem *item) { 49 TimedRemoteApp *app = variable_item_get_context(item); 50 uint8_t index = variable_item_get_current_value_index(item); 51 app->seconds = index; 52 char buf[4]; 53 snprintf(buf, sizeof(buf), "%02d", app->seconds); 54 variable_item_set_current_value_text(item, buf); 55 } 56 57 static void timer_config_repeat_change(VariableItem *item) { 58 TimedRemoteApp *app = variable_item_get_context(item); 59 uint8_t index = variable_item_get_current_value_index(item); 60 61 char buf[16]; 62 if (index == 0) { 63 /* Off */ 64 app->repeat_count = 0; 65 snprintf(buf, sizeof(buf), "Off"); 66 } else if (index == 1) { 67 /* Unlimited */ 68 app->repeat_count = 255; 69 snprintf(buf, sizeof(buf), "Unlimited"); 70 } else { 71 /* 1, 2, 3, ... 99 */ 72 app->repeat_count = index - 1; 73 snprintf(buf, sizeof(buf), "%d", app->repeat_count); 74 } 75 variable_item_set_current_value_text(item, buf); 76 } 77 78 static void timer_config_enter_callback(void *context, uint32_t index) { 79 TimedRemoteApp *app = context; 80 /* In countdown mode, confirm is at index 5, in scheduled mode it's at index 4 */ 81 uint32_t confirm_index = app->timer_mode == TimerModeCountdown 82 ? TimerConfigIndexConfirm 83 : (TimerConfigIndexSeconds + 1); 84 if (index == confirm_index) { 85 view_dispatcher_send_custom_event(app->view_dispatcher, 86 TimedRemoteEventTimerConfigured); 87 } 88 } 89 90 static void build_timer_config_list(TimedRemoteApp *app) { 91 VariableItem *item; 92 char buf[16]; 93 94 variable_item_list_reset(app->variable_item_list); 95 96 /* Mode: Countdown / Scheduled */ 97 item = variable_item_list_add(app->variable_item_list, "Mode", 2, 98 timer_config_mode_change, app); 99 variable_item_set_current_value_index( 100 item, app->timer_mode == TimerModeCountdown ? 0 : 1); 101 variable_item_set_current_value_text( 102 item, app->timer_mode == TimerModeCountdown ? "Countdown" : "Scheduled"); 103 104 /* Hours: 0-23 */ 105 item = variable_item_list_add(app->variable_item_list, "Hours", 24, 106 timer_config_hours_change, app); 107 variable_item_set_current_value_index(item, app->hours); 108 snprintf(buf, sizeof(buf), "%02d", app->hours); 109 variable_item_set_current_value_text(item, buf); 110 111 /* Minutes: 0-59 */ 112 item = variable_item_list_add(app->variable_item_list, "Minutes", 60, 113 timer_config_minutes_change, app); 114 variable_item_set_current_value_index(item, app->minutes); 115 snprintf(buf, sizeof(buf), "%02d", app->minutes); 116 variable_item_set_current_value_text(item, buf); 117 118 /* Seconds: 0-59 */ 119 item = variable_item_list_add(app->variable_item_list, "Seconds", 60, 120 timer_config_seconds_change, app); 121 variable_item_set_current_value_index(item, app->seconds); 122 snprintf(buf, sizeof(buf), "%02d", app->seconds); 123 variable_item_set_current_value_text(item, buf); 124 125 /* Repeat options - only for countdown mode */ 126 if (app->timer_mode == TimerModeCountdown) { 127 /* Repeat: Off, Unlimited, 1, 2, 3, ... 99 (total 101 values) */ 128 item = variable_item_list_add(app->variable_item_list, "Repeat", 101, 129 timer_config_repeat_change, app); 130 131 /* Convert repeat_count to index */ 132 uint8_t repeat_index; 133 if (app->repeat_count == 0) { 134 repeat_index = 0; /* Off */ 135 } else if (app->repeat_count == 255) { 136 repeat_index = 1; /* Unlimited */ 137 } else { 138 repeat_index = app->repeat_count + 1; /* 1-99 */ 139 } 140 variable_item_set_current_value_index(item, repeat_index); 141 142 /* Set display text */ 143 if (app->repeat_count == 0) { 144 variable_item_set_current_value_text(item, "Off"); 145 } else if (app->repeat_count == 255) { 146 variable_item_set_current_value_text(item, "Unlimited"); 147 } else { 148 snprintf(buf, sizeof(buf), "%d", app->repeat_count); 149 variable_item_set_current_value_text(item, buf); 150 } 151 } 152 153 /* Confirm button */ 154 variable_item_list_add(app->variable_item_list, ">> Start Timer <<", 0, NULL, 155 NULL); 156 157 variable_item_list_set_enter_callback(app->variable_item_list, 158 timer_config_enter_callback, app); 159 } 160 161 void timed_remote_scene_timer_config_on_enter(void *context) { 162 TimedRemoteApp *app = context; 163 build_timer_config_list(app); 164 view_dispatcher_switch_to_view(app->view_dispatcher, 165 TimedRemoteViewVariableItemList); 166 } 167 168 bool timed_remote_scene_timer_config_on_event(void *context, 169 SceneManagerEvent event) { 170 TimedRemoteApp *app = context; 171 bool consumed = false; 172 173 if (event.type == SceneManagerEventTypeCustom) { 174 if (event.event == TimedRemoteEventModeChanged) { 175 /* Rebuild the list to show/hide repeat options */ 176 build_timer_config_list(app); 177 consumed = true; 178 } else if (event.event == TimedRemoteEventTimerConfigured) { 179 /* Initialize repeats remaining based on repeat_count encoding */ 180 if (app->repeat_count == 0) { 181 /* Off - single execution */ 182 app->repeats_remaining = 1; 183 } else if (app->repeat_count == 255) { 184 /* Unlimited */ 185 app->repeats_remaining = 255; 186 } else { 187 /* Fixed count (1-99): initial + N repeats = N+1 total executions */ 188 app->repeats_remaining = app->repeat_count + 1; 189 } 190 scene_manager_next_scene(app->scene_manager, 191 TimedRemoteSceneTimerRunning); 192 consumed = true; 193 } 194 } 195 196 return consumed; 197 } 198 199 void timed_remote_scene_timer_config_on_exit(void *context) { 200 TimedRemoteApp *app = context; 201 variable_item_list_reset(app->variable_item_list); 202 }