scene_timer_config.c - timed-remote - Flipper Zero app for sending delayed IR commands
HTML git clone git://src.adamsgaard.dk/timed-remote
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
scene_timer_config.c (5444B)
---
1 #include <stdio.h>
2
3 #include "../timed_remote.h"
4 #include "timed_remote_scene.h"
5
6 enum
7 {
8 ITEM_MODE,
9 ITEM_HOURS,
10 ITEM_MINUTES,
11 ITEM_SECONDS,
12 ITEM_REPEAT,
13 ITEM_START,
14 };
15
16 #define REPEAT_OFF 0U
17 #define REPEAT_UNLIMITED 255U
18
19 static void add_time_item(VariableItemList *, const char *, uint8_t, uint8_t,
20 VariableItemChangeCallback, TimedRemoteApp *);
21 static void build_items(TimedRemoteApp *);
22 static uint8_t index_from_repeat(uint8_t);
23 static void set_repeat_text(VariableItem *, uint8_t);
24 static uint8_t repeat_from_index(uint8_t);
25 static void set_two_digits(VariableItem *, uint8_t);
26 static uint32_t start_item_index(const TimedRemoteApp *);
27
28 static void
29 set_two_digits(VariableItem *item, uint8_t value)
30 {
31 char text[4];
32
33 snprintf(text, sizeof(text), "%02d", value);
34 variable_item_set_current_value_text(item, text);
35 }
36
37 static uint8_t
38 repeat_from_index(uint8_t index)
39 {
40 if (index == 0)
41 return REPEAT_OFF;
42 if (index == 1)
43 return REPEAT_UNLIMITED;
44 return index - 1;
45 }
46
47 static uint8_t
48 index_from_repeat(uint8_t repeat)
49 {
50 if (repeat == REPEAT_OFF)
51 return 0;
52 if (repeat == REPEAT_UNLIMITED)
53 return 1;
54 return repeat + 1;
55 }
56
57 static void
58 set_repeat_text(VariableItem *item, uint8_t repeat)
59 {
60 char text[16];
61
62 if (repeat == REPEAT_OFF) {
63 variable_item_set_current_value_text(item, "Off");
64 return;
65 }
66 if (repeat == REPEAT_UNLIMITED) {
67 variable_item_set_current_value_text(item, "Unlimited");
68 return;
69 }
70
71 snprintf(text, sizeof(text), "%u", repeat);
72 variable_item_set_current_value_text(item, text);
73 }
74
75 static uint32_t
76 start_item_index(const TimedRemoteApp *app)
77 {
78 if (app->mode == MODE_COUNTDOWN)
79 return ITEM_START;
80 return ITEM_REPEAT;
81 }
82
83 static void
84 on_mode_change(VariableItem *item)
85 {
86 TimedRemoteApp *app;
87 uint8_t mode_index;
88
89 app = variable_item_get_context(item);
90 mode_index = variable_item_get_current_value_index(item);
91 app->mode = mode_index == 0 ? MODE_COUNTDOWN : MODE_SCHEDULED;
92 variable_item_set_current_value_text(
93 item,
94 app->mode == MODE_COUNTDOWN ? "Countdown" : "Scheduled");
95 if (app->mode == MODE_SCHEDULED)
96 app->repeat = REPEAT_OFF;
97
98 view_dispatcher_send_custom_event(app->vd, EVENT_MODE_CHANGED);
99 }
100
101 static void
102 on_hours_change(VariableItem *item)
103 {
104 TimedRemoteApp *app;
105
106 app = variable_item_get_context(item);
107 app->h = variable_item_get_current_value_index(item);
108 set_two_digits(item, app->h);
109 }
110
111 static void
112 on_minutes_change(VariableItem *item)
113 {
114 TimedRemoteApp *app;
115
116 app = variable_item_get_context(item);
117 app->m = variable_item_get_current_value_index(item);
118 set_two_digits(item, app->m);
119 }
120
121 static void
122 on_seconds_change(VariableItem *item)
123 {
124 TimedRemoteApp *app;
125
126 app = variable_item_get_context(item);
127 app->s = variable_item_get_current_value_index(item);
128 set_two_digits(item, app->s);
129 }
130
131 static void
132 on_repeat_change(VariableItem *item)
133 {
134 TimedRemoteApp *app;
135
136 app = variable_item_get_context(item);
137 app->repeat = repeat_from_index(variable_item_get_current_value_index(item));
138 set_repeat_text(item, app->repeat);
139 }
140
141 static void
142 on_enter(void *context, uint32_t index)
143 {
144 TimedRemoteApp *app;
145
146 app = context;
147 if (index != start_item_index(app))
148 return;
149
150 view_dispatcher_send_custom_event(app->vd, EVENT_TIMER_CONFIGURED);
151 }
152
153 static void
154 add_time_item(VariableItemList *list,
155 const char *name,
156 uint8_t value_count,
157 uint8_t value,
158 VariableItemChangeCallback callback,
159 TimedRemoteApp *app)
160 {
161 VariableItem *item;
162
163 item = variable_item_list_add(list, name, value_count, callback, app);
164 variable_item_set_current_value_index(item, value);
165 set_two_digits(item, value);
166 }
167
168 static void
169 build_items(TimedRemoteApp *app)
170 {
171 VariableItem *item;
172
173 variable_item_list_reset(app->vlist);
174
175 item = variable_item_list_add(app->vlist, "Mode", 2, on_mode_change, app);
176 variable_item_set_current_value_index(
177 item,
178 app->mode == MODE_COUNTDOWN ? 0 : 1);
179 variable_item_set_current_value_text(
180 item,
181 app->mode == MODE_COUNTDOWN ? "Countdown" : "Scheduled");
182
183 add_time_item(app->vlist, "Hours", 24, app->h, on_hours_change, app);
184 add_time_item(app->vlist, "Minutes", 60, app->m, on_minutes_change, app);
185 add_time_item(app->vlist, "Seconds", 60, app->s, on_seconds_change, app);
186
187 if (app->mode == MODE_COUNTDOWN) {
188 item = variable_item_list_add(
189 app->vlist,
190 "Repeat",
191 101,
192 on_repeat_change,
193 app);
194 variable_item_set_current_value_index(item, index_from_repeat(app->repeat));
195 set_repeat_text(item, app->repeat);
196 }
197
198 variable_item_list_add(app->vlist, ">> Start Timer <<", 0, NULL, NULL);
199 variable_item_list_set_enter_callback(app->vlist, on_enter, app);
200 }
201
202 void
203 scene_cfg_enter(void *context)
204 {
205 TimedRemoteApp *app;
206
207 app = context;
208 build_items(app);
209 view_dispatcher_switch_to_view(app->vd, VIEW_LIST);
210 }
211
212 bool
213 scene_cfg_event(void *context, SceneManagerEvent event)
214 {
215 TimedRemoteApp *app;
216
217 app = context;
218 if (event.type != SceneManagerEventTypeCustom)
219 return false;
220
221 if (event.event == EVENT_MODE_CHANGED) {
222 build_items(app);
223 return true;
224 }
225 if (event.event != EVENT_TIMER_CONFIGURED)
226 return false;
227
228 if (app->repeat == REPEAT_OFF)
229 app->repeat_left = 1;
230 else if (app->repeat == REPEAT_UNLIMITED)
231 app->repeat_left = REPEAT_UNLIMITED;
232 else
233 app->repeat_left = app->repeat + 1;
234
235 scene_manager_next_scene(app->sm, SCENE_RUN);
236 return true;
237 }
238
239 void
240 scene_cfg_exit(void *context)
241 {
242 TimedRemoteApp *app;
243
244 app = context;
245 variable_item_list_reset(app->vlist);
246 }