Просмотр исходного кода

Support for setting all screen orientations (#1928)

* Support for setting all screen orientations
* Gui: add flipped orientation to view
* Gui: correct assert conditions in gui_add_view_port

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
Vasyl "vk" Kaigorodov 3 лет назад
Родитель
Сommit
ebaa84b0c2

+ 29 - 6
applications/services/gui/canvas.c

@@ -371,16 +371,39 @@ void canvas_set_bitmap_mode(Canvas* canvas, bool alpha) {
 void canvas_set_orientation(Canvas* canvas, CanvasOrientation orientation) {
 void canvas_set_orientation(Canvas* canvas, CanvasOrientation orientation) {
     furi_assert(canvas);
     furi_assert(canvas);
     if(canvas->orientation != orientation) {
     if(canvas->orientation != orientation) {
-        canvas->orientation = orientation;
-        if(canvas->orientation == CanvasOrientationHorizontal) {
-            FURI_SWAP(canvas->width, canvas->height);
+        switch(orientation) {
+        case CanvasOrientationHorizontal:
+            if(canvas->orientation == CanvasOrientationVertical ||
+               canvas->orientation == CanvasOrientationVerticalFlip) {
+                FURI_SWAP(canvas->width, canvas->height);
+            }
             u8g2_SetDisplayRotation(&canvas->fb, U8G2_R0);
             u8g2_SetDisplayRotation(&canvas->fb, U8G2_R0);
-        } else if(canvas->orientation == CanvasOrientationVertical) {
-            FURI_SWAP(canvas->width, canvas->height);
+            break;
+        case CanvasOrientationHorizontalFlip:
+            if(canvas->orientation == CanvasOrientationVertical ||
+               canvas->orientation == CanvasOrientationVerticalFlip) {
+                FURI_SWAP(canvas->width, canvas->height);
+            }
+            u8g2_SetDisplayRotation(&canvas->fb, U8G2_R2);
+            break;
+        case CanvasOrientationVertical:
+            if(canvas->orientation == CanvasOrientationHorizontal ||
+               canvas->orientation == CanvasOrientationHorizontalFlip) {
+                FURI_SWAP(canvas->width, canvas->height);
+            };
             u8g2_SetDisplayRotation(&canvas->fb, U8G2_R3);
             u8g2_SetDisplayRotation(&canvas->fb, U8G2_R3);
-        } else {
+            break;
+        case CanvasOrientationVerticalFlip:
+            if(canvas->orientation == CanvasOrientationHorizontal ||
+               canvas->orientation == CanvasOrientationHorizontalFlip) {
+                FURI_SWAP(canvas->width, canvas->height);
+            }
+            u8g2_SetDisplayRotation(&canvas->fb, U8G2_R1);
+            break;
+        default:
             furi_assert(0);
             furi_assert(0);
         }
         }
+        canvas->orientation = orientation;
     }
     }
 }
 }
 
 

+ 2 - 0
applications/services/gui/canvas.h

@@ -42,7 +42,9 @@ typedef enum {
 /** Canvas Orientation */
 /** Canvas Orientation */
 typedef enum {
 typedef enum {
     CanvasOrientationHorizontal,
     CanvasOrientationHorizontal,
+    CanvasOrientationHorizontalFlip,
     CanvasOrientationVertical,
     CanvasOrientationVertical,
+    CanvasOrientationVerticalFlip,
 } CanvasOrientation;
 } CanvasOrientation;
 
 
 /** Font Direction */
 /** Font Direction */

+ 3 - 1
applications/services/gui/gui.c

@@ -322,7 +322,9 @@ void gui_add_view_port(Gui* gui, ViewPort* view_port, GuiLayer layer) {
     furi_check(layer < GuiLayerMAX);
     furi_check(layer < GuiLayerMAX);
     // Only fullscreen supports Vertical orientation for now
     // Only fullscreen supports Vertical orientation for now
     furi_assert(
     furi_assert(
-        (layer == GuiLayerFullscreen) || (view_port->orientation != ViewPortOrientationVertical));
+        (layer == GuiLayerFullscreen) ||
+        ((view_port->orientation != ViewPortOrientationVertical) &&
+         (view_port->orientation != ViewPortOrientationVerticalFlip)));
 
 
     gui_lock(gui);
     gui_lock(gui);
     // Verify that view port is not yet added
     // Verify that view port is not yet added

+ 2 - 0
applications/services/gui/view.h

@@ -25,7 +25,9 @@ extern "C" {
 
 
 typedef enum {
 typedef enum {
     ViewOrientationHorizontal,
     ViewOrientationHorizontal,
+    ViewOrientationHorizontalFlip,
     ViewOrientationVertical,
     ViewOrientationVertical,
+    ViewOrientationVerticalFlip,
 } ViewOrientation;
 } ViewOrientation;
 
 
 /** View, anonymous type */
 /** View, anonymous type */

+ 8 - 2
applications/services/gui/view_dispatcher.c

@@ -331,10 +331,16 @@ 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)
+        if(view->orientation == ViewOrientationVertical) {
             view_port_set_orientation(view_dispatcher->view_port, ViewPortOrientationVertical);
             view_port_set_orientation(view_dispatcher->view_port, ViewPortOrientationVertical);
-        else if(view->orientation == ViewOrientationHorizontal)
+        } else if(view->orientation == ViewOrientationVerticalFlip) {
+            view_port_set_orientation(view_dispatcher->view_port, ViewPortOrientationVerticalFlip);
+        } else if(view->orientation == ViewOrientationHorizontal) {
             view_port_set_orientation(view_dispatcher->view_port, ViewPortOrientationHorizontal);
             view_port_set_orientation(view_dispatcher->view_port, ViewPortOrientationHorizontal);
+        } else if(view->orientation == ViewOrientationHorizontalFlip) {
+            view_port_set_orientation(
+                view_dispatcher->view_port, ViewPortOrientationHorizontalFlip);
+        }
         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);

+ 65 - 7
applications/services/gui/view_port.c

@@ -7,7 +7,7 @@
 
 
 // TODO add mutex to view_port ops
 // TODO add mutex to view_port ops
 
 
-static void view_port_rotate_buttons(InputEvent* event) {
+static void view_port_remap_buttons_vertical(InputEvent* event) {
     switch(event->key) {
     switch(event->key) {
     case InputKeyUp:
     case InputKeyUp:
         event->key = InputKeyRight;
         event->key = InputKeyRight;
@@ -26,12 +26,59 @@ static void view_port_rotate_buttons(InputEvent* event) {
     }
     }
 }
 }
 
 
+static void view_port_remap_buttons_vertical_flip(InputEvent* event) {
+    switch(event->key) {
+    case InputKeyUp:
+        event->key = InputKeyLeft;
+        break;
+    case InputKeyDown:
+        event->key = InputKeyRight;
+        break;
+    case InputKeyRight:
+        event->key = InputKeyUp;
+        break;
+    case InputKeyLeft:
+        event->key = InputKeyDown;
+        break;
+    default:
+        break;
+    }
+}
+
+static void view_port_remap_buttons_horizontal_flip(InputEvent* event) {
+    switch(event->key) {
+    case InputKeyUp:
+        event->key = InputKeyDown;
+        break;
+    case InputKeyDown:
+        event->key = InputKeyUp;
+        break;
+    case InputKeyRight:
+        event->key = InputKeyLeft;
+        break;
+    case InputKeyLeft:
+        event->key = InputKeyRight;
+        break;
+    default:
+        break;
+    }
+}
+
 static void view_port_setup_canvas_orientation(const ViewPort* view_port, Canvas* canvas) {
 static void view_port_setup_canvas_orientation(const ViewPort* view_port, Canvas* canvas) {
-    if(view_port->orientation == ViewPortOrientationHorizontal) {
-        canvas_set_orientation(canvas, CanvasOrientationHorizontal);
-    } else if(view_port->orientation == ViewPortOrientationVertical) {
+    switch(view_port->orientation) {
+    case ViewPortOrientationHorizontalFlip:
+        canvas_set_orientation(canvas, CanvasOrientationHorizontalFlip);
+        break;
+    case ViewPortOrientationVertical:
         canvas_set_orientation(canvas, CanvasOrientationVertical);
         canvas_set_orientation(canvas, CanvasOrientationVertical);
-    }
+        break;
+    case ViewPortOrientationVerticalFlip:
+        canvas_set_orientation(canvas, CanvasOrientationVerticalFlip);
+        break;
+    default:
+        canvas_set_orientation(canvas, CanvasOrientationHorizontal);
+        break;
+    };
 }
 }
 
 
 ViewPort* view_port_alloc() {
 ViewPort* view_port_alloc() {
@@ -122,8 +169,19 @@ void view_port_input(ViewPort* view_port, InputEvent* event) {
     furi_check(view_port->gui);
     furi_check(view_port->gui);
 
 
     if(view_port->input_callback) {
     if(view_port->input_callback) {
-        if(view_port_get_orientation(view_port) == ViewPortOrientationVertical) {
-            view_port_rotate_buttons(event);
+        ViewPortOrientation orientation = view_port_get_orientation(view_port);
+        switch(orientation) {
+        case ViewPortOrientationHorizontalFlip:
+            view_port_remap_buttons_horizontal_flip(event);
+            break;
+        case ViewPortOrientationVertical:
+            view_port_remap_buttons_vertical(event);
+            break;
+        case ViewPortOrientationVerticalFlip:
+            view_port_remap_buttons_vertical_flip(event);
+            break;
+        default:
+            break;
         }
         }
         view_port->input_callback(event, view_port->input_callback_context);
         view_port->input_callback(event, view_port->input_callback_context);
     }
     }

+ 2 - 0
applications/services/gui/view_port.h

@@ -16,7 +16,9 @@ typedef struct ViewPort ViewPort;
 
 
 typedef enum {
 typedef enum {
     ViewPortOrientationHorizontal,
     ViewPortOrientationHorizontal,
+    ViewPortOrientationHorizontalFlip,
     ViewPortOrientationVertical,
     ViewPortOrientationVertical,
+    ViewPortOrientationVerticalFlip,
 } ViewPortOrientation;
 } ViewPortOrientation;
 
 
 /** ViewPort Draw callback
 /** ViewPort Draw callback