[dali_2.3.24] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / public-api / object / handle.h
1 #ifndef DALI_HANDLE_H
2 #define DALI_HANDLE_H
3
4 /*
5  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <cstdint> // uint32_t
23 #include <string>
24
25 // INTERNAL INCLUDES
26 #include <dali/public-api/common/dali-common.h>
27 #include <dali/public-api/object/base-handle.h>
28 #include <dali/public-api/object/indirect-value.h>
29 #include <dali/public-api/object/property-key.h>
30 #include <dali/public-api/object/property-notification-declarations.h>
31 #include <dali/public-api/object/property-types.h>
32 #include <dali/public-api/object/property-value.h>
33 #include <dali/public-api/object/ref-object.h>
34 #include <dali/public-api/signals/dali-signal.h>
35
36 namespace Dali
37 {
38 /**
39  * @addtogroup dali_core_object
40  * @{
41  */
42
43 class Constraint;
44 class PropertyNotification;
45 class PropertyCondition;
46
47 namespace Internal DALI_INTERNAL
48 {
49 class Object;
50 }
51
52 /**
53  * @brief Dali::Handle is a handle to an internal property owning Dali object that can have constraints applied to it.
54  * @SINCE_1_0.0
55  */
56 class DALI_CORE_API Handle : public BaseHandle
57 {
58 public:
59   /**
60    * @brief Enumeration for Handle's capabilities that can be queried using Handle::Supports().
61    * @SINCE_1_0.0
62    */
63   enum Capability
64   {
65     /**
66      * @brief Some objects support dynamic property creation at run-time.
67      *
68      * New properties are registered by calling RegisterProperty() with an unused property name.
69      * @SINCE_1_0.0
70      */
71     DYNAMIC_PROPERTIES = 0x01,
72   };
73
74   /**
75    * @brief PropertySetSignal function prototype for signal handler. Called when a property is set on this object.
76    */
77   using PropertySetSignalType = Signal<void(Handle& handle, Property::Index index, const Property::Value& value)>;
78
79 public:
80   /**
81    * @brief This constructor is used by Dali New() methods.
82    *
83    * @SINCE_1_0.0
84    * @param[in] handle A pointer to a newly allocated Dali resource
85    */
86   Handle(Dali::Internal::Object* handle);
87
88   /**
89    * @brief This constructor provides an uninitialized Dali::Handle.
90    *
91    * This should be initialized with a Dali New() method before use.
92    * Methods called on an uninitialized Dali::Handle will assert.
93    * @code
94    * Handle handle; // uninitialized
95    * handle.SomeMethod(); // unsafe! This will assert
96    *
97    * handle = SomeClass::New(); // now initialized
98    * handle.SomeMethod(); // safe
99    * @endcode
100    * @SINCE_1_0.0
101    */
102   Handle();
103
104   /**
105    * @brief Creates a new object.
106    *
107    * @SINCE_1_0.0
108    * @return A handle to a newly allocated object
109    */
110   static Handle New();
111
112   /**
113    * @brief Template to create a derived handle and set properties on it.
114    *
115    * Marked as DALI_NO_EXPORT_API to prevent internal usage exporting symbols.
116    * @SINCE_1_9.27
117    * @tparam T The derived class to create
118    * @param[in] properties The properties to set
119    */
120   template<typename Type>
121   static DALI_NO_EXPORT_API Type New(const Property::Map& properties)
122   {
123     Type handle = Type::New();
124     handle.SetProperties(properties);
125     return handle;
126   }
127
128   /**
129    * @brief Dali::Handle is intended as a base class.
130    *
131    * This is non-virtual since derived Handle types must not contain data or virtual methods.
132    * @SINCE_1_0.0
133    */
134   ~Handle();
135
136   /**
137    * @brief This copy constructor is required for (smart) pointer semantics.
138    *
139    * @SINCE_1_0.0
140    * @param[in] handle A reference to the copied handle
141    */
142   Handle(const Handle& handle);
143
144   /**
145    * @brief This assignment operator is required for (smart) pointer semantics.
146    *
147    * @SINCE_1_0.0
148    * @param[in] rhs A reference to the copied handle
149    * @return A reference to this
150    */
151   Handle& operator=(const Handle& rhs);
152
153   /**
154    * @brief Move constructor.
155    *
156    * @SINCE_1_9.22
157    * @param[in] rhs A reference to the moved handle
158    */
159   Handle(Handle&& rhs) noexcept;
160
161   /**
162    * @brief Move assignment operator.
163    *
164    * @SINCE_1_9.22
165    * @param[in] rhs A reference to the moved handle
166    * @return A reference to this handle
167    */
168   Handle& operator=(Handle&& rhs) noexcept;
169
170   /**
171    * @brief Downcasts to a handle.
172    *
173    * If not, the returned handle is left uninitialized.
174    * @SINCE_1_0.0
175    * @param[in] handle to An object
176    * @return handle or an uninitialized handle
177    */
178   static Handle DownCast(BaseHandle handle);
179
180   /**
181    * @brief Queries whether an handle supports a given capability.
182    *
183    * @SINCE_1_0.0
184    * @param[in] capability The queried capability
185    * @return True if the capability is supported
186    */
187   bool Supports(Capability capability) const;
188
189   // Properties
190
191   /**
192    * @brief Queries how many properties are provided by an handle.
193    *
194    * This may vary between instances of a class, if dynamic properties are supported.
195    * @SINCE_1_0.0
196    * @return The number of properties
197    */
198   uint32_t GetPropertyCount() const;
199
200   /**
201    * @brief Queries the name of a property.
202    *
203    * @SINCE_1_0.0
204    * @param[in] index The index of the property
205    * @return The name of the property
206    */
207   std::string GetPropertyName(Property::Index index) const;
208
209   /**
210    * @brief Query the index of a property using the given key.
211    *
212    * @SINCE_1_9.27
213    * @param[in] key The key of the property to search for. (The name or integer key provided to
214    * RegisterProperty()).
215    * @return the matching property index of the key, or Property::INVALID_INDEX if no
216    * property matches the given key.
217    */
218   Property::Index GetPropertyIndex(Property::Key key) const;
219
220   /**
221    * @brief Queries whether a property can be set using SetProperty().
222    *
223    * @SINCE_1_0.0
224    * @param[in] index The index of the property
225    * @return True if the property is writable
226    * @pre Property::INVALID_INDEX < index.
227    */
228   bool IsPropertyWritable(Property::Index index) const;
229
230   /**
231    * @brief Queries whether a writable property can be the target of an animation or constraint.
232    *
233    * @SINCE_1_0.0
234    * @param[in] index The index of the property
235    * @return True if the property is animatable
236    */
237   bool IsPropertyAnimatable(Property::Index index) const;
238
239   /**
240    * @brief Queries whether a property can be used as in input to a constraint.
241    *
242    * @SINCE_1_0.0
243    * @param[in] index The index of the property
244    * @return True if the property can be used as a constraint input
245    */
246   bool IsPropertyAConstraintInput(Property::Index index) const;
247
248   /**
249    * @brief Queries the type of a property.
250    *
251    * @SINCE_1_0.0
252    * @param[in] index The index of the property
253    * @return The type of the property
254    */
255   Property::Type GetPropertyType(Property::Index index) const;
256
257   /**
258    * @brief Sets the value of an existing property.
259    *
260    * Property should be write-able. Setting a read-only property is a no-op.
261    * @SINCE_1_0.0
262    * @param[in] index The index of the property
263    * @param[in] propertyValue The new value of the property
264    * @pre The property types match i.e. propertyValue.GetType() is equal to GetPropertyType(index).
265    */
266   void SetProperty(Property::Index index, Property::Value propertyValue);
267
268   /**
269    * @brief Reserves a number of custom properties
270    *
271    * Saves automatic re-allocation of vectors for properties when we know in advance how many there
272    * will be.
273    *
274    * @param[in] propertyCount The total number of initial properties.
275    */
276   void ReserveCustomProperties(int propertyCount);
277
278   /**
279    * @brief Registers a new animatable property.
280    *
281    * @SINCE_1_0.0
282    * @param[in] name The name of the property
283    * @param[in] propertyValue The new value of the property
284    * @return The index of the property or Property::INVALID_INDEX if registration failed
285    * @pre The object supports dynamic properties i.e. Supports(Handle::DYNAMIC_PROPERTIES) returns true.
286    * Property names are expected to be unique, but this is not enforced.
287    * Property indices are unique to each registered custom property in a given object.
288    * returns Property::INVALID_INDEX if registration failed. This can happen if you try to register
289    * animatable property on an object that does not have scene graph object.
290    * @note Only the following types can be animated:
291    *       - Property::BOOLEAN
292    *       - Property::FLOAT
293    *       - Property::INTEGER
294    *       - Property::VECTOR2
295    *       - Property::VECTOR3
296    *       - Property::VECTOR4
297    *       - Property::MATRIX3
298    *       - Property::MATRIX
299    *       - Property::ROTATION
300    * @note If a property with the desired name already exists, then the value given is just set.
301    */
302   Property::Index RegisterProperty(std::string_view name, Property::Value propertyValue);
303
304   /**
305    * @brief Registers a new animatable property.
306    *
307    * @SINCE_2_1.6
308    * @param[in] name The name of the property
309    * @param[in] propertyValue The new value of the property
310    * @return The index of the property or Property::INVALID_INDEX if registration failed
311    * @pre The object supports dynamic properties i.e. Supports(Handle::DYNAMIC_PROPERTIES) returns true.
312    * Property names are expected to be unique, but this is DEFINITELY not enforced. It is up to the
313    * caller to enforce uniqueness.
314    *
315    * Property indices are unique to each registered custom property in a given object.
316    * returns Property::INVALID_INDEX if registration failed. This can happen if you try to register
317    * animatable property on an object that does not have scene graph object.
318    * @note Only the following types can be animated:
319    *       - Property::BOOLEAN
320    *       - Property::FLOAT
321    *       - Property::INTEGER
322    *       - Property::VECTOR2
323    *       - Property::VECTOR3
324    *       - Property::VECTOR4
325    *       - Property::MATRIX3
326    *       - Property::MATRIX
327    *       - Property::ROTATION
328    * @note If a property with the desired name already exists, then this creates a secondary
329    * entry to a different scene graph property; Access by index works as expected, but uniform
330    * values will use the last registered version, not the existing version, so things may break.
331    */
332   Property::Index RegisterUniqueProperty(std::string_view name, Property::Value propertyValue);
333
334   /**
335    * @brief Register a new animatable property with an integer key.
336    *
337    * @SINCE_1_9.27
338    * @param[in] key  The integer key of the property.
339    * @param[in] name The text key of the property.
340    * @param[in] propertyValue The new value of the property.
341    *
342    * @return The index of the property or Property::INVALID_INDEX if registration failed
343    *
344    * @pre The object supports dynamic properties
345    * i.e. Supports(Handle::DYNAMIC_PROPERTIES) returns true.  Property names and keys
346    * are expected to be unique, but this is not enforced.  Property indices are unique
347    * to each registered custom property in a given object.
348    * @todo CHECK THIS!
349    *
350    * @note Returns Property::INVALID_INDEX if registration failed. This can happen if
351    * you try to register animatable property on an object that does not have scene graph
352    * object.
353    *
354    * @note The returned property index is not the same as the integer key (though it
355    * shares a type)
356    *
357    * This version of RegisterProperty associates both an integer key and the text key
358    * with the property, allowing for lookup of the property index by either key or name
359    * ( which is useful when other classes know the key but not the name )
360    *
361    * @note Only the following types can be animated:
362    *       - Property::BOOLEAN
363    *       - Property::FLOAT
364    *       - Property::INTEGER
365    *       - Property::VECTOR2
366    *       - Property::VECTOR3
367    *       - Property::VECTOR4
368    *       - Property::MATRIX3
369    *       - Property::MATRIX
370    *       - Property::ROTATION
371    * @note If a property with the desired name already exists, then the value given is just set.
372    */
373   Property::Index RegisterProperty(Property::Index  key,
374                                    std::string_view name,
375                                    Property::Value  propertyValue);
376
377   /**
378    * @brief Register a new animatable property with an integer key.
379    *
380    * @SINCE_2_1.6
381    * @param[in] key  The integer key of the property.
382    * @param[in] name The text key of the property.
383    * @param[in] propertyValue The new value of the property.
384    *
385    * @return The index of the property or Property::INVALID_INDEX if registration failed
386    * It is up to the caller to guarantee that the property is unique. This allows many
387    * checks to be skipped.
388    *
389    * @pre The object supports dynamic properties
390    * i.e. Supports(Handle::DYNAMIC_PROPERTIES) returns true.  Property names and keys
391    * are expected to be unique, and are therefore just added without any checks.
392    * Property indices are unique to each registered custom property in a given object.
393    *
394    * @note Returns Property::INVALID_INDEX if registration failed. This can happen if
395    * you try to register animatable property on an object that does not have scene graph
396    * object.
397    *
398    * @note The returned property index is not the same as the integer key (though it
399    * shares a type)
400    *
401    * This version of RegisterProperty associates both an integer key and the text key
402    * with the property, allowing for lookup of the property index by either key or name
403    * ( which is useful when other classes know the key but not the name )
404    *
405    * @note Only the following types can be animated:
406    *       - Property::BOOLEAN
407    *       - Property::FLOAT
408    *       - Property::INTEGER
409    *       - Property::VECTOR2
410    *       - Property::VECTOR3
411    *       - Property::VECTOR4
412    *       - Property::MATRIX3
413    *       - Property::MATRIX
414    *       - Property::ROTATION
415    *
416    * @note If a property with the desired name already exists, then this will create a second entry with
417    * the same name, and may cause problems. It is up to the caller to prevent this happening. Possible side
418    * effects are: lookup by name always finds the first such property, not the second; whereas, writing
419    * uniform value to shader will use the second, not the first;
420    * Using the returned Property::Index for future reference will always access the correct property.
421    */
422   Property::Index RegisterUniqueProperty(Property::Index  key,
423                                          std::string_view name,
424                                          Property::Value  propertyValue);
425
426   /**
427    * @brief Registers a new property.
428    *
429    * Properties can be set as non animatable using property attributes.
430    * @SINCE_1_0.0
431    * @param[in] name The name of the property
432    * @param[in] propertyValue The new value of the property
433    * @param[in] accessMode The property access mode (writable, animatable etc)
434    * @return The index of the property
435    * @pre The handle supports dynamic properties i.e. Supports(Handle::DYNAMIC_PROPERTIES) returns true.
436    * @pre name is unused i.e. GetPropertyIndex(name) returns PropertyIndex::INVALID.
437    * @note Only the following types can be animated:
438    *       - Property::BOOLEAN
439    *       - Property::FLOAT
440    *       - Property::INTEGER
441    *       - Property::VECTOR2
442    *       - Property::VECTOR3
443    *       - Property::VECTOR4
444    *       - Property::MATRIX3
445    *       - Property::MATRIX
446    *       - Property::ROTATION
447    * @note If a property with the desired name already exists, then the value given is just set.
448    */
449   Property::Index RegisterProperty(std::string_view name, Property::Value propertyValue, Property::AccessMode accessMode);
450
451   /**
452    * @brief Retrieves a property value.
453    *
454    * @SINCE_1_0.0
455    * @param[in] index The index of the property
456    * @return The property value
457    * @note This returns the value set by SetProperty() or the animation target value if it is being animated.
458    * @note To get the current value on the scene-graph, use GetCurrentProperty().
459    */
460   Property::Value GetProperty(Property::Index index) const;
461
462   /**
463    * @brief Convenience function for obtaining a property of a known type.
464    *
465    * @SINCE_1_0.0
466    * @param[in] index The index of the property
467    * @return The property value
468    * @pre The property types match i.e. PropertyTypes::Get<T>() is equal to GetPropertyType(index).
469    * @see GetProperty()
470    */
471   template<typename T>
472   T GetProperty(Property::Index index) const
473   {
474     Property::Value value = GetProperty(index);
475
476     return T(value.Get<T>());
477   }
478
479   /**
480    * @brief Retrieves the latest value of the property from the scene-graph.
481    *
482    * @SINCE_1_2.41
483    * @param[in] index The index of the property
484    * @return The property value
485    * @note This returns the value of the property in the last rendered frame so can be different to that
486    *       set by SetProperty() if the set-message has not been processed by the scene-graph yet.
487    * @note To retrieve the value set by SetProperty(), use GetProperty().
488    */
489   Property::Value GetCurrentProperty(Property::Index index) const;
490
491   /**
492    * @brief Convenience function for obtaining the current value of a property of a known type.
493    *
494    * @SINCE_1_2.41
495    * @param[in] index The index of the property
496    * @return The property value
497    * @pre The property types match i.e. PropertyTypes::Get<T>() is equal to GetPropertyType(index).
498    * @see GetCurrentProperty()
499    */
500   template<typename T>
501   T GetCurrentProperty(Property::Index index) const
502   {
503     Property::Value value = GetCurrentProperty(index);
504
505     return T(value.Get<T>());
506   }
507
508   /**
509    * @brief Sets all the properties in the given property map.
510    *
511    * @SINCE_1_9.27
512    * @param[in] properties The properties to set
513    */
514   void SetProperties(const Property::Map& properties);
515
516   /**
517    * @brief Retrieves all the properties and the values for this object
518    *
519    * @SINCE_1_9.27
520    * @param[out] properties A map which is populated with the index-value pairs
521    *
522    * @note The properties map will be cleared by this method first.
523    */
524   void GetProperties(Property::Map& properties);
525
526   /**
527    * @brief Retrieves all the property indices for this object (including custom properties).
528    *
529    * @SINCE_1_0.0
530    * @param[out] indices A container of property indices for this object
531    * @note The added container is cleared.
532    */
533   void GetPropertyIndices(Property::IndexContainer& indices) const;
534
535   /**
536    * @brief Determine if the custom property index exists on this object without throwing a Dali::Exception.
537    *
538    * @SINCE_1_9.27
539    * @note This does not check default properties.
540    * @param[in] index The index of the property to test for
541    */
542   bool DoesCustomPropertyExist(Property::Index index);
543
544   /**
545    * @brief Adds a property notification to this object.
546    *
547    * @SINCE_1_0.0
548    * @param[in] index The index of the property
549    * @param[in] condition The notification will be triggered when this condition is satisfied
550    * @return A handle to the newly created PropertyNotification
551    */
552   PropertyNotification AddPropertyNotification(Property::Index          index,
553                                                const PropertyCondition& condition);
554
555   /**
556    * @brief Adds a property notification to this object.
557    *
558    * @SINCE_1_0.0
559    * @param[in] index The index of the property
560    * @param[in] componentIndex Index to the component of a complex property such as a Vector
561    * @param[in] condition The notification will be triggered when this condition is satisfied
562    * @return A handle to the newly created PropertyNotification
563    */
564   PropertyNotification AddPropertyNotification(Property::Index          index,
565                                                int                      componentIndex,
566                                                const PropertyCondition& condition);
567
568   /**
569    * @brief Removes a property notification from this object.
570    *
571    * @SINCE_1_0.0
572    * @param[in] propertyNotification The propertyNotification to be removed
573    */
574   void RemovePropertyNotification(Dali::PropertyNotification propertyNotification);
575
576   /**
577    * @brief Removes all property notifications from this object.
578    * @SINCE_1_0.0
579    */
580   void RemovePropertyNotifications();
581
582   // Constraints
583
584   /**
585    * @brief Removes all constraints from an Object.
586    *
587    * @SINCE_1_0.0
588    * @pre The object has been initialized.
589    */
590   void RemoveConstraints();
591
592   /**
593    * @brief Removes all the constraint from the Object with a matching tag.
594    *
595    * @SINCE_1_0.0
596    * @param[in] tag The tag of the constraints which will be removed
597    * @pre The Object has been initialized.
598    */
599   void RemoveConstraints(uint32_t tag);
600
601   /**
602    * @brief Index operator, using integer lookup.
603    *
604    * Returns an object that can be assigned to or cast from, enabling
605    * the indexed property to be either read or written.
606    *
607    * @param[in] index The index of the property to access.
608    * @return indirect value. Should have shorter scope than the handle
609    */
610   IndirectValue operator[](Property::Index index);
611
612   /**
613    * @brief Index operator, using name lookup.
614    *
615    * Returns an object that can be assigned to or cast from, enabling
616    * the named property to be either read or written.
617    *
618    * @param[in] name The name of the property to access.
619    * @return indirect value. Should have shorter scope than the handle
620    */
621   IndirectValue operator[](const std::string& name);
622
623 public: // Signals
624   /**
625    * @brief Get a signal when a property is set on this object through the API (i.e. not when animating)
626    *
627    * @SINCE_1_9.27
628    * @return The signal to attach a connection to.
629    */
630   PropertySetSignalType& PropertySetSignal();
631 };
632
633 /**
634  * @brief This namespace provides a convenient function to create an object with a custom "weight" property.
635  * @SINCE_1_0.0
636  */
637 namespace WeightObject
638 {
639 DALI_CORE_API extern const Property::Index WEIGHT; ///< name "weight", type FLOAT
640
641 /**
642  * @brief Convenience function to create an object with a custom "weight" property.
643  *
644  * @SINCE_1_0.0
645  * @return A handle to a newly allocated object
646  */
647 DALI_CORE_API Handle New();
648
649 } // namespace WeightObject
650
651 /**
652  * @}
653  */
654 } // namespace Dali
655
656 #endif // DALI_HANDLE_H