| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- #include "one_shot_animation_view.h"
- #include <furi.h>
- #include <portmacro.h>
- #include <gui/canvas.h>
- #include <gui/view.h>
- #include <gui/icon_i.h>
- #include <stdint.h>
- typedef void (*OneShotInteractCallback)(void*);
- struct OneShotView {
- View* view;
- TimerHandle_t update_timer;
- OneShotInteractCallback interact_callback;
- void* interact_callback_context;
- };
- typedef struct {
- const Icon* icon;
- uint32_t index;
- bool block_input;
- } OneShotViewModel;
- static void one_shot_view_update_timer_callback(TimerHandle_t xTimer) {
- OneShotView* view = (void*)pvTimerGetTimerID(xTimer);
- OneShotViewModel* model = view_get_model(view->view);
- if((model->index + 1) < model->icon->frame_count) {
- ++model->index;
- } else {
- model->block_input = false;
- model->index = model->icon->frame_count - 2;
- }
- view_commit_model(view->view, true);
- }
- static void one_shot_view_draw(Canvas* canvas, void* model_) {
- furi_assert(canvas);
- furi_assert(model_);
- OneShotViewModel* model = model_;
- furi_check(model->index < model->icon->frame_count);
- uint8_t y_offset = canvas_height(canvas) - model->icon->height;
- canvas_draw_bitmap(
- canvas,
- 0,
- y_offset,
- model->icon->width,
- model->icon->height,
- model->icon->frames[model->index]);
- }
- static bool one_shot_view_input(InputEvent* event, void* context) {
- furi_assert(context);
- furi_assert(event);
- OneShotView* view = context;
- bool consumed = false;
- OneShotViewModel* model = view_get_model(view->view);
- consumed = model->block_input;
- view_commit_model(view->view, false);
- if(!consumed) {
- if(event->key == InputKeyRight) {
- /* Right button reserved for animation activation, so consume */
- consumed = true;
- if(event->type == InputTypeShort) {
- if(view->interact_callback) {
- view->interact_callback(view->interact_callback_context);
- }
- }
- }
- }
- return consumed;
- }
- OneShotView* one_shot_view_alloc(void) {
- OneShotView* view = malloc(sizeof(OneShotView));
- view->view = view_alloc();
- view->update_timer =
- xTimerCreate(NULL, 1000, pdTRUE, view, one_shot_view_update_timer_callback);
- view_allocate_model(view->view, ViewModelTypeLocking, sizeof(OneShotViewModel));
- view_set_context(view->view, view);
- view_set_draw_callback(view->view, one_shot_view_draw);
- view_set_input_callback(view->view, one_shot_view_input);
- return view;
- }
- void one_shot_view_free(OneShotView* view) {
- furi_assert(view);
- xTimerDelete(view->update_timer, portMAX_DELAY);
- view_free(view->view);
- view->view = NULL;
- free(view);
- }
- void one_shot_view_set_interact_callback(
- OneShotView* view,
- OneShotInteractCallback callback,
- void* context) {
- furi_assert(view);
- view->interact_callback_context = context;
- view->interact_callback = callback;
- }
- void one_shot_view_start_animation(OneShotView* view, const Icon* icon) {
- furi_assert(view);
- furi_assert(icon);
- furi_check(icon->frame_count >= 2);
- OneShotViewModel* model = view_get_model(view->view);
- model->index = 0;
- model->icon = icon;
- model->block_input = true;
- view_commit_model(view->view, true);
- xTimerChangePeriod(view->update_timer, 1000 / model->icon->frame_rate, portMAX_DELAY);
- }
- View* one_shot_view_get_view(OneShotView* view) {
- furi_assert(view);
- return view->view;
- }
|