2 * Copyright 2018 Samsung Electronics Co., Ltd
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "ScreenReaderSettingsPage.hpp"
21 #include "Genlist.hpp"
23 #include "Singleton.hpp"
25 #include "TextToSpeech.hpp"
27 #include "setting-accessibility.h"
31 #include <efl_extension.h>
32 #include <vconf-internal-keys.h>
40 std::string vconf_key;
44 std::vector<VConfCheckData> vConfCheckData = {{"IDS_ST_HEADER_TIME", VCONFKEY_SETAPPL_ACCESSIBILITY_TTS_INDICATOR_INFORMATION_TIME},
45 {"IDS_ST_BODY_DATE", VCONFKEY_SETAPPL_ACCESSIBILITY_TTS_INDICATOR_INFORMATION_DATE},
46 {"IDS_ST_BODY_BATTERY", VCONFKEY_SETAPPL_ACCESSIBILITY_TTS_INDICATOR_INFORMATION_BATTERY},
47 {"IDS_ST_BODY_SIGNAL_STRENGTH", VCONFKEY_SETAPPL_ACCESSIBILITY_TTS_INDICATOR_INFORMATION_SIGNAL_STRENGHT},
48 {"IDS_ST_BODY_BLUETOOTH", VCONFKEY_SETAPPL_ACCESSIBILITY_TTS_INDICATOR_INFORMATION_BLUETOOTH},
49 {"IDS_ST_BODY_MISSED_EVENTS", VCONFKEY_SETAPPL_ACCESSIBILITY_TTS_INDICATOR_INFORMATION_MISSED_EVENTS}};
51 static const size_t POPUP_CONTENT_BASE_SIZE = 120;
54 ScreenReaderSettingsPage::ScreenReaderSettingsPage()
55 : context_(Singleton<AppContext>::instance())
57 auto genlist = Widget::make<Genlist>(context_.navContext_.getNaviframe());
58 genlist->setMode(ELM_LIST_COMPRESS);
59 genlist->setStyle("dialogue");
60 genlist->clear(); // TODO check if necessary
62 DEBUG("Creating items");
64 auto percentage = calculateSpeedPercentage();
65 speechRateItem_ = genlist->appendItem({"type1", "IDS_ST_BODY_SPEECH_RATE", percentage, [this](auto item) { this->createSpeechRatePopup(); }});
67 Singleton<TextToSpeech>::instance().addSpeedChangedCb([item = speechRateItem_](auto val) {
68 DEBUG("Speed changed to (%d)", static_cast<int>(val));
69 item->setDescription(std::to_string(val));
72 auto item = genlist->appendItem({"multiline",
73 "IDS_ACCS_OPT_KEYBOARD_FEEDBACK_TTS",
74 "IDS_ACCS_OPT_ALWAYS_READ_OUT_KEYBOARD_INPUT_TTS",
76 Singleton<VConfInterface>::instance().set(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_KEYBOARD_FEEDBACK, item->getState());
78 GenlistItem::WidgetType::toggle});
79 item->setState(Singleton<VConfInterface>::instance().get(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_KEYBOARD_FEEDBACK, false));
81 item = genlist->appendItem({"type1",
82 "IDS_ACCS_MBODY_READ_OUT_USAGE_HINTS_ABB",
85 Singleton<VConfInterface>::instance().set(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_DESCRIPTION, item->getState());
87 GenlistItem::WidgetType::toggle});
88 item->setState(Singleton<VConfInterface>::instance().get(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_DESCRIPTION, false));
90 item = genlist->appendItem({"type1",
91 "IDS_ACCS_MBODY_VIBRATION_FEEDBACK",
94 Singleton<VConfInterface>::instance().set(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_HAPTIC, item->getState());
96 GenlistItem::WidgetType::toggle});
97 item->setState(Singleton<VConfInterface>::instance().get(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_HAPTIC, false));
99 item = genlist->appendItem({"type1",
100 "IDS_ACCS_MBODY_SOUND_FEEDBACK",
103 Singleton<VConfInterface>::instance().set(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_SOUND_FEEDBACK, item->getState());
105 GenlistItem::WidgetType::toggle});
106 item->setState(Singleton<VConfInterface>::instance().get(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_SOUND_FEEDBACK, false));
108 genlist->appendItem({"type1", "IDS_ACCS_TMBODY_STATUS_BAR_INFORMATION", {}, [this](auto item) { this->mouseUpGendialListCb(); }});
110 genlist->appendItem({"multiline",
112 "IDS_ACCS_SBODY_SELECT_WHICH_INFORMATION_FROM_INDICATORS_SHOWN_ON_THE_STATUS_BAR_WILL_BE_READ_OUT_WHEN_YOU_TRIPLE_"
113 "TAP_THE_SCREEN_WITH_TWO_FINGERS_MSG",
114 [this](auto item) {}});
116 context_.navContext_.getNaviframe()->pushBack("IDS_ST_OPT_SETTINGS", genlist, [this]() {
117 Singleton<TextToSpeech>::instance().clearSpeedChangedCallbacks();
121 void ScreenReaderSettingsPage::mouseUpGendialListCb()
123 auto window = this->context_.navContext_.getWindow();
125 this->popup_ = Widget::make<Popup>(window, "IDS_ACCS_TMBODY_STATUS_BAR_INFORMATION");
126 this->popup_->setAlignment(ELM_NOTIFY_ALIGN_FILL, 1.0);
128 auto removeCb = [p = this->popup_, window]() { window->removeChild(p); };
129 this->popup_->setEextEventCallback(EEXT_CALLBACK_BACK, removeCb);
131 auto box = Widget::make<Box>(this->popup_);
133 auto genlist = Widget::make<Genlist>(box);
134 genlist->setWeightHint(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
135 genlist->setAlignHint(EVAS_HINT_FILL, EVAS_HINT_FILL);
137 for (auto i = 0u; i < vConfCheckData.size(); ++i) {
138 auto screenreaderCheckbox = genlist->appendItem({"type1",
139 vConfCheckData[i].label,
142 vConfCheckData[i].state = item->getState();
144 GenlistItem::WidgetType::toggle});
145 vConfCheckData[i].state = Singleton<VConfInterface>::instance().get(vConfCheckData[i].vconf_key, vConfCheckData[i].state);
146 screenreaderCheckbox->setState(vConfCheckData[i].state);
149 genlist->blockScrolling(Elm_Scroller_Movement_Block(ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL | ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL));
150 genlist->setScrollbarsVisibility(ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
152 box->packEnd(genlist);
154 box->setMinSizeHint(-1, ELM_SCALE_SIZE(POPUP_CONTENT_BASE_SIZE) * vConfCheckData.size());
155 box->setMaxSizeHint(-1, ELM_SCALE_SIZE(POPUP_CONTENT_BASE_SIZE) * vConfCheckData.size());
156 this->popup_->setContent(box);
158 auto btnCancel = Widget::make<Button>(this->popup_, removeCb, "IDS_MSG_ACBUTTON_CANCEL_ABB", "popup");
159 this->popup_->setPartContent("button1", btnCancel);
161 auto onDone = [removeCb]() {
164 for (auto vConfData : vConfCheckData)
165 Singleton<VConfInterface>::instance().set(vConfData.vconf_key, vConfData.state);
168 auto btnDone = Widget::make<Button>(this->popup_, onDone, "IDS_MSG_ACBUTTON_DONE_ABB", "popup");
169 this->popup_->setPartContent("button2", btnDone);
172 void ScreenReaderSettingsPage::createSpeechRatePopup()
174 auto window = context_.navContext_.getWindow();
176 popup_ = Widget::make<Popup>(window, "IDS_ST_BODY_SPEECH_RATE");
177 popup_->setAlignment(ELM_NOTIFY_ALIGN_FILL, 1.0);
179 auto removeCb = [p = popup_, window]() { window->removeChild(p); };
180 popup_->setEextEventCallback(EEXT_CALLBACK_BACK, removeCb);
182 auto layout = Widget::make<Layout>(popup_);
183 layout->setFile(EDJDIR "/screen-reader-settings-popup.edj", "popup_text_slider_view_layout");
184 layout->setPartText("elm.text.description", "IDS_SCR_POP_DRAG_THE_SLIDER_TO_SET_THE_SPEECH_RATE");
185 layout->setWeightHint(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
186 popup_->setContent(layout);
188 auto slider = Widget::make<Slider>(layout);
189 slider->showIndicator(true);
190 slider->setWeightHint(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
191 slider->setAlignHint(EVAS_HINT_FILL, EVAS_HINT_FILL);
192 slider->setIndicatorFormat("%1.0f");
193 slider->setRange(1, 15);
195 auto speed = Singleton<TextToSpeech>::instance().getSpeed();
198 slider->setValue(speed);
199 layout->setPartContent("slider", slider);
201 auto cancelBtn = Widget::make<Button>(popup_, removeCb, "IDS_ST_BUTTON_CANCEL_ABB", "bottom");
202 popup_->setPartContent("button1", cancelBtn);
204 auto doneBtn = Widget::make<Button>(popup_,
205 [p = popup_, window, slider, this]() {
206 auto val = static_cast<size_t>(slider->getValue());
207 Singleton<TextToSpeech>::instance().setSpeed(val);
208 window->removeChild(p);
212 popup_->setPartContent("button2", doneBtn);
214 // TODO: add wrapper to the below function
215 evas_object_event_callback_add(popup_->getObject(), EVAS_CALLBACK_DEL, onPopupDel, this);
218 std::string ScreenReaderSettingsPage::calculateSpeedPercentage()
220 auto speed = Singleton<TextToSpeech>::instance().getSpeed();
221 auto speedRange = Singleton<TextToSpeech>::instance().getSpeedRange();
223 auto denominator = speedRange.max - speedRange.min;
224 auto speedPercent = 0.0;
225 if (denominator != 0)
226 speedPercent = (static_cast<double>(speed - speedRange.min) / denominator) * 100;
228 DEBUG("TTS rate is %.0f", speedPercent);
229 return std::to_string(std::lround(speedPercent));
232 void ScreenReaderSettingsPage::onPopupDel(void *data, Evas *e, Evas_Object *obj, void *event_info)
234 auto self = static_cast<ScreenReaderSettingsPage *>(data);
235 auto percentage = self->calculateSpeedPercentage();
236 self->speechRateItem_->setDescription(percentage);