Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/flipperzero-firmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Kharisov <ah@bright-box.com>2021-06-09 16:04:49 +0300
committerGitHub <noreply@github.com>2021-06-09 16:04:49 +0300
commit6c74ea65c27d86a98db55882ff86563bb161423e (patch)
tree792f0fbee2b9c35d7b7b3bc48f73f0eb7cd23ddb /applications/irda
parent498ffe8d2c7bcc2a107db3d5624fb4f612aac34c (diff)
[FL-1369, FL-1397, FL-1420] IRDA + SDcard (#513)
* Add saving to SD-Card (not ready yet) * Add saving to SD-card (done) * Select previous menu item * Fix central button * Fix current_button * Refactoring * Add notifications * [FL-1417] Add IRDA CLI CLI commands: 1) ir_rx Receives all IR-trafic, decodes and prints result to stdout 2) ir_tx <protocol> <address> <command> Transmits IR-signal. Address and command are hex-formatted * Fix BUG with random memory corruption at random time in random place in random universe in random unknown space and time forever amen * Fix submenu set_selected_item * Bring protocol order back * Add TODO sdcard check
Diffstat (limited to 'applications/irda')
-rw-r--r--applications/irda/cli/irda-cli.cpp104
-rw-r--r--applications/irda/irda-app-remote-manager.cpp378
-rw-r--r--applications/irda/irda-app-remote-manager.hpp64
-rw-r--r--applications/irda/irda-app.cpp68
-rw-r--r--applications/irda/irda-app.hpp24
-rw-r--r--applications/irda/scene/irda-app-scene-edit-delete.cpp22
-rw-r--r--applications/irda/scene/irda-app-scene-edit-key-select.cpp11
-rw-r--r--applications/irda/scene/irda-app-scene-edit-rename.cpp19
-rw-r--r--applications/irda/scene/irda-app-scene-edit.cpp5
-rw-r--r--applications/irda/scene/irda-app-scene-learn-enter-name.cpp13
-rw-r--r--applications/irda/scene/irda-app-scene-learn-success.cpp22
-rw-r--r--applications/irda/scene/irda-app-scene-learn.cpp9
-rw-r--r--applications/irda/scene/irda-app-scene-remote-list.cpp26
-rw-r--r--applications/irda/scene/irda-app-scene-remote.cpp13
-rw-r--r--applications/irda/scene/irda-app-scene-start.cpp6
-rw-r--r--applications/irda/scene/irda-app-scene-universal.cpp3
-rw-r--r--applications/irda/scene/irda-app-scene.hpp9
17 files changed, 675 insertions, 121 deletions
diff --git a/applications/irda/cli/irda-cli.cpp b/applications/irda/cli/irda-cli.cpp
new file mode 100644
index 00000000..549e2e23
--- /dev/null
+++ b/applications/irda/cli/irda-cli.cpp
@@ -0,0 +1,104 @@
+#include "app-template.h"
+#include "cli/cli.h"
+#include "cmsis_os2.h"
+#include <furi.h>
+#include <api-hal-irda.h>
+#include "irda.h"
+#include <sstream>
+#include <string>
+#include <m-string.h>
+
+typedef struct IrdaCli {
+ IrdaHandler* handler;
+ osMessageQueueId_t message_queue;
+} IrdaCli;
+
+static void irda_rx_callback(void* ctx, bool level, uint32_t duration) {
+ IrdaCli* irda_cli = (IrdaCli*)ctx;
+ const IrdaMessage* message;
+ message = irda_decode(irda_cli->handler, level, duration);
+ if(message) {
+ osMessageQueuePut(irda_cli->message_queue, message, 0, 0);
+ }
+}
+
+static void irda_cli_start_ir_rx(Cli* cli, string_t args, void* context) {
+ if(api_hal_irda_rx_irq_is_busy()) {
+ printf("IRDA is busy. Exit.");
+ return;
+ }
+ IrdaCli irda_cli;
+ irda_cli.handler = irda_alloc_decoder();
+ irda_cli.message_queue = osMessageQueueNew(2, sizeof(IrdaMessage), NULL);
+ api_hal_irda_rx_irq_init();
+ api_hal_irda_rx_irq_set_callback(irda_rx_callback, &irda_cli);
+
+ printf("Receiving IRDA...\r\nPress Ctrl+C to abort\r\n");
+ while(!cli_cmd_interrupt_received(cli)) {
+ IrdaMessage message;
+ if(osOK == osMessageQueueGet(irda_cli.message_queue, &message, NULL, 50)) {
+ printf(
+ "%s, A:0x%0*lX, C:0x%0*lX%s\r\n",
+ irda_get_protocol_name(message.protocol),
+ irda_get_protocol_address_length(message.protocol),
+ message.address,
+ irda_get_protocol_command_length(message.protocol),
+ message.command,
+ message.repeat ? " R" : "");
+ }
+ }
+
+ api_hal_irda_rx_irq_deinit();
+ irda_free_decoder(irda_cli.handler);
+ osMessageQueueDelete(irda_cli.message_queue);
+}
+
+static void irda_cli_print_usage(void) {
+ printf("Usage:\r\n\tir_tx <protocol> <command> <address>\r\n");
+ printf("\t<command> and <address> are hex-formatted\r\n");
+ printf("\tAvailable protocols:");
+ for(int i = 0; irda_is_protocol_valid((IrdaProtocol)i); ++i) {
+ printf(" %s", irda_get_protocol_name((IrdaProtocol)i));
+ }
+ printf("\r\n");
+}
+
+static void irda_cli_start_ir_tx(Cli* cli, string_t args, void* context) {
+ if(api_hal_irda_rx_irq_is_busy()) {
+ printf("IRDA is busy. Exit.");
+ return;
+ }
+ auto ss = std::istringstream(string_get_cstr(args));
+ uint32_t command = 0;
+ uint32_t address = 0;
+ std::string protocol_name;
+
+ if(!(ss >> protocol_name) || !(ss >> std::hex >> address) || !(ss >> std::hex >> command)) {
+ printf("Wrong arguments.\r\n");
+ irda_cli_print_usage();
+ return;
+ }
+
+ IrdaProtocol protocol = irda_get_protocol_by_name(protocol_name.c_str());
+
+ if(!irda_is_protocol_valid(protocol)) {
+ printf("Unknown protocol.\r\n");
+ irda_cli_print_usage();
+ return;
+ }
+
+ IrdaMessage message = {
+ .protocol = protocol,
+ .address = address,
+ .command = command,
+ .repeat = false,
+ };
+ irda_send(&message, 1);
+}
+
+extern "C" void irda_cli_init() {
+ Cli* cli = (Cli*)furi_record_open("cli");
+ cli_add_command(cli, "ir_rx", irda_cli_start_ir_rx, NULL);
+ cli_add_command(cli, "ir_tx", irda_cli_start_ir_tx, NULL);
+ furi_record_close("cli");
+}
diff --git a/applications/irda/irda-app-remote-manager.cpp b/applications/irda/irda-app-remote-manager.cpp
index 7e68b4c9..33d763bc 100644
--- a/applications/irda/irda-app-remote-manager.cpp
+++ b/applications/irda/irda-app-remote-manager.cpp
@@ -1,51 +1,78 @@
#include "irda-app-remote-manager.hpp"
+#include "filesystem-api.h"
#include "furi.h"
+#include "furi/check.h"
+#include "gui/modules/button_menu.h"
+#include "irda.h"
+#include "sys/_stdint.h"
+#include <cstdio>
#include <string>
#include <utility>
+const char* IrdaAppRemoteManager::irda_directory = "irda";
+const char* IrdaAppRemoteManager::irda_extension = ".ir";
+static const std::string default_remote_name = "remote";
+
+static bool find_string(const std::vector<std::string>& strings, const std::string& match_string) {
+ for(const auto& string : strings) {
+ if(!string.compare(match_string)) return true;
+ }
+ return false;
+}
+
+static std::string
+find_vacant_name(const std::vector<std::string>& strings, const std::string& name) {
+ // if suggested name is occupied, try another one (name2, name3, etc)
+ if(find_string(strings, name)) {
+ int i = 1;
+ while(find_string(strings, name + std::to_string(++i)))
+ ;
+ return name + std::to_string(i);
+ } else {
+ return name;
+ }
+}
+
IrdaAppRemoteManager::IrdaAppRemoteManager() {
- // Read from api-hal-storage, and fill remotes
+ sd_ex_api = static_cast<SdCard_Api*>(furi_record_open("sdcard-ex"));
+ fs_api = static_cast<FS_Api*>(furi_record_open("sdcard"));
}
-static const std::string default_remote_name = "remote";
+IrdaAppRemoteManager::~IrdaAppRemoteManager() {
+ furi_record_close("sdcard");
+ furi_record_close("sdcard-ex");
+}
-void IrdaAppRemoteManager::add_button(const char* button_name, const IrdaMessage* message) {
- remotes[current_remote_index].buttons.emplace_back(button_name, message);
+bool IrdaAppRemoteManager::add_button(const char* button_name, const IrdaMessage* message) {
+ remote->buttons.emplace_back(button_name, message);
+ return store();
}
-void IrdaAppRemoteManager::add_remote_with_button(
+bool IrdaAppRemoteManager::add_remote_with_button(
const char* button_name,
const IrdaMessage* message) {
- bool found = true;
- int i = 0;
+ furi_check(button_name != nullptr);
+ furi_check(message != nullptr);
- // find first free common name for remote
- do {
- found = false;
- ++i;
- for(const auto& it : remotes) {
- if(it.name == (default_remote_name + std::to_string(i))) {
- found = true;
- break;
- }
- }
- } while(found);
+ std::vector<std::string> remote_list;
+ bool result = get_remote_list(remote_list);
+ if(!result) return false;
- remotes.emplace_back(default_remote_name + std::to_string(i));
- current_remote_index = remotes.size() - 1;
- add_button(button_name, message);
+ auto new_name = find_vacant_name(remote_list, default_remote_name);
+
+ remote = std::make_unique<IrdaAppRemote>(new_name);
+ return add_button(button_name, message);
}
-IrdaAppRemote::IrdaAppRemote(std::string name)
+IrdaAppRemote::IrdaAppRemote(const std::string& name)
: name(name) {
}
std::vector<std::string> IrdaAppRemoteManager::get_button_list(void) const {
std::vector<std::string> name_vector;
- auto remote = remotes[current_remote_index];
- name_vector.reserve(remote.buttons.size());
+ name_vector.reserve(remote->buttons.size());
- for(const auto& it : remote.buttons) {
+ for(const auto& it : remote->buttons) {
name_vector.emplace_back(it.name);
}
@@ -53,78 +80,289 @@ std::vector<std::string> IrdaAppRemoteManager::get_button_list(void) const {
return name_vector;
}
-std::vector<std::string> IrdaAppRemoteManager::get_remote_list() const {
- std::vector<std::string> name_vector;
- name_vector.reserve(remotes.size());
+const IrdaMessage* IrdaAppRemoteManager::get_button_data(size_t index) const {
+ furi_check(remote.get() != nullptr);
+ auto& buttons = remote->buttons;
+ furi_check(index < buttons.size());
+
+ return &buttons.at(index).message;
+}
+
+std::string IrdaAppRemoteManager::make_filename(const std::string& name) const {
+ return std::string("/") + irda_directory + "/" + name + irda_extension;
+}
+
+bool IrdaAppRemoteManager::delete_remote() {
+ FS_Error fs_res;
- for(const auto& it : remotes) {
- name_vector.push_back(it.name);
+ fs_res = fs_api->common.remove(make_filename(remote->name).c_str());
+ if(fs_res != FSE_OK) {
+ show_file_error_message("Error deleting file");
+ return false;
}
+ remote.reset();
+ return true;
+}
- // copy elision
- return name_vector;
+bool IrdaAppRemoteManager::delete_button(uint32_t index) {
+ furi_check(remote.get() != nullptr);
+ auto& buttons = remote->buttons;
+ furi_check(index < buttons.size());
+
+ buttons.erase(buttons.begin() + index);
+ return store();
}
-size_t IrdaAppRemoteManager::get_current_remote(void) const {
- return current_remote_index;
+std::string IrdaAppRemoteManager::get_button_name(uint32_t index) {
+ furi_check(remote.get() != nullptr);
+ auto& buttons = remote->buttons;
+ furi_check(index < buttons.size());
+ return buttons[index].name;
}
-size_t IrdaAppRemoteManager::get_current_button(void) const {
- return current_button_index;
+std::string IrdaAppRemoteManager::get_remote_name() {
+ furi_check(remote.get() != nullptr);
+ return remote->name;
}
-void IrdaAppRemote::add_button(
- size_t remote_index,
- const char* button_name,
- const IrdaMessage* message) {
- buttons.emplace_back(button_name, message);
+int IrdaAppRemoteManager::find_remote_name(const std::vector<std::string>& strings) {
+ int i = 0;
+ for(const auto& str : strings) {
+ if(!str.compare(remote->name)) {
+ return i;
+ }
+ ++i;
+ }
+ return -1;
}
-const IrdaMessage* IrdaAppRemoteManager::get_button_data(size_t button_index) const {
- furi_check(remotes[current_remote_index].buttons.size() > button_index);
- auto& b = remotes[current_remote_index].buttons.at(button_index);
- return &b.message;
+bool IrdaAppRemoteManager::rename_remote(const char* str) {
+ furi_check(str != nullptr);
+ furi_check(remote.get() != nullptr);
+
+ if(!remote->name.compare(str)) return true;
+
+ std::vector<std::string> remote_list;
+ bool result = get_remote_list(remote_list);
+ if(!result) return false;
+
+ auto new_name = find_vacant_name(remote_list, str);
+ FS_Error fs_err = fs_api->common.rename(
+ make_filename(remote->name).c_str(), make_filename(new_name).c_str());
+ remote->name = new_name;
+ if(fs_err != FSE_OK) {
+ show_file_error_message("Error renaming\nremote file");
+ }
+ return fs_err == FSE_OK;
}
-void IrdaAppRemoteManager::set_current_remote(size_t index) {
- furi_check(index < remotes.size());
- current_remote_index = index;
+bool IrdaAppRemoteManager::rename_button(uint32_t index, const char* str) {
+ furi_check(remote.get() != nullptr);
+ auto& buttons = remote->buttons;
+ furi_check(index < buttons.size());
+
+ buttons[index].name = str;
+ return store();
}
-void IrdaAppRemoteManager::set_current_button(size_t index) {
- furi_check(current_remote_index < remotes.size());
- furi_check(index < remotes[current_remote_index].buttons.size());
- current_button_index = index;
+size_t IrdaAppRemoteManager::get_number_of_buttons() {
+ furi_check(remote.get() != nullptr);
+ return remote->buttons.size();
}
-void IrdaAppRemoteManager::delete_current_remote() {
- remotes.erase(remotes.begin() + current_remote_index);
- current_remote_index = 0;
+void IrdaAppRemoteManager::show_file_error_message(const char* error_text) const {
+ sd_ex_api->show_error(sd_ex_api->context, error_text);
}
-void IrdaAppRemoteManager::delete_current_button() {
- auto& buttons = remotes[current_remote_index].buttons;
- buttons.erase(buttons.begin() + current_button_index);
- current_button_index = 0;
+bool IrdaAppRemoteManager::store(void) {
+ File file;
+ uint16_t write_count;
+ std::string dirname(std::string("/") + irda_directory);
+
+ FS_Error fs_err = fs_api->common.mkdir(dirname.c_str());
+ if((fs_err != FSE_OK) && (fs_err != FSE_EXIST)) {
+ show_file_error_message("Can't create directory");
+ return false;
+ }
+
+ std::string filename = dirname + "/" + remote->name + irda_extension;
+ bool res = fs_api->file.open(&file, filename.c_str(), FSAM_WRITE, FSOM_CREATE_ALWAYS);
+
+ if(!res) {
+ show_file_error_message("Cannot create\nnew remote file");
+ return false;
+ }
+
+ char content[128];
+
+ for(const auto& button : remote->buttons) {
+ auto protocol = button.message.protocol;
+
+ sniprintf(
+ content,
+ sizeof(content),
+ "%.31s %.31s A:%0*lX C:%0*lX\n",
+ button.name.c_str(),
+ irda_get_protocol_name(protocol),
+ irda_get_protocol_address_length(protocol),
+ button.message.address,
+ irda_get_protocol_command_length(protocol),
+ button.message.command);
+
+ auto content_len = strlen(content);
+ write_count = fs_api->file.write(&file, content, content_len);
+ if(file.error_id != FSE_OK || write_count != content_len) {
+ show_file_error_message("Cannot write\nto key file");
+ fs_api->file.close(&file);
+ return false;
+ }
+ }
+
+ fs_api->file.close(&file);
+ sd_ex_api->check_error(sd_ex_api->context);
+
+ return true;
}
-std::string IrdaAppRemoteManager::get_current_button_name() {
- auto buttons = remotes[current_remote_index].buttons;
- return buttons[current_button_index].name;
+bool IrdaAppRemoteManager::parse_button(std::string& str) {
+ char button_name[32];
+ char protocol_name[32];
+ uint32_t address;
+ uint32_t command;
+
+ int parsed = std::sscanf(
+ str.c_str(), "%31s %31s A:%lX C:%lX", button_name, protocol_name, &address, &command);
+
+ if(parsed != 4) {
+ return false;
+ }
+
+ IrdaProtocol protocol = irda_get_protocol_by_name(protocol_name);
+
+ if(!irda_is_protocol_valid((IrdaProtocol)protocol)) {
+ return false;
+ }
+
+ int address_length = irda_get_protocol_address_length(protocol);
+ uint32_t address_mask = (1LU << (4 * address_length)) - 1;
+ if(address != (address & address_mask)) {
+ return false;
+ }
+
+ int command_length = irda_get_protocol_command_length(protocol);
+ uint32_t command_mask = (1LU << (4 * command_length)) - 1;
+ if(command != (command & command_mask)) {
+ return false;
+ }
+
+ IrdaMessage irda_message = {
+ .protocol = protocol,
+ .address = address,
+ .command = command,
+ .repeat = false,
+ };
+ remote->buttons.emplace_back(button_name, &irda_message);
+
+ return true;
}
-std::string IrdaAppRemoteManager::get_current_remote_name() {
- return remotes[current_remote_index].name;
+std::string getline(
+ const FS_Api* fs_api,
+ File& file,
+ char file_buf[],
+ size_t file_buf_size,
+ size_t& file_buf_cnt) {
+ std::string str;
+ size_t newline_index = 0;
+ bool found_eol = false;
+
+ while(1) {
+ if(file_buf_cnt > 0) {
+ size_t end_index = 0;
+ char* endline_ptr = (char*)memchr(file_buf, '\n', file_buf_cnt);
+ newline_index = endline_ptr - file_buf;
+
+ if(endline_ptr == 0) {
+ end_index = file_buf_cnt;
+ } else if(newline_index < file_buf_cnt) {
+ end_index = newline_index + 1;
+ found_eol = true;
+ } else {
+ furi_assert(0);
+ }
+
+ str.append(file_buf, end_index);
+ memmove(file_buf, &file_buf[end_index], file_buf_cnt - end_index);
+ file_buf_cnt = file_buf_cnt - end_index;
+ if(found_eol) break;
+ }
+
+ file_buf_cnt +=
+ fs_api->file.read(&file, &file_buf[file_buf_cnt], file_buf_size - file_buf_cnt);
+ if(file_buf_cnt == 0) {
+ break; // end of reading
+ }
+ }
+
+ return str;
}
-void IrdaAppRemoteManager::rename_remote(const char* str) {
- remotes[current_remote_index].name = str;
+bool IrdaAppRemoteManager::get_remote_list(std::vector<std::string>& remote_names) const {
+ bool fs_res = false;
+ char name[128];
+ File dir;
+ std::string dirname(std::string("/") + irda_directory);
+ remote_names.clear();
+
+ fs_res = fs_api->dir.open(&dir, dirname.c_str());
+ if(!fs_res) {
+ if(!check_fs()) {
+ show_file_error_message("Cannot open\napplication directory");
+ return false;
+ } else {
+ return true; // SD ok, but no files written yet
+ }
+ }
+
+ while(fs_api->dir.read(&dir, nullptr, name, sizeof(name)) && strlen(name)) {
+ std::string filename(name);
+ auto extension_index = filename.rfind(irda_extension);
+ if((extension_index == std::string::npos) ||
+ (extension_index + strlen(irda_extension) != filename.size())) {
+ continue;
+ }
+ remote_names.push_back(filename.erase(extension_index));
+ }
+ fs_api->dir.close(&dir);
+
+ return true;
}
-void IrdaAppRemoteManager::rename_button(const char* str) {
- remotes[current_remote_index].buttons[current_button_index].name = str;
+bool IrdaAppRemoteManager::load(const std::string& name) {
+ bool fs_res = false;
+ File file;
+
+ fs_res = fs_api->file.open(&file, make_filename(name).c_str(), FSAM_READ, FSOM_OPEN_EXISTING);
+ if(!fs_res) {
+ show_file_error_message("Error opening file");
+ return false;
+ }
+
+ remote = std::make_unique<IrdaAppRemote>(name);
+
+ while(1) {
+ auto str = getline(fs_api, file, file_buf, sizeof(file_buf), file_buf_cnt);
+ if(str.empty()) break;
+ parse_button(str);
+ }
+ fs_api->file.close(&file);
+
+ return true;
}
-size_t IrdaAppRemoteManager::get_current_remote_buttons_number() {
- return remotes[current_remote_index].buttons.size();
+bool IrdaAppRemoteManager::check_fs() const {
+ // TODO: [FL-1431] Add return value to sd_ex_api->check_error() and replace get_fs_info().
+ auto fs_err = fs_api->common.get_fs_info(nullptr, nullptr);
+ if(fs_err != FSE_OK) show_file_error_message("SD card not found");
+ return fs_err == FSE_OK;
}
diff --git a/applications/irda/irda-app-remote-manager.hpp b/applications/irda/irda-app-remote-manager.hpp
index 1930ba5b..dd0ae9bc 100644
--- a/applications/irda/irda-app-remote-manager.hpp
+++ b/applications/irda/irda-app-remote-manager.hpp
@@ -1,9 +1,14 @@
#pragma once
+#include "sys/_stdint.h"
+#include <algorithm>
#include <stdint.h>
#include <string>
#include <list>
#include <vector>
+#include <memory>
#include <irda.h>
+#include <sd-card-api.h>
+#include <filesystem-api.h>
class IrdaAppRemoteButton {
friend class IrdaAppRemoteManager;
@@ -19,35 +24,50 @@ class IrdaAppRemote {
friend class IrdaAppRemoteManager;
std::vector<IrdaAppRemoteButton> buttons;
std::string name;
- bool add(const IrdaMessage*);
- void add_button(size_t remote_index, const char* button_name, const IrdaMessage* message);
public:
- IrdaAppRemote(std::string name);
+ IrdaAppRemote(const std::string& name);
+ IrdaAppRemote& operator=(std::string& new_name) noexcept
+ {
+ name = new_name;
+ buttons.clear();
+ return *this;
+ }
};
class IrdaAppRemoteManager {
- size_t current_remote_index;
- size_t current_button_index;
- std::vector<IrdaAppRemote> remotes;
+ static const char* irda_directory;
+ static const char* irda_extension;
+ std::unique_ptr<IrdaAppRemote> remote;
+ // TODO: make FS_Api and SdCard_Api unique_ptr
+ SdCard_Api* sd_ex_api;
+ FS_Api* fs_api;
+ void show_file_error_message(const char* error_text) const;
+ bool parse_button(std::string& str);
+ std::string make_filename(const std::string& name) const;
+ char file_buf[48];
+ size_t file_buf_cnt = 0;
+
public:
- std::vector<std::string> get_remote_list() const;
- std::vector<std::string> get_button_list() const;
- void add_remote_with_button(const char* button_name, const IrdaMessage* message);
- void add_button(const char* button_name, const IrdaMessage* message);
+ bool add_remote_with_button(const char* button_name, const IrdaMessage* message);
+ bool add_button(const char* button_name, const IrdaMessage* message);
+
+ int find_remote_name(const std::vector<std::string>& strings);
+ bool rename_button(uint32_t index, const char* str);
+ bool rename_remote(const char* str);
- size_t get_current_remote(void) const;
- size_t get_current_button(void) const;
+ bool get_remote_list(std::vector<std::string>& remote_names) const;
+ std::vector<std::string> get_button_list() const;
+ std::string get_button_name(uint32_t index);
+ std::string get_remote_name();
+ size_t get_number_of_buttons();
const IrdaMessage* get_button_data(size_t button_index) const;
- void set_current_remote(size_t index);
- void set_current_button(size_t index);
- void rename_button(const char* str);
- void rename_remote(const char* str);
- std::string get_current_button_name();
- std::string get_current_remote_name();
- size_t get_current_remote_buttons_number();
- void delete_current_button();
- void delete_current_remote();
+ bool delete_button(uint32_t index);
+ bool delete_remote();
IrdaAppRemoteManager();
- ~IrdaAppRemoteManager() {};
+ ~IrdaAppRemoteManager();
+
+ bool store();
+ bool load(const std::string& name);
+ bool check_fs() const;
};
diff --git a/applications/irda/irda-app.cpp b/applications/irda/irda-app.cpp
index a4d69403..95b9a137 100644
--- a/applications/irda/irda-app.cpp
+++ b/applications/irda/irda-app.cpp
@@ -1,4 +1,5 @@
#include "irda-app.hpp"
+#include "sys/_stdint.h"
#include <furi.h>
#include <gui/gui.h>
#include <input/input.h>
@@ -154,3 +155,70 @@ void IrdaApp::set_edit_action(IrdaApp::EditAction value) {
IrdaApp::EditAction IrdaApp::get_edit_action(void) {
return action;
}
+
+void IrdaApp::set_current_button(int value) {
+ current_button = value;
+}
+
+int IrdaApp::get_current_button() {
+ return current_button;
+}
+
+void IrdaApp::notify_success() {
+ notification_message(notification, &sequence_success);
+}
+
+void IrdaApp::notify_red_blink() {
+ notification_message(notification, &sequence_blink_red_10);
+}
+
+void IrdaApp::notify_space_blink() {
+ static const NotificationSequence sequence = {
+ &message_green_0,
+ &message_delay_50,
+ &message_green_255,
+ &message_do_not_reset,
+ NULL,
+ };
+
+ notification_message_block(notification, &sequence);
+}
+
+void IrdaApp::notify_click() {
+ static const NotificationSequence sequence = {
+ &message_click,
+ &message_delay_1,
+ &message_sound_off,
+ NULL,
+ };
+
+ notification_message_block(notification, &sequence);
+}
+
+void IrdaApp::notify_click_and_blink() {
+ static const NotificationSequence sequence = {
+ &message_click,
+ &message_delay_1,
+ &message_sound_off,
+ &message_red_0,
+ &message_green_255,
+ &message_blue_0,
+ &message_delay_10,
+ &message_green_0,
+ NULL,
+ };
+
+ notification_message_block(notification, &sequence);
+}
+
+void IrdaApp::notify_double_vibro() {
+ notification_message(notification, &sequence_double_vibro);
+}
+
+void IrdaApp::notify_green_on() {
+ notification_message(notification, &sequence_set_only_green_255);
+}
+
+void IrdaApp::notify_green_off() {
+ notification_message(notification, &sequence_reset_green);
+}
diff --git a/applications/irda/irda-app.hpp b/applications/irda/irda-app.hpp
index c1e8ce62..16ba3f49 100644
--- a/applications/irda/irda-app.hpp
+++ b/applications/irda/irda-app.hpp
@@ -1,4 +1,5 @@
#pragma once
+#include "sys/_stdint.h"
#include <map>
#include <irda.h>
#include <furi.h>
@@ -9,6 +10,7 @@
#include "irda-app-receiver.hpp"
#include <forward_list>
#include <stdint.h>
+#include <notification/notification-messages.h>
class IrdaApp {
@@ -65,11 +67,29 @@ public:
bool get_learn_new_remote();
void set_learn_new_remote(bool value);
+ enum : int {
+ ButtonNA = -1,
+ };
+ int get_current_button();
+ void set_current_button(int value);
+
+ void notify_success();
+ void notify_red_blink();
+ void notify_space_blink();
+ void notify_double_vibro();
+ void notify_green_on();
+ void notify_green_off();
+ void notify_click();
+ void notify_click_and_blink();
+
static void text_input_callback(void* context, char* text);
static void popup_callback(void* context);
- IrdaApp() {}
+ IrdaApp() {
+ notification = static_cast<NotificationApp*>(furi_record_open("notification"));
+ }
~IrdaApp() {
+ furi_record_close("notification");
for (auto &it : scenes)
delete it.second;
}
@@ -80,7 +100,9 @@ private:
bool learn_new_remote;
EditElement element;
EditAction action;
+ uint32_t current_button;
+ NotificationApp* notification;
IrdaAppSignalReceiver receiver;
IrdaAppViewManager view_manager;
IrdaAppRemoteManager remote_manager;
diff --git a/applications/irda/scene/irda-app-scene-edit-delete.cpp b/applications/irda/scene/irda-app-scene-edit-delete.cpp
index 929dd2d4..a2d8934f 100644
--- a/applications/irda/scene/irda-app-scene-edit-delete.cpp
+++ b/applications/irda/scene/irda-app-scene-edit-delete.cpp
@@ -1,5 +1,6 @@
#include "../irda-app.hpp"
#include "irda.h"
+#include "irda/scene/irda-app-scene.hpp"
#include <string>
#include <stdio.h>
@@ -20,12 +21,12 @@ void IrdaAppSceneEditDelete::on_enter(IrdaApp* app) {
auto remote_manager = app->get_remote_manager();
if(app->get_edit_element() == IrdaApp::EditElement::Button) {
- auto message = remote_manager->get_button_data(remote_manager->get_current_button());
+ auto message = remote_manager->get_button_data(app->get_current_button());
dialog_ex_set_header(dialog_ex, "Delete button?", 64, 6, AlignCenter, AlignCenter);
app->set_text_store(
0,
"%s\n%s\nA=0x%0*lX C=0x%0*lX",
- remote_manager->get_current_button_name().c_str(),
+ remote_manager->get_button_name(app->get_current_button()).c_str(),
irda_get_protocol_name(message->protocol),
irda_get_protocol_address_length(message->protocol),
message->address,
@@ -36,8 +37,8 @@ void IrdaAppSceneEditDelete::on_enter(IrdaApp* app) {
app->set_text_store(
0,
"%s\n with %lu buttons",
- remote_manager->get_current_remote_name().c_str(),
- remote_manager->get_current_remote_buttons_number());
+ 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, 32, AlignCenter, AlignCenter);
@@ -63,13 +64,20 @@ bool IrdaAppSceneEditDelete::on_event(IrdaApp* app, IrdaAppEvent* event) {
break;
case DialogExResultRight:
auto remote_manager = app->get_remote_manager();
+ bool result = false;
if(app->get_edit_element() == IrdaApp::EditElement::Remote) {
- remote_manager->delete_current_remote();
+ result = remote_manager->delete_remote();
} else {
- remote_manager->delete_current_button();
+ result = remote_manager->delete_button(app->get_current_button());
+ app->set_current_button(IrdaApp::ButtonNA);
}
- app->switch_to_next_scene(IrdaApp::Scene::EditDeleteDone);
+ if(!result) {
+ app->search_and_switch_to_previous_scene(
+ {IrdaApp::Scene::RemoteList, IrdaApp::Scene::Start});
+ } else {
+ app->switch_to_next_scene(IrdaApp::Scene::EditDeleteDone);
+ }
break;
}
}
diff --git a/applications/irda/scene/irda-app-scene-edit-key-select.cpp b/applications/irda/scene/irda-app-scene-edit-key-select.cpp
index e0ead609..41956b1d 100644
--- a/applications/irda/scene/irda-app-scene-edit-key-select.cpp
+++ b/applications/irda/scene/irda-app-scene-edit-key-select.cpp
@@ -14,7 +14,7 @@ static void submenu_callback(void* context, uint32_t index) {
void IrdaAppSceneEditKeySelect::on_enter(IrdaApp* app) {
IrdaAppViewManager* view_manager = app->get_view_manager();
Submenu* submenu = view_manager->get_submenu();
- int i = 0;
+ int item_number = 0;
const char* header = app->get_edit_action() == IrdaApp::EditAction::Rename ? "Rename key:" :
"Delete key:";
@@ -23,7 +23,11 @@ void IrdaAppSceneEditKeySelect::on_enter(IrdaApp* app) {
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(), i++, submenu_callback, app);
+ submenu_add_item(submenu, it.c_str(), item_number++, submenu_callback, app);
+ }
+ if((item_number > 0) && (app->get_current_button() != IrdaApp::ButtonNA)) {
+ submenu_set_selected_item(submenu, app->get_current_button());
+ app->set_current_button(IrdaApp::ButtonNA);
}
view_manager->switch_to(IrdaAppViewManager::ViewType::Submenu);
@@ -33,8 +37,7 @@ bool IrdaAppSceneEditKeySelect::on_event(IrdaApp* app, IrdaAppEvent* event) {
bool consumed = false;
if(event->type == IrdaAppEvent::Type::MenuSelected) {
- auto remote_manager = app->get_remote_manager();
- remote_manager->set_current_button(event->payload.menu_index);
+ app->set_current_button(event->payload.menu_index);
consumed = true;
if(app->get_edit_action() == IrdaApp::EditAction::Rename) {
app->switch_to_next_scene(IrdaApp::Scene::EditRename);
diff --git a/applications/irda/scene/irda-app-scene-edit-rename.cpp b/applications/irda/scene/irda-app-scene-edit-rename.cpp
index 0ade41ca..0ed3700e 100644
--- a/applications/irda/scene/irda-app-scene-edit-rename.cpp
+++ b/applications/irda/scene/irda-app-scene-edit-rename.cpp
@@ -7,10 +7,11 @@ void IrdaAppSceneEditRename::on_enter(IrdaApp* app) {
auto remote_manager = app->get_remote_manager();
if(app->get_edit_element() == IrdaApp::EditElement::Button) {
- auto button_name = remote_manager->get_current_button_name();
+ furi_assert(app->get_current_button() != IrdaApp::ButtonNA);
+ auto button_name = remote_manager->get_button_name(app->get_current_button());
strncpy(app->get_text_store(0), button_name.c_str(), app->get_text_store_size());
} else {
- auto remote_name = remote_manager->get_current_remote_name();
+ auto remote_name = remote_manager->get_remote_name();
strncpy(app->get_text_store(0), remote_name.c_str(), app->get_text_store_size());
}
@@ -30,12 +31,20 @@ bool IrdaAppSceneEditRename::on_event(IrdaApp* app, IrdaAppEvent* event) {
if(event->type == IrdaAppEvent::Type::TextEditDone) {
auto remote_manager = app->get_remote_manager();
+ bool result = false;
if(app->get_edit_element() == IrdaApp::EditElement::Button) {
- remote_manager->rename_button(app->get_text_store(0));
+ result =
+ remote_manager->rename_button(app->get_current_button(), app->get_text_store(0));
+ app->set_current_button(IrdaApp::ButtonNA);
} else {
- remote_manager->rename_remote(app->get_text_store(0));
+ result = remote_manager->rename_remote(app->get_text_store(0));
+ }
+ if(!result) {
+ app->search_and_switch_to_previous_scene(
+ {IrdaApp::Scene::Start, IrdaApp::Scene::RemoteList});
+ } else {
+ app->switch_to_next_scene_without_saving(IrdaApp::Scene::EditRenameDone);
}
- app->switch_to_next_scene_without_saving(IrdaApp::Scene::EditRenameDone);
consumed = true;
}
diff --git a/applications/irda/scene/irda-app-scene-edit.cpp b/applications/irda/scene/irda-app-scene-edit.cpp
index cd8a84fc..0ecb8d9e 100644
--- a/applications/irda/scene/irda-app-scene-edit.cpp
+++ b/applications/irda/scene/irda-app-scene-edit.cpp
@@ -1,4 +1,5 @@
#include "../irda-app.hpp"
+#include "gui/modules/submenu.h"
typedef enum {
SubmenuIndexAddKey,
@@ -27,6 +28,8 @@ void IrdaAppSceneEdit::on_enter(IrdaApp* 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(IrdaAppViewManager::ViewType::Submenu);
}
@@ -35,8 +38,10 @@ bool IrdaAppSceneEdit::on_event(IrdaApp* app, IrdaAppEvent* event) {
bool consumed = false;
if(event->type == IrdaAppEvent::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(IrdaApp::Scene::Learn);
break;
case SubmenuIndexRenameKey:
diff --git a/applications/irda/scene/irda-app-scene-learn-enter-name.cpp b/applications/irda/scene/irda-app-scene-learn-enter-name.cpp
index 49b581d1..590902ff 100644
--- a/applications/irda/scene/irda-app-scene-learn-enter-name.cpp
+++ b/applications/irda/scene/irda-app-scene-learn-enter-name.cpp
@@ -35,14 +35,21 @@ bool IrdaAppSceneLearnEnterName::on_event(IrdaApp* app, IrdaAppEvent* event) {
if(event->type == IrdaAppEvent::Type::TextEditDone) {
auto remote_manager = app->get_remote_manager();
auto receiver = app->get_receiver();
+ bool result = false;
if(app->get_learn_new_remote()) {
- remote_manager->add_remote_with_button(
+ result = remote_manager->add_remote_with_button(
app->get_text_store(0), receiver->get_last_message());
} else {
- remote_manager->add_button(app->get_text_store(0), receiver->get_last_message());
+ result =
+ remote_manager->add_button(app->get_text_store(0), receiver->get_last_message());
}
- app->switch_to_next_scene_without_saving(IrdaApp::Scene::LearnDone);
+ if(!result) {
+ app->search_and_switch_to_previous_scene(
+ {IrdaApp::Scene::Start, IrdaApp::Scene::RemoteList});
+ } else {
+ app->switch_to_next_scene_without_saving(IrdaApp::Scene::LearnDone);
+ }
}
return consumed;
}
diff --git a/applications/irda/scene/irda-app-scene-learn-success.cpp b/applications/irda/scene/irda-app-scene-learn-success.cpp
index 12a7f9ad..b4037d78 100644
--- a/applications/irda/scene/irda-app-scene-learn-success.cpp
+++ b/applications/irda/scene/irda-app-scene-learn-success.cpp
@@ -17,6 +17,8 @@ void IrdaAppSceneLearnSuccess::on_enter(IrdaApp* app) {
IrdaAppViewManager* view_manager = app->get_view_manager();
DialogEx* dialog_ex = view_manager->get_dialog_ex();
+ app->notify_green_on();
+
auto receiver = app->get_receiver();
auto message = receiver->get_last_message();
@@ -32,6 +34,7 @@ void IrdaAppSceneLearnSuccess::on_enter(IrdaApp* app) {
dialog_ex_set_text(dialog_ex, app->get_text_store(1), 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_DolphinExcited_64x63);
dialog_ex_set_result_callback(dialog_ex, dialog_result_callback);
dialog_ex_set_context(dialog_ex, app);
@@ -47,11 +50,20 @@ bool IrdaAppSceneLearnSuccess::on_event(IrdaApp* app, IrdaAppEvent* event) {
case DialogExResultLeft:
app->switch_to_next_scene_without_saving(IrdaApp::Scene::Learn);
break;
- case DialogExResultCenter:
- furi_assert(0);
+ case DialogExResultCenter: {
+ app->notify_space_blink();
+ auto receiver = app->get_receiver();
+ auto message = receiver->get_last_message();
+ irda_send(message, 1);
break;
+ }
case DialogExResultRight:
- app->switch_to_next_scene(IrdaApp::Scene::LearnEnterName);
+ auto remote_manager = app->get_remote_manager();
+ if(remote_manager->check_fs()) {
+ app->switch_to_next_scene(IrdaApp::Scene::LearnEnterName);
+ } else {
+ app->switch_to_previous_scene();
+ }
break;
}
}
@@ -60,4 +72,8 @@ bool IrdaAppSceneLearnSuccess::on_event(IrdaApp* app, IrdaAppEvent* event) {
}
void IrdaAppSceneLearnSuccess::on_exit(IrdaApp* app) {
+ IrdaAppViewManager* view_manager = app->get_view_manager();
+ DialogEx* dialog_ex = view_manager->get_dialog_ex();
+ dialog_ex_set_center_button_text(dialog_ex, nullptr);
+ app->notify_green_off();
}
diff --git a/applications/irda/scene/irda-app-scene-learn.cpp b/applications/irda/scene/irda-app-scene-learn.cpp
index 993575bb..c551706a 100644
--- a/applications/irda/scene/irda-app-scene-learn.cpp
+++ b/applications/irda/scene/irda-app-scene-learn.cpp
@@ -14,13 +14,22 @@ void IrdaAppSceneLearn::on_enter(IrdaApp* app) {
popup, "Point the remote at IR port\nand push the button", 5, 10, AlignLeft, AlignCenter);
popup_set_callback(popup, NULL);
+ if(app->get_learn_new_remote()) {
+ app->notify_double_vibro();
+ }
+
view_manager->switch_to(IrdaAppViewManager::ViewType::Popup);
}
bool IrdaAppSceneLearn::on_event(IrdaApp* app, IrdaAppEvent* event) {
bool consumed = false;
+ if(event->type == IrdaAppEvent::Type::Tick) {
+ consumed = true;
+ app->notify_red_blink();
+ }
if(event->type == IrdaAppEvent::Type::IrdaMessageReceived) {
+ app->notify_success();
app->switch_to_next_scene_without_saving(IrdaApp::Scene::LearnSuccess);
}
diff --git a/applications/irda/scene/irda-app-scene-remote-list.cpp b/applications/irda/scene/irda-app-scene-remote-list.cpp
index 51afcb48..aacc537f 100644
--- a/applications/irda/scene/irda-app-scene-remote-list.cpp
+++ b/applications/irda/scene/irda-app-scene-remote-list.cpp
@@ -20,13 +20,26 @@ void IrdaAppSceneRemoteList::on_enter(IrdaApp* app) {
auto remote_manager = app->get_remote_manager();
int i = 0;
- remote_names = remote_manager->get_remote_list();
- for(auto& a : remote_names) {
- submenu_add_item(submenu, a.c_str(), i++, submenu_callback, app);
+ bool result = remote_manager->get_remote_list(remote_names);
+ if(!result) {
+ app->switch_to_previous_scene();
+ return;
+ }
+
+ for(auto& name : remote_names) {
+ submenu_add_item(submenu, name.c_str(), i++, submenu_callback, app);
}
submenu_add_item(
submenu, " +", SubmenuIndexPlus, submenu_callback, app);
+ if((SubmenuIndex)submenu_item_selected == SubmenuIndexPlus) {
+ submenu_set_selected_item(submenu, submenu_item_selected);
+ } else {
+ int remote_index = remote_manager->find_remote_name(remote_names);
+ submenu_set_selected_item(submenu, (remote_index >= 0) ? remote_index : 0);
+ }
+
+ submenu_item_selected = 0;
view_manager->switch_to(IrdaAppViewManager::ViewType::Submenu);
}
@@ -38,11 +51,14 @@ bool IrdaAppSceneRemoteList::on_event(IrdaApp* app, IrdaAppEvent* event) {
case SubmenuIndexPlus:
app->set_learn_new_remote(true);
app->switch_to_next_scene(IrdaApp::Scene::Learn);
+ submenu_item_selected = event->payload.menu_index;
break;
default:
auto remote_manager = app->get_remote_manager();
- remote_manager->set_current_remote(event->payload.menu_index);
- app->switch_to_next_scene(IrdaApp::Scene::Remote);
+ bool result = remote_manager->load(remote_names.at(event->payload.menu_index));
+ if(result) {
+ app->switch_to_next_scene(IrdaApp::Scene::Remote);
+ }
consumed = true;
break;
}
diff --git a/applications/irda/scene/irda-app-scene-remote.cpp b/applications/irda/scene/irda-app-scene-remote.cpp
index ba65ead0..ac33fcad 100644
--- a/applications/irda/scene/irda-app-scene-remote.cpp
+++ b/applications/irda/scene/irda-app-scene-remote.cpp
@@ -4,6 +4,7 @@
typedef enum {
ButtonIndexPlus = -2,
ButtonIndexEdit = -1,
+ ButtonIndexNA = 0,
} ButtonIndex;
static void button_menu_callback(void* context, int32_t index) {
@@ -35,8 +36,12 @@ void IrdaAppSceneRemote::on_enter(IrdaApp* app) {
button_menu_add_item(
button_menu, "Edit", ButtonIndexEdit, button_menu_callback, ButtonMenuItemTypeControl, app);
- app->set_text_store(0, "%s", remote_manager->get_current_remote_name().c_str());
+ 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(IrdaAppViewManager::ViewType::ButtonMenu);
}
@@ -46,12 +51,18 @@ bool IrdaAppSceneRemote::on_event(IrdaApp* app, IrdaAppEvent* event) {
if(event->type == IrdaAppEvent::Type::MenuSelected) {
switch(event->payload.menu_index) {
case ButtonIndexPlus:
+ app->notify_click();
+ buttonmenu_item_selected = event->payload.menu_index;
+ app->set_learn_new_remote(false);
app->switch_to_next_scene(IrdaApp::Scene::Learn);
break;
case ButtonIndexEdit:
+ app->notify_click();
+ buttonmenu_item_selected = event->payload.menu_index;
app->switch_to_next_scene(IrdaApp::Scene::Edit);
break;
default:
+ app->notify_click_and_blink();
auto remote_manager = app->get_remote_manager();
auto message = remote_manager->get_button_data(event->payload.menu_index);
app->get_receiver()->send_message(message);
diff --git a/applications/irda/scene/irda-app-scene-start.cpp b/applications/irda/scene/irda-app-scene-start.cpp
index 7efb6ccb..27f40ad3 100644
--- a/applications/irda/scene/irda-app-scene-start.cpp
+++ b/applications/irda/scene/irda-app-scene-start.cpp
@@ -25,6 +25,8 @@ void IrdaAppSceneStart::on_enter(IrdaApp* 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(IrdaAppViewManager::ViewType::Submenu);
}
@@ -33,6 +35,7 @@ bool IrdaAppSceneStart::on_event(IrdaApp* app, IrdaAppEvent* event) {
bool consumed = false;
if(event->type == IrdaAppEvent::Type::MenuSelected) {
+ submenu_item_selected = event->payload.menu_index;
switch(event->payload.menu_index) {
case SubmenuIndexUniversalLibrary:
app->switch_to_next_scene(IrdaApp::Scene::Universal);
@@ -44,6 +47,9 @@ bool IrdaAppSceneStart::on_event(IrdaApp* app, IrdaAppEvent* event) {
case SubmenuIndexSavedRemotes:
app->switch_to_next_scene(IrdaApp::Scene::RemoteList);
break;
+ default:
+ furi_assert(0);
+ break;
}
consumed = true;
}
diff --git a/applications/irda/scene/irda-app-scene-universal.cpp b/applications/irda/scene/irda-app-scene-universal.cpp
index 2ab4ae2e..949f995b 100644
--- a/applications/irda/scene/irda-app-scene-universal.cpp
+++ b/applications/irda/scene/irda-app-scene-universal.cpp
@@ -24,6 +24,8 @@ void IrdaAppSceneUniversal::on_enter(IrdaApp* app) {
submenu_add_item(submenu, "Audio Players", SubmenuIndexUniversalAudio, submenu_callback, app);
submenu_add_item(
submenu, "Air Conditioners", SubmenuIndexUniversalAirConditioner, submenu_callback, app);
+ submenu_set_selected_item(submenu, submenu_item_selected);
+ submenu_item_selected = 0;
view_manager->switch_to(IrdaAppViewManager::ViewType::Submenu);
}
@@ -32,6 +34,7 @@ bool IrdaAppSceneUniversal::on_event(IrdaApp* app, IrdaAppEvent* event) {
bool consumed = false;
if(event->type == IrdaAppEvent::Type::MenuSelected) {
+ submenu_item_selected = event->payload.menu_index;
switch(event->payload.menu_index) {
case SubmenuIndexUniversalTV:
// app->switch_to_next_scene(IrdaApp::Scene::UniversalTV);
diff --git a/applications/irda/scene/irda-app-scene.hpp b/applications/irda/scene/irda-app-scene.hpp
index 832e4bc0..b21d435a 100644
--- a/applications/irda/scene/irda-app-scene.hpp
+++ b/applications/irda/scene/irda-app-scene.hpp
@@ -23,6 +23,8 @@ public:
void on_enter(IrdaApp* app) final;
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
void on_exit(IrdaApp* app) final;
+private:
+ uint32_t submenu_item_selected = 0;
};
class IrdaAppSceneUniversal : public IrdaAppScene {
@@ -30,6 +32,8 @@ public:
void on_enter(IrdaApp* app) final;
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
void on_exit(IrdaApp* app) final;
+private:
+ uint32_t submenu_item_selected = 0;
};
class IrdaAppSceneLearn : public IrdaAppScene {
@@ -74,6 +78,7 @@ public:
void on_exit(IrdaApp* app) final;
private:
std::vector<std::string> buttons_names;
+ uint32_t buttonmenu_item_selected = 0;
};
class IrdaAppSceneRemoteList : public IrdaAppScene {
@@ -81,6 +86,8 @@ public:
void on_enter(IrdaApp* app) final;
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
void on_exit(IrdaApp* app) final;
+private:
+ uint32_t submenu_item_selected = 0;
std::vector<std::string> remote_names;
};
@@ -89,6 +96,8 @@ public:
void on_enter(IrdaApp* app) final;
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
void on_exit(IrdaApp* app) final;
+private:
+ uint32_t submenu_item_selected = 0;
};
class IrdaAppSceneEditKeySelect : public IrdaAppScene {