Bläddra i källkod

old code removed stop added

HonestLocksmith 1 år sedan
förälder
incheckning
8a2b6a9eea
1 ändrade filer med 705 tillägg och 731 borttagningar
  1. 705 731
      key_copier.c

+ 705 - 731
key_copier.c

@@ -23,795 +23,769 @@
 #define BACKLIGHT_ON 1
 
 typedef enum {
-  KeyCopierSubmenuIndexMeasure,
-  KeyCopierSubmenuIndexConfigure,
-  KeyCopierSubmenuIndexSave,
-  KeyCopierSubmenuIndexLoad,
-  KeyCopierSubmenuIndexAbout,
+    KeyCopierSubmenuIndexMeasure,
+    KeyCopierSubmenuIndexConfigure,
+    KeyCopierSubmenuIndexSave,
+    KeyCopierSubmenuIndexLoad,
+    KeyCopierSubmenuIndexAbout,
 } KeyCopierSubmenuIndex;
 
 typedef enum {
-  KeyCopierViewSubmenu,
-  KeyCopierViewTextInput,
-  KeyCopierViewConfigure_i,
-  KeyCopierViewConfigure_e,
-  KeyCopierViewSave,
-  KeyCopierViewLoad,
-  KeyCopierViewMeasure,
-  KeyCopierViewAbout,
+    KeyCopierViewSubmenu,
+    KeyCopierViewTextInput,
+    KeyCopierViewConfigure_i,
+    KeyCopierViewConfigure_e,
+    KeyCopierViewSave,
+    KeyCopierViewLoad,
+    KeyCopierViewMeasure,
+    KeyCopierViewAbout,
 } KeyCopierView;
 
 typedef struct {
-  ViewDispatcher *view_dispatcher;
-  NotificationApp *notifications;
-  Submenu *submenu;
-  TextInput *text_input;
-  VariableItemList *variable_item_list_config;
-  View *view_measure;
-  View *view_config_e;
-  View *view_save;
-  View *view_load;
-  Widget *widget_about;
-  VariableItem *key_name_item;
-  VariableItem *format_item;
-  char *temp_buffer;
-  uint32_t temp_buffer_size;
-
-  DialogsApp *dialogs;
-  FuriString *file_path;
+    ViewDispatcher* view_dispatcher;
+    NotificationApp* notifications;
+    Submenu* submenu;
+    TextInput* text_input;
+    VariableItemList* variable_item_list_config;
+    View* view_measure;
+    View* view_config_e;
+    View* view_save;
+    View* view_load;
+    Widget* widget_about;
+    VariableItem* key_name_item;
+    VariableItem* format_item;
+    char* temp_buffer;
+    uint32_t temp_buffer_size;
+
+    DialogsApp* dialogs;
+    FuriString* file_path;
 } KeyCopierApp;
 
 typedef struct {
-  uint32_t format_index;
-  FuriString *key_name_str;
-  uint8_t pin_slc; // The pin that is being adjusted
-  uint8_t *depth;  // The cutting depth
-  bool data_loaded;
-  KeyFormat format;
+    uint32_t format_index;
+    FuriString* key_name_str;
+    uint8_t pin_slc; // The pin that is being adjusted
+    uint8_t* depth; // The cutting depth
+    bool data_loaded;
+    KeyFormat format;
 } KeyCopierModel;
 
-void initialize_model(KeyCopierModel *model) {
-  if (model->depth != NULL) {
-    free(model->depth);
-  }
-  model->format_index = 0;
-  memcpy(&model->format, &all_formats[model->format_index], sizeof(KeyFormat));
-  model->depth =
-      (uint8_t *)malloc((model->format.pin_num + 1) * sizeof(uint8_t));
-  for (uint8_t i = 0; i <= model->format.pin_num; i++) {
-    model->depth[i] = model->format.min_depth_ind;
-  }
-  model->pin_slc = 1;
-  model->data_loaded = 0;
-  model->key_name_str = furi_string_alloc();
+void initialize_model(KeyCopierModel* model) {
+    if(model->depth != NULL) {
+        free(model->depth);
+    }
+    model->format_index = 0;
+    memcpy(&model->format, &all_formats[model->format_index], sizeof(KeyFormat));
+    model->depth = (uint8_t*)malloc((model->format.pin_num + 1) * sizeof(uint8_t));
+    for(uint8_t i = 0; i <= model->format.pin_num; i++) {
+        model->depth[i] = model->format.min_depth_ind;
+    }
+    model->pin_slc = 1;
+    model->data_loaded = 0;
+    model->key_name_str = furi_string_alloc();
 }
 
-static uint32_t key_copier_navigation_exit_callback(void *_context) {
-  UNUSED(_context);
-  return VIEW_NONE;
+static uint32_t key_copier_navigation_exit_callback(void* _context) {
+    UNUSED(_context);
+    return VIEW_NONE;
 }
 
-static uint32_t key_copier_navigation_submenu_callback(void *_context) {
-  UNUSED(_context);
-  return KeyCopierViewSubmenu;
+static uint32_t key_copier_navigation_submenu_callback(void* _context) {
+    UNUSED(_context);
+    return KeyCopierViewSubmenu;
 }
 
-static void key_copier_submenu_callback(void *context, uint32_t index) {
-  KeyCopierApp *app = (KeyCopierApp *)context;
-  switch (index) {
-  case KeyCopierSubmenuIndexMeasure:
-    view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewMeasure);
-    break;
-  case KeyCopierSubmenuIndexConfigure:
-    view_dispatcher_switch_to_view(app->view_dispatcher,
-                                   KeyCopierViewConfigure_e);
-    break;
-  case KeyCopierSubmenuIndexSave:
-    view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewSave);
-    break;
-  case KeyCopierSubmenuIndexLoad:
-    view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewLoad);
-    break;
-  case KeyCopierSubmenuIndexAbout:
-    view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewAbout);
-    break;
-  default:
-    break;
-  }
+static void key_copier_submenu_callback(void* context, uint32_t index) {
+    KeyCopierApp* app = (KeyCopierApp*)context;
+    switch(index) {
+    case KeyCopierSubmenuIndexMeasure:
+        view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewMeasure);
+        break;
+    case KeyCopierSubmenuIndexConfigure:
+        view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewConfigure_e);
+        break;
+    case KeyCopierSubmenuIndexSave:
+        view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewSave);
+        break;
+    case KeyCopierSubmenuIndexLoad:
+        view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewLoad);
+        break;
+    case KeyCopierSubmenuIndexAbout:
+        view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewAbout);
+        break;
+    default:
+        break;
+    }
 }
 
-char *manufacturers[COUNT_OF(all_formats)];
-void initialize_manufacturers(char **manufacturers) {
-  // Populate the manufacturers array
-  for (size_t i = 0; i < COUNT_OF(all_formats); i++) {
-    manufacturers[i] = all_formats[i].manufacturer;
-  }
+char* manufacturers[COUNT_OF(all_formats)];
+void initialize_manufacturers(char** manufacturers) {
+    // Populate the manufacturers array
+    for(size_t i = 0; i < COUNT_OF(all_formats); i++) {
+        manufacturers[i] = all_formats[i].manufacturer;
+    }
 }
 
-static void key_copier_format_change(VariableItem *item) {
-  KeyCopierApp *app = variable_item_get_context(item);
-  KeyCopierModel *model = view_get_model(app->view_measure);
-  if (model->data_loaded) {
-    variable_item_set_current_value_index(item, model->format_index);
-  }
-  uint8_t format_index = variable_item_get_current_value_index(item);
-  if (format_index != model->format_index) {
-    model->format_index = format_index;
-    model->format = all_formats[format_index];
-    if (model->depth != NULL) {
-      free(model->depth);
+static void key_copier_format_change(VariableItem* item) {
+    KeyCopierApp* app = variable_item_get_context(item);
+    KeyCopierModel* model = view_get_model(app->view_measure);
+    if(model->data_loaded) {
+        variable_item_set_current_value_index(item, model->format_index);
     }
-    model->depth =
-        (uint8_t *)malloc((model->format.pin_num + 1) * sizeof(uint8_t));
-    for (uint8_t i = 0; i <= model->format.pin_num; i++) {
-      model->depth[i] = model->format.min_depth_ind;
+    uint8_t format_index = variable_item_get_current_value_index(item);
+    if(format_index != model->format_index) {
+        model->format_index = format_index;
+        model->format = all_formats[format_index];
+        if(model->depth != NULL) {
+            free(model->depth);
+        }
+        model->depth = (uint8_t*)malloc((model->format.pin_num + 1) * sizeof(uint8_t));
+        for(uint8_t i = 0; i <= model->format.pin_num; i++) {
+            model->depth[i] = model->format.min_depth_ind;
+        }
+        model->pin_slc = 1;
     }
-    model->pin_slc = 1;
-  }
-  model->data_loaded = false;
-  variable_item_set_current_value_text(item, model->format.format_name);
-  model->format = all_formats[model->format_index];
+    model->data_loaded = false;
+    variable_item_set_current_value_text(item, model->format.format_name);
+    model->format = all_formats[model->format_index];
 }
-static const char *format_config_label = "Key Format";
-static void key_copier_config_enter_callback(void *context) {
-  KeyCopierApp *app = (KeyCopierApp *)context;
-  KeyCopierModel *my_model = view_get_model(app->view_measure);
-  variable_item_list_reset(app->variable_item_list_config);
-  // Recreate this view every time we enter it so that it's always updated
-  app->format_item = variable_item_list_add(
-      app->variable_item_list_config, format_config_label,
-      COUNT_OF(all_formats), key_copier_format_change, app);
-
-  View *view_config_i =
-      variable_item_list_get_view(app->variable_item_list_config);
-  variable_item_set_current_value_index(app->format_item,
-                                        my_model->format_index);
-  key_copier_format_change(app->format_item);
-  view_set_previous_callback(view_config_i,
-                             key_copier_navigation_submenu_callback);
-  view_dispatcher_remove_view(app->view_dispatcher,
-                              KeyCopierViewConfigure_i); // delete the last one
-  view_dispatcher_add_view(app->view_dispatcher, KeyCopierViewConfigure_i,
-                           view_config_i);
-  view_dispatcher_switch_to_view(app->view_dispatcher,
-                                 KeyCopierViewConfigure_i); // recreate it
+static const char* format_config_label = "Key Format";
+static void key_copier_config_enter_callback(void* context) {
+    KeyCopierApp* app = (KeyCopierApp*)context;
+    KeyCopierModel* my_model = view_get_model(app->view_measure);
+    variable_item_list_reset(app->variable_item_list_config);
+    // Recreate this view every time we enter it so that it's always updated
+    app->format_item = variable_item_list_add(
+        app->variable_item_list_config,
+        format_config_label,
+        COUNT_OF(all_formats),
+        key_copier_format_change,
+        app);
+
+    View* view_config_i = variable_item_list_get_view(app->variable_item_list_config);
+    variable_item_set_current_value_index(app->format_item, my_model->format_index);
+    key_copier_format_change(app->format_item);
+    view_set_previous_callback(view_config_i, key_copier_navigation_submenu_callback);
+    view_dispatcher_remove_view(
+        app->view_dispatcher,
+        KeyCopierViewConfigure_i); // delete the last one
+    view_dispatcher_add_view(app->view_dispatcher, KeyCopierViewConfigure_i, view_config_i);
+    view_dispatcher_switch_to_view(app->view_dispatcher,
+                                   KeyCopierViewConfigure_i); // recreate it
 }
 
-static const char *key_name_entry_text = "Enter name";
-static void key_copier_file_saver(void *context) {
-  KeyCopierApp *app = (KeyCopierApp *)context;
-  KeyCopierModel *model = view_get_model(app->view_measure);
-  bool redraw = true;
-  with_view_model(
-      app->view_measure, KeyCopierModel * model,
-      { furi_string_set(model->key_name_str, app->temp_buffer); }, redraw);
-  FuriString *file_path = furi_string_alloc();
-  furi_string_printf(file_path, "%s/%s%s", STORAGE_APP_DATA_PATH_PREFIX,
-                     furi_string_get_cstr(model->key_name_str),
-                     KEY_COPIER_FILE_EXTENSION);
-
-  Storage *storage = furi_record_open(RECORD_STORAGE);
-  storage_simply_mkdir(storage, STORAGE_APP_DATA_PATH_PREFIX);
-  FURI_LOG_D(TAG, "mkdir finished");
-  FlipperFormat *flipper_format = flipper_format_file_alloc(storage);
-  do {
-    const uint32_t version = 1;
-    const uint32_t pin_num_buffer = (uint32_t)model->format.pin_num;
-    const uint32_t macs_buffer = (uint32_t)model->format.macs;
-    FuriString *buffer = furi_string_alloc();
-    if (!flipper_format_file_open_always(flipper_format,
-                                         furi_string_get_cstr(file_path)))
-      break;
-    if (!flipper_format_write_header_cstr(flipper_format,
-                                          "Flipper Key Copier File", version))
-      break;
-    if (!flipper_format_write_string_cstr(flipper_format, "Manufacturer",
-                                          model->format.manufacturer))
-      break;
-    if (!flipper_format_write_string_cstr(flipper_format, "Format Name",
-                                          model->format.format_name))
-      break;
-    if (!flipper_format_write_string_cstr(flipper_format, "Data Sheet",
-                                          model->format.format_link))
-      break;
-    if (!flipper_format_write_uint32(flipper_format, "Number of Pins",
-                                     &pin_num_buffer, 1))
-      break;
-    if (!flipper_format_write_uint32(
-            flipper_format, "Maximum Adjacent Cut Specification (MACS)",
-            &macs_buffer, 1))
-      break;
-    for (int i = 0; i < model->format.pin_num; i++) {
-      if (i < model->format.pin_num - 1) {
-        furi_string_cat_printf(buffer, "%d-", model->depth[i]);
-      } else {
-        furi_string_cat_printf(buffer, "%d", model->depth[i]);
-      }
-    }
-    if (!flipper_format_write_string(flipper_format, "Bitting Pattern", buffer))
-      break;
-    furi_string_free(buffer);
-    // signal that the file was written successfully
-  } while (0);
-  flipper_format_free(flipper_format);
+static const char* key_name_entry_text = "Enter name";
+static void key_copier_file_saver(void* context) {
+    KeyCopierApp* app = (KeyCopierApp*)context;
+    KeyCopierModel* model = view_get_model(app->view_measure);
+    bool redraw = true;
+    with_view_model(
+        app->view_measure,
+        KeyCopierModel * model,
+        { furi_string_set(model->key_name_str, app->temp_buffer); },
+        redraw);
+    FuriString* file_path = furi_string_alloc();
+    furi_string_printf(
+        file_path,
+        "%s/%s%s",
+        STORAGE_APP_DATA_PATH_PREFIX,
+        furi_string_get_cstr(model->key_name_str),
+        KEY_COPIER_FILE_EXTENSION);
+
+    Storage* storage = furi_record_open(RECORD_STORAGE);
+    storage_simply_mkdir(storage, STORAGE_APP_DATA_PATH_PREFIX);
+    FURI_LOG_D(TAG, "mkdir finished");
+    FlipperFormat* flipper_format = flipper_format_file_alloc(storage);
+    do {
+        const uint32_t version = 1;
+        const uint32_t pin_num_buffer = (uint32_t)model->format.pin_num;
+        const uint32_t macs_buffer = (uint32_t)model->format.macs;
+        FuriString* buffer = furi_string_alloc();
+        if(!flipper_format_file_open_always(flipper_format, furi_string_get_cstr(file_path)))
+            break;
+        if(!flipper_format_write_header_cstr(flipper_format, "Flipper Key Copier File", version))
+            break;
+        if(!flipper_format_write_string_cstr(
+               flipper_format, "Manufacturer", model->format.manufacturer))
+            break;
+        if(!flipper_format_write_string_cstr(
+               flipper_format, "Format Name", model->format.format_name))
+            break;
+        if(!flipper_format_write_string_cstr(
+               flipper_format, "Data Sheet", model->format.format_link))
+            break;
+        if(!flipper_format_write_uint32(flipper_format, "Number of Pins", &pin_num_buffer, 1))
+            break;
+        if(!flipper_format_write_uint32(
+               flipper_format, "Maximum Adjacent Cut Specification (MACS)", &macs_buffer, 1))
+            break;
+        for(int i = 0; i < model->format.pin_num; i++) {
+            if(i < model->format.pin_num - 1) {
+                furi_string_cat_printf(buffer, "%d-", model->depth[i]);
+            } else {
+                furi_string_cat_printf(buffer, "%d", model->depth[i]);
+            }
+        }
+        if(!flipper_format_write_string(flipper_format, "Bitting Pattern", buffer)) break;
+        furi_string_free(buffer);
+        // signal that the file was written successfully
+    } while(0);
+    flipper_format_free(flipper_format);
 
-  view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewSubmenu);
+    view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewSubmenu);
 }
 
-static void key_copier_view_save_callback(void *context) {
-  KeyCopierApp *app = (KeyCopierApp *)context;
-  // Header to display on the text input screen.
-  text_input_set_header_text(app->text_input, key_name_entry_text);
-
-  // Copy the current name into the temporary buffer.
-  bool redraw = false;
-  with_view_model(
-      app->view_measure, KeyCopierModel * model,
-      {
-        strncpy(app->temp_buffer, furi_string_get_cstr(model->key_name_str),
+static void key_copier_view_save_callback(void* context) {
+    KeyCopierApp* app = (KeyCopierApp*)context;
+    // Header to display on the text input screen.
+    text_input_set_header_text(app->text_input, key_name_entry_text);
+
+    // Copy the current name into the temporary buffer.
+    bool redraw = false;
+    with_view_model(
+        app->view_measure,
+        KeyCopierModel * model,
+        {
+            strncpy(
+                app->temp_buffer,
+                furi_string_get_cstr(model->key_name_str),
                 app->temp_buffer_size);
-      },
-      redraw);
-
-  // Configure the text input.  When user enters text and clicks OK,
-  // key_copier_file_saver be called.
-  bool clear_previous_text = false;
-  text_input_set_result_callback(app->text_input, key_copier_file_saver, app,
-                                 app->temp_buffer, app->temp_buffer_size,
-                                 clear_previous_text);
+        },
+        redraw);
+
+    // Configure the text input.  When user enters text and clicks OK,
+    // key_copier_file_saver be called.
+    bool clear_previous_text = false;
+    text_input_set_result_callback(
+        app->text_input,
+        key_copier_file_saver,
+        app,
+        app->temp_buffer,
+        app->temp_buffer_size,
+        clear_previous_text);
+
+    view_set_previous_callback(
+        text_input_get_view(app->text_input), key_copier_navigation_submenu_callback);
+
+    // Show text input dialog.
+    view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewTextInput);
+}
 
-  view_set_previous_callback(text_input_get_view(app->text_input),
-                             key_copier_navigation_submenu_callback);
+static void key_copier_view_load_callback(void* context) {
+    KeyCopierApp* app = (KeyCopierApp*)context;
+    KeyCopierModel* model = view_get_model(app->view_measure);
+    DialogsFileBrowserOptions browser_options;
+    Storage* storage = furi_record_open(RECORD_STORAGE);
+    storage_simply_mkdir(storage, STORAGE_APP_DATA_PATH_PREFIX);
+    dialog_file_browser_set_basic_options(&browser_options, KEY_COPIER_FILE_EXTENSION, &I_icon);
+    browser_options.base_path = STORAGE_APP_DATA_PATH_PREFIX;
+    furi_string_set(app->file_path, browser_options.base_path);
+    if(dialog_file_browser_show(app->dialogs, app->file_path, app->file_path, &browser_options)) {
+        FlipperFormat* flipper_format = flipper_format_file_alloc(storage);
+        do {
+            if(!flipper_format_file_open_existing(
+                   flipper_format, furi_string_get_cstr(app->file_path)))
+                break;
+            FuriString* format_buffer = furi_string_alloc();
+            FuriString* depth_buffer = furi_string_alloc();
+            if(!flipper_format_read_string(flipper_format, "Format Name", format_buffer)) break;
+            if(!flipper_format_read_string(flipper_format, "Bitting Pattern", depth_buffer)) break;
+            for(size_t i = 0; i < COUNT_OF(all_formats); i++) {
+                if(!strcmp(furi_string_get_cstr(format_buffer), all_formats[i].format_name)) {
+                    model->format_index = (uint32_t)i;
+                    model->format = all_formats[model->format_index];
+                }
+            }
 
-  // Show text input dialog.
-  view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewTextInput);
+            for(int i = 0; i < model->format.pin_num; i++) {
+                model->depth[i] = (uint8_t)(furi_string_get_char(depth_buffer, i * 2) - '0');
+            }
+            model->data_loaded = true;
+            // signal that the file was read successfully
+        } while(0);
+        flipper_format_free(flipper_format);
+        furi_record_close(RECORD_STORAGE);
+    }
+    view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewSubmenu);
 }
 
-static void key_copier_view_load_callback(void *context) {
-  KeyCopierApp *app = (KeyCopierApp *)context;
-  KeyCopierModel *model = view_get_model(app->view_measure);
-  DialogsFileBrowserOptions browser_options;
-  Storage *storage = furi_record_open(RECORD_STORAGE);
-  storage_simply_mkdir(storage, STORAGE_APP_DATA_PATH_PREFIX);
-  dialog_file_browser_set_basic_options(&browser_options,
-                                        KEY_COPIER_FILE_EXTENSION, &I_icon);
-  browser_options.base_path = STORAGE_APP_DATA_PATH_PREFIX;
-  furi_string_set(app->file_path, browser_options.base_path);
-  if (dialog_file_browser_show(app->dialogs, app->file_path, app->file_path,
-                               &browser_options)) {
-    FlipperFormat *flipper_format = flipper_format_file_alloc(storage);
-    do {
-      if (!flipper_format_file_open_existing(
-              flipper_format, furi_string_get_cstr(app->file_path)))
-        break;
-      FuriString *format_buffer = furi_string_alloc();
-      FuriString *depth_buffer = furi_string_alloc();
-      if (!flipper_format_read_string(flipper_format, "Format Name",
-                                      format_buffer))
-        break;
-      if (!flipper_format_read_string(flipper_format, "Bitting Pattern",
-                                      depth_buffer))
-        break;
-      for (size_t i = 0; i < COUNT_OF(all_formats); i++) {
-        if (!strcmp(furi_string_get_cstr(format_buffer),
-                    all_formats[i].format_name)) {
-          model->format_index = (uint32_t)i;
-          model->format = all_formats[model->format_index];
-        }
-      }
-
-      for (int i = 0; i < model->format.pin_num; i++) {
-        model->depth[i] =
-            (uint8_t)(furi_string_get_char(depth_buffer, i * 2) - '0');
-      }
-      model->data_loaded = true;
-      // signal that the file was read successfully
-    } while (0);
-    flipper_format_free(flipper_format);
-    furi_record_close(RECORD_STORAGE);
-  }
-  view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewSubmenu);
-}
+static void key_copier_view_measure_draw_callback(Canvas* canvas, void* model) {
+    static double inches_per_px = (double)INCHES_PER_PX;
+    canvas_set_bitmap_mode(canvas, true);
+    KeyCopierModel* my_model = (KeyCopierModel*)model;
+    KeyFormat my_format = my_model->format;
+    FuriString* buffer = furi_string_alloc();
+    int pin_half_width_px = (int)round((my_format.pin_width_inch / inches_per_px) / 2);
+    int pin_step_px = (int)round(my_format.pin_increment_inch / inches_per_px);
+    double drill_radians =
+        (180 - my_format.drill_angle) / 2 / 180 * (double)M_PI; // Convert angle to radians
+    double tangent = tan(drill_radians);
+    int top_contour_px = (int)round(62 - my_format.uncut_depth_inch / inches_per_px);
+    int bottom_contour_px = 0;
+
+    if(my_format.sides == 2)
+        bottom_contour_px =
+            top_contour_px + (int)round(my_format.uncut_depth_inch / inches_per_px);
+    int post_extra_x_px = 0;
+    int pre_extra_x_px = 0;
+    int bottom_post_extra_x_px = 0; // new
+    int bottom_pre_extra_x_px = 0; // new
+    for(int current_pin = 1; current_pin <= my_model->format.pin_num; current_pin += 1) {
+        double current_center_px =
+            my_format.first_pin_inch + (current_pin - 1) * my_format.pin_increment_inch;
+        int pin_center_px = (int)round(current_center_px / inches_per_px);
+
+        furi_string_printf(buffer, "%d", my_model->depth[current_pin - 1]);
+        canvas_draw_str_aligned(
+            canvas,
+            pin_center_px,
+            top_contour_px - 12,
+            AlignCenter,
+            AlignCenter,
+            furi_string_get_cstr(buffer));
 
-static void key_copier_view_measure_draw_callback(Canvas *canvas, void *model) {
-  static double inches_per_px = (double)INCHES_PER_PX;
-  canvas_set_bitmap_mode(canvas, true);
-  KeyCopierModel *my_model = (KeyCopierModel *)model;
-  KeyFormat my_format = my_model->format;
-  FuriString *buffer = furi_string_alloc();
-  int pin_half_width_px =
-      (int)round((my_format.pin_width_inch / inches_per_px) / 2);
-  int pin_step_px = (int)round(my_format.pin_increment_inch / inches_per_px);
-  double drill_radians = (180 - my_format.drill_angle) / 2 / 180 *
-                         (double)M_PI; // Convert angle to radians
-  double tangent = tan(drill_radians);
-  int top_contour_px =
-      (int)round(62 - my_format.uncut_depth_inch / inches_per_px);
-  int bottom_contour_px = 0;
-  // int bottom_contour_px =
-  //     top_contour_px + (int)round(my_format.uncut_depth_inch /
-  //     inches_per_px);
-  if (my_format.sides == 2)
-    bottom_contour_px =
-        top_contour_px + (int)round(my_format.uncut_depth_inch / inches_per_px);
-  int post_extra_x_px = 0;
-  int pre_extra_x_px = 0;
-  int bottom_post_extra_x_px = 0; // new
-  int bottom_pre_extra_x_px = 0;  // new
-  for (int current_pin = 1; current_pin <= my_model->format.pin_num;
-       current_pin += 1) {
-    double current_center_px = my_format.first_pin_inch +
-                               (current_pin - 1) * my_format.pin_increment_inch;
-    int pin_center_px = (int)round(current_center_px / inches_per_px);
-
-    furi_string_printf(buffer, "%d", my_model->depth[current_pin - 1]);
-    canvas_draw_str_aligned(canvas, pin_center_px, top_contour_px - 12,
-                            AlignCenter, AlignCenter,
-                            furi_string_get_cstr(buffer));
-
-    canvas_draw_line(
-        canvas, pin_center_px, top_contour_px - 5, pin_center_px,
-        top_contour_px); // the vertical line to indicate pin center
-    int current_depth =
-        my_model->depth[current_pin - 1] - my_format.min_depth_ind;
-    int current_depth_px =
-        (int)round(current_depth * my_format.depth_step_inch / inches_per_px);
-    canvas_draw_line(
-        canvas, pin_center_px - pin_half_width_px,
-        top_contour_px + current_depth_px, pin_center_px + pin_half_width_px,
-        top_contour_px +
-            current_depth_px); // draw top pin width horizontal line
-
-    // if(my_format.sides == 2) //old (remove new start to end and remove // for
-    // this line to fix)
-
-    if (my_format.sides == 2) { // new start
-      int last_depth =
-          my_model->depth[current_pin - 2] - my_format.min_depth_ind;
-      int next_depth = my_model->depth[current_pin] - my_format.min_depth_ind;
-      int current_depth =
-          my_model->depth[current_pin - 1] - my_format.min_depth_ind;
-      int current_depth_px =
-          (int)round(current_depth * my_format.depth_step_inch / inches_per_px);
-
-      // Draw horizontal line for bottom pin
-      canvas_draw_line(canvas, pin_center_px - pin_half_width_px,
-                       bottom_contour_px - current_depth_px,
-                       pin_center_px + pin_half_width_px,
-                       bottom_contour_px - current_depth_px);
-
-      // Handle first pin for bottom
-      if (current_pin == 1) {
-        canvas_draw_line(canvas, 0, bottom_contour_px,
-                         pin_center_px - pin_half_width_px - current_depth_px,
-                         bottom_contour_px);
-        last_depth = 0;
-        bottom_pre_extra_x_px = max(current_depth_px + pin_half_width_px, 0);
-      }
-
-      // Handle left side intersection for bottom
-      if ((last_depth + current_depth) > my_format.clearance) {
-        if (current_pin != 1) {
-          bottom_pre_extra_x_px =
-              min(max(pin_step_px - bottom_post_extra_x_px, pin_half_width_px),
-                  pin_step_px - pin_half_width_px);
-        }
-        canvas_draw_line(
-            canvas, pin_center_px - bottom_pre_extra_x_px,
-            bottom_contour_px -
-                max((int)round((current_depth_px -
-                                (bottom_pre_extra_x_px - pin_half_width_px)) *
-                               tangent),
-                    0),
-            pin_center_px - pin_half_width_px,
-            bottom_contour_px - (int)round(current_depth_px * tangent));
-      } else {
-        int last_depth_px =
-            (int)round(last_depth * my_format.depth_step_inch / inches_per_px);
-        int up_slope_start_x_px =
-            pin_center_px - pin_half_width_px - current_depth_px;
-        canvas_draw_line(
-            canvas, pin_center_px - pin_half_width_px - current_depth_px,
-            bottom_contour_px, pin_center_px - pin_half_width_px,
-            bottom_contour_px - (int)round(current_depth_px * tangent));
         canvas_draw_line(
             canvas,
-            min(pin_center_px - pin_step_px + pin_half_width_px + last_depth_px,
-                up_slope_start_x_px),
-            bottom_contour_px, up_slope_start_x_px, bottom_contour_px);
-      }
-
-      // Handle right side intersection for bottom
-      if ((current_depth + next_depth) > my_format.clearance) {
-        double numerator = (double)current_depth;
-        double denominator = (double)(current_depth + next_depth);
-        double product = (numerator / denominator) * pin_step_px;
-        bottom_post_extra_x_px = (int)min(max(product, pin_half_width_px),
-                                          pin_step_px - pin_half_width_px);
+            pin_center_px,
+            top_contour_px - 5,
+            pin_center_px,
+            top_contour_px); // the vertical line to indicate pin center
+        int current_depth = my_model->depth[current_pin - 1] - my_format.min_depth_ind;
+        int current_depth_px =
+            (int)round(current_depth * my_format.depth_step_inch / inches_per_px);
         canvas_draw_line(
-            canvas, pin_center_px + pin_half_width_px,
-            bottom_contour_px - current_depth_px,
-            pin_center_px + bottom_post_extra_x_px,
-            bottom_contour_px -
-                max(current_depth_px - (int)round((bottom_post_extra_x_px -
-                                                   pin_half_width_px) *
-                                                  tangent),
-                    0));
-      } else {
-        canvas_draw_line(canvas, pin_center_px + pin_half_width_px,
-                         bottom_contour_px -
-                             (int)round(current_depth_px * tangent),
-                         pin_center_px + pin_half_width_px + current_depth_px,
-                         bottom_contour_px);
-      }
-    }
-    // new end
-
-    //      canvas_draw_line(
-    //          canvas,
-    //          pin_center_px - pin_half_width_px,
-    //         bottom_contour_px - current_depth_px,
-    //         pin_center_px + pin_half_width_px,
-    //         bottom_contour_px - current_depth_px); // draw bottom pin width
-    //         horizontal line
-
-    int last_depth = my_model->depth[current_pin - 2] - my_format.min_depth_ind;
-    int next_depth = my_model->depth[current_pin] - my_format.min_depth_ind;
-    if (current_pin == 1) {
-      canvas_draw_line(canvas, 0, top_contour_px,
-                       pin_center_px - pin_half_width_px - current_depth_px,
-                       top_contour_px); // draw top shoulder
-      last_depth = 0;
-      pre_extra_x_px = max(current_depth_px + pin_half_width_px, 0);
-
-      //           canvas_draw_line(
-      //               canvas,
-      //               0,
-      //              bottom_contour_px,
-      //              pin_center_px - pin_half_width_px - current_depth_px,
-      //              bottom_contour_px); // draw bottom shoulder (hidden by
-      //              level contour)
-    }
-    if (current_pin == my_model->format.pin_num) {
-      next_depth = 0;
-    }
-    if ((last_depth + current_depth) > my_format.clearance) { // yes
-      // intersection
-
-      if (current_pin != 1) {
-        pre_extra_x_px =
-            min(max(pin_step_px - post_extra_x_px, pin_half_width_px),
-                pin_step_px - pin_half_width_px);
-      }
-      canvas_draw_line(
-          canvas, pin_center_px - pre_extra_x_px,
-          top_contour_px +
-              max((int)round((current_depth_px -
-                              (pre_extra_x_px - pin_half_width_px)) *
-                             tangent),
-                  0),
-          pin_center_px - pin_half_width_px,
-          top_contour_px + (int)round(current_depth_px * tangent));
-    } else {
-      int last_depth_px =
-          (int)round(last_depth * my_format.depth_step_inch / inches_per_px);
-      int down_slope_start_x_px =
-          pin_center_px - pin_half_width_px - current_depth_px;
-      canvas_draw_line(canvas,
-                       pin_center_px - pin_half_width_px - current_depth_px,
-                       top_contour_px, pin_center_px - pin_half_width_px,
-                       top_contour_px + (int)round(current_depth_px * tangent));
-      canvas_draw_line(
-          canvas,
-          min(pin_center_px - pin_step_px + pin_half_width_px + last_depth_px,
-              down_slope_start_x_px),
-          top_contour_px, down_slope_start_x_px, top_contour_px);
-    }
-    if ((current_depth + next_depth) > my_format.clearance) { // yes
-      // intersection
-      double numerator = (double)current_depth;
-      double denominator = (double)(current_depth + next_depth);
-      double product = (numerator / denominator) * pin_step_px;
-      post_extra_x_px = (int)min(max(product, pin_half_width_px),
-                                 pin_step_px - pin_half_width_px);
-      canvas_draw_line(
-          canvas, pin_center_px + pin_half_width_px,
-          top_contour_px + current_depth_px, pin_center_px + post_extra_x_px,
-          top_contour_px +
-              max(current_depth_px -
-                      (int)round((post_extra_x_px - pin_half_width_px) *
-                                 tangent),
-                  0));
-    } else { // no intersection
-      canvas_draw_line(canvas, pin_center_px + pin_half_width_px,
-                       top_contour_px + (int)round(current_depth_px * tangent),
-                       pin_center_px + pin_half_width_px + current_depth_px,
-                       top_contour_px);
-    }
-  }
-
-  int level_contour_px = (int)round(
-      (my_format.last_pin_inch + my_format.elbow_inch) / inches_per_px);
-  int elbow_px = (int)round(my_format.elbow_inch / inches_per_px);
-  canvas_draw_line(canvas, 0, 62, level_contour_px, 62);
-  canvas_draw_line(canvas, level_contour_px, 62, level_contour_px + elbow_px,
-                   62 - elbow_px);
-
-  if (my_format.stop == 2) {
-    // Draw a line using level_contour_px if stop equals tip
-    canvas_draw_line(
-        canvas, level_contour_px, top_contour_px, level_contour_px,
-        63); // change to if stop ==tip and measure from this point back.
-  } else {
-    // Otherwise, draw a default line
-    canvas_draw_line(canvas, 1, top_contour_px, 1, 63);
-  }
-
-  int slc_pin_px =
-      (int)round((my_format.first_pin_inch +
-                  (my_model->pin_slc - 1) * my_format.pin_increment_inch) /
-                 inches_per_px);
-  canvas_draw_icon(canvas, slc_pin_px - 2, top_contour_px - 25, &I_arrow_down);
-
-  furi_string_printf(buffer, "%s", my_format.format_name);
-  canvas_draw_str(canvas, 100, 10, furi_string_get_cstr(buffer));
-  furi_string_free(buffer);
-}
+            canvas,
+            pin_center_px - pin_half_width_px,
+            top_contour_px + current_depth_px,
+            pin_center_px + pin_half_width_px,
+            top_contour_px + current_depth_px); // draw top pin width horizontal line
+
+        if(my_format.sides == 2) { // new
+            int last_depth = my_model->depth[current_pin - 2] - my_format.min_depth_ind;
+            int next_depth = my_model->depth[current_pin] - my_format.min_depth_ind;
+            int current_depth = my_model->depth[current_pin - 1] - my_format.min_depth_ind;
+            int current_depth_px =
+                (int)round(current_depth * my_format.depth_step_inch / inches_per_px);
+
+            // Draw horizontal line for bottom pin
+            canvas_draw_line(
+                canvas,
+                pin_center_px - pin_half_width_px,
+                bottom_contour_px - current_depth_px,
+                pin_center_px + pin_half_width_px,
+                bottom_contour_px - current_depth_px);
+
+            // Handle first pin for bottom
+            if(current_pin == 1) {
+                canvas_draw_line(
+                    canvas,
+                    0,
+                    bottom_contour_px,
+                    pin_center_px - pin_half_width_px - current_depth_px,
+                    bottom_contour_px);
+                last_depth = 0;
+                bottom_pre_extra_x_px = max(current_depth_px + pin_half_width_px, 0);
+            }
 
-static bool key_copier_view_measure_input_callback(InputEvent *event,
-                                                   void *context) {
-  KeyCopierApp *app = (KeyCopierApp *)context;
-  if (event->type == InputTypeShort) {
-    switch (event->key) {
-    case InputKeyLeft: {
-      bool redraw = true;
-      with_view_model(
-          app->view_measure, KeyCopierModel * model,
-          {
-            if (model->pin_slc > 1) {
-              model->pin_slc--;
+            // Handle left side intersection for bottom
+            if((last_depth + current_depth) > my_format.clearance) {
+                if(current_pin != 1) {
+                    bottom_pre_extra_x_px =
+                        min(max(pin_step_px - bottom_post_extra_x_px, pin_half_width_px),
+                            pin_step_px - pin_half_width_px);
+                }
+                canvas_draw_line(
+                    canvas,
+                    pin_center_px - bottom_pre_extra_x_px,
+                    bottom_contour_px -
+                        max((int)round(
+                                (current_depth_px - (bottom_pre_extra_x_px - pin_half_width_px)) *
+                                tangent),
+                            0),
+                    pin_center_px - pin_half_width_px,
+                    bottom_contour_px - (int)round(current_depth_px * tangent));
+            } else {
+                int last_depth_px =
+                    (int)round(last_depth * my_format.depth_step_inch / inches_per_px);
+                int up_slope_start_x_px = pin_center_px - pin_half_width_px - current_depth_px;
+                canvas_draw_line(
+                    canvas,
+                    pin_center_px - pin_half_width_px - current_depth_px,
+                    bottom_contour_px,
+                    pin_center_px - pin_half_width_px,
+                    bottom_contour_px - (int)round(current_depth_px * tangent));
+                canvas_draw_line(
+                    canvas,
+                    min(pin_center_px - pin_step_px + pin_half_width_px + last_depth_px,
+                        up_slope_start_x_px),
+                    bottom_contour_px,
+                    up_slope_start_x_px,
+                    bottom_contour_px);
             }
-          },
-          redraw);
-      break;
-    }
-    case InputKeyRight: {
-      bool redraw = true;
-      with_view_model(
-          app->view_measure, KeyCopierModel * model,
-          {
-            if (model->pin_slc < model->format.pin_num) {
-              model->pin_slc++;
+
+            // Handle right side intersection for bottom
+            if((current_depth + next_depth) > my_format.clearance) {
+                double numerator = (double)current_depth;
+                double denominator = (double)(current_depth + next_depth);
+                double product = (numerator / denominator) * pin_step_px;
+                bottom_post_extra_x_px =
+                    (int)min(max(product, pin_half_width_px), pin_step_px - pin_half_width_px);
+                canvas_draw_line(
+                    canvas,
+                    pin_center_px + pin_half_width_px,
+                    bottom_contour_px - current_depth_px,
+                    pin_center_px + bottom_post_extra_x_px,
+                    bottom_contour_px -
+                        max(current_depth_px -
+                                (int)round((bottom_post_extra_x_px - pin_half_width_px) * tangent),
+                            0));
+            } else {
+                canvas_draw_line(
+                    canvas,
+                    pin_center_px + pin_half_width_px,
+                    bottom_contour_px - (int)round(current_depth_px * tangent),
+                    pin_center_px + pin_half_width_px + current_depth_px,
+                    bottom_contour_px);
             }
-          },
-          redraw);
-      break;
-    }
-    case InputKeyUp: {
-      bool redraw = true;
-      with_view_model(
-          app->view_measure, KeyCopierModel * model,
-          {
-            if (model->depth[model->pin_slc - 1] >
-                model->format.min_depth_ind) {
-              if (model->pin_slc ==
-                  1) { // first pin only limited by the next one
-                if (model->depth[model->pin_slc] -
-                        model->depth[model->pin_slc - 1] <
-                    model->format.macs)
-                  model->depth[model->pin_slc - 1]--;
-              } else if (model->pin_slc ==
-                         model->format.pin_num) { // last pin only limited by
-                // the previous one
-                if (model->depth[model->pin_slc - 2] -
-                        model->depth[model->pin_slc - 1] <
-                    model->format.macs) {
-                  model->depth[model->pin_slc - 1]--;
-                }
-              } else {
-                if (model->depth[model->pin_slc] -
-                            model->depth[model->pin_slc - 1] <
-                        model->format.macs &&
-                    model->depth[model->pin_slc - 2] -
-                            model->depth[model->pin_slc - 1] <
-                        model->format.macs) {
-                  model->depth[model->pin_slc - 1]--;
-                }
-              }
+        }
+        // new end
+
+        int last_depth = my_model->depth[current_pin - 2] - my_format.min_depth_ind;
+        int next_depth = my_model->depth[current_pin] - my_format.min_depth_ind;
+        if(current_pin == 1) {
+            canvas_draw_line(
+                canvas,
+                0,
+                top_contour_px,
+                pin_center_px - pin_half_width_px - current_depth_px,
+                top_contour_px); // draw top shoulder
+            last_depth = 0;
+            pre_extra_x_px = max(current_depth_px + pin_half_width_px, 0);
+        }
+        if(current_pin == my_model->format.pin_num) {
+            next_depth = 0;
+        }
+        if((last_depth + current_depth) > my_format.clearance) { // yes
+            // intersection
+
+            if(current_pin != 1) {
+                pre_extra_x_px =
+                    min(max(pin_step_px - post_extra_x_px, pin_half_width_px),
+                        pin_step_px - pin_half_width_px);
             }
-          },
-          redraw);
-      break;
+            canvas_draw_line(
+                canvas,
+                pin_center_px - pre_extra_x_px,
+                top_contour_px +
+                    max((int)round(
+                            (current_depth_px - (pre_extra_x_px - pin_half_width_px)) * tangent),
+                        0),
+                pin_center_px - pin_half_width_px,
+                top_contour_px + (int)round(current_depth_px * tangent));
+        } else {
+            int last_depth_px = (int)round(last_depth * my_format.depth_step_inch / inches_per_px);
+            int down_slope_start_x_px = pin_center_px - pin_half_width_px - current_depth_px;
+            canvas_draw_line(
+                canvas,
+                pin_center_px - pin_half_width_px - current_depth_px,
+                top_contour_px,
+                pin_center_px - pin_half_width_px,
+                top_contour_px + (int)round(current_depth_px * tangent));
+            canvas_draw_line(
+                canvas,
+                min(pin_center_px - pin_step_px + pin_half_width_px + last_depth_px,
+                    down_slope_start_x_px),
+                top_contour_px,
+                down_slope_start_x_px,
+                top_contour_px);
+        }
+        if((current_depth + next_depth) > my_format.clearance) { // yes
+            // intersection
+            double numerator = (double)current_depth;
+            double denominator = (double)(current_depth + next_depth);
+            double product = (numerator / denominator) * pin_step_px;
+            post_extra_x_px =
+                (int)min(max(product, pin_half_width_px), pin_step_px - pin_half_width_px);
+            canvas_draw_line(
+                canvas,
+                pin_center_px + pin_half_width_px,
+                top_contour_px + current_depth_px,
+                pin_center_px + post_extra_x_px,
+                top_contour_px +
+                    max(current_depth_px -
+                            (int)round((post_extra_x_px - pin_half_width_px) * tangent),
+                        0));
+        } else { // no intersection
+            canvas_draw_line(
+                canvas,
+                pin_center_px + pin_half_width_px,
+                top_contour_px + (int)round(current_depth_px * tangent),
+                pin_center_px + pin_half_width_px + current_depth_px,
+                top_contour_px);
+        }
     }
-    case InputKeyDown: {
-      bool redraw = true;
-      with_view_model(
-          app->view_measure, KeyCopierModel * model,
-          {
-            if (model->depth[model->pin_slc - 1] <
-                model->format.max_depth_ind) {
-              if (model->pin_slc ==
-                  1) { // first pin only limited by the next one
-                if (model->depth[model->pin_slc - 1] -
-                        model->depth[model->pin_slc] <
-                    model->format.macs)
-                  model->depth[model->pin_slc - 1]++;
-              } else if (model->pin_slc ==
-                         model->format.pin_num) { // last pin only limited by
-                // the previous one
-                if (model->depth[model->pin_slc - 1] -
-                        model->depth[model->pin_slc - 2] <
-                    model->format.macs) {
-                  model->depth[model->pin_slc - 1]++;
-                }
-              } else {
-                if (model->depth[model->pin_slc - 1] -
-                            model->depth[model->pin_slc] <
-                        model->format.macs &&
-                    model->depth[model->pin_slc - 1] -
-                            model->depth[model->pin_slc - 2] <
-                        model->format.macs) {
-                  model->depth[model->pin_slc - 1]++;
-                }
-              }
-            }
-          },
-          redraw);
-      break;
+
+    int level_contour_px =
+        (int)round((my_format.last_pin_inch + my_format.elbow_inch) / inches_per_px);
+    int elbow_px = (int)round(my_format.elbow_inch / inches_per_px);
+    canvas_draw_line(canvas, 0, 62, level_contour_px, 62);
+    canvas_draw_line(canvas, level_contour_px, 62, level_contour_px + elbow_px, 62 - elbow_px);
+
+    if(my_format.stop == 2) {
+        // Draw a line using level_contour_px if stop equals 2 elbow must be firt pin inch
+        canvas_draw_line(canvas, level_contour_px, top_contour_px, level_contour_px, 63);
+    } else {
+        // Otherwise, draw a default line
+        canvas_draw_line(canvas, 0, top_contour_px, 0, 63);
     }
-    default:
-      // Handle other keys or do nothing
-      break;
+
+    int slc_pin_px = (int)round(
+        (my_format.first_pin_inch + (my_model->pin_slc - 1) * my_format.pin_increment_inch) /
+        inches_per_px);
+    canvas_draw_icon(canvas, slc_pin_px - 2, top_contour_px - 25, &I_arrow_down);
+
+    furi_string_printf(buffer, "%s", my_format.format_name);
+    canvas_draw_str(canvas, 100, 10, furi_string_get_cstr(buffer));
+    furi_string_free(buffer);
+}
+
+static bool key_copier_view_measure_input_callback(InputEvent* event, void* context) {
+    KeyCopierApp* app = (KeyCopierApp*)context;
+    if(event->type == InputTypeShort) {
+        switch(event->key) {
+        case InputKeyLeft: {
+            bool redraw = true;
+            with_view_model(
+                app->view_measure,
+                KeyCopierModel * model,
+                {
+                    if(model->pin_slc > 1) {
+                        model->pin_slc--;
+                    }
+                },
+                redraw);
+            break;
+        }
+        case InputKeyRight: {
+            bool redraw = true;
+            with_view_model(
+                app->view_measure,
+                KeyCopierModel * model,
+                {
+                    if(model->pin_slc < model->format.pin_num) {
+                        model->pin_slc++;
+                    }
+                },
+                redraw);
+            break;
+        }
+        case InputKeyUp: {
+            bool redraw = true;
+            with_view_model(
+                app->view_measure,
+                KeyCopierModel * model,
+                {
+                    if(model->depth[model->pin_slc - 1] > model->format.min_depth_ind) {
+                        if(model->pin_slc == 1) { // first pin only limited by the next one
+                            if(model->depth[model->pin_slc] - model->depth[model->pin_slc - 1] <
+                               model->format.macs)
+                                model->depth[model->pin_slc - 1]--;
+                        } else if(model->pin_slc == model->format.pin_num) { // last pin only limited by
+                            // the previous one
+                            if(model->depth[model->pin_slc - 2] -
+                                   model->depth[model->pin_slc - 1] <
+                               model->format.macs) {
+                                model->depth[model->pin_slc - 1]--;
+                            }
+                        } else {
+                            if(model->depth[model->pin_slc] - model->depth[model->pin_slc - 1] <
+                                   model->format.macs &&
+                               model->depth[model->pin_slc - 2] -
+                                       model->depth[model->pin_slc - 1] <
+                                   model->format.macs) {
+                                model->depth[model->pin_slc - 1]--;
+                            }
+                        }
+                    }
+                },
+                redraw);
+            break;
+        }
+        case InputKeyDown: {
+            bool redraw = true;
+            with_view_model(
+                app->view_measure,
+                KeyCopierModel * model,
+                {
+                    if(model->depth[model->pin_slc - 1] < model->format.max_depth_ind) {
+                        if(model->pin_slc == 1) { // first pin only limited by the next one
+                            if(model->depth[model->pin_slc - 1] - model->depth[model->pin_slc] <
+                               model->format.macs)
+                                model->depth[model->pin_slc - 1]++;
+                        } else if(model->pin_slc == model->format.pin_num) { // last pin only limited by
+                            // the previous one
+                            if(model->depth[model->pin_slc - 1] -
+                                   model->depth[model->pin_slc - 2] <
+                               model->format.macs) {
+                                model->depth[model->pin_slc - 1]++;
+                            }
+                        } else {
+                            if(model->depth[model->pin_slc - 1] - model->depth[model->pin_slc] <
+                                   model->format.macs &&
+                               model->depth[model->pin_slc - 1] -
+                                       model->depth[model->pin_slc - 2] <
+                                   model->format.macs) {
+                                model->depth[model->pin_slc - 1]++;
+                            }
+                        }
+                    }
+                },
+                redraw);
+            break;
+        }
+        default:
+            // Handle other keys or do nothing
+            break;
+        }
     }
-  }
 
-  return false;
+    return false;
 }
 
-static KeyCopierApp *key_copier_app_alloc() {
-  KeyCopierApp *app = (KeyCopierApp *)malloc(sizeof(KeyCopierApp));
-
-  Gui *gui = furi_record_open(RECORD_GUI);
-
-  app->view_dispatcher = view_dispatcher_alloc();
-  view_dispatcher_attach_to_gui(app->view_dispatcher, gui,
-                                ViewDispatcherTypeFullscreen);
-  view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
-  app->dialogs = furi_record_open(RECORD_DIALOGS);
-  app->file_path = furi_string_alloc();
-  app->submenu = submenu_alloc();
-  submenu_add_item(app->submenu, "Measure", KeyCopierSubmenuIndexMeasure,
-                   key_copier_submenu_callback, app);
-  submenu_add_item(app->submenu, "Config", KeyCopierSubmenuIndexConfigure,
-                   key_copier_submenu_callback, app);
-  submenu_add_item(app->submenu, "Save", KeyCopierSubmenuIndexSave,
-                   key_copier_submenu_callback, app);
-  submenu_add_item(app->submenu, "Load", KeyCopierSubmenuIndexLoad,
-                   key_copier_submenu_callback, app);
-  submenu_add_item(app->submenu, "About", KeyCopierSubmenuIndexAbout,
-                   key_copier_submenu_callback, app);
-  view_set_previous_callback(submenu_get_view(app->submenu),
-                             key_copier_navigation_exit_callback);
-  view_dispatcher_add_view(app->view_dispatcher, KeyCopierViewSubmenu,
-                           submenu_get_view(app->submenu));
-  view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewSubmenu);
-
-  app->text_input = text_input_alloc();
-  view_dispatcher_add_view(app->view_dispatcher, KeyCopierViewTextInput,
-                           text_input_get_view(app->text_input));
-  app->temp_buffer_size = 32;
-  app->temp_buffer = (char *)malloc(app->temp_buffer_size);
-  app->temp_buffer = "";
-
-  app->view_measure = view_alloc();
-  view_set_draw_callback(app->view_measure,
-                         key_copier_view_measure_draw_callback);
-  view_set_input_callback(app->view_measure,
-                          key_copier_view_measure_input_callback);
-  view_set_previous_callback(app->view_measure,
-                             key_copier_navigation_submenu_callback);
-  view_set_context(app->view_measure, app);
-  view_allocate_model(app->view_measure, ViewModelTypeLockFree,
-                      sizeof(KeyCopierModel));
-  KeyCopierModel *model = view_get_model(app->view_measure);
-
-  initialize_model(model);
-  view_dispatcher_add_view(app->view_dispatcher, KeyCopierViewMeasure,
-                           app->view_measure);
-
-  app->variable_item_list_config = variable_item_list_alloc();
-  app->view_config_e = view_alloc();
-  view_set_context(app->view_config_e, app);
-  view_set_previous_callback(app->view_config_e,
-                             key_copier_navigation_submenu_callback);
-  view_set_enter_callback(app->view_config_e, key_copier_config_enter_callback);
-  view_dispatcher_add_view(app->view_dispatcher, KeyCopierViewConfigure_e,
-                           app->view_config_e);
-
-  View *view_buffer = view_alloc();
-  view_dispatcher_add_view(app->view_dispatcher, KeyCopierViewConfigure_i,
-                           view_buffer);
-
-  app->view_save = view_alloc();
-  view_set_context(app->view_save, app);
-  view_set_enter_callback(app->view_save, key_copier_view_save_callback);
-  view_set_previous_callback(app->view_save,
-                             key_copier_navigation_submenu_callback);
-  view_dispatcher_add_view(app->view_dispatcher, KeyCopierViewSave,
-                           app->view_save);
-
-  app->view_load = view_alloc();
-  view_set_context(app->view_load, app);
-  view_set_enter_callback(app->view_load, key_copier_view_load_callback);
-  view_set_previous_callback(app->view_load,
-                             key_copier_navigation_submenu_callback);
-  view_dispatcher_add_view(app->view_dispatcher, KeyCopierViewLoad,
-                           app->view_load);
-
-  app->widget_about = widget_alloc();
-  widget_add_text_scroll_element(
-      app->widget_about, 0, 0, 128, 64,
-      "Key Maker App 1.0\nAuthor: @Torron\n\nTo measure your key:\n\n1. Place "
-      "it on top of the screen.\n\n2. Use the contour to align your key.\n\n3. "
-      "Adjust each pin's depth until they match. It's easier if you look with "
-      "one eye closed.\n\nGithub: github.com/zinongli/KeyCopier \n\nSpecial "
-      "thanks to Derek Jamison's Skeleton App Template.");
-  view_set_previous_callback(widget_get_view(app->widget_about),
-                             key_copier_navigation_submenu_callback);
-  view_dispatcher_add_view(app->view_dispatcher, KeyCopierViewAbout,
-                           widget_get_view(app->widget_about));
-
-  app->notifications = furi_record_open(RECORD_NOTIFICATION);
+static KeyCopierApp* key_copier_app_alloc() {
+    KeyCopierApp* app = (KeyCopierApp*)malloc(sizeof(KeyCopierApp));
+
+    Gui* gui = furi_record_open(RECORD_GUI);
+
+    app->view_dispatcher = view_dispatcher_alloc();
+    view_dispatcher_attach_to_gui(app->view_dispatcher, gui, ViewDispatcherTypeFullscreen);
+    view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
+    app->dialogs = furi_record_open(RECORD_DIALOGS);
+    app->file_path = furi_string_alloc();
+    app->submenu = submenu_alloc();
+    submenu_add_item(
+        app->submenu, "Measure", KeyCopierSubmenuIndexMeasure, key_copier_submenu_callback, app);
+    submenu_add_item(
+        app->submenu, "Config", KeyCopierSubmenuIndexConfigure, key_copier_submenu_callback, app);
+    submenu_add_item(
+        app->submenu, "Save", KeyCopierSubmenuIndexSave, key_copier_submenu_callback, app);
+    submenu_add_item(
+        app->submenu, "Load", KeyCopierSubmenuIndexLoad, key_copier_submenu_callback, app);
+    submenu_add_item(
+        app->submenu, "About", KeyCopierSubmenuIndexAbout, key_copier_submenu_callback, app);
+    view_set_previous_callback(
+        submenu_get_view(app->submenu), key_copier_navigation_exit_callback);
+    view_dispatcher_add_view(
+        app->view_dispatcher, KeyCopierViewSubmenu, submenu_get_view(app->submenu));
+    view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewSubmenu);
+
+    app->text_input = text_input_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher, KeyCopierViewTextInput, text_input_get_view(app->text_input));
+    app->temp_buffer_size = 32;
+    app->temp_buffer = (char*)malloc(app->temp_buffer_size);
+    app->temp_buffer = "";
+
+    app->view_measure = view_alloc();
+    view_set_draw_callback(app->view_measure, key_copier_view_measure_draw_callback);
+    view_set_input_callback(app->view_measure, key_copier_view_measure_input_callback);
+    view_set_previous_callback(app->view_measure, key_copier_navigation_submenu_callback);
+    view_set_context(app->view_measure, app);
+    view_allocate_model(app->view_measure, ViewModelTypeLockFree, sizeof(KeyCopierModel));
+    KeyCopierModel* model = view_get_model(app->view_measure);
+
+    initialize_model(model);
+    view_dispatcher_add_view(app->view_dispatcher, KeyCopierViewMeasure, app->view_measure);
+
+    app->variable_item_list_config = variable_item_list_alloc();
+    app->view_config_e = view_alloc();
+    view_set_context(app->view_config_e, app);
+    view_set_previous_callback(app->view_config_e, key_copier_navigation_submenu_callback);
+    view_set_enter_callback(app->view_config_e, key_copier_config_enter_callback);
+    view_dispatcher_add_view(app->view_dispatcher, KeyCopierViewConfigure_e, app->view_config_e);
+
+    View* view_buffer = view_alloc();
+    view_dispatcher_add_view(app->view_dispatcher, KeyCopierViewConfigure_i, view_buffer);
+
+    app->view_save = view_alloc();
+    view_set_context(app->view_save, app);
+    view_set_enter_callback(app->view_save, key_copier_view_save_callback);
+    view_set_previous_callback(app->view_save, key_copier_navigation_submenu_callback);
+    view_dispatcher_add_view(app->view_dispatcher, KeyCopierViewSave, app->view_save);
+
+    app->view_load = view_alloc();
+    view_set_context(app->view_load, app);
+    view_set_enter_callback(app->view_load, key_copier_view_load_callback);
+    view_set_previous_callback(app->view_load, key_copier_navigation_submenu_callback);
+    view_dispatcher_add_view(app->view_dispatcher, KeyCopierViewLoad, app->view_load);
+
+    app->widget_about = widget_alloc();
+    widget_add_text_scroll_element(
+        app->widget_about,
+        0,
+        0,
+        128,
+        64,
+        "Key Maker App 1.0\nAuthor: @Torron\n\nTo measure your key:\n\n1. Place "
+        "it on top of the screen.\n\n2. Use the contour to align your key.\n\n3. "
+        "Adjust each pin's depth until they match. It's easier if you look with "
+        "one eye closed.\n\nGithub: github.com/zinongli/KeyCopier \n\nSpecial "
+        "thanks to Derek Jamison's Skeleton App Template.");
+    view_set_previous_callback(
+        widget_get_view(app->widget_about), key_copier_navigation_submenu_callback);
+    view_dispatcher_add_view(
+        app->view_dispatcher, KeyCopierViewAbout, widget_get_view(app->widget_about));
+
+    app->notifications = furi_record_open(RECORD_NOTIFICATION);
 
 #ifdef BACKLIGHT_ON
-  notification_message(app->notifications,
-                       &sequence_display_backlight_enforce_on);
+    notification_message(app->notifications, &sequence_display_backlight_enforce_on);
 #endif
 
-  return app;
+    return app;
 }
 
-static void key_copier_app_free(KeyCopierApp *app) {
+static void key_copier_app_free(KeyCopierApp* app) {
 #ifdef BACKLIGHT_ON
-  notification_message(app->notifications,
-                       &sequence_display_backlight_enforce_auto);
+    notification_message(app->notifications, &sequence_display_backlight_enforce_auto);
 #endif
-  furi_record_close(RECORD_NOTIFICATION);
-
-  view_dispatcher_remove_view(app->view_dispatcher, KeyCopierViewTextInput);
-  text_input_free(app->text_input);
-  free(app->temp_buffer);
-  view_dispatcher_remove_view(app->view_dispatcher, KeyCopierViewAbout);
-  widget_free(app->widget_about);
-  view_dispatcher_remove_view(app->view_dispatcher, KeyCopierViewMeasure);
-  with_view_model(
-      app->view_measure, KeyCopierModel * model,
-      {
-        if (model->depth != NULL) {
-          free(model->depth);
-        }
-      },
-      false);
-  view_free(app->view_measure);
-  view_dispatcher_remove_view(app->view_dispatcher, KeyCopierViewConfigure_e);
-  view_dispatcher_remove_view(app->view_dispatcher, KeyCopierViewConfigure_i);
-  view_dispatcher_remove_view(app->view_dispatcher, KeyCopierViewSave);
-  view_dispatcher_remove_view(app->view_dispatcher, KeyCopierViewLoad);
-  variable_item_list_free(app->variable_item_list_config);
-  view_dispatcher_remove_view(app->view_dispatcher, KeyCopierViewSubmenu);
-  submenu_free(app->submenu);
-  view_dispatcher_free(app->view_dispatcher);
-  furi_record_close(RECORD_GUI);
-
-  free(app);
+    furi_record_close(RECORD_NOTIFICATION);
+
+    view_dispatcher_remove_view(app->view_dispatcher, KeyCopierViewTextInput);
+    text_input_free(app->text_input);
+    free(app->temp_buffer);
+    view_dispatcher_remove_view(app->view_dispatcher, KeyCopierViewAbout);
+    widget_free(app->widget_about);
+    view_dispatcher_remove_view(app->view_dispatcher, KeyCopierViewMeasure);
+    with_view_model(
+        app->view_measure,
+        KeyCopierModel * model,
+        {
+            if(model->depth != NULL) {
+                free(model->depth);
+            }
+        },
+        false);
+    view_free(app->view_measure);
+    view_dispatcher_remove_view(app->view_dispatcher, KeyCopierViewConfigure_e);
+    view_dispatcher_remove_view(app->view_dispatcher, KeyCopierViewConfigure_i);
+    view_dispatcher_remove_view(app->view_dispatcher, KeyCopierViewSave);
+    view_dispatcher_remove_view(app->view_dispatcher, KeyCopierViewLoad);
+    variable_item_list_free(app->variable_item_list_config);
+    view_dispatcher_remove_view(app->view_dispatcher, KeyCopierViewSubmenu);
+    submenu_free(app->submenu);
+    view_dispatcher_free(app->view_dispatcher);
+    furi_record_close(RECORD_GUI);
+
+    free(app);
 }
 
-int32_t main_key_copier_app(void *_p) {
-  UNUSED(_p);
+int32_t main_key_copier_app(void* _p) {
+    UNUSED(_p);
 
-  KeyCopierApp *app = key_copier_app_alloc();
-  view_dispatcher_run(app->view_dispatcher);
+    KeyCopierApp* app = key_copier_app_alloc();
+    view_dispatcher_run(app->view_dispatcher);
 
-  key_copier_app_free(app);
-  return 0;
+    key_copier_app_free(app);
+    return 0;
 }