diff --git a/applications/gui/view_dispatcher.c b/applications/gui/view_dispatcher.c old mode 100644 new mode 100755 index d9a1acec..d5b80515 --- a/applications/gui/view_dispatcher.c +++ b/applications/gui/view_dispatcher.c @@ -51,6 +51,8 @@ void view_dispatcher_run(ViewDispatcher* view_dispatcher) { break; } else if(message.type == ViewDispatcherMessageTypeInput) { view_dispatcher_handle_input(view_dispatcher, &message.input); + } else if(message.type == ViewDispatcherMessageTypeCustomEvent) { + view_dispatcher_handle_custom_event(view_dispatcher, message.custom_event); } } } @@ -179,6 +181,34 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e } } +void view_dispatcher_set_custom_callback( + ViewDispatcher* view_dispatcher, + CustomEventCallback callback, + void* context) { + furi_assert(view_dispatcher); + furi_assert(callback); + + view_dispatcher->custom_event_cb = callback; + view_dispatcher->custom_event_ctx = context; +} + +void view_dispatcher_handle_custom_event(ViewDispatcher* view_dispatcher, uint32_t event) { + if(view_dispatcher->custom_event_cb) { + view_dispatcher->custom_event_cb(event, view_dispatcher->custom_event_ctx); + } +} + +void view_dispatcher_send_custom_event(ViewDispatcher* view_dispatcher, uint32_t event) { + furi_assert(view_dispatcher); + furi_assert(view_dispatcher->queue); + + ViewDispatcherMessage message; + message.type = ViewDispatcherMessageTypeCustomEvent; + message.custom_event = event; + + furi_check(osMessageQueuePut(view_dispatcher->queue, &message, 0, osWaitForever) == osOK); +} + void view_dispatcher_set_current_view(ViewDispatcher* view_dispatcher, View* view) { furi_assert(view_dispatcher); // Dispatch view exit event diff --git a/applications/gui/view_dispatcher.h b/applications/gui/view_dispatcher.h old mode 100644 new mode 100755 index 0096b7bf..252a0ec4 --- a/applications/gui/view_dispatcher.h +++ b/applications/gui/view_dispatcher.h @@ -7,6 +7,10 @@ extern "C" { #endif +/** Prototype for custom event callback + */ +typedef void (*CustomEventCallback)(uint32_t custom_event, void* context); + /** ViewDispatcher view_port placement */ typedef enum { @@ -28,11 +32,23 @@ ViewDispatcher* view_dispatcher_alloc(); void view_dispatcher_free(ViewDispatcher* view_dispatcher); /** Enable queue support - * If queue enabled all input events will be dispatched throw internal queue + * If queue enabled all input and custom events will be dispatched throw internal queue * @param view_dispatcher ViewDispatcher instance */ void view_dispatcher_enable_queue(ViewDispatcher* view_dispatcher); +/** Set custom event callback + * Custom callback is called when custom event in internal queue received + */ +void view_dispatcher_set_custom_callback( + ViewDispatcher* view_dispatcher, + CustomEventCallback callback, + void* context); + +/** Send custom event + */ +void view_dispatcher_send_custom_event(ViewDispatcher* view_dispatcher, uint32_t event); + /** Run ViewDispatcher * Use only after queue enabled * @param view_dispatcher ViewDispatcher instance diff --git a/applications/gui/view_dispatcher_i.h b/applications/gui/view_dispatcher_i.h index 20c6acf9..ac026791 100644 --- a/applications/gui/view_dispatcher_i.h +++ b/applications/gui/view_dispatcher_i.h @@ -15,10 +15,13 @@ struct ViewDispatcher { ViewPort* view_port; ViewDict_t views; View* current_view; + CustomEventCallback custom_event_cb; + void* custom_event_ctx; }; typedef enum { ViewDispatcherMessageTypeInput, + ViewDispatcherMessageTypeCustomEvent, ViewDispatcherMessageTypeStop, } ViewDispatcherMessageType; @@ -26,6 +29,7 @@ typedef struct { ViewDispatcherMessageType type; union { InputEvent input; + uint32_t custom_event; }; } ViewDispatcherMessage; @@ -38,6 +42,9 @@ void view_dispatcher_input_callback(InputEvent* event, void* context); /* Input handler */ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* event); +/* Custom event handler */ +void view_dispatcher_handle_custom_event(ViewDispatcher* view_dispatcher, uint32_t event); + /* Set current view, dispatches view enter and exit */ void view_dispatcher_set_current_view(ViewDispatcher* view_dispatcher, View* view);