From fe212228e2a7b4649de73be940156ad3d4945111 Mon Sep 17 00:00:00 2001 From: gid9798 <30450294+gid9798@users.noreply.github.com> Date: Fri, 12 May 2023 16:47:39 +0300 Subject: [PATCH] New SubGhz Remote GUI --- .../subghz_remote_new/application.fam | 15 + .../helpers/subrem_custom_event.h | 67 ++++ .../subghz_remote_new/helpers/subrem_types.h | 39 +++ .../icons/ButtonDown_7x4.png | Bin 0 -> 102 bytes .../icons/ButtonLeft_4x7.png | Bin 0 -> 1415 bytes .../icons/ButtonRight_4x7.png | Bin 0 -> 1839 bytes .../subghz_remote_new/icons/ButtonUp_7x4.png | Bin 0 -> 102 bytes .../subghz_remote_new/icons/Ok_btn_9x9.png | Bin 0 -> 3605 bytes .../icons/Pin_arrow_up_7x9.png | Bin 0 -> 3603 bytes .../icons/Pin_cell_13x13.png | Bin 0 -> 3593 bytes .../subghz_remote_new/icons/Pin_star_7x7.png | Bin 0 -> 3600 bytes .../subghz_remote_new/icons/back_10px.png | Bin 0 -> 154 bytes .../subghz_remote_new/icons/sub1_10px.png | Bin 0 -> 299 bytes .../subghz_remote_new/scenes/subrem_scene.c | 30 ++ .../subghz_remote_new/scenes/subrem_scene.h | 29 ++ .../scenes/subrem_scene_config.h | 3 + .../scenes/subrem_scene_openmapfile.c | 26 ++ .../scenes/subrem_scene_remote.c | 135 ++++++++ .../scenes/subrem_scene_start.c | 93 +++++ .../subghz_remote_new/subghz_remote_app.c | 181 ++++++++++ .../subghz_remote_new/subghz_remote_app_i.c | 28 ++ .../subghz_remote_new/subghz_remote_app_i.h | 53 +++ .../subghz_remote_new/views/transmitter.c | 277 +++++++++++++++ .../subghz_remote_new/views/transmitter.h | 27 ++ .../views/transmitter_old.txt | 317 ++++++++++++++++++ 25 files changed, 1320 insertions(+) create mode 100644 applications/external/subghz_remote_new/application.fam create mode 100644 applications/external/subghz_remote_new/helpers/subrem_custom_event.h create mode 100644 applications/external/subghz_remote_new/helpers/subrem_types.h create mode 100644 applications/external/subghz_remote_new/icons/ButtonDown_7x4.png create mode 100644 applications/external/subghz_remote_new/icons/ButtonLeft_4x7.png create mode 100644 applications/external/subghz_remote_new/icons/ButtonRight_4x7.png create mode 100644 applications/external/subghz_remote_new/icons/ButtonUp_7x4.png create mode 100644 applications/external/subghz_remote_new/icons/Ok_btn_9x9.png create mode 100644 applications/external/subghz_remote_new/icons/Pin_arrow_up_7x9.png create mode 100644 applications/external/subghz_remote_new/icons/Pin_cell_13x13.png create mode 100644 applications/external/subghz_remote_new/icons/Pin_star_7x7.png create mode 100644 applications/external/subghz_remote_new/icons/back_10px.png create mode 100644 applications/external/subghz_remote_new/icons/sub1_10px.png create mode 100644 applications/external/subghz_remote_new/scenes/subrem_scene.c create mode 100644 applications/external/subghz_remote_new/scenes/subrem_scene.h create mode 100644 applications/external/subghz_remote_new/scenes/subrem_scene_config.h create mode 100644 applications/external/subghz_remote_new/scenes/subrem_scene_openmapfile.c create mode 100644 applications/external/subghz_remote_new/scenes/subrem_scene_remote.c create mode 100644 applications/external/subghz_remote_new/scenes/subrem_scene_start.c create mode 100644 applications/external/subghz_remote_new/subghz_remote_app.c create mode 100644 applications/external/subghz_remote_new/subghz_remote_app_i.c create mode 100644 applications/external/subghz_remote_new/subghz_remote_app_i.h create mode 100644 applications/external/subghz_remote_new/views/transmitter.c create mode 100644 applications/external/subghz_remote_new/views/transmitter.h create mode 100644 applications/external/subghz_remote_new/views/transmitter_old.txt diff --git a/applications/external/subghz_remote_new/application.fam b/applications/external/subghz_remote_new/application.fam new file mode 100644 index 000000000..4f633b961 --- /dev/null +++ b/applications/external/subghz_remote_new/application.fam @@ -0,0 +1,15 @@ +App( + appid="subghz_remote_new", + name="SubRem new", + apptype=FlipperAppType.EXTERNAL, + entry_point="subghz_remote_app", + requires=[ + "gui", + "dialogs", + ], + icon="A_SubGHzRemote_14", + stack_size=4 * 1024, + order=12, + fap_category="Debug", + fap_icon_assets="icons", +) \ No newline at end of file diff --git a/applications/external/subghz_remote_new/helpers/subrem_custom_event.h b/applications/external/subghz_remote_new/helpers/subrem_custom_event.h new file mode 100644 index 000000000..d1559a796 --- /dev/null +++ b/applications/external/subghz_remote_new/helpers/subrem_custom_event.h @@ -0,0 +1,67 @@ +#pragma once + +typedef enum { + // SubRemCustomEventManagerNoSet = 0, + // SubRemCustomEventManagerSet, + // SubRemCustomEventManagerSetRAW, + + //SubmenuIndex + SubmenuIndexOpenMapFile, + SubmenuIndexOpenView, // TODO: temp debug + + //SubRemCustomEvent + SubRemCustomEventViewRemoteBack = 100, + // SubRemCustomEventSceneDeleteSuccess = 100, + // SubRemCustomEventSceneDelete, + // SubRemCustomEventSceneDeleteRAW, + // SubRemCustomEventSceneDeleteRAWBack, + + // SubRemCustomEventSceneReceiverInfoTxStart, + // SubRemCustomEventSceneReceiverInfoTxStop, + // SubRemCustomEventSceneReceiverInfoSave, + // SubRemCustomEventSceneSaveName, + // SubRemCustomEventSceneSaveSuccess, + // SubRemCustomEventSceneShowErrorBack, + // SubRemCustomEventSceneShowErrorOk, + // SubRemCustomEventSceneShowErrorSub, + // SubRemCustomEventSceneShowOnlyRX, + // SubRemCustomEventSceneAnalyzerLock, + // SubRemCustomEventSceneAnalyzerUnlock, + // SubRemCustomEventSceneSettingLock, + + // SubRemCustomEventSceneExit, + // SubRemCustomEventSceneStay, + + // SubRemCustomEventSceneRpcLoad, + // SubRemCustomEventSceneRpcButtonPress, + // SubRemCustomEventSceneRpcButtonRelease, + // SubRemCustomEventSceneRpcSessionClose, + + // SubRemCustomEventViewReceiverOK, + // SubRemCustomEventViewReceiverConfig, + // SubRemCustomEventViewReceiverBack, + // SubRemCustomEventViewReceiverOffDisplay, + // SubRemCustomEventViewReceiverUnlock, + // SubRemCustomEventViewReceiverDeleteItem, + + // SubRemCustomEventViewReadRAWBack, + // SubRemCustomEventViewReadRAWIDLE, + // SubRemCustomEventViewReadRAWREC, + // SubRemCustomEventViewReadRAWConfig, + // SubRemCustomEventViewReadRAWErase, + // SubRemCustomEventViewReadRAWSendStart, + // SubRemCustomEventViewReadRAWSendStop, + // SubRemCustomEventViewReadRAWSave, + // SubRemCustomEventViewReadRAWTXRXStop, + // SubRemCustomEventViewReadRAWMore, + + // SubRemCustomEventViewTransmitterBack, + // SubRemCustomEventViewTransmitterSendStart, + // SubRemCustomEventViewTransmitterSendStop, + // SubRemCustomEventViewTransmitterError, + + // SubRemCustomEventViewFreqAnalOkShort, + // SubRemCustomEventViewFreqAnalOkLong, + + // SubRemCustomEventByteInputDone, +} SubRemCustomEvent; diff --git a/applications/external/subghz_remote_new/helpers/subrem_types.h b/applications/external/subghz_remote_new/helpers/subrem_types.h new file mode 100644 index 000000000..ffb2f8044 --- /dev/null +++ b/applications/external/subghz_remote_new/helpers/subrem_types.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include +/* +#define AVR_ISP_VERSION_APP "0.1" +#define AVR_ISP_DEVELOPED "SkorP" +#define AVR_ISP_GITHUB "https://github.com/flipperdevices/flipperzero-firmware" + +#define AVR_ISP_APP_FILE_VERSION 1 +#define AVR_ISP_APP_FILE_TYPE "Flipper Dump AVR" +#define AVR_ISP_APP_EXTENSION ".avr" +*/ + +// TODO: rename Filepath +//#define SUBREMOTEMAP_FOLDER "/ext/subghz_remote" +#define SUBGHZ_REMOTE_APP_EXTENSION ".txt" +#define SUBGHZ_REMOTE_APP_PATH_PREFIX "/ext/subghz_remote" + +typedef enum { + //SubRemViewVariableItemList, + SubRemViewSubmenu, + //SubRemViewProgrammer, + //SubRemViewReader, + //SubRemViewWriter, + SubRemViewWidget, + SubRemViewPopup, + SubRemViewTextInput, + SubRemViewIDRemote, + //SubRemViewChipDetect, +} SubRemViewID; +/* +typedef enum { + SubRemErrorNoError, + SubRemErrorReading, + SubRemErrorWriting, + SubRemErrorVerification, + SubRemErrorWritingFuse, +} SubRemError;*/ \ No newline at end of file diff --git a/applications/external/subghz_remote_new/icons/ButtonDown_7x4.png b/applications/external/subghz_remote_new/icons/ButtonDown_7x4.png new file mode 100644 index 0000000000000000000000000000000000000000..2954bb6a67d1c23c0bb5d765e8d2aa04b9b5adec GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)I!3HFqj;YoHDIHH2#}J9|(o>FH3<^BV2haYO z-y5_sM4;GPjq%Ck6>60csmUj6EiNa>ORduPH4*)h!w|e3sE@(Z)z4*}Q$iC10Gods AV*mgE literal 0 HcmV?d00001 diff --git a/applications/external/subghz_remote_new/icons/ButtonLeft_4x7.png b/applications/external/subghz_remote_new/icons/ButtonLeft_4x7.png new file mode 100644 index 0000000000000000000000000000000000000000..0b4655d43247083aa705620e9836ac415b42ca46 GIT binary patch literal 1415 zcmbVM+iKK67*5rq)>aU2M7$VM1Vxif;vTv~W2u`S7ED{V3s&&L*<`XiG|9wd+THd> z5CnY!sdyuJtrvQyAo>KpiLcV|{Tkc)riAbluXfwSZCApL`ztB&p zx6LGKvks4K_4~)qD&oGa-YdJlW)hAKMNJd7<=t?6c^RI1>c$ifyjaM>^|&8!ey zB4!nh9u>5uen6Ve@<H5rru6h<2Ef#GQdQ*CmZOlQi~N!?9H`Rp;C% zU}CB21#?;r`&0|6C0}b-=jODa5|nEJ#ntxQ&{~jpgtwDta4hftr~G=#p@V36e4Zjh zq%J~{y26Jjn=1Nw-l*3%QW5YFE*v4z3gt0$&(*xf2en34c?JpH8+FYldo+Alvg8af-pG4(=!fyUi-Wsg z`g#n9VUcf(DFr{poMSNzw-lz>w+HV+n1ELr&SLA#LHUb0p(xWQ(1*vJ-i+1!`swxZ Z!O7;c$;lT_->m1Ovaz)0yuI`A$q$F8u*d)a literal 0 HcmV?d00001 diff --git a/applications/external/subghz_remote_new/icons/ButtonRight_4x7.png b/applications/external/subghz_remote_new/icons/ButtonRight_4x7.png new file mode 100644 index 0000000000000000000000000000000000000000..8e1c74c1c0038ea55172f19ac875003fc80c2d06 GIT binary patch literal 1839 zcmcIlO>f*p7#Yw)M6zw!O+@VZ{?d|D~WYi~8rHRY?X-&T}Yen`g$^+EJ;z+|RV zE@PoDvZ9%#+_}3bC_5Cj8jDGq541mi{7F+&KF}W65sr$Xn5H|YrMQ2(J7%Yc%;(zO z57ax000=TsQ+1Ke@+w#iw3au3cGGQWY740k2ijH>P(6tD)S)be>gX6Tj7`<`b>di- zgWp$8Y+?i31~CzF0&E4uRlA=C(Mp~K`{74jEchB|)4DDK!ZVhSwdFyw0YIZ1cDh0S{OvfO-U_~ zvmRF*m9sWDXNH)GOyqS1Skhxbr6}s*7t&@~kFM(NW5}qh?Lu@lJ}HE;FDiLdGO>LO z5pS*%E2grR)l^;|?O5b_?u0me&c1U}%jrk8*%=Wk%i)8yp2P|kuxmKg<=(u_`oQRI_0 zS`-DNysBx=#3&qSkgA@hJP>~D+ZM(s5jI6Owp`?yE=3e`YGUqkVOp#Cp=3wR3O4hX zX6BLsN3UBzV(vI5;|SZHgOb=HD0VFjpTyfFW}GnQuh>2*Q`k>*cAmA#iUT7EXSpo# zkPm5~#I-o^cpgfe#P$=4-Pi*SpT!-@nJgp8L347xe>5EKl`=_ZFc8XGy+_j=_R_7! z@vZZMowS1GJ?Zw)eetks%~G{BTR>T}9|jt0j3Btyb*C3-`C?fwY3EY`q*oYZ39DpM z&uJ;PCZPLs4QO1Jd_|A1PF)azZJ)RZ`^-VMWr6e#XUOA%3eLG_Ch@BDOHzMk*MF0G zCo7xMd?Mg*HMIXw%nNz?%60fZiZPlqb?GqUpXO`F&Yi!okZl(n>P@r1P2i)yk3DgRwbHeNn6e|;J^SK4TM LH~i+q&mR8;k>NTA literal 0 HcmV?d00001 diff --git a/applications/external/subghz_remote_new/icons/ButtonUp_7x4.png b/applications/external/subghz_remote_new/icons/ButtonUp_7x4.png new file mode 100644 index 0000000000000000000000000000000000000000..1be79328b40a93297a5609756328406565c437c0 GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)I!3HFqj;YoHDIHH2#}J8d-yTOk1_O>mFaFD) zeWb+ZHz{mGZZ1QpXe09^4tcYT#4oe=UbmGC^A-KE*|F&zP#=S*tDnm{r-UX30HgpM AM*si- literal 0 HcmV?d00001 diff --git a/applications/external/subghz_remote_new/icons/Ok_btn_9x9.png b/applications/external/subghz_remote_new/icons/Ok_btn_9x9.png new file mode 100644 index 0000000000000000000000000000000000000000..9a1539da2049f12f7b25f96b11a9c40cd8227302 GIT binary patch literal 3605 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 LwKgd=cDwXHDN#*w literal 0 HcmV?d00001 diff --git a/applications/external/subghz_remote_new/icons/back_10px.png b/applications/external/subghz_remote_new/icons/back_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..f9c615a99e69c0100b03a9ae7b2df903da4ecd66 GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xGmzZ=C-xtZVk{1FcVbv~PUa<$!;&U>c zv7h@-A}f&37T^=&`v3obAT#vPO>_%)r1c48n{Iv*t(u1!X;5977~7Co?ed rv9U?Av01aVRT(gMJdt+jXk=uN>R^g!*w%ImsF1<>&pI=m5)cB{fFDGZlI8yr;B3<$MxhJ?+;A4eL&#) z0Ra}bue?07WhLz78x$BO|L3mq-MMxdP^D^#YeY#(Vo9o1a#1RfVlXl=GSoFN)ipE; zF*LF=Hn1|b&^9ozGB8+QQTzo(LvDUbW?CgwgE3G~h=Hk + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) SubRemScene##id, +typedef enum { +#include "subrem_scene_config.h" + SubRemSceneNum, +} SubRemScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers subrem_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "subrem_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_event handlers declaration +#define ADD_SCENE(prefix, name, id) \ + bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); +#include "subrem_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_exit handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); +#include "subrem_scene_config.h" +#undef ADD_SCENE diff --git a/applications/external/subghz_remote_new/scenes/subrem_scene_config.h b/applications/external/subghz_remote_new/scenes/subrem_scene_config.h new file mode 100644 index 000000000..93d4de642 --- /dev/null +++ b/applications/external/subghz_remote_new/scenes/subrem_scene_config.h @@ -0,0 +1,3 @@ +ADD_SCENE(subrem, start, Start) +ADD_SCENE(subrem, openmapfile, OpenMapFile) +ADD_SCENE(subrem, remote, Remote) \ No newline at end of file diff --git a/applications/external/subghz_remote_new/scenes/subrem_scene_openmapfile.c b/applications/external/subghz_remote_new/scenes/subrem_scene_openmapfile.c new file mode 100644 index 000000000..8e651a534 --- /dev/null +++ b/applications/external/subghz_remote_new/scenes/subrem_scene_openmapfile.c @@ -0,0 +1,26 @@ +#include "../subghz_remote_app_i.h" + +void subrem_scene_openmapfile_on_enter(void* context) { + SubGhzRemoteApp* app = context; + + if(subrem_load_from_file(app)) { + // if(subghz_get_load_type_file(subghz) == SubGhzLoadTypeFileRaw) { + // subghz_rx_key_state_set(subghz, SubGhzRxKeyStateRAWLoad); + // scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW); + // } else { + // scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSavedMenu); + // } + } else { + scene_manager_search_and_switch_to_previous_scene(app->scene_manager, SubRemSceneStart); + } +} + +bool subrem_scene_openmapfile_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + return false; +} + +void subrem_scene_openmapfile_on_exit(void* context) { + UNUSED(context); +} diff --git a/applications/external/subghz_remote_new/scenes/subrem_scene_remote.c b/applications/external/subghz_remote_new/scenes/subrem_scene_remote.c new file mode 100644 index 000000000..787a71760 --- /dev/null +++ b/applications/external/subghz_remote_new/scenes/subrem_scene_remote.c @@ -0,0 +1,135 @@ +#include "../subghz_remote_app_i.h" +#include "../views/transmitter.h" + +// TODO: +// #include +// #include + +// #include + +void subrem_scene_remote_callback(SubRemCustomEvent event, void* context) { + furi_assert(context); + SubGhzRemoteApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, event); +} + +bool subrem_scene_remote_update_data_show(void* context) { + SubGhzRemoteApp* app = context; + //UNUSED(app); + bool ret = false; + + subrem_view_remote_add_data_to_show( + //app->subrem_remote_view, "N/A", "N/A", "N/A", "N/A", "N/A"); + app->subrem_remote_view, + "UP", + "DOWN", + "LEFT", + "RIGHT", + "OK"); + // SubGhzProtocolDecoderBase* decoder = subghz_txrx_get_decoder(app->txrx); + + // if(decoder) { + // FuriString* key_str = furi_string_alloc(); + // FuriString* frequency_str = furi_string_alloc(); + // FuriString* modulation_str = furi_string_alloc(); + + // if(subghz_protocol_decoder_base_deserialize( + // decoder, subghz_txrx_get_fff_data(app->txrx)) == SubGhzProtocolStatusOk) { + // subghz_protocol_decoder_base_get_string(decoder, key_str); + + // subghz_txrx_get_frequency_and_modulation( + // app->txrx, frequency_str, modulation_str, false); + // subghz_view_transmitter_add_data_to_show( + // app->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(app->txrx, false)); + // ret = true; + // } + // furi_string_free(frequency_str); + // furi_string_free(modulation_str); + // furi_string_free(key_str); + // } + return ret; +} + +void subrem_scene_remote_on_enter(void* context) { + SubGhzRemoteApp* app = context; + + // TODO: reset custom btns + // keeloq_reset_original_btn(); + // subghz_custom_btns_reset(); + + // TODO: init view data + + if(!subrem_scene_remote_update_data_show(app)) { + // view_dispatcher_send_custom_event( + // app->view_dispatcher, SubGhzCustomEventViewTransmitterError); + } + subrem_view_remote_set_callback(app->subrem_remote_view, subrem_scene_remote_callback, app); + + // TODO: notifications + // app->state_notifications = SubGhzNotificationStateIDLE; + view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDRemote); +} + +bool subrem_scene_remote_on_event(void* context, SceneManagerEvent event) { + SubGhzRemoteApp* app = context; + if(event.type == SceneManagerEventTypeCustom) { + // if(event.event == SubGhzCustomEventViewTransmitterSendStart) { + // app->state_notifications = SubGhzNotificationStateIDLE; + + // if(subghz_tx_start(app, subghz_txrx_get_fff_data(app->txrx))) { + // app->state_notifications = SubGhzNotificationStateTx; + // subrem_scene_remote_update_data_show(app); + // DOLPHIN_DEED(DolphinDeedSubGhzSend); + // } + // return true; + // } else if(event.event == SubGhzCustomEventViewTransmitterSendStop) { + // app->state_notifications = SubGhzNotificationStateIDLE; + // subghz_txrx_stop(app->txrx); + // if(subghz_custom_btn_get() != 0) { + // subghz_custom_btn_set(0); + // uint8_t tmp_counter = furi_hal_subghz_get_rolling_counter_mult(); + // furi_hal_subghz_set_rolling_counter_mult(0); + // // Calling restore! + // subghz_tx_start(app, subghz_txrx_get_fff_data(app->txrx)); + // subghz_txrx_stop(app->txrx); + // furi_hal_subghz_set_rolling_counter_mult(tmp_counter); + // } + // return true; + // } else + if(event.event == SubRemCustomEventViewRemoteBack) { + // app->state_notifications = SubGhzNotificationStateIDLE; //TODO: notification + scene_manager_search_and_switch_to_previous_scene( + app->scene_manager, SubRemSceneStart); + return true; + } + // else if(event.event == SubGhzCustomEventViewTransmitterError) { + // furi_string_set(app->error_str, "Protocol not\nfound!"); + // scene_manager_next_scene(app->scene_manager, SubGhzSceneShowErrorSub); + // } + } else if(event.type == SceneManagerEventTypeTick) { + // if(app->state_notifications == SubGhzNotificationStateTx) { + // notification_message(app->notifications, &sequence_blink_magenta_10); + // } + // return true; + } + return false; +} + +void subrem_scene_remote_on_exit(void* context) { + SubGhzRemoteApp* app = context; + UNUSED(app); + // TODO: notifications and reset KL + + //app->state_notifications = SubGhzNotificationStateIDLE; + + // keeloq_reset_mfname(); + // keeloq_reset_kl_type(); + // keeloq_reset_original_btn(); + // subghz_custom_btns_reset(); + // star_line_reset_mfname(); + // star_line_reset_kl_type(); +} diff --git a/applications/external/subghz_remote_new/scenes/subrem_scene_start.c b/applications/external/subghz_remote_new/scenes/subrem_scene_start.c new file mode 100644 index 000000000..0ad9837e9 --- /dev/null +++ b/applications/external/subghz_remote_new/scenes/subrem_scene_start.c @@ -0,0 +1,93 @@ +#include "../subghz_remote_app_i.h" +#include "../helpers/subrem_custom_event.h" + +void subrem_scene_start_submenu_callback(void* context, uint32_t index) { + furi_assert(context); + SubGhzRemoteApp* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void subrem_scene_start_on_enter(void* context) { + furi_assert(context); + + SubGhzRemoteApp* app = context; + Submenu* submenu = app->submenu; + submenu_add_item( + submenu, + "Open Map File", + SubmenuIndexOpenMapFile, + subrem_scene_start_submenu_callback, + app); + submenu_add_item( + submenu, "Remote", SubmenuIndexOpenView, subrem_scene_start_submenu_callback, app); + // submenu_add_item( + // submenu, + // "ISP Programmer", + // SubmenuIndexSubGhzRemoteProgrammer, + // subrem_scene_start_submenu_callback, + // app); + // submenu_add_item( + // submenu, + // "Wiring", + // SubmenuIndexAvrIsWiring, + // subrem_scene_start_submenu_callback, + // app); + // submenu_add_item( + // submenu, + // "About", + // SubmenuIndexSubGhzRemoteAbout, + // subrem_scene_start_submenu_callback, + // app); + + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(app->scene_manager, SubRemSceneStart)); + + view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewSubmenu); +} + +bool subrem_scene_start_on_event(void* context, SceneManagerEvent event) { + furi_assert(context); + + SubGhzRemoteApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexOpenMapFile) { + scene_manager_next_scene(app->scene_manager, SubRemSceneOpenMapFile); + consumed = true; + } else if(event.event == SubmenuIndexOpenView) { + scene_manager_next_scene(app->scene_manager, SubRemSceneRemote); + consumed = true; + } + // } else if(event.event == SubmenuIndexSubGhzRemoteProgrammer) { + // scene_manager_set_scene_state( + // app->scene_manager, SubRemSceneChipDetect, SubGhzRemoteViewProgrammer); + // scene_manager_next_scene(app->scene_manager, SubRemSceneChipDetect); + // consumed = true; + // } else if(event.event == SubmenuIndexSubGhzRemoteReader) { + // scene_manager_set_scene_state( + // app->scene_manager, SubRemSceneChipDetect, SubGhzRemoteViewReader); + // scene_manager_next_scene(app->scene_manager, SubRemSceneChipDetect); + // consumed = true; + // } else if(event.event == SubmenuIndexSubGhzRemoteWriter) { + // scene_manager_set_scene_state( + // app->scene_manager, SubRemSceneChipDetect, SubGhzRemoteViewWriter); + // scene_manager_next_scene(app->scene_manager, SubRemSceneChipDetect); + // consumed = true; + // } else if(event.event == SubmenuIndexAvrIsWiring) { + // scene_manager_next_scene(app->scene_manager, SubRemSceneWiring); + // consumed = true; + // } + scene_manager_set_scene_state(app->scene_manager, SubRemSceneStart, event.event); + } + + return consumed; +} + +void subrem_scene_start_on_exit(void* context) { + furi_assert(context); + + SubGhzRemoteApp* app = context; + submenu_reset(app->submenu); +} diff --git a/applications/external/subghz_remote_new/subghz_remote_app.c b/applications/external/subghz_remote_new/subghz_remote_app.c new file mode 100644 index 000000000..d25e65ce7 --- /dev/null +++ b/applications/external/subghz_remote_new/subghz_remote_app.c @@ -0,0 +1,181 @@ +#include "subghz_remote_app_i.h" + +static bool subghz_remote_app_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + SubGhzRemoteApp* app = context; + return scene_manager_handle_custom_event(app->scene_manager, event); +} + +static bool subghz_remote_app_back_event_callback(void* context) { + furi_assert(context); + SubGhzRemoteApp* app = context; + return scene_manager_handle_back_event(app->scene_manager); +} + +static void subghz_remote_app_tick_event_callback(void* context) { + furi_assert(context); + SubGhzRemoteApp* app = context; + scene_manager_handle_tick_event(app->scene_manager); +} + +SubGhzRemoteApp* subghz_remote_app_alloc() { + SubGhzRemoteApp* app = malloc(sizeof(SubGhzRemoteApp)); + + // // Enable 5v power, multiple attempts to avoid issues with power chip protection false triggering + // uint8_t attempts = 0; + // while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { + // furi_hal_power_enable_otg(); + // furi_delay_ms(10); + // } + + app->file_path = furi_string_alloc(); + furi_string_set(app->file_path, STORAGE_APP_DATA_PATH_PREFIX); + //app->error = SubGhzRemoteErrorNoError; + + // GUI + app->gui = furi_record_open(RECORD_GUI); + + // View Dispatcher + app->view_dispatcher = view_dispatcher_alloc(); + app->scene_manager = scene_manager_alloc(&subrem_scene_handlers, app); + view_dispatcher_enable_queue(app->view_dispatcher); + + view_dispatcher_set_event_callback_context(app->view_dispatcher, app); + view_dispatcher_set_custom_event_callback( + app->view_dispatcher, subghz_remote_app_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + app->view_dispatcher, subghz_remote_app_back_event_callback); + view_dispatcher_set_tick_event_callback( + app->view_dispatcher, subghz_remote_app_tick_event_callback, 100); + + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + // Open Notification record + app->notifications = furi_record_open(RECORD_NOTIFICATION); + + // SubMenu + app->submenu = submenu_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, SubRemViewSubmenu, submenu_get_view(app->submenu)); + + // Widget + app->widget = widget_alloc(); + view_dispatcher_add_view(app->view_dispatcher, SubRemViewWidget, widget_get_view(app->widget)); + + // Text Input + app->text_input = text_input_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, SubRemViewTextInput, text_input_get_view(app->text_input)); + + // Popup + app->popup = popup_alloc(); + view_dispatcher_add_view(app->view_dispatcher, SubRemViewPopup, popup_get_view(app->popup)); + + //Dialog + app->dialogs = furi_record_open(RECORD_DIALOGS); + + // Remote view + app->subrem_remote_view = subrem_view_remote_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, + SubRemViewIDRemote, + subrem_view_remote_get_view(app->subrem_remote_view)); + /* + // Reader view + app->subghz_remote_reader_view = subghz_remote_reader_view_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, + SubRemViewReader, + subghz_remote_reader_view_get_view(app->subghz_remote_reader_view)); + + // Writer view + app->subghz_remote_writer_view = subghz_remote_writer_view_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, + SubRemViewWriter, + subghz_remote_writer_view_get_view(app->subghz_remote_writer_view)); + + // Chip detect view + app->subghz_remote_chip_detect_view = subghz_remote_chip_detect_view_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, + SubRemViewChipDetect, + subghz_remote_chip_detect_view_get_view(app->subghz_remote_chip_detect_view)); +*/ + scene_manager_next_scene(app->scene_manager, SubRemSceneStart); + + return app; +} + +void subghz_remote_app_free(SubGhzRemoteApp* app) { + furi_assert(app); + + // Submenu + view_dispatcher_remove_view(app->view_dispatcher, SubRemViewSubmenu); + submenu_free(app->submenu); + + // Widget + view_dispatcher_remove_view(app->view_dispatcher, SubRemViewWidget); + widget_free(app->widget); + + // TextInput + view_dispatcher_remove_view(app->view_dispatcher, SubRemViewTextInput); + text_input_free(app->text_input); + + // Popup + view_dispatcher_remove_view(app->view_dispatcher, SubRemViewPopup); + popup_free(app->popup); + + //Dialog + furi_record_close(RECORD_DIALOGS); + + // Remote view + view_dispatcher_remove_view(app->view_dispatcher, SubRemViewIDRemote); + subrem_view_remote_free(app->subrem_remote_view); + + // // Reader view + // view_dispatcher_remove_view(app->view_dispatcher, SubRemViewReader); + // subghz_remote_reader_view_free(app->subghz_remote_reader_view); + + // // Writer view + // view_dispatcher_remove_view(app->view_dispatcher, SubRemViewWriter); + // subghz_remote_writer_view_free(app->subghz_remote_writer_view); + + // // Chip detect view + // view_dispatcher_remove_view(app->view_dispatcher, SubRemViewChipDetect); + // subghz_remote_chip_detect_view_free(app->subghz_remote_chip_detect_view); + + // // View dispatcher + // view_dispatcher_free(app->view_dispatcher); + // scene_manager_free(app->scene_manager); + + // Notifications + furi_record_close(RECORD_NOTIFICATION); + app->notifications = NULL; + + // Close records + furi_record_close(RECORD_GUI); + + // Path strings + furi_string_free(app->file_path); + + // Disable 5v power + // if(furi_hal_power_is_otg_enabled()) { + // furi_hal_power_disable_otg(); + // } + + free(app); +} + +int32_t subghz_remote_app(void* p) { + UNUSED(p); + SubGhzRemoteApp* subghz_remote_app = subghz_remote_app_alloc(); + + furi_string_set(subghz_remote_app->file_path, SUBREM_APP_FOLDER); + + view_dispatcher_run(subghz_remote_app->view_dispatcher); + + subghz_remote_app_free(subghz_remote_app); + + return 0; +} diff --git a/applications/external/subghz_remote_new/subghz_remote_app_i.c b/applications/external/subghz_remote_new/subghz_remote_app_i.c new file mode 100644 index 000000000..43bdd73f3 --- /dev/null +++ b/applications/external/subghz_remote_new/subghz_remote_app_i.c @@ -0,0 +1,28 @@ +#include "subghz_remote_app_i.h" +#include +#include + +#define TAG "SubGhzRemote" + +bool subrem_load_from_file(SubGhzRemoteApp* app) { + furi_assert(app); + + FuriString* file_path = furi_string_alloc(); + + DialogsFileBrowserOptions browser_options; + dialog_file_browser_set_basic_options(&browser_options, SUBREM_APP_EXTENSION, &I_sub1_10px); + browser_options.base_path = SUBREM_APP_FOLDER; + + // Input events and views are managed by file_select + bool res = + dialog_file_browser_show(app->dialogs, app->file_path, app->file_path, &browser_options); + + if(res) { + // res = subghz_key_load(app, furi_string_get_cstr(app->file_path), true); + res = false; + } + + furi_string_free(file_path); + + return res; +} diff --git a/applications/external/subghz_remote_new/subghz_remote_app_i.h b/applications/external/subghz_remote_new/subghz_remote_app_i.h new file mode 100644 index 000000000..bc8c61cdd --- /dev/null +++ b/applications/external/subghz_remote_new/subghz_remote_app_i.h @@ -0,0 +1,53 @@ +#pragma once + +#include "helpers/subrem_types.h" + +#include "views/transmitter.h" + +#include "scenes/subrem_scene.h" + +#include // TODO: +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// #include "views/subghz_remote_view_programmer.h" +// #include "views/subghz_remote_view_reader.h" +// #include "views/subghz_remote_view_writer.h" +// #include "views/subghz_remote_view_chip_detect.h" + +#define SUBREM_APP_EXTENSION ".txt" +#define SUBREM_APP_FOLDER "/ext/subghz_remote" +#define SUBGHZ_REMOTE_MAX_LEN_NAME 64 + +typedef struct { + Gui* gui; + ViewDispatcher* view_dispatcher; + SceneManager* scene_manager; + NotificationApp* notifications; + DialogsApp* dialogs; + Popup* popup; + Submenu* submenu; + Widget* widget; + TextInput* text_input; + FuriString* file_path; + char file_name_tmp[SUBGHZ_REMOTE_MAX_LEN_NAME]; + + SubRemViewRemote* subrem_remote_view; + + // AvrIspProgrammerView* subghz_remote_programmer_view; + // AvrIspReaderView* subghz_remote_reader_view; + // AvrIspWriterView* subghz_remote_writer_view; + // AvrIspChipDetectView* subghz_remote_chip_detect_view; + + // AvrIspError error; +} SubGhzRemoteApp; + +bool subrem_load_from_file(SubGhzRemoteApp* app); \ No newline at end of file diff --git a/applications/external/subghz_remote_new/views/transmitter.c b/applications/external/subghz_remote_new/views/transmitter.c new file mode 100644 index 000000000..a3589339d --- /dev/null +++ b/applications/external/subghz_remote_new/views/transmitter.c @@ -0,0 +1,277 @@ +#include "transmitter.h" +#include "../subghz_remote_app_i.h" + +#include +#include + +#define SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH 16 +struct SubRemViewRemote { + View* view; + SubRemViewRemoteCallback callback; + void* context; +}; +// FIXME: drop +// static char* char_to_str(char* str, int i) { +// char* converted = malloc(sizeof(char) * i + 1); +// memcpy(converted, str, i); + +// converted[i] = '\0'; + +// return converted; +// } + +// TODO: model + +typedef struct { + // FuriString* up_label; + // FuriString* down_label; + // FuriString* left_label; + // FuriString* right_label; + // FuriString* ok_label; + + char* up_label; + char* down_label; + char* left_label; + char* right_label; + char* ok_label; + + uint8_t pressed_btn; + // bool show_button; + // FuriString* temp_button_id; + // bool draw_temp_button; +} 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_add_data_to_show( + SubRemViewRemote* subrem_view_remote, + const char* up_label, + const char* down_label, + const char* left_label, + const char* right_label, + const char* ok_label) { + furi_assert(subrem_view_remote); + + with_view_model( + subrem_view_remote->view, + SubRemViewRemoteModel * model, + { + strncpy(model->up_label, up_label, SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH); + strncpy(model->down_label, down_label, SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH); + strncpy(model->left_label, left_label, SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH); + strncpy(model->right_label, right_label, SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH); + strncpy(model->ok_label, ok_label, SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH); + + // model->up_label = char_to_str((char*)up_label, 16); + // model->down_label = char_to_str((char*)down_label, 16); + // model->left_label = char_to_str((char*)left_label, 16); + // model->right_label = char_to_str((char*)right_label, 16); + // model->ok_label = char_to_str((char*)ok_label, 16); + + // furi_string_set(model->up_label, up_label); + // furi_string_set(model->down_label, down_label); + // furi_string_set(model->left_label, left_label); + // furi_string_set(model->right_label, right_label); + // furi_string_set(model->ok_label, ok_label); + }, + true); +} + +void subrem_view_remote_draw(Canvas* canvas, SubRemViewRemoteModel* model) { + canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + + //map found, draw all the things + canvas_clear(canvas); + + //canvas_set_font(canvas, FontPrimary); + //canvas_draw_str(canvas, 0, 10, "U: "); + //canvas_draw_str(canvas, 0, 20, "L: "); + //canvas_draw_str(canvas, 0, 30, "R: "); + //canvas_draw_str(canvas, 0, 40, "D: "); + //canvas_draw_str(canvas, 0, 50, "Ok: "); + + //PNGs are located in assets/icons/SubGHzRemote before compilation + + //Icons for Labels + //canvas_draw_icon(canvas, 0, 0, &I_SubGHzRemote_LeftAlignedButtons_9x64); + canvas_draw_icon(canvas, 1, 5, &I_ButtonUp_7x4); + canvas_draw_icon(canvas, 1, 15, &I_ButtonDown_7x4); + canvas_draw_icon(canvas, 2, 23, &I_ButtonLeft_4x7); + canvas_draw_icon(canvas, 2, 33, &I_ButtonRight_4x7); + canvas_draw_icon(canvas, 0, 42, &I_Ok_btn_9x9); + canvas_draw_icon(canvas, 0, 53, &I_back_10px); + + //Labels + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 10, 10, model->up_label); + canvas_draw_str(canvas, 10, 20, model->down_label); + canvas_draw_str(canvas, 10, 30, model->left_label); + canvas_draw_str(canvas, 10, 40, model->right_label); + canvas_draw_str(canvas, 10, 50, model->ok_label); + // canvas_draw_str(canvas, 10, 10, furi_string_get_cstr(model->up_label)); + // canvas_draw_str(canvas, 10, 10, furi_string_get_cstr(model->up_label)); + // canvas_draw_str(canvas, 10, 10, furi_string_get_cstr(model->up_label)); + // canvas_draw_str(canvas, 10, 10, furi_string_get_cstr(model->up_label)); + // canvas_draw_str(canvas, 10, 10, furi_string_get_cstr(model->up_label)); + + canvas_draw_str_aligned(canvas, 11, 62, AlignLeft, AlignBottom, "Hold=Exit."); + + //Status text and indicator + // canvas_draw_str_aligned(canvas, 126, 10, AlignRight, AlignBottom, app->send_status); + + canvas_draw_icon(canvas, 113, 15, &I_Pin_cell_13x13); + switch(model->pressed_btn) { + case 0: + break; + case 1: + canvas_draw_icon(canvas, 116, 17, &I_Pin_arrow_up_7x9); + break; + case 2: + canvas_draw_icon_ex(canvas, 116, 17, &I_Pin_arrow_up_7x9, IconRotation180); + break; + case 3: + canvas_draw_icon_ex(canvas, 115, 18, &I_Pin_arrow_up_7x9, IconRotation90); + break; + case 4: + canvas_draw_icon_ex(canvas, 115, 18, &I_Pin_arrow_up_7x9, IconRotation270); + break; + case 5: + canvas_draw_icon(canvas, 116, 18, &I_Pin_star_7x7); + break; + } + + //Repeat indicator + //canvas_draw_str_aligned(canvas, 125, 40, AlignRight, AlignBottom, "Repeat:"); + //canvas_draw_icon(canvas, 115, 39, &I_SubGHzRemote_Repeat_12x14); + //canvas_draw_str_aligned(canvas, 125, 62, AlignRight, AlignBottom, int_to_char(app->repeat)); +} + +bool subrem_view_remote_input(InputEvent* event, void* context) { + furi_assert(context); + SubRemViewRemote* subrem_view_remote = context; + + if(event->key == InputKeyBack && event->type == InputTypeLong) { + with_view_model( + subrem_view_remote->view, + SubRemViewRemoteModel * model, + { + strcpy(model->up_label, "N/A"); + strcpy(model->down_label, "N/A"); + strcpy(model->left_label, "N/A"); + strcpy(model->right_label, "N/A"); + strcpy(model->ok_label, "N/A"); + + // furi_string_reset(model->up_label); + // furi_string_reset(model->down_label); + // furi_string_reset(model->left_label); + // furi_string_reset(model->right_label); + // furi_string_reset(model->ok_label); + }, + false); + return false; + } else if(event->key == InputKeyUp) { + if(event->type == InputTypePress) { + with_view_model( + subrem_view_remote->view, + SubRemViewRemoteModel * model, + { model->pressed_btn = 1; }, + true); + return true; + } else if(event->type == InputTypeRelease) { + with_view_model( + subrem_view_remote->view, + SubRemViewRemoteModel * model, + { model->pressed_btn = 0; }, + true); + 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() { + 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_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->up_label = malloc(sizeof(char) * SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH + 1); + model->down_label = malloc(sizeof(char) * SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH + 1); + model->left_label = malloc(sizeof(char) * SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH + 1); + model->right_label = malloc(sizeof(char) * SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH + 1); + model->ok_label = malloc(sizeof(char) * SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH + 1); + + strcpy(model->up_label, "N/A"); + strcpy(model->down_label, "N/A"); + strcpy(model->left_label, "N/A"); + strcpy(model->right_label, "N/A"); + strcpy(model->ok_label, "N/A"); + + // model->up_label = furi_string_alloc(); + // model->down_label = furi_string_alloc(); + // model->left_label = furi_string_alloc(); + // model->right_label = furi_string_alloc(); + // model->ok_label = furi_string_alloc(); + + model->pressed_btn = 0; + }, + 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, + { + free(model->up_label); + free(model->down_label); + free(model->left_label); + free(model->right_label); + free(model->ok_label); + + // furi_string_free(model->up_label); + // furi_string_free(model->down_label); + // furi_string_free(model->left_label); + // furi_string_free(model->right_label); + // furi_string_free(model->ok_label); + }, + 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; +} \ No newline at end of file diff --git a/applications/external/subghz_remote_new/views/transmitter.h b/applications/external/subghz_remote_new/views/transmitter.h new file mode 100644 index 000000000..a324d09ec --- /dev/null +++ b/applications/external/subghz_remote_new/views/transmitter.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include "../helpers/subrem_custom_event.h" + +typedef struct SubRemViewRemote SubRemViewRemote; + +typedef void (*SubRemViewRemoteCallback)(SubRemCustomEvent event, void* context); + +void subrem_view_remote_set_callback( + SubRemViewRemote* subrem_view_remote, + SubRemViewRemoteCallback callback, + void* context); + +SubRemViewRemote* subrem_view_remote_alloc(); + +void subrem_view_remote_free(SubRemViewRemote* subrem_view_remote); + +View* subrem_view_remote_get_view(SubRemViewRemote* subrem_view_remote); + +void subrem_view_remote_add_data_to_show( + SubRemViewRemote* subrem_view_remote, + const char* up_label, + const char* down_label, + const char* left_label, + const char* right_label, + const char* ok_label); \ No newline at end of file diff --git a/applications/external/subghz_remote_new/views/transmitter_old.txt b/applications/external/subghz_remote_new/views/transmitter_old.txt new file mode 100644 index 000000000..ea2dc2f62 --- /dev/null +++ b/applications/external/subghz_remote_new/views/transmitter_old.txt @@ -0,0 +1,317 @@ +#include "transmitter.h" +#include "../subghz_remote_app_i.h" + +#include +#include + +#include + +struct SubGhzRemoteViewRemote { + View* view; + SubGhzRemoteViewRemoteCallback callback; + void* context; +}; + +typedef struct { + FuriString* frequency_str; + FuriString* preset_str; + FuriString* key_str; + // bool show_button; + // FuriString* temp_button_id; + // bool draw_temp_button; +} SubGhzRemoteViewRemoteModel; + +void subghz_view_transmitter_set_callback( + SubGhzRemoteViewRemote* subghz_transmitter, + SubGhzRemoteViewRemoteCallback callback, + void* context) { + furi_assert(subghz_transmitter); + + subghz_transmitter->callback = callback; + subghz_transmitter->context = context; +} + +void subghz_view_transmitter_add_data_to_show( + SubGhzRemoteViewRemote* subghz_transmitter, + const char* key_str, + const char* frequency_str, + const char* preset_str, + bool show_button) { + furi_assert(subghz_transmitter); + with_view_model( + subghz_transmitter->view, + SubGhzRemoteViewRemoteModel * model, + { + furi_string_set(model->key_str, key_str); + furi_string_set(model->frequency_str, frequency_str); + furi_string_set(model->preset_str, preset_str); + model->show_button = show_button; + }, + 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; + const uint8_t horizontal_offset = 1; + const uint8_t string_width = canvas_string_width(canvas, str); + const Icon* icon = &I_ButtonCenter_7x7; + const uint8_t icon_offset = 3; + const uint8_t icon_width_with_offset = icon_get_width(icon) + icon_offset; + const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset; + + const uint8_t x = (canvas_width(canvas) - button_width) / 2 + 40; + const uint8_t y = canvas_height(canvas); + + canvas_draw_box(canvas, x, y - button_height, button_width, button_height); + + canvas_draw_line(canvas, x - 1, y, x - 1, y - button_height + 0); + canvas_draw_line(canvas, x - 2, y, x - 2, y - button_height + 1); + canvas_draw_line(canvas, x - 3, y, x - 3, y - button_height + 2); + + canvas_draw_line(canvas, x + button_width + 0, y, x + button_width + 0, y - button_height + 0); + canvas_draw_line(canvas, x + button_width + 1, y, x + button_width + 1, y - button_height + 1); + canvas_draw_line(canvas, x + button_width + 2, y, x + button_width + 2, y - button_height + 2); + + canvas_invert_color(canvas); + canvas_draw_icon( + canvas, + x + horizontal_offset, + y - button_height + vertical_offset - 1, + &I_ButtonCenter_7x7); + canvas_draw_str( + canvas, x + horizontal_offset + icon_width_with_offset, y - vertical_offset, str); + canvas_invert_color(canvas); +} + +void subghz_view_transmitter_draw(Canvas* canvas, SubGhzRemoteViewRemoteModel* model) { + canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontSecondary); + elements_multiline_text_aligned( + 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->draw_temp_button) { + // canvas_set_font(canvas, FontBatteryPercent); + // canvas_draw_str(canvas, 117, 40, furi_string_get_cstr(model->temp_button_id)); + // canvas_set_font(canvas, FontSecondary); + // } + + // if(model->show_button) { + // canvas_draw_str(canvas, 58, 62, furi_hal_subghz_get_radio_type() ? "R: Ext" : "R: Int"); + // subghz_view_transmitter_button_right(canvas, "Send"); + // } +} + +bool subghz_view_transmitter_input(InputEvent* event, void* context) { + furi_assert(context); + SubGhzRemoteViewRemote* subghz_transmitter = context; + bool can_be_sent = false; + + if(event->key == InputKeyBack && event->type == InputTypeShort) { + with_view_model( + subghz_transmitter->view, + SubGhzRemoteViewRemoteModel * model, + { + furi_string_reset(model->frequency_str); + furi_string_reset(model->preset_str); + furi_string_reset(model->key_str); + furi_string_reset(model->temp_button_id); + model->show_button = false; + model->draw_temp_button = false; + }, + false); + return false; + } + + with_view_model( + subghz_transmitter->view, + SubGhzRemoteViewRemoteModel * model, + { + if(model->show_button) { + can_be_sent = true; + } + }, + true); + + if(can_be_sent && event->key == InputKeyOk && event->type == InputTypePress) { + subghz_custom_btn_set(0); + with_view_model( + subghz_transmitter->view, + SubGhzRemoteViewRemoteModel * model, + { + furi_string_reset(model->temp_button_id); + model->draw_temp_button = false; + }, + true); + subghz_transmitter->callback( + SubGhzCustomEventViewTransmitterSendStart, subghz_transmitter->context); + return true; + } else if(can_be_sent && event->key == InputKeyOk && event->type == InputTypeRelease) { + subghz_transmitter->callback( + SubGhzCustomEventViewTransmitterSendStop, subghz_transmitter->context); + return true; + } + + // Temp Buttons (UP) + if(can_be_sent && event->key == InputKeyUp && event->type == InputTypePress) { + subghz_custom_btn_set(1); + with_view_model( + subghz_transmitter->view, + SubGhzRemoteViewRemoteModel * model, + { + furi_string_reset(model->temp_button_id); + if(subghz_custom_btn_get_original() != 0) { + if(subghz_custom_btn_get() == 1) { + furi_string_printf( + model->temp_button_id, "%01X", subghz_custom_btn_get_original()); + model->draw_temp_button = true; + } + } + }, + true); + subghz_transmitter->callback( + SubGhzCustomEventViewTransmitterSendStart, subghz_transmitter->context); + return true; + } else if(can_be_sent && event->key == InputKeyUp && event->type == InputTypeRelease) { + subghz_transmitter->callback( + SubGhzCustomEventViewTransmitterSendStop, subghz_transmitter->context); + return true; + } + // Down + if(can_be_sent && event->key == InputKeyDown && event->type == InputTypePress) { + subghz_custom_btn_set(2); + with_view_model( + subghz_transmitter->view, + SubGhzRemoteViewRemoteModel * model, + { + furi_string_reset(model->temp_button_id); + if(subghz_custom_btn_get_original() != 0) { + if(subghz_custom_btn_get() == 2) { + furi_string_printf( + model->temp_button_id, "%01X", subghz_custom_btn_get_original()); + model->draw_temp_button = true; + } + } + }, + true); + subghz_transmitter->callback( + SubGhzCustomEventViewTransmitterSendStart, subghz_transmitter->context); + return true; + } else if(can_be_sent && event->key == InputKeyDown && event->type == InputTypeRelease) { + subghz_transmitter->callback( + SubGhzCustomEventViewTransmitterSendStop, subghz_transmitter->context); + return true; + } + // Left + if(can_be_sent && event->key == InputKeyLeft && event->type == InputTypePress) { + subghz_custom_btn_set(3); + with_view_model( + subghz_transmitter->view, + SubGhzRemoteViewRemoteModel * model, + { + furi_string_reset(model->temp_button_id); + if(subghz_custom_btn_get_original() != 0) { + if(subghz_custom_btn_get() == 3) { + furi_string_printf( + model->temp_button_id, "%01X", subghz_custom_btn_get_original()); + model->draw_temp_button = true; + } + } + }, + true); + subghz_transmitter->callback( + SubGhzCustomEventViewTransmitterSendStart, subghz_transmitter->context); + return true; + } else if(can_be_sent && event->key == InputKeyLeft && event->type == InputTypeRelease) { + subghz_transmitter->callback( + SubGhzCustomEventViewTransmitterSendStop, subghz_transmitter->context); + return true; + } + // Right + if(can_be_sent && event->key == InputKeyRight && event->type == InputTypePress) { + subghz_custom_btn_set(4); + with_view_model( + subghz_transmitter->view, + SubGhzRemoteViewRemoteModel * model, + { + furi_string_reset(model->temp_button_id); + if(subghz_custom_btn_get_original() != 0) { + if(subghz_custom_btn_get() == 4) { + furi_string_printf( + model->temp_button_id, "%01X", subghz_custom_btn_get_original()); + model->draw_temp_button = true; + } + } + }, + true); + subghz_transmitter->callback( + SubGhzCustomEventViewTransmitterSendStart, subghz_transmitter->context); + return true; + } else if(can_be_sent && event->key == InputKeyRight && event->type == InputTypeRelease) { + subghz_transmitter->callback( + SubGhzCustomEventViewTransmitterSendStop, subghz_transmitter->context); + return true; + } + + return true; +} + +void subghz_view_transmitter_enter(void* context) { + furi_assert(context); +} + +void subghz_view_transmitter_exit(void* context) { + furi_assert(context); +} + +SubGhzRemoteViewRemote* subghz_view_transmitter_alloc() { + SubGhzRemoteViewRemote* subghz_transmitter = malloc(sizeof(SubGhzRemoteViewRemote)); + + // View allocation and configuration + subghz_transmitter->view = view_alloc(); + view_allocate_model( + subghz_transmitter->view, ViewModelTypeLocking, sizeof(SubGhzRemoteViewRemoteModel)); + view_set_context(subghz_transmitter->view, subghz_transmitter); + view_set_draw_callback( + subghz_transmitter->view, (ViewDrawCallback)subghz_view_transmitter_draw); + view_set_input_callback(subghz_transmitter->view, subghz_view_transmitter_input); + view_set_enter_callback(subghz_transmitter->view, subghz_view_transmitter_enter); + view_set_exit_callback(subghz_transmitter->view, subghz_view_transmitter_exit); + + with_view_model( + subghz_transmitter->view, + SubGhzRemoteViewRemoteModel * model, + { + model->frequency_str = furi_string_alloc(); + model->preset_str = furi_string_alloc(); + model->key_str = furi_string_alloc(); + model->temp_button_id = furi_string_alloc(); + }, + true); + return subghz_transmitter; +} + +void subghz_view_transmitter_free(SubGhzRemoteViewRemote* subghz_transmitter) { + furi_assert(subghz_transmitter); + + with_view_model( + subghz_transmitter->view, + SubGhzRemoteViewRemoteModel * model, + { + furi_string_free(model->frequency_str); + furi_string_free(model->preset_str); + furi_string_free(model->key_str); + furi_string_free(model->temp_button_id); + }, + true); + view_free(subghz_transmitter->view); + free(subghz_transmitter); +} + +View* subghz_view_transmitter_get_view(SubGhzRemoteViewRemote* subghz_transmitter) { + furi_assert(subghz_transmitter); + return subghz_transmitter->view; +}