Przeglądaj źródła

view_dispatcher: add custom events (#526)

Co-authored-by: あく <alleteam@gmail.com>
gornekich 4 lat temu
rodzic
commit
8605f53c28

+ 30 - 0
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

+ 17 - 1
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

+ 7 - 0
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);