timed-remote

Flipper Zero app for sending delayed IR commands
git clone git://src.adamsgaard.dk/timed-remote # fast
git clone https://src.adamsgaard.dk/timed-remote.git # slow
Log | Files | Refs | README | LICENSE Back to index

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 }