From 48e4de121371ecea082655d8e09a78e449b4a87b Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Sun, 14 Jan 2024 08:58:29 +0400 Subject: [PATCH] [FL-3743] SubGhz: UI update (#3352) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [FL-3743]SubGhz: screen refactoring * SubGhz: fix syntax * SubGhz: gui * SubGhz: add animation icon ant in read_info scene * SubGhz: up speed animation icon Co-authored-by: あく --- .../main/subghz/helpers/subghz_custom_event.h | 2 + .../main/subghz/scenes/subghz_scene_delete.c | 54 +++++---- .../subghz/scenes/subghz_scene_delete_raw.c | 47 +++----- .../subghz/scenes/subghz_scene_need_saving.c | 16 +-- .../scenes/subghz_scene_receiver_info.c | 105 +++++++----------- .../subghz/scenes/subghz_scene_region_info.c | 10 +- .../subghz/scenes/subghz_scene_save_name.c | 2 +- .../main/subghz/scenes/subghz_scene_saved.c | 2 + .../subghz/scenes/subghz_scene_transmitter.c | 2 + applications/main/subghz/views/receiver.c | 4 +- .../subghz/views/subghz_frequency_analyzer.c | 2 +- .../main/subghz/views/subghz_read_raw.c | 4 +- applications/main/subghz/views/transmitter.c | 56 +++++++++- applications/main/subghz/views/transmitter.h | 9 ++ assets/icons/SubGhz/External_ant_1_9x11.png | Bin 0 -> 1092 bytes .../icons/SubGhz/External_antenna_20x12.png | Bin 990 -> 0 bytes assets/icons/SubGhz/Internal_ant_1_9x11.png | Bin 0 -> 1111 bytes .../icons/SubGhz/Internal_antenna_20x12.png | Bin 994 -> 0 bytes .../SubGhz/SubGhz_External_ant/frame_01.png | Bin 0 -> 1092 bytes .../SubGhz/SubGhz_External_ant/frame_02.png | Bin 0 -> 1097 bytes .../SubGhz/SubGhz_External_ant/frame_03.png | Bin 0 -> 1079 bytes .../SubGhz/SubGhz_External_ant/frame_04.png | Bin 0 -> 1085 bytes .../SubGhz/SubGhz_External_ant/frame_rate | 1 + .../SubGhz/SubGhz_Internal_ant/frame_01.png | Bin 0 -> 1111 bytes .../SubGhz/SubGhz_Internal_ant/frame_02.png | Bin 0 -> 1111 bytes .../SubGhz/SubGhz_Internal_ant/frame_03.png | Bin 0 -> 1110 bytes .../SubGhz/SubGhz_Internal_ant/frame_04.png | Bin 0 -> 1110 bytes .../SubGhz/SubGhz_Internal_ant/frame_rate | 1 + 28 files changed, 180 insertions(+), 137 deletions(-) create mode 100644 assets/icons/SubGhz/External_ant_1_9x11.png delete mode 100644 assets/icons/SubGhz/External_antenna_20x12.png create mode 100644 assets/icons/SubGhz/Internal_ant_1_9x11.png delete mode 100644 assets/icons/SubGhz/Internal_antenna_20x12.png create mode 100644 assets/icons/SubGhz/SubGhz_External_ant/frame_01.png create mode 100644 assets/icons/SubGhz/SubGhz_External_ant/frame_02.png create mode 100644 assets/icons/SubGhz/SubGhz_External_ant/frame_03.png create mode 100644 assets/icons/SubGhz/SubGhz_External_ant/frame_04.png create mode 100644 assets/icons/SubGhz/SubGhz_External_ant/frame_rate create mode 100644 assets/icons/SubGhz/SubGhz_Internal_ant/frame_01.png create mode 100644 assets/icons/SubGhz/SubGhz_Internal_ant/frame_02.png create mode 100644 assets/icons/SubGhz/SubGhz_Internal_ant/frame_03.png create mode 100644 assets/icons/SubGhz/SubGhz_Internal_ant/frame_04.png create mode 100644 assets/icons/SubGhz/SubGhz_Internal_ant/frame_rate diff --git a/applications/main/subghz/helpers/subghz_custom_event.h b/applications/main/subghz/helpers/subghz_custom_event.h index 285b4a60..fe2c08fc 100644 --- a/applications/main/subghz/helpers/subghz_custom_event.h +++ b/applications/main/subghz/helpers/subghz_custom_event.h @@ -26,6 +26,7 @@ typedef enum { //SubGhzCustomEvent SubGhzCustomEventSceneDeleteSuccess = 100, SubGhzCustomEventSceneDelete, + SubGhzCustomEventSceneDeleteBack, SubGhzCustomEventSceneDeleteRAW, SubGhzCustomEventSceneDeleteRAWBack, @@ -70,5 +71,6 @@ typedef enum { SubGhzCustomEventViewTransmitterBack, SubGhzCustomEventViewTransmitterSendStart, SubGhzCustomEventViewTransmitterSendStop, + SubGhzCustomEventViewTransmitterSendSave, SubGhzCustomEventViewTransmitterError, } SubGhzCustomEvent; diff --git a/applications/main/subghz/scenes/subghz_scene_delete.c b/applications/main/subghz/scenes/subghz_scene_delete.c index 0d14cd23..8092845a 100644 --- a/applications/main/subghz/scenes/subghz_scene_delete.c +++ b/applications/main/subghz/scenes/subghz_scene_delete.c @@ -6,47 +6,57 @@ void subghz_scene_delete_callback(GuiButtonType result, InputType type, void* co SubGhz* subghz = context; if((result == GuiButtonTypeRight) && (type == InputTypeShort)) { view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneDelete); + } else if((result == GuiButtonTypeLeft) && (type == InputTypeShort)) { + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubGhzCustomEventSceneDeleteBack); } } void subghz_scene_delete_on_enter(void* context) { SubGhz* subghz = context; + FuriString* frequency_str; FuriString* modulation_str; + FuriString* text_out; FuriString* text; + text_out = furi_string_alloc(); + text = furi_string_alloc(); + + path_extract_filename(subghz->file_path, text, true); + furi_string_cat_printf(text_out, "\e#Delete %s?\e#\n", furi_string_get_cstr(text)); + + furi_string_reset(text); + subghz_protocol_decoder_base_get_string(subghz_txrx_get_decoder(subghz->txrx), text); + + size_t dot = furi_string_search_char(text, '\r'); + if(dot > 0) { + furi_string_left(text, dot); + } + furi_string_cat_printf(text_out, "%s\n", furi_string_get_cstr(text)); + + furi_string_free(text); frequency_str = furi_string_alloc(); modulation_str = furi_string_alloc(); - text = furi_string_alloc(); - subghz_txrx_get_frequency_and_modulation(subghz->txrx, frequency_str, modulation_str); - widget_add_string_element( - subghz->widget, - 78, - 0, - AlignLeft, - AlignTop, - FontSecondary, - furi_string_get_cstr(frequency_str)); - widget_add_string_element( - subghz->widget, - 113, - 0, - AlignLeft, - AlignTop, - FontSecondary, + furi_string_cat_printf( + text_out, + "%s %s", + furi_string_get_cstr(frequency_str), furi_string_get_cstr(modulation_str)); - subghz_protocol_decoder_base_get_string(subghz_txrx_get_decoder(subghz->txrx), text); - widget_add_string_multiline_element( - subghz->widget, 0, 0, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(text)); + + widget_add_text_box_element( + subghz->widget, 0, 0, 128, 54, AlignCenter, AlignTop, furi_string_get_cstr(text_out), false); furi_string_free(frequency_str); furi_string_free(modulation_str); - furi_string_free(text); + furi_string_free(text_out); widget_add_button_element( subghz->widget, GuiButtonTypeRight, "Delete", subghz_scene_delete_callback, subghz); + widget_add_button_element( + subghz->widget, GuiButtonTypeLeft, "Cancel", subghz_scene_delete_callback, subghz); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdWidget); } @@ -63,6 +73,8 @@ bool subghz_scene_delete_on_event(void* context, SceneManagerEvent event) { subghz->scene_manager, SubGhzSceneStart); } return true; + } else if(event.event == SubGhzCustomEventSceneDeleteBack) { + return scene_manager_previous_scene(subghz->scene_manager); } } return false; diff --git a/applications/main/subghz/scenes/subghz_scene_delete_raw.c b/applications/main/subghz/scenes/subghz_scene_delete_raw.c index 8dff442a..53f13b68 100644 --- a/applications/main/subghz/scenes/subghz_scene_delete_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_delete_raw.c @@ -17,48 +17,37 @@ void subghz_scene_delete_raw_on_enter(void* context) { SubGhz* subghz = context; FuriString* frequency_str; FuriString* modulation_str; + FuriString* text_out; + FuriString* file_name; + text_out = furi_string_alloc(); + file_name = furi_string_alloc(); + + path_extract_filename(subghz->file_path, file_name, true); + furi_string_cat_printf( + text_out, "\e#Delete %s?\e#\nRAW signal\n", furi_string_get_cstr(file_name)); + furi_string_free(file_name); frequency_str = furi_string_alloc(); modulation_str = furi_string_alloc(); + subghz_txrx_get_frequency_and_modulation(subghz->txrx, frequency_str, modulation_str); - char delete_str[SUBGHZ_MAX_LEN_NAME + 16]; - FuriString* file_name; - file_name = furi_string_alloc(); - path_extract_filename(subghz->file_path, file_name, true); - snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", furi_string_get_cstr(file_name)); - furi_string_free(file_name); + furi_string_cat_printf( + text_out, + "%s %s", + furi_string_get_cstr(frequency_str), + furi_string_get_cstr(modulation_str)); widget_add_text_box_element( - subghz->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, delete_str, false); - - widget_add_string_element( - subghz->widget, 38, 25, AlignLeft, AlignTop, FontSecondary, "RAW signal"); - subghz_txrx_get_frequency_and_modulation(subghz->txrx, frequency_str, modulation_str); - widget_add_string_element( - subghz->widget, - 35, - 37, - AlignLeft, - AlignTop, - FontSecondary, - furi_string_get_cstr(frequency_str)); - - widget_add_string_element( - subghz->widget, - 72, - 37, - AlignLeft, - AlignTop, - FontSecondary, - furi_string_get_cstr(modulation_str)); + subghz->widget, 0, 0, 128, 54, AlignCenter, AlignTop, furi_string_get_cstr(text_out), false); furi_string_free(frequency_str); furi_string_free(modulation_str); + furi_string_free(text_out); widget_add_button_element( subghz->widget, GuiButtonTypeRight, "Delete", subghz_scene_delete_raw_callback, subghz); widget_add_button_element( - subghz->widget, GuiButtonTypeLeft, "Back", subghz_scene_delete_raw_callback, subghz); + subghz->widget, GuiButtonTypeLeft, "Cancel", subghz_scene_delete_raw_callback, subghz); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdWidget); } diff --git a/applications/main/subghz/scenes/subghz_scene_need_saving.c b/applications/main/subghz/scenes/subghz_scene_need_saving.c index f29f2630..90c72a0d 100644 --- a/applications/main/subghz/scenes/subghz_scene_need_saving.c +++ b/applications/main/subghz/scenes/subghz_scene_need_saving.c @@ -15,16 +15,16 @@ void subghz_scene_need_saving_callback(GuiButtonType result, InputType type, voi void subghz_scene_need_saving_on_enter(void* context) { SubGhz* subghz = context; - widget_add_string_multiline_element( - subghz->widget, 64, 13, AlignCenter, AlignCenter, FontPrimary, "Exit to Sub-GHz Menu?"); - widget_add_string_multiline_element( + widget_add_text_box_element( subghz->widget, - 64, - 32, + 0, + 0, + 128, + 54, AlignCenter, - AlignCenter, - FontSecondary, - "All unsaved data\nwill be lost!"); + AlignTop, + "\e#Exit to Sub-GHz Menu?\e#\nAll unsaved data will be lost", + false); widget_add_button_element( subghz->widget, GuiButtonTypeRight, "Stay", subghz_scene_need_saving_callback, subghz); diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_info.c b/applications/main/subghz/scenes/subghz_scene_receiver_info.c index 08d4caec..4ab1e7ad 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_info.c @@ -1,20 +1,11 @@ #include "../subghz_i.h" #include "../helpers/subghz_custom_event.h" +#include "../views/transmitter.h" -void subghz_scene_receiver_info_callback(GuiButtonType result, InputType type, void* context) { +void subghz_scene_receiver_info_callback(SubGhzCustomEvent event, void* context) { furi_assert(context); SubGhz* subghz = context; - - if((result == GuiButtonTypeCenter) && (type == InputTypePress)) { - view_dispatcher_send_custom_event( - subghz->view_dispatcher, SubGhzCustomEventSceneReceiverInfoTxStart); - } else if((result == GuiButtonTypeCenter) && (type == InputTypeRelease)) { - view_dispatcher_send_custom_event( - subghz->view_dispatcher, SubGhzCustomEventSceneReceiverInfoTxStop); - } else if((result == GuiButtonTypeRight) && (type == InputTypeShort)) { - view_dispatcher_send_custom_event( - subghz->view_dispatcher, SubGhzCustomEventSceneReceiverInfoSave); - } + view_dispatcher_send_custom_event(subghz->view_dispatcher, event); } static bool subghz_scene_receiver_info_update_parser(void* context) { @@ -37,6 +28,28 @@ static bool subghz_scene_receiver_info_update_parser(void* context) { preset->data, preset->data_size); + FuriString* key_str = furi_string_alloc(); + FuriString* frequency_str = furi_string_alloc(); + FuriString* modulation_str = furi_string_alloc(); + + subghz_protocol_decoder_base_get_string(subghz_txrx_get_decoder(subghz->txrx), key_str); + subghz_txrx_get_frequency_and_modulation(subghz->txrx, frequency_str, modulation_str); + subghz_view_transmitter_add_data_to_show( + subghz->subghz_transmitter, + furi_string_get_cstr(key_str), + furi_string_get_cstr(frequency_str), + furi_string_get_cstr(modulation_str), + subghz_txrx_protocol_is_transmittable(subghz->txrx, true)); + + furi_string_free(frequency_str); + furi_string_free(modulation_str); + furi_string_free(key_str); + + subghz_view_transmitter_set_radio_device_type( + subghz->subghz_transmitter, subghz_txrx_radio_device_get(subghz->txrx)); + subghz_view_transmitter_set_model_type( + subghz->subghz_transmitter, SubGhzViewTransmitterModelTypeInfo); + return true; } return false; @@ -44,67 +57,23 @@ static bool subghz_scene_receiver_info_update_parser(void* context) { void subghz_scene_receiver_info_on_enter(void* context) { SubGhz* subghz = context; - if(subghz_scene_receiver_info_update_parser(subghz)) { - FuriString* frequency_str = furi_string_alloc(); - FuriString* modulation_str = furi_string_alloc(); - FuriString* text = furi_string_alloc(); - - subghz_txrx_get_frequency_and_modulation(subghz->txrx, frequency_str, modulation_str); - widget_add_string_element( - subghz->widget, - 78, - 0, - AlignLeft, - AlignTop, - FontSecondary, - furi_string_get_cstr(frequency_str)); - - widget_add_string_element( - subghz->widget, - 113, - 0, - AlignLeft, - AlignTop, - FontSecondary, - furi_string_get_cstr(modulation_str)); - subghz_protocol_decoder_base_get_string(subghz_txrx_get_decoder(subghz->txrx), text); - widget_add_string_multiline_element( - subghz->widget, 0, 0, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(text)); - - furi_string_free(frequency_str); - furi_string_free(modulation_str); - furi_string_free(text); - - if(subghz_txrx_protocol_is_serializable(subghz->txrx)) { - widget_add_button_element( - subghz->widget, - GuiButtonTypeRight, - "Save", - subghz_scene_receiver_info_callback, - subghz); - } - if(subghz_txrx_protocol_is_transmittable(subghz->txrx, true)) { - widget_add_button_element( - subghz->widget, - GuiButtonTypeCenter, - "Send", - subghz_scene_receiver_info_callback, - subghz); - } } else { - widget_add_icon_element(subghz->widget, 83, 22, &I_WarningDolphinFlip_45x42); - widget_add_string_element( - subghz->widget, 13, 8, AlignLeft, AlignBottom, FontSecondary, "Error history parse."); + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubGhzCustomEventSceneShowErrorSub); } - view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdWidget); + subghz_view_transmitter_set_callback( + subghz->subghz_transmitter, subghz_scene_receiver_info_callback, subghz); + + subghz->state_notifications = SubGhzNotificationStateIDLE; + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdTransmitter); } bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubGhzCustomEventSceneReceiverInfoTxStart) { + if(event.event == SubGhzCustomEventViewTransmitterSendStart) { if(!subghz_scene_receiver_info_update_parser(subghz)) { return false; } @@ -120,7 +89,7 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) subghz->state_notifications = SubGhzNotificationStateTx; } return true; - } else if(event.event == SubGhzCustomEventSceneReceiverInfoTxStop) { + } else if(event.event == SubGhzCustomEventViewTransmitterSendStop) { //CC1101 Stop Tx -> Start RX subghz->state_notifications = SubGhzNotificationStateIDLE; @@ -129,7 +98,7 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) subghz_txrx_hopper_unpause(subghz->txrx); subghz->state_notifications = SubGhzNotificationStateRx; return true; - } else if(event.event == SubGhzCustomEventSceneReceiverInfoSave) { + } else if(event.event == SubGhzCustomEventViewTransmitterSendSave) { //CC1101 Stop RX -> Save subghz->state_notifications = SubGhzNotificationStateIDLE; subghz_txrx_hopper_set_state(subghz->txrx, SubGhzHopperStateOFF); @@ -144,7 +113,11 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); } return true; + } else if(event.event == SubGhzCustomEventSceneShowErrorSub) { + furi_string_set(subghz->error_str, "Error history parse."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); } + } else if(event.type == SceneManagerEventTypeTick) { if(subghz_txrx_hopper_get_state(subghz->txrx) != SubGhzHopperStateOFF) { subghz_txrx_hopper_update(subghz->txrx); diff --git a/applications/main/subghz/scenes/subghz_scene_region_info.c b/applications/main/subghz/scenes/subghz_scene_region_info.c index b98394af..61bd1acc 100644 --- a/applications/main/subghz/scenes/subghz_scene_region_info.c +++ b/applications/main/subghz/scenes/subghz_scene_region_info.c @@ -6,12 +6,13 @@ void subghz_scene_region_info_on_enter(void* context) { SubGhz* subghz = context; const FuriHalRegion* const region = furi_hal_region_get(); FuriString* buffer = furi_string_alloc(); + if(region) { - furi_string_cat_printf(buffer, "Region: %s, bands:\n", region->country_code); + furi_string_cat_printf(buffer, "Region: %s\nBands:\n", region->country_code); for(uint16_t i = 0; i < region->bands_count; ++i) { furi_string_cat_printf( buffer, - " %lu-%lu kHz\n", + "%lu-%lu kHz\n", region->bands[i].start / 1000, region->bands[i].end / 1000); } @@ -20,7 +21,10 @@ void subghz_scene_region_info_on_enter(void* context) { } widget_add_string_multiline_element( - subghz->widget, 0, 0, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(buffer)); + subghz->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Region Information"); + + widget_add_string_multiline_element( + subghz->widget, 0, 13, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(buffer)); furi_string_free(buffer); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdWidget); diff --git a/applications/main/subghz/scenes/subghz_scene_save_name.c b/applications/main/subghz/scenes/subghz_scene_save_name.c index 394dda89..30d0821e 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_name.c +++ b/applications/main/subghz/scenes/subghz_scene_save_name.c @@ -132,7 +132,7 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet); } else { - subghz_file_name_clear(subghz); + furi_string_reset(subghz->file_path_tmp); } scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveSuccess); diff --git a/applications/main/subghz/scenes/subghz_scene_saved.c b/applications/main/subghz/scenes/subghz_scene_saved.c index 8b198e33..3daedd33 100644 --- a/applications/main/subghz/scenes/subghz_scene_saved.c +++ b/applications/main/subghz/scenes/subghz_scene_saved.c @@ -22,5 +22,7 @@ bool subghz_scene_saved_on_event(void* context, SceneManagerEvent event) { } void subghz_scene_saved_on_exit(void* context) { + SubGhz* subghz = context; + scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneSavedMenu, 0); UNUSED(context); } diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index f83e44a0..cbc4e7d8 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -37,6 +37,8 @@ bool subghz_scene_transmitter_update_data_show(void* context) { } subghz_view_transmitter_set_radio_device_type( subghz->subghz_transmitter, subghz_txrx_radio_device_get(subghz->txrx)); + subghz_view_transmitter_set_model_type( + subghz->subghz_transmitter, SubGhzViewTransmitterModelTypeTx); return ret; } diff --git a/applications/main/subghz/views/receiver.c b/applications/main/subghz/views/receiver.c index 23fa26c7..9dfe85d1 100644 --- a/applications/main/subghz/views/receiver.c +++ b/applications/main/subghz/views/receiver.c @@ -251,9 +251,9 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { } if(model->device_type == SubGhzRadioDeviceTypeInternal) { - canvas_draw_icon(canvas, 108, 0, &I_Internal_antenna_20x12); + canvas_draw_icon(canvas, 109, 0, &I_Internal_ant_1_9x11); } else { - canvas_draw_icon(canvas, 108, 0, &I_External_antenna_20x12); + canvas_draw_icon(canvas, 109, 0, &I_External_ant_1_9x11); } subghz_view_rssi_draw(canvas, model); diff --git a/applications/main/subghz/views/subghz_frequency_analyzer.c b/applications/main/subghz/views/subghz_frequency_analyzer.c index d9040167..5a4afa63 100644 --- a/applications/main/subghz/views/subghz_frequency_analyzer.c +++ b/applications/main/subghz/views/subghz_frequency_analyzer.c @@ -178,7 +178,7 @@ void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel subghz_frequency_analyzer_log_frequency_draw(canvas, model); } else { canvas_draw_str(canvas, 0, 8, "Frequency Analyzer"); - canvas_draw_icon(canvas, 108, 0, &I_Internal_antenna_20x12); + canvas_draw_icon(canvas, 109, 0, &I_Internal_ant_1_9x11); canvas_draw_str(canvas, 0, 64, "RSSI"); subghz_frequency_analyzer_draw_rssi(canvas, model->rssi, 20, 64); diff --git a/applications/main/subghz/views/subghz_read_raw.c b/applications/main/subghz/views/subghz_read_raw.c index d630d47e..cf64567c 100644 --- a/applications/main/subghz/views/subghz_read_raw.c +++ b/applications/main/subghz/views/subghz_read_raw.c @@ -294,9 +294,9 @@ void subghz_read_raw_draw(Canvas* canvas, SubGhzReadRAWModel* model) { canvas, 106, 2, AlignRight, AlignTop, furi_string_get_cstr(model->sample_write)); if(model->device_type == SubGhzRadioDeviceTypeInternal) { - canvas_draw_icon(canvas, 108, 0, &I_Internal_antenna_20x12); + canvas_draw_icon(canvas, 109, 0, &I_Internal_ant_1_9x11); } else { - canvas_draw_icon(canvas, 108, 0, &I_External_antenna_20x12); + canvas_draw_icon(canvas, 109, 0, &I_External_ant_1_9x11); } canvas_draw_line(canvas, 0, 14, 115, 14); canvas_draw_line(canvas, 0, 48, 115, 48); diff --git a/applications/main/subghz/views/transmitter.c b/applications/main/subghz/views/transmitter.c index 2a876f8c..45c07acc 100644 --- a/applications/main/subghz/views/transmitter.c +++ b/applications/main/subghz/views/transmitter.c @@ -16,6 +16,9 @@ typedef struct { FuriString* key_str; bool show_button; SubGhzRadioDeviceType device_type; + SubGhzViewTransmitterModelType model_type; + IconAnimation* icon_int_ant; + IconAnimation* icon_ext_ant; } SubGhzViewTransmitterModel; void subghz_view_transmitter_set_callback( @@ -58,6 +61,17 @@ void subghz_view_transmitter_set_radio_device_type( true); } +void subghz_view_transmitter_set_model_type( + SubGhzViewTransmitter* subghz_transmitter, + SubGhzViewTransmitterModelType model_type) { + furi_assert(subghz_transmitter); + with_view_model( + subghz_transmitter->view, + SubGhzViewTransmitterModel * model, + { model->model_type = model_type; }, + true); +} + static void subghz_view_transmitter_button_right(Canvas* canvas, const char* str) { const uint8_t button_height = 12; const uint8_t vertical_offset = 3; @@ -100,13 +114,21 @@ void subghz_view_transmitter_draw(Canvas* canvas, SubGhzViewTransmitterModel* mo canvas, 0, 0, AlignLeft, AlignTop, furi_string_get_cstr(model->key_str)); canvas_draw_str(canvas, 78, 7, furi_string_get_cstr(model->frequency_str)); canvas_draw_str(canvas, 113, 7, furi_string_get_cstr(model->preset_str)); + if(model->show_button) { - if(model->device_type == SubGhzRadioDeviceTypeInternal) { - canvas_draw_icon(canvas, 108, 39, &I_Internal_antenna_20x12); + if(model->model_type == SubGhzViewTransmitterModelTypeInfo) { + elements_button_center(canvas, "Send"); + elements_button_right(canvas, "Save"); } else { - canvas_draw_icon(canvas, 108, 39, &I_External_antenna_20x12); + //default type SubGhzViewTransmitterModelTypeTx + subghz_view_transmitter_button_right(canvas, "Send"); + } + + if(model->device_type == SubGhzRadioDeviceTypeInternal) { + canvas_draw_icon_animation(canvas, 109, 40, model->icon_int_ant); + } else { + canvas_draw_icon_animation(canvas, 109, 40, model->icon_ext_ant); } - subghz_view_transmitter_button_right(canvas, "Send"); } } @@ -140,13 +162,32 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) { true); if(can_be_sent && event->key == InputKeyOk && event->type == InputTypePress) { + with_view_model( + subghz_transmitter->view, + SubGhzViewTransmitterModel * model, + { + icon_animation_start(model->icon_int_ant); + icon_animation_start(model->icon_ext_ant); + }, + false); subghz_transmitter->callback( SubGhzCustomEventViewTransmitterSendStart, subghz_transmitter->context); return true; } else if(can_be_sent && event->key == InputKeyOk && event->type == InputTypeRelease) { + with_view_model( + subghz_transmitter->view, + SubGhzViewTransmitterModel * model, + { + icon_animation_stop(model->icon_int_ant); + icon_animation_stop(model->icon_ext_ant); + }, + false); subghz_transmitter->callback( SubGhzCustomEventViewTransmitterSendStop, subghz_transmitter->context); return true; + } else if(can_be_sent && event->key == InputKeyRight && event->type == InputTypeShort) { + subghz_transmitter->callback( + SubGhzCustomEventViewTransmitterSendSave, subghz_transmitter->context); } return true; @@ -181,6 +222,11 @@ SubGhzViewTransmitter* subghz_view_transmitter_alloc() { model->frequency_str = furi_string_alloc(); model->preset_str = furi_string_alloc(); model->key_str = furi_string_alloc(); + model->model_type = SubGhzViewTransmitterModelTypeTx; + model->icon_int_ant = icon_animation_alloc(&A_SubGhz_Internal_ant); + view_tie_icon_animation(subghz_transmitter->view, model->icon_int_ant); + model->icon_ext_ant = icon_animation_alloc(&A_SubGhz_External_ant); + view_tie_icon_animation(subghz_transmitter->view, model->icon_ext_ant); }, true); return subghz_transmitter; @@ -196,6 +242,8 @@ void subghz_view_transmitter_free(SubGhzViewTransmitter* subghz_transmitter) { furi_string_free(model->frequency_str); furi_string_free(model->preset_str); furi_string_free(model->key_str); + icon_animation_free(model->icon_int_ant); + icon_animation_free(model->icon_ext_ant); }, true); view_free(subghz_transmitter->view); diff --git a/applications/main/subghz/views/transmitter.h b/applications/main/subghz/views/transmitter.h index 19da3145..e22898ad 100644 --- a/applications/main/subghz/views/transmitter.h +++ b/applications/main/subghz/views/transmitter.h @@ -6,6 +6,11 @@ typedef struct SubGhzViewTransmitter SubGhzViewTransmitter; +typedef enum { + SubGhzViewTransmitterModelTypeTx, + SubGhzViewTransmitterModelTypeInfo, +} SubGhzViewTransmitterModelType; + typedef void (*SubGhzViewTransmitterCallback)(SubGhzCustomEvent event, void* context); void subghz_view_transmitter_set_callback( @@ -17,6 +22,10 @@ void subghz_view_transmitter_set_radio_device_type( SubGhzViewTransmitter* subghz_transmitter, SubGhzRadioDeviceType device_type); +void subghz_view_transmitter_set_model_type( + SubGhzViewTransmitter* subghz_transmitter, + SubGhzViewTransmitterModelType model_type); + SubGhzViewTransmitter* subghz_view_transmitter_alloc(); void subghz_view_transmitter_free(SubGhzViewTransmitter* subghz_transmitter); diff --git a/assets/icons/SubGhz/External_ant_1_9x11.png b/assets/icons/SubGhz/External_ant_1_9x11.png new file mode 100644 index 0000000000000000000000000000000000000000..175f16048c577901dd1fde5ef322371a9a4cb776 GIT binary patch literal 1092 zcmbVLOK8+U7!DL_=>x%Ds;4pa(1J-OukI#vt?MRh7n-_kSKNb#<}vApHkp`AyXhjL z#f#9J7tfxGh>SVWDJ(MB_l7D9Mec%7j|9DhizCJN}VU%H* ziQ1ykpmvhJVyWA#djxJ_}>YW|;YfEVkWsM1X_Vf~drPfAxk1fmdR0sTQ>23Tg+7-2|<4mz!>P z-PJsH;R=|~bSe-cVuLK)h*CW(u{~X#uJdDo1w9B^FR}fgT2>uYaDsrwi<}Fg1PU7O z%c_EWw*W5#2}-gciUQO)QPQERt1>uxSn4qGe7#{*kKEB+iER@S>w?hfboh?U<77<` zHBA$sBuElR5nQ?*5j*3ebb6p*pwvx*m;^WixuWghO;TcMu>D(vv1J_#N9j?nXx4!DN9K!3tG5uG--VINmc*YPkZJl(ca#HZH2RGspmnh~4D4=( zC?YkZ#L_>!7kIkuYOX3fkn<&^a7qytIY*n*IM4H4UlUzfvC%;1Bz~c67Dd&Bng)xa zXqsh1QLFMCtY~G~ESrS^w-%+uj$AbG9Z=tWu2DUet5*_a6Pz?L-WW7Oy^RS@+c*Z2 z$}3JZUJRcNd9G-gX>@MEjn;PDk+}*qV+Q!$5 literal 0 HcmV?d00001 diff --git a/assets/icons/SubGhz/External_antenna_20x12.png b/assets/icons/SubGhz/External_antenna_20x12.png deleted file mode 100644 index 940087071a1c4225eb48383e3a93d5c841b638b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 990 zcmaJ=zi-n(6t>hBswf?bK&VV7S4dPe_W6LTf33i9am!vER3maae$(r__=1^b4 zsgIQSAx8^Bc`FIA(@%PtnBJf;Yd{MNa9h#))?T#XHFxqc8qrRiM;?^@z zPBc#76NW+J9|f_N=;D}H<9ceAMKE?@eOlf;6R|p#qpZB99ok9j$KdOycpAF7_A;HCY}E2GSre(Womcs;Z_O2<5m( zE*=I9C%GVApE6h^b|Noi9t}Xsh}-mp=_1eex(q*@(FXCPRlI3(fiaYAnAOQmzW*eS8^e&ubrRE)$l=55tf!$u&5Q_UG-^vCn{I?3^2ip6yqCn?iKq|8Rcqe-T+F$A6RbNw7i%t7=E=zEZ2y|| z)WjDkRcG7F53~Iz0blxvZ}*$#t7Z;p>#9uWj#ygqL? z`Fx50qr(Gyd@))Z=2MPUSJ_JBu?|kCP@h`|c+?BM1Y}{njd5Z7f(M z3S^vN@2p(&IUoQ zIC~w;bS+L0P=-M_*bGyvTN00WExyi<6%iak*hWb_7PZ<~29+qG0Lhv}R26~(l0Drt zs7DIwH2_tpE1IULNYbFCnwF`9-Y0U0iR)QSyVi5ZcO`M1vDi|SPNySxbU8}a6b&Jy zs8E4W;s`0-4jJxBVLI7ouxUyXKW2Uuf{YP6(H1L-TS2_mNMsFDY%AsI!rC^;yPB-izbhcu!anD%+jvM*F>d8i>9A+@4u)oR%` z%$lB8E2ykj%hf{PwjQPohlKWh``mZWwsNkmRY@pjQPPT{&3+*)uSYCO*P|FfQ#Qa< zmUs=S1v!wR0rS8>rUPAV8i1(=CVrTKr?Uhe$HS(He~-GgBnrS$1}y(9b&duR(F+nS zXYZbh>~RtE6aK=uFVuowQN@%LBojKA4~8i@1}`v# zpkr|9RHKflaEVG*RHurpf5a;{Tb^_c-<Ik>#gsvaI5^5yLh zpYQX@s@vsO_q)?>+e2exHy#d7>>pel`Ee_^|FvxAa_vW&_+;)c-h2N=d-m<==Fr~T fiQgZ8UU(o32v-k;wO>nDa-2n|R~PM9bM4)K-N#v< literal 0 HcmV?d00001 diff --git a/assets/icons/SubGhz/Internal_antenna_20x12.png b/assets/icons/SubGhz/Internal_antenna_20x12.png deleted file mode 100644 index a8a5be09fb87ab29d5eccda96c07de44b465be0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 994 zcmaJ=y>HV%6gRB|C29u*3tc$5LZVXRk4r*o6H_^HN`vYuq=9C{u`i9)p3m49;&em^ zfspzyAO@HKu~vL^r4xb$0YYMBKrk{Og>$~j5U^~&cTey4d%t)0?p}HA(oAAD!ExM7 zX~n28dy0M2Qt%PmE|Wp5!0>S)vTH2%kneIB@u#&2Xy$@B}T>8|VqXnkj`YVT~> zio-8m1i46M1Q<~ZM0nc^)kx!eyejkKu*id63fx1^uoCzgMmUjaDD0$55$aCowTUNGqwFTus@>p!ogOtO%o%_7iB?; z+ZraC=KoVM9%YBLf)4eLB@U|{ABhzdl2%}|!)wgNrF^vzAd8ZqO33zbC(BJjN!TPl zfN3EE&Y70&dU0gF2Qf{x!{g6=6pJ%>k=%aWVu+>mBp+A^G06Q z^$b+9L##pU7DgT&Vx2>5{-4-*BCyXY8z^vZB4;@u81%YU-7#A7c|9c+78S+^$7|_h zoiSPl*tn1JSdoblx%Ds;4pa(1J-OukI#vt?MRh7n-_kSKNb#<}vApHkp`AyXhjL z#f#9J7tfxGh>SVWDJ(MB_l7D9Mec%7j|9DhizCJN}VU%H* ziQ1ykpmvhJVyWA#djxJ_}>YW|;YfEVkWsM1X_Vf~drPfAxk1fmdR0sTQ>23Tg+7-2|<4mz!>P z-PJsH;R=|~bSe-cVuLK)h*CW(u{~X#uJdDo1w9B^FR}fgT2>uYaDsrwi<}Fg1PU7O z%c_EWw*W5#2}-gciUQO)QPQERt1>uxSn4qGe7#{*kKEB+iER@S>w?hfboh?U<77<` zHBA$sBuElR5nQ?*5j*3ebb6p*pwvx*m;^WixuWghO;TcMu>D(vv1J_#N9j?nXx4!DN9K!3tG5uG--VINmc*YPkZJl(ca#HZH2RGspmnh~4D4=( zC?YkZ#L_>!7kIkuYOX3fkn<&^a7qytIY*n*IM4H4UlUzfvC%;1Bz~c67Dd&Bng)xa zXqsh1QLFMCtY~G~ESrS^w-%+uj$AbG9Z=tWu2DUet5*_a6Pz?L-WW7Oy^RS@+c*Z2 z$}3JZUJRcNd9G-gX>@MEjn;PDk+}*qV+Q!$5 literal 0 HcmV?d00001 diff --git a/assets/icons/SubGhz/SubGhz_External_ant/frame_02.png b/assets/icons/SubGhz/SubGhz_External_ant/frame_02.png new file mode 100644 index 0000000000000000000000000000000000000000..3285496fea846e6f3712065d21818422765325cd GIT binary patch literal 1097 zcmbVLO>5LZ7)}w|(vO1(Qaw#mkQU5$(%pov?Yc?rVz(~a75Cs_C&{E6+GJufb<-lE zBBJ0$Jcyup6H)LFcu4Cquxcjwt@&Yr{rT=a3w*c0UePLIB`TqozqB2r)$NtK zv%T)jxH>gIX3Q9OeK<6dS5k(o~ zbly`m6?slhJPTw|Rs=~BM4gjlL(~jS0lkN%4rA9dYUX0k9o-e!79o)#2<>*8Z!0{G z*91w|bwQK`S>`B$OSVD+Q!Y%V`U)mWoY;?uk3*0tLK|^~0>E()M zO-NxRNW3TnL3XtcIw3XmCyYbUNqs9qLJcK&Gj?c6ys18!rtfG+8IVR}T#9{K7r0?! zXEQ({DVqhB{^4EUHK3zAnqrHbCnJ?p^J1Q}^;w;BUC;4!$x&2@`Z|a4b44pJX_l(% zVqTIgt7xj)qB1L%^rB)Ftz4g54if@H2lajX)OU}o9LY6GF@glgb&NOqjZkf2f|C}G zfUNN$zqNVcv+QafvRh^>`F5LOjn@ehZ%S#D_}PtCW`&*$X$$a06G;g{6nJq zx6E|;?*C?1pg{>)8~xQ*{Uh3|+45jc=;mP3P)NrsrgQY7zLyR4V0F1}?eFi?<>j3( zH>okoX0e`rvztwGXl!iZ?%>2n`{B}!R})juJ~Q8UK7ANGK6&ruliQC5o;J;|yZ3*b gBzy4J(88?&W^#5LZ7>*Qb>Bq^79|wo@(t`O;b~~Z5Za2Gjp<9>jihGhyCX;UHCKHpXn^q7k z9{jin9=&<=;2-cH2t9c5B6tx0gZK;TWIw8hQp7;=&P<-?eV=(hp0~DcFU($@6$D|S zvEjD4y~N+SnJNB#H&>tG<_fEI*)|Q>0Hs8z_|zky5ushuCdfZ{@R_U%!qn@q(`DV} zrj2PNqXHx6QNr1Ru)3Bf2=5UFJhB_cj`;J#M-ha+Bi^%`YBQ;lUbu0XlI_E-4nEw& z&==Qkg4NvS4kE%3$fJIo*|{SQ{n~t894jIiLfD=ojzo2vEl{N?0Z`T?tg1RFLpd-k zlLWY|-T=C)8;YhWDwH(cRxR5y!1xh)z|;@ywp$;E<2y&}F_zehG8hcxfg#g$SJ5DZ zimEHRE^&mE9mEXfQk*SLJh&voX_&B(#-Q+sJi5;uk&7MOB1)RgQ^#>O&K1v^lA}b? zWL1fx;%Y;5#@ghMj5E<$=O7_Un`Cr9#k?fJ;)Kl8cYdG($ko_)(va5$^<9ehBNDTQ z>xlf1?1#RMFvOPOsZyX5Q!-c770H7oDEWSX1E^ucL}cRUEPlCKFXFZ-|mKtuQ zlYjSicHE2e^S7Q(U;gz{^Ikkz5ZCA5+<$xg>c`RXb>YIaaIG(_h5cuXoFg=9TkiYy Goul7(K})It literal 0 HcmV?d00001 diff --git a/assets/icons/SubGhz/SubGhz_External_ant/frame_04.png b/assets/icons/SubGhz/SubGhz_External_ant/frame_04.png new file mode 100644 index 0000000000000000000000000000000000000000..3acbc03f44dbbd47da08bb70f8cb1e426fcafc64 GIT binary patch literal 1085 zcmbVLJ#5oJ6t)zpRBbAdSoj$@xl1e6_W3WVt(ua?NgJstQ5qlZ572#LL%^HUhA3Sr59cjxbW@7?#_d)C@mote5e#c|wB zW6f?edzrn{lLhvDGhLr#<|?gq=_c`M-$^i6@ra8-BXqWL8#~_qgU@)0;|kA%PM3C@ z>n0+h=;RnN3uDISxTWPRcF+!{z{T4^Wbr@Vf8asjS^Pb{37c^h_ky*91aBT}bkM;L zGCY3yCRoZ$<{-q>0a>^krDkUF1HUF)=f@Hc1`xVq@x!FL%@(MV1Or2q1q7i2%7*Bx zx`usJh6_M}iYm#n1Pwt}OsJc>3Puml0w$hsw(a^T9NSrZkJ8wbq<+6I_EnK2+mdV; zh6EK!Q3Qq%(*1}!nGmJ3V-Ge?Q4+*7AQ8wtIxg9x7SEC$-Xe^f%~QuwI?{@%CS^`6 z$s&}(Fu&RWozgb`lg63ow6h;$sf|;zmmpRWe|Ah}@|_K4QZ)yU{hY-wSL-Du7tMfGS+3P8 zwx-wB608~(wN|N>$J|DgQYS)q96MmKN8H78xn?!N4kby4klk@3w0eY+v`1o~=%NPZ z^1{msEQ_J2Xi5oahVCk!JP*KJ(?LO$gXi-C4)w5c5&WOpt4`0e6juE5<`;8uSfeSgQ8 NT%)#Ozg^jS@*5^2P5=M^ literal 0 HcmV?d00001 diff --git a/assets/icons/SubGhz/SubGhz_External_ant/frame_rate b/assets/icons/SubGhz/SubGhz_External_ant/frame_rate new file mode 100644 index 00000000..62f94575 --- /dev/null +++ b/assets/icons/SubGhz/SubGhz_External_ant/frame_rate @@ -0,0 +1 @@ +6 \ No newline at end of file diff --git a/assets/icons/SubGhz/SubGhz_Internal_ant/frame_01.png b/assets/icons/SubGhz/SubGhz_Internal_ant/frame_01.png new file mode 100644 index 0000000000000000000000000000000000000000..62be9f276f395c0a268ae5242289aa82565a63d5 GIT binary patch literal 1111 zcmaJ=%TE(Q9NvTk2#;vuh3aLpTp+ry+1<9Ypt7Z;p>#9uWj#ygqL? z`Fx50qr(Gyd@))Z=2MPUSJ_JBu?|kCP@h`|c+?BM1Y}{njd5Z7f(M z3S^vN@2p(&IUoQ zIC~w;bS+L0P=-M_*bGyvTN00WExyi<6%iak*hWb_7PZ<~29+qG0Lhv}R26~(l0Drt zs7DIwH2_tpE1IULNYbFCnwF`9-Y0U0iR)QSyVi5ZcO`M1vDi|SPNySxbU8}a6b&Jy zs8E4W;s`0-4jJxBVLI7ouxUyXKW2Uuf{YP6(H1L-TS2_mNMsFDY%AsI!rC^;yPB-izbhcu!anD%+jvM*F>d8i>9A+@4u)oR%` z%$lB8E2ykj%hf{PwjQPohlKWh``mZWwsNkmRY@pjQPPT{&3+*)uSYCO*P|FfQ#Qa< zmUs=S1v!wR0rS8>rUPAV8i1(=CVrTKr?Uhe$HS(He~-GgBnrS$1}y(9b&duR(F+nS zXYZbh>~RtE6aK=uFVuowQN@%LBojKA4~8i@1}`v# zpkr|9RHKflaEVG*RHurpf5a;{Tb^_c-<Ik>#gsvaI5^5yLh zpYQX@s@vsO_q)?>+e2exHy#d7>>pel`Ee_^|FvxAa_vW&_+;)c-h2N=d-m<==Fr~T fiQgZ8UU(o32v-k;wO>nDa-2n|R~PM9bM4)K-N#v< literal 0 HcmV?d00001 diff --git a/assets/icons/SubGhz/SubGhz_Internal_ant/frame_02.png b/assets/icons/SubGhz/SubGhz_Internal_ant/frame_02.png new file mode 100644 index 0000000000000000000000000000000000000000..cd87fcdc9d5df2b0d8ffcfb42ab67f975943b6d4 GIT binary patch literal 1111 zcmaJ=J#W)M7`9Z2qCy1{OUrbar66pd&vuft8X&|e4Qfgig6Np@`P^Eqea60$v;#s2 zkYED-K_w;z7T6F%>6LG#14T9*Q2xm{JS4&p_3=?B) zKx81KNraZKCxY~~BtJW3@K{c>C>0S;K*30Sz9y=w6ubM1IBm7|h?9H}D;YJTPg29w zp%KT$({|9gXtVz^4n*gj^^_THmh-iY%9Mm>hsH8|hdU~OQjL2(i)3ENs>kVC%o5S` zs;a!vgD7wb#niEUsD+5xnq7ev&BrCI1wlwdY*Nc6Y{+wveZ6wULsq4PF|3)O31vgyk@P*Vbq=+4>lq`0XC2O0hlQ}P%mvSvc?yuD+hD3l zyoq30k9B0D60ou3qrf}|z*LLSC@H|_iUjV)!(&-=hXpekkHJm`+~@#xW#2@YT4jxu zOQB|4ey9s>jyO|RDJ|M0tAZ}j-_%MXrBJo|KV?ANu)XWzFTbRTVfp4i-&oS1~4pME>@^IPq+iKN>VzPyhe` literal 0 HcmV?d00001 diff --git a/assets/icons/SubGhz/SubGhz_Internal_ant/frame_03.png b/assets/icons/SubGhz/SubGhz_Internal_ant/frame_03.png new file mode 100644 index 0000000000000000000000000000000000000000..459bd3eca18ea8095fa28446bf3916c79aa3da70 GIT binary patch literal 1110 zcmaJ=J7^R^7+wrWFhmOr(P~%=AGojC-Q3NRGoH5>bC8SSJTVA@v$M0wlI+g9JMk_l z6f6X_u(K7dM9?~*plD@fVP|DwVIf#q%K2|{7cD{-cAnq={onkL2a5}rCJ&uBq$tW{ zYtHY$d=&nP@i7=*PRx$ObX+!<l2?=l(A=VcS$a_ z=RGD8ot7BApJZUIDAP0jjIvcOQNWkuw5I-g^G-!^SW~aLZL^&<_)0vtne!`~3thIk z%1EfroJZ4r4+s)2De5O{Y2o#2>Nc+j>+;x8(KbY`*3=zQOYKF}5IILgw=`y&7*&WK z*{;JQRx!^ZY+~E6EW;$4g+0^tTpJBP6&&VaU^Cg5_~0W09hgkp^O2)>II?^NJ*Ew|9xtVi+rkn$f43 zVd}B7mUi7hDtrKE4EUVe9 z`;I$nPniu;x1055Wn|k*3rSPPN4{h5J+y_0?_=vVa!#elyF#pu3Sn_YNKvea3}IJy z(CISq7B(w-qGJb7A&0mD4y`i?oo-VWrzQAInZTWR_&kqq^Kdp73EIwp7w@625?Gip zyQ1;RRHQj}5NXuqwiX4vN=ZC(D=u%gS*#{oSoRpPVkAF$9~56?SWUnzkR=7`&>MlH@1F0 h{Bc=iPiLMeW6G)L%8lZ}i%&qJw3-Y4>x(z<{RMqXT@U~O literal 0 HcmV?d00001 diff --git a/assets/icons/SubGhz/SubGhz_Internal_ant/frame_04.png b/assets/icons/SubGhz/SubGhz_Internal_ant/frame_04.png new file mode 100644 index 0000000000000000000000000000000000000000..1d785d453414c6013996b52792d385b5e4ce5902 GIT binary patch literal 1110 zcmaJ=J4_To7~X^g2@fC9LTsEY4J7Pqc9*-^aKdqWCzo(|InH>A4YRYeu);pv9lV3W z7|}!%8)Iu@Cl)5w780?s)k;e%wXw6sS-3+A!X`V<@BjX9{>Rh$;`NciD}#a{j8y0C z2A?nTe`uhOk8g%51AH1~kof7VLH}huxUyXKW2Uuf{YP6(FQAsT