mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-25 06:13:14 +03:00
fap
This commit is contained in:
parent
43a7b50b74
commit
0b25cc5a5c
@ -1,16 +1,19 @@
|
||||
App(
|
||||
appid="subghz_remote_new",
|
||||
name="SubRem new",
|
||||
apptype=FlipperAppType.EXTERNAL,
|
||||
appid="subrem_remote_fap",
|
||||
name="Sub-GHz Remote",
|
||||
apptype=FlipperAppType.APP,
|
||||
entry_point="subghz_remote_app",
|
||||
cdefines=[
|
||||
"APP_SUBGHZREMOTE",
|
||||
"SUBREM_LIGHT",
|
||||
],
|
||||
requires=[
|
||||
"gui",
|
||||
"dialogs",
|
||||
],
|
||||
cdefines=["SUBREM_LIGHT"],
|
||||
icon="A_SubGHzRemote_14",
|
||||
stack_size=4 * 1024,
|
||||
order=12,
|
||||
order=50,
|
||||
fap_category="Debug",
|
||||
fap_icon_assets="icons",
|
||||
)
|
@ -1,13 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
// SubRemCustomEventManagerNoSet = 0,
|
||||
// SubRemCustomEventManagerSet,
|
||||
// SubRemCustomEventManagerSetRAW,
|
||||
|
||||
//SubmenuIndex
|
||||
SubmenuIndexSubRemOpenMapFile,
|
||||
SubmenuIndexSubRemRemoteView, // TODO: temp debug
|
||||
SubmenuIndexSubRemRemoteView,
|
||||
SubmenuIndexSubRemAbout,
|
||||
|
||||
//SubRemCustomEvent
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
// TODO: File version/type logic
|
||||
// #define SUBREM_APP_APP_FILE_VERSION 1
|
||||
// #define SUBREM_APP_APP_FILE_TYPE "Flipper SubRem Map file"
|
||||
#define SUBREM_APP_EXTENSION ".txt"
|
||||
@ -25,16 +26,7 @@ typedef enum {
|
||||
} SubRemViewID;
|
||||
|
||||
typedef enum {
|
||||
// Loadin State
|
||||
SubRemSubKeyTypeNoData = 0,
|
||||
// SubRemSubKeyTypeHaveFileName,
|
||||
|
||||
// Key Type
|
||||
SubRemSubKeyTypeStaticKey = 100,
|
||||
SubRemSubKeyTypeDynamicKey,
|
||||
SubRemSubKeyTypeRawKey,
|
||||
} SubRemSubKeyType; // TODO: depricated
|
||||
|
||||
// typedef enum {
|
||||
//
|
||||
// } SubRemLoadMapState;
|
||||
SubRemLoadMapStateBack = 0,
|
||||
SubRemLoadMapStateError,
|
||||
SubRemLoadMapStateOK,
|
||||
} SubRemLoadMapState;
|
@ -2,15 +2,12 @@
|
||||
|
||||
void subrem_scene_openmapfile_on_enter(void* context) {
|
||||
SubGhzRemoteApp* app = context;
|
||||
SubRemLoadMapState load_state = subrem_load_from_file(app);
|
||||
|
||||
if(subrem_load_from_file(app)) {
|
||||
scene_manager_next_scene(app->scene_manager, SubRemSceneRemote);
|
||||
} else {
|
||||
// TODO: Map Preset Reset
|
||||
|
||||
// #if SUBREM_LIGHT
|
||||
// dialog_message_show_storage_error(app->dialogs, "Can't load\nMap file");
|
||||
// #else
|
||||
if(load_state == SubRemLoadMapStateError) {
|
||||
#ifdef SUBREM_LIGHT
|
||||
dialog_message_show_storage_error(app->dialogs, "Can't load\nMap file");
|
||||
#else
|
||||
DialogMessage* message = dialog_message_alloc();
|
||||
|
||||
dialog_message_set_header(message, "Map File Error", 64, 8, AlignCenter, AlignCenter);
|
||||
@ -19,8 +16,12 @@ void subrem_scene_openmapfile_on_enter(void* context) {
|
||||
dialog_message_show(app->dialogs, message);
|
||||
|
||||
dialog_message_free(message);
|
||||
// #endif
|
||||
|
||||
#endif
|
||||
}
|
||||
if(load_state == SubRemLoadMapStateOK) {
|
||||
scene_manager_next_scene(app->scene_manager, SubRemSceneRemote);
|
||||
} else {
|
||||
// TODO: Map Preset Reset
|
||||
if(!scene_manager_search_and_switch_to_previous_scene(
|
||||
app->scene_manager, SubRemSceneStart)) {
|
||||
scene_manager_stop(app->scene_manager);
|
||||
|
@ -5,12 +5,6 @@
|
||||
|
||||
#define TAG "SubRemScenRemote"
|
||||
|
||||
// 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;
|
||||
@ -59,16 +53,10 @@ static bool subrem_scene_remote_update_data_show(void* context) {
|
||||
void subrem_scene_remote_on_enter(void* context) {
|
||||
SubGhzRemoteApp* app = context;
|
||||
|
||||
// TODO: init view data
|
||||
subrem_scene_remote_update_data_show(app);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -92,10 +80,10 @@ bool subrem_scene_remote_on_event(void* context, SceneManagerEvent event) {
|
||||
event.event == SubRemCustomEventViewRemoteStartRIGHT ||
|
||||
event.event == SubRemCustomEventViewRemoteStartOK) {
|
||||
// Start sending sub
|
||||
subghz_tx_stop_sub(app, true);
|
||||
subrem_tx_stop_sub(app, true);
|
||||
app->chusen_sub = subrem_scene_remote_event_to_index(event.event);
|
||||
subrem_view_remote_set_state(app->subrem_remote_view, SubRemViewRemoteStateLoading);
|
||||
if(subghz_tx_start_sub(
|
||||
if(subrem_tx_start_sub(
|
||||
app,
|
||||
app->subs_preset[app->chusen_sub],
|
||||
subrem_scene_remote_raw_callback_end_tx)) {
|
||||
@ -105,17 +93,18 @@ bool subrem_scene_remote_on_event(void* context, SceneManagerEvent event) {
|
||||
notification_message(app->notifications, &sequence_blink_start_magenta);
|
||||
} else {
|
||||
subrem_view_remote_set_state(app->subrem_remote_view, SubRemViewRemoteStateIdle);
|
||||
notification_message(app->notifications, &sequence_blink_stop);
|
||||
}
|
||||
return true;
|
||||
} else if(event.event == SubRemCustomEventViewRemoteForcedStop) {
|
||||
subghz_tx_stop_sub(app, true);
|
||||
subrem_tx_stop_sub(app, true);
|
||||
subrem_view_remote_set_presed_btn(app->subrem_remote_view, 0);
|
||||
subrem_view_remote_set_state(app->subrem_remote_view, SubRemViewRemoteStateIdle);
|
||||
|
||||
notification_message(app->notifications, &sequence_blink_stop);
|
||||
return true;
|
||||
} else if(event.event == SubRemCustomEventViewRemoteStop) {
|
||||
if(subghz_tx_stop_sub(app, false)) {
|
||||
if(subrem_tx_stop_sub(app, false)) {
|
||||
subrem_view_remote_set_presed_btn(app->subrem_remote_view, 0);
|
||||
subrem_view_remote_set_state(app->subrem_remote_view, SubRemViewRemoteStateIdle);
|
||||
|
||||
@ -132,19 +121,10 @@ bool subrem_scene_remote_on_event(void* context, SceneManagerEvent event) {
|
||||
void subrem_scene_remote_on_exit(void* context) {
|
||||
SubGhzRemoteApp* app = context;
|
||||
|
||||
subghz_tx_stop_sub(app, true);
|
||||
subrem_tx_stop_sub(app, true);
|
||||
|
||||
subrem_view_remote_set_presed_btn(app->subrem_remote_view, 0);
|
||||
subrem_view_remote_set_state(app->subrem_remote_view, SubRemViewRemoteStateIdle);
|
||||
|
||||
notification_message(app->notifications, &sequence_blink_stop);
|
||||
|
||||
// TODO: notifications and reset KL
|
||||
|
||||
// keeloq_reset_mfname();
|
||||
// keeloq_reset_kl_type();
|
||||
// keeloq_reset_original_btn();
|
||||
// subghz_custom_btns_reset();
|
||||
// star_line_reset_mfname();
|
||||
// star_line_reset_kl_type();
|
||||
}
|
||||
|
@ -48,7 +48,6 @@ bool subrem_scene_start_on_event(void* context, SceneManagerEvent event) {
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SubmenuIndexSubRemOpenMapFile) {
|
||||
//scene_manager_set_scene_state(app->scene_manager, SubRemSceneStart, event.event);
|
||||
scene_manager_next_scene(app->scene_manager, SubRemSceneOpenMapFile);
|
||||
consumed = true;
|
||||
}
|
||||
|
@ -34,16 +34,8 @@ SubGhzRemoteApp* subghz_remote_app_alloc() {
|
||||
|
||||
furi_hal_power_suppress_charge_enter();
|
||||
|
||||
// // 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;
|
||||
furi_string_set(app->file_path, SUBREM_APP_FOLDER);
|
||||
|
||||
// GUI
|
||||
app->gui = furi_record_open(RECORD_GUI);
|
||||
@ -71,19 +63,6 @@ SubGhzRemoteApp* subghz_remote_app_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);
|
||||
|
||||
@ -118,7 +97,11 @@ SubGhzRemoteApp* subghz_remote_app_alloc() {
|
||||
|
||||
app->tx_running = false;
|
||||
|
||||
#ifdef SUBREM_LIGHT
|
||||
scene_manager_next_scene(app->scene_manager, SubRemSceneOpenMapFile);
|
||||
#else
|
||||
scene_manager_next_scene(app->scene_manager, SubRemSceneStart);
|
||||
#endif
|
||||
|
||||
return app;
|
||||
}
|
||||
@ -137,18 +120,6 @@ void subghz_remote_app_free(SubGhzRemoteApp* app) {
|
||||
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);
|
||||
|
||||
|
@ -2,9 +2,13 @@
|
||||
#include <lib/toolbox/path.h>
|
||||
#include <flipper_format/flipper_format_i.h>
|
||||
|
||||
#include <lib/subghz/protocols/raw.h>
|
||||
#include <lib/subghz/protocols/protocol_items.h>
|
||||
|
||||
// #include <lib/subghz/protocols/keeloq.h>
|
||||
// #include <lib/subghz/protocols/star_line.h>
|
||||
|
||||
#include <lib/subghz/blocks/custom_btn.h>
|
||||
|
||||
#define TAG "SubGhzRemote"
|
||||
|
||||
static const char* map_file_labels[SubRemSubKeyNameMaxCount][2] = {
|
||||
@ -91,7 +95,7 @@ static bool subrem_map_preset_load(SubGhzRemoteApp* app, FlipperFormat* fff_data
|
||||
sub_preset = app->subs_preset[i];
|
||||
if(!flipper_format_read_string(
|
||||
fff_data_file, map_file_labels[i][0], sub_preset->file_path)) {
|
||||
#if FURO_LOG
|
||||
#if FURI_DEBUG
|
||||
FURI_LOG_W(TAG, "No file patch for %s", map_file_labels[i][0]);
|
||||
#endif
|
||||
sub_preset->type = SubGhzProtocolTypeUnknown;
|
||||
@ -99,11 +103,10 @@ static bool subrem_map_preset_load(SubGhzRemoteApp* app, FlipperFormat* fff_data
|
||||
// Rewind error
|
||||
} else if(!flipper_format_read_string(
|
||||
fff_data_file, map_file_labels[i][1], sub_preset->label)) {
|
||||
#if FURO_LOG
|
||||
#if FURI_DEBUG
|
||||
FURI_LOG_W(TAG, "No Label for %s", map_file_labels[i][0]);
|
||||
#endif
|
||||
furi_string_set_str(sub_preset->label,
|
||||
"N/A"); // TODO: Standart name or part of name
|
||||
path_extract_filename(sub_preset->file_path, sub_preset->label, true);
|
||||
} else {
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
@ -118,8 +121,7 @@ static bool subrem_map_preset_load(SubGhzRemoteApp* app, FlipperFormat* fff_data
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool subghz_save_protocol_to_file(FlipperFormat* flipper_format, const char* dev_file_name) {
|
||||
// furi_assert(subghz);
|
||||
bool subrem_save_protocol_to_file(FlipperFormat* flipper_format, const char* dev_file_name) {
|
||||
furi_assert(flipper_format);
|
||||
furi_assert(dev_file_name);
|
||||
|
||||
@ -135,12 +137,6 @@ bool subghz_save_protocol_to_file(FlipperFormat* flipper_format, const char* dev
|
||||
flipper_format_delete_key(flipper_format, "Repeat");
|
||||
//flipper_format_delete_key(flipper_format, "Manufacture");
|
||||
|
||||
// Create subghz folder directory if necessary
|
||||
// if(!storage_simply_mkdir(storage, furi_string_get_cstr(file_dir))) {
|
||||
// dialog_message_show_storage_error(subghz->dialogs, "Cannot create\nfolder");
|
||||
// break;
|
||||
// }
|
||||
|
||||
if(!storage_simply_remove(storage, dev_file_name)) {
|
||||
break;
|
||||
}
|
||||
@ -155,7 +151,7 @@ bool subghz_save_protocol_to_file(FlipperFormat* flipper_format, const char* dev
|
||||
return saved;
|
||||
}
|
||||
|
||||
bool subghz_tx_start_sub(
|
||||
bool subrem_tx_start_sub(
|
||||
SubGhzRemoteApp* app,
|
||||
SubRemSubFilePreset* sub_preset,
|
||||
SubGhzProtocolEncoderRAWCallbackEnd callback) {
|
||||
@ -163,7 +159,7 @@ bool subghz_tx_start_sub(
|
||||
furi_assert(sub_preset);
|
||||
bool ret = false;
|
||||
|
||||
subghz_tx_stop_sub(app, true);
|
||||
subrem_tx_stop_sub(app, true);
|
||||
|
||||
if(sub_preset->type == SubGhzProtocolTypeUnknown) {
|
||||
return false;
|
||||
@ -171,8 +167,12 @@ bool subghz_tx_start_sub(
|
||||
|
||||
FURI_LOG_I(TAG, "Send %s", furi_string_get_cstr(sub_preset->label));
|
||||
|
||||
// subghz_custom_btn_set(SUBGHZ_CUSTOM_BTN_OK);
|
||||
// keeloq_reset_original_btn();
|
||||
// subghz_custom_btns_reset();
|
||||
|
||||
do {
|
||||
flipper_format_rewind(sub_preset->fff_data); // FIXME:
|
||||
flipper_format_rewind(sub_preset->fff_data); //
|
||||
|
||||
app->transmitter = subghz_transmitter_alloc_init(
|
||||
app->environment, furi_string_get_cstr(sub_preset->protocaol_name));
|
||||
@ -215,7 +215,7 @@ bool subghz_tx_start_sub(
|
||||
}
|
||||
} while(false);
|
||||
|
||||
app->tx_running = ret; // TODO:
|
||||
app->tx_running = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -231,7 +231,7 @@ static void subghz_tx_stop(SubGhzRemoteApp* app) {
|
||||
furi_hal_subghz_idle();
|
||||
}
|
||||
|
||||
bool subghz_tx_stop_sub(SubGhzRemoteApp* app, bool forced) {
|
||||
bool subrem_tx_stop_sub(SubGhzRemoteApp* app, bool forced) {
|
||||
furi_assert(app);
|
||||
SubRemSubFilePreset* sub_preset = app->subs_preset[app->chusen_sub];
|
||||
|
||||
@ -241,8 +241,15 @@ bool subghz_tx_stop_sub(SubGhzRemoteApp* app, bool forced) {
|
||||
subghz_tx_stop(app);
|
||||
|
||||
if(sub_preset->type == SubGhzProtocolTypeDynamic) {
|
||||
subghz_save_protocol_to_file(
|
||||
subrem_save_protocol_to_file(
|
||||
sub_preset->fff_data, furi_string_get_cstr(sub_preset->file_path));
|
||||
|
||||
// keeloq_reset_mfname();
|
||||
// keeloq_reset_kl_type();
|
||||
// keeloq_reset_original_btn();
|
||||
// subghz_custom_btns_reset();
|
||||
// star_line_reset_mfname();
|
||||
// star_line_reset_kl_type();
|
||||
}
|
||||
|
||||
app->tx_running = false;
|
||||
@ -251,10 +258,6 @@ bool subghz_tx_stop_sub(SubGhzRemoteApp* app, bool forced) {
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
// SubRemSubFilePreset* sub_preset = app->subs_preset[app->chusen_sub];
|
||||
|
||||
// TODO: need saving logic
|
||||
}
|
||||
|
||||
static bool subrem_map_preset_check(SubGhzRemoteApp* app, FlipperFormat* fff_data_file) {
|
||||
@ -408,7 +411,7 @@ bool subrem_map_file_load(SubGhzRemoteApp* app, const char* file_path) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Pop for error or return error type
|
||||
// TODO: Popup for error or return error type
|
||||
if(!ret) {
|
||||
FURI_LOG_E(TAG, "Broken Map File");
|
||||
}
|
||||
@ -421,24 +424,25 @@ bool subrem_map_file_load(SubGhzRemoteApp* app, const char* file_path) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool subrem_load_from_file(SubGhzRemoteApp* app) {
|
||||
SubRemLoadMapState subrem_load_from_file(SubGhzRemoteApp* app) {
|
||||
furi_assert(app);
|
||||
|
||||
FuriString* file_path = furi_string_alloc();
|
||||
SubRemLoadMapState ret = SubRemLoadMapStateBack;
|
||||
|
||||
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 = subrem_map_file_load(app, furi_string_get_cstr(app->file_path));
|
||||
if(!dialog_file_browser_show(app->dialogs, app->file_path, app->file_path, &browser_options)) {
|
||||
} else if(subrem_map_file_load(app, furi_string_get_cstr(app->file_path))) {
|
||||
ret = SubRemLoadMapStateOK;
|
||||
} else {
|
||||
ret = SubRemLoadMapStateError;
|
||||
}
|
||||
|
||||
furi_string_free(file_path);
|
||||
|
||||
return res;
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "helpers/subrem_types.h"
|
||||
#include <subghz_remote_new_icons.h> // TODO:
|
||||
#include <subrem_remote_fap_icons.h>
|
||||
|
||||
// #include <assets_icons.h>
|
||||
|
||||
#include "views/remote.h"
|
||||
|
||||
@ -18,16 +20,16 @@
|
||||
#include <storage/storage.h>
|
||||
#include <gui/modules/popup.h>
|
||||
|
||||
#include <flipper_format/flipper_format_i.h>
|
||||
|
||||
#include <lib/subghz/protocols/raw.h>
|
||||
|
||||
#include <lib/subghz/subghz_setting.h>
|
||||
#include <lib/subghz/receiver.h>
|
||||
#include <lib/subghz/transmitter.h>
|
||||
|
||||
#include <flipper_format/flipper_format_i.h> // FIXME:
|
||||
|
||||
#define SUBREM_APP_FOLDER ANY_PATH("subghz_remote")
|
||||
#define SUBGHZ_REMOTE_MAX_LEN_NAME 64
|
||||
#define SUBREM_APP_FOLDER EXT_PATH("subghz_remote")
|
||||
#define SUBREM_MAX_LEN_NAME 64
|
||||
|
||||
typedef struct {
|
||||
uint32_t frequency;
|
||||
@ -54,12 +56,9 @@ typedef struct {
|
||||
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];
|
||||
char file_name_tmp[SUBREM_MAX_LEN_NAME];
|
||||
|
||||
SubRemViewRemote* subrem_remote_view;
|
||||
|
||||
@ -77,11 +76,11 @@ typedef struct {
|
||||
// TODO: LoadFileError
|
||||
} SubGhzRemoteApp;
|
||||
|
||||
bool subrem_load_from_file(SubGhzRemoteApp* app);
|
||||
SubRemLoadMapState subrem_load_from_file(SubGhzRemoteApp* app);
|
||||
|
||||
bool subghz_tx_start_sub(
|
||||
bool subrem_tx_start_sub(
|
||||
SubGhzRemoteApp* app,
|
||||
SubRemSubFilePreset* sub_preset,
|
||||
SubGhzProtocolEncoderRAWCallbackEnd callback);
|
||||
|
||||
bool subghz_tx_stop_sub(SubGhzRemoteApp* app, bool forced);
|
||||
bool subrem_tx_stop_sub(SubGhzRemoteApp* app, bool forced);
|
@ -29,9 +29,6 @@ typedef struct {
|
||||
SubRemViewRemoteState state;
|
||||
|
||||
uint8_t pressed_btn;
|
||||
// bool show_button;
|
||||
// FuriString* temp_button_id;
|
||||
// bool draw_temp_button;
|
||||
} SubRemViewRemoteModel;
|
||||
|
||||
void subrem_view_remote_set_callback(
|
||||
@ -93,18 +90,8 @@ 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);
|
||||
@ -121,6 +108,7 @@ void subrem_view_remote_draw(Canvas* canvas, SubRemViewRemoteModel* model) {
|
||||
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));
|
||||
@ -130,9 +118,6 @@ void subrem_view_remote_draw(Canvas* canvas, SubRemViewRemoteModel* model) {
|
||||
canvas_draw_str_aligned(canvas, 11, 62, AlignLeft, AlignBottom, "Hold=Exit.");
|
||||
|
||||
//Status text and indicator
|
||||
|
||||
//canvas_draw_str_aligned(canvas, 126, 10, AlignRight, AlignBottom, model->state);
|
||||
|
||||
canvas_draw_icon(canvas, 113, 15, &I_Pin_cell_13x13);
|
||||
|
||||
if(model->state == SubRemViewRemoteStateIdle) {
|
||||
@ -146,7 +131,9 @@ void subrem_view_remote_draw(Canvas* canvas, SubRemViewRemoteModel* model) {
|
||||
canvas_draw_str_aligned(canvas, 126, 10, AlignRight, AlignBottom, "Load");
|
||||
break;
|
||||
default:
|
||||
canvas_draw_str_aligned(canvas, 126, 10, AlignRight, AlignBottom, "Idle");
|
||||
#if FURI_DEBUG
|
||||
canvas_draw_str_aligned(canvas, 126, 10, AlignRight, AlignBottom, "Wrong_state");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@ -179,7 +166,6 @@ bool subrem_view_remote_input(InputEvent* event, void* context) {
|
||||
SubRemViewRemote* subrem_view_remote = context;
|
||||
|
||||
if(event->key == InputKeyBack && event->type == InputTypeLong) {
|
||||
// TODO: remove reset Debug
|
||||
with_view_model(
|
||||
subrem_view_remote->view,
|
||||
SubRemViewRemoteModel * model,
|
||||
@ -189,12 +175,6 @@ bool subrem_view_remote_input(InputEvent* event, void* context) {
|
||||
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);
|
||||
subrem_view_remote->callback(SubRemCustomEventViewRemoteBack, subrem_view_remote->context);
|
||||
@ -280,11 +260,11 @@ SubRemViewRemote* subrem_view_remote_alloc() {
|
||||
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->up_label = furi_string_alloc_set_str("N/A");
|
||||
// model->down_label = furi_string_alloc_set_str("N/A");
|
||||
// model->left_label = furi_string_alloc_set_str("N/A");
|
||||
// model->right_label = furi_string_alloc_set_str("N/A");
|
||||
// model->ok_label = furi_string_alloc_set_str("N/A");
|
||||
|
||||
model->pressed_btn = 0;
|
||||
},
|
||||
|
@ -1,317 +0,0 @@
|
||||
#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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user