/* * Copyright 2024 jacqueline * * SPDX-License-Identifier: GPL-3.0-only */ #include "input/feedback_tts.hpp" #include #include #include "lvgl/lvgl.h" #include "core/lv_group.h" #include "core/lv_obj.h" #include "core/lv_obj_class.h" #include "core/lv_obj_tree.h" #include "tts/events.hpp" #include "widgets/button/lv_button.h" #include "widgets/label/lv_label.h" #include "widgets/list/lv_list.h" #include "tts/events.hpp" #include "tts/provider.hpp" #include "feedback_tts.hpp" namespace input { TextToSpeech::TextToSpeech(tts::Provider& tts) : tts_(tts), last_obj_(nullptr) {} auto TextToSpeech::feedback(lv_group_t* group, uint8_t event_type) -> void { if (group != last_group_) { last_group_ = group; last_obj_ = nullptr; if (group) { tts_.feed(tts::SimpleEvent::kContextChanged); } } if (group) { lv_obj_t* focused = lv_group_get_focused(group); if (focused == last_obj_) { return; } last_obj_ = focused; if (focused != nullptr) { describe(*focused); } } } auto TextToSpeech::feedback(lv_group_t*, InputEvent event) -> void { return; } auto TextToSpeech::describe(lv_obj_t& obj) -> void { if (lv_obj_check_type(&obj, &lv_button_class) || lv_obj_check_type(&obj, &lv_list_button_class)) { auto desc = findDescription(obj); tts_.feed(tts::SelectionChanged{ .new_selection = tts::SelectionChanged::Selection{ .description = desc, .is_interactive = true, }, }); } else { auto desc = findDescription(obj); tts_.feed(tts::SelectionChanged{ .new_selection = tts::SelectionChanged::Selection{ .description = desc, .is_interactive = false, }, }); } } auto TextToSpeech::findDescription(lv_obj_t& obj) -> std::optional { if (lv_obj_get_child_cnt(&obj) > 0) { for (size_t i = 0; i < lv_obj_get_child_cnt(&obj); i++) { auto res = findDescription(*lv_obj_get_child(&obj, i)); if (res) { return res; } } } if (lv_obj_check_type(&obj, &lv_label_class)) { std::string text = lv_label_get_text(&obj); if (!text.empty()) { return text; } } return {}; } } // namespace input