[FL-2627] Flipper applications: SDK, build and debug system (#1387)
* Added support for running applications from SD card (FAPs - Flipper Application Packages) * Added plugin_dist target for fbt to build FAPs * All apps of type FlipperAppType.EXTERNAL and FlipperAppType.PLUGIN are built as FAPs by default * Updated VSCode configuration for new fbt features - re-deploy stock configuration to use them * Added debugging support for FAPs with fbt debug & VSCode * Added public firmware API with automated versioning Co-authored-by: hedger <hedger@users.noreply.github.com> Co-authored-by: SG <who.just.the.doctor@gmail.com> Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
#include "../../infrared_i.h"
|
||||
|
||||
#include <dolphin/dolphin.h>
|
||||
|
||||
void infrared_scene_universal_common_item_callback(void* context, uint32_t index) {
|
||||
Infrared* infrared = context;
|
||||
uint32_t event = infrared_custom_event_pack(InfraredCustomEventTypeButtonSelected, index);
|
||||
view_dispatcher_send_custom_event(infrared->view_dispatcher, event);
|
||||
}
|
||||
|
||||
static void infrared_scene_universal_common_progress_back_callback(void* context) {
|
||||
Infrared* infrared = context;
|
||||
uint32_t event = infrared_custom_event_pack(InfraredCustomEventTypeBackPressed, -1);
|
||||
view_dispatcher_send_custom_event(infrared->view_dispatcher, event);
|
||||
}
|
||||
|
||||
static void infrared_scene_universal_common_show_popup(Infrared* infrared, uint32_t record_count) {
|
||||
ViewStack* view_stack = infrared->view_stack;
|
||||
InfraredProgressView* progress = infrared->progress;
|
||||
infrared_progress_view_set_progress_total(progress, record_count);
|
||||
infrared_progress_view_set_back_callback(
|
||||
progress, infrared_scene_universal_common_progress_back_callback, infrared);
|
||||
view_stack_add_view(view_stack, infrared_progress_view_get_view(progress));
|
||||
infrared_play_notification_message(infrared, InfraredNotificationMessageBlinkStartSend);
|
||||
}
|
||||
|
||||
static void infrared_scene_universal_common_hide_popup(Infrared* infrared) {
|
||||
ViewStack* view_stack = infrared->view_stack;
|
||||
InfraredProgressView* progress = infrared->progress;
|
||||
view_stack_remove_view(view_stack, infrared_progress_view_get_view(progress));
|
||||
infrared_play_notification_message(infrared, InfraredNotificationMessageBlinkStop);
|
||||
}
|
||||
|
||||
void infrared_scene_universal_common_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
view_stack_add_view(infrared->view_stack, button_panel_get_view(infrared->button_panel));
|
||||
}
|
||||
|
||||
bool infrared_scene_universal_common_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
InfraredBruteForce* brute_force = infrared->brute_force;
|
||||
bool consumed = false;
|
||||
|
||||
if(infrared_brute_force_is_started(brute_force)) {
|
||||
if(event.type == SceneManagerEventTypeTick) {
|
||||
bool success = infrared_brute_force_send_next(brute_force);
|
||||
if(success) {
|
||||
success = infrared_progress_view_increase_progress(infrared->progress);
|
||||
}
|
||||
if(!success) {
|
||||
infrared_brute_force_stop(brute_force);
|
||||
infrared_scene_universal_common_hide_popup(infrared);
|
||||
}
|
||||
consumed = true;
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(infrared_custom_event_get_type(event.event) == InfraredCustomEventTypeBackPressed) {
|
||||
infrared_brute_force_stop(brute_force);
|
||||
infrared_scene_universal_common_hide_popup(infrared);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
scene_manager_previous_scene(scene_manager);
|
||||
consumed = true;
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(infrared_custom_event_get_type(event.event) ==
|
||||
InfraredCustomEventTypeButtonSelected) {
|
||||
uint32_t record_count;
|
||||
if(infrared_brute_force_start(
|
||||
brute_force, infrared_custom_event_get_value(event.event), &record_count)) {
|
||||
DOLPHIN_DEED(DolphinDeedIrBruteForce);
|
||||
infrared_scene_universal_common_show_popup(infrared, record_count);
|
||||
} else {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneErrorDatabases);
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_universal_common_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
ButtonPanel* button_panel = infrared->button_panel;
|
||||
view_stack_remove_view(infrared->view_stack, button_panel_get_view(button_panel));
|
||||
button_panel_reset(button_panel);
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/scene_manager.h>
|
||||
|
||||
void infrared_scene_universal_common_on_enter(void* context);
|
||||
bool infrared_scene_universal_common_on_event(void* context, SceneManagerEvent event);
|
||||
void infrared_scene_universal_common_on_exit(void* context);
|
||||
void infrared_scene_universal_common_item_callback(void* context, uint32_t index);
|
30
applications/main/infrared/scenes/infrared_scene.c
Normal file
30
applications/main/infrared/scenes/infrared_scene.c
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "infrared_scene.h"
|
||||
|
||||
// Generate scene on_enter handlers array
|
||||
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
|
||||
void (*const infrared_on_enter_handlers[])(void*) = {
|
||||
#include "infrared_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 infrared_on_event_handlers[])(void* context, SceneManagerEvent event) = {
|
||||
#include "infrared_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 infrared_on_exit_handlers[])(void* context) = {
|
||||
#include "infrared_scene_config.h"
|
||||
};
|
||||
#undef ADD_SCENE
|
||||
|
||||
// Initialize scene handlers configuration structure
|
||||
const SceneManagerHandlers infrared_scene_handlers = {
|
||||
.on_enter_handlers = infrared_on_enter_handlers,
|
||||
.on_event_handlers = infrared_on_event_handlers,
|
||||
.on_exit_handlers = infrared_on_exit_handlers,
|
||||
.scene_num = InfraredSceneNum,
|
||||
};
|
29
applications/main/infrared/scenes/infrared_scene.h
Normal file
29
applications/main/infrared/scenes/infrared_scene.h
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) InfraredScene##id,
|
||||
typedef enum {
|
||||
#include "infrared_scene_config.h"
|
||||
InfraredSceneNum,
|
||||
} InfraredScene;
|
||||
#undef ADD_SCENE
|
||||
|
||||
extern const SceneManagerHandlers infrared_scene_handlers;
|
||||
|
||||
// Generate scene on_enter handlers declaration
|
||||
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
|
||||
#include "infrared_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 "infrared_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 "infrared_scene_config.h"
|
||||
#undef ADD_SCENE
|
59
applications/main/infrared/scenes/infrared_scene_ask_back.c
Normal file
59
applications/main/infrared/scenes/infrared_scene_ask_back.c
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
static void infrared_scene_dialog_result_callback(DialogExResult result, void* context) {
|
||||
Infrared* infrared = context;
|
||||
view_dispatcher_send_custom_event(infrared->view_dispatcher, result);
|
||||
}
|
||||
|
||||
void infrared_scene_ask_back_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
DialogEx* dialog_ex = infrared->dialog_ex;
|
||||
|
||||
if(infrared->app_state.is_learning_new_remote) {
|
||||
dialog_ex_set_header(dialog_ex, "Exit to Infrared Menu?", 64, 0, AlignCenter, AlignTop);
|
||||
} else {
|
||||
dialog_ex_set_header(dialog_ex, "Exit to Remote Menu?", 64, 0, AlignCenter, AlignTop);
|
||||
}
|
||||
|
||||
dialog_ex_set_text(
|
||||
dialog_ex, "All unsaved data\nwill be lost!", 64, 31, AlignCenter, AlignCenter);
|
||||
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
|
||||
dialog_ex_set_left_button_text(dialog_ex, "Exit");
|
||||
dialog_ex_set_center_button_text(dialog_ex, NULL);
|
||||
dialog_ex_set_right_button_text(dialog_ex, "Stay");
|
||||
dialog_ex_set_result_callback(dialog_ex, infrared_scene_dialog_result_callback);
|
||||
dialog_ex_set_context(dialog_ex, context);
|
||||
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewDialogEx);
|
||||
}
|
||||
|
||||
bool infrared_scene_ask_back_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
consumed = true;
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == DialogExResultLeft) {
|
||||
if(infrared->app_state.is_learning_new_remote) {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
scene_manager, InfraredSceneStart);
|
||||
} else {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
scene_manager, InfraredSceneRemote);
|
||||
}
|
||||
consumed = true;
|
||||
} else if(event.event == DialogExResultRight) {
|
||||
scene_manager_previous_scene(scene_manager);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_ask_back_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
dialog_ex_reset(infrared->dialog_ex);
|
||||
}
|
48
applications/main/infrared/scenes/infrared_scene_ask_retry.c
Normal file
48
applications/main/infrared/scenes/infrared_scene_ask_retry.c
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
static void infrared_scene_dialog_result_callback(DialogExResult result, void* context) {
|
||||
Infrared* infrared = context;
|
||||
view_dispatcher_send_custom_event(infrared->view_dispatcher, result);
|
||||
}
|
||||
|
||||
void infrared_scene_ask_retry_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
DialogEx* dialog_ex = infrared->dialog_ex;
|
||||
|
||||
dialog_ex_set_header(dialog_ex, "Return to Reading?", 64, 0, AlignCenter, AlignTop);
|
||||
dialog_ex_set_text(
|
||||
dialog_ex, "All unsaved data\nwill be lost!", 64, 31, AlignCenter, AlignCenter);
|
||||
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
|
||||
dialog_ex_set_left_button_text(dialog_ex, "Exit");
|
||||
dialog_ex_set_center_button_text(dialog_ex, NULL);
|
||||
dialog_ex_set_right_button_text(dialog_ex, "Stay");
|
||||
dialog_ex_set_result_callback(dialog_ex, infrared_scene_dialog_result_callback);
|
||||
dialog_ex_set_context(dialog_ex, context);
|
||||
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewDialogEx);
|
||||
}
|
||||
|
||||
bool infrared_scene_ask_retry_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
consumed = true;
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == DialogExResultLeft) {
|
||||
scene_manager_search_and_switch_to_previous_scene(scene_manager, InfraredSceneLearn);
|
||||
consumed = true;
|
||||
} else if(event.event == DialogExResultRight) {
|
||||
scene_manager_previous_scene(scene_manager);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_ask_retry_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
dialog_ex_reset(infrared->dialog_ex);
|
||||
}
|
20
applications/main/infrared/scenes/infrared_scene_config.h
Normal file
20
applications/main/infrared/scenes/infrared_scene_config.h
Normal file
@@ -0,0 +1,20 @@
|
||||
ADD_SCENE(infrared, start, Start)
|
||||
ADD_SCENE(infrared, ask_back, AskBack)
|
||||
ADD_SCENE(infrared, ask_retry, AskRetry)
|
||||
ADD_SCENE(infrared, edit, Edit)
|
||||
ADD_SCENE(infrared, edit_delete, EditDelete)
|
||||
ADD_SCENE(infrared, edit_delete_done, EditDeleteDone)
|
||||
ADD_SCENE(infrared, edit_button_select, EditButtonSelect)
|
||||
ADD_SCENE(infrared, edit_rename, EditRename)
|
||||
ADD_SCENE(infrared, edit_rename_done, EditRenameDone)
|
||||
ADD_SCENE(infrared, learn, Learn)
|
||||
ADD_SCENE(infrared, learn_done, LearnDone)
|
||||
ADD_SCENE(infrared, learn_enter_name, LearnEnterName)
|
||||
ADD_SCENE(infrared, learn_success, LearnSuccess)
|
||||
ADD_SCENE(infrared, remote, Remote)
|
||||
ADD_SCENE(infrared, remote_list, RemoteList)
|
||||
ADD_SCENE(infrared, universal, Universal)
|
||||
ADD_SCENE(infrared, universal_tv, UniversalTV)
|
||||
ADD_SCENE(infrared, debug, Debug)
|
||||
ADD_SCENE(infrared, error_databases, ErrorDatabases)
|
||||
ADD_SCENE(infrared, rpc, Rpc)
|
69
applications/main/infrared/scenes/infrared_scene_debug.c
Normal file
69
applications/main/infrared/scenes/infrared_scene_debug.c
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
void infrared_scene_debug_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
InfraredWorker* worker = infrared->worker;
|
||||
|
||||
infrared_worker_rx_set_received_signal_callback(
|
||||
worker, infrared_signal_received_callback, context);
|
||||
infrared_worker_rx_enable_blink_on_receiving(worker, true);
|
||||
infrared_worker_rx_start(worker);
|
||||
|
||||
infrared_debug_view_set_text(infrared->debug_view, "Received signals\nwill appear here");
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewDebugView);
|
||||
}
|
||||
|
||||
bool infrared_scene_debug_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == InfraredCustomEventTypeSignalReceived) {
|
||||
InfraredDebugView* debug_view = infrared->debug_view;
|
||||
InfraredSignal* signal = infrared->received_signal;
|
||||
|
||||
if(infrared_signal_is_raw(signal)) {
|
||||
InfraredRawSignal* raw = infrared_signal_get_raw_signal(signal);
|
||||
infrared_debug_view_set_text(debug_view, "RAW\n%d samples\n", raw->timings_size);
|
||||
|
||||
printf("RAW, %d samples:\r\n", raw->timings_size);
|
||||
for(size_t i = 0; i < raw->timings_size; ++i) {
|
||||
printf("%lu ", raw->timings[i]);
|
||||
}
|
||||
printf("\r\n");
|
||||
|
||||
} else {
|
||||
InfraredMessage* message = infrared_signal_get_message(signal);
|
||||
infrared_debug_view_set_text(
|
||||
debug_view,
|
||||
"%s\nA:0x%0*lX\nC:0x%0*lX\n%s\n",
|
||||
infrared_get_protocol_name(message->protocol),
|
||||
ROUND_UP_TO(infrared_get_protocol_address_length(message->protocol), 4),
|
||||
message->address,
|
||||
ROUND_UP_TO(infrared_get_protocol_command_length(message->protocol), 4),
|
||||
message->command,
|
||||
message->repeat ? " R" : "");
|
||||
|
||||
printf(
|
||||
"== %s, A:0x%0*lX, C:0x%0*lX%s ==\r\n",
|
||||
infrared_get_protocol_name(message->protocol),
|
||||
ROUND_UP_TO(infrared_get_protocol_address_length(message->protocol), 4),
|
||||
message->address,
|
||||
ROUND_UP_TO(infrared_get_protocol_command_length(message->protocol), 4),
|
||||
message->command,
|
||||
message->repeat ? " R" : "");
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_debug_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
InfraredWorker* worker = infrared->worker;
|
||||
infrared_worker_rx_stop(worker);
|
||||
infrared_worker_rx_enable_blink_on_receiving(worker, false);
|
||||
infrared_worker_rx_set_received_signal_callback(worker, NULL, NULL);
|
||||
}
|
101
applications/main/infrared/scenes/infrared_scene_edit.c
Normal file
101
applications/main/infrared/scenes/infrared_scene_edit.c
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
typedef enum {
|
||||
SubmenuIndexAddButton,
|
||||
SubmenuIndexRenameButton,
|
||||
SubmenuIndexDeleteButton,
|
||||
SubmenuIndexRenameRemote,
|
||||
SubmenuIndexDeleteRemote,
|
||||
} SubmenuIndex;
|
||||
|
||||
static void infrared_scene_edit_submenu_callback(void* context, uint32_t index) {
|
||||
Infrared* infrared = context;
|
||||
view_dispatcher_send_custom_event(infrared->view_dispatcher, index);
|
||||
}
|
||||
|
||||
void infrared_scene_edit_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
Submenu* submenu = infrared->submenu;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Add Button",
|
||||
SubmenuIndexAddButton,
|
||||
infrared_scene_edit_submenu_callback,
|
||||
context);
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Rename Button",
|
||||
SubmenuIndexRenameButton,
|
||||
infrared_scene_edit_submenu_callback,
|
||||
context);
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Delete Button",
|
||||
SubmenuIndexDeleteButton,
|
||||
infrared_scene_edit_submenu_callback,
|
||||
context);
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Rename Remote",
|
||||
SubmenuIndexRenameRemote,
|
||||
infrared_scene_edit_submenu_callback,
|
||||
context);
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Delete Remote",
|
||||
SubmenuIndexDeleteRemote,
|
||||
infrared_scene_edit_submenu_callback,
|
||||
context);
|
||||
|
||||
const uint32_t submenu_index = scene_manager_get_scene_state(scene_manager, InfraredSceneEdit);
|
||||
submenu_set_selected_item(submenu, submenu_index);
|
||||
scene_manager_set_scene_state(scene_manager, InfraredSceneEdit, SubmenuIndexAddButton);
|
||||
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewSubmenu);
|
||||
}
|
||||
|
||||
bool infrared_scene_edit_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
const uint32_t submenu_index = event.event;
|
||||
scene_manager_set_scene_state(scene_manager, InfraredSceneEdit, submenu_index);
|
||||
|
||||
if(submenu_index == SubmenuIndexAddButton) {
|
||||
infrared->app_state.is_learning_new_remote = false;
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneLearn);
|
||||
consumed = true;
|
||||
} else if(submenu_index == SubmenuIndexRenameButton) {
|
||||
infrared->app_state.edit_target = InfraredEditTargetButton;
|
||||
infrared->app_state.edit_mode = InfraredEditModeRename;
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneEditButtonSelect);
|
||||
consumed = true;
|
||||
} else if(submenu_index == SubmenuIndexDeleteButton) {
|
||||
infrared->app_state.edit_target = InfraredEditTargetButton;
|
||||
infrared->app_state.edit_mode = InfraredEditModeDelete;
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneEditButtonSelect);
|
||||
consumed = true;
|
||||
} else if(submenu_index == SubmenuIndexRenameRemote) {
|
||||
infrared->app_state.edit_target = InfraredEditTargetRemote;
|
||||
infrared->app_state.edit_mode = InfraredEditModeRename;
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneEditRename);
|
||||
consumed = true;
|
||||
} else if(submenu_index == SubmenuIndexDeleteRemote) {
|
||||
infrared->app_state.edit_target = InfraredEditTargetRemote;
|
||||
infrared->app_state.edit_mode = InfraredEditModeDelete;
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneEditDelete);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_edit_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
submenu_reset(infrared->submenu);
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
static void infrared_scene_edit_button_select_submenu_callback(void* context, uint32_t index) {
|
||||
Infrared* infrared = context;
|
||||
view_dispatcher_send_custom_event(infrared->view_dispatcher, index);
|
||||
}
|
||||
|
||||
void infrared_scene_edit_button_select_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
Submenu* submenu = infrared->submenu;
|
||||
InfraredRemote* remote = infrared->remote;
|
||||
InfraredAppState* app_state = &infrared->app_state;
|
||||
|
||||
const char* header = infrared->app_state.edit_mode == InfraredEditModeRename ?
|
||||
"Rename Button:" :
|
||||
"Delete Button:";
|
||||
submenu_set_header(submenu, header);
|
||||
|
||||
const size_t button_count = infrared_remote_get_button_count(remote);
|
||||
for(size_t i = 0; i < button_count; ++i) {
|
||||
InfraredRemoteButton* button = infrared_remote_get_button(remote, i);
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
infrared_remote_button_get_name(button),
|
||||
i,
|
||||
infrared_scene_edit_button_select_submenu_callback,
|
||||
context);
|
||||
}
|
||||
|
||||
if(button_count && app_state->current_button_index != InfraredButtonIndexNone) {
|
||||
submenu_set_selected_item(submenu, app_state->current_button_index);
|
||||
app_state->current_button_index = InfraredButtonIndexNone;
|
||||
}
|
||||
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewSubmenu);
|
||||
}
|
||||
|
||||
bool infrared_scene_edit_button_select_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
InfraredAppState* app_state = &infrared->app_state;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
app_state->current_button_index = event.event;
|
||||
const InfraredEditMode edit_mode = app_state->edit_mode;
|
||||
if(edit_mode == InfraredEditModeRename) {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneEditRename);
|
||||
} else if(edit_mode == InfraredEditModeDelete) {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneEditDelete);
|
||||
} else {
|
||||
furi_assert(0);
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_edit_button_select_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
submenu_reset(infrared->submenu);
|
||||
}
|
112
applications/main/infrared/scenes/infrared_scene_edit_delete.c
Normal file
112
applications/main/infrared/scenes/infrared_scene_edit_delete.c
Normal file
@@ -0,0 +1,112 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
static void
|
||||
infrared_scene_edit_delete_dialog_result_callback(DialogExResult result, void* context) {
|
||||
Infrared* infrared = context;
|
||||
view_dispatcher_send_custom_event(infrared->view_dispatcher, result);
|
||||
}
|
||||
|
||||
void infrared_scene_edit_delete_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
DialogEx* dialog_ex = infrared->dialog_ex;
|
||||
InfraredRemote* remote = infrared->remote;
|
||||
|
||||
const InfraredEditTarget edit_target = infrared->app_state.edit_target;
|
||||
if(edit_target == InfraredEditTargetButton) {
|
||||
int32_t current_button_index = infrared->app_state.current_button_index;
|
||||
furi_assert(current_button_index != InfraredButtonIndexNone);
|
||||
|
||||
dialog_ex_set_header(dialog_ex, "Delete Button?", 64, 0, AlignCenter, AlignTop);
|
||||
InfraredRemoteButton* current_button =
|
||||
infrared_remote_get_button(remote, current_button_index);
|
||||
InfraredSignal* signal = infrared_remote_button_get_signal(current_button);
|
||||
|
||||
if(infrared_signal_is_raw(signal)) {
|
||||
const InfraredRawSignal* raw = infrared_signal_get_raw_signal(signal);
|
||||
infrared_text_store_set(
|
||||
infrared,
|
||||
0,
|
||||
"%s\nRAW\n%ld samples",
|
||||
infrared_remote_button_get_name(current_button),
|
||||
raw->timings_size);
|
||||
|
||||
} else {
|
||||
const InfraredMessage* message = infrared_signal_get_message(signal);
|
||||
infrared_text_store_set(
|
||||
infrared,
|
||||
0,
|
||||
"%s\n%s\nA=0x%0*lX C=0x%0*lX",
|
||||
infrared_remote_button_get_name(current_button),
|
||||
infrared_get_protocol_name(message->protocol),
|
||||
ROUND_UP_TO(infrared_get_protocol_address_length(message->protocol), 4),
|
||||
message->address,
|
||||
ROUND_UP_TO(infrared_get_protocol_command_length(message->protocol), 4),
|
||||
message->command);
|
||||
}
|
||||
|
||||
} else if(edit_target == InfraredEditTargetRemote) {
|
||||
dialog_ex_set_header(dialog_ex, "Delete Remote?", 64, 0, AlignCenter, AlignTop);
|
||||
infrared_text_store_set(
|
||||
infrared,
|
||||
0,
|
||||
"%s\n with %lu buttons",
|
||||
infrared_remote_get_name(remote),
|
||||
infrared_remote_get_button_count(remote));
|
||||
} else {
|
||||
furi_assert(0);
|
||||
}
|
||||
|
||||
dialog_ex_set_text(dialog_ex, infrared->text_store[0], 64, 31, AlignCenter, AlignCenter);
|
||||
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
|
||||
dialog_ex_set_left_button_text(dialog_ex, "Cancel");
|
||||
dialog_ex_set_right_button_text(dialog_ex, "Delete");
|
||||
dialog_ex_set_result_callback(dialog_ex, infrared_scene_edit_delete_dialog_result_callback);
|
||||
dialog_ex_set_context(dialog_ex, context);
|
||||
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewDialogEx);
|
||||
}
|
||||
|
||||
bool infrared_scene_edit_delete_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == DialogExResultLeft) {
|
||||
scene_manager_previous_scene(scene_manager);
|
||||
consumed = true;
|
||||
} else if(event.event == DialogExResultRight) {
|
||||
bool success = false;
|
||||
InfraredRemote* remote = infrared->remote;
|
||||
InfraredAppState* app_state = &infrared->app_state;
|
||||
const InfraredEditTarget edit_target = app_state->edit_target;
|
||||
|
||||
if(edit_target == InfraredEditTargetButton) {
|
||||
furi_assert(app_state->current_button_index != InfraredButtonIndexNone);
|
||||
success = infrared_remote_delete_button(remote, app_state->current_button_index);
|
||||
app_state->current_button_index = InfraredButtonIndexNone;
|
||||
} else if(edit_target == InfraredEditTargetRemote) {
|
||||
success = infrared_remote_remove(remote);
|
||||
app_state->current_button_index = InfraredButtonIndexNone;
|
||||
} else {
|
||||
furi_assert(0);
|
||||
}
|
||||
|
||||
if(success) {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneEditDeleteDone);
|
||||
} else {
|
||||
const uint32_t possible_scenes[] = {InfraredSceneRemoteList, InfraredSceneStart};
|
||||
scene_manager_search_and_switch_to_previous_scene_one_of(
|
||||
scene_manager, possible_scenes, COUNT_OF(possible_scenes));
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_edit_delete_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
UNUSED(infrared);
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
void infrared_scene_edit_delete_done_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
Popup* popup = infrared->popup;
|
||||
|
||||
popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62);
|
||||
popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom);
|
||||
|
||||
popup_set_callback(popup, infrared_popup_closed_callback);
|
||||
popup_set_context(popup, context);
|
||||
popup_set_timeout(popup, 1500);
|
||||
popup_enable_timeout(popup);
|
||||
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup);
|
||||
}
|
||||
|
||||
bool infrared_scene_edit_delete_done_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == InfraredCustomEventTypePopupClosed) {
|
||||
const InfraredEditTarget edit_target = infrared->app_state.edit_target;
|
||||
if(edit_target == InfraredEditTargetButton) {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
scene_manager, InfraredSceneRemote);
|
||||
} else if(edit_target == InfraredEditTargetRemote) {
|
||||
const uint32_t possible_scenes[] = {InfraredSceneStart, InfraredSceneRemoteList};
|
||||
if(!scene_manager_search_and_switch_to_previous_scene_one_of(
|
||||
scene_manager, possible_scenes, COUNT_OF(possible_scenes))) {
|
||||
view_dispatcher_stop(infrared->view_dispatcher);
|
||||
}
|
||||
} else {
|
||||
furi_assert(0);
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_edit_delete_done_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
UNUSED(infrared);
|
||||
}
|
107
applications/main/infrared/scenes/infrared_scene_edit_rename.c
Normal file
107
applications/main/infrared/scenes/infrared_scene_edit_rename.c
Normal file
@@ -0,0 +1,107 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <toolbox/path.h>
|
||||
|
||||
void infrared_scene_edit_rename_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
InfraredRemote* remote = infrared->remote;
|
||||
TextInput* text_input = infrared->text_input;
|
||||
size_t enter_name_length = 0;
|
||||
|
||||
const InfraredEditTarget edit_target = infrared->app_state.edit_target;
|
||||
if(edit_target == InfraredEditTargetButton) {
|
||||
text_input_set_header_text(text_input, "Name the button");
|
||||
|
||||
const int32_t current_button_index = infrared->app_state.current_button_index;
|
||||
furi_assert(current_button_index != InfraredButtonIndexNone);
|
||||
|
||||
InfraredRemoteButton* current_button =
|
||||
infrared_remote_get_button(remote, current_button_index);
|
||||
enter_name_length = INFRARED_MAX_BUTTON_NAME_LENGTH;
|
||||
strncpy(
|
||||
infrared->text_store[0],
|
||||
infrared_remote_button_get_name(current_button),
|
||||
enter_name_length);
|
||||
|
||||
} else if(edit_target == InfraredEditTargetRemote) {
|
||||
text_input_set_header_text(text_input, "Name the remote");
|
||||
enter_name_length = INFRARED_MAX_REMOTE_NAME_LENGTH;
|
||||
strncpy(infrared->text_store[0], infrared_remote_get_name(remote), enter_name_length);
|
||||
|
||||
string_t folder_path;
|
||||
string_init(folder_path);
|
||||
|
||||
if(string_end_with_str_p(infrared->file_path, INFRARED_APP_EXTENSION)) {
|
||||
path_extract_dirname(string_get_cstr(infrared->file_path), folder_path);
|
||||
}
|
||||
|
||||
ValidatorIsFile* validator_is_file = validator_is_file_alloc_init(
|
||||
string_get_cstr(folder_path),
|
||||
INFRARED_APP_EXTENSION,
|
||||
infrared_remote_get_name(remote));
|
||||
text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
|
||||
|
||||
string_clear(folder_path);
|
||||
} else {
|
||||
furi_assert(0);
|
||||
}
|
||||
|
||||
text_input_set_result_callback(
|
||||
text_input,
|
||||
infrared_text_input_callback,
|
||||
context,
|
||||
infrared->text_store[0],
|
||||
enter_name_length,
|
||||
false);
|
||||
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewTextInput);
|
||||
}
|
||||
|
||||
bool infrared_scene_edit_rename_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
InfraredRemote* remote = infrared->remote;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
InfraredAppState* app_state = &infrared->app_state;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == InfraredCustomEventTypeTextEditDone) {
|
||||
bool success = false;
|
||||
const InfraredEditTarget edit_target = app_state->edit_target;
|
||||
if(edit_target == InfraredEditTargetButton) {
|
||||
const int32_t current_button_index = app_state->current_button_index;
|
||||
furi_assert(current_button_index != InfraredButtonIndexNone);
|
||||
success = infrared_remote_rename_button(
|
||||
remote, infrared->text_store[0], current_button_index);
|
||||
app_state->current_button_index = InfraredButtonIndexNone;
|
||||
} else if(edit_target == InfraredEditTargetRemote) {
|
||||
success = infrared_rename_current_remote(infrared, infrared->text_store[0]);
|
||||
} else {
|
||||
furi_assert(0);
|
||||
}
|
||||
|
||||
if(success) {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneEditRenameDone);
|
||||
} else {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
scene_manager, InfraredSceneRemoteList);
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_edit_rename_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
TextInput* text_input = infrared->text_input;
|
||||
|
||||
void* validator_context = text_input_get_validator_callback_context(text_input);
|
||||
text_input_set_validator(text_input, NULL, NULL);
|
||||
|
||||
if(validator_context) {
|
||||
validator_is_file_free((ValidatorIsFile*)validator_context);
|
||||
}
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
void infrared_scene_edit_rename_done_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
Popup* popup = infrared->popup;
|
||||
|
||||
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
|
||||
popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop);
|
||||
|
||||
popup_set_callback(popup, infrared_popup_closed_callback);
|
||||
popup_set_context(popup, context);
|
||||
popup_set_timeout(popup, 1500);
|
||||
popup_enable_timeout(popup);
|
||||
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup);
|
||||
}
|
||||
|
||||
bool infrared_scene_edit_rename_done_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == InfraredCustomEventTypePopupClosed) {
|
||||
if(!scene_manager_search_and_switch_to_previous_scene(
|
||||
infrared->scene_manager, InfraredSceneRemote)) {
|
||||
scene_manager_next_scene(infrared->scene_manager, InfraredSceneRemote);
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_edit_rename_done_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
UNUSED(infrared);
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
void infrared_scene_error_databases_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
Popup* popup = infrared->popup;
|
||||
|
||||
popup_set_icon(popup, 5, 11, &I_SDQuestion_35x43);
|
||||
popup_set_text(
|
||||
popup, "Function requires\nSD card with fresh\ndatabases.", 47, 17, AlignLeft, AlignTop);
|
||||
|
||||
popup_set_context(popup, context);
|
||||
popup_set_callback(popup, infrared_popup_closed_callback);
|
||||
|
||||
infrared_play_notification_message(infrared, InfraredNotificationMessageYellowOn);
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup);
|
||||
}
|
||||
|
||||
bool infrared_scene_error_databases_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == InfraredCustomEventTypePopupClosed) {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
infrared->scene_manager, InfraredSceneUniversal);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_error_databases_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
popup_reset(infrared->popup);
|
||||
infrared_play_notification_message(infrared, InfraredNotificationMessageYellowOff);
|
||||
}
|
45
applications/main/infrared/scenes/infrared_scene_learn.c
Normal file
45
applications/main/infrared/scenes/infrared_scene_learn.c
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
void infrared_scene_learn_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
Popup* popup = infrared->popup;
|
||||
InfraredWorker* worker = infrared->worker;
|
||||
|
||||
infrared_worker_rx_set_received_signal_callback(
|
||||
worker, infrared_signal_received_callback, context);
|
||||
infrared_worker_rx_start(worker);
|
||||
infrared_play_notification_message(infrared, InfraredNotificationMessageBlinkStartRead);
|
||||
|
||||
popup_set_icon(popup, 0, 32, &I_InfraredLearnShort_128x31);
|
||||
popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignCenter);
|
||||
popup_set_text(
|
||||
popup, "Point the remote at IR port\nand push the button", 5, 10, AlignLeft, AlignCenter);
|
||||
popup_set_callback(popup, NULL);
|
||||
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup);
|
||||
}
|
||||
|
||||
bool infrared_scene_learn_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == InfraredCustomEventTypeSignalReceived) {
|
||||
infrared_play_notification_message(infrared, InfraredNotificationMessageSuccess);
|
||||
scene_manager_next_scene(infrared->scene_manager, InfraredSceneLearnSuccess);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_learn_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
Popup* popup = infrared->popup;
|
||||
infrared_worker_rx_set_received_signal_callback(infrared->worker, NULL, NULL);
|
||||
infrared_worker_rx_stop(infrared->worker);
|
||||
infrared_play_notification_message(infrared, InfraredNotificationMessageBlinkStop);
|
||||
popup_set_icon(popup, 0, 0, NULL);
|
||||
popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignCenter);
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
#include <dolphin/dolphin.h>
|
||||
|
||||
void infrared_scene_learn_done_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
Popup* popup = infrared->popup;
|
||||
|
||||
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
|
||||
DOLPHIN_DEED(DolphinDeedIrSave);
|
||||
|
||||
if(infrared->app_state.is_learning_new_remote) {
|
||||
popup_set_header(popup, "New remote\ncreated!", 0, 0, AlignLeft, AlignTop);
|
||||
} else {
|
||||
popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop);
|
||||
}
|
||||
|
||||
popup_set_callback(popup, infrared_popup_closed_callback);
|
||||
popup_set_context(popup, context);
|
||||
popup_set_timeout(popup, 1500);
|
||||
popup_enable_timeout(popup);
|
||||
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup);
|
||||
}
|
||||
|
||||
bool infrared_scene_learn_done_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == InfraredCustomEventTypePopupClosed) {
|
||||
if(!scene_manager_search_and_switch_to_previous_scene(
|
||||
infrared->scene_manager, InfraredSceneRemote)) {
|
||||
scene_manager_next_scene(infrared->scene_manager, InfraredSceneRemote);
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_learn_done_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
infrared->app_state.is_learning_new_remote = false;
|
||||
popup_set_header(infrared->popup, NULL, 0, 0, AlignLeft, AlignTop);
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
void infrared_scene_learn_enter_name_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
TextInput* text_input = infrared->text_input;
|
||||
InfraredSignal* signal = infrared->received_signal;
|
||||
|
||||
if(infrared_signal_is_raw(signal)) {
|
||||
InfraredRawSignal* raw = infrared_signal_get_raw_signal(signal);
|
||||
infrared_text_store_set(infrared, 0, "RAW_%d", raw->timings_size);
|
||||
} else {
|
||||
InfraredMessage* message = infrared_signal_get_message(signal);
|
||||
infrared_text_store_set(
|
||||
infrared,
|
||||
0,
|
||||
"%.4s_%0*lX",
|
||||
infrared_get_protocol_name(message->protocol),
|
||||
ROUND_UP_TO(infrared_get_protocol_command_length(message->protocol), 4),
|
||||
message->command);
|
||||
}
|
||||
|
||||
text_input_set_header_text(text_input, "Name the button");
|
||||
text_input_set_result_callback(
|
||||
text_input,
|
||||
infrared_text_input_callback,
|
||||
context,
|
||||
infrared->text_store[0],
|
||||
INFRARED_MAX_BUTTON_NAME_LENGTH,
|
||||
true);
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewTextInput);
|
||||
}
|
||||
|
||||
bool infrared_scene_learn_enter_name_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
InfraredSignal* signal = infrared->received_signal;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == InfraredCustomEventTypeTextEditDone) {
|
||||
bool success = false;
|
||||
if(infrared->app_state.is_learning_new_remote) {
|
||||
success =
|
||||
infrared_add_remote_with_button(infrared, infrared->text_store[0], signal);
|
||||
} else {
|
||||
success =
|
||||
infrared_remote_add_button(infrared->remote, infrared->text_store[0], signal);
|
||||
}
|
||||
|
||||
if(success) {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneLearnDone);
|
||||
} else {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
scene_manager, InfraredSceneRemoteList);
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_learn_enter_name_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
UNUSED(infrared);
|
||||
}
|
105
applications/main/infrared/scenes/infrared_scene_learn_success.c
Normal file
105
applications/main/infrared/scenes/infrared_scene_learn_success.c
Normal file
@@ -0,0 +1,105 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
#include <dolphin/dolphin.h>
|
||||
|
||||
static void
|
||||
infrared_scene_learn_success_dialog_result_callback(DialogExResult result, void* context) {
|
||||
Infrared* infrared = context;
|
||||
view_dispatcher_send_custom_event(infrared->view_dispatcher, result);
|
||||
}
|
||||
|
||||
void infrared_scene_learn_success_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
DialogEx* dialog_ex = infrared->dialog_ex;
|
||||
InfraredSignal* signal = infrared->received_signal;
|
||||
|
||||
DOLPHIN_DEED(DolphinDeedIrLearnSuccess);
|
||||
infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOn);
|
||||
|
||||
if(infrared_signal_is_raw(signal)) {
|
||||
InfraredRawSignal* raw = infrared_signal_get_raw_signal(signal);
|
||||
dialog_ex_set_header(dialog_ex, "Unknown", 95, 10, AlignCenter, AlignCenter);
|
||||
infrared_text_store_set(infrared, 0, "%d samples", raw->timings_size);
|
||||
dialog_ex_set_text(dialog_ex, infrared->text_store[0], 75, 23, AlignLeft, AlignTop);
|
||||
|
||||
} else {
|
||||
InfraredMessage* message = infrared_signal_get_message(signal);
|
||||
uint8_t addr_digits =
|
||||
ROUND_UP_TO(infrared_get_protocol_address_length(message->protocol), 4);
|
||||
uint8_t cmd_digits =
|
||||
ROUND_UP_TO(infrared_get_protocol_command_length(message->protocol), 4);
|
||||
uint8_t max_digits = MAX(addr_digits, cmd_digits);
|
||||
max_digits = MIN(max_digits, 7);
|
||||
size_t label_x_offset = 63 + (7 - max_digits) * 3;
|
||||
|
||||
infrared_text_store_set(infrared, 0, "%s", infrared_get_protocol_name(message->protocol));
|
||||
infrared_text_store_set(
|
||||
infrared,
|
||||
1,
|
||||
"A: 0x%0*lX\nC: 0x%0*lX\n",
|
||||
addr_digits,
|
||||
message->address,
|
||||
cmd_digits,
|
||||
message->command);
|
||||
|
||||
dialog_ex_set_header(dialog_ex, infrared->text_store[0], 95, 7, AlignCenter, AlignCenter);
|
||||
dialog_ex_set_text(
|
||||
dialog_ex, infrared->text_store[1], label_x_offset, 34, AlignLeft, AlignCenter);
|
||||
}
|
||||
|
||||
dialog_ex_set_left_button_text(dialog_ex, "Retry");
|
||||
dialog_ex_set_right_button_text(dialog_ex, "Save");
|
||||
dialog_ex_set_center_button_text(dialog_ex, "Send");
|
||||
dialog_ex_set_icon(dialog_ex, 0, 1, &I_DolphinReadingSuccess_59x63);
|
||||
dialog_ex_set_result_callback(dialog_ex, infrared_scene_learn_success_dialog_result_callback);
|
||||
dialog_ex_set_context(dialog_ex, context);
|
||||
dialog_ex_enable_extended_events(dialog_ex);
|
||||
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewDialogEx);
|
||||
}
|
||||
|
||||
bool infrared_scene_learn_success_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
const bool is_transmitter_idle = !infrared->app_state.is_transmitting;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeTick) {
|
||||
if(is_transmitter_idle) {
|
||||
infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOn);
|
||||
}
|
||||
consumed = true;
|
||||
} else if(event.type == SceneManagerEventTypeBack) {
|
||||
if(is_transmitter_idle) {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneAskBack);
|
||||
}
|
||||
consumed = true;
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == DialogExResultLeft) {
|
||||
if(is_transmitter_idle) {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneAskRetry);
|
||||
}
|
||||
consumed = true;
|
||||
} else if(event.event == DialogExResultRight) {
|
||||
if(is_transmitter_idle) {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneLearnEnterName);
|
||||
}
|
||||
consumed = true;
|
||||
} else if(event.event == DialogExPressCenter) {
|
||||
infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOff);
|
||||
infrared_tx_start_received(infrared);
|
||||
consumed = true;
|
||||
} else if(event.event == DialogExReleaseCenter) {
|
||||
infrared_tx_stop(infrared);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_learn_success_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
dialog_ex_reset(infrared->dialog_ex);
|
||||
infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOff);
|
||||
}
|
121
applications/main/infrared/scenes/infrared_scene_remote.c
Normal file
121
applications/main/infrared/scenes/infrared_scene_remote.c
Normal file
@@ -0,0 +1,121 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
typedef enum {
|
||||
ButtonIndexPlus = -2,
|
||||
ButtonIndexEdit = -1,
|
||||
ButtonIndexNA = 0,
|
||||
} ButtonIndex;
|
||||
|
||||
static void
|
||||
infrared_scene_remote_button_menu_callback(void* context, int32_t index, InputType type) {
|
||||
Infrared* infrared = context;
|
||||
|
||||
uint16_t custom_type;
|
||||
if(type == InputTypePress) {
|
||||
custom_type = InfraredCustomEventTypeTransmitStarted;
|
||||
} else if(type == InputTypeRelease) {
|
||||
custom_type = InfraredCustomEventTypeTransmitStopped;
|
||||
} else if(type == InputTypeShort) {
|
||||
custom_type = InfraredCustomEventTypeMenuSelected;
|
||||
} else {
|
||||
furi_crash("Unexpected input type");
|
||||
}
|
||||
|
||||
view_dispatcher_send_custom_event(
|
||||
infrared->view_dispatcher, infrared_custom_event_pack(custom_type, index));
|
||||
}
|
||||
|
||||
void infrared_scene_remote_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
InfraredRemote* remote = infrared->remote;
|
||||
ButtonMenu* button_menu = infrared->button_menu;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
|
||||
size_t button_count = infrared_remote_get_button_count(remote);
|
||||
for(size_t i = 0; i < button_count; ++i) {
|
||||
InfraredRemoteButton* button = infrared_remote_get_button(remote, i);
|
||||
button_menu_add_item(
|
||||
button_menu,
|
||||
infrared_remote_button_get_name(button),
|
||||
i,
|
||||
infrared_scene_remote_button_menu_callback,
|
||||
ButtonMenuItemTypeCommon,
|
||||
context);
|
||||
}
|
||||
|
||||
button_menu_add_item(
|
||||
button_menu,
|
||||
"+",
|
||||
ButtonIndexPlus,
|
||||
infrared_scene_remote_button_menu_callback,
|
||||
ButtonMenuItemTypeControl,
|
||||
context);
|
||||
button_menu_add_item(
|
||||
button_menu,
|
||||
"Edit",
|
||||
ButtonIndexEdit,
|
||||
infrared_scene_remote_button_menu_callback,
|
||||
ButtonMenuItemTypeControl,
|
||||
context);
|
||||
|
||||
button_menu_set_header(button_menu, infrared_remote_get_name(remote));
|
||||
const int16_t button_index =
|
||||
(signed)scene_manager_get_scene_state(scene_manager, InfraredSceneRemote);
|
||||
button_menu_set_selected_item(button_menu, button_index);
|
||||
scene_manager_set_scene_state(scene_manager, InfraredSceneRemote, ButtonIndexNA);
|
||||
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewButtonMenu);
|
||||
}
|
||||
|
||||
bool infrared_scene_remote_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
const bool is_transmitter_idle = !infrared->app_state.is_transmitting;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
if(is_transmitter_idle) {
|
||||
const uint32_t possible_scenes[] = {InfraredSceneRemoteList, InfraredSceneStart};
|
||||
consumed = scene_manager_search_and_switch_to_previous_scene_one_of(
|
||||
scene_manager, possible_scenes, COUNT_OF(possible_scenes));
|
||||
} else {
|
||||
consumed = true;
|
||||
}
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
const uint16_t custom_type = infrared_custom_event_get_type(event.event);
|
||||
const int16_t button_index = infrared_custom_event_get_value(event.event);
|
||||
|
||||
if(custom_type == InfraredCustomEventTypeTransmitStarted) {
|
||||
furi_assert(button_index >= 0);
|
||||
infrared_tx_start_button_index(infrared, button_index);
|
||||
consumed = true;
|
||||
} else if(custom_type == InfraredCustomEventTypeTransmitStopped) {
|
||||
infrared_tx_stop(infrared);
|
||||
consumed = true;
|
||||
} else if(custom_type == InfraredCustomEventTypeMenuSelected) {
|
||||
furi_assert(button_index < 0);
|
||||
if(is_transmitter_idle) {
|
||||
scene_manager_set_scene_state(
|
||||
scene_manager, InfraredSceneRemote, (unsigned)button_index);
|
||||
if(button_index == ButtonIndexPlus) {
|
||||
infrared->app_state.is_learning_new_remote = false;
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneLearn);
|
||||
consumed = true;
|
||||
} else if(button_index == ButtonIndexEdit) {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneEdit);
|
||||
consumed = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_remote_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
button_menu_reset(infrared->button_menu);
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
void infrared_scene_remote_list_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
ViewDispatcher* view_dispatcher = infrared->view_dispatcher;
|
||||
|
||||
DialogsFileBrowserOptions browser_options;
|
||||
dialog_file_browser_set_basic_options(&browser_options, INFRARED_APP_EXTENSION, &I_ir_10px);
|
||||
|
||||
bool success = dialog_file_browser_show(
|
||||
infrared->dialogs, infrared->file_path, infrared->file_path, &browser_options);
|
||||
|
||||
if(success) {
|
||||
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
|
||||
view_dispatcher_switch_to_view(view_dispatcher, InfraredViewStack);
|
||||
|
||||
infrared_show_loading_popup(infrared, true);
|
||||
success = infrared_remote_load(infrared->remote, infrared->file_path);
|
||||
infrared_show_loading_popup(infrared, false);
|
||||
}
|
||||
|
||||
if(success) {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneRemote);
|
||||
} else {
|
||||
scene_manager_previous_scene(scene_manager);
|
||||
}
|
||||
}
|
||||
|
||||
bool infrared_scene_remote_list_on_event(void* context, SceneManagerEvent event) {
|
||||
UNUSED(context);
|
||||
UNUSED(event);
|
||||
bool consumed = false;
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_remote_list_on_exit(void* context) {
|
||||
UNUSED(context);
|
||||
}
|
100
applications/main/infrared/scenes/infrared_scene_rpc.c
Normal file
100
applications/main/infrared/scenes/infrared_scene_rpc.c
Normal file
@@ -0,0 +1,100 @@
|
||||
#include "../infrared_i.h"
|
||||
#include "gui/canvas.h"
|
||||
|
||||
typedef enum {
|
||||
InfraredRpcStateIdle,
|
||||
InfraredRpcStateLoaded,
|
||||
InfraredRpcStateSending,
|
||||
} InfraredRpcState;
|
||||
|
||||
void infrared_scene_rpc_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
Popup* popup = infrared->popup;
|
||||
|
||||
popup_set_header(popup, "Infrared", 89, 42, AlignCenter, AlignBottom);
|
||||
popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop);
|
||||
|
||||
popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61);
|
||||
|
||||
popup_set_context(popup, context);
|
||||
popup_set_callback(popup, infrared_popup_closed_callback);
|
||||
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup);
|
||||
|
||||
scene_manager_set_scene_state(infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateIdle);
|
||||
|
||||
notification_message(infrared->notifications, &sequence_display_backlight_on);
|
||||
}
|
||||
|
||||
bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
consumed = true;
|
||||
InfraredRpcState state =
|
||||
scene_manager_get_scene_state(infrared->scene_manager, InfraredSceneRpc);
|
||||
if(event.event == InfraredCustomEventTypeBackPressed) {
|
||||
view_dispatcher_stop(infrared->view_dispatcher);
|
||||
} else if(event.event == InfraredCustomEventTypePopupClosed) {
|
||||
view_dispatcher_stop(infrared->view_dispatcher);
|
||||
} else if(event.event == InfraredCustomEventTypeRpcLoad) {
|
||||
bool result = false;
|
||||
const char* arg = rpc_system_app_get_data(infrared->rpc_ctx);
|
||||
if(arg && (state == InfraredRpcStateIdle)) {
|
||||
string_set_str(infrared->file_path, arg);
|
||||
result = infrared_remote_load(infrared->remote, infrared->file_path);
|
||||
if(result) {
|
||||
scene_manager_set_scene_state(
|
||||
infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateLoaded);
|
||||
}
|
||||
}
|
||||
const char* remote_name = infrared_remote_get_name(infrared->remote);
|
||||
|
||||
infrared_text_store_set(infrared, 0, "loaded\n%s", remote_name);
|
||||
popup_set_text(
|
||||
infrared->popup, infrared->text_store[0], 89, 44, AlignCenter, AlignTop);
|
||||
|
||||
rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventLoadFile, result);
|
||||
} else if(event.event == InfraredCustomEventTypeRpcButtonPress) {
|
||||
bool result = false;
|
||||
const char* arg = rpc_system_app_get_data(infrared->rpc_ctx);
|
||||
if(arg && (state == InfraredRpcStateLoaded)) {
|
||||
size_t button_index = 0;
|
||||
if(infrared_remote_find_button_by_name(infrared->remote, arg, &button_index)) {
|
||||
infrared_tx_start_button_index(infrared, button_index);
|
||||
result = true;
|
||||
scene_manager_set_scene_state(
|
||||
infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateSending);
|
||||
}
|
||||
}
|
||||
rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventButtonRelease, result);
|
||||
} else if(event.event == InfraredCustomEventTypeRpcButtonRelease) {
|
||||
bool result = false;
|
||||
if(state == InfraredRpcStateSending) {
|
||||
infrared_tx_stop(infrared);
|
||||
result = true;
|
||||
scene_manager_set_scene_state(
|
||||
infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateLoaded);
|
||||
}
|
||||
rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventButtonRelease, result);
|
||||
} else if(event.event == InfraredCustomEventTypeRpcExit) {
|
||||
scene_manager_stop(infrared->scene_manager);
|
||||
view_dispatcher_stop(infrared->view_dispatcher);
|
||||
rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventAppExit, true);
|
||||
} else if(event.event == InfraredCustomEventTypeRpcSessionClose) {
|
||||
scene_manager_stop(infrared->scene_manager);
|
||||
view_dispatcher_stop(infrared->view_dispatcher);
|
||||
}
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_rpc_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
if(scene_manager_get_scene_state(infrared->scene_manager, InfraredSceneRpc) ==
|
||||
InfraredRpcStateSending) {
|
||||
infrared_tx_stop(infrared);
|
||||
}
|
||||
popup_reset(infrared->popup);
|
||||
}
|
84
applications/main/infrared/scenes/infrared_scene_start.c
Normal file
84
applications/main/infrared/scenes/infrared_scene_start.c
Normal file
@@ -0,0 +1,84 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
enum SubmenuIndex {
|
||||
SubmenuIndexUniversalRemotes,
|
||||
SubmenuIndexLearnNewRemote,
|
||||
SubmenuIndexSavedRemotes,
|
||||
SubmenuIndexDebug
|
||||
};
|
||||
|
||||
static void infrared_scene_start_submenu_callback(void* context, uint32_t index) {
|
||||
Infrared* infrared = context;
|
||||
view_dispatcher_send_custom_event(infrared->view_dispatcher, index);
|
||||
}
|
||||
|
||||
void infrared_scene_start_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
Submenu* submenu = infrared->submenu;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Universal Remotes",
|
||||
SubmenuIndexUniversalRemotes,
|
||||
infrared_scene_start_submenu_callback,
|
||||
infrared);
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Learn New Remote",
|
||||
SubmenuIndexLearnNewRemote,
|
||||
infrared_scene_start_submenu_callback,
|
||||
infrared);
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Saved Remotes",
|
||||
SubmenuIndexSavedRemotes,
|
||||
infrared_scene_start_submenu_callback,
|
||||
infrared);
|
||||
|
||||
if(infrared->app_state.is_debug_enabled) {
|
||||
submenu_add_item(
|
||||
submenu, "Debug", SubmenuIndexDebug, infrared_scene_start_submenu_callback, infrared);
|
||||
}
|
||||
|
||||
const uint32_t submenu_index =
|
||||
scene_manager_get_scene_state(scene_manager, InfraredSceneStart);
|
||||
submenu_set_selected_item(submenu, submenu_index);
|
||||
scene_manager_set_scene_state(scene_manager, InfraredSceneStart, SubmenuIndexUniversalRemotes);
|
||||
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewSubmenu);
|
||||
}
|
||||
|
||||
bool infrared_scene_start_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
const uint32_t submenu_index = event.event;
|
||||
scene_manager_set_scene_state(scene_manager, InfraredSceneStart, submenu_index);
|
||||
if(submenu_index == SubmenuIndexUniversalRemotes) {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneUniversal);
|
||||
consumed = true;
|
||||
} else if(submenu_index == SubmenuIndexLearnNewRemote) {
|
||||
infrared->app_state.is_learning_new_remote = true;
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneLearn);
|
||||
consumed = true;
|
||||
} else if(submenu_index == SubmenuIndexSavedRemotes) {
|
||||
string_set_str(infrared->file_path, INFRARED_APP_FOLDER);
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneRemoteList);
|
||||
consumed = true;
|
||||
} else if(submenu_index == SubmenuIndexDebug) {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneDebug);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_start_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
submenu_reset(infrared->submenu);
|
||||
}
|
53
applications/main/infrared/scenes/infrared_scene_universal.c
Normal file
53
applications/main/infrared/scenes/infrared_scene_universal.c
Normal file
@@ -0,0 +1,53 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
typedef enum {
|
||||
SubmenuIndexUniversalTV,
|
||||
SubmenuIndexUniversalAudio,
|
||||
SubmenuIndexUniversalAirConditioner,
|
||||
} SubmenuIndex;
|
||||
|
||||
static void infrared_scene_universal_submenu_callback(void* context, uint32_t index) {
|
||||
Infrared* infrared = context;
|
||||
view_dispatcher_send_custom_event(infrared->view_dispatcher, index);
|
||||
}
|
||||
|
||||
void infrared_scene_universal_on_enter(void* context) {
|
||||
Infrared* infrared = context;
|
||||
Submenu* submenu = infrared->submenu;
|
||||
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"TVs",
|
||||
SubmenuIndexUniversalTV,
|
||||
infrared_scene_universal_submenu_callback,
|
||||
context);
|
||||
submenu_set_selected_item(submenu, 0);
|
||||
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewSubmenu);
|
||||
}
|
||||
|
||||
bool infrared_scene_universal_on_event(void* context, SceneManagerEvent event) {
|
||||
Infrared* infrared = context;
|
||||
SceneManager* scene_manager = infrared->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SubmenuIndexUniversalTV) {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneUniversalTV);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexUniversalAudio) {
|
||||
//TODO Implement Audio universal remote
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexUniversalAirConditioner) {
|
||||
//TODO Implement A/C universal remote
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void infrared_scene_universal_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
submenu_reset(infrared->submenu);
|
||||
}
|
111
applications/main/infrared/scenes/infrared_scene_universal_tv.c
Normal file
111
applications/main/infrared/scenes/infrared_scene_universal_tv.c
Normal file
@@ -0,0 +1,111 @@
|
||||
#include "../infrared_i.h"
|
||||
|
||||
#include "common/infrared_scene_universal_common.h"
|
||||
|
||||
void infrared_scene_universal_tv_on_enter(void* context) {
|
||||
infrared_scene_universal_common_on_enter(context);
|
||||
|
||||
Infrared* infrared = context;
|
||||
ButtonPanel* button_panel = infrared->button_panel;
|
||||
InfraredBruteForce* brute_force = infrared->brute_force;
|
||||
|
||||
infrared_brute_force_set_db_filename(brute_force, EXT_PATH("infrared/assets/tv.ir"));
|
||||
|
||||
button_panel_reserve(button_panel, 2, 3);
|
||||
uint32_t i = 0;
|
||||
button_panel_add_item(
|
||||
button_panel,
|
||||
i,
|
||||
0,
|
||||
0,
|
||||
3,
|
||||
19,
|
||||
&I_Power_25x27,
|
||||
&I_Power_hvr_25x27,
|
||||
infrared_scene_universal_common_item_callback,
|
||||
context);
|
||||
infrared_brute_force_add_record(brute_force, i++, "POWER");
|
||||
button_panel_add_item(
|
||||
button_panel,
|
||||
i,
|
||||
1,
|
||||
0,
|
||||
36,
|
||||
19,
|
||||
&I_Mute_25x27,
|
||||
&I_Mute_hvr_25x27,
|
||||
infrared_scene_universal_common_item_callback,
|
||||
context);
|
||||
infrared_brute_force_add_record(brute_force, i++, "MUTE");
|
||||
button_panel_add_item(
|
||||
button_panel,
|
||||
i,
|
||||
0,
|
||||
1,
|
||||
3,
|
||||
66,
|
||||
&I_Vol_up_25x27,
|
||||
&I_Vol_up_hvr_25x27,
|
||||
infrared_scene_universal_common_item_callback,
|
||||
context);
|
||||
infrared_brute_force_add_record(brute_force, i++, "VOL+");
|
||||
button_panel_add_item(
|
||||
button_panel,
|
||||
i,
|
||||
1,
|
||||
1,
|
||||
36,
|
||||
66,
|
||||
&I_Up_25x27,
|
||||
&I_Up_hvr_25x27,
|
||||
infrared_scene_universal_common_item_callback,
|
||||
context);
|
||||
infrared_brute_force_add_record(brute_force, i++, "CH+");
|
||||
button_panel_add_item(
|
||||
button_panel,
|
||||
i,
|
||||
0,
|
||||
2,
|
||||
3,
|
||||
98,
|
||||
&I_Vol_down_25x27,
|
||||
&I_Vol_down_hvr_25x27,
|
||||
infrared_scene_universal_common_item_callback,
|
||||
context);
|
||||
infrared_brute_force_add_record(brute_force, i++, "VOL-");
|
||||
button_panel_add_item(
|
||||
button_panel,
|
||||
i,
|
||||
1,
|
||||
2,
|
||||
36,
|
||||
98,
|
||||
&I_Down_25x27,
|
||||
&I_Down_hvr_25x27,
|
||||
infrared_scene_universal_common_item_callback,
|
||||
context);
|
||||
infrared_brute_force_add_record(brute_force, i++, "CH-");
|
||||
|
||||
button_panel_add_label(button_panel, 6, 11, FontPrimary, "TV remote");
|
||||
button_panel_add_label(button_panel, 9, 64, FontSecondary, "Vol");
|
||||
button_panel_add_label(button_panel, 43, 64, FontSecondary, "Ch");
|
||||
|
||||
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);
|
||||
|
||||
infrared_show_loading_popup(infrared, true);
|
||||
bool success = infrared_brute_force_calculate_messages(brute_force);
|
||||
infrared_show_loading_popup(infrared, false);
|
||||
|
||||
if(!success) {
|
||||
scene_manager_next_scene(infrared->scene_manager, InfraredSceneErrorDatabases);
|
||||
}
|
||||
}
|
||||
|
||||
bool infrared_scene_universal_tv_on_event(void* context, SceneManagerEvent event) {
|
||||
return infrared_scene_universal_common_on_event(context, event);
|
||||
}
|
||||
|
||||
void infrared_scene_universal_tv_on_exit(void* context) {
|
||||
infrared_scene_universal_common_on_exit(context);
|
||||
}
|
Reference in New Issue
Block a user