Explorar el Código

Gui: refactor buttons remapping (#1949)

* Gui: refactor buttons remapping
  Instead of calling 3 separate functions with a ton of switch/case statements,
  use a 2-dimensional lookup table to remap buttons based on the orientation.
* Gui: cleanup input mapping and fix incorrect asserts
* SnakeGame: handle input special case

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
Vasyl "vk" Kaigorodov hace 3 años
padre
commit
abfa804ae0

+ 2 - 0
applications/plugins/snake_game/snake_game.c

@@ -380,6 +380,8 @@ int32_t snake_game_app(void* p) {
                     case InputKeyBack:
                     case InputKeyBack:
                         processing = false;
                         processing = false;
                         break;
                         break;
+                    default:
+                        break;
                     }
                     }
                 }
                 }
             } else if(event.type == EventTypeTick) {
             } else if(event.type == EventTypeTick) {

+ 46 - 68
applications/services/gui/view_port.c

@@ -7,61 +7,51 @@
 
 
 // TODO add mutex to view_port ops
 // TODO add mutex to view_port ops
 
 
-static void view_port_remap_buttons_vertical(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 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_assert(ViewPortOrientationMAX == 4, "Incorrect ViewPortOrientation count");
+_Static_assert(
+    (ViewPortOrientationHorizontal == 0 && ViewPortOrientationHorizontalFlip == 1 &&
+     ViewPortOrientationVertical == 2 && ViewPortOrientationVerticalFlip == 3),
+    "Incorrect ViewPortOrientation order");
+_Static_assert(InputKeyMAX == 6, "Incorrect InputKey count");
+_Static_assert(
+    (InputKeyUp == 0 && InputKeyDown == 1 && InputKeyRight == 2 && InputKeyLeft == 3 &&
+     InputKeyOk == 4 && InputKeyBack == 5),
+    "Incorrect InputKey order");
+
+/** InputKey directional keys mappings for different screen orientations
+* 
+*/
+static const InputKey view_port_input_mapping[ViewPortOrientationMAX][InputKeyMAX] = {
+    {InputKeyUp,
+     InputKeyDown,
+     InputKeyRight,
+     InputKeyLeft,
+     InputKeyOk,
+     InputKeyBack}, //ViewPortOrientationHorizontal
+    {InputKeyDown,
+     InputKeyUp,
+     InputKeyLeft,
+     InputKeyRight,
+     InputKeyOk,
+     InputKeyBack}, //ViewPortOrientationHorizontalFlip
+    {InputKeyRight,
+     InputKeyLeft,
+     InputKeyDown,
+     InputKeyUp,
+     InputKeyOk,
+     InputKeyBack}, //ViewPortOrientationVertical
+    {InputKeyLeft,
+     InputKeyRight,
+     InputKeyUp,
+     InputKeyDown,
+     InputKeyOk,
+     InputKeyBack}, //ViewPortOrientationVerticalFlip
+};
+
+// Remaps directional pad buttons on Flipper based on ViewPort orientation
+static void view_port_map_input(InputEvent* event, ViewPortOrientation orientation) {
+    furi_assert(orientation < ViewPortOrientationMAX && event->key < InputKeyMAX);
+    event->key = view_port_input_mapping[orientation][event->key];
 }
 }
 
 
 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) {
@@ -170,19 +160,7 @@ void view_port_input(ViewPort* view_port, InputEvent* event) {
 
 
     if(view_port->input_callback) {
     if(view_port->input_callback) {
         ViewPortOrientation orientation = view_port_get_orientation(view_port);
         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_map_input(event, orientation);
         view_port->input_callback(event, view_port->input_callback_context);
         view_port->input_callback(event, view_port->input_callback_context);
     }
     }
 }
 }

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

@@ -19,6 +19,7 @@ typedef enum {
     ViewPortOrientationHorizontalFlip,
     ViewPortOrientationHorizontalFlip,
     ViewPortOrientationVertical,
     ViewPortOrientationVertical,
     ViewPortOrientationVerticalFlip,
     ViewPortOrientationVerticalFlip,
+    ViewPortOrientationMAX, /**< Special value, don't use it */
 } ViewPortOrientation;
 } ViewPortOrientation;
 
 
 /** ViewPort Draw callback
 /** ViewPort Draw callback

+ 2 - 1
applications/services/input/input.c

@@ -60,8 +60,9 @@ const char* input_get_type_name(InputType type) {
         return "Long";
         return "Long";
     case InputTypeRepeat:
     case InputTypeRepeat:
         return "Repeat";
         return "Repeat";
+    default:
+        return "Unknown";
     }
     }
-    return "Unknown";
 }
 }
 
 
 int32_t input_srv(void* p) {
 int32_t input_srv(void* p) {

+ 1 - 0
applications/services/input/input.h

@@ -22,6 +22,7 @@ typedef enum {
     InputTypeShort, /**< Short event, emitted after InputTypeRelease done withing INPUT_LONG_PRESS interval */
     InputTypeShort, /**< Short event, emitted after InputTypeRelease done withing INPUT_LONG_PRESS interval */
     InputTypeLong, /**< Long event, emmited after INPUT_LONG_PRESS interval, asynchronouse to InputTypeRelease  */
     InputTypeLong, /**< Long event, emmited after INPUT_LONG_PRESS interval, asynchronouse to InputTypeRelease  */
     InputTypeRepeat, /**< Repeat event, emmited with INPUT_REPEATE_PRESS period after InputTypeLong event */
     InputTypeRepeat, /**< Repeat event, emmited with INPUT_REPEATE_PRESS period after InputTypeLong event */
+    InputTypeMAX, /**< Special value for exceptional */
 } InputType;
 } InputType;
 
 
 /** Input Event, dispatches with FuriPubSub */
 /** Input Event, dispatches with FuriPubSub */

+ 1 - 0
firmware/targets/f7/furi_hal/furi_hal_resources.h

@@ -20,6 +20,7 @@ typedef enum {
     InputKeyLeft,
     InputKeyLeft,
     InputKeyOk,
     InputKeyOk,
     InputKeyBack,
     InputKeyBack,
+    InputKeyMAX, /**< Special value */
 } InputKey;
 } InputKey;
 
 
 /* Light */
 /* Light */