@@ -55,28 +55,63 @@ typedef struct {
5555
5656 FuriMutex * * mutex ;
5757 QRCode * qrcode ;
58+ bool loading ;
5859 bool too_long ;
60+ bool show_stats ;
5961} QRCodeApp ;
6062
63+ /**
64+ * @param ecc ECC number
65+ * @returns a character corresponding to the ecc level
66+ */
67+ static char get_ecc_char (uint8_t ecc ) {
68+ switch (ecc ) {
69+ case 0 : return 'L' ;
70+ case 1 : return 'M' ;
71+ case 2 : return 'Q' ;
72+ case 3 : return 'H' ;
73+ default : return '?' ;
74+ }
75+ }
76+
77+ /**
78+ * @param mode qrcode mode
79+ * @returns a character corresponding to the mode
80+ */
81+ static char get_mode_char (uint8_t mode ) {
82+ switch (mode ) {
83+ case 0 : return 'N' ;
84+ case 1 : return 'A' ;
85+ case 2 : return 'B' ;
86+ case 3 : return 'K' ;
87+ default : return '?' ;
88+ }
89+ }
90+
6191/**
6292 * Render
6393 * @param canvas The canvas to render to
6494 * @param ctx Context provided to the callback by view_port_draw_callback_set
6595 */
6696static void render_callback (Canvas * canvas , void * ctx ) {
97+ furi_assert (canvas );
98+ furi_assert (ctx );
99+
67100 QRCodeApp * instance = ctx ;
68101 furi_check (furi_mutex_acquire (instance -> mutex , FuriWaitForever ) == FuriStatusOk );
69102
70103 canvas_clear (canvas );
71104 canvas_set_color (canvas , ColorBlack );
105+ canvas_set_font (canvas , FontPrimary );
72106
107+ uint8_t font_height = canvas_current_font_height (canvas );
73108 uint8_t width = canvas_width (canvas );
74109 uint8_t height = canvas_height (canvas );
75110 if (instance -> qrcode ) {
76111 uint8_t size = instance -> qrcode -> size ;
77112 uint8_t pixel_size = height / size ;
78113 uint8_t top = (height - pixel_size * size ) / 2 ;
79- uint8_t left = (width - pixel_size * size ) / 2 ;
114+ uint8_t left = instance -> show_stats ? top : (width - pixel_size * size ) / 2 ;
80115 for (uint8_t y = 0 ; y < size ; y ++ ) {
81116 for (uint8_t x = 0 ; x < size ; x ++ ) {
82117 if (qrcode_getModule (instance -> qrcode , x , y )) {
@@ -88,10 +123,27 @@ static void render_callback(Canvas* canvas, void* ctx) {
88123 }
89124 }
90125 }
91- } else {
92- canvas_set_font (canvas , FontPrimary );
93126
94- uint8_t font_height = canvas_current_font_height (canvas );
127+ if (instance -> show_stats ) {
128+ if (top < 2 ) top = 2 ;
129+ left += size * pixel_size + top ;
130+
131+ FuriString * str = furi_string_alloc ();
132+
133+ furi_string_printf (str , "Ver: %i" , instance -> qrcode -> version );
134+ canvas_draw_str (canvas , left , top + font_height , furi_string_get_cstr (str ));
135+
136+ furi_string_printf (str , "ECC: %c" , get_ecc_char (instance -> qrcode -> ecc ));
137+ canvas_draw_str (canvas , left , 2 * (top + font_height ), furi_string_get_cstr (str ));
138+
139+ furi_string_printf (str , "Mod: %c" , get_mode_char (instance -> qrcode -> mode ));
140+ canvas_draw_str (canvas , left , 3 * (top + font_height ), furi_string_get_cstr (str ));
141+
142+ furi_string_free (str );
143+ }
144+ } else if (instance -> loading ) {
145+ canvas_draw_str_aligned (canvas , width / 2 , height / 2 , AlignCenter , AlignCenter , "Loading..." );
146+ } else {
95147 uint8_t margin = (height - font_height * 2 ) / 3 ;
96148 canvas_draw_str_aligned (canvas , width / 2 , margin , AlignCenter , AlignTop , "Could not load qrcode." );
97149 if (instance -> too_long ) {
@@ -109,6 +161,8 @@ static void render_callback(Canvas* canvas, void* ctx) {
109161 * @param ctx Context provided to the callback by view_port_input_callback_set
110162 */
111163static void input_callback (InputEvent * input_event , void * ctx ) {
164+ furi_assert (input_event );
165+ furi_assert (ctx );
112166 if (input_event -> type == InputTypeShort ) {
113167 QRCodeApp * instance = ctx ;
114168 furi_message_queue_put (instance -> input_queue , input_event , 0 );
@@ -121,6 +175,7 @@ static void input_callback(InputEvent* input_event, void* ctx) {
121175 * @returns true if the string is all numeric
122176 */
123177static bool is_numeric (const char * str , uint16_t len ) {
178+ furi_assert (str );
124179 while (len > 0 ) {
125180 char c = str [-- len ];
126181 if (c < '0' || c > '9' ) return false;
@@ -134,6 +189,7 @@ static bool is_numeric(const char* str, uint16_t len) {
134189 * @returns true if the string is alphanumeric
135190 */
136191static bool is_alphanumeric (const char * str , uint16_t len ) {
192+ furi_assert (str );
137193 while (len > 0 ) {
138194 char c = str [-- len ];
139195 if (c >= '0' && c <= '9' ) continue ;
@@ -169,6 +225,7 @@ static QRCode* qrcode_alloc(uint8_t version) {
169225 * @param qrcode The QRCode to free
170226 */
171227static void qrcode_free (QRCode * qrcode ) {
228+ furi_assert (qrcode );
172229 free (qrcode -> modules );
173230 free (qrcode );
174231}
@@ -180,12 +237,16 @@ static void qrcode_free(QRCode* qrcode) {
180237 * @returns true if the string was successfully loaded
181238 */
182239static bool qrcode_load_string (QRCodeApp * instance , FuriString * str ) {
240+ furi_assert (instance );
241+ furi_assert (str );
242+
183243 furi_check (furi_mutex_acquire (instance -> mutex , FuriWaitForever ) == FuriStatusOk );
184244 if (instance -> qrcode ) {
185245 qrcode_free (instance -> qrcode );
186246 instance -> qrcode = NULL ;
187247 }
188248 instance -> too_long = false;
249+ instance -> show_stats = false;
189250
190251 bool result = false;
191252 do {
@@ -238,6 +299,8 @@ static bool qrcode_load_string(QRCodeApp* instance, FuriString* str) {
238299 result = true;
239300 } while (false);
240301
302+ instance -> loading = false;
303+
241304 furi_mutex_release (instance -> mutex );
242305
243306 return result ;
@@ -307,6 +370,11 @@ static QRCodeApp* qrcode_app_alloc() {
307370
308371 instance -> mutex = furi_mutex_alloc (FuriMutexTypeNormal );
309372
373+ instance -> qrcode = NULL ;
374+ instance -> loading = true;
375+ instance -> too_long = false;
376+ instance -> show_stats = false;
377+
310378 return instance ;
311379}
312380
@@ -332,9 +400,7 @@ static void qrcode_app_free(QRCodeApp* instance) {
332400/** App entrypoint */
333401int32_t qrcode_app (void * p ) {
334402 QRCodeApp * instance = qrcode_app_alloc ();
335-
336- FuriString * file_path ;
337- file_path = furi_string_alloc ();
403+ FuriString * file_path = furi_string_alloc ();
338404
339405 do {
340406 if (p && strlen (p )) {
@@ -371,19 +437,25 @@ int32_t qrcode_app(void* p) {
371437 qrcode_free (instance -> qrcode );
372438 instance -> qrcode = NULL ;
373439 }
440+ instance -> loading = true;
374441 furi_mutex_release (instance -> mutex );
375442 break ;
443+ } else if (input .key == InputKeyRight ) {
444+ instance -> show_stats = true;
445+ } else if (input .key == InputKeyLeft ) {
446+ instance -> show_stats = false;
376447 }
377448
378449 furi_mutex_release (instance -> mutex );
379450 view_port_update (instance -> view_port );
380451 }
381452
382453 if (p && strlen (p )) {
383- // if started with an arg, exit instead of going to the browser
454+ // if started with an arg, exit instead
455+ // of looping back to the browser
384456 break ;
385457 }
386- } while (1 );
458+ } while (true );
387459
388460 furi_string_free (file_path );
389461 qrcode_app_free (instance );
0 commit comments