URI:
       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 }