ViewDispatcher example

This commit is contained in:
Derek Jamison 2023-06-04 16:25:43 -05:00
parent 808e0772c2
commit 0672ab0b77
4 changed files with 171 additions and 0 deletions

View File

@ -0,0 +1,8 @@
# viewdispatcher demo
This is a UI demo of the ViewDispatcher class. It is based off the wiki code for the [ViewDispatcher] (https://github.com/jamisonderek/flipper-zero-tutorials/wiki/User-Interface#viewdispatcher) section of the User-Interface page.
The two [View](https://github.com/jamisonderek/flipper-zero-tutorials/wiki/User-Interface#view) objects registers draw and input callbacks and set different screen orientations.
The draw callback does some basic text drawing on a [Canvas](https://github.com/jamisonderek/flipper-zero-tutorials/wiki/User-Interface#canvas).
The input callback changes the X and Y position of a cursor "^" based on the key that is pressed. You can see that when the ViewPort orientation is rotated, both the screen and the keypress is translated automatically. Pressing the back button uses a [Message Queue](https://github.com/jamisonderek/flipper-zero-tutorials/wiki/Message-Queue) to signal that application should exit. Pressing OK button switches the [View](https://github.com/jamisonderek/flipper-zero-tutorials/wiki/User-Interface#view).

View File

@ -0,0 +1,18 @@
App(
appid="viewdispatcher_demo",
name="ViewDispatcher demo",
apptype=FlipperAppType.EXTERNAL,
entry_point="viewdispatcher_demo_app",
cdefines=["VIEWDISPATCHER_DEMO_APP"],
requires=[
"gui",
],
stack_size=2 * 1024,
order=100,
fap_description = "ViewDispatcher demo",
fap_author = "codeallnight",
fap_weburl = "https://github.com/jamisonderek/Flipper-Zero-tutorials",
fap_category="UI",
fap_icon="icon.png",
fap_libs=["assets"],
)

View File

@ -0,0 +1,145 @@
/*
This is an example of using a ViewDispatcher. It is a simple Hello World program that
allows you to move a cursor around the screen with the arrow keys. Pressing the OK button
will switch between two Views (the views share the same callback functions), just have
different screen orientations. Pressing the the back button will exit the program.
The code is from the Message Queue wiki page
(https://github.com/jamisonderek/flipper-zero-tutorials/wiki/Message-Queue) and
also the ViewDispatcher section of the User Interface wiki page
(https://github.com/jamisonderek/flipper-zero-tutorials/wiki/User-Interface#viewdispatcher).
*/
#include <furi.h>
#include <gui/gui.h>
#include <gui/view_dispatcher.h>
#include <gui/view.h>
typedef enum {
MyEventTypeKey,
MyEventTypeDone,
} MyEventType;
typedef struct {
MyEventType type; // The reason for this event.
InputEvent input; // This data is specific to keypress data.
} MyEvent;
typedef enum {
MyViewId,
MyOtherViewId,
} ViewId;
FuriMessageQueue* queue;
int x = 32;
int y = 48;
ViewId current_view;
static void my_draw_callback(Canvas* canvas, void* context) {
UNUSED(context);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str(canvas, 5, 30, "Hello world");
canvas_draw_str_aligned(canvas, x, y, AlignLeft, AlignTop, "^");
}
static bool my_input_callback(InputEvent* input_event, void* context) {
furi_assert(context);
bool handled = false;
// we set our callback context to be the view_dispatcher.
ViewDispatcher* view_dispatcher = context;
if(input_event->type == InputTypeShort) {
if(input_event->key == InputKeyBack) {
// Default back handler.
handled = false;
} else if(input_event->key == InputKeyLeft) {
x--;
handled = true;
} else if(input_event->key == InputKeyRight) {
x++;
handled = true;
} else if(input_event->key == InputKeyUp) {
y--;
handled = true;
} else if(input_event->key == InputKeyDown) {
y++;
handled = true;
} else if(input_event->key == InputKeyOk) {
// switch the view!
view_dispatcher_send_custom_event(view_dispatcher, 42);
handled = true;
}
}
return handled;
}
bool view_dispatcher_navigation_event_callback(void* context) {
UNUSED(context);
// We did not handle the event, so return false.
return false;
}
bool my_view_dispatcher_custom_event_callback(void* context, uint32_t event) {
furi_assert(context);
bool handled = false;
// we set our callback context to be the view_dispatcher.
ViewDispatcher* view_dispatcher = context;
if(event == 42) {
if(current_view == MyViewId) {
current_view = MyOtherViewId;
} else {
current_view = MyViewId;
}
view_dispatcher_switch_to_view(view_dispatcher, current_view);
handled = true;
}
// NOTE: The return value is not currently used by the ViewDispatcher.
return handled;
}
int32_t viewdispatcher_demo_app() {
ViewDispatcher* view_dispatcher = view_dispatcher_alloc();
// For this demo, we just use view_dispatcher as our application context.
void* my_context = view_dispatcher;
View* view1 = view_alloc();
view_set_context(view1, my_context);
view_set_draw_callback(view1, my_draw_callback);
view_set_input_callback(view1, my_input_callback);
view_set_orientation(view1, ViewOrientationHorizontal);
View* view2 = view_alloc();
view_set_context(view2, my_context);
view_set_draw_callback(view2, my_draw_callback);
view_set_input_callback(view2, my_input_callback);
view_set_orientation(view2, ViewOrientationVertical);
// set param 1 of custom event callback (impacts tick and navigation too).
view_dispatcher_set_event_callback_context(view_dispatcher, my_context);
view_dispatcher_set_navigation_event_callback(
view_dispatcher, view_dispatcher_navigation_event_callback);
view_dispatcher_set_custom_event_callback(
view_dispatcher, my_view_dispatcher_custom_event_callback);
view_dispatcher_enable_queue(view_dispatcher);
view_dispatcher_add_view(view_dispatcher, MyViewId, view1);
view_dispatcher_add_view(view_dispatcher, MyOtherViewId, view2);
Gui* gui = furi_record_open(RECORD_GUI);
view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
current_view = MyViewId;
view_dispatcher_switch_to_view(view_dispatcher, current_view);
view_dispatcher_run(view_dispatcher);
view_dispatcher_remove_view(view_dispatcher, MyViewId);
view_dispatcher_remove_view(view_dispatcher, MyOtherViewId);
furi_record_close(RECORD_GUI);
view_dispatcher_free(view_dispatcher);
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB