diff --git a/applications/playlist/canvas_helper.c b/applications/playlist/canvas_helper.c new file mode 100644 index 000000000..ecb2eed8b --- /dev/null +++ b/applications/playlist/canvas_helper.c @@ -0,0 +1,81 @@ +#include + +#define WIDTH 128 +#define HEIGHT 64 + +void draw_centered_boxed_str(Canvas* canvas, int x, int y, int height, int pad, const char* text) { + // get width of text + int w = canvas_string_width(canvas, text); + canvas_draw_rframe(canvas, x, y, w + pad, height, 2); + canvas_draw_str_aligned(canvas, x + pad / 2, y + height / 2, AlignLeft, AlignCenter, text); +} + +void draw_corner_aligned(Canvas* canvas, int width, int height, Align horizontal, Align vertical) { + canvas_set_color(canvas, ColorBlack); + switch(horizontal) { + case AlignLeft: + switch(vertical) { + case AlignTop: + canvas_draw_rbox(canvas, 0, 0, width, height, 3); + canvas_draw_box(canvas, 0, 0, width, 3); + canvas_draw_box(canvas, 0, 0, 3, height); + break; + case AlignCenter: + canvas_draw_rbox(canvas, 0, HEIGHT - height / 2, width, height, 3); + canvas_draw_box(canvas, 0, HEIGHT - height / 2, 3, height); + break; + case AlignBottom: + canvas_draw_rbox(canvas, 0, HEIGHT - height, width, height, 3); + canvas_draw_box(canvas, 0, HEIGHT - height, 3, height); + canvas_draw_box(canvas, 0, HEIGHT - 3, width, 3); + break; + default: + break; + } + break; + case AlignRight: + switch(vertical) { + case AlignTop: + canvas_draw_rbox(canvas, WIDTH - width, 0, width, height, 3); + canvas_draw_box(canvas, WIDTH - width, 0, width, 3); // bottom corner + canvas_draw_box(canvas, WIDTH - 3, 0, 3, height); // right corner + break; + case AlignCenter: + canvas_draw_rbox(canvas, WIDTH - width, HEIGHT / 2 - height / 2, width, height, 3); + canvas_draw_box(canvas, WIDTH - 3, HEIGHT / 2 - height / 2, 3, height); // right corner + break; + case AlignBottom: + canvas_draw_rbox(canvas, WIDTH - width, HEIGHT - height, width, height, 3); + canvas_draw_box(canvas, WIDTH - 3, HEIGHT - height, 3, height); // right corner + canvas_draw_box(canvas, WIDTH - width, HEIGHT - 3, width, 3); // bottom corner + break; + default: + break; + } + break; + case AlignCenter: + switch(vertical) { + case AlignTop: + canvas_draw_rbox(canvas, WIDTH / 2 - width / 2, 0, width, height, 3); + canvas_draw_box(canvas, WIDTH / 2 - width / 2, 0, width, 3); // bottom corner + canvas_draw_box(canvas, WIDTH / 2 - 3, 0, 3, height); // right corner + break; + case AlignCenter: + canvas_draw_rbox( + canvas, WIDTH / 2 - width / 2, HEIGHT / 2 - height / 2, width, height, 3); + canvas_draw_box( + canvas, WIDTH / 2 - 3, HEIGHT / 2 - height / 2, 3, height); // right corner + break; + case AlignBottom: + canvas_draw_rbox(canvas, WIDTH / 2 - width / 2, HEIGHT - height, width, height, 3); + canvas_draw_box(canvas, WIDTH / 2 - 3, HEIGHT - height, 3, height); // right corner + canvas_draw_box(canvas, WIDTH / 2 - width / 2, HEIGHT - 3, width, 3); // bottom corner + break; + default: + break; + } + break; + default: + break; + } +} \ No newline at end of file diff --git a/applications/playlist/canvas_helper.h b/applications/playlist/canvas_helper.h new file mode 100644 index 000000000..cf73bdb32 --- /dev/null +++ b/applications/playlist/canvas_helper.h @@ -0,0 +1,5 @@ +#include + +void draw_centered_boxed_str(Canvas* canvas, int x, int y, int height, int pad, const char* text); + +void draw_corner_aligned(Canvas* canvas, int width, int height, Align horizontal, Align vertical); \ No newline at end of file diff --git a/applications/playlist/example_playlist.txt b/applications/playlist/example_playlist.txt deleted file mode 100644 index 7c7a05191..000000000 --- a/applications/playlist/example_playlist.txt +++ /dev/null @@ -1,5 +0,0 @@ -SUB: /ext/subghz/Garages/deBruijn/Binary/deBruijn300AllBit.sub -SUB: /ext/subghz/Garages/deBruijn/Binary/deBruijn310AllBit.sub -SUB: /ext/subghz/Garages/deBruijn/Binary/deBruijn315AllBit.sub -SUB: /ext/subghz/Garages/deBruijn/Binary/deBruijn318AllBit.sub -SUB: /ext/subghz/Garages/deBruijn/Binary/deBruijn390AllBit.sub \ No newline at end of file diff --git a/applications/playlist/playlist.c b/applications/playlist/playlist.c index 0661114d5..83ae75dc6 100644 --- a/applications/playlist/playlist.c +++ b/applications/playlist/playlist.c @@ -18,12 +18,15 @@ #include #include "playlist_file.h" +#include "canvas_helper.h" #define PLAYLIST_FOLDER "/ext/playlist" #define PLAYLIST_EXT ".txt" #define TAG "Playlist" -#define STATE_OVERVIEW 2 +#define STATE_NONE 0 +#define STATE_OVERVIEW 1 +#define STATE_SENDING 2 #define WIDTH 128 #define HEIGHT 64 @@ -40,6 +43,8 @@ typedef struct { string_t prev_1_path; // previous file string_t prev_2_path; // previous previous file string_t prev_3_path; // you get the idea + + int state; // current state } DisplayMeta; typedef struct { @@ -67,8 +72,6 @@ typedef struct { PlaylistWorker* worker; string_t file_path; // Path to the playlist file - - int state; // Current state for rendering } Playlist; //////////////////////////////////////////////////////////////////////////////// @@ -231,6 +234,9 @@ static int32_t playlist_worker_thread(void* ctx) { break; } + // update state to sending + worker->meta->state = STATE_SENDING; + worker->meta->current_single_repetition = 0; ++worker->meta->current_count; @@ -295,6 +301,9 @@ static int32_t playlist_worker_thread(void* ctx) { FURI_LOG_I(TAG, "Done reading. Read %d data lines.", worker->meta->current_count); worker->is_running = false; + // update state to overview + worker->meta->state = STATE_OVERVIEW; + return 0; } @@ -318,6 +327,7 @@ DisplayMeta* playlist_meta_alloc() { string_init(instance->prev_3_path); playlist_meta_reset(instance); instance->single_repetitions = 1; + instance->state = STATE_NONE; return instance; } @@ -389,9 +399,65 @@ static void render_callback(Canvas* canvas, void* ctx) { furi_check(furi_mutex_acquire(app->mutex, FuriWaitForever) == FuriStatusOk); canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontSecondary); + + switch(app->meta->state) { + case STATE_NONE: + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned( + canvas, WIDTH / 2, HEIGHT / 2, AlignCenter, AlignCenter, "No playlist loaded"); + break; - switch(app->state) { case STATE_OVERVIEW: + // draw file name + { + string_t playlist_name; + string_init(playlist_name); + path_extract_filename(app->file_path, playlist_name, true); + + canvas_set_font(canvas, FontPrimary); + draw_centered_boxed_str(canvas, 1, 1, 15, 6, string_get_cstr(playlist_name)); + + string_clear(playlist_name); + } + + canvas_set_font(canvas, FontSecondary); + + // draw loaded count + { + string_t str; + string_init_printf(str, "%d Items in playlist", app->meta->total_count); + canvas_draw_str_aligned(canvas, 1, 19, AlignLeft, AlignTop, string_get_cstr(str)); + string_printf(str, "Repetitions: (single) %d", app->meta->single_repetitions); + canvas_draw_str_aligned(canvas, 1, 29, AlignLeft, AlignTop, string_get_cstr(str)); + string_clear(str); + } + + // draw buttons + draw_corner_aligned(canvas, 40, 15, AlignCenter, AlignBottom); + + canvas_set_color(canvas, ColorWhite); + canvas_draw_str_aligned(canvas, WIDTH / 2 - 7, HEIGHT - 11, AlignLeft, AlignTop, "Start"); + canvas_draw_disc(canvas, WIDTH / 2 - 14, HEIGHT - 8, 3); + + // + canvas_set_color(canvas, ColorBlack); + draw_corner_aligned(canvas, 20, 15, AlignLeft, AlignBottom); + + canvas_set_color(canvas, ColorWhite); + canvas_draw_str_aligned(canvas, 4, HEIGHT - 11, AlignLeft, AlignTop, "R-"); + + // + canvas_set_color(canvas, ColorBlack); + draw_corner_aligned(canvas, 20, 15, AlignRight, AlignBottom); + canvas_set_color(canvas, ColorWhite); + canvas_draw_str_aligned(canvas, WIDTH - 4, HEIGHT - 11, AlignRight, AlignTop, "R+"); + + canvas_set_color(canvas, ColorBlack); + + break; + case STATE_SENDING: // draw progress bar { double progress = (double)app->meta->current_count / (double)app->meta->total_count; @@ -527,8 +593,6 @@ static void input_callback(InputEvent* event, void* ctx) { Playlist* playlist_alloc(DisplayMeta* meta) { Playlist* app = malloc(sizeof(Playlist)); - app->state = 0; - string_init(app->file_path); string_set_str(app->file_path, PLAYLIST_FOLDER); @@ -610,7 +674,7 @@ int32_t playlist_app(void* p) { //////////////////////////////////////////////////////////////////////////////// playlist_start_worker(app, meta); - app->state = STATE_OVERVIEW; + app->meta->state = STATE_OVERVIEW; bool exit_loop = false; InputEvent input; @@ -619,14 +683,28 @@ int32_t playlist_app(void* p) { furi_message_queue_get(app->input_queue, &input, FuriWaitForever) == FuriStatusOk); switch(input.key) { + case InputKeyLeft: + if(input.type == InputTypeShort && app->meta->single_repetitions > 1) { + --app->meta->single_repetitions; + } + break; + + case InputKeyRight: + if(input.type == InputTypeShort) { + ++app->meta->single_repetitions; + } + break; + case InputKeyOk: - // toggle pause state - if(!app->worker->is_running) { - app->worker->ctl_pause = false; - app->worker->ctl_request_exit = false; - playlist_worker_start(app->worker, string_get_cstr(app->file_path)); - } else { - app->worker->ctl_pause = !app->worker->ctl_pause; + if(input.type == InputTypeShort) { + // toggle pause state + if(!app->worker->is_running) { + app->worker->ctl_pause = false; + app->worker->ctl_request_exit = false; + playlist_worker_start(app->worker, string_get_cstr(app->file_path)); + } else { + app->worker->ctl_pause = !app->worker->ctl_pause; + } } break; case InputKeyBack: