[AT-SPI] Add Selection interface
[platform/core/uifw/dali-adaptor.git] / dali / internal / accessibility / bridge / accessible.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19
20 //INTERNAL INCLUDES
21 #include <dali/internal/accessibility/bridge/accessibility-common.h>
22 #include <third-party/libunibreak/linebreak.h>
23 #include <third-party/libunibreak/wordbreak.h>
24
25 using namespace Dali::Accessibility;
26
27 std::vector<std::string> Accessible::GetInterfaces()
28 {
29   std::vector<std::string> tmp;
30   tmp.push_back(AtspiDbusInterfaceAccessible);
31   if(dynamic_cast<Collection*>(this))
32   {
33     tmp.push_back(AtspiDbusInterfaceCollection);
34   }
35   if(dynamic_cast<Text*>(this))
36   {
37     tmp.push_back(AtspiDbusInterfaceText);
38   }
39   if(dynamic_cast<EditableText*>(this))
40   {
41     tmp.push_back(AtspiDbusInterfaceEditableText);
42   }
43   if(dynamic_cast<Value*>(this))
44   {
45     tmp.push_back(AtspiDbusInterfaceValue);
46   }
47   if(dynamic_cast<Component*>(this))
48   {
49     tmp.push_back(AtspiDbusInterfaceComponent);
50   }
51   if(auto d = dynamic_cast<Action*>(this))
52   {
53     if(d->GetActionCount() > 0)
54     {
55       tmp.push_back(AtspiDbusInterfaceAction);
56     }
57   }
58   if(dynamic_cast<Selection*>(this))
59   {
60     tmp.push_back(AtspiDbusInterfaceSelection);
61   }
62   return tmp;
63 }
64
65 Accessible::Accessible()
66 {
67 }
68
69 Accessible::~Accessible()
70 {
71   auto b = bridgeData.lock();
72   if(b)
73     b->knownObjects.erase(this);
74 }
75
76 void Accessible::EmitActiveDescendantChanged(Accessible* obj, Accessible* child)
77 {
78   if(auto b = GetBridgeData())
79   {
80     b->bridge->EmitActiveDescendantChanged(obj, child);
81   }
82 }
83
84 void Accessible::EmitStateChanged(State state, int newValue1, int newValue2)
85 {
86   if(auto b = GetBridgeData())
87   {
88     b->bridge->EmitStateChanged(this, state, newValue1, newValue2);
89   }
90 }
91
92 void Accessible::EmitShowing(bool showing)
93 {
94   if(auto b = GetBridgeData())
95   {
96     b->bridge->EmitStateChanged(this, State::SHOWING, showing ? 1 : 0, 0);
97   }
98 }
99
100 void Accessible::EmitVisible(bool visible)
101 {
102   if(auto b = GetBridgeData())
103   {
104     b->bridge->EmitStateChanged(this, State::VISIBLE, visible ? 1 : 0, 0);
105   }
106 }
107
108 void Accessible::EmitHighlighted(bool set)
109 {
110   if(auto b = GetBridgeData())
111   {
112     b->bridge->EmitStateChanged(this, State::HIGHLIGHTED, set ? 1 : 0, 0);
113   }
114 }
115
116 void Accessible::EmitFocused(bool set)
117 {
118   if(auto b = GetBridgeData())
119   {
120     b->bridge->EmitStateChanged(this, State::FOCUSED, set ? 1 : 0, 0);
121   }
122 }
123 void Accessible::EmitTextInserted(unsigned int position, unsigned int length, const std::string& content)
124 {
125   if(auto b = GetBridgeData())
126   {
127     b->bridge->EmitTextChanged(this, TextChangedState::INSERTED, position, length, content);
128   }
129 }
130 void Accessible::EmitTextDeleted(unsigned int position, unsigned int length, const std::string& content)
131 {
132   if(auto b = GetBridgeData())
133   {
134     b->bridge->EmitTextChanged(this, TextChangedState::DELETED, position, length, content);
135   }
136 }
137 void Accessible::EmitTextCaretMoved(unsigned int cursorPosition)
138 {
139   if(auto b = GetBridgeData())
140   {
141     b->bridge->EmitCaretMoved(this, cursorPosition);
142   }
143 }
144 void Accessible::Emit(WindowEvent we, unsigned int detail1)
145 {
146   if(auto b = GetBridgeData())
147   {
148     b->bridge->Emit(this, we, detail1);
149   }
150 }
151 void Accessible::Emit(ObjectPropertyChangeEvent ev)
152 {
153   if(auto b = GetBridgeData())
154   {
155     b->bridge->Emit(this, ev);
156   }
157 }
158
159 void Accessible::EmitBoundsChanged(Rect<> rect)
160 {
161   if(auto b = GetBridgeData())
162   {
163     b->bridge->EmitBoundsChanged(this, rect);
164   }
165 }
166
167 std::vector<Accessible*> Accessible::GetChildren()
168 {
169   std::vector<Accessible*> tmp(GetChildCount());
170   for(auto i = 0u; i < tmp.size(); ++i)
171   {
172     tmp[i] = GetChildAtIndex(i);
173   }
174   return tmp;
175 }
176
177 std::shared_ptr<Bridge::Data> Accessible::GetBridgeData()
178 {
179   auto b = bridgeData.lock();
180   if(!b)
181   {
182     auto p = Bridge::GetCurrentBridge();
183     b      = p->data;
184   }
185   return b;
186 }
187
188 Address Accessible::GetAddress()
189 {
190   auto b = bridgeData.lock();
191   if(!b)
192   {
193     b = GetBridgeData();
194     if(b)
195       b->bridge->RegisterOnBridge(this);
196   }
197   std::ostringstream tmp;
198   tmp << this;
199   return {b ? b->busName : "", tmp.str()};
200 }
201
202 void Bridge::RegisterOnBridge(Accessible* obj)
203 {
204   assert(!obj->bridgeData.lock() || obj->bridgeData.lock() == data);
205   if(!obj->bridgeData.lock())
206   {
207     assert(data);
208     data->knownObjects.insert(obj);
209     obj->bridgeData = data;
210   }
211 }
212
213 bool Accessible::IsProxy()
214 {
215   return false;
216 }
217
218 Accessible* Accessible::GetDefaultLabel()
219 {
220   return this;
221 }
222
223 void Accessible::NotifyAccessibilityStateChange(Dali::Accessibility::States states, bool doRecursive)
224 {
225   if(auto b = GetBridgeData())
226   {
227     auto s = GetStates() & states;
228     for(auto i = 0u; i < s.size(); i++)
229     {
230       auto index = static_cast<Dali::Accessibility::State>(i);
231       if(s[index])
232         b->bridge->EmitStateChanged(this, index, 1, 0);
233     }
234     if(doRecursive)
235     {
236       auto children = GetChildren();
237       for(auto c : children)
238         c->NotifyAccessibilityStateChange(states, doRecursive);
239     }
240   }
241 }
242
243 void Accessible::FindWordSeparationsUtf8(const utf8_t* s, size_t length, const char* language, char* breaks)
244 {
245   set_wordbreaks_utf8(s, length, language, breaks);
246 }
247
248 void Accessible::FindLineSeparationsUtf8(const utf8_t* s, size_t length, const char* language, char* breaks)
249 {
250   set_linebreaks_utf8(s, length, language, breaks);
251 }