New SubGhz Remote GUI
15
applications/external/subghz_remote_new/application.fam
vendored
Normal file
@ -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",
|
||||
)
|
67
applications/external/subghz_remote_new/helpers/subrem_custom_event.h
vendored
Normal file
@ -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;
|
39
applications/external/subghz_remote_new/helpers/subrem_types.h
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
/*
|
||||
#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;*/
|
BIN
applications/external/subghz_remote_new/icons/ButtonDown_7x4.png
vendored
Normal file
After Width: | Height: | Size: 102 B |
BIN
applications/external/subghz_remote_new/icons/ButtonLeft_4x7.png
vendored
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
applications/external/subghz_remote_new/icons/ButtonRight_4x7.png
vendored
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
applications/external/subghz_remote_new/icons/ButtonUp_7x4.png
vendored
Normal file
After Width: | Height: | Size: 102 B |
BIN
applications/external/subghz_remote_new/icons/Ok_btn_9x9.png
vendored
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/external/subghz_remote_new/icons/Pin_arrow_up_7x9.png
vendored
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/external/subghz_remote_new/icons/Pin_cell_13x13.png
vendored
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/external/subghz_remote_new/icons/Pin_star_7x7.png
vendored
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/external/subghz_remote_new/icons/back_10px.png
vendored
Normal file
After Width: | Height: | Size: 154 B |
BIN
applications/external/subghz_remote_new/icons/sub1_10px.png
vendored
Normal file
After Width: | Height: | Size: 299 B |
30
applications/external/subghz_remote_new/scenes/subrem_scene.c
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
#include "../subghz_remote_app_i.h"
|
||||
|
||||
// Generate scene on_enter handlers array
|
||||
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
|
||||
void (*const subrem_scene_on_enter_handlers[])(void*) = {
|
||||
#include "subrem_scene_config.h"
|
||||
};
|
||||
#undef ADD_SCENE
|
||||
|
||||
// Generate scene on_event handlers array
|
||||
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
|
||||
bool (*const subrem_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = {
|
||||
#include "subrem_scene_config.h"
|
||||
};
|
||||
#undef ADD_SCENE
|
||||
|
||||
// Generate scene on_exit handlers array
|
||||
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
|
||||
void (*const subrem_scene_on_exit_handlers[])(void* context) = {
|
||||
#include "subrem_scene_config.h"
|
||||
};
|
||||
#undef ADD_SCENE
|
||||
|
||||
// Initialize scene handlers configuration structure
|
||||
const SceneManagerHandlers subrem_scene_handlers = {
|
||||
.on_enter_handlers = subrem_scene_on_enter_handlers,
|
||||
.on_event_handlers = subrem_scene_on_event_handlers,
|
||||
.on_exit_handlers = subrem_scene_on_exit_handlers,
|
||||
.scene_num = SubRemSceneNum,
|
||||
};
|
29
applications/external/subghz_remote_new/scenes/subrem_scene.h
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/scene_manager.h>
|
||||
|
||||
// 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
|
3
applications/external/subghz_remote_new/scenes/subrem_scene_config.h
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
ADD_SCENE(subrem, start, Start)
|
||||
ADD_SCENE(subrem, openmapfile, OpenMapFile)
|
||||
ADD_SCENE(subrem, remote, Remote)
|
26
applications/external/subghz_remote_new/scenes/subrem_scene_openmapfile.c
vendored
Normal file
@ -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);
|
||||
}
|
135
applications/external/subghz_remote_new/scenes/subrem_scene_remote.c
vendored
Normal file
@ -0,0 +1,135 @@
|
||||
#include "../subghz_remote_app_i.h"
|
||||
#include "../views/transmitter.h"
|
||||
|
||||
// TODO:
|
||||
// #include <lib/subghz/protocols/keeloq.h>
|
||||
// #include <lib/subghz/protocols/star_line.h>
|
||||
|
||||
// #include <lib/subghz/blocks/custom_btn.h>
|
||||
|
||||
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();
|
||||
}
|
93
applications/external/subghz_remote_new/scenes/subrem_scene_start.c
vendored
Normal file
@ -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);
|
||||
}
|
181
applications/external/subghz_remote_new/subghz_remote_app.c
vendored
Normal file
@ -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;
|
||||
}
|
28
applications/external/subghz_remote_new/subghz_remote_app_i.c
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
#include "subghz_remote_app_i.h"
|
||||
#include <lib/toolbox/path.h>
|
||||
#include <flipper_format/flipper_format_i.h>
|
||||
|
||||
#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;
|
||||
}
|
53
applications/external/subghz_remote_new/subghz_remote_app_i.h
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include "helpers/subrem_types.h"
|
||||
|
||||
#include "views/transmitter.h"
|
||||
|
||||
#include "scenes/subrem_scene.h"
|
||||
|
||||
#include <subghz_remote_new_icons.h> // TODO:
|
||||
#include <gui/gui.h>
|
||||
#include <gui/view_dispatcher.h>
|
||||
#include <gui/scene_manager.h>
|
||||
#include <gui/modules/submenu.h>
|
||||
#include <gui/modules/widget.h>
|
||||
#include <notification/notification_messages.h>
|
||||
#include <gui/modules/text_input.h>
|
||||
#include <dialogs/dialogs.h>
|
||||
#include <storage/storage.h>
|
||||
#include <gui/modules/popup.h>
|
||||
|
||||
// #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);
|
277
applications/external/subghz_remote_new/views/transmitter.c
vendored
Normal file
@ -0,0 +1,277 @@
|
||||
#include "transmitter.h"
|
||||
#include "../subghz_remote_app_i.h"
|
||||
|
||||
#include <input/input.h>
|
||||
#include <gui/elements.h>
|
||||
|
||||
#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;
|
||||
}
|
27
applications/external/subghz_remote_new/views/transmitter.h
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/view.h>
|
||||
#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);
|
317
applications/external/subghz_remote_new/views/transmitter_old.txt
vendored
Normal file
@ -0,0 +1,317 @@
|
||||
#include "transmitter.h"
|
||||
#include "../subghz_remote_app_i.h"
|
||||
|
||||
#include <input/input.h>
|
||||
#include <gui/elements.h>
|
||||
|
||||
#include <lib/subghz/blocks/custom_btn.h>
|
||||
|
||||
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;
|
||||
}
|