X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=docs%2Fcontent%2Fprogramming-guide%2Ftype-registration.h;h=ad7b5a4d32549e42a6ed26e2dce6ba31485e0fed;hp=43fe731cbebe69c8b2550d9be93b7a075aae57a3;hb=6047d364c31f7078c1950b8251e478d5c9b0f0dc;hpb=01864cd4216d958c5f0e95643dbbeca7c9937716 diff --git a/docs/content/programming-guide/type-registration.h b/docs/content/programming-guide/type-registration.h index 43fe731..ad7b5a4 100644 --- a/docs/content/programming-guide/type-registration.h +++ b/docs/content/programming-guide/type-registration.h @@ -6,23 +6,22 @@ DALi has a \link Dali::TypeRegistry type registration \endlink system which can a derived actor/control type along with specifying a method which is used to create this type. This type registration normally takes place at library load time. -Once a type is registered, signals, actions and properties can also be registered for all instances +Once a type is registered, properties, signals and actions can also be registered for all instances of this type. -This then allows the application writer to create instances using just the type name; connect to -signals using only the signal name; activate an action by just using the action name; and finally, -getting and setting properties using a property name or index. +This then allows the application writer to create instances using just the type name; getting and setting properties using a property name or index; connect to +signals using only the signal name; and activate an action by just using the action name. This topic covers: - @ref register-type + - @ref register-property - @ref register-signal - @ref register-action - - @ref register-property - @ref using-type + - @ref using-property - @ref using-signal - @ref using-action - - @ref using-property @section register-type Registering a Type @@ -30,29 +29,259 @@ A type can be registered using Dali::TypeRegistration. This is normally done in within the source file of the deriving control as shown in the code below. Please note: This snippet assumes knowledge of the \link Dali::Toolkit::Control Control -\endlink / \link Dali::Toolkit::ControlImpl ControlImpl \endlink creation process where -MyControl derives from a Control and MyControlImpl derives from ControlImpl. +\endlink / \link Dali::Toolkit::Internal::Control Internal::Control \endlink creation process where +MyControl derives from a Control and MyControlImpl derives from Internal::Control. @code namespace { -Dali::BaseHandle Create() +Dali::BaseHandle CreateMyControl() { // Create an instance of MyControl and return the handle. return MyControlImpl::New(); } -Dali::TypeRegistration type( - typeid( MyControl ), // Type ID of our Control - typeid( Dali::Toolkit::Control ), // Type ID of what our Control derives from - Create // Function which creates our Control, signature shown above -); +DALI_TYPE_REGISTRATION_BEGIN( MyControl, Toolkit::Control, CreateMyControl ); +DALI_TYPE_REGISTRATION_END() } // unnamed namespace @endcode -This registration informs DALi of the existence of MyControl type. +This registration macro informs DALi of the existence of MyControl type, which class it derives from, and a method for creating an instance of MyControl. + + +@section register-property Registering a Property + +DALi has a property system which can be extended by registering more properties through the type +registry. The property index is very important when registering these properties and +all property indices should be between Dali::PROPERTY_REGISTRATION_START_INDEX and +Dali::PROPERTY_REGISTRATION_MAX_INDEX. + +Furthermore, if deriving from a \link Dali::Toolkit::Control Control\endlink, the control +writer needs to be aware of their parent class's property range to avoid overlapping indices, so should start their property indices after their parent's range. +Control reserves a property range between +\link Dali::Toolkit::Control::CONTROL_PROPERTY_START_INDEX Control::CONTROL_PROPERTY_START_INDEX\endlink +and \link Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX Control::CONTROL_PROPERTY_END_INDEX\endlink. + +Any control deriving from \link Dali::Toolkit::Control Control\endlink +should start at +\link Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX Control::CONTROL_PROPERTY_END_INDEX\endlink + 1. +Controls deriving from an existing control such as \link Dali::Toolkit::Button Button\endlink should start at +\link Dali::Toolkit::Button::PROPERTY_END_INDEX Button::PROPERTY_END_INDEX\endlink + 1. + +Please have a look at \ref property-indices for more information. + +The following code shows how a property can be added to a type. + +@code +// Define the indices we will use for the properties: + +class MyControl : public Control +{ + /** + * @brief The start and end property ranges for this control. + */ + enum PropertyRange + { + PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1, + PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000, + + ANIMATABLE_PROPERTY_START_INDEX = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX, + ANIMATABLE_PROPERTY_END_INDEX = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 1000 + }; + + struct Property + { + enum + { + // Event side properties + + /** + * @brief name "propertyOne", type bool + * @details Enables the feature. + * @SINCE_1_0.0 + */ + PROPERTY_ONE = PROPERTY_START_INDEX, + + /** + * @brief name "propertyTwo", type float + * @details Controls the level of the feature + * @SINCE_1_0.0 + */ + PROPERTY_TWO, + + /** + * @brief name "propertyThree", type Vector4 + * @details The foreground color + * @SINCE_1_0.0 + */ + PROPERTY_THREE, + + // Animatable properties + + /** + * @brief name "propertyFour", type Vector4 + * @details Animatable parameters of the feature + * @SINCE_1_0.0 + */ + PROPERTY_FOUR = ANIMATABLE_PROPERTY_START_INDEX, + }; + }; + + /// ... +}; +@endcode + +The control and properties are registered with the TypeRegistry using the following macros: + +@code +DALI_TYPE_REGISTRATION_BEGIN( MyControl, Toolkit::Control, CreateMyControl ); +DALI_PROPERTY_REGISTRATION( AppNamespace, MyControl, "property1", BOOLEAN, PROPERTY_ONE ) +DALI_PROPERTY_REGISTRATION( AppNamespace, MyControl, "property2", FLOAT, PROPERTY_TWO ) +DALI_PROPERTY_REGISTRATION( AppNamespace, MyControl, "property3", VECTOR4, PROPERTY_THREE ) + +DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT( AppNamespace, MyControl, "property4", Vector4(0.f, 0.f, 1.f, 1.f), PROPERTY_FOUR ) + +DALI_TYPE_REGISTRATION_END() +@endcode + +The DALI_PROPERTY_REGISTRATION macro requires that you define the class methods SetProperty() and GetProperty(). + +The DALI_ANIMATABLE_PROPERTY_REGISTRATION macros automatically create and handle scene-graph values, and do not need any code in your derived class. Just use the property index in animation or constraint methods. + +The SetProperty class method has to be static, and follows the format: + +@code +void MyControl::SetProperty( + Dali::BaseObject* object, // A pointer to an instance of MyControl + Dali::Property::Index index, // The index of the property to set + const Dali::Property::Value& value // The value to set the property to +) +{ + // DownCast to MyControl so that we can do the specific behaviour + MyControl control = MyControl::DownCast( Dali::BaseHandle ( object ) ); + + if ( control ) + { + MyControlImpl& controlImpl( GetImplementation( control ) ); + + switch ( index ) + { + case PROPERTY_ONE: + { + // Assume we already have a method in MyControl which sets the appropriate value and takes in a boolean + bool property; + if( value.Get( property ) ) + { + controlImpl.SetPropertyOne( property ); + } + break; + } + + case PROPERTY_TWO + { + // Assume we already have a method in MyControl which sets the appropriate value and takes in a float + float property; + if( value.Get( property ) ) + { + controlImpl.SetPropertyTwo( property ); + } + break; + } + + case PROPERTY_THREE + { + // Assume we already have a method in MyControl which sets the appropriate value and takes in a Vector4 + Vector4 property; + if( value.Get( property ) ) + { + controlImpl.SetPropertyThree( property ); + } + break; + } + } + } +} +@endcode + +And the GetProperty method also has to be static and takes the form: + +@code +Property::Value MyControl::GetProperty( + BaseObject* object, // A pointer to an instance of MyControl + Property::Index index ) // The index of the property to retrieve +{ + Property::Value value; + + // DownCast to MyControl so that we can do the specific behaviour + MyControl control = MyControl::DownCast( Dali::BaseHandle ( object ) ); + + if ( control ) + { + MyControlImpl& controlImpl( GetImplementation( control ) ); + + switch ( index ) + { + case PROPERTY_ONE: + { + // Assume we have a member variable that stores the value of this property + value = controlImpl.mPropertyOne; + break; + } + + case PROPERTY_TWO: + { + // Assume we have a member variable that stores the value of this property + value = controlImpl.mPropertyTwo; + break; + } + + case PROPERTY_THREE: + { + // Assume we have a member variable that stores the value of this property + value = controlImpl.mPropertyThree; + break; + } + } + } +} +@endcode + +@section using-property Setting & Getting Registered Properties + +Like other properties, type registered properties can also be set and their values can be retrieved +in a similar manner. The code below shows how this can be done. + +@code +Dali::TypeInfo type = Dali::TypeRegistry::Get().GetTypeInfo( "MyControl" ); + +if ( type ) +{ + Dali::BaseHandle baseHandle = type.CreateInstance(); + + if ( baseHandle ) + { + // Handle deals with properties, so DownCast + Dali::Handle handle = Dali::Handle::DownCast( baseHandle ); + + if ( handle ) + { + // Setting a property + handle.SetProperty( MyControl::Property::PROPERTY_ONE, 11.0f ); + + // Get the property name + std::cout << "Property1 name is: " << handle.GetPropertyName( MyControl::Property::PROPERTY_ONE ) << std::endl; + + // Get the property + bool propertyOne = handle.GetProperty< bool >( MyControl::Property::PROPERTY_ONE ); + + // Set the second property + handle.SetProperty( MyControl::Property::PROPERTY_TWO, 4.0f ); + } + } +} +@endcode @section register-signal Registering a Signal @@ -184,133 +413,10 @@ bool MyControl::DoAction( } @endcode -@section register-property Registering a Property - -DALi has a property system which can be extended by registering more properties through the type -registry. The property index is very important when registering these properties and -all property indices should be between Dali::PROPERTY_REGISTRATION_START_INDEX and -Dali::PROPERTY_REGISTRATION_MAX_INDEX. - -Furthermore, if deriving from \link Dali::Toolkit::Control Control\endlink, the control writer -needs to be aware of their parent class's property range. Control reserves a property range between -\link Dali::Toolkit::ControlImpl::CONTROL_PROPERTY_START_INDEX ControlImpl::CONTROL_PROPERTY_START_INDEX\endlink -and \link Dali::Toolkit::ControlImpl::CONTROL_PROPERTY_END_INDEX ControlImpl::CONTROL_PROPERTY_END_INDEX\endlink. -Any deriving control should start their property indices from -\link Dali::Toolkit::ControlImpl::CONTROL_PROPERTY_END_INDEX ControlImpl::CONTROL_PROPERTY_END_INDEX\endlink + 1. - -Please have a look at \ref property-indices for more information. - -The following code shows how a property can be added to a type. - -@code -// Define the indices we will use for the properties -static const int PROPERTY_ONE( Dali::Toolkit::ControlImpl::CONTROL_PROPERTY_END_INDEX + 1 ); -static const int PROPERTY_TWO( Dali::Toolkit::ControlImpl::CONTROL_PROPERTY_END_INDEX + 2 ); -static const int PROPERTY_THREE( Dali::Toolkit::ControlImpl::CONTROL_PROPERTY_END_INDEX + 3 ); - -Dali::PropertyRegistration property1( - type, // Reference to type registration object (see above) - "property1", // Name of the property - PROPERTY_ONE, // Index of this property - Dali::Property::BOOLEAN, // The property type - &MyControl::SetProperty, // Method called when property is set - &MyControl::GetProperty // Method called when retrieving the value of the property -); - -// Register more properties -Dali::PropertyRegistration property2( - type, "property2", PROPERTY_TWO, Dali::Property::FLOAT, - NULL, // SetProperty is NULL, means that this property is a read-only property - &MyControl::GetProperty -); -Dali::PropertyRegistration property3( type, "property3", PROPERTY_THREE, Dali::Property::FLOAT, &MyControl::SetProperty, &MyControl::GetProperty); -@endcode - -It is recommended to use static members (of MyControl class) for the property indices. That way -applications can also use the static member as well. If they require the property name, they can -just call the Dali::Handle::GetPropertyName(). +If the action is not performed by the derived class, it will be propagated to the base class. +For example, in the above case, MyControl can perform "action1" so should return true, but it +cannot perform "action4" so should return false and propagate the action to Control. -The method that deals with setting the property has to be static, and follows the format: - -@code -void MyControl::SetProperty( - Dali::BaseObject* object, // A pointer to an instance of MyControl - Dali::Property::Index index, // The index of the property to set - const Dali::Property::Value& value // The value to set the property to -) -{ - // DownCast to MyControl so that we can do the specific behaviour - MyControl control = MyControl::DownCast( Dali::BaseHandle ( object ) ); - - if ( control ) - { - MyControlImpl& controlImpl( GetImplementation( control ) ); - - switch ( index ) - { - case PROPERTY_ONE: - { - // Assume we already have a method in MyControl which sets the appropriate value and takes in a boolean - controlImpl.SetPropertyOne( value.Get< bool >() ); - break; - } - - // PROPERTY_TWO is read-only so does not need to be handled - - case PROPERTY_THREE - { - // Assume we already have a method in MyControl which sets the appropriate value and takes in a float - controlImpl.SetPropertyThree( value.Get< float >() ); - break; - } - } - } -} -@endcode - -And the function to retrieve the property value also has to be static and takes the form: - -@code -Property::Value MyControl::GetProperty( - BaseObject* object, // A pointer to an instance of MyControl - Property::Index index // The index of the property to retrieve -) -{ - Property::Value value; - - // DownCast to MyControl so that we can do the specific behaviour - MyControl control = MyControl::DownCast( Dali::BaseHandle ( object ) ); - - if ( control ) - { - MyControlImpl& controlImpl( GetImplementation( control ) ); - - switch ( index ) - { - case PROPERTY_ONE: - { - // Assume we have a member variable that stores the value of this property - value = controlImpl.mPropertyOne; - break; - } - - case PROPERTY_TWO: - { - // Assume we have a member variable that stores the value of this property - value = controlImpl.mPropertyTwo; - break; - } - - case PROPERTY_THREE: - { - // Assume we have a member variable that stores the value of this property - value = controlImpl.mPropertyThree; - break; - } - } - } -} -@endcode @section using-type Creating an instance of a Registered Type @@ -403,39 +509,5 @@ if ( type ) } @endcode -@section using-property Setting & Getting Registered Properties - -Like other properties, type registered properties can also be set and their values can be retrieved -in a similar manner. The code below shows how this can be done. - -@code -Dali::TypeInfo type = Dali::TypeRegistry::Get().GetTypeInfo( "MyControl" ); - -if ( type ) -{ - Dali::BaseHandle baseHandle = type.CreateInstance(); - - if ( baseHandle ) - { - // Handle deals with properties, so DownCast - Dali::Handle handle = Dali::Handle::DownCast( baseHandle ); - - if ( handle ) - { - // Setting a property - handle.SetProperty( PROPERTY_ONE, true ); // Assume Property indices are publicly accessible - - // Get the property name - std::cout << "Property1 name is: " << handle.GetPropertyName( PROPERTY_ONE ) << std::endl; - - // Get the property - bool propertyOne = handle.GetProperty< bool >( PROPERTY_ONE ); - - // Attempt to write a read-only property... - handle.SetProperty( PROPERTY_TWO, 4.0f ); // !!! Will assert as PROPERTY_TWO is read-only !!! - } - } -} -@endcode * */