Skip to content

Commit 7c9cf9d

Browse files
tixlegeektixlegeek
authored and
tixlegeek
committed
Merge pull request #12 from tixlegeek/tixlegeek-check_bmp_size_editor
- Rework BMP Editor events - Add width check for editing bitmaps on flipper
2 parents 80ba0cc + cf74053 commit 7c9cf9d

File tree

3 files changed

+118
-32
lines changed

3 files changed

+118
-32
lines changed

401lightMessengerApp/401LightMsg_bmp_editor.c

+106-27
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,24 @@ static uint8_t bmp_editor_move(AppBmpEditor* BmpEditor, int8_t x, int8_t y) {
3232
}
3333

3434
static uint8_t bmp_editor_resize(AppBmpEditor* BmpEditor, int8_t w, int8_t h) {
35+
// Compute the new dimensions given increments/decrements in size. Usually only height
3536
int dh = BmpEditor->model_data->bmp_h + h;
3637
int dw = BmpEditor->model_data->bmp_w + w;
37-
if(dh < PARAM_BMP_EDITOR_MIN_RES_H)
38+
if(dh < PARAM_BMP_EDITOR_MIN_RES_H) {
3839
BmpEditor->model_data->bmp_h = PARAM_BMP_EDITOR_MIN_RES_H;
39-
else if(dh > PARAM_BMP_EDITOR_MAX_RES_H)
40+
} else if(dh > PARAM_BMP_EDITOR_MAX_RES_H) {
4041
BmpEditor->model_data->bmp_h = PARAM_BMP_EDITOR_MAX_RES_H;
41-
else
42+
} else {
4243
BmpEditor->model_data->bmp_h = dh;
44+
}
4345

44-
if(dw < PARAM_BMP_EDITOR_MIN_RES_W)
46+
if(dw < PARAM_BMP_EDITOR_MIN_RES_W) {
4547
BmpEditor->model_data->bmp_w = PARAM_BMP_EDITOR_MIN_RES_W;
46-
else if(dw > PARAM_BMP_EDITOR_MAX_RES_W)
48+
} else if(dw > PARAM_BMP_EDITOR_MAX_RES_W) {
4749
BmpEditor->model_data->bmp_w = PARAM_BMP_EDITOR_MAX_RES_W;
48-
else
50+
} else {
4951
BmpEditor->model_data->bmp_w = dw;
52+
}
5053

5154
BmpEditor->model_data->cursor.x = (BmpEditor->model_data->bmp_w / 2);
5255
BmpEditor->model_data->cursor.y = (BmpEditor->model_data->bmp_h / 2);
@@ -84,7 +87,7 @@ static void bmp_editor_text_input_callback(void* ctx) {
8487
LIGHTMSGCONF_SAVE_FOLDER,
8588
BmpEditor->bitmapName,
8689
".bmp");
87-
view_dispatcher_send_custom_event(app->view_dispatcher, SetTextInputSaveEvent);
90+
view_dispatcher_send_custom_event(app->view_dispatcher, AppBmpEditorEventSaveText);
8891
}
8992

9093
static void bmp_editor_select_name(void* ctx) {
@@ -114,6 +117,7 @@ static void bmp_editor_select_file(void* ctx) {
114117
AppContext* app = (AppContext*)ctx; // Main app struct
115118
AppData* appData = (AppData*)app->data;
116119
AppBmpEditor* BmpEditor = app->sceneBmpEditor;
120+
117121
bmpEditorData* BmpEditorData = BmpEditor->model_data;
118122
Configuration* light_msg_data = (Configuration*)appData->config;
119123
DialogsFileBrowserOptions browser_options;
@@ -129,16 +133,24 @@ static void bmp_editor_select_file(void* ctx) {
129133
if(dialog_file_browser_show(BmpEditor->dialogs, bitmapPath, bitmapPath, &browser_options)) {
130134
if(BmpEditorData->bitmap) bitmapMatrix_free(BmpEditorData->bitmap);
131135
BmpEditorData->bitmap = bmp_to_bitmapMatrix(furi_string_get_cstr(bitmapPath));
132-
BmpEditorData->bmp_w = BmpEditorData->bitmap->width;
133-
BmpEditorData->bmp_h = BmpEditorData->bitmap->height;
134-
BmpEditorData->state = BmpEditorStateDrawing;
135-
136-
memcpy(
137-
BmpEditor->bitmapPath,
138-
furi_string_get_cstr(bitmapPath),
139-
strlen(furi_string_get_cstr(bitmapPath)));
140-
bmp_compute_model(BmpEditor, BmpEditor->model_data);
141-
view_dispatcher_switch_to_view(app->view_dispatcher, AppViewBmpEditor);
136+
if(BmpEditorData->bitmap->width > PARAM_BMP_EDITOR_MAX_RES_W) {
137+
//if(BmpEditorData->bitmap) bitmapMatrix_free(BmpEditorData->bitmap);
138+
//furi_string_free(bitmapPath);
139+
BmpEditorData->state = BmpEditorStateSizeError;
140+
BmpEditorData->error = L401_ERR_WIDTH;
141+
view_dispatcher_switch_to_view(app->view_dispatcher, AppViewBmpEditor);
142+
return;
143+
} else {
144+
BmpEditorData->bmp_w = BmpEditorData->bitmap->width;
145+
BmpEditorData->bmp_h = BmpEditorData->bitmap->height;
146+
BmpEditorData->state = BmpEditorStateDrawing;
147+
memcpy(
148+
BmpEditor->bitmapPath,
149+
furi_string_get_cstr(bitmapPath),
150+
strlen(furi_string_get_cstr(bitmapPath)));
151+
bmp_compute_model(BmpEditor, BmpEditor->model_data);
152+
view_dispatcher_switch_to_view(app->view_dispatcher, AppViewBmpEditor);
153+
}
142154
}
143155
furi_string_free(bitmapPath);
144156
}
@@ -149,6 +161,17 @@ static bool bmp_editor_mainmenu_input_callback(InputEvent* input_event, void* ct
149161
return false;
150162
}
151163

164+
static bool bmp_editor_error_input_callback(InputEvent* input_event, void* ctx) {
165+
AppContext* app = (AppContext*)ctx;
166+
bool consumed = false;
167+
168+
if((input_event->type == InputTypePress) || (input_event->type == InputTypeRepeat)) {
169+
view_dispatcher_send_custom_event(app->view_dispatcher, AppBmpEditorEventQuit);
170+
consumed = true;
171+
}
172+
return consumed;
173+
}
174+
152175
static bool bmp_editor_select_size_input_callback(InputEvent* input_event, void* ctx) {
153176
AppContext* app = (AppContext*)ctx;
154177
AppBmpEditor* BmpEditor = app->sceneBmpEditor;
@@ -189,32 +212,52 @@ static bool bmp_editor_select_size_input_callback(InputEvent* input_event, void*
189212
static bool bmp_editor_draw_input_callback(InputEvent* input_event, void* ctx) {
190213
AppContext* app = (AppContext*)ctx;
191214
AppBmpEditor* BmpEditor = app->sceneBmpEditor;
192-
215+
bmpEditorData* BmpEditorData = BmpEditor->model_data;
193216
bool consumed = false;
194217
BMP_err res = BMP_OK;
195-
if((input_event->type == InputTypePress) || (input_event->type == InputTypeRepeat)) {
218+
if((input_event->type == InputTypePress) || (input_event->type == InputTypeRepeat) ||
219+
(input_event->type == InputTypeLong)) {
196220
switch(input_event->key) {
197221
case InputKeyUp:
198222
bmp_editor_move(BmpEditor, 0, -1);
223+
if(BmpEditorData->draw_mode == BmpEditorDrawModeContinuous) {
224+
bmp_editor_toggle(BmpEditor);
225+
}
199226
consumed = true;
200227
break;
201228
case InputKeyDown:
202229
bmp_editor_move(BmpEditor, 0, 1);
230+
if(BmpEditorData->draw_mode == BmpEditorDrawModeContinuous) {
231+
bmp_editor_toggle(BmpEditor);
232+
}
203233
consumed = true;
204234
break;
205235
case InputKeyLeft:
206236
bmp_editor_move(BmpEditor, -1, 0);
207-
bmp_compute_model(BmpEditor, BmpEditor->model_data);
237+
//bmp_compute_model(BmpEditor, BmpEditor->model_data);
238+
if(BmpEditorData->draw_mode == BmpEditorDrawModeContinuous) {
239+
bmp_editor_toggle(BmpEditor);
240+
}
208241
consumed = true;
209242
break;
210243
case InputKeyRight:
211244
bmp_editor_move(BmpEditor, 1, 0);
212-
bmp_compute_model(BmpEditor, BmpEditor->model_data);
245+
//bmp_compute_model(BmpEditor, BmpEditor->model_data);
246+
if(BmpEditorData->draw_mode == BmpEditorDrawModeContinuous) {
247+
bmp_editor_toggle(BmpEditor);
248+
}
213249
consumed = true;
214250
break;
215251
case InputKeyOk:
216-
bmp_editor_toggle(BmpEditor);
217-
view_dispatcher_send_custom_event(app->view_dispatcher, AppBmpEditorEventToggle);
252+
if(input_event->type == InputTypeLong) {
253+
BmpEditorData->draw_mode = (BmpEditorData->draw_mode == BmpEditorDrawModeOneshot) ?
254+
BmpEditorDrawModeContinuous :
255+
BmpEditorDrawModeOneshot;
256+
} else {
257+
if(BmpEditorData->draw_mode == BmpEditorDrawModeOneshot) {
258+
bmp_editor_toggle(BmpEditor);
259+
}
260+
}
218261
consumed = false;
219262
break;
220263
case InputKeyBack:
@@ -261,6 +304,9 @@ static bool app_scene_bmp_editor_input_callback(InputEvent* input_event, void* c
261304
case BmpEditorStateDrawing:
262305
consumed = bmp_editor_draw_input_callback(input_event, ctx);
263306
break;
307+
case BmpEditorStateSizeError:
308+
consumed = bmp_editor_error_input_callback(input_event, ctx);
309+
break;
264310
default:
265311
break;
266312
}
@@ -290,6 +336,27 @@ static void bmp_editor_drawSizePicker(Canvas* canvas, void* ctx) {
290336
canvas_draw_str(canvas, 25 + 45, 62, "OK");
291337
}
292338

339+
static void bmp_editor_drawError(Canvas* canvas, void* ctx) {
340+
// UNUSED(ctx);
341+
bmpEditorModel* BmpEditorModel = (bmpEditorModel*)ctx;
342+
bmpEditorData* BmpEditorData = BmpEditorModel->data;
343+
344+
switch(BmpEditorData->error) {
345+
case L401_ERR_WIDTH:
346+
canvas_clear(canvas);
347+
canvas_set_font(canvas, FontSecondary);
348+
canvas_draw_str_aligned(canvas, 64, 20, AlignCenter, AlignCenter, "BMP File too large to");
349+
canvas_draw_str_aligned(canvas, 64, 30, AlignCenter, AlignCenter, "be edited on flipper!");
350+
break;
351+
default:
352+
canvas_clear(canvas);
353+
canvas_set_font(canvas, FontPrimary);
354+
canvas_draw_str_aligned(canvas, 64, 10, AlignCenter, AlignCenter, "Unknown error");
355+
break;
356+
}
357+
elements_button_center(canvas, "Return");
358+
}
359+
293360
static void bmp_editor_drawBoard(Canvas* canvas, void* ctx) {
294361
bmpEditorModel* BmpEditorModel = (bmpEditorModel*)ctx;
295362
bmpEditorData* BmpEditorData = BmpEditorModel->data;
@@ -315,8 +382,12 @@ static void bmp_editor_drawBoard(Canvas* canvas, void* ctx) {
315382
canvas_draw_str(canvas, 25 + 10, 62, "Save");
316383
canvas_draw_icon(canvas, 25 + 35, 56, &I_btn_ok_7x7);
317384
canvas_draw_str(canvas, 25 + 45, 62, "Toggle");
318-
385+
// Indicates continuous mode
319386
canvas_set_font(canvas, FontPrimary);
387+
if(BmpEditorData->draw_mode == BmpEditorDrawModeContinuous) {
388+
canvas_draw_str(canvas, 0, 62, "C");
389+
;
390+
}
320391
// Bitmap
321392
for(x = 0; x < BmpEditorData->bmp_w; x++) {
322393
for(y = 0; y < BmpEditorData->bmp_h; y++) {
@@ -365,6 +436,9 @@ static void app_scene_bmp_editor_render_callback(Canvas* canvas, void* _model) {
365436
case BmpEditorStateDrawing:
366437
bmp_editor_drawBoard(canvas, _model);
367438
break;
439+
case BmpEditorStateSizeError:
440+
bmp_editor_drawError(canvas, _model);
441+
break;
368442
default:
369443
break;
370444
}
@@ -404,6 +478,7 @@ AppBmpEditor* app_bmp_editor_alloc(void* ctx) {
404478
appBmpEditor->model_data->bmp_pixel_spacing = 0;
405479
appBmpEditor->model_data->bmp_w = 32;
406480
appBmpEditor->model_data->bmp_h = 16;
481+
appBmpEditor->model_data->error = L401_OK;
407482
appBmpEditor->mainmenu = submenu_alloc();
408483

409484
submenu_add_item(
@@ -432,11 +507,9 @@ AppBmpEditor* app_bmp_editor_alloc(void* ctx) {
432507

433508
appBmpEditor->view = view_alloc();
434509
view_allocate_model(appBmpEditor->view, ViewModelTypeLocking, sizeof(bmpEditorModel));
435-
436510
view_set_context(appBmpEditor->view, app);
437511
view_set_draw_callback(appBmpEditor->view, app_scene_bmp_editor_render_callback);
438512
view_set_input_callback(appBmpEditor->view, app_scene_bmp_editor_input_callback);
439-
440513
return appBmpEditor;
441514
}
442515

@@ -536,11 +609,17 @@ bool app_scene_bmp_editor_on_event(void* ctx, SceneManagerEvent event) {
536609
// UNUSED(ctx);
537610
bool consumed = false;
538611
if(event.type == SceneManagerEventTypeCustom) {
539-
if(event.event == SetTextInputSaveEvent) {
612+
switch(event.event) {
613+
case AppBmpEditorEventSaveText:
540614
bmp_editor_init_bitmap(ctx);
541615
BmpEditorData->state = BmpEditorStateDrawing;
542616
view_dispatcher_switch_to_view(app->view_dispatcher, AppViewBmpEditor);
543617
consumed = true;
618+
break;
619+
case AppBmpEditorEventQuit:
620+
view_dispatcher_switch_to_view(app->view_dispatcher, BmpEditorViewMainMenu);
621+
consumed = true;
622+
break;
544623
}
545624
}
546625
// scene_manager_next_scene(app->scene_manager, AppSceneMainMenu);

401lightMessengerApp/401LightMsg_bmp_editor.h

+11-5
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@
1212
#include <stdlib.h>
1313

1414
#include "bmp.h"
15+
#include "401_err.h"
1516
#include "drivers/sk6805.h"
1617
#include <401_light_msg_icons.h>
1718
#include <dialogs/dialogs.h>
1819
#include <gui/gui.h>
1920
#include <gui/modules/submenu.h>
2021
#include <gui/modules/text_input.h>
22+
#include <gui/elements.h>
2123
#include <gui/scene_manager.h>
2224
#include <gui/view_dispatcher.h>
2325
#include <lib/toolbox/name_generator.h>
@@ -30,6 +32,7 @@ typedef struct {
3032
typedef enum {
3133
BmpEditorStateDrawing,
3234
BmpEditorStateSelectSize,
35+
BmpEditorStateSizeError,
3336
BmpEditorStateSelectName,
3437
BmpEditorStateSelectFile,
3538
BmpEditorStateSelectSource,
@@ -50,6 +53,11 @@ typedef enum {
5053
BmpEditorMainmenuIndex_Open,
5154
} BmpEditorMainmenuIndex;
5255

56+
typedef enum {
57+
BmpEditorDrawModeOneshot,
58+
BmpEditorDrawModeContinuous,
59+
} BmpEditorDrawMode;
60+
5361
typedef struct {
5462
bmpEditorCursor cursor;
5563
uint8_t bmp_pixel_size;
@@ -64,6 +72,8 @@ typedef struct {
6472
uint8_t* bmp_canvas;
6573
bitmapMatrix* bitmap;
6674
bmpEditorState state;
75+
BmpEditorDrawMode draw_mode;
76+
l401_err error;
6777
} bmpEditorData;
6878

6979
typedef struct {
@@ -84,11 +94,7 @@ typedef struct AppBmpEditor {
8494

8595
typedef enum {
8696
AppBmpEditorEventQuit,
87-
AppBmpEditorEventUp,
88-
AppBmpEditorEventDown,
89-
AppBmpEditorEventLeft,
90-
AppBmpEditorEventRight,
91-
AppBmpEditorEventToggle,
97+
AppBmpEditorEventSaveText,
9298
} AppBmpEditorCustomEvents;
9399

94100
AppBmpEditor* app_bmp_editor_alloc();

401lightMessengerApp/401_err.h

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ typedef enum {
1818
L401_ERR_BMP_FILE,
1919
L401_ERR_NULLPTR,
2020
L401_ERR_HARDWARE,
21+
L401_ERR_WIDTH,
2122
} l401_err;
2223

2324
#endif /* end of include guard: L401_ERR_H */

0 commit comments

Comments
 (0)