| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- #include "gui/view.h"
- #include "furi/memmgr.h"
- #include "view_composed.h"
- #include "view_i.h"
- typedef struct {
- View* bottom;
- View* top;
- bool top_enabled;
- } ViewComposedModel;
- struct ViewComposed {
- View* view;
- };
- static void view_composed_draw(Canvas* canvas, void* model);
- static bool view_composed_input(InputEvent* event, void* context);
- static void view_composed_update_callback(View* view_top_or_bottom, void* context) {
- furi_assert(view_top_or_bottom);
- furi_assert(context);
- View* view_composed_view = context;
- view_composed_view->update_callback(
- view_composed_view, view_composed_view->update_callback_context);
- }
- static void view_composed_enter(void* context) {
- furi_assert(context);
- ViewComposed* view_composed = context;
- ViewComposedModel* model = view_get_model(view_composed->view);
- /* if more than 1 composed views hold same view it has to reassign update_callback_context */
- if(model->bottom) {
- view_set_update_callback_context(model->bottom, view_composed->view);
- if(model->bottom->enter_callback) {
- model->bottom->enter_callback(model->bottom->context);
- }
- }
- if(model->top) {
- view_set_update_callback_context(model->top, view_composed->view);
- if(model->top->enter_callback) {
- model->top->enter_callback(model->top->context);
- }
- }
- view_commit_model(view_composed->view, false);
- }
- static void view_composed_exit(void* context) {
- furi_assert(context);
- ViewComposed* view_composed = context;
- ViewComposedModel* model = view_get_model(view_composed->view);
- if(model->bottom) {
- if(model->bottom->exit_callback) {
- model->bottom->exit_callback(model->bottom->context);
- }
- }
- if(model->top) {
- if(model->top->exit_callback) {
- model->top->exit_callback(model->top->context);
- }
- }
- view_commit_model(view_composed->view, false);
- }
- ViewComposed* view_composed_alloc(void) {
- ViewComposed* view_composed = furi_alloc(sizeof(ViewComposed));
- view_composed->view = view_alloc();
- view_allocate_model(view_composed->view, ViewModelTypeLocking, sizeof(ViewComposedModel));
- view_set_draw_callback(view_composed->view, view_composed_draw);
- view_set_input_callback(view_composed->view, view_composed_input);
- view_set_context(view_composed->view, view_composed);
- view_set_enter_callback(view_composed->view, view_composed_enter);
- view_set_exit_callback(view_composed->view, view_composed_exit);
- return view_composed;
- }
- void view_composed_free(ViewComposed* view_composed) {
- furi_assert(view_composed);
- ViewComposedModel* view_composed_model = view_get_model(view_composed->view);
- view_set_update_callback(view_composed_model->bottom, NULL);
- view_set_update_callback_context(view_composed_model->bottom, NULL);
- view_set_update_callback(view_composed_model->top, NULL);
- view_set_update_callback_context(view_composed_model->top, NULL);
- view_commit_model(view_composed->view, true);
- view_free(view_composed->view);
- free(view_composed);
- }
- static void view_composed_draw(Canvas* canvas, void* model) {
- furi_assert(model);
- ViewComposedModel* view_composed_model = model;
- view_draw(view_composed_model->bottom, canvas);
- if(view_composed_model->top_enabled && view_composed_model->top) {
- view_draw(view_composed_model->top, canvas);
- }
- }
- static bool view_composed_input(InputEvent* event, void* context) {
- furi_assert(event);
- furi_assert(context);
- ViewComposed* view_composed = context;
- ViewComposedModel* view_composed_model = view_get_model(view_composed->view);
- bool consumed = false;
- if(view_composed_model->top_enabled && view_composed_model->top) {
- consumed = view_input(view_composed_model->top, event);
- }
- if(!consumed) {
- consumed = view_input(view_composed_model->bottom, event);
- }
- view_commit_model(view_composed->view, false);
- return consumed;
- }
- void view_composed_top_enable(ViewComposed* view_composed, bool enable) {
- furi_assert(view_composed);
- ViewComposedModel* view_composed_model = view_get_model(view_composed->view);
- bool update = (view_composed_model->top_enabled != enable);
- view_composed_model->top_enabled = enable;
- view_commit_model(view_composed->view, update);
- }
- void view_composed_tie_views(ViewComposed* view_composed, View* view_bottom, View* view_top) {
- furi_assert(view_composed);
- furi_assert(view_bottom);
- ViewComposedModel* view_composed_model = view_get_model(view_composed->view);
- if(view_composed_model->bottom) {
- view_set_update_callback(view_composed_model->bottom, NULL);
- view_set_update_callback_context(view_composed_model->bottom, NULL);
- }
- if(view_composed_model->top) {
- view_set_update_callback(view_composed_model->top, NULL);
- view_set_update_callback_context(view_composed_model->top, NULL);
- }
- view_composed_model->bottom = view_bottom;
- view_set_update_callback(view_bottom, view_composed_update_callback);
- view_set_update_callback_context(view_bottom, view_composed->view);
- view_composed_model->top = view_top;
- view_set_update_callback(view_top, view_composed_update_callback);
- view_set_update_callback_context(view_top, view_composed->view);
- view_commit_model(view_composed->view, true);
- }
- View* view_composed_get_view(ViewComposed* view_composed) {
- furi_assert(view_composed);
- return view_composed->view;
- }
|