mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2024-11-10 06:54:19 +00:00
Overly missed feature: Infrared: move button (change button order in a remote) (#2894)
* Feature: Infrared: move button (change button order in a remote) * little fix in furi_assert (case Move button to the end)
This commit is contained in:
parent
a677b2bcc2
commit
be86b0f38a
8 changed files with 215 additions and 4 deletions
|
@ -60,6 +60,8 @@ typedef enum {
|
|||
InfraredEditModeNone,
|
||||
InfraredEditModeRename,
|
||||
InfraredEditModeDelete,
|
||||
InfraredEditModeMove,
|
||||
InfraredEditModeMoveSelectDest
|
||||
} InfraredEditMode;
|
||||
|
||||
typedef struct {
|
||||
|
@ -69,6 +71,7 @@ typedef struct {
|
|||
InfraredEditTarget edit_target : 8;
|
||||
InfraredEditMode edit_mode : 8;
|
||||
int32_t current_button_index;
|
||||
int32_t current_button_index_move_orig;
|
||||
uint32_t last_transmit_time;
|
||||
} InfraredAppState;
|
||||
|
||||
|
|
|
@ -108,6 +108,21 @@ bool infrared_remote_delete_button(InfraredRemote* remote, size_t index) {
|
|||
return infrared_remote_store(remote);
|
||||
}
|
||||
|
||||
bool infrared_remote_move_button(InfraredRemote* remote, size_t index_orig, size_t index_dest) {
|
||||
furi_assert(index_orig < InfraredButtonArray_size(remote->buttons));
|
||||
furi_assert(index_dest <= InfraredButtonArray_size(remote->buttons));
|
||||
if(index_orig == index_dest) {
|
||||
return true;
|
||||
}
|
||||
InfraredRemoteButton* button;
|
||||
InfraredButtonArray_pop_at(&button, remote->buttons, index_orig);
|
||||
if(index_orig > index_dest)
|
||||
InfraredButtonArray_push_at(remote->buttons, index_dest, button);
|
||||
else
|
||||
InfraredButtonArray_push_at(remote->buttons, index_dest - 1, button);
|
||||
return infrared_remote_store(remote);
|
||||
}
|
||||
|
||||
bool infrared_remote_store(InfraredRemote* remote) {
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
FlipperFormat* ff = flipper_format_file_alloc(storage);
|
||||
|
|
|
@ -23,6 +23,7 @@ bool infrared_remote_find_button_by_name(InfraredRemote* remote, const char* nam
|
|||
bool infrared_remote_add_button(InfraredRemote* remote, const char* name, InfraredSignal* signal);
|
||||
bool infrared_remote_rename_button(InfraredRemote* remote, const char* new_name, size_t index);
|
||||
bool infrared_remote_delete_button(InfraredRemote* remote, size_t index);
|
||||
bool infrared_remote_move_button(InfraredRemote* remote, size_t index_orig, size_t index_dest);
|
||||
|
||||
bool infrared_remote_store(InfraredRemote* remote);
|
||||
bool infrared_remote_load(InfraredRemote* remote, FuriString* path);
|
||||
|
|
|
@ -7,6 +7,8 @@ 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, edit_move, EditMove)
|
||||
ADD_SCENE(infrared, edit_move_done, EditMoveDone)
|
||||
ADD_SCENE(infrared, learn, Learn)
|
||||
ADD_SCENE(infrared, learn_done, LearnDone)
|
||||
ADD_SCENE(infrared, learn_enter_name, LearnEnterName)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
typedef enum {
|
||||
SubmenuIndexAddButton,
|
||||
SubmenuIndexRenameButton,
|
||||
SubmenuIndexMoveButton,
|
||||
SubmenuIndexDeleteButton,
|
||||
SubmenuIndexRenameRemote,
|
||||
SubmenuIndexDeleteRemote,
|
||||
|
@ -30,6 +31,12 @@ void infrared_scene_edit_on_enter(void* context) {
|
|||
SubmenuIndexRenameButton,
|
||||
infrared_scene_edit_submenu_callback,
|
||||
context);
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Move Button",
|
||||
SubmenuIndexMoveButton,
|
||||
infrared_scene_edit_submenu_callback,
|
||||
context);
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Delete Button",
|
||||
|
@ -74,6 +81,11 @@ bool infrared_scene_edit_on_event(void* context, SceneManagerEvent event) {
|
|||
infrared->app_state.edit_mode = InfraredEditModeRename;
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneEditButtonSelect);
|
||||
consumed = true;
|
||||
} else if(submenu_index == SubmenuIndexMoveButton) {
|
||||
infrared->app_state.edit_target = InfraredEditTargetButton;
|
||||
infrared->app_state.edit_mode = InfraredEditModeMove;
|
||||
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;
|
||||
|
|
|
@ -11,9 +11,23 @@ void infrared_scene_edit_button_select_on_enter(void* context) {
|
|||
InfraredRemote* remote = infrared->remote;
|
||||
InfraredAppState* app_state = &infrared->app_state;
|
||||
|
||||
const char* header = infrared->app_state.edit_mode == InfraredEditModeRename ?
|
||||
"Rename Button:" :
|
||||
"Delete Button:";
|
||||
const char* header = NULL;
|
||||
switch(infrared->app_state.edit_mode) {
|
||||
case InfraredEditModeRename:
|
||||
header = "Rename Button:";
|
||||
break;
|
||||
case InfraredEditModeDelete:
|
||||
header = "Delete Button:";
|
||||
break;
|
||||
case InfraredEditModeMove:
|
||||
header = "Select Button to Move:";
|
||||
break;
|
||||
case InfraredEditModeMoveSelectDest:
|
||||
case InfraredEditModeNone:
|
||||
default:
|
||||
header = "Move Button Before:";
|
||||
break;
|
||||
}
|
||||
submenu_set_header(submenu, header);
|
||||
|
||||
const size_t button_count = infrared_remote_get_button_count(remote);
|
||||
|
@ -26,7 +40,14 @@ void infrared_scene_edit_button_select_on_enter(void* context) {
|
|||
infrared_scene_edit_button_select_submenu_callback,
|
||||
context);
|
||||
}
|
||||
|
||||
if(infrared->app_state.edit_mode == InfraredEditModeMoveSelectDest) {
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"-- Move to the end --",
|
||||
button_count,
|
||||
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;
|
||||
|
@ -48,6 +69,12 @@ bool infrared_scene_edit_button_select_on_event(void* context, SceneManagerEvent
|
|||
scene_manager_next_scene(scene_manager, InfraredSceneEditRename);
|
||||
} else if(edit_mode == InfraredEditModeDelete) {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneEditDelete);
|
||||
} else if(edit_mode == InfraredEditModeMove) {
|
||||
app_state->current_button_index_move_orig = event.event;
|
||||
app_state->edit_mode = InfraredEditModeMoveSelectDest;
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneEditButtonSelect);
|
||||
} else if(edit_mode == InfraredEditModeMoveSelectDest) {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneEditMove);
|
||||
} else {
|
||||
furi_assert(0);
|
||||
}
|
||||
|
|
103
applications/main/infrared/scenes/infrared_scene_edit_move.c
Normal file
103
applications/main/infrared/scenes/infrared_scene_edit_move.c
Normal file
|
@ -0,0 +1,103 @@
|
|||
#include "../infrared_i.h"
|
||||
|
||||
static void infrared_scene_edit_move_dialog_result_callback(DialogExResult result, void* context) {
|
||||
Infrared* infrared = context;
|
||||
view_dispatcher_send_custom_event(infrared->view_dispatcher, result);
|
||||
}
|
||||
|
||||
void infrared_scene_edit_move_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_move_orig;
|
||||
furi_assert(current_button_index != InfraredButtonIndexNone);
|
||||
|
||||
dialog_ex_set_header(dialog_ex, "Move 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 {
|
||||
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, "Move");
|
||||
dialog_ex_set_result_callback(dialog_ex, infrared_scene_edit_move_dialog_result_callback);
|
||||
dialog_ex_set_context(dialog_ex, context);
|
||||
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewDialogEx);
|
||||
}
|
||||
|
||||
bool infrared_scene_edit_move_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_move_button(
|
||||
remote,
|
||||
app_state->current_button_index_move_orig,
|
||||
app_state->current_button_index);
|
||||
app_state->current_button_index_move_orig = InfraredButtonIndexNone;
|
||||
app_state->current_button_index = InfraredButtonIndexNone;
|
||||
} else {
|
||||
furi_assert(0);
|
||||
}
|
||||
|
||||
if(success) {
|
||||
scene_manager_next_scene(scene_manager, InfraredSceneEditMoveDone);
|
||||
} 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_move_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
UNUSED(infrared);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
#include "../infrared_i.h"
|
||||
|
||||
void infrared_scene_edit_move_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, "Moved", 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_move_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_move_done_on_exit(void* context) {
|
||||
Infrared* infrared = context;
|
||||
UNUSED(infrared);
|
||||
}
|
Loading…
Reference in a new issue