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

Merge pull request #9 from CodyTolene/ct/issue-4-add-screen-orientation-function-and-setting

Add 'Orientation' setting and functionality.
Cody Tolene 2 лет назад
Родитель
Сommit
753cc99e2f

+ 4 - 3
src-fap/camera-suite.c

@@ -43,9 +43,10 @@ CameraSuite* camera_suite_app_alloc() {
     app->submenu = submenu_alloc();
 
     // Set defaults, in case no config loaded
-    app->haptic = 1;
-    app->speaker = 1;
-    app->led = 1;
+    app->orientation = 0; // Orientation is "portrait", zero degrees by default.
+    app->haptic = 1; // Haptic is on by default
+    app->speaker = 1; // Speaker is on by default
+    app->led = 1; // LED is on by default
 
     // Load configs
     camera_suite_read_settings(app);

+ 8 - 0
src-fap/camera-suite.h

@@ -32,6 +32,7 @@ typedef struct {
     CameraSuiteViewStyle1* camera_suite_view_style_1;
     CameraSuiteViewStyle2* camera_suite_view_style_2;
     CameraSuiteViewGuide* camera_suite_view_guide;
+    uint32_t orientation;
     uint32_t haptic;
     uint32_t speaker;
     uint32_t led;
@@ -47,6 +48,13 @@ typedef enum {
     CameraSuiteViewIdSettings,
 } CameraSuiteViewId;
 
+typedef enum {
+    CameraSuiteOrientation0,
+    CameraSuiteOrientation90,
+    CameraSuiteOrientation180,
+    CameraSuiteOrientation270,
+} CameraSuiteOrientationState;
+
 typedef enum {
     CameraSuiteHapticOff,
     CameraSuiteHapticOn,

+ 4 - 0
src-fap/helpers/camera_suite_storage.c

@@ -49,6 +49,8 @@ void camera_suite_save_settings(void* context) {
     // Store Settings
     flipper_format_write_header_cstr(
         fff_file, BOILERPLATE_SETTINGS_HEADER, BOILERPLATE_SETTINGS_FILE_VERSION);
+    flipper_format_write_uint32(
+        fff_file, BOILERPLATE_SETTINGS_KEY_ORIENTATION, &app->orientation, 1);
     flipper_format_write_uint32(fff_file, BOILERPLATE_SETTINGS_KEY_HAPTIC, &app->haptic, 1);
     flipper_format_write_uint32(fff_file, BOILERPLATE_SETTINGS_KEY_SPEAKER, &app->speaker, 1);
     flipper_format_write_uint32(fff_file, BOILERPLATE_SETTINGS_KEY_LED, &app->led, 1);
@@ -98,6 +100,8 @@ void camera_suite_read_settings(void* context) {
         return;
     }
 
+    flipper_format_read_uint32(
+        fff_file, BOILERPLATE_SETTINGS_KEY_ORIENTATION, &app->orientation, 1);
     flipper_format_read_uint32(fff_file, BOILERPLATE_SETTINGS_KEY_HAPTIC, &app->haptic, 1);
     flipper_format_read_uint32(fff_file, BOILERPLATE_SETTINGS_KEY_SPEAKER, &app->speaker, 1);
     flipper_format_read_uint32(fff_file, BOILERPLATE_SETTINGS_KEY_LED, &app->led, 1);

+ 1 - 0
src-fap/helpers/camera_suite_storage.h

@@ -9,6 +9,7 @@
 #define BOILERPLATE_SETTINGS_SAVE_PATH CONFIG_FILE_DIRECTORY_PATH "/camera-suite.conf"
 #define BOILERPLATE_SETTINGS_SAVE_PATH_TMP BOILERPLATE_SETTINGS_SAVE_PATH ".tmp"
 #define BOILERPLATE_SETTINGS_HEADER "Camera Suite Config File"
+#define BOILERPLATE_SETTINGS_KEY_ORIENTATION "Orientation"
 #define BOILERPLATE_SETTINGS_KEY_HAPTIC "Haptic"
 #define BOILERPLATE_SETTINGS_KEY_LED "Led"
 #define BOILERPLATE_SETTINGS_KEY_SPEAKER "Speaker"

+ 8 - 7
src-fap/scenes/camera_suite_scene_menu.c

@@ -21,16 +21,17 @@ void camera_suite_scene_menu_on_enter(void* context) {
 
     submenu_add_item(
         app->submenu,
-        "Style 1: Atkinson",
+        "Open Camera", // Style: Atkinson
         SubmenuIndexSceneStyle1,
         camera_suite_scene_menu_submenu_callback,
         app);
-    submenu_add_item(
-        app->submenu,
-        "Style 2: Floyd-Steinberg",
-        SubmenuIndexSceneStyle2,
-        camera_suite_scene_menu_submenu_callback,
-        app);
+    // TODO: Uncomment when style 2 is implemented
+    // submenu_add_item(
+    //     app->submenu,
+    //     "Style: Floyd-Steinberg",
+    //     SubmenuIndexSceneStyle2,
+    //     camera_suite_scene_menu_submenu_callback,
+    //     app);
     submenu_add_item(
         app->submenu, "Guide", SubmenuIndexGuide, camera_suite_scene_menu_submenu_callback, app);
     submenu_add_item(

+ 34 - 0
src-fap/scenes/camera_suite_scene_settings.c

@@ -1,6 +1,21 @@
 #include "../camera-suite.h"
 #include <lib/toolbox/value_index.h>
 
+// Camera orientation, in degrees.
+const char* const orientation_text[4] = {
+    "0",
+    "90",
+    "180",
+    "270",
+};
+
+const uint32_t orientation_value[4] = {
+    CameraSuiteOrientation0,
+    CameraSuiteOrientation90,
+    CameraSuiteOrientation180,
+    CameraSuiteOrientation270,
+};
+
 const char* const haptic_text[2] = {
     "OFF",
     "ON",
@@ -31,6 +46,14 @@ const uint32_t led_value[2] = {
     CameraSuiteLedOn,
 };
 
+static void camera_suite_scene_settings_set_camera_orientation(VariableItem* item) {
+    CameraSuite* app = variable_item_get_context(item);
+    uint8_t index = variable_item_get_current_value_index(item);
+
+    variable_item_set_current_value_text(item, orientation_text[index]);
+    app->orientation = orientation_value[index];
+}
+
 static void camera_suite_scene_settings_set_haptic(VariableItem* item) {
     CameraSuite* app = variable_item_get_context(item);
     uint8_t index = variable_item_get_current_value_index(item);
@@ -63,6 +86,17 @@ void camera_suite_scene_settings_on_enter(void* context) {
     VariableItem* item;
     uint8_t value_index;
 
+    // Camera Orientation
+    item = variable_item_list_add(
+        app->variable_item_list,
+        "Orientation:",
+        4,
+        camera_suite_scene_settings_set_camera_orientation,
+        app);
+    value_index = value_index_uint32(app->orientation, orientation_value, 4);
+    variable_item_set_current_value_index(item, value_index);
+    variable_item_set_current_value_text(item, orientation_text[value_index]);
+
     // Haptic FX ON/OFF
     item = variable_item_list_add(
         app->variable_item_list, "Haptic FX:", 2, camera_suite_scene_settings_set_haptic, app);

+ 5 - 5
src-fap/views/camera_suite_view_guide.c

@@ -32,11 +32,11 @@ void camera_suite_view_guide_draw(Canvas* canvas, CameraSuiteViewGuideModel* mod
     canvas_set_font(canvas, FontPrimary);
     canvas_draw_str_aligned(canvas, 0, 0, AlignLeft, AlignTop, "Guide");
     canvas_set_font(canvas, FontSecondary);
-    canvas_draw_str_aligned(canvas, 0, 12, AlignLeft, AlignTop, "Left = Contrast Down");
-    canvas_draw_str_aligned(canvas, 0, 22, AlignLeft, AlignTop, "Right = Contrast Up");
-    canvas_draw_str_aligned(canvas, 0, 32, AlignLeft, AlignTop, "Up = Brightness Up");
-    canvas_draw_str_aligned(canvas, 0, 42, AlignLeft, AlignTop, "Down = Brightness Down");
-    canvas_draw_str_aligned(canvas, 0, 52, AlignLeft, AlignTop, "Center = Take Picture");
+    canvas_draw_str_aligned(canvas, 0, 12, AlignLeft, AlignTop, "Left = Toggle Invert");
+    canvas_draw_str_aligned(canvas, 0, 22, AlignLeft, AlignTop, "Right = Toggle Dithering");
+    canvas_draw_str_aligned(canvas, 0, 32, AlignLeft, AlignTop, "Up = Contrast Up");
+    canvas_draw_str_aligned(canvas, 0, 42, AlignLeft, AlignTop, "Down = Contrast Down");
+    canvas_draw_str_aligned(canvas, 0, 52, AlignLeft, AlignTop, "Center = Take Picture (TODO)");
 }
 
 static void camera_suite_view_guide_model_init(CameraSuiteViewGuideModel* const model) {

+ 13 - 14
src-fap/views/camera_suite_view_style_1.c

@@ -12,7 +12,6 @@ struct CameraSuiteViewStyle1 {
     FuriStreamBuffer* rx_stream;
     FuriThread* worker_thread;
     View* view;
-    int rotation_angle;
     void* context;
 };
 
@@ -33,6 +32,8 @@ static void camera_suite_view_style_1_draw(Canvas* canvas, UartDumpModel* model)
     // Draw the frame.
     canvas_draw_frame(canvas, 0, 0, FRAME_WIDTH, FRAME_HEIGHT);
 
+    CameraSuite* app = current_instance->context;
+
     // Draw the pixels with rotation.
     for(size_t p = 0; p < FRAME_BUFFER_LENGTH; ++p) {
         uint8_t x = p % ROW_BUFFER_LENGTH; // 0 .. 15
@@ -40,19 +41,20 @@ static void camera_suite_view_style_1_draw(Canvas* canvas, UartDumpModel* model)
 
         // Apply rotation
         int16_t rotated_x, rotated_y;
-        switch(current_instance->rotation_angle) {
-        case 90:
+        switch(app->orientation) {
+        case 1: // 90 degrees
             rotated_x = y;
             rotated_y = FRAME_WIDTH - 1 - x;
             break;
-        case 180:
+        case 2: // 180 degrees
             rotated_x = FRAME_WIDTH - 1 - x;
             rotated_y = FRAME_HEIGHT - 1 - y;
             break;
-        case 270:
+        case 3: // 270 degrees
             rotated_x = FRAME_HEIGHT - 1 - y;
             rotated_y = x;
             break;
+        case 0: // 0 degrees
         default:
             rotated_x = x;
             rotated_y = y;
@@ -63,19 +65,20 @@ static void camera_suite_view_style_1_draw(Canvas* canvas, UartDumpModel* model)
             if((model->pixels[p] & (1 << i)) != 0) {
                 // Adjust the coordinates based on the new screen dimensions
                 uint16_t screen_x, screen_y;
-                switch(current_instance->rotation_angle) {
-                case 90:
+                switch(app->orientation) {
+                case 1: // 90 degrees
                     screen_x = rotated_x;
                     screen_y = FRAME_HEIGHT - 8 + (rotated_y * 8) + i;
                     break;
-                case 180:
+                case 2: // 180 degrees
                     screen_x = FRAME_WIDTH - 8 + (rotated_x * 8) + i;
                     screen_y = FRAME_HEIGHT - 1 - rotated_y;
                     break;
-                case 270:
+                case 3: // 270 degrees
                     screen_x = FRAME_WIDTH - 1 - rotated_x;
                     screen_y = rotated_y * 8 + i;
                     break;
+                case 0: // 0 degrees
                 default:
                     screen_x = rotated_x * 8 + i;
                     screen_y = rotated_y;
@@ -171,11 +174,7 @@ static bool camera_suite_view_style_1_input(InputEvent* event, void* context) {
                 true);
             break;
         case InputKeyOk:
-            // Rotate the camera image 90 degrees
-            instance->rotation_angle += 90;
-            if(instance->rotation_angle >= 360) {
-                instance->rotation_angle = 0;
-            }
+            // TODO: Take picture.
             with_view_model(
                 instance->view,
                 UartDumpModel * model,