| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- #include "countdown_view.h"
- #include "../utils/utils.h"
- // internal
- static void handle_misc_cmd(CountDownTimView* hw, CountDownViewCmd cmd);
- static void handle_time_setting_updown(CountDownTimView* cdv, CountDownViewCmd cmd);
- static void handle_time_setting_select(InputKey key, CountDownTimView* cdv);
- static void draw_selection(Canvas* canvas, CountDownViewSelect selection);
- static void countdown_timer_start_counting(CountDownTimView* cdv);
- static void countdown_timer_pause_counting(CountDownTimView* cdv);
- // callbacks
- static void countdown_timer_view_on_enter(void* ctx);
- static void countdown_timer_view_on_draw(Canvas* canvas, void* ctx);
- static bool countdown_timer_view_on_input(InputEvent* event, void* ctx);
- static void timer_cb(void* ctx);
- CountDownTimView* countdown_timer_view_new() {
- CountDownTimView* cdv = (CountDownTimView*)(malloc(sizeof(CountDownTimView)));
- cdv->view = view_alloc();
- cdv->timer = furi_timer_alloc(timer_cb, FuriTimerTypePeriodic, cdv);
- cdv->counting = false;
- view_set_context(cdv->view, cdv);
- view_allocate_model(cdv->view, ViewModelTypeLocking, sizeof(CountDownModel));
- view_set_draw_callback(cdv->view, countdown_timer_view_on_draw);
- view_set_input_callback(cdv->view, countdown_timer_view_on_input);
- view_set_enter_callback(cdv->view, countdown_timer_view_on_enter);
- return cdv;
- }
- void countdown_timer_view_delete(CountDownTimView* cdv) {
- furi_assert(cdv);
- view_free(cdv->view);
- furi_timer_stop(cdv->timer);
- furi_timer_free(cdv->timer);
- free(cdv);
- }
- View* countdown_timer_view_get_view(CountDownTimView* cdv) {
- return cdv->view;
- }
- void countdown_timer_view_state_reset(CountDownTimView* cdv) {
- cdv->counting = false;
- with_view_model(
- cdv->view, CountDownModel * model, { model->count = model->saved_count_setting; }, true)
- }
- void countdown_timer_state_toggle(CountDownTimView* cdv) {
- bool on = cdv->counting;
- if(!on) {
- countdown_timer_start_counting(cdv);
- } else {
- countdown_timer_pause_counting(cdv);
- }
- cdv->counting = !on;
- }
- // on enter callback, CountDownTimView as ctx
- static void countdown_timer_view_on_enter(void* ctx) {
- furi_assert(ctx);
- CountDownTimView* cdv = (CountDownTimView*)ctx;
- // set current count to a initial value
- with_view_model(
- cdv->view,
- CountDownModel * model,
- {
- model->count = INIT_COUNT;
- model->saved_count_setting = INIT_COUNT;
- },
- true);
- }
- // view draw callback, CountDownModel as ctx
- static void countdown_timer_view_on_draw(Canvas* canvas, void* ctx) {
- furi_assert(ctx);
- CountDownModel* model = (CountDownModel*)ctx;
- char buffer[64];
- int32_t count = model->count;
- int32_t expected_count = model->saved_count_setting;
- CountDownViewSelect select = model->select;
- // elements_frame(canvas, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
- canvas_set_font(canvas, FontBigNumbers);
- draw_selection(canvas, select);
- parse_sec_to_time_str(buffer, sizeof(buffer), count);
- canvas_draw_str_aligned(
- canvas, SCREEN_CENTER_X, SCREEN_CENTER_Y, AlignCenter, AlignCenter, buffer);
- elements_progress_bar(canvas, 0, 0, SCREEN_WIDTH, (1.0 * count / expected_count));
- }
- // keys input event callback, CountDownTimView as ctx
- static bool countdown_timer_view_on_input(InputEvent* event, void* ctx) {
- furi_assert(ctx);
- CountDownTimView* hw = (CountDownTimView*)ctx;
- if(event->type == InputTypeShort || event->type == InputTypeRepeat) {
- switch(event->key) {
- case InputKeyUp:
- case InputKeyDown:
- case InputKeyRight:
- case InputKeyLeft:
- handle_time_setting_select(event->key, hw);
- break;
- case InputKeyOk:
- if(event->type == InputTypeShort) {
- handle_misc_cmd(hw, CountDownTimerToggleCounting);
- }
- break;
- case InputKeyBack:
- return false;
- break;
- default:
- break;
- }
- return true;
- }
- if(event->type == InputTypeLong) {
- switch(event->key) {
- case InputKeyOk:
- handle_misc_cmd(hw, CountDownTimerReset);
- break;
- case InputKeyBack:
- return false;
- break;
- default:
- break;
- }
- return true;
- }
- return false;
- }
- static void timer_cb(void* ctx) {
- furi_assert(ctx);
- CountDownTimView* cdv = (CountDownTimView*)ctx;
- int32_t count;
- bool timeup = false;
- // decrement counter
- with_view_model(
- cdv->view,
- CountDownModel * model,
- {
- count = model->count;
- count--;
- // check timeup
- if(count <= 0) {
- count = 0;
- timeup = true;
- }
- model->count = count;
- },
- true);
- if(timeup) {
- handle_misc_cmd(cdv, CountDownTimerTimeUp);
- }
- }
- static void handle_time_setting_updown(CountDownTimView* cdv, CountDownViewCmd cmd) {
- int32_t count;
- with_view_model(
- cdv->view,
- CountDownModel * model,
- {
- count = model->count;
- switch(cmd) {
- case CountDownTimerMinuteUp:
- count += 60;
- break;
- case CountDownTimerMinuteDown:
- count -= 60;
- break;
- case CountDownTimerHourDown:
- count -= 3600;
- break;
- case CountDownTimerHourUp:
- count += 3600;
- break;
- case CountDownTimerSecUp:
- count++;
- break;
- case CountDownTimerSecDown:
- count--;
- break;
- default:
- break;
- }
- if(count < 0) {
- count = 0;
- }
- // update count state
- model->count = count;
- // save the count time setting
- model->saved_count_setting = count;
- },
- true);
- }
- static void handle_misc_cmd(CountDownTimView* hw, CountDownViewCmd cmd) {
- switch(cmd) {
- case CountDownTimerTimeUp:
- notification_timeup();
- break;
- case CountDownTimerReset:
- furi_timer_stop(hw->timer);
- countdown_timer_view_state_reset(hw);
- notification_off();
- break;
- case CountDownTimerToggleCounting:
- countdown_timer_state_toggle(hw);
- break;
- default:
- break;
- }
- return;
- }
- static void handle_time_setting_select(InputKey key, CountDownTimView* cdv) {
- bool counting = cdv->counting;
- CountDownViewCmd setting_cmd = CountDownTimerSecUp;
- CountDownViewSelect selection;
- if(counting) {
- return;
- }
- // load current selection from model context
- with_view_model(
- cdv->view, CountDownModel * model, { selection = model->select; }, false);
- // select
- switch(key) {
- case InputKeyUp:
- switch(selection) {
- case CountDownTimerSelectSec:
- setting_cmd = CountDownTimerSecUp;
- break;
- case CountDownTimerSelectMinute:
- setting_cmd = CountDownTimerMinuteUp;
- break;
- case CountDownTimerSelectHour:
- setting_cmd = CountDownTimerHourUp;
- break;
- }
- handle_time_setting_updown(cdv, setting_cmd);
- break;
- case InputKeyDown:
- switch(selection) {
- case CountDownTimerSelectSec:
- setting_cmd = CountDownTimerSecDown;
- break;
- case CountDownTimerSelectMinute:
- setting_cmd = CountDownTimerMinuteDown;
- break;
- case CountDownTimerSelectHour:
- setting_cmd = CountDownTimerHourDown;
- break;
- }
- handle_time_setting_updown(cdv, setting_cmd);
- break;
- case InputKeyRight:
- selection--;
- selection = selection % 3;
- break;
- case InputKeyLeft:
- selection++;
- selection = selection % 3;
- break;
- default:
- break;
- }
- // save selection to model context
- with_view_model(
- cdv->view, CountDownModel * model, { model->select = selection; }, false);
- }
- static void draw_selection(Canvas* canvas, CountDownViewSelect selection) {
- switch(selection) {
- case CountDownTimerSelectSec:
- elements_slightly_rounded_box(canvas, SCREEN_CENTER_X + 25, SCREEN_CENTER_Y + 11, 24, 2);
- break;
- case CountDownTimerSelectMinute:
- elements_slightly_rounded_box(canvas, SCREEN_CENTER_X - 10, SCREEN_CENTER_Y + 11, 21, 2);
- break;
- case CountDownTimerSelectHour:
- elements_slightly_rounded_box(canvas, SCREEN_CENTER_X - 47, SCREEN_CENTER_Y + 11, 24, 2);
- break;
- }
- }
- static void countdown_timer_start_counting(CountDownTimView* cdv) {
- furi_timer_start(cdv->timer, furi_kernel_get_tick_frequency() * 1); // 1s
- }
- static void countdown_timer_pause_counting(CountDownTimView* cdv) {
- furi_timer_stop(cdv->timer);
- notification_off();
- }
|