| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494 |
- #include "../barcode_app.h"
- #include "create_view.h"
- #include <math.h>
- #define LINE_HEIGHT 16
- #define TEXT_PADDING 4
- #define TOTAL_MENU_ITEMS 5
- typedef enum {
- TypeMenuItem,
- FileNameMenuItem,
- BarcodeDataMenuItem,
- SaveMenuButton,
- DeleteMenuButton
- } MenuItems;
- /**
- * Took this function from blackjack
- * @author @teeebor
- */
- void draw_menu_item(
- Canvas* const canvas,
- const char* text,
- const char* value,
- int y,
- bool left_caret,
- bool right_caret,
- bool selected) {
- UNUSED(selected);
- if(y < 0 || y >= 64) {
- return;
- }
- if(selected) {
- canvas_set_color(canvas, ColorBlack);
- canvas_draw_box(canvas, 0, y, 123, LINE_HEIGHT);
- canvas_set_color(canvas, ColorWhite);
- }
- canvas_draw_str_aligned(canvas, 4, y + TEXT_PADDING, AlignLeft, AlignTop, text);
- if(left_caret) {
- canvas_draw_str_aligned(canvas, 60, y + TEXT_PADDING, AlignLeft, AlignTop, "<");
- }
- canvas_draw_str_aligned(canvas, 90, y + TEXT_PADDING, AlignCenter, AlignTop, value);
- if(right_caret) {
- canvas_draw_str_aligned(canvas, 120, y + TEXT_PADDING, AlignRight, AlignTop, ">");
- }
- canvas_set_color(canvas, ColorBlack);
- }
- void draw_button(Canvas* const canvas, const char* text, int y, bool selected) {
- if(selected) {
- canvas_set_color(canvas, ColorBlack);
- canvas_draw_box(canvas, 0, y, 123, LINE_HEIGHT);
- canvas_set_color(canvas, ColorWhite);
- }
- canvas_draw_str_aligned(canvas, 64, y + TEXT_PADDING, AlignCenter, AlignTop, text);
- canvas_set_color(canvas, ColorBlack);
- }
- static void app_draw_callback(Canvas* canvas, void* ctx) {
- furi_assert(ctx);
- CreateViewModel* create_view_model = ctx;
- BarcodeTypeObj* type_obj = create_view_model->barcode_type;
- if(create_view_model->barcode_type == NULL) {
- return;
- }
- BarcodeType selected_type = type_obj->type;
- int selected_menu_item = create_view_model->selected_menu_item;
- int total_menu_items = create_view_model->mode == EditMode ? TOTAL_MENU_ITEMS :
- TOTAL_MENU_ITEMS - 1;
- int startY = 0;
- //the menu items index that is/would be in view
- //int current_last_menu_item = selected_menu_item + 3;
- if(selected_menu_item > 1) {
- int offset = 2;
- if(selected_menu_item + offset > total_menu_items) {
- offset = 3;
- }
- startY -= (LINE_HEIGHT * (selected_menu_item - offset));
- }
- //ensure that the scroll height is atleast 1
- int scrollHeight = ceil(64.0 / total_menu_items);
- int scrollPos = scrollHeight * selected_menu_item;
- canvas_set_color(canvas, ColorBlack);
- //draw the scroll bar box
- canvas_draw_box(canvas, 125, scrollPos, 3, scrollHeight);
- //draw the scroll bar track
- canvas_draw_box(canvas, 126, 0, 1, 64);
- draw_menu_item(
- canvas,
- "Type",
- type_obj->name,
- TypeMenuItem * LINE_HEIGHT + startY,
- selected_type > 0,
- selected_type < NUMBER_OF_BARCODE_TYPES - 2,
- selected_menu_item == TypeMenuItem);
- draw_menu_item(
- canvas,
- "Name",
- furi_string_empty(create_view_model->file_name) ?
- "--" :
- furi_string_get_cstr(create_view_model->file_name),
- FileNameMenuItem * LINE_HEIGHT + startY,
- false,
- false,
- selected_menu_item == FileNameMenuItem);
- draw_menu_item(
- canvas,
- "Data",
- furi_string_empty(create_view_model->barcode_data) ?
- "--" :
- furi_string_get_cstr(create_view_model->barcode_data),
- BarcodeDataMenuItem * LINE_HEIGHT + startY,
- false,
- false,
- selected_menu_item == BarcodeDataMenuItem);
- draw_button(
- canvas,
- "Save",
- SaveMenuButton * LINE_HEIGHT + startY,
- selected_menu_item == SaveMenuButton);
- if(create_view_model->mode == EditMode) {
- draw_button(
- canvas,
- "Delete",
- DeleteMenuButton * LINE_HEIGHT + startY,
- selected_menu_item == DeleteMenuButton);
- }
- }
- void text_input_callback(void* ctx) {
- CreateView* create_view_object = ctx;
- with_view_model(
- create_view_object->view,
- CreateViewModel * model,
- {
- if(create_view_object->setter == FileNameSetter) {
- furi_string_set_str(model->file_name, create_view_object->input);
- }
- if(create_view_object->setter == BarcodeDataSetter) {
- furi_string_set_str(model->barcode_data, create_view_object->input);
- }
- },
- true);
- view_dispatcher_switch_to_view(
- create_view_object->barcode_app->view_dispatcher, CreateBarcodeView);
- }
- static bool app_input_callback(InputEvent* input_event, void* ctx) {
- furi_assert(ctx);
- if(input_event->key == InputKeyBack) {
- return false;
- }
- CreateView* create_view_object = ctx;
- //get the currently selected menu item from the model
- int selected_menu_item = 0;
- BarcodeTypeObj* barcode_type = NULL;
- FuriString* file_name;
- FuriString* barcode_data;
- CreateMode mode;
- with_view_model(
- create_view_object->view,
- CreateViewModel * model,
- {
- selected_menu_item = model->selected_menu_item;
- barcode_type = model->barcode_type;
- file_name = model->file_name;
- barcode_data = model->barcode_data;
- mode = model->mode;
- },
- true);
- int total_menu_items = mode == EditMode ? TOTAL_MENU_ITEMS : TOTAL_MENU_ITEMS - 1;
- if(input_event->type == InputTypePress) {
- if(input_event->key == InputKeyUp && selected_menu_item > 0) {
- selected_menu_item--;
- } else if(input_event->key == InputKeyDown && selected_menu_item < total_menu_items - 1) {
- selected_menu_item++;
- } else if(input_event->key == InputKeyLeft) {
- if(selected_menu_item == TypeMenuItem && barcode_type != NULL) { //Select Barcode Type
- if(barcode_type->type > 0) {
- barcode_type = barcode_type_objs[barcode_type->type - 1];
- }
- }
- } else if(input_event->key == InputKeyRight) {
- if(selected_menu_item == TypeMenuItem && barcode_type != NULL) { //Select Barcode Type
- if(barcode_type->type < NUMBER_OF_BARCODE_TYPES - 2) {
- barcode_type = barcode_type_objs[barcode_type->type + 1];
- }
- }
- } else if(input_event->key == InputKeyOk) {
- if(selected_menu_item == FileNameMenuItem && barcode_type != NULL) {
- create_view_object->setter = FileNameSetter;
- snprintf(
- create_view_object->input,
- sizeof(create_view_object->input),
- "%s",
- furi_string_get_cstr(file_name));
- text_input_set_result_callback(
- create_view_object->barcode_app->text_input,
- text_input_callback,
- create_view_object,
- create_view_object->input,
- TEXT_BUFFER_SIZE - BARCODE_EXTENSION_LENGTH, //remove the barcode length
- //clear default text
- false);
- text_input_set_header_text(
- create_view_object->barcode_app->text_input, "File Name");
- view_dispatcher_switch_to_view(
- create_view_object->barcode_app->view_dispatcher, TextInputView);
- }
- if(selected_menu_item == BarcodeDataMenuItem && barcode_type != NULL) {
- create_view_object->setter = BarcodeDataSetter;
- snprintf(
- create_view_object->input,
- sizeof(create_view_object->input),
- "%s",
- furi_string_get_cstr(barcode_data));
- text_input_set_result_callback(
- create_view_object->barcode_app->text_input,
- text_input_callback,
- create_view_object,
- create_view_object->input,
- TEXT_BUFFER_SIZE,
- //clear default text
- false);
- text_input_set_header_text(
- create_view_object->barcode_app->text_input, "Barcode Data");
- view_dispatcher_switch_to_view(
- create_view_object->barcode_app->view_dispatcher, TextInputView);
- }
- if(selected_menu_item == SaveMenuButton && barcode_type != NULL) {
- save_barcode(create_view_object);
- }
- if(selected_menu_item == DeleteMenuButton && barcode_type != NULL) {
- if(mode == EditMode) {
- remove_barcode(create_view_object);
- } else if(mode == NewMode) {
- view_dispatcher_switch_to_view(
- create_view_object->barcode_app->view_dispatcher, MainMenuView);
- }
- }
- }
- }
- //change the currently selected menu item
- with_view_model(
- create_view_object->view,
- CreateViewModel * model,
- {
- model->selected_menu_item = selected_menu_item;
- model->barcode_type = barcode_type;
- },
- true);
- return true;
- }
- CreateView* create_view_allocate(BarcodeApp* barcode_app) {
- furi_assert(barcode_app);
- CreateView* create_view_object = malloc(sizeof(CreateView));
- create_view_object->view = view_alloc();
- create_view_object->barcode_app = barcode_app;
- view_set_context(create_view_object->view, create_view_object);
- view_allocate_model(create_view_object->view, ViewModelTypeLocking, sizeof(CreateViewModel));
- view_set_draw_callback(create_view_object->view, app_draw_callback);
- view_set_input_callback(create_view_object->view, app_input_callback);
- return create_view_object;
- }
- void create_view_free_model(CreateView* create_view_object) {
- with_view_model(
- create_view_object->view,
- CreateViewModel * model,
- {
- if(model->file_path != NULL) {
- furi_string_free(model->file_path);
- }
- if(model->file_name != NULL) {
- furi_string_free(model->file_name);
- }
- if(model->barcode_data != NULL) {
- furi_string_free(model->barcode_data);
- }
- },
- true);
- }
- void remove_barcode(CreateView* create_view_object) {
- Storage* storage = furi_record_open(RECORD_STORAGE);
- bool success = false;
- with_view_model(
- create_view_object->view,
- CreateViewModel * model,
- {
- FURI_LOG_I(TAG, "Attempting to remove file");
- if(model->file_path != NULL) {
- FURI_LOG_I(TAG, "Removing File: %s", furi_string_get_cstr(model->file_path));
- if(storage_simply_remove(storage, furi_string_get_cstr(model->file_path))) {
- FURI_LOG_I(
- TAG,
- "File: \"%s\" was successfully removed",
- furi_string_get_cstr(model->file_path));
- success = true;
- } else {
- FURI_LOG_E(TAG, "Unable to remove file!");
- success = false;
- }
- } else {
- FURI_LOG_E(TAG, "Could not remove barcode file");
- success = false;
- }
- },
- true);
- furi_record_close(RECORD_STORAGE);
- with_view_model(
- create_view_object->barcode_app->message_view->view,
- MessageViewModel * model,
- {
- if(success) {
- model->message = "File Deleted";
- } else {
- model->message = "Could not delete file";
- }
- },
- true);
- view_dispatcher_switch_to_view(
- create_view_object->barcode_app->view_dispatcher, MessageErrorView);
- }
- void save_barcode(CreateView* create_view_object) {
- BarcodeTypeObj* barcode_type = NULL;
- FuriString* file_path; //this may be empty
- FuriString* file_name;
- FuriString* barcode_data;
- CreateMode mode;
- with_view_model(
- create_view_object->view,
- CreateViewModel * model,
- {
- file_path = model->file_path;
- file_name = model->file_name;
- barcode_data = model->barcode_data;
- barcode_type = model->barcode_type;
- mode = model->mode;
- },
- true);
- if(file_name == NULL || furi_string_empty(file_name)) {
- FURI_LOG_E(TAG, "File Name cannot be empty");
- return;
- }
- if(barcode_data == NULL || furi_string_empty(barcode_data)) {
- FURI_LOG_E(TAG, "Barcode Data cannot be empty");
- return;
- }
- if(barcode_type == NULL) {
- FURI_LOG_E(TAG, "Type not defined");
- return;
- }
- bool success = false;
- FuriString* full_file_path = furi_string_alloc_set(DEFAULT_USER_BARCODES);
- furi_string_push_back(full_file_path, '/');
- furi_string_cat(full_file_path, file_name);
- furi_string_cat_str(full_file_path, BARCODE_EXTENSION);
- Storage* storage = furi_record_open(RECORD_STORAGE);
- if(mode == EditMode) {
- if(!furi_string_empty(file_path)) {
- if(!furi_string_equal(file_path, full_file_path)) {
- FS_Error error = storage_common_rename(
- storage,
- furi_string_get_cstr(file_path),
- furi_string_get_cstr(full_file_path));
- if(error != FSE_OK) {
- FURI_LOG_E(TAG, "Rename error: %s", storage_error_get_desc(error));
- } else {
- FURI_LOG_I(TAG, "Rename Success");
- }
- }
- }
- }
- FlipperFormat* ff = flipper_format_file_alloc(storage);
- FURI_LOG_I(TAG, "Saving Barcode to: %s", furi_string_get_cstr(full_file_path));
- bool file_opened_status = false;
- if(mode == NewMode) {
- file_opened_status =
- flipper_format_file_open_new(ff, furi_string_get_cstr(full_file_path));
- } else if(mode == EditMode) {
- file_opened_status =
- flipper_format_file_open_always(ff, furi_string_get_cstr(full_file_path));
- }
- if(file_opened_status) {
- // Filetype: Barcode
- // Version: 1
- // # Types - UPC-A, EAN-8, EAN-13, CODE-39
- // Type: CODE-39
- // Data: AB
- flipper_format_write_string_cstr(ff, "Filetype", "Barcode");
- flipper_format_write_string_cstr(ff, "Version", FILE_VERSION);
- flipper_format_write_comment_cstr(
- ff, "Types - UPC-A, EAN-8, EAN-13, CODE-39, CODE-128, Codabar");
- flipper_format_write_string_cstr(ff, "Type", barcode_type->name);
- flipper_format_write_string_cstr(ff, "Data", furi_string_get_cstr(barcode_data));
- success = true;
- } else {
- FURI_LOG_E(TAG, "Save error");
- success = false;
- }
- furi_string_free(full_file_path);
- flipper_format_free(ff);
- furi_record_close(RECORD_STORAGE);
- with_view_model(
- create_view_object->barcode_app->message_view->view,
- MessageViewModel * model,
- {
- if(success) {
- model->message = "File Saved!";
- } else {
- model->message = "A saving error has occurred";
- }
- },
- true);
- view_dispatcher_switch_to_view(
- create_view_object->barcode_app->view_dispatcher, MessageErrorView);
- }
- void create_view_free(CreateView* create_view_object) {
- furi_assert(create_view_object);
- create_view_free_model(create_view_object);
- view_free(create_view_object->view);
- free(create_view_object);
- }
- View* create_get_view(CreateView* create_view_object) {
- furi_assert(create_view_object);
- return create_view_object->view;
- }
|