(Programming Guide) Initial chapter on creating a custom control 48/59948/8
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 19 Feb 2016 15:53:35 +0000 (15:53 +0000)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Wed, 24 Feb 2016 16:10:00 +0000 (16:10 +0000)
- Update Properties to include Animatable Properties
  - Also updated the examples
- Updated Accessibility
- Added a CMakeLists.txt to the example-code directly to directly build the example code

Change-Id: I8a363e79a13d639b14be6d1d4ae487eea9d35563

13 files changed:
docs/content/example-code/.gitignore [new file with mode: 0644]
docs/content/example-code/CMakeLists.txt [new file with mode: 0644]
docs/content/example-code/images/cards.jpg [new file with mode: 0644]
docs/content/example-code/properties.cpp [new file with mode: 0644]
docs/content/example-code/property-example.cpp [deleted file]
docs/content/images/creating-custom-controls/control-handle-body.png [new file with mode: 0644]
docs/content/images/creating-custom-controls/popup-normal.png [new file with mode: 0644]
docs/content/images/creating-custom-controls/popup-styled.png [new file with mode: 0644]
docs/content/images/creating-custom-controls/rendering.png [new file with mode: 0644]
docs/content/main.md
docs/content/programming-guide/properties.h
docs/content/shared-javascript-and-cpp-documentation/accessibility.md
docs/content/shared-javascript-and-cpp-documentation/creating-custom-controls.md [new file with mode: 0644]

diff --git a/docs/content/example-code/.gitignore b/docs/content/example-code/.gitignore
new file mode 100644 (file)
index 0000000..06994ce
--- /dev/null
@@ -0,0 +1,6 @@
+/CMakeFiles
+/cmake_install.cmake
+/build
+*.example
+/Makefile
+/CMakeCache.txt
diff --git a/docs/content/example-code/CMakeLists.txt b/docs/content/example-code/CMakeLists.txt
new file mode 100644 (file)
index 0000000..133ab59
--- /dev/null
@@ -0,0 +1,22 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+SET(PKG_LIST dali-core
+             dali-adaptor
+             dali-toolkit)
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(REQUIRED_PKGS REQUIRED ${PKG_LIST})
+
+FOREACH(flag ${REQUIRED_PKGS_CFLAGS})
+        SET(REQUIRED_CFLAGS "${REQUIRED_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${REQUIRED_CFLAGS} -Werror -Wall")
+SET(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
+
+FILE(GLOB SRCS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.cpp")
+
+FOREACH(EXAMPLE ${SRCS})
+  STRING(REGEX REPLACE ".cpp" "" EXECUTABLE "${EXAMPLE}")
+  ADD_EXECUTABLE (${EXECUTABLE}.example ${EXAMPLE})
+  TARGET_LINK_LIBRARIES(${EXECUTABLE}.example ${REQUIRED_PKGS_LDFLAGS})
+ENDFOREACH(EXAMPLE)
diff --git a/docs/content/example-code/images/cards.jpg b/docs/content/example-code/images/cards.jpg
new file mode 100644 (file)
index 0000000..11bd590
Binary files /dev/null and b/docs/content/example-code/images/cards.jpg differ
diff --git a/docs/content/example-code/properties.cpp b/docs/content/example-code/properties.cpp
new file mode 100644 (file)
index 0000000..dcbb47f
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/dali.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <sstream>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+namespace
+{
+
+// The name we will use to register our custom property by.
+const char* const TAG_PROPERTY_NAME = "tagIdentifier";
+
+// The image for our image view
+const char* const IMAGE_CARDS = "images/cards.jpg";
+}  // namespace
+
+/**
+ * This example shows how to set properties in C++ and how to register and look-up custom properties.
+ * An image is added to the screen which changes and a custom property is added to the image-view.
+ * This value is incremented every time the image is touched and the text-label is updated.
+ */
+class PropertyController: public ConnectionTracker
+{
+public:
+
+  PropertyController( Application& application )
+  : mTagText(),
+    mTagPropertyIndex( Property::INVALID_INDEX )
+  {
+    // Connect to the Application's Init signal
+    application.InitSignal().Connect( this, &PropertyController::Create );
+  }
+
+  ~PropertyController()
+  {
+  }
+
+  // C++ EXAMPLE
+  void Create( Application& application )
+  {
+    // Get the stage handle
+    Stage stage = Stage::GetCurrent();
+
+    mImageView = ImageView::New();
+
+    // Set the property to move to the center
+    mImageView.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
+
+    // Set another property to set the image-map
+    Property::Map imageMap;
+    imageMap[ "rendererType" ] = "image";
+    imageMap[ "imageUrl" ]     = IMAGE_CARDS;
+    imageMap[ "width" ]        = 100;
+    imageMap[ "height" ]       = 100;
+    mImageView.SetProperty( ImageView::Property::IMAGE, imageMap );
+
+    // Add the image view to the stage
+    stage.Add( mImageView );
+
+    // Register a custom float property on mImageView and use it to store the number of times we are tapped
+    mTagPropertyIndex = mImageView.RegisterProperty( TAG_PROPERTY_NAME, 0, Property::READ_WRITE /* Event-side only, i.e. not animatable */ );
+
+    // Connect to the touch-event
+    mImageView.TouchedSignal().Connect( this, &PropertyController::OnTouched );
+
+    // Create text label
+    mTagText = Toolkit::TextLabel::New( "0" );
+    mTagText.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
+    mTagText.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
+    mTagText.SetProperty( TextLabel::Property::TEXT_COLOR, Color::WHITE );
+    mTagText.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
+    stage.Add( mTagText );
+  }
+
+  /**
+   * Called when the image view is touched
+   * param[in] touch The touch-event
+   * return Set to true if the signal was consumed correctly
+   */
+  bool OnTouched( Actor actor, const TouchEvent& touch )
+  {
+    int touchedCount = 0;
+
+    // Look up the tag property by the cached property index.
+    // Note: If the property belongs to a control in another library, or we do not know the index, we can look the index up first with:
+    // Property::Index index = actor.GetPropertyIndex( TAG_PROPERTY_NAME );
+    actor.GetProperty( mTagPropertyIndex ).Get( touchedCount );
+
+    // Increment and set back again
+    ++touchedCount;
+    actor.SetProperty( mTagPropertyIndex, touchedCount );
+
+    // Set the text in the text-label
+    std::stringstream valueText;
+    valueText << touchedCount;
+    mTagText.SetProperty( TextLabel::Property::TEXT, valueText.str() );
+
+    return true; // Consumed
+  }
+  // C++ EXAMPLE END
+
+private:
+
+  ImageView mImageView;              ///< An image view to show an image
+  TextLabel mTagText;                 ///< A text label used to show the last button pressed.
+  Property::Index mTagPropertyIndex;  ///< A cached property index of our custom tag property.
+};
+
+// Entry point for applications.
+int main( int argc, char **argv )
+{
+  Application application = Application::New( &argc, &argv );
+
+  PropertyController test( application );
+  application.MainLoop();
+
+  return 0;
+}
diff --git a/docs/content/example-code/property-example.cpp b/docs/content/example-code/property-example.cpp
deleted file mode 100644 (file)
index 388385d..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <dali/dali.h>
-#include <dali-toolkit/dali-toolkit.h>
-#include <sstream>
-
-using namespace Dali;
-
-namespace
-{
-
-// The name we will use to register our custom property by.
-const char* const TAG_PROPERTY_NAME = "tagIdentifier";
-
-const char* const PUSHBUTTON_PRESS_IMAGE =  DALI_IMAGE_DIR "button-down.9.png";
-const char* const PUSHBUTTON_BUTTON_IMAGE = DALI_IMAGE_DIR "button-up.9.png";
-
-// Define the grid geometry.
-#define BUTTON_ROWS    9.0f
-#define BUTTON_COLUMNS 7.0f
-#define BUTTON_GAP     10.0f
-
-}  // namespace
-
-/**
- * This example shows how to register and look-up custom properties.
- * A button grid is created, each with a new "tag" property which is set to a unique value.
- * When pressed, the "tag" property is looked up to retrieve the unique value and display it.
- */
-class PropertyButtonsController: public ConnectionTracker
-{
-  public:
-
-  PropertyButtonsController( Application& application )
-  {
-    // Connect to the Application's Init signal
-    application.InitSignal().Connect( this, &PropertyButtonsController::Create );
-  }
-
-  ~PropertyButtonsController()
-  {
-  }
-
-  void Create( Application& application )
-  {
-    // Setup precalculations for button size and start positions.
-    Toolkit::PushButton button;
-    int index = 0;
-    Vector2 stageSize = Stage::GetCurrent().GetSize();
-    float buttonSize = ( stageSize.x - ( BUTTON_GAP * ( BUTTON_COLUMNS + 1 ) ) ) / BUTTON_COLUMNS;
-    float yStart = ( stageSize.y - ( ( buttonSize * BUTTON_ROWS ) + ( BUTTON_GAP * ( BUTTON_ROWS - 1 ) ) ) ) / 2.0f;
-
-    // Create a grid of buttons.
-    for( int y = 0; y < BUTTON_ROWS; ++y )
-    {
-      for( int x = 0; x < BUTTON_COLUMNS; ++x )
-      {
-        // Create a button and position it.
-        button = Toolkit::PushButton::New();
-        button.SetParentOrigin( ParentOrigin::TOP_LEFT );
-        button.SetAnchorPoint( AnchorPoint::TOP_LEFT );
-        button.SetPosition( Vector3( BUTTON_GAP + ( x * ( buttonSize + BUTTON_GAP ) ), yStart + ( y * ( buttonSize + BUTTON_GAP ) ), 0.0f ) );
-        button.SetSize( Vector3( buttonSize, buttonSize, 0) );
-        button.SetSelectedImage( Dali::ResourceImage::New( PUSHBUTTON_PRESS_IMAGE ) );
-        button.SetButtonImage( Dali::ResourceImage::New( PUSHBUTTON_BUTTON_IMAGE ) );
-
-        // Label the button with a unique value.
-        std::stringstream label;
-        label << index;
-        button.SetLabel( label.str() );
-
-        // Register our custom property, and use it to store a unique number.
-        // Store the index to the property so we can look it up later.
-        // Note: This is much faster than looking the property up by name and should always be used if possible.
-        // As all our control types are the same (PushButtons) the indecies to our unique property is the same for each one.
-        Property::Value tag = ( float )index;
-        mTagPropertyIndex = button.RegisterProperty( TAG_PROPERTY_NAME, tag );
-
-        // Hook a callback when the button is clicked.
-        button.ClickedSignal().Connect( this, &PropertyButtonsController::OnButtonClicked );
-
-        // Add the button to the stage.
-        Stage::GetCurrent().Add( button );
-        index++;
-      }
-    }
-
-    // Create the last selected button text view.
-    mTagText = Toolkit::TextLabel::New( "None selected" );
-    mTagText.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
-    mTagText.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
-    mTagText.SetPosition( Vector3( 0.0f, -30.0f, 0.0f ) );
-    Stage::GetCurrent().Add( mTagText );
-  }
-
-  /**
-   * Called when any button within the grid is clicked.
-   * param[in] The clicked button control
-   * return Set to true if the signal was consumed correctly
-   */
-  bool OnButtonClicked( Toolkit::Button button )
-  {
-    std::stringstream valueText;
-    // Look up the tag property by the cached property index.
-    // Note: If the property belongs to a control in another library, or we do not know the index, we can look the index up first with:
-    // Property::Index index = button.GetPropertyIndex( TAG_PROPERTY_NAME );
-    valueText << "Selected: " << button.GetProperty< float >( mTagPropertyIndex );
-
-    mTagText.SetProperty( TextLabel::Property::TEXT, valueText.str() );
-
-    return true;
-  }
-
-  private:
-
-  Toolkit::TextLabel mTagText;        ///< A text label used to show the last button pressed.
-  Property::Index mTagPropertyIndex; ///< A cached property index of our custom tag property.
-};
-
-// Entry point for applications.
-int main( int argc, char **argv )
-{
-  Application application = Application::New( &argc, &argv );
-
-  PropertyButtonsController test( application );
-  application.MainLoop();
-
-  return 0;
-}
diff --git a/docs/content/images/creating-custom-controls/control-handle-body.png b/docs/content/images/creating-custom-controls/control-handle-body.png
new file mode 100644 (file)
index 0000000..4349789
Binary files /dev/null and b/docs/content/images/creating-custom-controls/control-handle-body.png differ
diff --git a/docs/content/images/creating-custom-controls/popup-normal.png b/docs/content/images/creating-custom-controls/popup-normal.png
new file mode 100644 (file)
index 0000000..ce06133
Binary files /dev/null and b/docs/content/images/creating-custom-controls/popup-normal.png differ
diff --git a/docs/content/images/creating-custom-controls/popup-styled.png b/docs/content/images/creating-custom-controls/popup-styled.png
new file mode 100644 (file)
index 0000000..831950a
Binary files /dev/null and b/docs/content/images/creating-custom-controls/popup-styled.png differ
diff --git a/docs/content/images/creating-custom-controls/rendering.png b/docs/content/images/creating-custom-controls/rendering.png
new file mode 100644 (file)
index 0000000..4ec4e1d
Binary files /dev/null and b/docs/content/images/creating-custom-controls/rendering.png differ
index 0b06506..2a9fd0b 100644 (file)
  + [Overview](@ref viewing-modes)
 
 ### Extending DALi
- + Control Base Class Services
- + How to write Custom UI Components
+ + [How to write Custom UI Components](@ref creating-custom-controls)
   + [Size Negotiation for Controls](@ref size-negotiation-controls)
   + [Type Registration](@ref type-registration)
-  + How to make Controls Scriptable
  + [Automated Tests](@ref auto_testing)
  + [Programming Guide](@ref documentationguide)
  + [JavaScript Wrapping Guide for DALi developers](@ref javascriptwrapping)
index b9c87e9..b445a2e 100644 (file)
@@ -26,34 +26,34 @@ There are some pre-defined macros designed to help with and standardise the defi
 
 These macros generate an array of property details which allow efficient lookup of flags like "animatable" or "constraint input".
 
-<b>Example: ImageActor</b>
+<b>Example: Layer</b>
 
-Within the public-api header file; image-actor.h:
+Within the public-api header file; layer.h:
 
 @code
-/**
- * @brief An enumeration of properties belonging to the ImageActor class.
- * Properties additional to Actor.
- */
-struct Property
-{
-  enum
+  /**
+   * @brief An enumeration of properties belonging to the Layer class.
+   *
+   * Properties additional to Actor.
+   */
+  struct Property
   {
-    PIXEL_AREA = DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX, ///< name "pixelArea",   type Rect<int>
-    STYLE,                                                   ///< name "style",       type std::string
-    BORDER,                                                  ///< name "border",      type Vector4
-    IMAGE,                                                   ///< name "image",       type Map {"filename":"", "loadPolicy":...}
+    enum
+    {
+      CLIPPING_ENABLE = DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX, ///< name "clippingEnable",   type bool @SINCE_1_0.0
+      CLIPPING_BOX,                                                 ///< name "clippingBox",      type Rect<int> @SINCE_1_0.0
+      BEHAVIOR,                                                     ///< name "behavior",         type String @SINCE_1_0.0
+    };
   };
-};
 @endcode
-From @ref Dali::ImageActor::Property
+From @ref Dali::Layer::Property
 
 <b>Notes:</b>
 
 - The properties are enumerated within a named struct to give them a namespace.
 - The properties are then refered to as &lt;OBJECT&gt;::%Property::&lt;PROPERTY_NAME&gt;.
 
-Within the internal implementation; <b>image-actor-impl.cpp</b>:
+Within the internal implementation; <b>layer-impl.cpp</b>:
 
 @code
 namespace // Unnamed namespace
@@ -61,12 +61,11 @@ namespace // Unnamed namespace
 
 // Properties
 
-//              Name           Type   writable animatable constraint-input  enum for index-checking
+//              Name                Type      writable animatable constraint-input  enum for index-checking
 DALI_PROPERTY_TABLE_BEGIN
-DALI_PROPERTY( "pixelArea",    RECTANGLE, true,    false,   true,    Dali::ImageActor::Property::PIXEL_AREA )
-DALI_PROPERTY( "style",        STRING,    true,    false,   true,    Dali::ImageActor::Property::STYLE      )
-DALI_PROPERTY( "border",       VECTOR4,   true,    false,   true,    Dali::ImageActor::Property::BORDER     )
-DALI_PROPERTY( "image",        MAP,       true,    false,   false,   Dali::ImageActor::Property::IMAGE      )
+DALI_PROPERTY( "clippingEnable",    BOOLEAN,    true,    false,   true,             Dali::Layer::Property::CLIPPING_ENABLE )
+DALI_PROPERTY( "clippingBox",       RECTANGLE,  true,    false,   true,             Dali::Layer::Property::CLIPPING_BOX    )
+DALI_PROPERTY( "behavior",          STRING,     true,    false,   false,            Dali::Layer::Property::BEHAVIOR        )
 DALI_PROPERTY_TABLE_END( DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX )
 @endcode
 
@@ -82,22 +81,23 @@ DALI_PROPERTY_TABLE_END( DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX )
 <br>
 <h2 class="pg">How to implement a property within Dali-toolkit:</h2>
 
-Note that toolkit properties have extra limitations in that they cannot be animated or used as a constraint input. For this reason there is no requirement for a table of property details.
-Macros are still used to define properties, but for the following reasons:
+Macros are used to define properties for the following reasons:
+
+- To standardise the way properties are defined.
+- To handle type-registering for properties, signals and actions in one place.
+- To facilitate the posibility of running the code with the type-registry disabled.
 
-To standardise the way properties are defined.
-To handle type-registering for properties, signals and actions in one place.
-To facilitate the posibility of running the code with the type-registry disabled.
+Two different macros are provided depending on whether the property is to be an event-side only property or an animatable property.
 
 <b>There are two stages:</b>
 
 - Define the properties as an enum in the public-api header file, along with a definition of the property ranges.
 - Define the property details using the pre-defined macros to perform the type-registering of the properties. This is done for signals and actions also.
 
-<b>Example: Button</b>
+<b>Example: ImageView</b>
 
-Source file: <b>button.h</b>:
-Note that the “PropertyRange” contents “PROPERTY_START_INDEX” is also used by the macro for order checking.
+Source file: <b>image-view.h</b>:
+Note that the “PropertyRange” contents “PROPERTY_START_INDEX” & "ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX" are also used by the macro for order checking.
 
 @code
   /**
@@ -105,8 +105,11 @@ Note that the “PropertyRange” contents “PROPERTY_START_INDEX” is also us
    */
   enum PropertyRange
   {
-    PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
-    PROPERTY_END_INDEX =   PROPERTY_START_INDEX + 1000              ///< Reserve property indices
+    PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,  ///< @SINCE_1_0.0
+    PROPERTY_END_INDEX =   PROPERTY_START_INDEX + 1000,              ///< Reserve property indices @SINCE_1_0.0
+
+    ANIMATABLE_PROPERTY_START_INDEX = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX,        ///< @SINCE_1_1.18
+    ANIMATABLE_PROPERTY_END_INDEX =   ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 1000  ///< Reserve animatable property indices, @SINCE_1_1.18
   };
 
   /**
@@ -116,23 +119,41 @@ Note that the “PropertyRange” contents “PROPERTY_START_INDEX” is also us
   {
     enum
     {
-      DISABLED = PROPERTY_START_INDEX, ///< name "disabled",                     @see SetDisabled(),                  type bool
-      AUTO_REPEATING,                  ///< name "autoRepeating",                @see SetAutoRepeating(),             type bool
-      INITIAL_AUTO_REPEATING_DELAY,    ///< name "initialAutoRepeatingDelay",    @see SetInitialAutoRepeatingDelay(), type float
-      NEXT_AUTO_REPEATING_DELAY,       ///< name "nextAutoRepeatingDelay",       @see SetNextAutoRepeatingDelay(),    type float
-      TOGGLABLE,                       ///< name "togglable",                    @see SetTogglableButton(),           type bool
-      SELECTED,                        ///< name "selected",                     @see SetSelected(),                  type bool
-      NORMAL_STATE_ACTOR,              ///< name "normalStateActor",             @see SetButtonImage(),               type Map
-      SELECTED_STATE_ACTOR,            ///< name "selectedStateActor",           @see SetSelectedImage(),             type Map
-      DISABLED_STATE_ACTOR,            ///< name "disabledStateActor",           @see SetDisabledImage(),             type Map
-      LABEL_ACTOR,                     ///< name "labelActor",                   @see SetLabel(),                     type Map
+      // Event side properties
+
+      /**
+       * @DEPRECATED_1_1.16. Use IMAGE instead.
+       * @brief name "resourceUrl", type string
+       * @SINCE_1_0.0
+       */
+      RESOURCE_URL = PROPERTY_START_INDEX,
+      /**
+       * @brief name "image", type string if it is a url, map otherwise
+       * @SINCE_1_0.0
+       */
+      IMAGE,
+      /**
+       * @brief name "preMultipliedAlpha", type Boolean
+       * @SINCE_1_1.18
+       * @pre image must be initialized.
+       */
+      PRE_MULTIPLIED_ALPHA,
+
+      // Animatable properties
+
+      /**
+       * @brief name "pixelArea", type Vector4
+       * @details Pixel area is a relative value with the whole image area as [0.0, 0.0, 1.0, 1.0].
+       * @SINCE_1_0.18
+       */
+      PIXEL_AREA = ANIMATABLE_PROPERTY_START_INDEX,
     };
   };
 @endcode
 
-Source file: <b>button-impl.cpp</b>, within an unnamed namespace:
+Source file: <b>image-view-impl.cpp</b>, within an unnamed namespace:
 
-@clip{"button-impl.cpp",DALI_TYPE_REGISTRATION_BEGIN,DALI_TYPE_REGISTRATION_END}
+@clip{"image-view-impl.cpp",DALI_TYPE_REGISTRATION_BEGIN,DALI_TYPE_REGISTRATION_END}
 
 <b>Notes:</b>
 
@@ -141,7 +162,6 @@ Source file: <b>button-impl.cpp</b>, within an unnamed namespace:
 - Signals and actions are registered likewise in that order.
 - Properties type-registered using these macros will have their order checked at compile time. If you get an indexing compile error, check the order matches the enum order.
 
-
 <br>
 <hr>
 @section property-indices Property Indices
@@ -158,16 +178,14 @@ There are some predefined start indecies and ranges that should be used for comm
 DALi has a property system and provides several different kinds of properties. The following table
 shows the index range of the different properties in place.
 
-<table>
-  <tr> <td><b>Kind</b></td>     <td><b>Description</b></td>                                                                                <td style="text-align:center;"><b>Start Index</b></td><td><b>End Index</b></td>         </tr>
-  <tr> <td>Default</td>         <td>Properties defined within DALi Core, e.g. Dali::Actor, Dali::ShaderEffect default properties etc.</td> <td style="text-align:center;">\link Dali::DEFAULT_OBJECT_PROPERTY_START_INDEX DEFAULT_OBJECT_PROPERTY_START_INDEX\endlink (0)</td><td>9999999</td>         </tr>
-  <tr> <td>Registered</td>      <td>Properties registered using Dali::PropertyRegistration</td>                                            <td style="text-align:center;">\link Dali::PROPERTY_REGISTRATION_START_INDEX PROPERTY_REGISTRATION_START_INDEX\endlink (10000000)</td><td>\link Dali::PROPERTY_REGISTRATION_MAX_INDEX PROPERTY_REGISTRATION_MAX_INDEX\endlink (19999999)</td> </tr>
-  <tr> <td>Control</td>         <td>Property range reserved by Dali::Toolkit::Control</td>                                                 <td style="text-align:center;">\link Dali::Toolkit::Control::CONTROL_PROPERTY_START_INDEX CONTROL_PROPERTY_START_INDEX\endlink (10000000)</td><td>
-  \link Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX CONTROL_PROPERTY_END_INDEX\endlink (10001000)</td></tr>
-  <tr> <td>Derived Control</td> <td>Property range for control deriving directly from Dali::Toolkit::Control</td>                          <td style="text-align:center;">10001001</td><td>\link Dali::PROPERTY_REGISTRATION_MAX_INDEX PROPERTY_REGISTRATION_MAX_INDEX\endlink (19999999)</td> </tr>
-  <tr> <td>Custom</td>          <td>Custom properties added to instance using Dali::Handle::RegisterProperty</td>                          <td style="text-align:center;">\link Dali::PROPERTY_CUSTOM_START_INDEX PROPERTY_CUSTOM_START_INDEX\endlink (50000000)</td><td>Onwards...</td>     </tr>
-</table>
-
+| Kind                  | Description                                                                                       | Start Index                                                                                                | End Index                                                                                                                          |
+|:----------------------|:--------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|
+| Default               | Properties defined within DALi Core, e.g. Dali::Actor, Dali::ShaderEffect default properties etc. | \link Dali::DEFAULT_OBJECT_PROPERTY_START_INDEX DEFAULT_OBJECT_PROPERTY_START_INDEX\endlink                | \link Dali::DEFAULT_PROPERTY_MAX_COUNT DEFAULT_PROPERTY_MAX_COUNT\endlink (9999999)                                                |
+| Registered            | Properties registered using Dali::PropertyRegistration                                            | \link Dali::PROPERTY_REGISTRATION_START_INDEX PROPERTY_REGISTRATION_START_INDEX\endlink (10000000)         | \link Dali::PROPERTY_REGISTRATION_MAX_INDEX PROPERTY_REGISTRATION_MAX_INDEX\endlink (19999999)                                     |
+| Registered Animatable | Animatable properties registered using Dali::PropertyRegistration                                 | \link Dali::ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX\endlink (20000000) | \link Dali::ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX\endlink (29999999) |
+| Control               | Property range reserved by Dali::Toolkit::Control                                                 | \link Dali::Toolkit::Control::CONTROL_PROPERTY_START_INDEX CONTROL_PROPERTY_START_INDEX\endlink (10000000) | \link Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX CONTROL_PROPERTY_END_INDEX\endlink (10001000)                             |
+| Derived Control       | Property range for control deriving directly from Dali::Toolkit::Control                          | 10001001                                                                                                   | \link Dali::PROPERTY_REGISTRATION_MAX_INDEX PROPERTY_REGISTRATION_MAX_INDEX\endlink (19999999)                                     |
+| Custom                | Custom properties added to instance using Dali::Handle::RegisterProperty                          | \link Dali::PROPERTY_CUSTOM_START_INDEX PROPERTY_CUSTOM_START_INDEX\endlink (50000000)                     | Onwards...                                                                                                                         |
 
 <br>
 <hr>
@@ -180,12 +198,13 @@ An application developer can use an existing property, or, if necessary, registe
 Here is a code example.
 
 This example shows how to register and look-up custom properties.
-A grid of buttons is created, each with a new "tag" property which is set to a unique value. The index to this property is cached for later use.
-When pressed, the property is looked up by index (as this is much faster than a text lookup of the property name).
+An image is added to the screen which changes and a custom property is added to the image-view.
+This value is incremented every time the image is touched and the text-label is updated.
+When touched, the property is looked up by index (as this is much faster than a text lookup of the property name).
 
-Property lookup via index should always be used unless the indecies cannot be known. If the property reader was completely decoupled from the creation, EG. A custom control with a custom property being used by external application code, then it may be necessary. In this case the application writer should aim to perform the text lookup once at start-up, and cache the property index locally.
+Property lookup via index should always be used unless the indicies cannot be known. If the property reader was completely decoupled from the creation, e.g. A custom control with a custom property being used by external application code, then it may be necessary. In this case the application writer should aim to perform the text lookup once at start-up, and cache the property index locally.
 
-@clip{"property-example.cpp", void Create, return true;}
+@clip{"properties.cpp", // C++ EXAMPLE, // C++ EXAMPLE END}
 
 Once run, a grid of buttons will appear. When a button is pressed, the unique number stored in the property (in this case the index) is displayed at the bottom of the screen.
 
@@ -196,18 +215,22 @@ Once run, a grid of buttons will appear. When a button is pressed, the unique nu
 Note that constraints cannot be used within JavaScript, so below is a simple example that sets one of the default properties; scale:
 
 @code
-var image = new dali.ResourceImage( {url:"background.png"} );
-var imageActor = new dali.ImageActor( image );
+var imageView = new dali.Control( "ImageView" );
 
 // by default an actor is anchored to the top-left of it's parent actor
 // change it to the middle
-imageActor.parentOrigin = dali.CENTER;
-
-// scale it up by 2 times  in x,y
-imageActor.scale = [ 2, 2, 1  ];
+imageView.parentOrigin = dali.CENTER;
+
+// Set an image view property
+imageView.image = {
+  "rendererType" : "image",
+  "imageUrl" : "images/icon-0.png",
+  "width" : 100,
+  "height" : 100
+};
 
 // add to the stage
-dali.stage.add( imageActor );
+dali.stage.add( imageView );
 @endcode
 
 For a more detailed example see the ShaderEffect example in the JavaScript documentation.
@@ -220,32 +243,19 @@ This is a basic example of a button defined in JSON by setting the default prope
 
 @code
 {
-  "constants": {
-    "CONFIG_SCRIPT_LOG_LEVEL": "Verbose"
-  },
-  "stage": [
-    // First Button
+  "stage":
+  [
     {
-      "type": "PushButton",
-      "parentOrigin": "TOP_CENTER",
-      "anchorPoint": "TOP_CENTER",
+      "type": "ImageView",
+      "parentOrigin": "CENTER",
+      "anchorPoint": "CENTER",
       "position": [0, 0, 0],
-      "size": [0, 200, 0],
-      "normalStateActor": {
-        "type": "ImageActor",
-        "image": {
-          "filename": "{DALI_IMAGE_DIR}blocks-brick-1.png"
-        }
-      },
-      "selectedStateActor": {
-        "type": "ImageActor",
-        "image": {
-          "filename": "{DALI_IMAGE_DIR}blocks-brick-2.png"
-        }
-      },
-      "labelActor": {
-        "type": "TextLabel",
-        "text": "Normal"
+      "image":
+      {
+        "rendererType" : "image",
+        "imageUrl" : "images/icon-0.png",
+        "width" : 100,
+        "height" : 100
       }
     }
   ]
index 78a54aa..a9fc67c 100644 (file)
@@ -242,16 +242,19 @@ Stage::GetCurrent().Add( table );
 
 ### Using accessibility within a custom control (C++) {#accessibilitycustomcontrol}
 
-As well as the Activation signal, if implementing a custom control from C++ you can use the OnAccessibilityActivate() virtual function.
-  
-Other virtual accessibility methods are available for overriding within control also:
-  
-- virtual bool OnAccessibilityPan( PanGesture gesture );
-- virtual bool OnAccessibilityTouch( const TouchEvent& touchEvent );
-- virtual bool OnAccessibilityValueChange( bool isIncrease ); // (i.e. value change of slider control)
-- virtual bool OnAccessibilityZoom();
-  
-
+Accessibility behaviour can be customized in a custom UI control by overriding all or some of the following methods.
+
+| Method                     | Description                                                                                                                                                                |
+|----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| OnAccessibilityActivated   | When the control is *activated* or selected, in accessibility mode.                                                                                                        |
+| OnAccessibilityPan         | When an accessibility pan gesture occurs while this control is focussed.                                                                                                   |
+| OnAccessibilityTouch       | Touch events are delivered differently in Accessibility mode. This method should be overridden if some special behaviour is required when these touch events are received. |
+| OnAccessibilityValueChange | When a value is changed while this control is focussed (e.g. value change of a slider control).                                                                            |
+| OnAccessibilityZoom        | Should be overridden if behaviour is required when the magnification level changes when this control is focussed.                                                          |
+If these events are consumed, then the method should return true.
+The default behaviour in the control base classes returns false, i.e. not consumed.
 ### Using accessibility signals for extra control {#accessibilitysignals}
 
 For more specific control of functionality when accessibility is enabled, there are several signals within the accessibility manager's public API that can be connected to.
diff --git a/docs/content/shared-javascript-and-cpp-documentation/creating-custom-controls.md b/docs/content/shared-javascript-and-cpp-documentation/creating-custom-controls.md
new file mode 100644 (file)
index 0000000..b40262b
--- /dev/null
@@ -0,0 +1,340 @@
+<!--
+/**-->
+
+[TOC]
+
+# Creating Custom UI Controls {#creating-custom-controls}
+
+DALi provides the ability to create custom UI controls.
+This can be done by extending Dali::Toolkit::Control and Dali::Toolkit::Internal::Control classes.
+Custom controls are created using the [handle/body idiom](@ref handle-body-idiom) used in DALi.
+![ ](../assets/img/creating-custom-controls/control-handle-body.png)
+![ ](creating-custom-controls/control-handle-body.png)
+### 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).
++ 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.
+___________________________________________________________________________________________________
+
+## Rendering Content {#creating-controls-rendering-content}
+
+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.
+Currently, this is devel-api though, so is subject to change.
+![ ](../assets/img/creating-custom-controls/rendering.png)
+![ ](creating-custom-controls/rendering.png)
+___________________________________________________________________________________________________
+
+## Ensuring Control is Stylable {#creating-controls-stylable}
+
+DALi's property system allows custom controls to be easily styled.
+The [JSON Syntax](@ref script-json-specification) is used in the stylesheets:
+**JSON Styling Syntax Example:**
+~~~
+{
+  "styles":
+  {
+    "textfield":
+    {
+      "pointSize":18,
+      "primaryCursorColor":[0.0,0.72,0.9,1.0],
+      "secondaryCursorColor":[0.0,0.72,0.9,1.0],
+      "cursorWidth":1,
+      "selectionHighlightColor":[0.75,0.96,1.0,1.0],
+      "grabHandleImage" : "{DALI_STYLE_IMAGE_DIR}cursor_handler_drop_center.png",
+      "selectionHandleImageLeft" : {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_left.png" },
+      "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" }
+    }
+  }
+}
+~~~
+Styling gives the UI designer the ability to change the look and feel of the control without any code changes.
+| Normal Style | Customized Style |
+|:------------:|:----------------:|
+|![ ](../assets/img/creating-custom-controls/popup-normal.png) ![ ](creating-custom-controls/popup-normal.png) | ![ ](../assets/img/creating-custom-controls/popup-styled.png) ![ ](creating-custom-controls/popup-styled.png)|
+More information regarding styling can be found in the [Styling](@ref styling) section.
+___________________________________________________________________________________________________
+
+### Type Registration {#creating-controls-type-registration}
+
+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.
+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:
+ + **Event-side only:** A function is called to set this property or to retrieve the value of this property.
+                        Usually, the value is stored as a member parameter of the Impl class.
+                        Other operations can also be done, as required, in this called function.
+ + **Animatable Properties:** These are double-buffered properties that can be animated.
+ + **Custom Properties:** These are dynamic properties that are created for every single instance of the control.
+                          Therefore, these tend to take a lot of memory and are usually used by applications or other controls to dynamically set certain attributes on their children.
+                          The index for these properties can also be different for every instance.
+Careful consideration must be taken when choosing which property type to use for the properties of the custom control.
+For example, an Animatable property type can be animated but requires a lot more resources (both in its execution and memory footprint) compared to an event-side only property.
+___________________________________________________________________________________________________
+
+## Control Services {#creating-controls-control-services}
+
+### Initialization {#creating-controls-init}
+
+Controls are initialized in two steps: in the constructor, and then in the Initialize() method.
+This is so that a handle/body connection is made within DALi Core.
+See Dali::CustomActor & Dali::CustomActorImpl for more information.
+It is recommended to do provide a New() method in the custom control implementation where the Initialize() method should be called.
+
+~~~{.cpp}
+// C++
+MyUIControl MyUIControlImpl::New()
+{
+  // Create the implementation, temporarily owned on stack
+  IntrusivePtr< MyUIControlImpl > controlImpl = new MyUIControlImpl;
+
+  // Pass ownership to handle
+  MyUIControl handle( *controlImpl );
+
+  // Second-phase init of the implementation
+  controlImpl->Initialize();
+
+  return handle;
+}
+~~~
+Another advantage of using a New() method is that the constructor for MyUIControl can be made private (or protected).
+This will trigger the Dali::Toolkit::Internal::Control Initialize() method which will in-turn, call the virtual method OnInitialize().
+This should be overridden by the custom ui control.
+~~~{.cpp}
+// C++
+void MyUIControlImpl::OnInitialize()
+{
+  // Create renderers, register events etc.
+}
+~~~
+___________________________________________________________________________________________________
+
+### Control Behaviour {#creating-controls-behaviour}
+
+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_TOUCH_EVENTS                | If our control requires [touch events](@ref creating-controls-events).  |
+| 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.                            |
+___________________________________________________________________________________________________
+
+### Touch, Hover & Wheel Events {#creating-controls-events}
+
++ A **touch event** is when any touch occurs within the bounds of the custom actor.
++ 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 should needs to utilise these events, then the correct behaviour flag should be used when constructing the control.
+Then the appropriate method should be overridden.
+~~~{.cpp}
+// C++
+bool MyUIControlImpl::OnTouchEvent( const TouchEvent& event )
+{
+  bool consumed = false;
+
+  // Handle touch event
+
+  // Return true if handled/consumed, false otherwise
+  return consumed;
+}
+~~~
+~~~{.cpp}
+// C++
+bool MyUIControlImpl::OnHoverEvent( const HoverEvent& event )
+{
+  bool consumed = false;
+
+  // Handle hover event
+
+  // Return true if handled/consumed, false otherwise
+  return consumed;
+}
+~~~
+~~~{.cpp}
+// C++
+bool MyUIControlImpl::OnWheelEvent( const WheelEvent& event )
+{
+  bool consumed = false;
+
+  // Handle wheel event
+
+  // Return true if handled/consumed, false otherwise
+  return consumed;
+}
+~~~
+___________________________________________________________________________________________________
+
+### Gestures {#creating-controls-gestures}
+
+DALi has a gesture system which analyses a stream of touch events and attempts to determine the intention of the user.
+The following gesture detectors are provided:
+ + **Pan:** When the user starts panning (or dragging) one or more fingers.
+            The panning should start from within the bounds of the control.
+ + **Pinch:** Detects when two touch points move towards or away from each other.
+              The center point of the pinch should be within the bounds of the control.
+ + **Tap:** When the user taps within the bounds of the control.
+ + **LongPress:** When the user presses and holds on a certain point within the bounds of a control.
+The control base class provides basic set up to detect these gestures.
+If any of these detectors are required then this can be specified in the OnInitialize() method (or as required).
+~~~{.cpp}
+// C++
+void MyUIControlImpl::OnInitialize()
+{
+  // Only enable pan gesture detection
+  EnableGestureDetection( Gesture::Pan );
+
+  // Or if several gestures are required
+  EnableGestureDetection( Gesture::Type( Gesture::Pinch | Gesture::Tap | Gesture::LongPress ) );
+}
+~~~
+The above snippet of code will only enable the default gesture detection for each type.
+If customization of the gesture detection is required, then the gesture-detector can be retrieved and set up accordingly in the same method.
+~~~{.cpp}
+// C++
+PanGestureDetector panGestureDetector = GetPanGestureDetector();
+panGestureDetector.AddDirection( PanGestureDetector::DIRECTION_VERTICAL );
+~~~
+Finally, the appropriate method should be overridden:
+~~~{.cpp}
+// C++
+void MyUIControlImpl::OnPan( const PanGesture& pan )
+{
+  // Handle pan-gesture
+}
+~~~
+~~~{.cpp}
+// C++
+void MyUIControlImpl::OnPinch( const PinchGesture& pinch )
+{
+  // Handle pinch-event
+}
+~~~
+~~~{.cpp}
+// C++
+void MyUIControlImpl::OnTap( const TapGesture& tap )
+{
+  // Handle tap-gesture
+}
+~~~
+~~~{.cpp}
+// C++
+void MyUIControlImpl::OnLongPress( const LongPressGesture& longPress )
+{
+  // Handle long-press-gesture
+}
+~~~
+___________________________________________________________________________________________________
+
+### Accessibility {#creating-controls-accessibility}
+
+Accessibility is functionality that has been designed to aid usage by the visually impaired.
+More information can be found in the [Accessibility](@ref accessibility) section.
+Accessibility behaviour can be customized in the control by overriding certain virtual methods.
+This is detailed [here](@ref accessibilitycustomcontrol).
+___________________________________________________________________________________________________
+
+### Signals {#creating-controls-signals}
+
+If applications need to react to changes in the control state, controls can inform those applications using Dali::Signal.
+
+First, create a signature of the function the signal will call in the handle header file:
+~~~{.cpp}
+// C++: my-ui-control.h
+typedef Signal< void () > SignalType;
+~~~
+Then Create methods to get to the signal:
+~~~{.cpp}
+// C++: my-ui-control.h
+MyUIControl::SignalType& MyCustomSignal();
+~~~
+
+The source file should just call the impl:
+~~~{.cpp}
+// C++: my-ui-control.cpp
+MyUIControl::SignalType& MyUIControl::MyCustomSignal()
+{
+  return Dali::Toolkit::GetImplementation( *this ).MyCustomSignal();
+}
+~~~
+In the impl file, create an instance of the signal as follows and return it in the appropriate method:
+~~~{.cpp}
+// C++: my-ui-control-impl.h
+public:
+
+  MyUIControl::SignalType MyUIControl::MyCustomSignal()
+  {
+    return mMyCustomSignal;
+  }
+
+private:
+
+  MyUIControl::SignalType mMyCustomSignal;
+~~~
+Then, when you wish to emit this signal:
+~~~{.cpp}
+// C++: my-ui-control-impl.cpp
+mMyCustomSignal.Emit();
+~~~
+There is no need to check if there is anything connected to this signal as this is done by the framework.
+The application can then connect to the signal as follows:
+~~~{.cpp}
+void AppFunction()
+{
+  // Do Something
+}
+
+...
+
+customControl.MyCustomSignal.Connect( this, &AppFunction );
+~~~
+___________________________________________________________________________________________________
+
+### Other Features {#creating-controls-other}
+
+ + [Background](@ref background)
+___________________________________________________________________________________________________
+
+@class _Guide_Creating_UI_Controls
+
+*/