[FL-2279] IR doxygen, rename irda -> infrared (#1010)

* IR: Doxygen docs, some rename
* Rename irda -> infrared
* Rollback collateral renames

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Albert Kharisov
2022-02-25 19:22:58 +04:00
committed by GitHub
parent c42cce3c6c
commit 052237f8c9
159 changed files with 6387 additions and 5622 deletions

View File

@@ -0,0 +1,305 @@
/**
* @file infrared_app_scene.h
* Infrared: Application scenes
*/
#pragma once
#include "../infrared_app_event.h"
#include <furi_hal_infrared.h>
#include "infrared.h"
#include <vector>
#include <string>
#include "../infrared_app_brute_force.h"
/** Anonymous class */
class InfraredApp;
/** Base Scene class */
class InfraredAppScene {
public:
/** Called when enter scene */
virtual void on_enter(InfraredApp* app) = 0;
/** Events handler callback */
virtual bool on_event(InfraredApp* app, InfraredAppEvent* event) = 0;
/** Called when exit scene */
virtual void on_exit(InfraredApp* app) = 0;
/** Virtual destructor of base class */
virtual ~InfraredAppScene(){};
private:
};
/** Start scene
* Main Infrared application menu
*/
class InfraredAppSceneStart : public InfraredAppScene {
public:
/** Called when enter scene */
void on_enter(InfraredApp* app) final;
/** Events handler callback */
bool on_event(InfraredApp* app, InfraredAppEvent* event) final;
/** Called when exit scene */
void on_exit(InfraredApp* app) final;
private:
/** Save previously selected submenu index
* to highlight it when get back */
uint32_t submenu_item_selected = 0;
};
/** Universal menu scene
* Scene to select universal remote
*/
class InfraredAppSceneUniversal : public InfraredAppScene {
public:
/** Called when enter scene */
void on_enter(InfraredApp* app) final;
/** Events handler callback */
bool on_event(InfraredApp* app, InfraredAppEvent* event) final;
/** Called when exit scene */
void on_exit(InfraredApp* app) final;
private:
/** Save previously selected submenu index
* to highlight it when get back */
uint32_t submenu_item_selected = 0;
};
/** Learn new signal scene
* On this scene catching new IR signal performed.
*/
class InfraredAppSceneLearn : public InfraredAppScene {
public:
/** Called when enter scene */
void on_enter(InfraredApp* app) final;
/** Events handler callback */
bool on_event(InfraredApp* app, InfraredAppEvent* event) final;
/** Called when exit scene */
void on_exit(InfraredApp* app) final;
};
/** New signal learn succeeded scene
*/
class InfraredAppSceneLearnSuccess : public InfraredAppScene {
public:
/** Called when enter scene */
void on_enter(InfraredApp* app) final;
/** Events handler callback */
bool on_event(InfraredApp* app, InfraredAppEvent* event) final;
/** Called when exit scene */
void on_exit(InfraredApp* app) final;
bool button_pressed = false;
};
/** Scene to enter name for new button in remote
*/
class InfraredAppSceneLearnEnterName : public InfraredAppScene {
public:
/** Called when enter scene */
void on_enter(InfraredApp* app) final;
/** Events handler callback */
bool on_event(InfraredApp* app, InfraredAppEvent* event) final;
/** Called when exit scene */
void on_exit(InfraredApp* app) final;
};
/** Scene where signal is learnt
*/
class InfraredAppSceneLearnDone : public InfraredAppScene {
public:
/** Called when enter scene */
void on_enter(InfraredApp* app) final;
/** Events handler callback */
bool on_event(InfraredApp* app, InfraredAppEvent* event) final;
/** Called when exit scene */
void on_exit(InfraredApp* app) final;
};
/** Remote interface scene
* On this scene you can send IR signals from selected remote
*/
class InfraredAppSceneRemote : public InfraredAppScene {
public:
/** Called when enter scene */
void on_enter(InfraredApp* app) final;
/** Events handler callback */
bool on_event(InfraredApp* app, InfraredAppEvent* event) final;
/** Called when exit scene */
void on_exit(InfraredApp* app) final;
private:
/** container of button names in current remote. */
std::vector<std::string> buttons_names;
/** Save previously selected index
* to highlight it when get back */
uint32_t buttonmenu_item_selected = 0;
/** state flag to show button is pressed.
* As long as send-signal button pressed no other button
* events are handled. */
bool button_pressed = false;
};
/** List of remotes scene
* Every remote is a file, located on internal/external storage.
* Every file has same format, and same extension.
* Files are parsed as you enter 'Remote scene' and showed
* as a buttons.
*/
class InfraredAppSceneRemoteList : public InfraredAppScene {
public:
/** Called when enter scene */
void on_enter(InfraredApp* app) final;
/** Events handler callback */
bool on_event(InfraredApp* app, InfraredAppEvent* event) final;
/** Called when exit scene */
void on_exit(InfraredApp* app) final;
private:
/** Save previously selected index
* to highlight it when get back */
uint32_t submenu_item_selected = 0;
/** Remote names to show them in submenu */
std::vector<std::string> remote_names;
};
class InfraredAppSceneAskBack : public InfraredAppScene {
public:
/** Called when enter scene */
void on_enter(InfraredApp* app) final;
/** Events handler callback */
bool on_event(InfraredApp* app, InfraredAppEvent* event) final;
/** Called when exit scene */
void on_exit(InfraredApp* app) final;
};
class InfraredAppSceneEdit : public InfraredAppScene {
public:
/** Called when enter scene */
void on_enter(InfraredApp* app) final;
/** Events handler callback */
bool on_event(InfraredApp* app, InfraredAppEvent* event) final;
/** Called when exit scene */
void on_exit(InfraredApp* app) final;
private:
/** Save previously selected index
* to highlight it when get back */
uint32_t submenu_item_selected = 0;
};
class InfraredAppSceneEditKeySelect : public InfraredAppScene {
public:
/** Called when enter scene */
void on_enter(InfraredApp* app) final;
/** Events handler callback */
bool on_event(InfraredApp* app, InfraredAppEvent* event) final;
/** Called when exit scene */
void on_exit(InfraredApp* app) final;
private:
/** Button names to show them in submenu */
std::vector<std::string> buttons_names;
};
class InfraredAppSceneEditRename : public InfraredAppScene {
public:
/** Called when enter scene */
void on_enter(InfraredApp* app) final;
/** Events handler callback */
bool on_event(InfraredApp* app, InfraredAppEvent* event) final;
/** Called when exit scene */
void on_exit(InfraredApp* app) final;
};
class InfraredAppSceneEditDelete : public InfraredAppScene {
public:
/** Called when enter scene */
void on_enter(InfraredApp* app) final;
/** Events handler callback */
bool on_event(InfraredApp* app, InfraredAppEvent* event) final;
/** Called when exit scene */
void on_exit(InfraredApp* app) final;
};
class InfraredAppSceneEditRenameDone : public InfraredAppScene {
public:
/** Called when enter scene */
void on_enter(InfraredApp* app) final;
/** Events handler callback */
bool on_event(InfraredApp* app, InfraredAppEvent* event) final;
/** Called when exit scene */
void on_exit(InfraredApp* app) final;
};
class InfraredAppSceneEditDeleteDone : public InfraredAppScene {
public:
/** Called when enter scene */
void on_enter(InfraredApp* app) final;
/** Events handler callback */
bool on_event(InfraredApp* app, InfraredAppEvent* event) final;
/** Called when exit scene */
void on_exit(InfraredApp* app) final;
};
class InfraredAppSceneUniversalCommon : public InfraredAppScene {
/** Brute force started flag */
bool brute_force_started = false;
protected:
/** Events handler callback */
bool on_event(InfraredApp* app, InfraredAppEvent* event) final;
/** Called when exit scene */
void on_exit(InfraredApp* app) final;
/** Show popup window
*
* @param app - application instance
*/
void show_popup(InfraredApp* app, int record_amount);
/** Hide popup window
*
* @param app - application instance
*/
void hide_popup(InfraredApp* app);
/** Propagate progress in popup window
*
* @param app - application instance
*/
bool progress_popup(InfraredApp* app);
/** Item selected callback
*
* @param context - context
* @param index - selected item index
*/
static void infrared_app_item_callback(void* context, uint32_t index);
/** Brute Force instance */
InfraredAppBruteForce brute_force;
/** Constructor */
InfraredAppSceneUniversalCommon(const char* filename)
: brute_force(filename) {
}
/** Destructor */
~InfraredAppSceneUniversalCommon() {
}
};
class InfraredAppSceneUniversalTV : public InfraredAppSceneUniversalCommon {
public:
/** Called when enter scene */
void on_enter(InfraredApp* app) final;
/** Constructor
* Specifies path to brute force db library */
InfraredAppSceneUniversalTV()
: InfraredAppSceneUniversalCommon("/ext/infrared/assets/tv.ir") {
}
/** Destructor */
~InfraredAppSceneUniversalTV() {
}
};

View File

@@ -0,0 +1,73 @@
#include "../infrared_app.h"
#include "gui/modules/dialog_ex.h"
#include "infrared.h"
#include "infrared/scene/infrared_app_scene.h"
#include <string>
static void dialog_result_callback(DialogExResult result, void* context) {
auto app = static_cast<InfraredApp*>(context);
InfraredAppEvent event;
event.type = InfraredAppEvent::Type::DialogExSelected;
event.payload.dialog_ex_result = result;
app->get_view_manager()->send_event(&event);
}
void InfraredAppSceneAskBack::on_enter(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
DialogEx* dialog_ex = view_manager->get_dialog_ex();
if(app->get_learn_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, nullptr);
dialog_ex_set_right_button_text(dialog_ex, "Stay");
dialog_ex_set_result_callback(dialog_ex, dialog_result_callback);
dialog_ex_set_context(dialog_ex, app);
view_manager->switch_to(InfraredAppViewManager::ViewId::DialogEx);
}
bool InfraredAppSceneAskBack::on_event(InfraredApp* app, InfraredAppEvent* event) {
bool consumed = false;
if(event->type == InfraredAppEvent::Type::DialogExSelected) {
switch(event->payload.dialog_ex_result) {
case DialogExResultLeft:
consumed = true;
if(app->get_learn_new_remote()) {
app->search_and_switch_to_previous_scene({InfraredApp::Scene::Start});
} else {
app->search_and_switch_to_previous_scene(
{InfraredApp::Scene::Edit, InfraredApp::Scene::Remote});
}
break;
case DialogExResultCenter:
furi_assert(0);
break;
case DialogExResultRight:
app->switch_to_previous_scene();
consumed = true;
break;
default:
break;
}
}
if(event->type == InfraredAppEvent::Type::Back) {
consumed = true;
}
return consumed;
}
void InfraredAppSceneAskBack::on_exit(InfraredApp* app) {
}

View File

@@ -0,0 +1,79 @@
#include "../infrared_app.h"
#include "gui/modules/submenu.h"
typedef enum {
SubmenuIndexAddKey,
SubmenuIndexRenameKey,
SubmenuIndexDeleteKey,
SubmenuIndexRenameRemote,
SubmenuIndexDeleteRemote,
} SubmenuIndex;
static void submenu_callback(void* context, uint32_t index) {
InfraredApp* app = static_cast<InfraredApp*>(context);
InfraredAppEvent event;
event.type = InfraredAppEvent::Type::MenuSelected;
event.payload.menu_index = index;
app->get_view_manager()->send_event(&event);
}
void InfraredAppSceneEdit::on_enter(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
Submenu* submenu = view_manager->get_submenu();
submenu_add_item(submenu, "Add key", SubmenuIndexAddKey, submenu_callback, app);
submenu_add_item(submenu, "Rename key", SubmenuIndexRenameKey, submenu_callback, app);
submenu_add_item(submenu, "Delete key", SubmenuIndexDeleteKey, submenu_callback, app);
submenu_add_item(submenu, "Rename remote", SubmenuIndexRenameRemote, submenu_callback, app);
submenu_add_item(submenu, "Delete remote", SubmenuIndexDeleteRemote, submenu_callback, app);
submenu_set_selected_item(submenu, submenu_item_selected);
submenu_item_selected = 0;
view_manager->switch_to(InfraredAppViewManager::ViewId::Submenu);
}
bool InfraredAppSceneEdit::on_event(InfraredApp* app, InfraredAppEvent* event) {
bool consumed = false;
if(event->type == InfraredAppEvent::Type::MenuSelected) {
submenu_item_selected = event->payload.menu_index;
switch(event->payload.menu_index) {
case SubmenuIndexAddKey:
app->set_learn_new_remote(false);
app->switch_to_next_scene(InfraredApp::Scene::Learn);
break;
case SubmenuIndexRenameKey:
app->set_edit_action(InfraredApp::EditAction::Rename);
app->set_edit_element(InfraredApp::EditElement::Button);
app->switch_to_next_scene(InfraredApp::Scene::EditKeySelect);
break;
case SubmenuIndexDeleteKey:
app->set_edit_action(InfraredApp::EditAction::Delete);
app->set_edit_element(InfraredApp::EditElement::Button);
app->switch_to_next_scene(InfraredApp::Scene::EditKeySelect);
break;
case SubmenuIndexRenameRemote:
app->set_edit_action(InfraredApp::EditAction::Rename);
app->set_edit_element(InfraredApp::EditElement::Remote);
app->switch_to_next_scene(InfraredApp::Scene::EditRename);
break;
case SubmenuIndexDeleteRemote:
app->set_edit_action(InfraredApp::EditAction::Delete);
app->set_edit_element(InfraredApp::EditElement::Remote);
app->switch_to_next_scene(InfraredApp::Scene::EditDelete);
break;
}
consumed = true;
}
return consumed;
}
void InfraredAppSceneEdit::on_exit(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
Submenu* submenu = view_manager->get_submenu();
submenu_reset(submenu);
}

View File

@@ -0,0 +1,100 @@
#include "../infrared_app.h"
#include "infrared.h"
#include "infrared/scene/infrared_app_scene.h"
#include <string>
static void dialog_result_callback(DialogExResult result, void* context) {
auto app = static_cast<InfraredApp*>(context);
InfraredAppEvent event;
event.type = InfraredAppEvent::Type::DialogExSelected;
event.payload.dialog_ex_result = result;
app->get_view_manager()->send_event(&event);
}
void InfraredAppSceneEditDelete::on_enter(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
DialogEx* dialog_ex = view_manager->get_dialog_ex();
auto remote_manager = app->get_remote_manager();
if(app->get_edit_element() == InfraredApp::EditElement::Button) {
auto signal = remote_manager->get_button_data(app->get_current_button());
dialog_ex_set_header(dialog_ex, "Delete button?", 64, 0, AlignCenter, AlignTop);
if(!signal.is_raw()) {
auto message = &signal.get_message();
app->set_text_store(
0,
"%s\n%s\nA=0x%0*lX C=0x%0*lX",
remote_manager->get_button_name(app->get_current_button()).c_str(),
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 {
app->set_text_store(
0,
"%s\nRAW\n%ld samples",
remote_manager->get_button_name(app->get_current_button()).c_str(),
signal.get_raw_signal().timings_cnt);
}
} else {
dialog_ex_set_header(dialog_ex, "Delete remote?", 64, 0, AlignCenter, AlignTop);
app->set_text_store(
0,
"%s\n with %lu buttons",
remote_manager->get_remote_name().c_str(),
remote_manager->get_number_of_buttons());
}
dialog_ex_set_text(dialog_ex, app->get_text_store(0), 64, 31, AlignCenter, AlignCenter);
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
dialog_ex_set_left_button_text(dialog_ex, "Back");
dialog_ex_set_right_button_text(dialog_ex, "Delete");
dialog_ex_set_result_callback(dialog_ex, dialog_result_callback);
dialog_ex_set_context(dialog_ex, app);
view_manager->switch_to(InfraredAppViewManager::ViewId::DialogEx);
}
bool InfraredAppSceneEditDelete::on_event(InfraredApp* app, InfraredAppEvent* event) {
bool consumed = false;
if(event->type == InfraredAppEvent::Type::DialogExSelected) {
switch(event->payload.dialog_ex_result) {
case DialogExResultLeft:
app->switch_to_previous_scene();
break;
case DialogExResultCenter:
furi_assert(0);
break;
case DialogExResultRight: {
auto remote_manager = app->get_remote_manager();
bool result = false;
if(app->get_edit_element() == InfraredApp::EditElement::Remote) {
result = remote_manager->delete_remote();
} else {
result = remote_manager->delete_button(app->get_current_button());
app->set_current_button(InfraredApp::ButtonNA);
}
if(!result) {
app->search_and_switch_to_previous_scene(
{InfraredApp::Scene::RemoteList, InfraredApp::Scene::Start});
} else {
app->switch_to_next_scene(InfraredApp::Scene::EditDeleteDone);
}
break;
}
default:
break;
}
}
return consumed;
}
void InfraredAppSceneEditDelete::on_exit(InfraredApp* app) {
}

View File

@@ -0,0 +1,38 @@
#include "../infrared_app.h"
void InfraredAppSceneEditDeleteDone::on_enter(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
Popup* popup = view_manager->get_popup();
popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62);
popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom);
popup_set_callback(popup, InfraredApp::popup_callback);
popup_set_context(popup, app);
popup_set_timeout(popup, 1500);
popup_enable_timeout(popup);
view_manager->switch_to(InfraredAppViewManager::ViewId::Popup);
}
bool InfraredAppSceneEditDeleteDone::on_event(InfraredApp* app, InfraredAppEvent* event) {
bool consumed = false;
if(event->type == InfraredAppEvent::Type::PopupTimer) {
if(app->get_edit_element() == InfraredApp::EditElement::Remote) {
app->search_and_switch_to_previous_scene(
{InfraredApp::Scene::Start, InfraredApp::Scene::RemoteList});
} else {
app->search_and_switch_to_previous_scene({InfraredApp::Scene::Remote});
}
consumed = true;
}
return consumed;
}
void InfraredAppSceneEditDeleteDone::on_exit(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
Popup* popup = view_manager->get_popup();
popup_set_header(popup, nullptr, 0, 0, AlignLeft, AlignTop);
}

View File

@@ -0,0 +1,57 @@
#include "../infrared_app.h"
#include "gui/modules/submenu.h"
static void submenu_callback(void* context, uint32_t index) {
InfraredApp* app = static_cast<InfraredApp*>(context);
InfraredAppEvent event;
event.type = InfraredAppEvent::Type::MenuSelected;
event.payload.menu_index = index;
app->get_view_manager()->send_event(&event);
}
void InfraredAppSceneEditKeySelect::on_enter(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
Submenu* submenu = view_manager->get_submenu();
int item_number = 0;
const char* header =
app->get_edit_action() == InfraredApp::EditAction::Rename ? "Rename key:" : "Delete key:";
submenu_set_header(submenu, header);
auto remote_manager = app->get_remote_manager();
buttons_names = remote_manager->get_button_list();
for(const auto& it : buttons_names) {
submenu_add_item(submenu, it.c_str(), item_number++, submenu_callback, app);
}
if((item_number > 0) && (app->get_current_button() != InfraredApp::ButtonNA)) {
submenu_set_selected_item(submenu, app->get_current_button());
app->set_current_button(InfraredApp::ButtonNA);
}
view_manager->switch_to(InfraredAppViewManager::ViewId::Submenu);
}
bool InfraredAppSceneEditKeySelect::on_event(InfraredApp* app, InfraredAppEvent* event) {
bool consumed = false;
if(event->type == InfraredAppEvent::Type::MenuSelected) {
app->set_current_button(event->payload.menu_index);
consumed = true;
if(app->get_edit_action() == InfraredApp::EditAction::Rename) {
app->switch_to_next_scene(InfraredApp::Scene::EditRename);
} else {
app->switch_to_next_scene(InfraredApp::Scene::EditDelete);
}
}
return consumed;
}
void InfraredAppSceneEditKeySelect::on_exit(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
Submenu* submenu = view_manager->get_submenu();
submenu_reset(submenu);
}

View File

@@ -0,0 +1,72 @@
#include "../infrared_app.h"
void InfraredAppSceneEditRename::on_enter(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
TextInput* text_input = view_manager->get_text_input();
size_t enter_name_length = 0;
auto remote_manager = app->get_remote_manager();
if(app->get_edit_element() == InfraredApp::EditElement::Button) {
furi_assert(app->get_current_button() != InfraredApp::ButtonNA);
auto button_name = remote_manager->get_button_name(app->get_current_button());
char* buffer_str = app->get_text_store(0);
size_t max_len = InfraredAppRemoteManager::max_button_name_length;
strncpy(buffer_str, button_name.c_str(), max_len);
buffer_str[max_len + 1] = 0;
enter_name_length = max_len;
text_input_set_header_text(text_input, "Name the key");
} else {
auto remote_name = remote_manager->get_remote_name();
strncpy(app->get_text_store(0), remote_name.c_str(), app->get_text_store_size());
enter_name_length = InfraredAppRemoteManager::max_remote_name_length;
text_input_set_header_text(text_input, "Name the remote");
ValidatorIsFile* validator_is_file =
validator_is_file_alloc_init(app->infrared_directory, app->infrared_extension);
text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
}
text_input_set_result_callback(
text_input,
InfraredApp::text_input_callback,
app,
app->get_text_store(0),
enter_name_length,
false);
view_manager->switch_to(InfraredAppViewManager::ViewId::TextInput);
}
bool InfraredAppSceneEditRename::on_event(InfraredApp* app, InfraredAppEvent* event) {
bool consumed = false;
if(event->type == InfraredAppEvent::Type::TextEditDone) {
auto remote_manager = app->get_remote_manager();
bool result = false;
if(app->get_edit_element() == InfraredApp::EditElement::Button) {
result =
remote_manager->rename_button(app->get_current_button(), app->get_text_store(0));
app->set_current_button(InfraredApp::ButtonNA);
} else {
result = remote_manager->rename_remote(app->get_text_store(0));
}
if(!result) {
app->search_and_switch_to_previous_scene(
{InfraredApp::Scene::Start, InfraredApp::Scene::RemoteList});
} else {
app->switch_to_next_scene_without_saving(InfraredApp::Scene::EditRenameDone);
}
consumed = true;
}
return consumed;
}
void InfraredAppSceneEditRename::on_exit(InfraredApp* app) {
TextInput* text_input = app->get_view_manager()->get_text_input();
void* validator_context = text_input_get_validator_callback_context(text_input);
text_input_set_validator(text_input, NULL, NULL);
if(validator_context != NULL) validator_is_file_free((ValidatorIsFile*)validator_context);
}

View File

@@ -0,0 +1,31 @@
#include "../infrared_app.h"
void InfraredAppSceneEditRenameDone::on_enter(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
Popup* popup = view_manager->get_popup();
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop);
popup_set_callback(popup, InfraredApp::popup_callback);
popup_set_context(popup, app);
popup_set_timeout(popup, 1500);
popup_enable_timeout(popup);
view_manager->switch_to(InfraredAppViewManager::ViewId::Popup);
}
bool InfraredAppSceneEditRenameDone::on_event(InfraredApp* app, InfraredAppEvent* event) {
bool consumed = false;
if(event->type == InfraredAppEvent::Type::PopupTimer) {
app->switch_to_next_scene(InfraredApp::Scene::Remote);
consumed = true;
}
return consumed;
}
void InfraredAppSceneEditRenameDone::on_exit(InfraredApp* app) {
}

View File

@@ -0,0 +1,75 @@
#include "../infrared_app.h"
#include "../infrared_app_event.h"
#include "infrared.h"
#include <infrared_worker.h>
static void signal_received_callback(void* context, InfraredWorkerSignal* received_signal) {
furi_assert(context);
furi_assert(received_signal);
InfraredApp* app = static_cast<InfraredApp*>(context);
if(infrared_worker_signal_is_decoded(received_signal)) {
InfraredAppSignal signal(infrared_worker_get_decoded_signal(received_signal));
app->set_received_signal(signal);
} else {
const uint32_t* timings;
size_t timings_cnt;
infrared_worker_get_raw_signal(received_signal, &timings, &timings_cnt);
InfraredAppSignal signal(
timings, timings_cnt, INFRARED_COMMON_CARRIER_FREQUENCY, INFRARED_COMMON_DUTY_CYCLE);
app->set_received_signal(signal);
}
infrared_worker_rx_set_received_signal_callback(app->get_infrared_worker(), NULL, NULL);
InfraredAppEvent event;
event.type = InfraredAppEvent::Type::InfraredMessageReceived;
auto view_manager = app->get_view_manager();
view_manager->send_event(&event);
}
void InfraredAppSceneLearn::on_enter(InfraredApp* app) {
auto view_manager = app->get_view_manager();
auto popup = view_manager->get_popup();
auto worker = app->get_infrared_worker();
infrared_worker_rx_set_received_signal_callback(worker, signal_received_callback, app);
infrared_worker_rx_start(worker);
popup_set_icon(popup, 0, 32, &I_InfraredLearnShort_128x31);
popup_set_text(
popup, "Point the remote at IR port\nand push the button", 5, 10, AlignLeft, AlignCenter);
popup_set_callback(popup, NULL);
view_manager->switch_to(InfraredAppViewManager::ViewId::Popup);
}
bool InfraredAppSceneLearn::on_event(InfraredApp* app, InfraredAppEvent* event) {
bool consumed = false;
switch(event->type) {
case InfraredAppEvent::Type::Tick:
consumed = true;
app->notify_red_blink();
break;
case InfraredAppEvent::Type::InfraredMessageReceived:
app->notify_success();
app->switch_to_next_scene_without_saving(InfraredApp::Scene::LearnSuccess);
break;
case InfraredAppEvent::Type::Back:
consumed = true;
app->switch_to_previous_scene();
break;
default:
furi_assert(0);
}
return consumed;
}
void InfraredAppSceneLearn::on_exit(InfraredApp* app) {
infrared_worker_rx_stop(app->get_infrared_worker());
auto view_manager = app->get_view_manager();
auto popup = view_manager->get_popup();
popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignCenter);
}

View File

@@ -0,0 +1,41 @@
#include "../infrared_app.h"
#include <dolphin/dolphin.h>
void InfraredAppSceneLearnDone::on_enter(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
Popup* popup = view_manager->get_popup();
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
DOLPHIN_DEED(DolphinDeedIrSave);
if(app->get_learn_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, InfraredApp::popup_callback);
popup_set_context(popup, app);
popup_set_timeout(popup, 1500);
popup_enable_timeout(popup);
view_manager->switch_to(InfraredAppViewManager::ViewId::Popup);
}
bool InfraredAppSceneLearnDone::on_event(InfraredApp* app, InfraredAppEvent* event) {
bool consumed = false;
if(event->type == InfraredAppEvent::Type::PopupTimer) {
app->switch_to_next_scene(InfraredApp::Scene::Remote);
consumed = true;
}
return consumed;
}
void InfraredAppSceneLearnDone::on_exit(InfraredApp* app) {
app->set_learn_new_remote(false);
InfraredAppViewManager* view_manager = app->get_view_manager();
Popup* popup = view_manager->get_popup();
popup_set_header(popup, nullptr, 0, 0, AlignLeft, AlignTop);
}

View File

@@ -0,0 +1,60 @@
#include "../infrared_app.h"
#include "gui/modules/text_input.h"
void InfraredAppSceneLearnEnterName::on_enter(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
TextInput* text_input = view_manager->get_text_input();
auto signal = app->get_received_signal();
if(!signal.is_raw()) {
auto message = &signal.get_message();
app->set_text_store(
0,
"%.4s_%0*lX",
infrared_get_protocol_name(message->protocol),
ROUND_UP_TO(infrared_get_protocol_command_length(message->protocol), 4),
message->command);
} else {
auto raw_signal = signal.get_raw_signal();
app->set_text_store(0, "RAW_%d", raw_signal.timings_cnt);
}
text_input_set_header_text(text_input, "Name the key");
text_input_set_result_callback(
text_input,
InfraredApp::text_input_callback,
app,
app->get_text_store(0),
InfraredAppRemoteManager::max_button_name_length,
true);
view_manager->switch_to(InfraredAppViewManager::ViewId::TextInput);
}
bool InfraredAppSceneLearnEnterName::on_event(InfraredApp* app, InfraredAppEvent* event) {
bool consumed = false;
if(event->type == InfraredAppEvent::Type::TextEditDone) {
auto remote_manager = app->get_remote_manager();
bool result = false;
if(app->get_learn_new_remote()) {
result = remote_manager->add_remote_with_button(
app->get_text_store(0), app->get_received_signal());
} else {
result =
remote_manager->add_button(app->get_text_store(0), app->get_received_signal());
}
if(!result) {
app->search_and_switch_to_previous_scene(
{InfraredApp::Scene::Start, InfraredApp::Scene::RemoteList});
} else {
app->switch_to_next_scene_without_saving(InfraredApp::Scene::LearnDone);
}
}
return consumed;
}
void InfraredAppSceneLearnEnterName::on_exit(InfraredApp* app) {
}

View File

@@ -0,0 +1,149 @@
#include <gui/modules/dialog_ex.h>
#include <file_worker_cpp.h>
#include <memory>
#include <dolphin/dolphin.h>
#include "../infrared_app.h"
#include "infrared.h"
static void dialog_result_callback(DialogExResult result, void* context) {
auto app = static_cast<InfraredApp*>(context);
InfraredAppEvent event;
event.type = InfraredAppEvent::Type::DialogExSelected;
event.payload.dialog_ex_result = result;
app->get_view_manager()->send_event(&event);
}
void InfraredAppSceneLearnSuccess::on_enter(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
DialogEx* dialog_ex = view_manager->get_dialog_ex();
DOLPHIN_DEED(DolphinDeedIrLearnSuccess);
app->notify_green_on();
infrared_worker_tx_set_get_signal_callback(
app->get_infrared_worker(), infrared_worker_tx_get_signal_steady_callback, app);
infrared_worker_tx_set_signal_sent_callback(
app->get_infrared_worker(), InfraredApp::signal_sent_callback, app);
auto signal = app->get_received_signal();
if(!signal.is_raw()) {
auto message = &signal.get_message();
uint8_t adr_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(adr_digits, cmd_digits);
max_digits = MIN(max_digits, 7);
size_t label_x_offset = 63 + (7 - max_digits) * 3;
app->set_text_store(0, "%s", infrared_get_protocol_name(message->protocol));
app->set_text_store(
1,
"A: 0x%0*lX\nC: 0x%0*lX\n",
adr_digits,
message->address,
cmd_digits,
message->command);
dialog_ex_set_header(dialog_ex, app->get_text_store(0), 95, 7, AlignCenter, AlignCenter);
dialog_ex_set_text(
dialog_ex, app->get_text_store(1), label_x_offset, 34, AlignLeft, AlignCenter);
} else {
dialog_ex_set_header(dialog_ex, "Unknown", 95, 10, AlignCenter, AlignCenter);
app->set_text_store(0, "%d samples", signal.get_raw_signal().timings_cnt);
dialog_ex_set_text(dialog_ex, app->get_text_store(0), 75, 23, AlignLeft, AlignTop);
}
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, dialog_result_callback);
dialog_ex_set_context(dialog_ex, app);
dialog_ex_enable_extended_events(dialog_ex);
view_manager->switch_to(InfraredAppViewManager::ViewId::DialogEx);
}
bool InfraredAppSceneLearnSuccess::on_event(InfraredApp* app, InfraredAppEvent* event) {
bool consumed = false;
if(event->type == InfraredAppEvent::Type::Tick) {
/* Send event every tick to suppress any switching off green light */
if(!button_pressed) {
app->notify_green_on();
}
}
if(event->type == InfraredAppEvent::Type::DialogExSelected) {
switch(event->payload.dialog_ex_result) {
case DialogExResultLeft:
consumed = true;
if(!button_pressed) {
app->switch_to_next_scene_without_saving(InfraredApp::Scene::Learn);
}
break;
case DialogExResultRight: {
consumed = true;
FileWorkerCpp file_worker;
if(!button_pressed) {
if(file_worker.check_errors()) {
app->switch_to_next_scene(InfraredApp::Scene::LearnEnterName);
} else {
app->switch_to_previous_scene();
}
}
break;
}
case DialogExPressCenter:
if(!button_pressed) {
button_pressed = true;
app->notify_click_and_green_blink();
auto signal = app->get_received_signal();
if(signal.is_raw()) {
infrared_worker_set_raw_signal(
app->get_infrared_worker(),
signal.get_raw_signal().timings,
signal.get_raw_signal().timings_cnt);
} else {
infrared_worker_set_decoded_signal(
app->get_infrared_worker(), &signal.get_message());
}
infrared_worker_tx_start(app->get_infrared_worker());
}
break;
case DialogExReleaseCenter:
if(button_pressed) {
button_pressed = false;
infrared_worker_tx_stop(app->get_infrared_worker());
app->notify_green_off();
}
break;
default:
break;
}
}
if(event->type == InfraredAppEvent::Type::Back) {
if(!button_pressed) {
app->switch_to_next_scene(InfraredApp::Scene::AskBack);
}
consumed = true;
}
return consumed;
}
void InfraredAppSceneLearnSuccess::on_exit(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
DialogEx* dialog_ex = view_manager->get_dialog_ex();
dialog_ex_reset(dialog_ex);
app->notify_green_off();
infrared_worker_tx_set_get_signal_callback(app->get_infrared_worker(), nullptr, nullptr);
infrared_worker_tx_set_signal_sent_callback(app->get_infrared_worker(), nullptr, nullptr);
}

View File

@@ -0,0 +1,134 @@
#include <gui/modules/button_menu.h>
#include <input/input.h>
#include <infrared_worker.h>
#include <dolphin/dolphin.h>
#include "../infrared_app.h"
#include "../infrared_app_view_manager.h"
typedef enum {
ButtonIndexPlus = -2,
ButtonIndexEdit = -1,
ButtonIndexNA = 0,
} ButtonIndex;
static void button_menu_callback(void* context, int32_t index, InputType type) {
InfraredApp* app = static_cast<InfraredApp*>(context);
InfraredAppEvent event;
if(type == InputTypePress) {
event.type = InfraredAppEvent::Type::MenuSelectedPress;
} else if(type == InputTypeRelease) {
event.type = InfraredAppEvent::Type::MenuSelectedRelease;
} else if(type == InputTypeShort) {
event.type = InfraredAppEvent::Type::MenuSelected;
} else {
furi_assert(0);
}
event.payload.menu_index = index;
app->get_view_manager()->send_event(&event);
}
void InfraredAppSceneRemote::on_enter(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
ButtonMenu* button_menu = view_manager->get_button_menu();
auto remote_manager = app->get_remote_manager();
int i = 0;
button_pressed = false;
infrared_worker_tx_set_get_signal_callback(
app->get_infrared_worker(), infrared_worker_tx_get_signal_steady_callback, app);
infrared_worker_tx_set_signal_sent_callback(
app->get_infrared_worker(), InfraredApp::signal_sent_callback, app);
buttons_names = remote_manager->get_button_list();
i = 0;
for(auto& name : buttons_names) {
button_menu_add_item(
button_menu, name.c_str(), i++, button_menu_callback, ButtonMenuItemTypeCommon, app);
}
button_menu_add_item(
button_menu, "+", ButtonIndexPlus, button_menu_callback, ButtonMenuItemTypeControl, app);
button_menu_add_item(
button_menu, "Edit", ButtonIndexEdit, button_menu_callback, ButtonMenuItemTypeControl, app);
app->set_text_store(0, "%s", remote_manager->get_remote_name().c_str());
button_menu_set_header(button_menu, app->get_text_store(0));
if(buttonmenu_item_selected != ButtonIndexNA) {
button_menu_set_selected_item(button_menu, buttonmenu_item_selected);
buttonmenu_item_selected = ButtonIndexNA;
}
view_manager->switch_to(InfraredAppViewManager::ViewId::ButtonMenu);
}
bool InfraredAppSceneRemote::on_event(InfraredApp* app, InfraredAppEvent* event) {
bool consumed = true;
if((event->type == InfraredAppEvent::Type::MenuSelected) ||
(event->type == InfraredAppEvent::Type::MenuSelectedPress) ||
(event->type == InfraredAppEvent::Type::MenuSelectedRelease)) {
switch(event->payload.menu_index) {
case ButtonIndexPlus:
furi_assert(event->type == InfraredAppEvent::Type::MenuSelected);
app->notify_click();
buttonmenu_item_selected = event->payload.menu_index;
app->set_learn_new_remote(false);
app->switch_to_next_scene(InfraredApp::Scene::Learn);
break;
case ButtonIndexEdit:
furi_assert(event->type == InfraredAppEvent::Type::MenuSelected);
app->notify_click();
buttonmenu_item_selected = event->payload.menu_index;
app->switch_to_next_scene(InfraredApp::Scene::Edit);
break;
default:
furi_assert(event->type != InfraredAppEvent::Type::MenuSelected);
bool pressed = (event->type == InfraredAppEvent::Type::MenuSelectedPress);
if(pressed && !button_pressed) {
button_pressed = true;
app->notify_click_and_green_blink();
auto button_signal =
app->get_remote_manager()->get_button_data(event->payload.menu_index);
if(button_signal.is_raw()) {
infrared_worker_set_raw_signal(
app->get_infrared_worker(),
button_signal.get_raw_signal().timings,
button_signal.get_raw_signal().timings_cnt);
} else {
infrared_worker_set_decoded_signal(
app->get_infrared_worker(), &button_signal.get_message());
}
DOLPHIN_DEED(DolphinDeedIrSend);
infrared_worker_tx_start(app->get_infrared_worker());
} else if(!pressed && button_pressed) {
button_pressed = false;
infrared_worker_tx_stop(app->get_infrared_worker());
app->notify_green_off();
}
break;
}
} else if(event->type == InfraredAppEvent::Type::Back) {
if(!button_pressed) {
app->search_and_switch_to_previous_scene(
{InfraredApp::Scene::Start, InfraredApp::Scene::RemoteList});
}
} else {
consumed = false;
}
return consumed;
}
void InfraredAppSceneRemote::on_exit(InfraredApp* app) {
infrared_worker_tx_set_get_signal_callback(app->get_infrared_worker(), nullptr, nullptr);
infrared_worker_tx_set_signal_sent_callback(app->get_infrared_worker(), nullptr, nullptr);
InfraredAppViewManager* view_manager = app->get_view_manager();
ButtonMenu* button_menu = view_manager->get_button_menu();
button_menu_reset(button_menu);
}

View File

@@ -0,0 +1,50 @@
#include "../infrared_app.h"
#include "infrared/infrared_app_event.h"
#include <text_store.h>
#include <file_worker_cpp.h>
void InfraredAppSceneRemoteList::on_enter(InfraredApp* app) {
furi_assert(app);
FileWorkerCpp file_worker;
bool result = false;
bool file_select_result;
auto remote_manager = app->get_remote_manager();
auto last_selected_remote = remote_manager->get_remote_name();
const char* last_selected_remote_name =
last_selected_remote.size() ? last_selected_remote.c_str() : nullptr;
auto filename_ts =
std::make_unique<TextStore>(InfraredAppRemoteManager::max_remote_name_length);
InfraredAppViewManager* view_manager = app->get_view_manager();
ButtonMenu* button_menu = view_manager->get_button_menu();
button_menu_reset(button_menu);
view_manager->switch_to(InfraredAppViewManager::ViewId::ButtonMenu);
file_select_result = file_worker.file_select(
InfraredApp::infrared_directory,
InfraredApp::infrared_extension,
filename_ts->text,
filename_ts->text_size,
last_selected_remote_name);
if(file_select_result) {
if(remote_manager->load(std::string(filename_ts->text))) {
app->switch_to_next_scene(InfraredApp::Scene::Remote);
result = true;
}
}
if(!result) {
app->switch_to_previous_scene();
}
}
bool InfraredAppSceneRemoteList::on_event(InfraredApp* app, InfraredAppEvent* event) {
bool consumed = false;
return consumed;
}
void InfraredAppSceneRemoteList::on_exit(InfraredApp* app) {
}

View File

@@ -0,0 +1,66 @@
#include "../infrared_app.h"
typedef enum {
SubmenuIndexUniversalLibrary,
SubmenuIndexLearnNewRemote,
SubmenuIndexSavedRemotes,
} SubmenuIndex;
static void submenu_callback(void* context, uint32_t index) {
InfraredApp* app = static_cast<InfraredApp*>(context);
InfraredAppEvent event;
event.type = InfraredAppEvent::Type::MenuSelected;
event.payload.menu_index = index;
app->get_view_manager()->send_event(&event);
}
void InfraredAppSceneStart::on_enter(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
Submenu* submenu = view_manager->get_submenu();
submenu_add_item(
submenu, "Universal library", SubmenuIndexUniversalLibrary, submenu_callback, app);
submenu_add_item(
submenu, "Learn new remote", SubmenuIndexLearnNewRemote, submenu_callback, app);
submenu_add_item(submenu, "Saved remotes", SubmenuIndexSavedRemotes, submenu_callback, app);
submenu_set_selected_item(submenu, submenu_item_selected);
submenu_item_selected = 0;
view_manager->switch_to(InfraredAppViewManager::ViewId::Submenu);
}
bool InfraredAppSceneStart::on_event(InfraredApp* app, InfraredAppEvent* event) {
bool consumed = false;
if(event->type == InfraredAppEvent::Type::MenuSelected) {
submenu_item_selected = event->payload.menu_index;
switch(event->payload.menu_index) {
case SubmenuIndexUniversalLibrary:
app->switch_to_next_scene(InfraredApp::Scene::Universal);
break;
case SubmenuIndexLearnNewRemote:
app->set_learn_new_remote(true);
app->switch_to_next_scene(InfraredApp::Scene::Learn);
break;
case SubmenuIndexSavedRemotes:
app->switch_to_next_scene(InfraredApp::Scene::RemoteList);
break;
default:
furi_assert(0);
break;
}
consumed = true;
}
return consumed;
}
void InfraredAppSceneStart::on_exit(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
Submenu* submenu = view_manager->get_submenu();
app->get_remote_manager()->reset_remote();
submenu_reset(submenu);
}

View File

@@ -0,0 +1,57 @@
#include "../infrared_app.h"
typedef enum {
SubmenuIndexUniversalTV,
SubmenuIndexUniversalAudio,
SubmenuIndexUniversalAirConditioner,
} SubmenuIndex;
static void submenu_callback(void* context, uint32_t index) {
InfraredApp* app = static_cast<InfraredApp*>(context);
InfraredAppEvent event;
event.type = InfraredAppEvent::Type::MenuSelected;
event.payload.menu_index = index;
app->get_view_manager()->send_event(&event);
}
void InfraredAppSceneUniversal::on_enter(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
Submenu* submenu = view_manager->get_submenu();
submenu_add_item(submenu, "TV's", SubmenuIndexUniversalTV, submenu_callback, app);
submenu_set_selected_item(submenu, submenu_item_selected);
submenu_item_selected = 0;
view_manager->switch_to(InfraredAppViewManager::ViewId::Submenu);
}
bool InfraredAppSceneUniversal::on_event(InfraredApp* app, InfraredAppEvent* event) {
bool consumed = false;
if(event->type == InfraredAppEvent::Type::MenuSelected) {
submenu_item_selected = event->payload.menu_index;
switch(event->payload.menu_index) {
case SubmenuIndexUniversalTV:
app->switch_to_next_scene(InfraredApp::Scene::UniversalTV);
break;
case SubmenuIndexUniversalAudio:
// app->switch_to_next_scene(InfraredApp::Scene::UniversalAudio);
break;
case SubmenuIndexUniversalAirConditioner:
// app->switch_to_next_scene(InfraredApp::Scene::UniversalAirConditioner);
break;
}
consumed = true;
}
return consumed;
}
void InfraredAppSceneUniversal::on_exit(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
Submenu* submenu = view_manager->get_submenu();
submenu_reset(submenu);
}

View File

@@ -0,0 +1,101 @@
#include <dolphin/dolphin.h>
#include <gui/modules/button_menu.h>
#include <gui/modules/button_panel.h>
#include <gui/view.h>
#include <gui/view_stack.h>
#include "../infrared_app.h"
#include "infrared/infrared_app_event.h"
#include "infrared/infrared_app_view_manager.h"
#include "infrared/scene/infrared_app_scene.h"
#include "../view/infrared_progress_view.h"
void InfraredAppSceneUniversalCommon::infrared_app_item_callback(void* context, uint32_t index) {
InfraredApp* app = static_cast<InfraredApp*>(context);
InfraredAppEvent event;
event.type = InfraredAppEvent::Type::ButtonPanelPressed;
event.payload.menu_index = index;
app->get_view_manager()->send_event(&event);
}
static void infrared_progress_back_callback(void* context) {
furi_assert(context);
auto app = static_cast<InfraredApp*>(context);
InfraredAppEvent infrared_event = {
.type = InfraredAppEvent::Type::Back,
};
app->get_view_manager()->clear_events();
app->get_view_manager()->send_event(&infrared_event);
}
void InfraredAppSceneUniversalCommon::hide_popup(InfraredApp* app) {
auto stack_view = app->get_view_manager()->get_universal_view_stack();
auto progress_view = app->get_view_manager()->get_progress();
view_stack_remove_view(stack_view, infrared_progress_view_get_view(progress_view));
}
void InfraredAppSceneUniversalCommon::show_popup(InfraredApp* app, int record_amount) {
auto stack_view = app->get_view_manager()->get_universal_view_stack();
auto progress_view = app->get_view_manager()->get_progress();
infrared_progress_view_set_progress_total(progress_view, record_amount);
infrared_progress_view_set_back_callback(progress_view, infrared_progress_back_callback, app);
view_stack_add_view(stack_view, infrared_progress_view_get_view(progress_view));
}
bool InfraredAppSceneUniversalCommon::progress_popup(InfraredApp* app) {
auto progress_view = app->get_view_manager()->get_progress();
return infrared_progress_view_increase_progress(progress_view);
}
bool InfraredAppSceneUniversalCommon::on_event(InfraredApp* app, InfraredAppEvent* event) {
bool consumed = false;
if(brute_force_started) {
if(event->type == InfraredAppEvent::Type::Tick) {
auto view_manager = app->get_view_manager();
InfraredAppEvent tick_event = {.type = InfraredAppEvent::Type::Tick};
view_manager->send_event(&tick_event);
bool result = brute_force.send_next_bruteforce();
if(result) {
result = progress_popup(app);
}
if(!result) {
brute_force.stop_bruteforce();
brute_force_started = false;
hide_popup(app);
}
consumed = true;
} else if(event->type == InfraredAppEvent::Type::Back) {
brute_force_started = false;
brute_force.stop_bruteforce();
hide_popup(app);
consumed = true;
}
} else {
if(event->type == InfraredAppEvent::Type::ButtonPanelPressed) {
int record_amount = 0;
if(brute_force.start_bruteforce(event->payload.menu_index, record_amount)) {
DOLPHIN_DEED(DolphinDeedIrBruteForce);
brute_force_started = true;
show_popup(app, record_amount);
} else {
app->switch_to_previous_scene();
}
consumed = true;
} else if(event->type == InfraredAppEvent::Type::Back) {
app->switch_to_previous_scene();
consumed = true;
}
}
return consumed;
}
void InfraredAppSceneUniversalCommon::on_exit(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
ButtonPanel* button_panel = view_manager->get_button_panel();
button_panel_reset(button_panel);
}

View File

@@ -0,0 +1,123 @@
#include <stdint.h>
#include <gui/modules/loading.h>
#include <gui/view_stack.h>
#include "infrared/scene/infrared_app_scene.h"
#include "infrared/infrared_app.h"
void InfraredAppSceneUniversalTV::on_enter(InfraredApp* app) {
InfraredAppViewManager* view_manager = app->get_view_manager();
ButtonPanel* button_panel = view_manager->get_button_panel();
button_panel_reserve(button_panel, 2, 3);
int i = 0;
button_panel_add_item(
button_panel,
i,
0,
0,
3,
19,
&I_Power_25x27,
&I_Power_hvr_25x27,
infrared_app_item_callback,
app);
brute_force.add_record(i, "POWER");
++i;
button_panel_add_item(
button_panel,
i,
1,
0,
36,
19,
&I_Mute_25x27,
&I_Mute_hvr_25x27,
infrared_app_item_callback,
app);
brute_force.add_record(i, "MUTE");
++i;
button_panel_add_item(
button_panel,
i,
0,
1,
3,
66,
&I_Vol_up_25x27,
&I_Vol_up_hvr_25x27,
infrared_app_item_callback,
app);
brute_force.add_record(i, "VOL+");
++i;
button_panel_add_item(
button_panel,
i,
1,
1,
36,
66,
&I_Up_25x27,
&I_Up_hvr_25x27,
infrared_app_item_callback,
app);
brute_force.add_record(i, "CH+");
++i;
button_panel_add_item(
button_panel,
i,
0,
2,
3,
98,
&I_Vol_down_25x27,
&I_Vol_down_hvr_25x27,
infrared_app_item_callback,
app);
brute_force.add_record(i, "VOL-");
++i;
button_panel_add_item(
button_panel,
i,
1,
2,
36,
98,
&I_Down_25x27,
&I_Down_hvr_25x27,
infrared_app_item_callback,
app);
brute_force.add_record(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_manager->switch_to(InfraredAppViewManager::ViewId::UniversalRemote);
auto stack_view = app->get_view_manager()->get_universal_view_stack();
auto loading_view = app->get_view_manager()->get_loading();
view_stack_add_view(stack_view, loading_get_view(loading_view));
/**
* Problem: Update events are not handled in Loading View, because:
* 1) Timer task has least prio
* 2) Storage service uses drivers that capture whole CPU time
* to handle SD communication
*
* Ugly workaround, but it works for current situation:
* raise timer task prio for DB scanning period.
*/
TaskHandle_t timer_task = xTaskGetHandle(configTIMER_SERVICE_TASK_NAME);
TaskHandle_t storage_task = xTaskGetHandle("StorageSrv");
uint32_t timer_prio = uxTaskPriorityGet(timer_task);
uint32_t storage_prio = uxTaskPriorityGet(storage_task);
vTaskPrioritySet(timer_task, storage_prio + 1);
bool result = brute_force.calculate_messages();
vTaskPrioritySet(timer_task, timer_prio);
view_stack_remove_view(stack_view, loading_get_view(loading_view));
if(!result) {
app->switch_to_previous_scene();
}
}