[FL-1286] Add vertical screen orientation (#472)

This commit is contained in:
Albert Kharisov
2021-05-19 12:43:15 +03:00
committed by GitHub
parent f5f9a04fda
commit 4fa49882e0
16 changed files with 248 additions and 4 deletions

View File

@@ -12,6 +12,7 @@ Canvas* canvas_init() {
api_hal_power_insomnia_enter();
canvas->orientation = CanvasOrientationHorizontal;
u8g2_Setup_st7565_erc12864_alt_f(
&canvas->fb, U8G2_R0, u8x8_hw_spi_stm32, u8g2_gpio_and_delay_stm32);
@@ -254,3 +255,20 @@ void canvas_draw_glyph(Canvas* canvas, uint8_t x, uint8_t y, uint16_t ch) {
void canvas_set_bitmap_mode(Canvas* canvas, bool alpha) {
u8g2_SetBitmapMode(&canvas->fb, alpha ? 1 : 0);
}
void canvas_set_orientation(Canvas* canvas, CanvasOrientation orientation) {
furi_assert(canvas);
if(canvas->orientation != orientation) {
canvas->orientation = orientation;
if(canvas->orientation == CanvasOrientationHorizontal)
u8g2_SetDisplayRotation(&canvas->fb, U8G2_R0);
else if(canvas->orientation == CanvasOrientationVertical)
u8g2_SetDisplayRotation(&canvas->fb, U8G2_R3);
else
furi_assert(0);
}
}
CanvasOrientation canvas_get_orientation(const Canvas* canvas) {
return canvas->orientation;
}

View File

@@ -28,6 +28,11 @@ typedef enum {
AlignCenter,
} Align;
typedef enum {
CanvasOrientationHorizontal,
CanvasOrientationVertical,
} CanvasOrientation;
typedef struct Canvas Canvas;
/*

View File

@@ -5,6 +5,7 @@
struct Canvas {
u8g2_t fb;
CanvasOrientation orientation;
uint8_t offset_x;
uint8_t offset_y;
uint8_t width;
@@ -52,3 +53,13 @@ void canvas_frame_set(
uint8_t offset_y,
uint8_t width,
uint8_t height);
/*
* Set canvas orientation
*/
void canvas_set_orientation(Canvas* canvas, CanvasOrientation orientation);
/*
* Get canvas orientation
*/
CanvasOrientation canvas_get_orientation(const Canvas* canvas);

View File

@@ -1,5 +1,40 @@
#include "gui_i.h"
static void gui_rotate_buttons(InputEvent* event) {
switch(event->key) {
case InputKeyUp:
event->key = InputKeyRight;
break;
case InputKeyDown:
event->key = InputKeyLeft;
break;
case InputKeyRight:
event->key = InputKeyDown;
break;
case InputKeyLeft:
event->key = InputKeyUp;
break;
default:
break;
}
}
static void gui_setup_fs_orientation(const ViewPort* view_port, Canvas* canvas) {
ViewPortOrientation view_port_orientation = view_port_get_orientation(view_port);
CanvasOrientation canvas_orientation = canvas_get_orientation(canvas);
if(view_port_orientation == ViewPortOrientationHorizontal) {
canvas_frame_set(canvas, 0, 0, GUI_DISPLAY_WIDTH, GUI_DISPLAY_HEIGHT);
if(canvas_orientation != CanvasOrientationHorizontal) {
canvas_set_orientation(canvas, CanvasOrientationHorizontal);
}
} else if(view_port_orientation == ViewPortOrientationVertical) {
canvas_frame_set(canvas, 0, 0, GUI_DISPLAY_HEIGHT, GUI_DISPLAY_WIDTH);
if(canvas_orientation != CanvasOrientationVertical) {
canvas_set_orientation(canvas, CanvasOrientationVertical);
}
}
}
ViewPort* gui_view_port_find_enabled(ViewPortArray_t array) {
// Iterating backward
ViewPortArray_it_t it;
@@ -29,10 +64,11 @@ void gui_input_events_callback(const void* value, void* ctx) {
osThreadFlagsSet(gui->thread, GUI_THREAD_FLAG_INPUT);
}
// Only Fullscreen supports vertical display for now
bool gui_redraw_fs(Gui* gui) {
canvas_frame_set(gui->canvas, 0, 0, GUI_DISPLAY_WIDTH, GUI_DISPLAY_HEIGHT);
ViewPort* view_port = gui_view_port_find_enabled(gui->layers[GuiLayerFullscreen]);
if(view_port) {
gui_setup_fs_orientation(view_port, gui->canvas);
view_port_draw(view_port, gui->canvas);
return true;
} else {
@@ -46,6 +82,7 @@ void gui_redraw_status_bar(Gui* gui) {
uint8_t x_used = 0;
uint8_t width;
ViewPort* view_port;
canvas_set_orientation(gui->canvas, CanvasOrientationHorizontal);
canvas_frame_set(
gui->canvas, GUI_STATUS_BAR_X, GUI_STATUS_BAR_Y, GUI_DISPLAY_WIDTH, GUI_STATUS_BAR_HEIGHT);
canvas_draw_icon_name(gui->canvas, 0, 0, I_Background_128x11);
@@ -130,6 +167,7 @@ void gui_redraw_status_bar(Gui* gui) {
}
bool gui_redraw_normal(Gui* gui) {
canvas_set_orientation(gui->canvas, CanvasOrientationHorizontal);
canvas_frame_set(gui->canvas, GUI_MAIN_X, GUI_MAIN_Y, GUI_MAIN_WIDTH, GUI_MAIN_HEIGHT);
ViewPort* view_port = gui_view_port_find_enabled(gui->layers[GuiLayerMain]);
if(view_port) {
@@ -140,6 +178,7 @@ bool gui_redraw_normal(Gui* gui) {
}
bool gui_redraw_none(Gui* gui) {
canvas_set_orientation(gui->canvas, CanvasOrientationHorizontal);
canvas_frame_set(gui->canvas, GUI_MAIN_X, GUI_MAIN_Y, GUI_MAIN_WIDTH, GUI_MAIN_HEIGHT);
ViewPort* view_port = gui_view_port_find_enabled(gui->layers[GuiLayerNone]);
if(view_port) {
@@ -186,6 +225,10 @@ void gui_input(Gui* gui, InputEvent* input_event) {
if(!view_port) view_port = gui_view_port_find_enabled(gui->layers[GuiLayerNone]);
if(view_port) {
if(view_port_get_orientation(view_port) == ViewPortOrientationVertical) {
gui_rotate_buttons(input_event);
}
view_port_input(view_port, input_event);
}
@@ -228,6 +271,9 @@ void gui_add_view_port(Gui* gui, ViewPort* view_port, GuiLayer layer) {
furi_assert(gui);
furi_assert(view_port);
furi_check(layer < GuiLayerMAX);
// Only fullscreen supports Vertical orientation for now
furi_assert(
(layer == GuiLayerFullscreen) || (view_port->orientation != ViewPortOrientationVertical));
gui_lock(gui);
// Verify that view port is not yet added

View File

@@ -217,4 +217,4 @@ void submenu_process_ok(Submenu* submenu) {
if(item && item->callback) {
item->callback(item->callback_context, item->index);
}
}
}

View File

@@ -46,6 +46,8 @@ SubmenuItem* submenu_add_item(
*/
void submenu_clean(Submenu* submenu);
Submenu* submenu_vertical_alloc();
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -2,6 +2,7 @@
View* view_alloc() {
View* view = furi_alloc(sizeof(View));
view->orientation = ViewOrientationHorizontal;
return view;
}
@@ -59,6 +60,11 @@ void view_set_context(View* view, void* context) {
view->context = context;
}
void view_set_orientation(View* view, ViewOrientation orientation) {
furi_assert(view);
view->orientation = orientation;
}
void view_allocate_model(View* view, ViewModelType type, size_t size) {
furi_assert(view);
furi_assert(size > 0);

View File

@@ -20,6 +20,11 @@ extern "C" {
*/
#define VIEW_DESTROY 0xFFFFFFFA
typedef enum {
ViewOrientationHorizontal,
ViewOrientationVertical,
} ViewOrientation;
/* View, anonymous type */
typedef struct View View;
@@ -137,6 +142,12 @@ void view_set_update_callback_context(View* view, void* context);
*/
void view_set_context(View* view, void* context);
/* Set View Orientation
* @param view, pointer to View
* @param orientation, either vertical or horizontal
*/
void view_set_orientation(View* view, ViewOrientation orientation);
/* Allocate view model.
* @param view, pointer to View
* @param type, View Model Type
@@ -186,4 +197,4 @@ void view_commit_model(View* view, bool update);
bool update = ({ bool __fn__ function_body __fn__; })(p); \
view_commit_model(view, update); \
}
#endif
#endif

View File

@@ -151,6 +151,10 @@ void view_dispatcher_set_current_view(ViewDispatcher* view_dispatcher, View* vie
view_dispatcher->current_view = view;
// Dispatch view enter event
if(view_dispatcher->current_view) {
if(view->orientation == ViewOrientationVertical)
view_port_set_orientation(view_dispatcher->view_port, ViewPortOrientationVertical);
else if(view->orientation == ViewOrientationHorizontal)
view_port_set_orientation(view_dispatcher->view_port, ViewPortOrientationHorizontal);
view_enter(view_dispatcher->current_view);
view_port_enabled_set(view_dispatcher->view_port, true);
view_port_update(view_dispatcher->view_port);

View File

@@ -17,6 +17,7 @@ struct View {
ViewNavigationCallback next_callback;
ViewCallback enter_callback;
ViewCallback exit_callback;
ViewOrientation orientation;
ViewUpdateCallback update_callback;
void* update_callback_context;

View File

@@ -9,6 +9,7 @@
ViewPort* view_port_alloc(ViewPortDrawCallback callback, void* callback_context) {
ViewPort* view_port = furi_alloc(sizeof(ViewPort));
view_port->orientation = ViewPortOrientationHorizontal;
view_port->is_enabled = true;
return view_port;
}
@@ -96,3 +97,12 @@ void view_port_input(ViewPort* view_port, InputEvent* event) {
view_port->input_callback(event, view_port->input_callback_context);
}
}
void view_port_set_orientation(ViewPort* view_port, ViewPortOrientation orientation) {
furi_assert(view_port);
view_port->orientation = orientation;
}
ViewPortOrientation view_port_get_orientation(const ViewPort* view_port) {
return view_port->orientation;
}

View File

@@ -9,6 +9,11 @@ extern "C" {
typedef struct ViewPort ViewPort;
typedef enum {
ViewPortOrientationHorizontal,
ViewPortOrientationVertical,
} ViewPortOrientation;
/*
* ViewPort Draw callback
* @warning called from GUI thread
@@ -75,6 +80,13 @@ void view_port_input_callback_set(
*/
void view_port_update(ViewPort* view_port);
/*
* Set ViewPort orientation.
* @param orientation, display orientation, horizontal or vertical.
*/
void view_port_set_orientation(ViewPort* view_port, ViewPortOrientation orientation);
ViewPortOrientation view_port_get_orientation(const ViewPort* view_port);
#ifdef __cplusplus
}
#endif

View File

@@ -6,6 +6,7 @@
struct ViewPort {
Gui* gui;
bool is_enabled;
ViewPortOrientation orientation;
uint8_t width;
uint8_t height;