kPQ5z`%M)B0Xno
zJ;V7FgwIp?8!qqswYTBhjpPQ~8HfnK$^1a%+@59juUOt^pBD2MV(V9UHJH8P33ft*|iGXh-O*l}B63G!RV)
z9eV&(9?|{*i)$Mo4uloD;#QrdKS;1$8Mf=t7I}=&biPDPzIDq@n?2NZR
zsA^yO?QZj76MjjE4Vjx~+7d0_p2XD!b)V+(^UFMylS;wCDy7&f;A
zEUR_H!bX^B#`7@fj)E@&pbool=wVMDy10ZFN;)k!HS?QiqUrp4&TJ#GJ2QfWyw2_u
zn;5j?0J$#kVvHTe$UxV6EvFXWr{PWODK%!EB#PFaDR@iP&odL)g&Nzt(YxV$G)Z;b
zMUHJ6#~LWpTGcOUQ#k`-%tFhrGF|M`XCvdcvN50fCeUM`<>l=VwCONW?ghCYqgzvJ
zeuPKj^sh`)rFe;Yy`zCcJ@TMn0p*lTYq4uvuXrX(Qm9eQ4}Vqd*F|W>_jXoJRk%x6
z@BqXU0N);fgRw&Q5~4wsNAx?r#Na>a(U;fjS@qOJmtC%Ej?Aay)(g1wMgt!5HWv|H
z=WL^DpjIA9z~xnS0{;mricDER@%wu8X6^l-fkN1~h&ys`YZ=F!n$_e)rrEf)
z$^j-htx^#j*tkuEBdrDn)Y(WEnp9>2QgUEhReMrN-@8+$@ITR?-cSwctF^0Kb!iCm
zHB6bdFx-M>6N|ZmVH!rUu@H*-n*zs!-{YaAi`jj;RUEaMD~YlUKm5EtH*=iF9+68)
z2Bkt4q}U*b?46Ie9Xv5-xs!jXd(>N(O3qP|43(;DT~4`muF;{g&<{J~EfsE|Z8G}W
zH7C|T9QC}jmU=gr-ZWMqGopw2f_r;Z&-0RXZYTSoqH3MT%DPm3Sv>pCUu1
zl4@I?uVBV}0Rm?u)^1kThW>X4o}#iiN`ogj@(2Nx@;s=NDieIGGv$w{a
z_#U6Zh=k?V+Og0>uA(h_mF;-`e+7b!fHHLJ1eI`N1y=o(R9m`zegAW5
z2HWqO{TUjHIT#$KFfh1q;-PH&><;|>`}z3w>E{)q_NBkQ>7x8z(z1QxM&;*wzD7hp
zmznwe#p?}bWtr>G7rwqB7;fJ_v(oL&*Lw3}U$k^IdiTD4yxi_P^-<@H
zKUo=^=VDOsVqjRr!k}uGMS-v2W>+w^asLAucWW)t~#lw{dgg;Bx3M%^>bP0l+XkK2Z=AV
literal 0
HcmV?d00001
diff --git a/applications/external/barcode_gen/screenshots/Flipper Box Barcode.png b/applications/external/barcode_gen/screenshots/Flipper Box Barcode.png
new file mode 100644
index 0000000000000000000000000000000000000000..8dbd7d2a9c1b0564a1a2188e6de48fe9370ad426
GIT binary patch
literal 1372
zcmeAS@N?(olHy`uVBq!ia0y~yU;;8388|?c*QZDWAjMhW5n0T@z;^_M8K-LVNi#68
z@_D*AhE&XXd)M3VwE=^}MfN1iHT|v|?5;K6<0%!=419F!rEPl4Dzo{=UTEdb-t)Jv
z{vY##=e6J17!2AO7+g3R9H!u*t{i{EYw`N;>*w#^AAc>CYrF63E%)kq`=3jBRd379
z-s`?S_e)jy?Ka!>dtZHATWTxy@t&OQ;c(gGf{#D1`af6j{LRmQ7N6e9ozB1z$iyI^
zI!cWO!H`M?`TOtB-@N_dl<({3@82)~J@s|rtRCTSD|&^IQndW$us;^dx21lGx!qB@
zclEdI^F?m@|6f!WO;4S-@zV^;UF#x`Kk7^V9cszU&>_Uopuxz{QS~aF!Tq^>`q}OC
zBA<2qon`ue_w%3Sk$~yq>ajDi76?7FzF9ZuDnE;s&yBsGoVxYB
z>H2N@L_AKW^J5uTZKKS~}5{XBJZ&y8os_ov?b{P*>0yYPxoyXX8zo#$
z{h9gt{2Bvsn@6?Mg@5O)j2BYgfF$?abI_=KPCw;X0F^`vvZs1y6c9o=N(pl*O@i*eBpG%&FQh5>$Y!9k4^tp
tzSVHE5mM-0wqs^U&_fcySC0H=oN}tJOPWI=6Ifg_c)I$ztaD0e0suzQQWgLJ
literal 0
HcmV?d00001
diff --git a/applications/external/barcode_gen/views/barcode_view.c b/applications/external/barcode_gen/views/barcode_view.c
new file mode 100644
index 000000000..55ab52046
--- /dev/null
+++ b/applications/external/barcode_gen/views/barcode_view.c
@@ -0,0 +1,510 @@
+#include "../barcode_app.h"
+#include "barcode_view.h"
+#include "../encodings.h"
+
+/**
+ * @brief Draws a single bit from a barcode at a specified location
+ * @param canvas
+ * @param bit a 1 or a 0 to signify a bit of data
+ * @param x the top left x coordinate
+ * @param y the top left y coordinate
+ * @param width the width of the bit
+ * @param height the height of the bit
+ */
+static void draw_bit(Canvas* canvas, int bit, int x, int y, int width, int height) {
+ if(bit == 1) {
+ canvas_set_color(canvas, ColorBlack);
+ } else {
+ canvas_set_color(canvas, ColorWhite);
+ }
+ canvas_draw_box(canvas, x, y, width, height);
+}
+
+/**
+ *
+*/
+static void draw_error_str(Canvas* canvas, const char* error) {
+ canvas_clear(canvas);
+ canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignCenter, error);
+}
+
+/**
+ * @param bits a string of 1's and 0's
+ * @returns the x coordinate after the bits have been drawn, useful for drawing the next section of bits
+*/
+static int draw_bits(Canvas* canvas, const char* bits, int x, int y, int width, int height) {
+ int bits_length = strlen(bits);
+ for(int i = 0; i < bits_length; i++) {
+ char c = bits[i];
+ int num = c - '0';
+
+ draw_bit(canvas, num, x, y, width, height);
+
+ x += width;
+ }
+ return x;
+}
+
+/**
+ * Draws an EAN-8 type barcode, does not check if the barcode is valid
+ * @param canvas the canvas
+ * @param barcode_digits the digits in the barcode, must be 8 characters long
+*/
+static void draw_ean_8(Canvas* canvas, BarcodeData* barcode_data) {
+ FuriString* barcode_digits = barcode_data->correct_data;
+ BarcodeTypeObj* type_obj = barcode_data->type_obj;
+
+ int barcode_length = furi_string_size(barcode_digits);
+
+ int x = type_obj->start_pos;
+ int y = BARCODE_Y_START;
+ int width = 1;
+ int height = BARCODE_HEIGHT;
+
+ //the guard patterns for the beginning, center, ending
+ const char* end_bits = "101";
+ const char* center_bits = "01010";
+
+ //draw the starting guard pattern
+ x = draw_bits(canvas, end_bits, x, y, width, height + 5);
+
+ FuriString* code_part = furi_string_alloc();
+
+ //loop through each digit, find the encoding, and draw it
+ for(int i = 0; i < barcode_length; i++) {
+ char current_digit = furi_string_get_char(barcode_digits, i);
+
+ //the actual number and the index of the bits
+ int index = current_digit - '0';
+ //use the L-codes for the first 4 digits and the R-Codes for the last 4 digits
+ if(i <= 3) {
+ furi_string_set_str(code_part, UPC_EAN_L_CODES[index]);
+ } else {
+ furi_string_set_str(code_part, UPC_EAN_R_CODES[index]);
+ }
+
+ //convert the current_digit char into a string so it can be printed
+ char current_digit_string[2];
+ snprintf(current_digit_string, 2, "%c", current_digit);
+
+ //set the canvas color to black to print the digit
+ canvas_set_color(canvas, ColorBlack);
+ canvas_draw_str(canvas, x + 1, y + height + 8, current_digit_string);
+
+ //draw the bits of the barcode
+ x = draw_bits(canvas, furi_string_get_cstr(code_part), x, y, width, height);
+
+ //if the index has reached 3, that means 4 digits have been drawn and now draw the center guard pattern
+ if(i == 3) {
+ x = draw_bits(canvas, center_bits, x, y, width, height + 5);
+ }
+ }
+ furi_string_free(code_part);
+
+ //draw the ending guard pattern
+ x = draw_bits(canvas, end_bits, x, y, width, height + 5);
+}
+
+static void draw_ean_13(Canvas* canvas, BarcodeData* barcode_data) {
+ FuriString* barcode_digits = barcode_data->correct_data;
+ BarcodeTypeObj* type_obj = barcode_data->type_obj;
+
+ int barcode_length = furi_string_size(barcode_digits);
+
+ int x = type_obj->start_pos;
+ int y = BARCODE_Y_START;
+ int width = 1;
+ int height = BARCODE_HEIGHT;
+
+ //the guard patterns for the beginning, center, ending
+ const char* end_bits = "101";
+ const char* center_bits = "01010";
+
+ //draw the starting guard pattern
+ x = draw_bits(canvas, end_bits, x, y, width, height + 5);
+
+ FuriString* left_structure = furi_string_alloc();
+ FuriString* code_part = furi_string_alloc();
+
+ //loop through each digit, find the encoding, and draw it
+ for(int i = 0; i < barcode_length; i++) {
+ char current_digit = furi_string_get_char(barcode_digits, i);
+ int index = current_digit - '0';
+
+ if(i == 0) {
+ furi_string_set_str(left_structure, EAN_13_STRUCTURE_CODES[index]);
+
+ //convert the current_digit char into a string so it can be printed
+ char current_digit_string[2];
+ snprintf(current_digit_string, 2, "%c", current_digit);
+
+ //set the canvas color to black to print the digit
+ canvas_set_color(canvas, ColorBlack);
+ canvas_draw_str(canvas, x - 10, y + height + 8, current_digit_string);
+
+ continue;
+ } else {
+ //use the L-codes for the first 6 digits and the R-Codes for the last 6 digits
+ if(i <= 6) {
+ //get the encoding type at the current barcode bit position
+ char encoding_type = furi_string_get_char(left_structure, i - 1);
+ if(encoding_type == 'L') {
+ furi_string_set_str(code_part, UPC_EAN_L_CODES[index]);
+ } else {
+ furi_string_set_str(code_part, EAN_G_CODES[index]);
+ }
+ } else {
+ furi_string_set_str(code_part, UPC_EAN_R_CODES[index]);
+ }
+
+ //convert the current_digit char into a string so it can be printed
+ char current_digit_string[2];
+ snprintf(current_digit_string, 2, "%c", current_digit);
+
+ //set the canvas color to black to print the digit
+ canvas_set_color(canvas, ColorBlack);
+ canvas_draw_str(canvas, x + 1, y + height + 8, current_digit_string);
+
+ //draw the bits of the barcode
+ x = draw_bits(canvas, furi_string_get_cstr(code_part), x, y, width, height);
+
+ //if the index has reached 6, that means 6 digits have been drawn and we now draw the center guard pattern
+ if(i == 6) {
+ x = draw_bits(canvas, center_bits, x, y, width, height + 5);
+ }
+ }
+ }
+
+ furi_string_free(left_structure);
+ furi_string_free(code_part);
+
+ //draw the ending guard pattern
+ x = draw_bits(canvas, end_bits, x, y, width, height + 5);
+}
+
+/**
+ * Draw a UPC-A barcode
+*/
+static void draw_upc_a(Canvas* canvas, BarcodeData* barcode_data) {
+ FuriString* barcode_digits = barcode_data->correct_data;
+ BarcodeTypeObj* type_obj = barcode_data->type_obj;
+
+ int barcode_length = furi_string_size(barcode_digits);
+
+ int x = type_obj->start_pos;
+ int y = BARCODE_Y_START;
+ int width = 1;
+ int height = BARCODE_HEIGHT;
+
+ //the guard patterns for the beginning, center, ending
+ char* end_bits = "101";
+ char* center_bits = "01010";
+
+ //draw the starting guard pattern
+ x = draw_bits(canvas, end_bits, x, y, width, height + 5);
+
+ FuriString* code_part = furi_string_alloc();
+
+ //loop through each digit, find the encoding, and draw it
+ for(int i = 0; i < barcode_length; i++) {
+ char current_digit = furi_string_get_char(barcode_digits, i);
+ int index = current_digit - '0'; //convert the number into an int (also the index)
+
+ //use the L-codes for the first 6 digits and the R-Codes for the last 6 digits
+ if(i <= 5) {
+ furi_string_set_str(code_part, UPC_EAN_L_CODES[index]);
+ } else {
+ furi_string_set_str(code_part, UPC_EAN_R_CODES[index]);
+ }
+
+ //convert the current_digit char into a string so it can be printed
+ char current_digit_string[2];
+ snprintf(current_digit_string, 2, "%c", current_digit);
+
+ //set the canvas color to black to print the digit
+ canvas_set_color(canvas, ColorBlack);
+ canvas_draw_str(canvas, x + 1, y + height + 8, current_digit_string);
+
+ //draw the bits of the barcode
+ x = draw_bits(canvas, furi_string_get_cstr(code_part), x, y, width, height);
+
+ //if the index has reached 6, that means 6 digits have been drawn and we now draw the center guard pattern
+ if(i == 5) {
+ x = draw_bits(canvas, center_bits, x, y, width, height + 5);
+ }
+ }
+
+ furi_string_free(code_part);
+
+ //draw the ending guard pattern
+ x = draw_bits(canvas, end_bits, x, y, width, height + 5);
+}
+
+static void draw_code_39(Canvas* canvas, BarcodeData* barcode_data) {
+ FuriString* raw_data = barcode_data->raw_data;
+ FuriString* barcode_digits = barcode_data->correct_data;
+ //BarcodeTypeObj* type_obj = barcode_data->type_obj;
+
+ int barcode_length = furi_string_size(barcode_digits);
+ int total_pixels = 0;
+
+ for(int i = 0; i < barcode_length; i++) {
+ //1 for wide, 0 for narrow
+ char wide_or_narrow = furi_string_get_char(barcode_digits, i);
+ int wn_digit = wide_or_narrow - '0'; //wide(1) or narrow(0) digit
+
+ if(wn_digit == 1) {
+ total_pixels += 3;
+ } else {
+ total_pixels += 1;
+ }
+ if((i + 1) % 9 == 0) {
+ total_pixels += 1;
+ }
+ }
+
+ int x = (128 - total_pixels) / 2;
+ int y = BARCODE_Y_START;
+ int width = 1;
+ int height = BARCODE_HEIGHT;
+ bool filled_in = true;
+
+ //set the canvas color to black to print the digit
+ canvas_set_color(canvas, ColorBlack);
+ // canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignCenter, error);
+ canvas_draw_str_aligned(
+ canvas, 62, y + height + 8, AlignCenter, AlignBottom, furi_string_get_cstr(raw_data));
+
+ for(int i = 0; i < barcode_length; i++) {
+ //1 for wide, 0 for narrow
+ char wide_or_narrow = furi_string_get_char(barcode_digits, i);
+ int wn_digit = wide_or_narrow - '0'; //wide(1) or narrow(0) digit
+
+ if(filled_in) {
+ if(wn_digit == 1) {
+ x = draw_bits(canvas, "111", x, y, width, height);
+ } else {
+ x = draw_bits(canvas, "1", x, y, width, height);
+ }
+ filled_in = false;
+ } else {
+ if(wn_digit == 1) {
+ x = draw_bits(canvas, "000", x, y, width, height);
+ } else {
+ x = draw_bits(canvas, "0", x, y, width, height);
+ }
+ filled_in = true;
+ }
+ if((i + 1) % 9 == 0) {
+ x = draw_bits(canvas, "0", x, y, width, height);
+ filled_in = true;
+ }
+ }
+}
+
+static void draw_code_128(Canvas* canvas, BarcodeData* barcode_data) {
+ FuriString* raw_data = barcode_data->raw_data;
+ FuriString* barcode_digits = barcode_data->correct_data;
+
+ int barcode_length = furi_string_size(barcode_digits);
+
+ int x = (128 - barcode_length) / 2;
+ int y = BARCODE_Y_START;
+ int width = 1;
+ int height = BARCODE_HEIGHT;
+
+ x = draw_bits(canvas, furi_string_get_cstr(barcode_digits), x, y, width, height);
+
+ //set the canvas color to black to print the digit
+ canvas_set_color(canvas, ColorBlack);
+ // canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignCenter, error);
+ canvas_draw_str_aligned(
+ canvas, 62, y + height + 8, AlignCenter, AlignBottom, furi_string_get_cstr(raw_data));
+}
+
+static void draw_codabar(Canvas* canvas, BarcodeData* barcode_data) {
+ FuriString* raw_data = barcode_data->raw_data;
+ FuriString* barcode_digits = barcode_data->correct_data;
+ //BarcodeTypeObj* type_obj = barcode_data->type_obj;
+
+ int barcode_length = furi_string_size(barcode_digits);
+ int total_pixels = 0;
+
+ for(int i = 0; i < barcode_length; i++) {
+ //1 for wide, 0 for narrow
+ char wide_or_narrow = furi_string_get_char(barcode_digits, i);
+ int wn_digit = wide_or_narrow - '0'; //wide(1) or narrow(0) digit
+
+ if(wn_digit == 1) {
+ total_pixels += 3;
+ } else {
+ total_pixels += 1;
+ }
+ if((i + 1) % 7 == 0) {
+ total_pixels += 1;
+ }
+ }
+
+ int x = (128 - total_pixels) / 2;
+ int y = BARCODE_Y_START;
+ int width = 1;
+ int height = BARCODE_HEIGHT;
+ bool filled_in = true;
+
+ //set the canvas color to black to print the digit
+ canvas_set_color(canvas, ColorBlack);
+ // canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignCenter, error);
+ canvas_draw_str_aligned(
+ canvas, 62, y + height + 8, AlignCenter, AlignBottom, furi_string_get_cstr(raw_data));
+
+ for(int i = 0; i < barcode_length; i++) {
+ //1 for wide, 0 for narrow
+ char wide_or_narrow = furi_string_get_char(barcode_digits, i);
+ int wn_digit = wide_or_narrow - '0'; //wide(1) or narrow(0) digit
+
+ if(filled_in) {
+ if(wn_digit == 1) {
+ x = draw_bits(canvas, "111", x, y, width, height);
+ } else {
+ x = draw_bits(canvas, "1", x, y, width, height);
+ }
+ filled_in = false;
+ } else {
+ if(wn_digit == 1) {
+ x = draw_bits(canvas, "000", x, y, width, height);
+ } else {
+ x = draw_bits(canvas, "0", x, y, width, height);
+ }
+ filled_in = true;
+ }
+ if((i + 1) % 7 == 0) {
+ x = draw_bits(canvas, "0", x, y, width, height);
+ filled_in = true;
+ }
+ }
+}
+
+static void barcode_draw_callback(Canvas* canvas, void* ctx) {
+ furi_assert(ctx);
+ BarcodeModel* barcode_model = ctx;
+ BarcodeData* data = barcode_model->data;
+ // const char* barcode_digits =;
+
+ canvas_clear(canvas);
+ if(data->valid) {
+ switch(data->type_obj->type) {
+ case UPCA:
+ draw_upc_a(canvas, data);
+ break;
+ case EAN8:
+ draw_ean_8(canvas, data);
+ break;
+ case EAN13:
+ draw_ean_13(canvas, data);
+ break;
+ case CODE39:
+ draw_code_39(canvas, data);
+ break;
+ case CODE128:
+ case CODE128C:
+ draw_code_128(canvas, data);
+ break;
+ case CODABAR:
+ draw_codabar(canvas, data);
+ break;
+ case UNKNOWN:
+ default:
+ break;
+ }
+ } else {
+ switch(data->reason) {
+ case WrongNumberOfDigits:
+ draw_error_str(canvas, "Wrong # of characters");
+ break;
+ case InvalidCharacters:
+ draw_error_str(canvas, "Invalid characters");
+ break;
+ case UnsupportedType:
+ draw_error_str(canvas, "Unsupported barcode type");
+ break;
+ case FileOpening:
+ draw_error_str(canvas, "Could not open file");
+ break;
+ case InvalidFileData:
+ draw_error_str(canvas, "Invalid file data");
+ break;
+ case MissingEncodingTable:
+ draw_error_str(canvas, "Missing encoding table");
+ break;
+ case EncodingTableError:
+ draw_error_str(canvas, "Encoding table error");
+ break;
+ default:
+ draw_error_str(canvas, "Could not read barcode data");
+ break;
+ }
+ }
+}
+
+bool barcode_input_callback(InputEvent* input_event, void* ctx) {
+ UNUSED(ctx);
+ //furi_assert(ctx);
+
+ //Barcode* test_view_object = ctx;
+
+ if(input_event->key == InputKeyBack) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+Barcode* barcode_view_allocate(BarcodeApp* barcode_app) {
+ furi_assert(barcode_app);
+
+ Barcode* barcode = malloc(sizeof(Barcode));
+
+ barcode->view = view_alloc();
+ barcode->barcode_app = barcode_app;
+
+ view_set_context(barcode->view, barcode);
+ view_allocate_model(barcode->view, ViewModelTypeLocking, sizeof(BarcodeModel));
+ view_set_draw_callback(barcode->view, barcode_draw_callback);
+ view_set_input_callback(barcode->view, barcode_input_callback);
+
+ return barcode;
+}
+
+void barcode_free_model(Barcode* barcode) {
+ with_view_model(
+ barcode->view,
+ BarcodeModel * model,
+ {
+ if(model->file_path != NULL) {
+ furi_string_free(model->file_path);
+ }
+ if(model->data != NULL) {
+ if(model->data->raw_data != NULL) {
+ furi_string_free(model->data->raw_data);
+ }
+ if(model->data->correct_data != NULL) {
+ furi_string_free(model->data->correct_data);
+ }
+ free(model->data);
+ }
+ },
+ false);
+}
+
+void barcode_free(Barcode* barcode) {
+ furi_assert(barcode);
+
+ barcode_free_model(barcode);
+ view_free(barcode->view);
+ free(barcode);
+}
+
+View* barcode_get_view(Barcode* barcode) {
+ furi_assert(barcode);
+ return barcode->view;
+}
diff --git a/applications/external/barcode_gen/views/barcode_view.h b/applications/external/barcode_gen/views/barcode_view.h
new file mode 100644
index 000000000..828428c08
--- /dev/null
+++ b/applications/external/barcode_gen/views/barcode_view.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include
+
+typedef struct BarcodeApp BarcodeApp;
+
+typedef struct {
+ View* view;
+ BarcodeApp* barcode_app;
+} Barcode;
+
+typedef struct {
+ FuriString* file_path;
+ BarcodeData* data;
+} BarcodeModel;
+
+Barcode* barcode_view_allocate(BarcodeApp* barcode_app);
+
+void barcode_free_model(Barcode* barcode);
+
+void barcode_free(Barcode* barcode);
+
+View* barcode_get_view(Barcode* barcode);
diff --git a/applications/external/barcode_gen/views/create_view.c b/applications/external/barcode_gen/views/create_view.c
new file mode 100644
index 000000000..e4e489113
--- /dev/null
+++ b/applications/external/barcode_gen/views/create_view.c
@@ -0,0 +1,494 @@
+#include "../barcode_app.h"
+#include "create_view.h"
+#include
+
+#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;
+}
\ No newline at end of file
diff --git a/applications/external/barcode_gen/views/create_view.h b/applications/external/barcode_gen/views/create_view.h
new file mode 100644
index 000000000..6063786d9
--- /dev/null
+++ b/applications/external/barcode_gen/views/create_view.h
@@ -0,0 +1,46 @@
+#pragma once
+
+#include
+
+typedef struct BarcodeApp BarcodeApp;
+
+typedef enum {
+ FileNameSetter,
+ BarcodeDataSetter
+} InputSetter; //what value to set for the text input view
+
+typedef enum {
+ EditMode,
+
+ NewMode
+} CreateMode;
+
+typedef struct {
+ View* view;
+ BarcodeApp* barcode_app;
+
+ InputSetter setter;
+ char input[TEXT_BUFFER_SIZE];
+} CreateView;
+
+typedef struct {
+ int selected_menu_item;
+
+ CreateMode mode;
+ BarcodeTypeObj* barcode_type;
+ FuriString* file_path; //the current file that is opened
+ FuriString* file_name;
+ FuriString* barcode_data;
+} CreateViewModel;
+
+CreateView* create_view_allocate(BarcodeApp* barcode_app);
+
+void remove_barcode(CreateView* create_view_object);
+
+void save_barcode(CreateView* create_view_object);
+
+void create_view_free_model(CreateView* create_view_object);
+
+void create_view_free(CreateView* create_view_object);
+
+View* create_get_view(CreateView* create_view_object);
diff --git a/applications/external/barcode_gen/views/message_view.c b/applications/external/barcode_gen/views/message_view.c
new file mode 100644
index 000000000..3a9aa90b3
--- /dev/null
+++ b/applications/external/barcode_gen/views/message_view.c
@@ -0,0 +1,66 @@
+#include "../barcode_app.h"
+#include "message_view.h"
+
+static void app_draw_callback(Canvas* canvas, void* ctx) {
+ furi_assert(ctx);
+
+ MessageViewModel* message_view_model = ctx;
+
+ canvas_clear(canvas);
+ if(message_view_model->message != NULL) {
+ canvas_draw_str_aligned(
+ canvas, 62, 30, AlignCenter, AlignCenter, message_view_model->message);
+ }
+
+ canvas_set_color(canvas, ColorBlack);
+ canvas_draw_box(canvas, 100, 52, 28, 12);
+ canvas_set_color(canvas, ColorWhite);
+ canvas_draw_str_aligned(canvas, 114, 58, AlignCenter, AlignCenter, "OK");
+}
+
+static bool app_input_callback(InputEvent* input_event, void* ctx) {
+ furi_assert(ctx);
+
+ MessageView* message_view_object = ctx;
+
+ if(input_event->key == InputKeyBack) {
+ view_dispatcher_switch_to_view(
+ message_view_object->barcode_app->view_dispatcher, MainMenuView);
+ }
+ if(input_event->type == InputTypeShort) {
+ if(input_event->key == InputKeyOk) {
+ view_dispatcher_switch_to_view(
+ message_view_object->barcode_app->view_dispatcher, MainMenuView);
+ }
+ }
+
+ return true;
+}
+
+MessageView* message_view_allocate(BarcodeApp* barcode_app) {
+ furi_assert(barcode_app);
+
+ MessageView* message_view_object = malloc(sizeof(MessageView));
+
+ message_view_object->view = view_alloc();
+ message_view_object->barcode_app = barcode_app;
+
+ view_set_context(message_view_object->view, message_view_object);
+ view_allocate_model(message_view_object->view, ViewModelTypeLocking, sizeof(MessageViewModel));
+ view_set_draw_callback(message_view_object->view, app_draw_callback);
+ view_set_input_callback(message_view_object->view, app_input_callback);
+
+ return message_view_object;
+}
+
+void message_view_free(MessageView* message_view_object) {
+ furi_assert(message_view_object);
+
+ view_free(message_view_object->view);
+ free(message_view_object);
+}
+
+View* message_get_view(MessageView* message_view_object) {
+ furi_assert(message_view_object);
+ return message_view_object->view;
+}
\ No newline at end of file
diff --git a/applications/external/barcode_gen/views/message_view.h b/applications/external/barcode_gen/views/message_view.h
new file mode 100644
index 000000000..33acc3d0c
--- /dev/null
+++ b/applications/external/barcode_gen/views/message_view.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include
+
+typedef struct BarcodeApp BarcodeApp;
+
+typedef struct {
+ View* view;
+ BarcodeApp* barcode_app;
+} MessageView;
+
+typedef struct {
+ const char* message;
+} MessageViewModel;
+
+MessageView* message_view_allocate(BarcodeApp* barcode_app);
+
+void message_view_free_model(MessageView* message_view_object);
+
+void message_view_free(MessageView* message_view_object);
+
+View* message_get_view(MessageView* message_view_object);
diff --git a/applications/external/barcode_generator/application.fam b/applications/external/barcode_generator/application.fam
deleted file mode 100644
index 9bb44915c..000000000
--- a/applications/external/barcode_generator/application.fam
+++ /dev/null
@@ -1,17 +0,0 @@
-App(
- appid="barcode_generator",
- name="Barcode Generator",
- apptype=FlipperAppType.EXTERNAL,
- entry_point="barcode_generator_app",
- requires=[
- "gui",
- "dialogs",
- ],
- stack_size=1 * 1024,
- order=50,
- fap_icon="barcode_10px.png",
- fap_category="Tools",
- fap_author="@xMasterX & @msvsergey & @McAzzaMan",
- fap_version="1.0",
- fap_description="App displays Barcode on flipper screen and allows to edit it",
-)
diff --git a/applications/external/barcode_generator/barcode_10px.png b/applications/external/barcode_generator/barcode_10px.png
deleted file mode 100644
index 7c19c665687e0e6f81a805511af4d8ed409b54bc..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 2363
zcmcIleQeZZ81FWfF+QB4FvMlG7#NXWKkwSN?ikzM?JL~4Z6|D~fnNLeR(IEyYq#AN
z%oaruB@i%+Xe3Ao#)CCTV+^Ork;KJQyBnW;32#3Z*#BN*U?_IKaeUzS
z(mh7`Q{OyWxU&9K%`bDe6`dY_KCpfM-7jDH?cf#g@cDuxu}cScwCuRreyr!qeaC+|
zcX^3+pm4DHz|o##-B{_$tsj?NnJ6B-6doDp&s-m1E8c1?Xn7AZ;Hz?we2wykvY;APuiu^WudPi-z(SN?R@;HLcx
zzv`HXo_hy&To_+b^XT3=ukAU{ovhfot7*~2FItwIohaJER3wD*lN;WD_rq%gfBEmb
zbQKzh>WkN|_AlwENgwtMJW=-eD?i6Rv6e2Jko%+Rh+v&4n0F%d!KN2}U0k(r02@2A
z{?Dsz)n`#A=UNRNHipexmF-j2N>s1GtI`r8NJ2-()5(Nk
zOKCrm;g!(Zy-g8#2I6%2iEKgJ!x21SrXVhO7*e5W8fO@vM+B;mlj+qsOS25cFcd42
zEF;lC;y66_AyB-Os!6TEx?D7Lg|^w9QedbD8qV^3FssvaOuN&(gSN@XwZJ((Pu#-JdnCYAT3h
zGMkbHfmhKWPx68YNKWHpB=89W$)F&DLi0Qq6Z35AQ#$G$IWd*hRiz?EFAG&o0D#nF
zD3F@KE2QWZASo!K07OLqng|H|X54_8FjHYuMcL&DTva5^OeJOHA3Z6@A!QkH*Ug9>
zouWavQR(_}{m}-u=2i(E&zMe<71!&2LUD@>RU&s=pC)^=)0w61?SzPQhT>;owy8P2
zathYOQKtXZT-2S!+j7s$(tTc$<9v#jgtU(%V*<~UKm;rac%W!BOZx;LlRx_ZB0ZN@
zrBgQI5WPAn;=dneb}pW_4*%?{+19~3waK%aZaWO+zAv*5qi#3fP4ng(pa!+3YfU>>
z(^@$`S=}|$_ZtmF=mQKSQNQ>|p64|ZXsSxGKn9G)sv>06s*H++ev>QTWdUDpD8SOZ
z;HwiECKM1uAW+NlLC#mlhXQr%l${xltRQM;hMI%NYqvc2H!SJ|umAu6
diff --git a/applications/external/barcode_generator/barcode_generator.c b/applications/external/barcode_generator/barcode_generator.c
deleted file mode 100644
index 2645bbcea..000000000
--- a/applications/external/barcode_generator/barcode_generator.c
+++ /dev/null
@@ -1,447 +0,0 @@
-#include "barcode_generator.h"
-
-static BarcodeType* barcodeTypes[NUMBER_OF_BARCODE_TYPES];
-
-void init_types() {
- BarcodeType* upcA = malloc(sizeof(BarcodeType));
- upcA->name = "UPC-A";
- upcA->numberOfDigits = 12;
- upcA->startPos = 19;
- upcA->bartype = BarTypeUPCA;
- barcodeTypes[0] = upcA;
-
- BarcodeType* ean8 = malloc(sizeof(BarcodeType));
- ean8->name = "EAN-8";
- ean8->numberOfDigits = 8;
- ean8->startPos = 33;
- ean8->bartype = BarTypeEAN8;
- barcodeTypes[1] = ean8;
-
- BarcodeType* ean13 = malloc(sizeof(BarcodeType));
- ean13->name = "EAN-13";
- ean13->numberOfDigits = 13;
- ean13->startPos = 19;
- ean13->bartype = BarTypeEAN13;
- barcodeTypes[2] = ean13;
-}
-
-void draw_digit(
- Canvas* canvas,
- int digit,
- BarEncodingType rightHand,
- int startingPosition,
- bool drawlines) {
- char digitStr[2];
- snprintf(digitStr, 2, "%u", digit);
- canvas_set_color(canvas, ColorBlack);
- canvas_draw_str(
- canvas, startingPosition, BARCODE_Y_START + BARCODE_HEIGHT + BARCODE_TEXT_OFFSET, digitStr);
-
- if(drawlines) {
- switch(rightHand) {
- case BarEncodingTypeLeft:
- case BarEncodingTypeRight:
- canvas_set_color(
- canvas, (rightHand == BarEncodingTypeRight) ? ColorBlack : ColorWhite);
- //int count = 0;
- for(int i = 0; i < 4; i++) {
- canvas_draw_box(
- canvas, startingPosition, BARCODE_Y_START, DIGITS[digit][i], BARCODE_HEIGHT);
- canvas_invert_color(canvas);
- startingPosition += DIGITS[digit][i];
- }
- break;
- case BarEncodingTypeG:
- canvas_set_color(canvas, ColorWhite);
- //int count = 0;
- for(int i = 3; i >= 0; i--) {
- canvas_draw_box(
- canvas, startingPosition, BARCODE_Y_START, DIGITS[digit][i], BARCODE_HEIGHT);
- canvas_invert_color(canvas);
- startingPosition += DIGITS[digit][i];
- }
- break;
- default:
- break;
- }
- }
-}
-
-int get_digit_position(int index, BarcodeType* type) {
- int pos = 0;
- switch(type->bartype) {
- case BarTypeEAN8:
- case BarTypeUPCA:
- pos = type->startPos + index * 7;
- if(index >= type->numberOfDigits / 2) {
- pos += 5;
- }
- break;
- case BarTypeEAN13:
- if(index == 0)
- pos = type->startPos - 10;
- else {
- pos = type->startPos + (index - 1) * 7;
- if((index - 1) >= type->numberOfDigits / 2) {
- pos += 5;
- }
- }
- break;
- default:
- break;
- }
- return pos;
-}
-
-int get_menu_text_location(int index) {
- return 20 + 10 * index;
-}
-
-int get_barcode_max_index(PluginState* plugin_state) {
- return plugin_state->barcode_state.doParityCalculation ?
- barcodeTypes[plugin_state->barcode_state.barcodeTypeIndex]->numberOfDigits - 1 :
- barcodeTypes[plugin_state->barcode_state.barcodeTypeIndex]->numberOfDigits;
-}
-
-int calculate_check_digit(PluginState* plugin_state, BarcodeType* type) {
- int checkDigit = 0;
- int checkDigitOdd = 0;
- int checkDigitEven = 0;
- //add all odd positions. Confusing because 0index
- for(int i = 0; i < type->numberOfDigits - 1; i += 2) {
- checkDigitOdd += plugin_state->barcode_state.barcodeNumeral[i];
- }
-
- //add all even positions to above. Confusing because 0index
- for(int i = 1; i < type->numberOfDigits - 1; i += 2) {
- checkDigitEven += plugin_state->barcode_state.barcodeNumeral[i];
- }
-
- if(type->bartype == BarTypeEAN13) {
- checkDigit = checkDigitEven * 3 + checkDigitOdd;
- } else {
- checkDigit = checkDigitOdd * 3 + checkDigitEven;
- }
-
- checkDigit = checkDigit % 10; //mod 10
-
- //if m = 0 then x12 = 0, otherwise x12 is 10 - m
- return (10 - checkDigit) % 10;
-}
-
-static void render_callback(Canvas* const canvas, void* ctx) {
- furi_assert(ctx);
- PluginState* plugin_state = ctx;
- furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
-
- if(plugin_state->mode == MenuMode) {
- canvas_set_color(canvas, ColorBlack);
- canvas_draw_str_aligned(canvas, 64, 6, AlignCenter, AlignCenter, "MENU");
- canvas_draw_frame(canvas, 50, 0, 29, 11); //box around Menu
- canvas_draw_str_aligned(
- canvas, 64, get_menu_text_location(0), AlignCenter, AlignCenter, "View");
- canvas_draw_str_aligned(
- canvas, 64, get_menu_text_location(1), AlignCenter, AlignCenter, "Edit");
- canvas_draw_str_aligned(
- canvas, 64, get_menu_text_location(2), AlignCenter, AlignCenter, "Parity?");
-
- canvas_draw_frame(canvas, 83, get_menu_text_location(2) - 3, 6, 6);
- if(plugin_state->barcode_state.doParityCalculation == true) {
- canvas_draw_box(canvas, 85, get_menu_text_location(2) - 1, 2, 2);
- }
- canvas_draw_str_aligned(
- canvas,
- 64,
- get_menu_text_location(3),
- AlignCenter,
- AlignCenter,
- (barcodeTypes[plugin_state->barcode_state.barcodeTypeIndex])->name);
- canvas_draw_disc(
- canvas,
- 40,
- get_menu_text_location(plugin_state->menuIndex) - 1,
- 2); //draw menu cursor
- } else {
- BarcodeType* type = barcodeTypes[plugin_state->barcode_state.barcodeTypeIndex];
-
- //start saftey
- canvas_set_color(canvas, ColorBlack);
- canvas_draw_box(canvas, type->startPos - 3, BARCODE_Y_START, 1, BARCODE_HEIGHT + 2);
- canvas_draw_box(canvas, (type->startPos - 1), BARCODE_Y_START, 1, BARCODE_HEIGHT + 2);
-
- int startpos = 0;
- int endpos = type->numberOfDigits;
- if(type->bartype == BarTypeEAN13) {
- startpos++;
- draw_digit(
- canvas,
- plugin_state->barcode_state.barcodeNumeral[0],
- BarEncodingTypeRight,
- get_digit_position(0, barcodeTypes[plugin_state->barcode_state.barcodeTypeIndex]),
- false);
- }
- if(plugin_state->barcode_state.doParityCalculation) { //calculate the check digit
- plugin_state->barcode_state.barcodeNumeral[type->numberOfDigits - 1] =
- calculate_check_digit(plugin_state, type);
- }
- for(int index = startpos; index < endpos; index++) {
- BarEncodingType barEncodingType = BarEncodingTypeLeft;
- if(type->bartype == BarTypeEAN13) {
- if(index - 1 >= (type->numberOfDigits - 1) / 2) {
- barEncodingType = BarEncodingTypeRight;
- } else {
- barEncodingType =
- (FURI_BIT(
- EAN13ENCODE[plugin_state->barcode_state.barcodeNumeral[0]],
- index - 1)) ?
- BarEncodingTypeG :
- BarEncodingTypeLeft;
- }
- } else {
- if(index >= type->numberOfDigits / 2) {
- barEncodingType = BarEncodingTypeRight;
- }
- }
-
- int digitPosition = get_digit_position(
- index, barcodeTypes[plugin_state->barcode_state.barcodeTypeIndex]);
- draw_digit(
- canvas,
- plugin_state->barcode_state.barcodeNumeral[index],
- barEncodingType,
- digitPosition,
- true);
- }
-
- //central separator
- canvas_set_color(canvas, ColorBlack);
- canvas_draw_box(canvas, 62, BARCODE_Y_START, 1, BARCODE_HEIGHT + 2);
- canvas_draw_box(canvas, 64, BARCODE_Y_START, 1, BARCODE_HEIGHT + 2);
-
- if(plugin_state->mode == EditMode) {
- canvas_set_color(canvas, ColorBlack);
- canvas_draw_box(
- canvas,
- get_digit_position(
- plugin_state->editingIndex,
- barcodeTypes[plugin_state->barcode_state.barcodeTypeIndex]) -
- 1,
- 63,
- 7,
- 1); //draw editing cursor
- }
-
- //end safety
- int endSafetyPosition = get_digit_position(type->numberOfDigits - 1, type) + 7;
- canvas_set_color(canvas, ColorBlack);
- canvas_draw_box(canvas, endSafetyPosition, BARCODE_Y_START, 1, BARCODE_HEIGHT + 2);
- canvas_draw_box(canvas, (endSafetyPosition + 2), BARCODE_Y_START, 1, BARCODE_HEIGHT + 2);
- }
-
- furi_mutex_release(plugin_state->mutex);
-}
-
-static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
- furi_assert(event_queue);
-
- PluginEvent event = {.type = EventTypeKey, .input = *input_event};
- furi_message_queue_put(event_queue, &event, FuriWaitForever);
-}
-
-static void barcode_generator_state_init(PluginState* plugin_state) {
- plugin_state->editingIndex = 0;
- plugin_state->mode = ViewMode;
- plugin_state->menuIndex = MENU_INDEX_VIEW;
- if(!LOAD_BARCODE_SETTINGS(&plugin_state->barcode_state)) {
- for(int i = 0; i < BARCODE_MAX_LENS; ++i) {
- plugin_state->barcode_state.barcodeNumeral[i] = i % 10;
- }
- plugin_state->barcode_state.doParityCalculation = true;
- plugin_state->barcode_state.barcodeTypeIndex = 0;
- }
-}
-
-static bool handle_key_press_view(InputKey key, PluginState* plugin_state) {
- switch(key) {
- case InputKeyOk:
- case InputKeyBack:
- plugin_state->mode = MenuMode;
- break;
-
- default:
- break;
- }
-
- return true;
-}
-
-static bool handle_key_press_edit(InputKey key, PluginState* plugin_state) {
- int barcodeMaxIndex = get_barcode_max_index(plugin_state);
-
- switch(key) {
- case InputKeyUp:
- plugin_state->barcode_state.barcodeNumeral[plugin_state->editingIndex] =
- (plugin_state->barcode_state.barcodeNumeral[plugin_state->editingIndex] + 1) % 10;
- break;
-
- case InputKeyDown:
- plugin_state->barcode_state.barcodeNumeral[plugin_state->editingIndex] =
- (plugin_state->barcode_state.barcodeNumeral[plugin_state->editingIndex] == 0) ?
- 9 :
- plugin_state->barcode_state.barcodeNumeral[plugin_state->editingIndex] - 1;
- break;
-
- case InputKeyRight:
- plugin_state->editingIndex = (plugin_state->editingIndex + 1) % barcodeMaxIndex;
- break;
-
- case InputKeyLeft:
- plugin_state->editingIndex = (plugin_state->editingIndex == 0) ?
- barcodeMaxIndex - 1 :
- plugin_state->editingIndex - 1;
- break;
-
- case InputKeyOk:
- case InputKeyBack:
- plugin_state->mode = MenuMode;
- break;
-
- default:
- break;
- }
-
- return true;
-}
-
-static bool handle_key_press_menu(InputKey key, PluginState* plugin_state) {
- switch(key) {
- case InputKeyUp:
- plugin_state->menuIndex = (plugin_state->menuIndex == MENU_INDEX_VIEW) ?
- MENU_INDEX_TYPE :
- plugin_state->menuIndex - 1;
- break;
-
- case InputKeyDown:
- plugin_state->menuIndex = (plugin_state->menuIndex + 1) % 4;
- break;
-
- case InputKeyRight:
- if(plugin_state->menuIndex == MENU_INDEX_TYPE) {
- plugin_state->barcode_state.barcodeTypeIndex =
- (plugin_state->barcode_state.barcodeTypeIndex == NUMBER_OF_BARCODE_TYPES - 1) ?
- 0 :
- plugin_state->barcode_state.barcodeTypeIndex + 1;
- } else if(plugin_state->menuIndex == MENU_INDEX_PARITY) {
- plugin_state->barcode_state.doParityCalculation =
- !plugin_state->barcode_state.doParityCalculation;
- }
- break;
- case InputKeyLeft:
- if(plugin_state->menuIndex == MENU_INDEX_TYPE) {
- plugin_state->barcode_state.barcodeTypeIndex =
- (plugin_state->barcode_state.barcodeTypeIndex == 0) ?
- NUMBER_OF_BARCODE_TYPES - 1 :
- plugin_state->barcode_state.barcodeTypeIndex - 1;
- } else if(plugin_state->menuIndex == MENU_INDEX_PARITY) {
- plugin_state->barcode_state.doParityCalculation =
- !plugin_state->barcode_state.doParityCalculation;
- }
- break;
-
- case InputKeyOk:
- if(plugin_state->menuIndex == MENU_INDEX_VIEW) {
- plugin_state->mode = ViewMode;
- } else if(plugin_state->menuIndex == MENU_INDEX_EDIT) {
- plugin_state->mode = EditMode;
- } else if(plugin_state->menuIndex == MENU_INDEX_PARITY) {
- plugin_state->barcode_state.doParityCalculation =
- !plugin_state->barcode_state.doParityCalculation;
- } else if(plugin_state->menuIndex == MENU_INDEX_TYPE) {
- plugin_state->barcode_state.barcodeTypeIndex =
- (plugin_state->barcode_state.barcodeTypeIndex == NUMBER_OF_BARCODE_TYPES - 1) ?
- 0 :
- plugin_state->barcode_state.barcodeTypeIndex + 1;
- }
- break;
-
- case InputKeyBack:
- return false;
-
- default:
- break;
- }
- int barcodeMaxIndex = get_barcode_max_index(plugin_state);
- if(plugin_state->editingIndex >= barcodeMaxIndex)
- plugin_state->editingIndex = barcodeMaxIndex - 1;
-
- return true;
-}
-
-int32_t barcode_generator_app(void* p) {
- UNUSED(p);
-
- init_types();
-
- FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
-
- PluginState* plugin_state = malloc(sizeof(PluginState));
- barcode_generator_state_init(plugin_state);
-
- plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
- if(!plugin_state->mutex) {
- FURI_LOG_E("barcode_generator", "cannot create mutex\r\n");
- furi_message_queue_free(event_queue);
- free(plugin_state);
- return 255;
- }
-
- // Set system callbacks
- ViewPort* view_port = view_port_alloc();
- view_port_draw_callback_set(view_port, render_callback, plugin_state);
- view_port_input_callback_set(view_port, input_callback, event_queue);
-
- // Open GUI and register view_port
- Gui* gui = furi_record_open(RECORD_GUI);
- gui_add_view_port(gui, view_port, GuiLayerFullscreen);
-
- PluginEvent event;
- for(bool processing = true; processing;) {
- FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
- furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
-
- if(event_status == FuriStatusOk) {
- // press events
- if(event.type == EventTypeKey &&
- ((event.input.type == InputTypePress) || (event.input.type == InputTypeRepeat))) {
- switch(plugin_state->mode) {
- case ViewMode:
- processing = handle_key_press_view(event.input.key, plugin_state);
- break;
- case EditMode:
- processing = handle_key_press_edit(event.input.key, plugin_state);
- break;
- case MenuMode:
- processing = handle_key_press_menu(event.input.key, plugin_state);
- break;
- default:
- break;
- }
- }
- }
-
- view_port_update(view_port);
- furi_mutex_release(plugin_state->mutex);
- }
-
- view_port_enabled_set(view_port, false);
- gui_remove_view_port(gui, view_port);
- furi_record_close(RECORD_GUI);
- view_port_free(view_port);
- furi_message_queue_free(event_queue);
- furi_mutex_free(plugin_state->mutex);
- // save settings
- SAVE_BARCODE_SETTINGS(&plugin_state->barcode_state);
- free(plugin_state);
-
- return 0;
-}
diff --git a/applications/external/barcode_generator/barcode_generator.h b/applications/external/barcode_generator/barcode_generator.h
deleted file mode 100644
index 9f2e10c16..000000000
--- a/applications/external/barcode_generator/barcode_generator.h
+++ /dev/null
@@ -1,115 +0,0 @@
-#pragma once
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define BARCODE_SETTINGS_FILE_NAME "apps/Tools/barcodegen.save"
-
-#define BARCODE_SETTINGS_VER (1)
-#define BARCODE_SETTINGS_PATH EXT_PATH(BARCODE_SETTINGS_FILE_NAME)
-#define BARCODE_SETTINGS_MAGIC (0xC2)
-
-#define SAVE_BARCODE_SETTINGS(x) \
- saved_struct_save( \
- BARCODE_SETTINGS_PATH, \
- (x), \
- sizeof(BarcodeState), \
- BARCODE_SETTINGS_MAGIC, \
- BARCODE_SETTINGS_VER)
-
-#define LOAD_BARCODE_SETTINGS(x) \
- saved_struct_load( \
- BARCODE_SETTINGS_PATH, \
- (x), \
- sizeof(BarcodeState), \
- BARCODE_SETTINGS_MAGIC, \
- BARCODE_SETTINGS_VER)
-
-#define BARCODE_HEIGHT 50
-#define BARCODE_Y_START 3
-#define BARCODE_TEXT_OFFSET 9
-#define BARCODE_MAX_LENS 13
-#define NUMBER_OF_BARCODE_TYPES 3
-#define MENU_INDEX_VIEW 0
-#define MENU_INDEX_EDIT 1
-#define MENU_INDEX_PARITY 2
-#define MENU_INDEX_TYPE 3
-
-typedef enum {
- EventTypeTick,
- EventTypeKey,
-} EventType;
-
-typedef struct {
- EventType type;
- InputEvent input;
-} PluginEvent;
-
-typedef enum {
- ViewMode,
- EditMode,
- MenuMode,
-} Mode;
-
-typedef enum {
- BarEncodingTypeLeft,
- BarEncodingTypeRight,
- BarEncodingTypeG,
-} BarEncodingType;
-
-typedef enum {
- BarTypeEAN8,
- BarTypeUPCA,
- BarTypeEAN13,
-} BarType;
-
-typedef struct {
- char* name;
- int numberOfDigits;
- int startPos;
- BarType bartype;
-} BarcodeType;
-
-typedef struct {
- int barcodeNumeral[BARCODE_MAX_LENS]; //The current barcode number
- bool doParityCalculation; //Should do parity check?
- int barcodeTypeIndex;
-} BarcodeState;
-
-typedef struct {
- FuriMutex* mutex;
- BarcodeState barcode_state;
- int editingIndex; //The index of the editing symbol
- int menuIndex; //The index of the menu cursor
- Mode mode; //View, edit or menu
-} PluginState;
-
-static const int DIGITS[10][4] = {
- {3, 2, 1, 1},
- {2, 2, 2, 1},
- {2, 1, 2, 2},
- {1, 4, 1, 1},
- {1, 1, 3, 2},
- {1, 2, 3, 1},
- {1, 1, 1, 4},
- {1, 3, 1, 2},
- {1, 2, 1, 3},
- {3, 1, 1, 2},
-};
-
-static const uint8_t EAN13ENCODE[10] = {
- 0b000000,
- 0b110100,
- 0b101100,
- 0b011100,
- 0b110010,
- 0b100110,
- 0b001110,
- 0b101010,
- 0b011010,
- 0b010110,
-};
\ No newline at end of file
diff --git a/assets/resources/apps_data/barcode_data/codabar_encodings.txt b/assets/resources/apps_data/barcode_data/codabar_encodings.txt
new file mode 100644
index 000000000..5f0684cbd
--- /dev/null
+++ b/assets/resources/apps_data/barcode_data/codabar_encodings.txt
@@ -0,0 +1,22 @@
+# alternates between bars and spaces, always begins with bar
+# 0 for narrow, 1 for wide
+0: 0000011
+1: 0000110
+2: 0001001
+3: 1100000
+4: 0010010
+5: 1000010
+6: 0100001
+7: 0100100
+8: 0110000
+9: 1001000
+-: 0001100
+$: 0011000
+:: 1000101
+/: 1010001
+.: 1010100
++: 0010101
+A: 0011010
+B: 0101001
+C: 0001011
+D: 0001110
\ No newline at end of file
diff --git a/assets/resources/apps_data/barcode_data/code128_encodings.txt b/assets/resources/apps_data/barcode_data/code128_encodings.txt
new file mode 100644
index 000000000..394a34520
--- /dev/null
+++ b/assets/resources/apps_data/barcode_data/code128_encodings.txt
@@ -0,0 +1,202 @@
+ : 00
+!: 01
+": 02
+#: 03
+$: 04
+%: 05
+&: 06
+': 07
+(: 08
+): 09
+*: 10
++: 11
+,: 12
+-: 13
+.: 14
+/: 15
+0: 16
+1: 17
+2: 18
+3: 19
+4: 20
+5: 21
+6: 22
+7: 23
+8: 24
+9: 25
+:: 26
+;: 27
+<: 28
+=: 29
+>: 30
+?: 31
+@: 32
+A: 33
+B: 34
+C: 35
+D: 36
+E: 37
+F: 38
+G: 39
+H: 40
+I: 41
+J: 42
+K: 43
+L: 44
+M: 45
+N: 46
+O: 47
+P: 48
+Q: 49
+R: 50
+S: 51
+T: 52
+U: 53
+V: 54
+W: 55
+X: 56
+Y: 57
+Z: 58
+[: 59
+\: 60
+]: 61
+^: 62
+_: 63
+`: 64
+a: 65
+b: 66
+c: 67
+d: 68
+e: 69
+f: 70
+g: 71
+h: 72
+i: 73
+j: 74
+k: 75
+l: 76
+m: 77
+n: 78
+o: 79
+p: 80
+q: 81
+r: 82
+s: 83
+t: 84
+u: 85
+v: 86
+w: 87
+x: 88
+y: 89
+z: 90
+{: 91
+|: 92
+}: 93
+~: 94
+
+00: 11011001100
+01: 11001101100
+02: 11001100110
+03: 10010011000
+04: 10010001100
+05: 10001001100
+06: 10011001000
+07: 10011000100
+08: 10001100100
+09: 11001001000
+10: 11001000100
+11: 11000100100
+12: 10110011100
+13: 10011011100
+14: 10011001110
+15: 10111001100
+16: 10011101100
+17: 10011100110
+18: 11001110010
+19: 11001011100
+20: 11001001110
+21: 11011100100
+22: 11001110100
+23: 11101101110
+24: 11101001100
+25: 11100101100
+26: 11100100110
+27: 11101100100
+28: 11100110100
+29: 11100110010
+30: 11011011000
+31: 11011000110
+32: 11000110110
+33: 10100011000
+34: 10001011000
+35: 10001000110
+36: 10110001000
+37: 10001101000
+38: 10001100010
+39: 11010001000
+40: 11000101000
+41: 11000100010
+42: 10110111000
+43: 10110001110
+44: 10001101110
+45: 10111011000
+46: 10111000110
+47: 10001110110
+48: 11101110110
+49: 11010001110
+50: 11000101110
+51: 11011101000
+52: 11011100010
+53: 11011101110
+54: 11101011000
+55: 11101000110
+56: 11100010110
+57: 11101101000
+58: 11101100010
+59: 11100011010
+60: 11101111010
+61: 11001000010
+62: 11110001010
+63: 10100110000
+64: 10100001100
+65: 10010110000
+66: 10010000110
+67: 10000101100
+68: 10000100110
+69: 10110010000
+70: 10110000100
+71: 10011010000
+72: 10011000010
+73: 10000110100
+74: 10000110010
+75: 11000010010
+76: 11001010000
+77: 11110111010
+78: 11000010100
+79: 10001111010
+80: 10100111100
+81: 10010111100
+82: 10010011110
+83: 10111100100
+84: 10011110100
+85: 10011110010
+86: 11110100100
+87: 11110010100
+88: 11110010010
+89: 11011011110
+90: 11011110110
+91: 11110110110
+92: 10101111000
+93: 10100011110
+94: 10001011110
+95: 10111101000
+96: 10111100010
+97: 11110101000
+98: 11110100010
+99: 10111011110
+100: 10111101110
+101: 11101011110
+102: 11110101110
+103: 11010000100
+104: 11010010000
+105: 11010011100
\ No newline at end of file
diff --git a/assets/resources/apps_data/barcode_data/code128c_encodings.txt b/assets/resources/apps_data/barcode_data/code128c_encodings.txt
new file mode 100644
index 000000000..75cc71135
--- /dev/null
+++ b/assets/resources/apps_data/barcode_data/code128c_encodings.txt
@@ -0,0 +1,106 @@
+00: 11011001100
+01: 11001101100
+02: 11001100110
+03: 10010011000
+04: 10010001100
+05: 10001001100
+06: 10011001000
+07: 10011000100
+08: 10001100100
+09: 11001001000
+10: 11001000100
+11: 11000100100
+12: 10110011100
+13: 10011011100
+14: 10011001110
+15: 10111001100
+16: 10011101100
+17: 10011100110
+18: 11001110010
+19: 11001011100
+20: 11001001110
+21: 11011100100
+22: 11001110100
+23: 11101101110
+24: 11101001100
+25: 11100101100
+26: 11100100110
+27: 11101100100
+28: 11100110100
+29: 11100110010
+30: 11011011000
+31: 11011000110
+32: 11000110110
+33: 10100011000
+34: 10001011000
+35: 10001000110
+36: 10110001000
+37: 10001101000
+38: 10001100010
+39: 11010001000
+40: 11000101000
+41: 11000100010
+42: 10110111000
+43: 10110001110
+44: 10001101110
+45: 10111011000
+46: 10111000110
+47: 10001110110
+48: 11101110110
+49: 11010001110
+50: 11000101110
+51: 11011101000
+52: 11011100010
+53: 11011101110
+54: 11101011000
+55: 11101000110
+56: 11100010110
+57: 11101101000
+58: 11101100010
+59: 11100011010
+60: 11101111010
+61: 11001000010
+62: 11110001010
+63: 10100110000
+64: 10100001100
+65: 10010110000
+66: 10010000110
+67: 10000101100
+68: 10000100110
+69: 10110010000
+70: 10110000100
+71: 10011010000
+72: 10011000010
+73: 10000110100
+74: 10000110010
+75: 11000010010
+76: 11001010000
+77: 11110111010
+78: 11000010100
+79: 10001111010
+80: 10100111100
+81: 10010111100
+82: 10010011110
+83: 10111100100
+84: 10011110100
+85: 10011110010
+86: 11110100100
+87: 11110010100
+88: 11110010010
+89: 11011011110
+90: 11011110110
+91: 11110110110
+92: 10101111000
+93: 10100011110
+94: 10001011110
+95: 10111101000
+96: 10111100010
+97: 11110101000
+98: 11110100010
+99: 10111011110
+100: 10111101110
+101: 11101011110
+102: 11110101110
+103: 11010000100
+104: 11010010000
+105: 11010011100
diff --git a/assets/resources/apps_data/barcode_data/code39_encodings.txt b/assets/resources/apps_data/barcode_data/code39_encodings.txt
new file mode 100644
index 000000000..a41ad16e9
--- /dev/null
+++ b/assets/resources/apps_data/barcode_data/code39_encodings.txt
@@ -0,0 +1,44 @@
+0: 000110100
+1: 100100001
+2: 001100001
+3: 101100000
+4: 000110001
+5: 100110000
+6: 001110000
+7: 000100101
+8: 100100100
+9: 001100100
+A: 100001001
+B: 001001001
+C: 101001000
+D: 000011001
+E: 100011000
+F: 001011000
+G: 000001101
+H: 100001100
+I: 001001100
+J: 000011100
+K: 100000011
+L: 001000011
+M: 101000010
+N: 000010011
+O: 100010010
+P: 001010010
+Q: 000000111
+R: 100000110
+S: 001000110
+T: 000010110
+U: 110000001
+V: 011000001
+W: 111000000
+X: 010010001
+Y: 110010000
+Z: 011010000
+-: 010000101
+.: 110000100
+ : 011000100
+*: 010010100
+$: 010101000
+/: 010100010
++: 010001010
+%: 000101010
\ No newline at end of file