[dali_2.3.20] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / control / control-debug.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 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
18 #include <dali-toolkit/internal/controls/control/control-debug.h>
19 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
20 #include <dali-toolkit/public-api/controls/control-impl.h>
21 #include <dali/integration-api/debug.h>
22 #include <dali/public-api/object/property-index-ranges.h>
23 #include <dali/public-api/object/property.h>
24 #include <algorithm>
25 #include <functional>
26 #include <iostream>
27
28 #if defined(DEBUG_ENABLED)
29
30 namespace Dali
31 {
32 namespace Toolkit
33 {
34 namespace Internal
35 {
36 class JsonWriter
37 {
38 public:
39   JsonWriter(Property::Value& value)
40   : mValue(value)
41   {
42   }
43
44   std::string ToString()
45   {
46     std::ostringstream stream;
47     ToStream(stream);
48     return stream.str();
49   }
50
51   void ToStream(std::ostream& stream)
52   {
53     switch(mValue.GetType())
54     {
55       case Dali::Property::BOOLEAN:
56       {
57         auto value = mValue.Get<bool>();
58         stream << ((value) ? "true" : "false");
59         break;
60       }
61       case Dali::Property::FLOAT:
62       {
63         stream << mValue.Get<float>();
64         break;
65       }
66       case Dali::Property::INTEGER:
67       {
68         stream << mValue.Get<int>();
69         break;
70       }
71       case Dali::Property::VECTOR2:
72       {
73         auto vector = mValue.Get<Vector2>();
74         stream << "[" << vector.x << ", " << vector.y << "]";
75         break;
76       }
77       case Dali::Property::VECTOR3:
78       {
79         auto vector = mValue.Get<Vector3>();
80         stream << "[" << vector.x << ", " << vector.y << ", " << vector.z << "]";
81         break;
82       }
83       case Dali::Property::VECTOR4:
84       {
85         auto vector = mValue.Get<Vector4>();
86         stream << "[" << vector.x << ", " << vector.y << ", " << vector.z << ", " << vector.w << "]";
87         break;
88       }
89       case Dali::Property::MATRIX3:
90       {
91         auto matrix = mValue.Get<Matrix3>();
92         stream << "[";
93         for(int i = 0; i < 9; ++i)
94         {
95           if(i > 0)
96             stream << ",";
97           stream << matrix.AsFloat()[i];
98         }
99         stream << "]";
100         break;
101       }
102       case Dali::Property::MATRIX:
103       {
104         auto matrix = mValue.Get<Matrix>();
105         stream << "[";
106         for(int i = 0; i < 16; ++i)
107         {
108           if(i > 0)
109             stream << ",";
110           stream << matrix.AsFloat()[i];
111         }
112         stream << "]";
113         break;
114       }
115       case Dali::Property::RECTANGLE:
116       {
117         auto vector = mValue.Get<Rect<int> >();
118         stream << "[" << vector.x << ", " << vector.y << ", " << vector.width << ", " << vector.height << "]";
119         break;
120       }
121       case Dali::Property::ROTATION:
122       {
123         auto angleAxis = mValue.Get<AngleAxis>();
124         stream << "[ [ " << angleAxis.axis.x << ", " << angleAxis.axis.y << ", " << angleAxis.axis.z << "], "
125                << angleAxis.angle.radian << "]";
126         break;
127       }
128       case Dali::Property::STRING:
129       {
130         stream << '"' << mValue.Get<std::string>() << '"';
131         break;
132       }
133       case Dali::Property::ARRAY:
134       {
135         auto array = mValue.GetArray();
136         stream << "[ ";
137         if(array)
138         {
139           for(Property::Array::SizeType i = 0; i < array->Size(); ++i)
140           {
141             if(i > 0)
142               stream << ", ";
143             auto outValue = JsonWriter(array->GetElementAt(i));
144             stream << outValue.ToString();
145           }
146         }
147         stream << "]";
148         break;
149       }
150       case Dali::Property::MAP:
151       {
152         auto map = mValue.GetMap();
153         stream << "{ ";
154         if(map)
155         {
156           for(Property::Map::SizeType i = 0; i < map->Count(); ++i)
157           {
158             if(i > 0)
159               stream << ", ";
160             auto key      = map->GetKeyAt(i);
161             auto outValue = JsonWriter(map->GetValue(i));
162             stream << '\"' << key << "\":";
163             stream << outValue.ToString();
164           }
165         }
166         stream << "}";
167         break;
168       }
169       case Dali::Property::EXTENTS:
170       {
171         stream << mValue.Get<Extents>();
172         break;
173       }
174       case Dali::Property::NONE:
175       {
176         stream << "undefined type";
177         break;
178       }
179     }
180   }
181
182   Property::Value& mValue;
183 };
184
185 static std::ostream& operator<<(std::ostream& o, JsonWriter& value)
186 {
187   value.ToStream(o);
188   return o;
189 }
190
191 std::ostream& operator<<(std::ostream& o, const RegisteredVisual& registeredVisual)
192 {
193   o << "{\n"
194     << "\"index\":" << registeredVisual.index << ",\n";
195   o << "\"enabled\":" << (registeredVisual.enabled ? "true" : "false") << ",\n";
196   o << "\"pending\":" << (registeredVisual.pending ? "true" : "false") << ",\n";
197
198   Property::Map map;
199   registeredVisual.visual.CreatePropertyMap(map);
200   o << "\"visual\": {\n\"name\":\"" << registeredVisual.visual.GetName() << "\",\n";
201   o << map << "}\n"
202     << "\n}\n";
203   return o;
204 }
205
206 std::ostream& operator<<(std::ostream& o, const RegisteredVisualContainer& visualContainer)
207 {
208   o << "[\n";
209
210   bool first = true;
211   for(auto&& elem : visualContainer)
212   {
213     if(!first)
214     {
215       o << ",";
216     }
217     first = false;
218
219     o << *elem << "\n";
220   }
221   o << "]\n";
222   return o;
223 }
224
225 std::ostream& DumpProperty(std::ostream& o, Property::Index index, Handle handle)
226 {
227   auto propertyValue     = handle.GetProperty(index);
228   auto jsonPropertyValue = JsonWriter(propertyValue);
229
230   o << "{\n";
231   o << "\"index\":" << index << ",\n";
232   o << "\"name\":\"" << handle.GetPropertyName(index) << "\",\n";
233   o << "\"value\":" << jsonPropertyValue << "\n";
234   o << "}";
235   return o;
236 }
237
238 std::ostream& DumpPropertiesWithPredicate(std::ostream& o, Dali::Handle handle, Property::IndexContainer& indices, std::function<bool(int)> predicate)
239 {
240   bool first = true;
241   for(auto index : indices)
242   {
243     if(predicate(index))
244     {
245       if(!first)
246       {
247         o << ",";
248       }
249       o << std::endl;
250       first = false;
251       DumpProperty(o, index, handle);
252     }
253   }
254   return o;
255 }
256
257 std::ostream& DumpProperties(std::ostream& o, Handle handle)
258 {
259   Property::IndexContainer indices;
260   handle.GetPropertyIndices(indices);
261
262   auto childPropertiesP = [](int index) -> bool {
263     return CHILD_PROPERTY_REGISTRATION_START_INDEX <= index && index <= CHILD_PROPERTY_REGISTRATION_MAX_INDEX;
264   };
265   auto propertiesP = [](int index) -> bool {
266     return !(CHILD_PROPERTY_REGISTRATION_START_INDEX <= index && index <= CHILD_PROPERTY_REGISTRATION_MAX_INDEX);
267   };
268
269   o << "\"childProperties\":[\n";
270   DumpPropertiesWithPredicate(o, handle, indices, childPropertiesP);
271   o << std::endl
272     << "]," << std::endl;
273
274   o << "\"Properties\":[\n";
275   DumpPropertiesWithPredicate(o, handle, indices, propertiesP);
276   o << std::endl
277     << "]" << std::endl;
278
279   return o;
280 }
281
282 std::string DumpControl(const Internal::Control& control)
283 {
284   auto& controlData = Internal::Control::Impl::Get(control);
285
286   std::ostringstream oss;
287   oss << "{\n  ";
288   const std::string& name = control.Self().GetProperty<std::string>(Dali::Actor::Property::NAME);
289   if(!name.empty())
290   {
291     oss << "\"name\":\"" << name << "\",\n";
292   }
293   oss << "\"id\":\"" << control.Self().GetProperty<int>(Actor::Property::ID) << "\",\n";
294   oss << "\"registeredVisuals\":\n"
295       << controlData.mVisuals << ",\n";
296   oss << "\"removeVisuals\":\n"
297       << controlData.mRemoveVisuals << ",\n";
298   oss << "\"rendererCount\":" << control.Self().GetRendererCount() << ",\n";
299   oss << "\"properties\":\n{\n";
300   DumpProperties(oss, control.Self()) << "}\n";
301   oss << "}\n";
302   return oss.str();
303 }
304
305 std::string DumpActor(Actor actor)
306 {
307   std::ostringstream oss;
308   oss << "{\n  ";
309   const std::string& name = actor.GetProperty<std::string>(Dali::Actor::Property::NAME);
310   if(!name.empty())
311   {
312     oss << "\"name\":\"" << name << "\",\n";
313   }
314   oss << "\"id\":\"" << actor.GetProperty<int>(Actor::Property::ID) << "\",\n";
315   oss << "\"rendererCount\":" << actor.GetRendererCount() << ",\n";
316   oss << "\"properties\":\n{\n";
317   Toolkit::Internal::DumpProperties(oss, actor) << "}\n";
318   oss << "}\n";
319   return oss.str();
320 }
321
322 void DumpControlHierarchy(std::ostream& o, Actor actor)
323 {
324   auto control = Toolkit::Control::DownCast(actor);
325   o << "{\n";
326   if(control)
327   {
328     o << "\"Control\":" << DumpControl(Toolkit::Internal::GetImplementation(control));
329   }
330   else
331   {
332     o << "\"Actor\":" << DumpActor(actor);
333   }
334   o << ",\n\"children\":[\n";
335   bool first = true;
336   for(auto count = actor.GetChildCount(), i = 0u; i < count; ++i)
337   {
338     if(!first)
339     {
340       o << ",";
341     }
342     first = false;
343     o << "\n";
344     DumpControlHierarchy(o, actor.GetChildAt(i));
345   }
346   o << "]}\n";
347 }
348
349 } // namespace Internal
350 } // namespace Toolkit
351 } // namespace Dali
352
353 #endif