Automatic Control Clipping
[platform/core/uifw/dali-toolkit.git] / docs / content / shared-javascript-and-cpp-documentation / creating-custom-controls.md
index 946b4f0..54a0220 100644 (file)
@@ -13,13 +13,26 @@ Custom controls are created using the [handle/body idiom](@ref handle-body-idiom
 ![ ](../assets/img/creating-custom-controls/control-handle-body.png)
 ![ ](creating-custom-controls/control-handle-body.png)
  
+Namespaces are important
++ The handle & body classes should have the same name but in different namespaces
++ TypeRegistry relies on this convention
++ Here our custom control requires
+  + MyControl
+  + Internal::MyControl
 ### General Guidelines:
 + Try to avoid adding C++ APIs as they become difficult to maintain.
   + Use **properties** as much as possible as Controls should be data driven.
   + These controls will be used through JavaScript and JSON files so need to be compatible.
-+ Bear in mind that the Control is required to update when the properties change, not just the first time they are set (to deal with style change).
++ Bear in mind that the Control can be updated when the properties change (e.g. style change)
+  + Ensure control deals with these property changes gracefully
+  + Not just the first time they are set
++ Use Visuals rather than creating several child Actors
+  + DALi rendering pipeline more efficient
 + Accessibility actions should be considered when designing the Control.
 + Consider using signals if the application needs to be react to changes in the control state.
++ Use of Gestures should be preferred over analysing raw touch events
++ Check if you need to chain up to base class if overriding certain methods
  
 ___________________________________________________________________________________________________
 
@@ -28,7 +41,7 @@ ________________________________________________________________________________
 To render content, the required actors can be created and added to the control itself as its children.
 However, this solution is not fully optimised and means extra actors will be added, and thus, need to be processed by DALi.
  
-Controls should be as generic as possible so the recommendation is to re-use control renderers to create the content required as described in the [Control Renderers](@ref control-renderers) section.
+Controls should be as generic as possible so the recommendation is to re-use visuals to create the content required as described in the [Visuals](@ref visuals) section.
 Currently, this is devel-api though, so is subject to change.
  
 ![ ](../assets/img/creating-custom-controls/rendering.png)
@@ -76,6 +89,8 @@ The TypeRegistry is used to register your custom control.
 This allows the creation of the control via a JSON file, as well as registering properties, signals and actions.
  
 To ensure your control is stylable, the process described in [Type Registration](@ref type-registration) should be followed.
+
+#### Properties
 To aid development, some macros are provided for registering properties which are described in the [Property](@ref properties) section.
  
 Control properties can be one of three types:
@@ -125,7 +140,8 @@ This should be overridden by the custom ui control.
 // C++
 void MyUIControlImpl::OnInitialize()
 {
-  // Create renderers, register events etc.
+  // Create visuals using the VisualFactory, register events etc.
+  // Register any created visuals with Control base class
 }
 ~~~
 ___________________________________________________________________________________________________
@@ -134,13 +150,14 @@ ________________________________________________________________________________
 
 Dali::Toolkit::Internal::Control provides several behaviours which are specified through its constructor (@ref Dali::Toolkit::Internal::Control::Control()).
  
-| Behaviour                            | Description                                                             |
-|--------------------------------------|-------------------------------------------------------------------------|
-| ACTOR_BEHAVIOUR_NONE                 | No behaviour required.                                                  |
-| REQUIRES_HOVER_EVENTS                | If our control requires [hover events](@ref creating-controls-events).  |
-| REQUIRES_WHEEL_EVENTS                | If our control requires [wheel events](@ref creating-controls-events).  |
-| REQUIRES_STYLE_CHANGE_SIGNALS        | True if need to monitor style change signals such as Theme/Font change. |
-| REQUIRES_KEYBOARD_NAVIGATION_SUPPORT | True if need to support keyboard navigation.                            |
+| Behaviour                            | Description                                                                                                    |
+|--------------------------------------|----------------------------------------------------------------------------------------------------------------|
+| CONTROL_BEHAVIOUR_DEFAULT              | Default behavior (size negotiation is on, style change is monitored, event callbacks are not called.                                      |
+| DISABLE_SIZE_NEGOTIATION             | If our control does not need size negotiation, i.e. control will be skipped by the size negotiation algorithm. |
+| REQUIRES_HOVER_EVENTS                | If our control requires [hover events](@ref creating-controls-events).                                         |
+| REQUIRES_WHEEL_EVENTS                | If our control requires [wheel events](@ref creating-controls-events).                                         |
+| DISABLE_STYLE_CHANGE_SIGNALS         | True if control should not monitor style change signals such as Theme/Font change.                                         |
+| REQUIRES_KEYBOARD_NAVIGATION_SUPPORT | True if need to support keyboard navigation.                                                                   |
 ___________________________________________________________________________________________________
 
 ### Touch, Hover & Wheel Events {#creating-controls-events}
@@ -149,7 +166,7 @@ ________________________________________________________________________________
 + A **hover event** is when a pointer moves within the bounds of a custom actor (e.g. mouse pointer or hover pointer).
 + A **wheel event** is when the mouse wheel (or similar) is moved while hovering over an actor (via a mouse pointer or hover pointer).
  
-If the control needs to utilise hover and wheel events, then the correct behaviour flag should be used when constructing the control and then the appropriate method should be overridden.
+If the control needs to utilize hover and wheel events, then the correct behaviour flag should be used when constructing the control and then the appropriate method should be overridden.
 ~~~{.cpp}
 // C++
 bool MyUIControlImpl::OnHoverEvent( const HoverEvent& event )
@@ -324,10 +341,10 @@ An up call to the Control class is necessary if these methods are overridden.
 // C++
 void MyUIControlImpl::OnChildAdd( Actor& child );
 {
-  // Up call to Control first
-  Control::OnChildAdd( child );
-
   // Do any other operations required upon child addition
+
+  // Up call to Control at the end
+  Control::OnChildAdd( child );
 }
 ~~~
 ~~~{.cpp}
@@ -354,10 +371,10 @@ An up call to the Control class is necessary if these methods are overridden.
 // C++
 void MyUIControlImpl::OnStageConnection( int depth )
 {
-  // Up call to Control first
-  Control::OnStageConnection( depth );
-
   // Do any other operations required upon stage connection
+
+  // Up call to Control at the end
+  Control::OnStageConnection( depth );
 }
 ~~~
 ~~~{.cpp}
@@ -373,31 +390,74 @@ void MyUIControlImpl::OnStageDisconnection()
  
 ___________________________________________________________________________________________________
 
-### Size {#creating-controls-size}
+### Size Negotiation {#creating-controls-size-negotiation}
 
-Methods are provided that can be overridden if notification is required when our control's size is manipulated.
-An up call to the Control class is necessary if these methods are overridden.
+The following methods must be overridden for size negotiation to work correctly with a custom control.
  
 ~~~{.cpp}
 // C++
-void MyUIControlImpl::OnSizeSet( const Vector3& targetSize )
+Vector3 MyUIControlImpl::GetNaturalSize()
+{
+  // Return the natural size of the control
+  // This depends on our layout
+  // If we have one visual, then we can return the natural size of that
+  // If we have more visuals, then we need to calculate their positions within our control and work out the overall size we would like our control to be
+
+  // After working out the natural size of visuals that belong to this control,
+  // should also chain up to ensure other visuals belonging to the base class are
+  // also taken into account:
+  Vector2 baseSize = Control::GetNaturalSize(); // returns the size of the background.
+}
+~~~
+~~~{.cpp}
+// C++
+float MyUIControlImpl::GetHeightForWidth( float width )
 {
-  // Up call to Control
-  Control::OnSizeSet( targetSize );
+  // Called by the size negotiation algorithm if we have a fixed width
+  // We should calculate the height we would like our control to be for that width
+
+  // Should also chain up to determine the base class's preferred height:
+  float baseHeight = Control::GetHeightForWidth( width );
 
-  // Do any other operations required upon size set
 }
 ~~~
 ~~~{.cpp}
 // C++
-void MyUIControlImpl::OnSizeAnimation( Animation& animation, const Vector3& targetSize )
+float MyUIControlImpl::GetWidthForHeight( float height )
 {
-  // Up call to Control
-  Control::OnSizeAnimation( animation, targetSize );
+  // Called by the size negotiation algorithm if we have a fixed height
+  // We should calculate the width we would like our control to be for that height
 
-  // Do any other operations required upon size animation
+  // Should also chain up to determine the base class's preferred width:
+  float baseWidth = Control::GetWidth( height );
 }
 ~~~
+~~~{.cpp}
+// C++
+void MyUIControlImpl::OnRelayout( const Vector2& size, RelayoutContainer& container )
+{
+  // The size is what we have been given and what our control needs to fit into
+  // Here, we need to set the position and the size of our visuals
+  // If we have other controls/actors as children
+  //  - Add the control/actor to the container paired with the size required
+  //  - To ensure this works, you need to set up the control with a relayout policy of USE_ASSIGNED_SIZE
+  //  - DO NOT CALL SetSize on this control: This will trigger another size negotiation calculation
+  // DO NOT chain up to base class.
+}
+~~~
+More information on size negotiation can be found [here](@ref size-negotiation-controls).
+___________________________________________________________________________________________________
+
+### Clipping Support {#creating-controls-clipping}
+
+When an Actor is set to clip its children, the renderers have to be added manually in order to specify what its children need to clip to.
+The Control base class automates the creation of the renderers/visuals when it is set to clip its children.
+This is only done if the application or custom control writer has not added any renderers to the Control or registered any visuals
+(regardless of whether these visuals are enabled or not).
+If custom control writers want to define the clipping visuals themselves, then they should register all required visuals before the control is staged.
  
 ___________________________________________________________________________________________________