Fork of Tangara with customizations
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
tangara-fw/src/tangara/input/feedback_tts.cpp

103 lines
2.3 KiB

/*
* Copyright 2024 jacqueline <me@jacqueline.id.au>
*
* SPDX-License-Identifier: GPL-3.0-only
*/
#include "input/feedback_tts.hpp"
#include <cstdint>
#include <variant>
#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<std::string> {
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