#include "infrared_app.h" #include #include #include #include #include #include int32_t InfraredApp::run(void* args) { InfraredAppEvent event; bool consumed; bool exit = false; if(args) { std::string path = static_cast(args); std::string remote_name(path, path.find_last_of('/') + 1, path.size()); remote_name.erase(remote_name.find_last_of('.')); path.erase(path.find_last_of('/')); bool result = remote_manager.load(path, remote_name); if(result) { current_scene = InfraredApp::Scene::Remote; } else { printf("Failed to load remote \'%s\'\r\n", remote_name.c_str()); return -1; } } scenes[current_scene]->on_enter(this); while(!exit) { view_manager.receive_event(&event); if(event.type == InfraredAppEvent::Type::Exit) break; consumed = scenes[current_scene]->on_event(this, &event); if(!consumed) { if(event.type == InfraredAppEvent::Type::Back) { exit = switch_to_previous_scene(); } } }; scenes[current_scene]->on_exit(this); return 0; }; InfraredApp::InfraredApp() { furi_check(InfraredAppRemoteManager::max_button_name_length < get_text_store_size()); notification = static_cast(furi_record_open("notification")); infrared_worker = infrared_worker_alloc(); } InfraredApp::~InfraredApp() { infrared_worker_free(infrared_worker); furi_record_close("notification"); for(auto& [key, scene] : scenes) delete scene; } InfraredAppViewManager* InfraredApp::get_view_manager() { return &view_manager; } void InfraredApp::set_learn_new_remote(bool value) { learn_new_remote = value; } bool InfraredApp::get_learn_new_remote() { return learn_new_remote; } void InfraredApp::switch_to_next_scene(Scene next_scene) { previous_scenes_list.push_front(current_scene); switch_to_next_scene_without_saving(next_scene); } void InfraredApp::switch_to_next_scene_without_saving(Scene next_scene) { if(next_scene != Scene::Exit) { scenes[current_scene]->on_exit(this); current_scene = next_scene; scenes[current_scene]->on_enter(this); view_manager.clear_events(); } } void InfraredApp::search_and_switch_to_previous_scene( const std::initializer_list& scenes_list) { Scene previous_scene = Scene::Start; bool scene_found = false; while(!scene_found) { previous_scene = get_previous_scene(); if(previous_scene == Scene::Exit) break; for(Scene element : scenes_list) { if(previous_scene == element) { scene_found = true; break; } } } if(previous_scene == Scene::Exit) { InfraredAppEvent event; event.type = InfraredAppEvent::Type::Exit; view_manager.send_event(&event); } else { scenes[current_scene]->on_exit(this); current_scene = previous_scene; scenes[current_scene]->on_enter(this); view_manager.clear_events(); } } bool InfraredApp::switch_to_previous_scene(uint8_t count) { Scene previous_scene = Scene::Start; for(uint8_t i = 0; i < count; i++) previous_scene = get_previous_scene(); if(previous_scene == Scene::Exit) return true; scenes[current_scene]->on_exit(this); current_scene = previous_scene; scenes[current_scene]->on_enter(this); view_manager.clear_events(); return false; } InfraredApp::Scene InfraredApp::get_previous_scene() { Scene scene = Scene::Exit; if(!previous_scenes_list.empty()) { scene = previous_scenes_list.front(); previous_scenes_list.pop_front(); } return scene; } InfraredAppRemoteManager* InfraredApp::get_remote_manager() { return &remote_manager; } void InfraredApp::set_text_store(uint8_t index, const char* text...) { furi_check(index < text_store_max); va_list args; va_start(args, text); vsnprintf(text_store[index], text_store_size, text, args); va_end(args); } char* InfraredApp::get_text_store(uint8_t index) { furi_check(index < text_store_max); return text_store[index]; } uint8_t InfraredApp::get_text_store_size() { return text_store_size; } void InfraredApp::text_input_callback(void* context) { InfraredApp* app = static_cast(context); InfraredAppEvent event; event.type = InfraredAppEvent::Type::TextEditDone; app->get_view_manager()->send_event(&event); } void InfraredApp::popup_callback(void* context) { InfraredApp* app = static_cast(context); InfraredAppEvent event; event.type = InfraredAppEvent::Type::PopupTimer; app->get_view_manager()->send_event(&event); } void InfraredApp::set_edit_element(InfraredApp::EditElement value) { element = value; } InfraredApp::EditElement InfraredApp::get_edit_element(void) { return element; } void InfraredApp::set_edit_action(InfraredApp::EditAction value) { action = value; } InfraredApp::EditAction InfraredApp::get_edit_action(void) { return action; } void InfraredApp::set_current_button(int value) { current_button = value; } int InfraredApp::get_current_button() { return current_button; } void InfraredApp::notify_success() { notification_message(notification, &sequence_success); } void InfraredApp::notify_red_blink() { notification_message(notification, &sequence_blink_red_10); } void InfraredApp::notify_click() { static const NotificationSequence sequence = { &message_click, &message_delay_1, &message_sound_off, NULL, }; notification_message_block(notification, &sequence); } void InfraredApp::notify_click_and_green_blink() { static const NotificationSequence sequence = { &message_click, &message_delay_1, &message_sound_off, &message_green_255, &message_delay_10, &message_green_0, &message_do_not_reset, NULL, }; notification_message_block(notification, &sequence); } void InfraredApp::notify_blink_green() { static const NotificationSequence sequence = { &message_green_255, &message_delay_10, &message_green_0, &message_do_not_reset, NULL, }; notification_message(notification, &sequence); } void InfraredApp::notify_green_on() { notification_message(notification, &sequence_set_only_green_255); } void InfraredApp::notify_green_off() { notification_message(notification, &sequence_reset_green); } InfraredWorker* InfraredApp::get_infrared_worker() { return infrared_worker; } const InfraredAppSignal& InfraredApp::get_received_signal() const { return received_signal; } void InfraredApp::set_received_signal(const InfraredAppSignal& signal) { received_signal = signal; } void InfraredApp::signal_sent_callback(void* context) { InfraredApp* app = static_cast(context); app->notify_blink_green(); }