From 2187dc71171431ec430aaf9edb69b81429cd810e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Thu, 4 Feb 2021 15:05:46 +0300 Subject: [PATCH] GUI: view enter, exit callbacks. (#326) --- applications/gui/view.c | 20 ++++++++++++++++++++ applications/gui/view.h | 18 ++++++++++++++++++ applications/gui/view_dispatcher.c | 25 ++++++++++++++++++++----- applications/gui/view_dispatcher_i.h | 3 +++ applications/gui/view_i.h | 8 ++++++++ applications/gui/view_port.h | 4 +++- 6 files changed, 72 insertions(+), 6 deletions(-) diff --git a/applications/gui/view.c b/applications/gui/view.c index 7aaffe76..93038368 100644 --- a/applications/gui/view.c +++ b/applications/gui/view.c @@ -40,6 +40,16 @@ void view_set_next_callback(View* view, ViewNavigationCallback callback) { view->next_callback = callback; } +void view_set_enter_callback(View* view, ViewCallback callback) { + furi_assert(view); + view->enter_callback = callback; +} + +void view_set_exit_callback(View* view, ViewCallback callback) { + furi_assert(view); + view->exit_callback = callback; +} + void view_set_context(View* view, void* context) { furi_assert(view); furi_assert(context); @@ -143,3 +153,13 @@ uint32_t view_next(View* view) { return VIEW_IGNORE; } } + +void view_enter(View* view) { + furi_assert(view); + if(view->enter_callback) view->enter_callback(view->context); +} + +void view_exit(View* view) { + furi_assert(view); + if(view->exit_callback) view->exit_callback(view->context); +} diff --git a/applications/gui/view.h b/applications/gui/view.h index 8563b067..2b2950da 100644 --- a/applications/gui/view.h +++ b/applications/gui/view.h @@ -42,6 +42,12 @@ typedef bool (*ViewInputCallback)(InputEvent* event, void* context); */ typedef uint32_t (*ViewNavigationCallback)(void* context); +/* View callback + * @param context, pointer to context + * @warning called from GUI thread + */ +typedef void (*ViewCallback)(void* context); + /* View model types */ typedef enum { /* Model is not allocated */ @@ -92,6 +98,18 @@ void view_set_previous_callback(View* view, ViewNavigationCallback callback); */ void view_set_next_callback(View* view, ViewNavigationCallback callback); +/* Set Enter callback + * @param view, pointer to View + * @param callback, callback + */ +void view_set_enter_callback(View* view, ViewCallback callback); + +/* Set Exit callback + * @param view, pointer to View + * @param callback, callback + */ +void view_set_exit_callback(View* view, ViewCallback callback); + /* Set View Draw callback * @param view, pointer to View * @param context, context for callbacks diff --git a/applications/gui/view_dispatcher.c b/applications/gui/view_dispatcher.c index b8ec50d2..1ec57a4f 100644 --- a/applications/gui/view_dispatcher.c +++ b/applications/gui/view_dispatcher.c @@ -45,17 +45,14 @@ void view_dispatcher_add_view(ViewDispatcher* view_dispatcher, uint32_t view_id, void view_dispatcher_switch_to_view(ViewDispatcher* view_dispatcher, uint32_t view_id) { furi_assert(view_dispatcher); if(view_id == VIEW_NONE) { - view_dispatcher->current_view = NULL; - view_port_enabled_set(view_dispatcher->view_port, false); + view_dispatcher_set_current_view(view_dispatcher, NULL); } else if(view_id == VIEW_IGNORE) { } else if(view_id == VIEW_DESTROY) { view_dispatcher_free(view_dispatcher); } else { View** view_pp = ViewDict_get(view_dispatcher->views, view_id); furi_check(view_pp != NULL); - view_dispatcher->current_view = *view_pp; - view_port_enabled_set(view_dispatcher->view_port, true); - view_port_update(view_dispatcher->view_port); + view_dispatcher_set_current_view(view_dispatcher, *view_pp); } } @@ -103,6 +100,24 @@ void view_dispatcher_input_callback(InputEvent* event, void* context) { } } +void view_dispatcher_set_current_view(ViewDispatcher* view_dispatcher, View* view) { + furi_assert(view_dispatcher); + // Dispatch view exit event + if(view_dispatcher->current_view) { + view_exit(view_dispatcher->current_view); + } + // Set current view + view_dispatcher->current_view = view; + // Dispatch view enter event + if(view_dispatcher->current_view) { + view_enter(view_dispatcher->current_view); + view_port_enabled_set(view_dispatcher->view_port, true); + view_port_update(view_dispatcher->view_port); + } else { + view_port_enabled_set(view_dispatcher->view_port, false); + } +} + void view_dispatcher_update(ViewDispatcher* view_dispatcher, View* view) { furi_assert(view_dispatcher); furi_assert(view); diff --git a/applications/gui/view_dispatcher_i.h b/applications/gui/view_dispatcher_i.h index bc87048b..6539609d 100644 --- a/applications/gui/view_dispatcher_i.h +++ b/applications/gui/view_dispatcher_i.h @@ -20,5 +20,8 @@ void view_dispatcher_draw_callback(Canvas* canvas, void* context); /* ViewPort Input Callback */ void view_dispatcher_input_callback(InputEvent* event, void* context); +/* Set current view, dispatches view enter and exit */ +void view_dispatcher_set_current_view(ViewDispatcher* view_dispatcher, View* view); + /* View to ViewDispatcher update event */ void view_dispatcher_update(ViewDispatcher* view_dispatcher, View* view); diff --git a/applications/gui/view_i.h b/applications/gui/view_i.h index 572f37f6..b4c4c7c9 100644 --- a/applications/gui/view_i.h +++ b/applications/gui/view_i.h @@ -16,6 +16,8 @@ struct View { ViewModelType model_type; ViewNavigationCallback previous_callback; ViewNavigationCallback next_callback; + ViewCallback enter_callback; + ViewCallback exit_callback; void* model; void* context; }; @@ -37,3 +39,9 @@ uint32_t view_previous(View* view); /* Next Callback for View dispatcher */ uint32_t view_next(View* view); + +/* Enter Callback for View dispatcher */ +void view_enter(View* view); + +/* Exit Callback for View dispatcher */ +void view_exit(View* view); diff --git a/applications/gui/view_port.h b/applications/gui/view_port.h index 37e855ce..2cb2ad52 100644 --- a/applications/gui/view_port.h +++ b/applications/gui/view_port.h @@ -51,7 +51,9 @@ uint8_t view_port_get_height(ViewPort* view_port); /* * Enable or disable view_port rendering. - * @param enabled. + * @param view_port - ViewPort instance + * @param enabled + * @warning automatically dispatches update event */ void view_port_enabled_set(ViewPort* view_port, bool enabled); bool view_port_is_enabled(ViewPort* view_port);