| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- #include "remote.h"
- #include "../subghz_remote_app_i.h"
- #include <input/input.h>
- #include <gui/elements.h>
- #include <lib/toolbox/path.h>
- #define SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH 30
- #define SUBREM_VIEW_REMOTE_LEFT_OFFSET 10
- #define SUBREM_VIEW_REMOTE_RIGHT_OFFSET 0
- struct SubRemViewRemote {
- View* view;
- SubRemViewRemoteCallback callback;
- void* context;
- };
- typedef struct {
- char* labels[SubRemSubKeyNameMaxCount];
- SubRemViewRemoteState state;
- uint8_t pressed_btn;
- bool is_external;
- } SubRemViewRemoteModel;
- void subrem_view_remote_set_callback(
- SubRemViewRemote* subrem_view_remote,
- SubRemViewRemoteCallback callback,
- void* context) {
- furi_assert(subrem_view_remote);
- subrem_view_remote->callback = callback;
- subrem_view_remote->context = context;
- }
- void subrem_view_remote_update_data_labels(
- SubRemViewRemote* subrem_view_remote,
- SubRemSubFilePreset** subs_presets) {
- furi_assert(subrem_view_remote);
- furi_assert(subs_presets);
- FuriString* labels[SubRemSubKeyNameMaxCount];
- SubRemSubFilePreset* sub_preset;
- for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) {
- sub_preset = subs_presets[i];
- switch(sub_preset->load_state) {
- case SubRemLoadSubStateOK:
- if(!furi_string_empty(sub_preset->label)) {
- labels[i] = furi_string_alloc_set(sub_preset->label);
- } else if(!furi_string_empty(sub_preset->file_path)) {
- labels[i] = furi_string_alloc();
- path_extract_filename(sub_preset->file_path, labels[i], true);
- } else {
- labels[i] = furi_string_alloc_set("Empty Label");
- }
- break;
- case SubRemLoadSubStateErrorNoFile:
- labels[i] = furi_string_alloc_set("[X] Can't open file");
- break;
- case SubRemLoadSubStateErrorFreq:
- case SubRemLoadSubStateErrorMod:
- case SubRemLoadSubStateErrorProtocol:
- labels[i] = furi_string_alloc_set("[X] Error in .sub file");
- break;
- default:
- labels[i] = furi_string_alloc_set("");
- break;
- }
- }
- with_view_model(
- subrem_view_remote->view,
- SubRemViewRemoteModel * model,
- {
- for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) {
- strncpy(
- model->labels[i],
- furi_string_get_cstr(labels[i]),
- SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH);
- }
- },
- true);
- for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) {
- furi_string_free(labels[i]);
- }
- }
- void subrem_view_remote_set_state(
- SubRemViewRemote* subrem_view_remote,
- SubRemViewRemoteState state,
- uint8_t presed_btn) {
- furi_assert(subrem_view_remote);
- with_view_model(
- subrem_view_remote->view,
- SubRemViewRemoteModel * model,
- {
- model->state = state;
- model->pressed_btn = presed_btn;
- },
- true);
- }
- void subrem_view_remote_set_radio(SubRemViewRemote* subrem_view_remote, bool external) {
- furi_assert(subrem_view_remote);
- with_view_model(
- subrem_view_remote->view,
- SubRemViewRemoteModel * model,
- { model->is_external = external; },
- true);
- }
- void subrem_view_remote_draw(Canvas* canvas, SubRemViewRemoteModel* model) {
- canvas_clear(canvas);
- canvas_set_color(canvas, ColorBlack);
- // Statusbar
- canvas_draw_icon(canvas, 0, 0, &I_status_bar);
- if(model->state == SubRemViewRemoteStateOFF) {
- canvas_invert_color(canvas);
- canvas_draw_rbox(canvas, 12, 0, 52 - 12, 13, 2);
- canvas_invert_color(canvas);
- canvas_draw_rframe(canvas, 12, 0, 52 - 12, 13, 2);
- canvas_draw_str_aligned(canvas, 32, 3, AlignCenter, AlignTop, "Preview");
- } else {
- canvas_draw_icon(
- canvas,
- 0,
- 2,
- (model->is_external) ? &I_External_antenna_20x12 : &I_Internal_antenna_20x12);
- canvas_draw_icon(canvas, 50, 0, &I_Status_cube_14x14);
- if(model->state == SubRemViewRemoteStateSending) {
- canvas_draw_icon_ex(canvas, 52, 3, &I_Pin_arrow_up_7x9, IconRotation90);
- }
- }
- //Icons for Labels
- const uint8_t list_y = 14;
- canvas_draw_icon(canvas, 1, list_y + 5, &I_ButtonUp_7x4);
- canvas_draw_icon(canvas, 1, list_y + 15, &I_ButtonDown_7x4);
- canvas_draw_icon(canvas, 2, list_y + 23, &I_ButtonLeft_4x7);
- canvas_draw_icon(canvas, 2, list_y + 33, &I_ButtonRight_4x7);
- canvas_draw_icon(canvas, 0, list_y + 42, &I_Ok_btn_9x9);
- //Labels
- canvas_set_font(canvas, FontSecondary);
- uint8_t y = list_y;
- for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) {
- elements_text_box(
- canvas,
- SUBREM_VIEW_REMOTE_LEFT_OFFSET,
- y + 2,
- 64 - SUBREM_VIEW_REMOTE_LEFT_OFFSET - SUBREM_VIEW_REMOTE_RIGHT_OFFSET,
- 12,
- AlignLeft,
- AlignBottom,
- model->labels[i],
- false);
- y += 10;
- }
- if(model->state != SubRemViewRemoteStateOFF) {
- // D-pad 59x62
- const uint8_t d_pad_x = 3;
- const uint8_t d_pad_y = 66;
- canvas_draw_icon(canvas, d_pad_x + 1 * (19 + 1), d_pad_y + 0 * (20 + 1), &I_up);
- canvas_draw_icon(canvas, d_pad_x + 0 * (19 + 1), d_pad_y + 1 * (20 + 1), &I_left);
- canvas_draw_icon(canvas, d_pad_x + 1 * (19 + 1), d_pad_y + 1 * (20 + 1), &I_ok);
- canvas_draw_icon(canvas, d_pad_x + 2 * (19 + 1), d_pad_y + 1 * (20 + 1), &I_right);
- canvas_draw_icon(canvas, d_pad_x + 1 * (19 + 1), d_pad_y + 2 * (20 + 1), &I_down);
- if(model->state == SubRemViewRemoteStateSending) {
- switch(model->pressed_btn) {
- case SubRemSubKeyNameUp:
- canvas_draw_icon(
- canvas, d_pad_x + 1 * (19 + 1), d_pad_y + 0 * (20 + 1), &I_up_hover);
- break;
- case SubRemSubKeyNameDown:
- canvas_draw_icon(
- canvas, d_pad_x + 1 * (19 + 1), d_pad_y + 2 * (20 + 1), &I_down_hover);
- break;
- case SubRemSubKeyNameLeft:
- canvas_draw_icon(
- canvas, d_pad_x + 0 * (19 + 1), d_pad_y + 1 * (20 + 1), &I_left_hover);
- break;
- case SubRemSubKeyNameRight:
- canvas_draw_icon(
- canvas, d_pad_x + 2 * (19 + 1), d_pad_y + 1 * (20 + 1), &I_right_hover);
- break;
- case SubRemSubKeyNameOk:
- canvas_draw_icon(
- canvas, d_pad_x + 1 * (19 + 1), d_pad_y + 1 * (20 + 1), &I_ok_hover);
- break;
- default:
- break;
- }
- }
- } else {
- canvas_draw_icon(canvas, 2, 128 - 11, &I_ButtonLeft_4x7);
- canvas_draw_str_aligned(canvas, 8, 128 - 4, AlignLeft, AlignBottom, "Back");
- canvas_draw_icon(canvas, 58, 128 - 11, &I_ButtonRight_4x7);
- canvas_draw_str_aligned(canvas, 56, 128 - 4, AlignRight, AlignBottom, "Save");
- }
- }
- bool subrem_view_remote_input(InputEvent* event, void* context) {
- furi_assert(context);
- SubRemViewRemote* subrem_view_remote = context;
- if(event->key == InputKeyBack && event->type == InputTypePress) {
- bool is_stopping = false;
- with_view_model(
- subrem_view_remote->view,
- SubRemViewRemoteModel * model,
- {
- if(model->state == SubRemViewRemoteStateSending) {
- is_stopping = true;
- model->pressed_btn = 0;
- }
- },
- true);
- //Cant send exit the app inside that with_model,locks the model and the app will hang and not unload!
- if(is_stopping)
- subrem_view_remote->callback(
- SubRemCustomEventViewRemoteForcedStop, subrem_view_remote->context);
- else
- subrem_view_remote->callback(
- SubRemCustomEventViewRemoteBack, subrem_view_remote->context);
- return true;
- }
- // BACK button processing end
- if(event->key == InputKeyUp && event->type == InputTypePress) {
- subrem_view_remote->callback(
- SubRemCustomEventViewRemoteStartUP, subrem_view_remote->context);
- return true;
- } else if(event->key == InputKeyDown && event->type == InputTypePress) {
- subrem_view_remote->callback(
- SubRemCustomEventViewRemoteStartDOWN, subrem_view_remote->context);
- return true;
- } else if(event->key == InputKeyLeft && event->type == InputTypePress) {
- subrem_view_remote->callback(
- SubRemCustomEventViewRemoteStartLEFT, subrem_view_remote->context);
- return true;
- } else if(event->key == InputKeyRight && event->type == InputTypePress) {
- subrem_view_remote->callback(
- SubRemCustomEventViewRemoteStartRIGHT, subrem_view_remote->context);
- return true;
- } else if(event->key == InputKeyOk && event->type == InputTypePress) {
- subrem_view_remote->callback(
- SubRemCustomEventViewRemoteStartOK, subrem_view_remote->context);
- return true;
- } else if(event->type == InputTypeRelease) {
- subrem_view_remote->callback(SubRemCustomEventViewRemoteStop, subrem_view_remote->context);
- return true;
- }
- return true;
- }
- void subrem_view_remote_enter(void* context) {
- furi_assert(context);
- }
- void subrem_view_remote_exit(void* context) {
- furi_assert(context);
- }
- SubRemViewRemote* subrem_view_remote_alloc(void) {
- SubRemViewRemote* subrem_view_remote = malloc(sizeof(SubRemViewRemote));
- // View allocation and configuration
- subrem_view_remote->view = view_alloc();
- view_allocate_model(
- subrem_view_remote->view, ViewModelTypeLocking, sizeof(SubRemViewRemoteModel));
- view_set_context(subrem_view_remote->view, subrem_view_remote);
- view_set_orientation(subrem_view_remote->view, ViewOrientationVertical);
- view_set_draw_callback(subrem_view_remote->view, (ViewDrawCallback)subrem_view_remote_draw);
- view_set_input_callback(subrem_view_remote->view, subrem_view_remote_input);
- view_set_enter_callback(subrem_view_remote->view, subrem_view_remote_enter);
- view_set_exit_callback(subrem_view_remote->view, subrem_view_remote_exit);
- with_view_model(
- subrem_view_remote->view,
- SubRemViewRemoteModel * model,
- {
- model->state = SubRemViewRemoteStateIdle;
- for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) {
- model->labels[i] = malloc(sizeof(char) * SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH + 1);
- strcpy(model->labels[i], "");
- }
- model->pressed_btn = 0;
- model->is_external = false;
- },
- true);
- return subrem_view_remote;
- }
- void subrem_view_remote_free(SubRemViewRemote* subghz_remote) {
- furi_assert(subghz_remote);
- with_view_model(
- subghz_remote->view,
- SubRemViewRemoteModel * model,
- {
- for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) {
- free(model->labels[i]);
- }
- },
- true);
- view_free(subghz_remote->view);
- free(subghz_remote);
- }
- View* subrem_view_remote_get_view(SubRemViewRemote* subrem_view_remote) {
- furi_assert(subrem_view_remote);
- return subrem_view_remote->view;
- }
|