| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- #include "countdown_view.h"
- #include "../utils/utils.h"
- // internal
- static void handle_cmd(CountDownTimView* hw, CountDownViewCmd cmd);
- static void handle_time_setting_updown(CountDownTimView* hwv, CountDownViewCmd cmd);
- static void handle_time_setting_select(InputKey key, CountDownTimView* hwv);
- static void draw_selection(Canvas* canvas, CountDownViewSelect selection);
- // 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* helloworld_view_new() {
- CountDownTimView* hwv = (CountDownTimView*)(malloc(sizeof(CountDownTimView)));
- hwv->view = view_alloc();
- hwv->timer = furi_timer_alloc(timer_cb, FuriTimerTypePeriodic, hwv);
- hwv->counting = false;
- view_set_context(hwv->view, hwv);
- view_allocate_model(hwv->view, ViewModelTypeLocking, sizeof(CountDownModel));
- view_set_draw_callback(hwv->view, countdown_timer_view_on_draw);
- view_set_input_callback(hwv->view, countdown_timer_view_on_input);
- view_set_enter_callback(hwv->view, countdown_timer_view_on_enter);
- return hwv;
- }
- void countdown_timer_view_delete(CountDownTimView* hwv) {
- furi_assert(hwv);
- view_free(hwv->view);
- furi_timer_stop(hwv->timer);
- furi_timer_free(hwv->timer);
- free(hwv);
- }
- View* countdown_timer_view_get_view(CountDownTimView* hwv) {
- return hwv->view;
- }
- void countdown_timer_view_state_reset(CountDownTimView* hwv) {
- hwv->counting = false;
- with_view_model(
- hwv->view, CountDownModel * model, { model->sec_expected = 10; }, true);
- }
- void countdown_timer_state_toggle(CountDownTimView* hwv) {
- bool on = hwv->counting;
- if(!on) {
- furi_timer_start(hwv->timer, furi_kernel_get_tick_frequency() * 1); // 1s
- } else {
- furi_timer_stop(hwv->timer);
- notification_off();
- }
- hwv->counting = !on;
- }
- // on enter callback, CountDownTimView as ctx
- static void countdown_timer_view_on_enter(void* ctx) {
- furi_assert(ctx);
- CountDownTimView* hwv = (CountDownTimView*)ctx;
- countdown_timer_view_state_reset(hwv);
- }
- // 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 sec = model->sec_expected;
- CountDownViewSelect select = model->select;
- elements_frame(canvas, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
- canvas_set_font(canvas, FontBigNumbers);
- draw_selection(canvas, select);
- snprintf(
- buffer,
- sizeof(buffer),
- "%02ld:%02ld:%02ld",
- (sec % (60 * 60 * 24)) / (60 * 60), // hour
- (sec % (60 * 60)) / 60, // minute
- sec % 60); // second
- canvas_draw_str_aligned(
- canvas, SCREEN_CENTER_X, SCREEN_CENTER_Y, AlignCenter, AlignCenter, buffer);
- }
- // 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_cmd(hw, CountDownTimerToggleCounting);
- }
- break;
- default:
- break;
- }
- return true;
- }
- if(event->type == InputTypeLong) {
- switch(event->key) {
- case InputKeyOk:
- handle_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* hwv = (CountDownTimView*)ctx;
- int32_t sec;
- bool timeup = false;
- // decrement counter
- with_view_model(
- hwv->view,
- CountDownModel * model,
- {
- sec = model->sec_expected;
- sec--;
- // check timeup
- if(sec <= 0) {
- sec = 0;
- timeup = true;
- }
- model->sec_expected = sec;
- },
- true);
- if(timeup) {
- handle_cmd(hwv, CountDownTimerTimeUp);
- }
- }
- static void handle_time_setting_updown(CountDownTimView* hwv, CountDownViewCmd cmd) {
- int32_t sec_expected;
- with_view_model(
- hwv->view,
- CountDownModel * model,
- {
- sec_expected = model->sec_expected;
- switch(cmd) {
- case CountDownTimerMinuteUp:
- sec_expected += 60;
- break;
- case CountDownTimerMinuteDown:
- sec_expected -= 60;
- break;
- case CountDownTimerHourDown:
- sec_expected -= 3600;
- break;
- case CountDownTimerHourUp:
- sec_expected += 3600;
- break;
- case CountDownTimerSecUp:
- sec_expected++;
- break;
- case CountDownTimerSecDown:
- sec_expected--;
- break;
- default:
- break;
- }
- if(sec_expected < 0) {
- sec_expected = 0;
- }
- model->sec_expected = sec_expected;
- },
- true);
- }
- static void handle_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* hwv) {
- bool counting = hwv->counting;
- CountDownViewCmd setting_cmd = CountDownTimerSecUp;
- CountDownViewSelect selection;
- if(counting) {
- return;
- }
- // load current selection from model context
- with_view_model(
- hwv->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(hwv, 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(hwv, 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(
- hwv->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, 21, 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, 21, 2);
- break;
- }
- }
|