[FL-1286] Add vertical screen orientation (#472)
This commit is contained in:
		@@ -1,6 +1,7 @@
 | 
				
			|||||||
#include "applications.h"
 | 
					#include "applications.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Services and apps decalartion
 | 
					// Services and apps decalartion
 | 
				
			||||||
 | 
					int32_t application_vertical_screen(void* p);
 | 
				
			||||||
int32_t irda_monitor_app(void* p);
 | 
					int32_t irda_monitor_app(void* p);
 | 
				
			||||||
int32_t flipper_test_app(void* p);
 | 
					int32_t flipper_test_app(void* p);
 | 
				
			||||||
int32_t application_blink(void* p);
 | 
					int32_t application_blink(void* p);
 | 
				
			||||||
@@ -266,6 +267,13 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = {
 | 
				
			|||||||
#ifdef APP_IRDA_MONITOR
 | 
					#ifdef APP_IRDA_MONITOR
 | 
				
			||||||
    {.app = irda_monitor_app, .name = "Irda Monitor", .stack_size = 1024, .icon = A_Plugins_14},
 | 
					    {.app = irda_monitor_app, .name = "Irda Monitor", .stack_size = 1024, .icon = A_Plugins_14},
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef APP_VERTICAL_SCREEN
 | 
				
			||||||
 | 
					    {.app = application_vertical_screen,
 | 
				
			||||||
 | 
					     .name = "Vertical Screen",
 | 
				
			||||||
 | 
					     .stack_size = 1024,
 | 
				
			||||||
 | 
					     .icon = A_Plugins_14},
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const size_t FLIPPER_DEBUG_APPS_COUNT = sizeof(FLIPPER_DEBUG_APPS) / sizeof(FlipperApplication);
 | 
					const size_t FLIPPER_DEBUG_APPS_COUNT = sizeof(FLIPPER_DEBUG_APPS) / sizeof(FlipperApplication);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,6 +43,7 @@ APP_EXAMPLE_UART_WRITE = 1
 | 
				
			|||||||
APP_EXAMPLE_INPUT_DUMP = 1
 | 
					APP_EXAMPLE_INPUT_DUMP = 1
 | 
				
			||||||
APP_UNIT_TESTS = 1
 | 
					APP_UNIT_TESTS = 1
 | 
				
			||||||
APP_IRDA_MONITOR = 1
 | 
					APP_IRDA_MONITOR = 1
 | 
				
			||||||
 | 
					APP_VERTICAL_SCREEN = 1
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SRV_DOLPHIN ?= 0
 | 
					SRV_DOLPHIN ?= 0
 | 
				
			||||||
@@ -76,6 +77,11 @@ SRV_GUI		= 1
 | 
				
			|||||||
CFLAGS		+= -DAPP_MENU
 | 
					CFLAGS		+= -DAPP_MENU
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					APP_VERTICAL_SCREEN	?= 0
 | 
				
			||||||
 | 
					ifeq ($(APP_VERTICAL_SCREEN), 1)
 | 
				
			||||||
 | 
					CFLAGS		+= -DAPP_VERTICAL_SCREEN
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
APP_IRDA_MONITOR	?= 0
 | 
					APP_IRDA_MONITOR	?= 0
 | 
				
			||||||
ifeq ($(APP_IRDA_MONITOR), 1)
 | 
					ifeq ($(APP_IRDA_MONITOR), 1)
 | 
				
			||||||
CFLAGS		+= -DAPP_IRDA_MONITOR
 | 
					CFLAGS		+= -DAPP_IRDA_MONITOR
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										103
									
								
								applications/examples/vertical_submenu.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								applications/examples/vertical_submenu.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
				
			|||||||
 | 
					#include <furi.h>
 | 
				
			||||||
 | 
					#include <gui/gui.h>
 | 
				
			||||||
 | 
					#include <gui/view_dispatcher.h>
 | 
				
			||||||
 | 
					#include <gui/modules/submenu.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ViewDispatcher* view_dispatcher;
 | 
				
			||||||
 | 
					static osMessageQueueId_t event_queue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    EventTypeGoAway,
 | 
				
			||||||
 | 
					    EventTypeGoToMainMenu,
 | 
				
			||||||
 | 
					    EventTypeSwitchToVertical,
 | 
				
			||||||
 | 
					    EventTypeSwitchToHorizontal,
 | 
				
			||||||
 | 
					} EventType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Nothing dangerous in settings some vars and flags inside callback
 | 
				
			||||||
 | 
					static void submenu_callback(void* context, uint32_t index) {
 | 
				
			||||||
 | 
					    EventType event = EventTypeGoAway;
 | 
				
			||||||
 | 
					    switch(index) {
 | 
				
			||||||
 | 
					    case 1:
 | 
				
			||||||
 | 
					        event = EventTypeSwitchToVertical;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case 2:
 | 
				
			||||||
 | 
					        event = EventTypeSwitchToHorizontal;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    osMessageQueuePut(event_queue, &event, 0, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t previous_exit_callback(void* context) {
 | 
				
			||||||
 | 
					    EventType event = EventTypeGoAway;
 | 
				
			||||||
 | 
					    osMessageQueuePut(event_queue, &event, 0, 0);
 | 
				
			||||||
 | 
					    return VIEW_IGNORE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t previous_callback(void* context) {
 | 
				
			||||||
 | 
					    EventType event = EventTypeGoToMainMenu;
 | 
				
			||||||
 | 
					    osMessageQueuePut(event_queue, &event, 0, 0);
 | 
				
			||||||
 | 
					    return VIEW_IGNORE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t application_vertical_screen(void* p) {
 | 
				
			||||||
 | 
					    event_queue = osMessageQueueNew(8, sizeof(EventType), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    view_dispatcher = view_dispatcher_alloc();
 | 
				
			||||||
 | 
					    Gui* gui = furi_record_open("gui");
 | 
				
			||||||
 | 
					    view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Submenu* submenu = submenu_alloc();
 | 
				
			||||||
 | 
					    View* submenu_view = submenu_get_view(submenu);
 | 
				
			||||||
 | 
					    view_set_previous_callback(submenu_view, previous_exit_callback);
 | 
				
			||||||
 | 
					    view_set_orientation(submenu_view, ViewOrientationVertical);
 | 
				
			||||||
 | 
					    submenu_add_item(submenu, "VerSubm", 1, submenu_callback, view_dispatcher);
 | 
				
			||||||
 | 
					    submenu_add_item(submenu, "HorSubm", 2, submenu_callback, view_dispatcher);
 | 
				
			||||||
 | 
					    view_dispatcher_add_view(view_dispatcher, 1, submenu_view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Submenu* submenu_vertical = submenu_alloc();
 | 
				
			||||||
 | 
					    View* submenu_vertical_view = submenu_get_view(submenu_vertical);
 | 
				
			||||||
 | 
					    view_set_previous_callback(submenu_vertical_view, previous_callback);
 | 
				
			||||||
 | 
					    view_set_orientation(submenu_vertical_view, ViewOrientationVertical);
 | 
				
			||||||
 | 
					    submenu_add_item(submenu_vertical, "Vert1", 1, NULL, view_dispatcher);
 | 
				
			||||||
 | 
					    submenu_add_item(submenu_vertical, "Vert2", 2, NULL, view_dispatcher);
 | 
				
			||||||
 | 
					    view_dispatcher_add_view(view_dispatcher, 2, submenu_vertical_view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Submenu* submenu_horizontal = submenu_alloc();
 | 
				
			||||||
 | 
					    View* submenu_horizontal_view = submenu_get_view(submenu_horizontal);
 | 
				
			||||||
 | 
					    view_set_previous_callback(submenu_horizontal_view, previous_callback);
 | 
				
			||||||
 | 
					    view_set_orientation(submenu_horizontal_view, ViewOrientationHorizontal);
 | 
				
			||||||
 | 
					    submenu_add_item(submenu_horizontal, "Horiz1", 1, NULL, view_dispatcher);
 | 
				
			||||||
 | 
					    submenu_add_item(submenu_horizontal, "Horiz2", 2, NULL, view_dispatcher);
 | 
				
			||||||
 | 
					    view_dispatcher_add_view(view_dispatcher, 3, submenu_horizontal_view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    view_dispatcher_switch_to_view(view_dispatcher, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while(1) {
 | 
				
			||||||
 | 
					        EventType event;
 | 
				
			||||||
 | 
					        furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK);
 | 
				
			||||||
 | 
					        if(event == EventTypeGoAway) {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        } else if(event == EventTypeGoToMainMenu) {
 | 
				
			||||||
 | 
					            view_dispatcher_switch_to_view(view_dispatcher, 1);
 | 
				
			||||||
 | 
					        } else if(event == EventTypeSwitchToVertical) {
 | 
				
			||||||
 | 
					            view_dispatcher_switch_to_view(view_dispatcher, 2);
 | 
				
			||||||
 | 
					        } else if(event == EventTypeSwitchToHorizontal) {
 | 
				
			||||||
 | 
					            view_dispatcher_switch_to_view(view_dispatcher, 3);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    view_dispatcher_remove_view(view_dispatcher, 1);
 | 
				
			||||||
 | 
					    view_dispatcher_remove_view(view_dispatcher, 2);
 | 
				
			||||||
 | 
					    view_dispatcher_remove_view(view_dispatcher, 3);
 | 
				
			||||||
 | 
					    submenu_free(submenu);
 | 
				
			||||||
 | 
					    submenu_free(submenu_vertical);
 | 
				
			||||||
 | 
					    submenu_free(submenu_horizontal);
 | 
				
			||||||
 | 
					    view_dispatcher_free(view_dispatcher);
 | 
				
			||||||
 | 
					    osMessageQueueDelete(event_queue);
 | 
				
			||||||
 | 
					    furi_record_close("gui");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -12,6 +12,7 @@ Canvas* canvas_init() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    api_hal_power_insomnia_enter();
 | 
					    api_hal_power_insomnia_enter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    canvas->orientation = CanvasOrientationHorizontal;
 | 
				
			||||||
    u8g2_Setup_st7565_erc12864_alt_f(
 | 
					    u8g2_Setup_st7565_erc12864_alt_f(
 | 
				
			||||||
        &canvas->fb, U8G2_R0, u8x8_hw_spi_stm32, u8g2_gpio_and_delay_stm32);
 | 
					        &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) {
 | 
					void canvas_set_bitmap_mode(Canvas* canvas, bool alpha) {
 | 
				
			||||||
    u8g2_SetBitmapMode(&canvas->fb, alpha ? 1 : 0);
 | 
					    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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,6 +28,11 @@ typedef enum {
 | 
				
			|||||||
    AlignCenter,
 | 
					    AlignCenter,
 | 
				
			||||||
} Align;
 | 
					} Align;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    CanvasOrientationHorizontal,
 | 
				
			||||||
 | 
					    CanvasOrientationVertical,
 | 
				
			||||||
 | 
					} CanvasOrientation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct Canvas Canvas;
 | 
					typedef struct Canvas Canvas;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct Canvas {
 | 
					struct Canvas {
 | 
				
			||||||
    u8g2_t fb;
 | 
					    u8g2_t fb;
 | 
				
			||||||
 | 
					    CanvasOrientation orientation;
 | 
				
			||||||
    uint8_t offset_x;
 | 
					    uint8_t offset_x;
 | 
				
			||||||
    uint8_t offset_y;
 | 
					    uint8_t offset_y;
 | 
				
			||||||
    uint8_t width;
 | 
					    uint8_t width;
 | 
				
			||||||
@@ -52,3 +53,13 @@ void canvas_frame_set(
 | 
				
			|||||||
    uint8_t offset_y,
 | 
					    uint8_t offset_y,
 | 
				
			||||||
    uint8_t width,
 | 
					    uint8_t width,
 | 
				
			||||||
    uint8_t height);
 | 
					    uint8_t height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Set canvas orientation
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void canvas_set_orientation(Canvas* canvas, CanvasOrientation orientation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Get canvas orientation
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					CanvasOrientation canvas_get_orientation(const Canvas* canvas);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,40 @@
 | 
				
			|||||||
#include "gui_i.h"
 | 
					#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) {
 | 
					ViewPort* gui_view_port_find_enabled(ViewPortArray_t array) {
 | 
				
			||||||
    // Iterating backward
 | 
					    // Iterating backward
 | 
				
			||||||
    ViewPortArray_it_t it;
 | 
					    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);
 | 
					    osThreadFlagsSet(gui->thread, GUI_THREAD_FLAG_INPUT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Only Fullscreen supports vertical display for now
 | 
				
			||||||
bool gui_redraw_fs(Gui* gui) {
 | 
					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]);
 | 
					    ViewPort* view_port = gui_view_port_find_enabled(gui->layers[GuiLayerFullscreen]);
 | 
				
			||||||
    if(view_port) {
 | 
					    if(view_port) {
 | 
				
			||||||
 | 
					        gui_setup_fs_orientation(view_port, gui->canvas);
 | 
				
			||||||
        view_port_draw(view_port, gui->canvas);
 | 
					        view_port_draw(view_port, gui->canvas);
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
@@ -46,6 +82,7 @@ void gui_redraw_status_bar(Gui* gui) {
 | 
				
			|||||||
    uint8_t x_used = 0;
 | 
					    uint8_t x_used = 0;
 | 
				
			||||||
    uint8_t width;
 | 
					    uint8_t width;
 | 
				
			||||||
    ViewPort* view_port;
 | 
					    ViewPort* view_port;
 | 
				
			||||||
 | 
					    canvas_set_orientation(gui->canvas, CanvasOrientationHorizontal);
 | 
				
			||||||
    canvas_frame_set(
 | 
					    canvas_frame_set(
 | 
				
			||||||
        gui->canvas, GUI_STATUS_BAR_X, GUI_STATUS_BAR_Y, GUI_DISPLAY_WIDTH, GUI_STATUS_BAR_HEIGHT);
 | 
					        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);
 | 
					    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) {
 | 
					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);
 | 
					    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]);
 | 
					    ViewPort* view_port = gui_view_port_find_enabled(gui->layers[GuiLayerMain]);
 | 
				
			||||||
    if(view_port) {
 | 
					    if(view_port) {
 | 
				
			||||||
@@ -140,6 +178,7 @@ bool gui_redraw_normal(Gui* gui) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool gui_redraw_none(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);
 | 
					    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]);
 | 
					    ViewPort* view_port = gui_view_port_find_enabled(gui->layers[GuiLayerNone]);
 | 
				
			||||||
    if(view_port) {
 | 
					    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) view_port = gui_view_port_find_enabled(gui->layers[GuiLayerNone]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(view_port) {
 | 
					    if(view_port) {
 | 
				
			||||||
 | 
					        if(view_port_get_orientation(view_port) == ViewPortOrientationVertical) {
 | 
				
			||||||
 | 
					            gui_rotate_buttons(input_event);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        view_port_input(view_port, 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(gui);
 | 
				
			||||||
    furi_assert(view_port);
 | 
					    furi_assert(view_port);
 | 
				
			||||||
    furi_check(layer < GuiLayerMAX);
 | 
					    furi_check(layer < GuiLayerMAX);
 | 
				
			||||||
 | 
					    // Only fullscreen supports Vertical orientation for now
 | 
				
			||||||
 | 
					    furi_assert(
 | 
				
			||||||
 | 
					        (layer == GuiLayerFullscreen) || (view_port->orientation != ViewPortOrientationVertical));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    gui_lock(gui);
 | 
					    gui_lock(gui);
 | 
				
			||||||
    // Verify that view port is not yet added
 | 
					    // Verify that view port is not yet added
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,6 +46,8 @@ SubmenuItem* submenu_add_item(
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void submenu_clean(Submenu* submenu);
 | 
					void submenu_clean(Submenu* submenu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Submenu* submenu_vertical_alloc();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -2,6 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
View* view_alloc() {
 | 
					View* view_alloc() {
 | 
				
			||||||
    View* view = furi_alloc(sizeof(View));
 | 
					    View* view = furi_alloc(sizeof(View));
 | 
				
			||||||
 | 
					    view->orientation = ViewOrientationHorizontal;
 | 
				
			||||||
    return view;
 | 
					    return view;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -59,6 +60,11 @@ void view_set_context(View* view, void* context) {
 | 
				
			|||||||
    view->context = 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) {
 | 
					void view_allocate_model(View* view, ViewModelType type, size_t size) {
 | 
				
			||||||
    furi_assert(view);
 | 
					    furi_assert(view);
 | 
				
			||||||
    furi_assert(size > 0);
 | 
					    furi_assert(size > 0);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,11 @@ extern "C" {
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
#define VIEW_DESTROY 0xFFFFFFFA
 | 
					#define VIEW_DESTROY 0xFFFFFFFA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    ViewOrientationHorizontal,
 | 
				
			||||||
 | 
					    ViewOrientationVertical,
 | 
				
			||||||
 | 
					} ViewOrientation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* View, anonymous type */
 | 
					/* View, anonymous type */
 | 
				
			||||||
typedef struct View View;
 | 
					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);
 | 
					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.
 | 
					/* Allocate view model.
 | 
				
			||||||
 * @param view, pointer to View
 | 
					 * @param view, pointer to View
 | 
				
			||||||
 * @param type, View Model Type
 | 
					 * @param type, View Model Type
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -151,6 +151,10 @@ void view_dispatcher_set_current_view(ViewDispatcher* view_dispatcher, View* vie
 | 
				
			|||||||
    view_dispatcher->current_view = view;
 | 
					    view_dispatcher->current_view = view;
 | 
				
			||||||
    // Dispatch view enter event
 | 
					    // Dispatch view enter event
 | 
				
			||||||
    if(view_dispatcher->current_view) {
 | 
					    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_enter(view_dispatcher->current_view);
 | 
				
			||||||
        view_port_enabled_set(view_dispatcher->view_port, true);
 | 
					        view_port_enabled_set(view_dispatcher->view_port, true);
 | 
				
			||||||
        view_port_update(view_dispatcher->view_port);
 | 
					        view_port_update(view_dispatcher->view_port);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,7 @@ struct View {
 | 
				
			|||||||
    ViewNavigationCallback next_callback;
 | 
					    ViewNavigationCallback next_callback;
 | 
				
			||||||
    ViewCallback enter_callback;
 | 
					    ViewCallback enter_callback;
 | 
				
			||||||
    ViewCallback exit_callback;
 | 
					    ViewCallback exit_callback;
 | 
				
			||||||
 | 
					    ViewOrientation orientation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ViewUpdateCallback update_callback;
 | 
					    ViewUpdateCallback update_callback;
 | 
				
			||||||
    void* update_callback_context;
 | 
					    void* update_callback_context;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
ViewPort* view_port_alloc(ViewPortDrawCallback callback, void* callback_context) {
 | 
					ViewPort* view_port_alloc(ViewPortDrawCallback callback, void* callback_context) {
 | 
				
			||||||
    ViewPort* view_port = furi_alloc(sizeof(ViewPort));
 | 
					    ViewPort* view_port = furi_alloc(sizeof(ViewPort));
 | 
				
			||||||
 | 
					    view_port->orientation = ViewPortOrientationHorizontal;
 | 
				
			||||||
    view_port->is_enabled = true;
 | 
					    view_port->is_enabled = true;
 | 
				
			||||||
    return view_port;
 | 
					    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);
 | 
					        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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,11 @@ extern "C" {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef struct ViewPort ViewPort;
 | 
					typedef struct ViewPort ViewPort;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    ViewPortOrientationHorizontal,
 | 
				
			||||||
 | 
					    ViewPortOrientationVertical,
 | 
				
			||||||
 | 
					} ViewPortOrientation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * ViewPort Draw callback
 | 
					 * ViewPort Draw callback
 | 
				
			||||||
 * @warning called from GUI thread
 | 
					 * @warning called from GUI thread
 | 
				
			||||||
@@ -75,6 +80,13 @@ void view_port_input_callback_set(
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void view_port_update(ViewPort* view_port);
 | 
					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
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@
 | 
				
			|||||||
struct ViewPort {
 | 
					struct ViewPort {
 | 
				
			||||||
    Gui* gui;
 | 
					    Gui* gui;
 | 
				
			||||||
    bool is_enabled;
 | 
					    bool is_enabled;
 | 
				
			||||||
 | 
					    ViewPortOrientation orientation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint8_t width;
 | 
					    uint8_t width;
 | 
				
			||||||
    uint8_t height;
 | 
					    uint8_t height;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user