Merge "Accessibility programming guide" into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Wed, 15 Jul 2015 08:50:53 +0000 (01:50 -0700)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Wed, 15 Jul 2015 08:50:53 +0000 (01:50 -0700)
34 files changed:
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-platform-abstraction.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-platform-abstraction.h
build/tizen/dali-toolkit/Makefile.am
dali-toolkit/devel-api/builder/json-parser.cpp
dali-toolkit/devel-api/builder/json-parser.h
dali-toolkit/internal/atlas-manager/atlas-manager.h
dali-toolkit/internal/builder/json-parser-impl.cpp
dali-toolkit/internal/builder/json-parser-impl.h
dali-toolkit/internal/controls/buttons/button-impl.cpp
dali-toolkit/internal/controls/buttons/button-impl.h
dali-toolkit/internal/controls/buttons/push-button-impl.cpp
dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp
dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp
dali-toolkit/internal/feedback/feedback-ids.h [new file with mode: 0644]
dali-toolkit/internal/feedback/feedback-style.cpp [new file with mode: 0644]
dali-toolkit/internal/feedback/feedback-style.h [new file with mode: 0644]
dali-toolkit/internal/file.list
dali-toolkit/internal/styling/style-manager-impl.cpp
dali-toolkit/internal/styling/style-manager-impl.h
dali-toolkit/internal/text/decorator/text-decorator.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/public-api/controls/control-depth-index-ranges.h
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/styles/default-feedback-theme.json [new file with mode: 0644]
docs/content/shared-javascript-and-cpp-documentation/performance-tips.md
plugins/dali-script-v8/docs/content/actor.js
plugins/dali-script-v8/docs/content/constants.js
plugins/dali-script-v8/src/constants/constants-wrapper.cpp

index 6acbca7..38c14a9 100644 (file)
@@ -110,20 +110,6 @@ Integration::ResourcePointer TestPlatformAbstraction::LoadResourceSynchronously(
 }
 
 /**
- * @copydoc PlatformAbstraction::SaveResource()
- */
-void TestPlatformAbstraction::SaveResource(const Integration::ResourceRequest& request)
-{
-  mTrace.PushCall("SaveResource", "");
-  if(mRequest != NULL)
-  {
-    delete mRequest;
-    tet_infoline ("Warning: multiple resource requests not handled by Test Suite. You may see unexpected errors");
-  }
-  mRequest = new Integration::ResourceRequest(request);
-}
-
-/**
  * @copydoc PlatformAbstraction::CancelLoad()
  */
 void TestPlatformAbstraction::CancelLoad(Integration::ResourceId id, Integration::ResourceTypeId typeId)
@@ -146,14 +132,6 @@ void TestPlatformAbstraction::GetResources(Integration::ResourceCache& cache)
   {
     cache.LoadFailed( mResources.loadFailedId, mResources.loadFailure );
   }
-  if(mResources.saved)
-  {
-    cache.SaveComplete( mResources.savedId, mResources.savedType );
-  }
-  if(mResources.saveFailed)
-  {
-    cache.SaveFailed( mResources.saveFailedId, mResources.saveFailure );
-  }
 }
 
 /**
@@ -258,7 +236,6 @@ bool TestPlatformAbstraction::WasCalled(TestFuncEnum func)
     case SuspendFunc:                         return mTrace.FindMethod("Suspend");
     case ResumeFunc:                          return mTrace.FindMethod("Resume");
     case LoadResourceFunc:                    return mTrace.FindMethod("LoadResource");
-    case SaveResourceFunc:                    return mTrace.FindMethod("SaveResource");
     case LoadFileFunc:                        return mTrace.FindMethod("LoadFile");
     case LoadShaderBinaryFileFunc:            return mTrace.FindMethod("LoadShaderBinaryFile");
     case SaveShaderBinaryFileFunc:            return mTrace.FindMethod("SaveShaderBinaryFile");
@@ -315,22 +292,6 @@ void TestPlatformAbstraction::SetResourceLoadFailed(Integration::ResourceId  id,
   mResources.loadFailure = failure;
 }
 
-void TestPlatformAbstraction::SetResourceSaved(Integration::ResourceId      savedId,
-                                               Integration::ResourceTypeId  savedType)
-{
-  mResources.saved = true;
-  mResources.savedId = savedId;
-  mResources.savedType = savedType;
-}
-
-void TestPlatformAbstraction::SetResourceSaveFailed(Integration::ResourceId  id,
-                                                    Integration::ResourceFailure failure)
-{
-  mResources.saveFailed = true;
-  mResources.saveFailedId = id;
-  mResources.saveFailure = failure;
-}
-
 Integration::ResourceRequest* TestPlatformAbstraction::GetRequest()
 {
   return mRequest;
index c35b2c2..cd6bf85 100644 (file)
@@ -51,14 +51,6 @@ public:
     bool                         loadFailed;
     Integration::ResourceId      loadFailedId;
     Integration::ResourceFailure loadFailure;
-
-    bool                         saved;
-    Integration::ResourceId      savedId;
-    Integration::ResourceTypeId  savedType;
-
-    bool                         saveFailed;
-    Integration::ResourceId      saveFailedId;
-    Integration::ResourceFailure saveFailure;
   };
 
   struct LoadFileResult
@@ -127,11 +119,6 @@ public:
   virtual Integration::ResourcePointer LoadResourceSynchronously( const Integration::ResourceType& resourceType, const std::string& resourcePath );
 
   /**
-   * @copydoc PlatformAbstraction::SaveResource()
-   */
-  virtual void SaveResource(const Integration::ResourceRequest& request);
-
-  /**
    * @copydoc PlatformAbstraction::CancelLoad()
    */
   virtual void CancelLoad(Integration::ResourceId id, Integration::ResourceTypeId typeId);
@@ -190,7 +177,6 @@ public: // TEST FUNCTIONS
     SuspendFunc,
     ResumeFunc,
     LoadResourceFunc,
-    SaveResourceFunc,
     SaveFileFunc,
     LoadFileFunc,
     LoadShaderBinaryFileFunc,
@@ -232,12 +218,6 @@ public: // TEST FUNCTIONS
   void SetResourceLoadFailed(Integration::ResourceId  id,
                              Integration::ResourceFailure failure);
 
-  void SetResourceSaved(Integration::ResourceId      savedId,
-                        Integration::ResourceTypeId  savedType);
-
-  void SetResourceSaveFailed(Integration::ResourceId  id,
-                             Integration::ResourceFailure failure);
-
   Integration::ResourceRequest* GetRequest();
 
   void DiscardRequest();
index 37bff58..17029e0 100644 (file)
@@ -115,7 +115,7 @@ develapistyling_HEADERS =           $(devel_api_styling_header_files)
 develapisuperblurview_HEADERS =     $(devel_api_super_blur_view_header_files)
 develapitoolbar_HEADERS =           $(devel_api_tool_bar_header_files)
 develapitransitioneffects_HEADERS = $(devel_api_transition_effects_header_files)
-develapitextselectionpopup_HEADERS = $(devel_api_text_selection_popup_header_files)
+develapitextselectionpopup_HEADERS = $(devel_api_text_controls_header_files)
 
 # public api source
 publicapidir =                    $(topleveldir)/public-api
index 5d3838e..5e8c0ae 100644 (file)
@@ -59,7 +59,7 @@ JsonParser DownCast( BaseHandle handle )
   return JsonParser( dynamic_cast<Internal::JsonParser*>(handle.GetObjectPtr()) );
 }
 
-int JsonParser::Parse(const std::string& source)
+bool JsonParser::Parse(const std::string& source)
 {
   return GetImplementation(*this).Parse(source);
 }
index b871948..05b8e80 100644 (file)
@@ -81,9 +81,9 @@ public:
    * Parse the source and construct a node tree.
    * Subsequent calls to this function will merge the trees.
    * @param source The json source to parse
-   * @return zero if parsed okay, otherwise an error.
+   * @return true if parsed okay, otherwise an error.
    */
-  int Parse(const std::string& source);
+  bool Parse(const std::string& source);
 
   /*
    * Optimize memory usage by packing strings
index 79eb9b7..532be6f 100644 (file)
@@ -162,10 +162,10 @@ public:
 
   struct AtlasSize
   {
-    SizeType mWidth;              // width of the atlas in pixels
-    SizeType mHeight;             // height of the atlas in pixels
-    SizeType mBlockWidth;         // width of a block in pixels
-    SizeType mBlockHeight;        // height of a block in pixels
+    SizeType mWidth;              ///< width of the atlas in pixels
+    SizeType mHeight;             ///< height of the atlas in pixels
+    SizeType mBlockWidth;         ///< width of a block in pixels
+    SizeType mBlockHeight;        ///< height of a block in pixels
   };
 
   /**
@@ -174,17 +174,25 @@ public:
    */
   struct AtlasMetricsEntry
   {
-    AtlasSize mSize;                 // size of atlas and blocks
-    SizeType mBlocksUsed;            // number of blocks used in the atlas
-    SizeType mTotalBlocks;           // total blocks used by atlas
-    Pixel::Format mPixelFormat;      // pixel format of the atlas
+    AtlasSize mSize;                 ///< size of atlas and blocks
+    SizeType mBlocksUsed;            ///< number of blocks used in the atlas
+    SizeType mTotalBlocks;           ///< total blocks used by atlas
+    Pixel::Format mPixelFormat;      ///< pixel format of the atlas
   };
 
   struct Metrics
   {
-    SizeType mAtlasCount;                               // number of atlases
-    SizeType mTextureMemoryUsed;                        // texture memory used by atlases
-    Dali::Vector< AtlasMetricsEntry > mAtlasMetrics;    // container of atlas information
+    Metrics()
+    : mAtlasCount( 0u ),
+      mTextureMemoryUsed( 0u )
+    {}
+
+    ~Metrics()
+    {}
+
+    SizeType mAtlasCount;                               ///< number of atlases
+    SizeType mTextureMemoryUsed;                        ///< texture memory used by atlases
+    Dali::Vector< AtlasMetricsEntry > mAtlasMetrics;    ///< container of atlas information
   };
 
   struct Vertex2D
@@ -233,8 +241,8 @@ public:
    */
   struct AtlasSlot
   {
-    ImageId mImageId;                           // Id of stored Image
-    AtlasId mAtlasId;                           // Id of Atlas containing this slot
+    ImageId mImageId;                           ///< Id of stored Image
+    AtlasId mAtlasId;                           ///< Id of Atlas containing this slot
   };
 
   typedef Dali::Vector< AtlasManager::AtlasSlot > slotContainer;
index 2cff977..fdec738 100644 (file)
@@ -96,7 +96,7 @@ JsonParser::~JsonParser()
   }
 }
 
-int JsonParser::Parse(const std::string& source)
+bool JsonParser::Parse(const std::string& source)
 {
   mSources.push_back( VectorChar(source.begin(), source.end()) );
 
index 9936974..dbdbf45 100644 (file)
@@ -62,7 +62,7 @@ public:
   /*
    * @copydoc Toolkit::JsonParser::Parse()
    */
-  int Parse(const std::string& source);
+  bool Parse(const std::string& source);
 
   /*
    * @copydoc Toolkit::JsonParser::Pack()
index 3031d4f..2883c9a 100644 (file)
@@ -143,8 +143,11 @@ void Button::SetDisabled( bool disabled )
       //(2) mDisabledBackgroundContent (Inserted)
       //(1) mBackgroundContent
 
-      TransitionInBetween( mUnselectedContent, mLabel, mDisabledContent );
-      TransitionInAbove( mBackgroundContent, mDisabledBackgroundContent );
+      AddButtonImage( mBackgroundContent );
+      TransitionButtonImage( mDisabledBackgroundContent );
+      AddButtonImage( mUnselectedContent );
+      TransitionButtonImage( mDisabledContent );
+      ReAddLabel();
 
       TransitionOut( mUnselectedContent );
       TransitionOut( mSelectedContent );
@@ -164,8 +167,12 @@ void Button::SetDisabled( bool disabled )
       //(2) mSelectedBackgroundContent
       //(1) mBackgroundContent
 
-      TransitionInBetween( mSelectedContent, mLabel, mDisabledSelectedContent );
-      TransitionInAbove( mSelectedBackgroundContent, mDisabledBackgroundContent );
+      AddButtonImage( mBackgroundContent );
+      AddButtonImage( mSelectedBackgroundContent );
+      TransitionButtonImage( mDisabledBackgroundContent );
+      AddButtonImage( mSelectedContent );
+      TransitionButtonImage( mDisabledSelectedContent );
+      ReAddLabel();
 
       TransitionOut( mUnselectedContent );
       TransitionOut( mSelectedContent );
@@ -184,8 +191,11 @@ void Button::SetDisabled( bool disabled )
       //(2) mBackgroundContent (Inserted)
       //(1) mDisabledBackgroundContent
 
-      TransitionInBetween( mDisabledContent, mLabel, mUnselectedContent );
-      TransitionInAbove( mDisabledBackgroundContent, mBackgroundContent );
+      AddButtonImage( mDisabledBackgroundContent );
+      TransitionButtonImage( mBackgroundContent );
+      AddButtonImage( mDisabledContent );
+      TransitionButtonImage( mUnselectedContent );
+      ReAddLabel();
 
       TransitionOut( mSelectedContent );
       TransitionOut( mSelectedBackgroundContent );
@@ -205,9 +215,12 @@ void Button::SetDisabled( bool disabled )
       //(2) mBackgroundContent (Inserted)
       //(1) mDisabledBackgroundContent
 
-      TransitionInBetween( mDisabledSelectedContent, mLabel, mSelectedContent );
-      TransitionInAbove( mDisabledBackgroundContent, mSelectedBackgroundContent );
-      TransitionInAbove( mDisabledBackgroundContent, mBackgroundContent );
+      AddButtonImage( mDisabledBackgroundContent );
+      TransitionButtonImage( mBackgroundContent );
+      TransitionButtonImage( mSelectedBackgroundContent );
+      AddButtonImage( mDisabledSelectedContent );
+      TransitionButtonImage( mSelectedContent );
+      ReAddLabel();
 
       TransitionOut( mUnselectedContent );
       TransitionOut( mDisabledContent );
@@ -314,9 +327,11 @@ void Button::SetSelected( bool selected, bool emitSignal )
       //(2) mSelectedBackgroundContent (Inserted)
       //(1) mBackgroundContent
 
-      TransitionInBetween( mUnselectedContent, mLabel, mSelectedContent );
-      TransitionInAbove( mBackgroundContent, mSelectedBackgroundContent );
-      TransitionInAtIndex( 0, mBackgroundContent );
+      AddButtonImage( mBackgroundContent );
+      TransitionButtonImage( mSelectedBackgroundContent );
+      AddButtonImage( mUnselectedContent );
+      TransitionButtonImage( mSelectedContent );
+      ReAddLabel();
 
       TransitionOut( mUnselectedContent );
       TransitionOut( mDisabledContent );
@@ -333,8 +348,10 @@ void Button::SetSelected( bool selected, bool emitSignal )
       //(2) mSelectedContent
       //(1) mBackgroundContent
 
-      TransitionInBetween( mSelectedContent, mLabel, mUnselectedContent );
-      TransitionInAtIndex( 0, mBackgroundContent );
+      AddButtonImage( mBackgroundContent );
+      AddButtonImage( mSelectedContent );
+      TransitionButtonImage( mUnselectedContent );
+      ReAddLabel();
 
       TransitionOut( mSelectedContent );
       TransitionOut( mSelectedBackgroundContent );
@@ -954,9 +971,11 @@ void Button::Pressed()
     //(2) mSelectedBackgroundContent (Inserted)
     //(1) mBackgroundContent
 
-    TransitionInBetween( mUnselectedContent, mLabel, mSelectedContent );
-    TransitionInAbove( mBackgroundContent, mSelectedBackgroundContent );
-    TransitionInAtIndex( 0, mBackgroundContent );
+    AddButtonImage( mBackgroundContent );
+    TransitionButtonImage( mSelectedBackgroundContent );
+    AddButtonImage( mUnselectedContent );
+    TransitionButtonImage( mSelectedContent );
+    ReAddLabel();
 
     TransitionOut( mUnselectedContent );
     TransitionOut( mDisabledContent );
@@ -983,8 +1002,10 @@ void Button::Released()
     //(2) mSelectedContent
     //(1) mBackgroundContent
 
-    TransitionInBetween( mSelectedContent, mLabel, mUnselectedContent );
-    TransitionInAtIndex( 0, mBackgroundContent );
+    AddButtonImage( mBackgroundContent );
+    AddButtonImage( mSelectedContent );
+    TransitionButtonImage( mUnselectedContent );
+    ReAddLabel();
 
     TransitionOut( mSelectedContent );
     TransitionOut( mSelectedBackgroundContent );
@@ -1008,16 +1029,44 @@ Button::PaintState Button::GetPaintState()
   return mPaintState;
 }
 
-bool Button::InsertButtonImage( unsigned int index, Actor& actor )
+void Button::PrepareAddButtonImage( Actor& actor )
 {
   if( actor )
   {
-    Self().Insert( index, actor );
+    actor.Unparent();
+    Self().Add( actor );
     PrepareForTranstionOut( actor );
-    return true;
   }
+}
 
-  return false;
+void Button::TransitionButtonImage( Actor& actor )
+{
+  if( actor )
+  {
+    if( !actor.GetParent() )
+    {
+      Self().Add( actor );
+    }
+
+    OnTransitionIn( actor );
+  }
+}
+
+void Button::AddButtonImage( Actor& actor )
+{
+  if( actor )
+  {
+    Self().Add( actor );
+  }
+}
+
+void Button::ReAddLabel()
+{
+  if( mLabel )
+  {
+    mLabel.Unparent();
+    Self().Add( mLabel );
+  }
 }
 
 void Button::RemoveButtonImage( Actor& actor )
@@ -1049,31 +1098,6 @@ unsigned int Button::FindChildIndex( Actor& actor )
   return childrenNum;
 }
 
-void Button::TransitionInBetween(  Actor childLower, Actor childUpper, Actor actor )
-{
-  unsigned int index = childLower ? FindChildIndex( childLower ) + 1 : FindChildIndex( childUpper );
-  TransitionInAtIndex( index, actor );
-}
-
-void Button::TransitionInAbove( Actor child, Actor actor )
-{
-  unsigned int index = child ? FindChildIndex( child ) + 1 : 0;
-  TransitionInAtIndex( index, actor );
-}
-
-void Button::TransitionInAtIndex( unsigned int index, Actor actor )
-{
-  if( actor )
-  {
-    if( !actor.GetParent() )
-    {
-      Self().Insert( index, actor );
-    }
-
-    OnTransitionIn( actor );
-  }
-}
-
 void Button::TransitionOut( Actor actor )
 {
   OnTransitionOut( actor );
@@ -1081,9 +1105,8 @@ void Button::TransitionOut( Actor actor )
 
 void Button::ResetImageLayers()
 {
-  //ensure that all layers are in the correct order and state according to the paint state
+  // Ensure that all layers are in the correct order and state according to the paint state
 
-  int index = 0;
   switch( mPaintState )
   {
     case UnselectedState:
@@ -1098,14 +1121,8 @@ void Button::ResetImageLayers()
       RemoveButtonImage( mDisabledSelectedContent );
       RemoveButtonImage( mDisabledBackgroundContent );
 
-      if( InsertButtonImage( index, mBackgroundContent ) )
-      {
-        ++index;
-      }
-      if( InsertButtonImage( index, mUnselectedContent ) )
-      {
-        ++index;
-      }
+      PrepareAddButtonImage( mBackgroundContent );
+      PrepareAddButtonImage( mUnselectedContent );
       break;
     }
     case SelectedState:
@@ -1120,18 +1137,10 @@ void Button::ResetImageLayers()
       RemoveButtonImage( mDisabledSelectedContent );
       RemoveButtonImage( mDisabledBackgroundContent );
 
-      if( InsertButtonImage( index, mBackgroundContent ) )
-      {
-        ++index;
-      }
-      if( InsertButtonImage( index, mSelectedBackgroundContent ) )
-      {
-        ++index;
-      }
-      if( InsertButtonImage( index, mSelectedContent ) )
-      {
-        ++index;
-      }
+      PrepareAddButtonImage( mBackgroundContent );
+      PrepareAddButtonImage( mSelectedBackgroundContent );
+      PrepareAddButtonImage( mSelectedContent );
+      ReAddLabel();
       break;
     }
     case DisabledUnselectedState:
@@ -1146,14 +1155,9 @@ void Button::ResetImageLayers()
       RemoveButtonImage( mDisabledSelectedContent );
       RemoveButtonImage( mSelectedBackgroundContent );
 
-      if( InsertButtonImage( index, mDisabledBackgroundContent ? mDisabledBackgroundContent : mBackgroundContent ) )
-      {
-        ++index;
-      }
-      if( InsertButtonImage( index, mDisabledContent ? mDisabledContent : mUnselectedContent ) )
-      {
-        ++index;
-      }
+      PrepareAddButtonImage( mDisabledBackgroundContent ? mDisabledBackgroundContent : mBackgroundContent );
+      PrepareAddButtonImage( mDisabledContent ? mDisabledContent : mUnselectedContent );
+      ReAddLabel();
       break;
     }
     case DisabledSelectedState:
@@ -1170,27 +1174,16 @@ void Button::ResetImageLayers()
 
       if( mDisabledBackgroundContent )
       {
-        if( InsertButtonImage( index, mDisabledBackgroundContent) )
-        {
-          ++index;
-        }
+        PrepareAddButtonImage( mDisabledBackgroundContent );
       }
       else
       {
-        if( InsertButtonImage( index, mBackgroundContent ) )
-        {
-          ++index;
-        }
-        if( InsertButtonImage( index, mSelectedBackgroundContent ) )
-        {
-          ++index;
-        }
+        PrepareAddButtonImage( mBackgroundContent );
+        PrepareAddButtonImage( mSelectedBackgroundContent );
       }
 
-      if( InsertButtonImage( index, mDisabledSelectedContent ? mDisabledSelectedContent : mSelectedContent) )
-      {
-        ++index;
-      }
+      PrepareAddButtonImage( mDisabledSelectedContent ? mDisabledSelectedContent : mSelectedContent );
+      ReAddLabel();
       break;
     }
   }
index 89f0591..a17d058 100644 (file)
@@ -578,45 +578,43 @@ private:
   void ResetImageLayers();
 
   /**
-   * Transitions in the actor, inserting the actor above childLower below the childUpper.
-   * Will not insert the actor if it is already attached to a parent (and so will not reorder the actor)
+   * Transitions out the actor
    */
-  void TransitionInBetween( Actor childLower, Actor childUpper, Actor actor );
+  void TransitionOut( Actor actor );
 
   /**
-   * Transitions in the actor, inserting the actor above the child if the child exists or at the bottom otherwise
-   * Will not insert the actor if it is already attached to a parent (and so will not reorder the actor)
+   * Removes the actor from the button and prepares it to be transitioned out
    */
-  void TransitionInAbove( Actor child, Actor actor );
+  void RemoveButtonImage( Actor& actor );
 
   /**
-   * Transitions in the actor, inserting the actor at the index
-   * Will not insert the actor if it is already attached to a parent (and so will not reorder the actor)
+   * Finds the index of the actor.
+   * If the actor doesn't exist, return the last index + 1.
    */
-  void TransitionInAtIndex( unsigned int index, Actor actor );
+  unsigned int FindChildIndex( Actor& actor );
 
   /**
-   * Transitions out the actor
+   * Adds an actor to the hierarchy and prepares it to be transitioned.
+   * @param[in] actor The actor to add
    */
-  void TransitionOut( Actor actor );
+  void PrepareAddButtonImage( Actor& actor );
 
   /**
-   * Inserts the actor to the button and prepares it to be transitioned out
-   * @return true if the child was inserted, false otherwise
+   * Adds an actor to the hierarchy and marks it to be transitioned.
+   * @param[in] actor The actor to add
    */
-  bool InsertButtonImage( unsigned int index, Actor& actor );
+  void TransitionButtonImage( Actor& actor );
 
   /**
-   * Removes the actor from the button and prepares it to be transitioned out
+   * Adds an actor to the hierarchy.
+   * @param[in] actor The actor to add
    */
-  void RemoveButtonImage( Actor& actor );
+  void AddButtonImage( Actor& actor );
 
   /**
-   * Finds the index of the actor.
-   * If the actor doesn't exist, return the last index + 1.
+   * (Re)Adds the label (if exists) to the hierarchy (so it is always on top).
    */
-  unsigned int FindChildIndex( Actor& actor );
-
+  void ReAddLabel();
 
   // Undefined
   Button( const Button& );
index 1ee6b92..b6efdf8 100644 (file)
@@ -241,8 +241,11 @@ Vector3 PushButton::GetNaturalSize()
   Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( GetLabel() );
   if( label )
   {
-    size.width  = std::max( size.width,  label.GetRelayoutSize( Dimension::WIDTH ) );
-    size.height = std::max( size.height, label.GetRelayoutSize( Dimension::HEIGHT ) );
+    Padding padding( 0.0f, 0.0f, 0.0f, 0.0f );
+    label.GetPadding( padding );
+    size = label.GetNaturalSize();
+    size.width += padding.x + padding.width;
+    size.height += padding.y + padding.height;
   }
   else
   {
index 1ef1e47..d2b715f 100755 (executable)
@@ -175,7 +175,7 @@ ScrollBar::~ScrollBar()
 void ScrollBar::OnInitialize()
 {
   CreateDefaultIndicatorActor();
-  Self().SetDrawMode(DrawMode::OVERLAY);
+  Self().SetDrawMode(DrawMode::OVERLAY_2D);
 }
 
 void ScrollBar::SetScrollPropertySource( Handle handle, Property::Index propertyScrollPosition, Property::Index propertyMinScrollPosition, Property::Index propertyMaxScrollPosition, Property::Index propertyScrollContentSize )
@@ -220,14 +220,11 @@ void ScrollBar::SetScrollIndicator( Actor indicator )
     mIndicator = indicator;
     Self().Add(mIndicator);
 
-    if( !mPanGestureDetector )
-    {
-      mPanGestureDetector = PanGestureDetector::New();
-      mPanGestureDetector.DetectedSignal().Connect(this, &ScrollBar::OnPan);
-    }
+    EnableGestureDetection(Gesture::Type(Gesture::Pan));
 
-    mPanGestureDetector.DetachAll();
-    mPanGestureDetector.Attach( mIndicator );
+    PanGestureDetector detector( GetPanGestureDetector() );
+    detector.DetachAll();
+    detector.Attach( mIndicator );
 
     unsigned int childCount = mIndicator.GetChildCount();
     for ( unsigned int index = 0; index < childCount; index++ )
@@ -235,7 +232,7 @@ void ScrollBar::SetScrollIndicator( Actor indicator )
       Actor child = mIndicator.GetChildAt( index );
       if ( child )
       {
-        mPanGestureDetector.Attach( child );
+        detector.Attach( child );
       }
     }
   }
@@ -370,7 +367,7 @@ bool ScrollBar::OnPanGestureProcessTick()
   return true;
 }
 
-void ScrollBar::OnPan( Actor source, const PanGesture& gesture )
+void ScrollBar::OnPan( const PanGesture& gesture )
 {
   if(mScrollableObject)
   {
@@ -437,7 +434,7 @@ void ScrollBar::OnPan( Actor source, const PanGesture& gesture )
     if(itemView)
     {
       // Disable automatic refresh in ItemView during fast scrolling
-      GetImpl(itemView).SetRefreshEnabled(true);//!mIsPanning);
+      GetImpl(itemView).SetRefreshEnabled(!mIsPanning);
     }
   }
 }
index f5321a4..8a8177d 100755 (executable)
@@ -201,6 +201,11 @@ private: // from Control
   virtual void OnInitialize();
 
   /**
+   * @copydoc Toolkit::Control::OnPan
+   */
+  virtual void OnPan( const PanGesture& gesture );
+
+  /**
    * @copydoc CustomActorImpl::OnSizeSet( const Vector3& size )
    */
   virtual void OnSizeSet( const Vector3& size );
@@ -243,14 +248,6 @@ private:
    */
   void OnIndicatorHeightPolicyPropertySet(Property::Value propertyValue);
 
-  /**
-   * Pan gesture callback
-   *
-   * @param[in] actor The actor the event is raised for
-   * @param[in] gesture The pan event info
-   */
-  void OnPan(Actor source, const PanGesture& gesture);
-
 private:
 
   /**
@@ -290,8 +287,6 @@ private:
   Toolkit::ScrollBar::IndicatorHeightPolicy mIndicatorHeightPolicy;  ///< The height policy of scroll indicator (variable or fixed)
   float mIndicatorFixedHeight;                                      ///< The fixed height of scroll indicator
 
-  PanGestureDetector mPanGestureDetector;                            ///< The pan gesture detector for scroll indicator
-
   Timer mContractDelayTimer;                                         ///< Timer guarantee contract delay time.
   Timer mPanProcessTimer;                                            ///< The timer to process the pan gesture after the gesture is started.
 
index 13ab888..c70b792 100644 (file)
@@ -1628,7 +1628,10 @@ void ItemView::GetItemsRange(ItemRange& range)
 void ItemView::OnScrollPositionChanged( float position )
 {
   // Cancel scroll animation to prevent any fighting of setting the scroll position property.
-  RemoveAnimation(mScrollAnimation);
+  if(!mRefreshEnabled)
+  {
+    RemoveAnimation(mScrollAnimation);
+  }
 
   // Refresh the cache immediately when the scroll position is changed.
   DoRefresh(position, false); // No need to cache extra items.
diff --git a/dali-toolkit/internal/feedback/feedback-ids.h b/dali-toolkit/internal/feedback/feedback-ids.h
new file mode 100644 (file)
index 0000000..cb7ffa3
--- /dev/null
@@ -0,0 +1,105 @@
+#ifndef __DALI_FEEDBACK_IDS_H__
+#define __DALI_FEEDBACK_IDS_H__
+
+/*
+ * 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.
+ *
+ */
+
+namespace Dali
+{
+
+/**
+ *  Enumerations for the types of feedback
+ *  Note: These are based on feedback_type_e in libsvi
+ */
+enum FeedbackType
+{
+  FEEDBACK_TYPE_NONE,
+
+  FEEDBACK_TYPE_SOUND,
+  FEEDBACK_TYPE_VIBRATION,
+  FEEDBACK_TYPE_LED,
+
+  FEEDBACK_TYPE_END
+};
+
+/**
+ *  The pattern list for feedback effects.
+ *  Note: These are based on feedback_pattern_e in libsvi
+ */
+enum FeedbackPattern
+{
+  FEEDBACK_PATTERN_NONE = -1,
+
+  FEEDBACK_PATTERN_TAP = 0,           /**< feedback pattern when general touch */
+  FEEDBACK_PATTERN_SIP,               /**< feedback pattern when touch text key */
+  FEEDBACK_PATTERN_SIP_BACKSPACE,     /**< feedback pattern when touch backspace key */
+  FEEDBACK_PATTERN_MAX_CHARACTER,     /**< feedback pattern when max character */
+  FEEDBACK_PATTERN_KEY0,              /**< feedback pattern when touch numeric 0 key */
+  FEEDBACK_PATTERN_KEY1,              /**< feedback pattern when touch numeric 1 key */
+  FEEDBACK_PATTERN_KEY2,              /**< feedback pattern when touch numeric 2 key */
+  FEEDBACK_PATTERN_KEY3,              /**< feedback pattern when touch numeric 3 key */
+  FEEDBACK_PATTERN_KEY4,              /**< feedback pattern when touch numeric 4 key */
+  FEEDBACK_PATTERN_KEY5,              /**< feedback pattern when touch numeric 5 key */
+  FEEDBACK_PATTERN_KEY6,              /**< feedback pattern when touch numeric 6 key */
+  FEEDBACK_PATTERN_KEY7,              /**< feedback pattern when touch numeric 7 key */
+  FEEDBACK_PATTERN_KEY8,              /**< feedback pattern when touch numeric 8 key */
+  FEEDBACK_PATTERN_KEY9,              /**< feedback pattern when touch numeric 9 key */
+  FEEDBACK_PATTERN_KEY_STAR,          /**< feedback pattern when touch star key */
+  FEEDBACK_PATTERN_KEY_SHARP,         /**< feedback pattern when touch sharp key */
+  FEEDBACK_PATTERN_HOLD,              /**< feedback pattern when touch hold */
+  FEEDBACK_PATTERN_MULTI_TAP,         /**< feedback pattern when multi touch */
+  FEEDBACK_PATTERN_HW_TAP,            /**< feedback pattern when press hardware key */
+  FEEDBACK_PATTERN_HW_HOLD,           /**< feedback pattern when holding press hardware key */
+
+  FEEDBACK_PATTERN_MESSAGE,           /**< feedback pattern when incoming a message */
+  FEEDBACK_PATTERN_MESSAGE_ON_CALL,   /**< feedback pattern when incoming a message on call */
+  FEEDBACK_PATTERN_EMAIL,             /**< feedback pattern when incoming an email */
+  FEEDBACK_PATTERN_EMAIL_ON_CALL,     /**< feedback pattern when incoming an email on call */
+  FEEDBACK_PATTERN_WAKEUP,            /**< feedback pattern when alert wake up call */
+  FEEDBACK_PATTERN_WAKEUP_ON_CALL,    /**< feedback pattern when alert wake up call on call */
+  FEEDBACK_PATTERN_SCHEDULE,          /**< feedback pattern when alert schedule alarm */
+  FEEDBACK_PATTERN_SCHEDULE_ON_CALL,    /**< feedback pattern when alert schedule alarm on call */
+  FEEDBACK_PATTERN_TIMER,             /**< feedback pattern when alert timer */
+  FEEDBACK_PATTERN_TIMER_ON_CALL,     /**< feedback pattern when alert timer on call */
+  FEEDBACK_PATTERN_GENERAL,           /**< feedback pattern when alert general event */
+  FEEDBACK_PATTERN_GENERAL_ON_CALL,   /**< feedback pattern when alert general event on call */
+
+  FEEDBACK_PATTERN_POWER_ON,           /**< feedback pattern when power on */
+  FEEDBACK_PATTERN_POWER_OFF,           /**< feedback pattern when power off */
+  FEEDBACK_PATTERN_CHARGERCONN,         /**< feedback pattern when connecting charger */
+  FEEDBACK_PATTERN_CHARGERCONN_ON_CALL, /**< feedback pattern when connecting charger on call */
+  FEEDBACK_PATTERN_FULLCHARGED,         /**< feedback pattern when full charged */
+  FEEDBACK_PATTERN_FULLCHARGED_ON_CALL, /**< feedback pattern when full charged on call */
+  FEEDBACK_PATTERN_LOWBATT,             /**< feedback pattern when low battery */
+  FEEDBACK_PATTERN_LOWBATT_ON_CALL,     /**< feedback pattern when low battery on call */
+  FEEDBACK_PATTERN_LOCK,                /**< feedback pattern when lock */
+  FEEDBACK_PATTERN_UNLOCK,              /**< feedback pattern when unlock */
+  FEEDBACK_PATTERN_CALLCONNECT,         /**< feedback pattern when connecting call */
+  FEEDBACK_PATTERN_DISCALLCONNECT,      /**< feedback pattern when disconnecting call */
+  FEEDBACK_PATTERN_MINUTEMINDER,        /**< feedback pattern when minute minder */
+  FEEDBACK_PATTERN_VIBRATION,           /**< feedback pattern when vibration */
+  FEEDBACK_PATTERN_SHUTTER,             /**< feedback pattern when screen capture or camera shutter */
+  FEEDBACK_PATTERN_LIST_REORDER,        /**< feedback pattern when list reorder */
+  FEEDBACK_PATTERN_SLIDER_SWEEP,        /**< feedback pattern when slider sweep */
+
+  FEEDBACK_PATTERN_END,
+};
+
+
+}  // namespace Dali
+
+#endif // __DALI_FEEDBACK_IDS_H__
diff --git a/dali-toolkit/internal/feedback/feedback-style.cpp b/dali-toolkit/internal/feedback/feedback-style.cpp
new file mode 100644 (file)
index 0000000..c1dca7e
--- /dev/null
@@ -0,0 +1,470 @@
+/*
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/feedback/feedback-style.h>
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/public-api/object/object-registry.h>
+#include <dali/devel-api/adaptor-framework/style-monitor.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/builder/json-parser.h>
+#include <dali-toolkit/internal/feedback/feedback-ids.h>
+
+using std::string;
+
+namespace // unnamed namespace
+{
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::General, false, "LOG_FEEDBACK");
+#endif
+
+const char* DEFAULT_FEEDBACK_THEME_PATH = DALI_STYLE_DIR"default-feedback-theme.json";
+
+// Sets bool and string if the node has a child "name"
+void GetIfString(const Dali::Toolkit::TreeNode& node, const std::string& name, bool& exists, std::string& str)
+{
+  const Dali::Toolkit::TreeNode* child = node.GetChild(name);
+  if( child &&
+      Dali::Toolkit::TreeNode::STRING == child->GetType() )
+  {
+    exists = true;
+    str = child->GetString();
+  }
+}
+
+} // unnamed namespace
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+struct SignalFeedbackInfo
+{
+  /**
+   * Default constructor.
+   */
+  SignalFeedbackInfo()
+  :mHasHapticFeedbackInfo(false),
+   mHasSoundFeedbackInfo(false)
+  {
+  }
+
+  bool mHasHapticFeedbackInfo;
+  bool mHasSoundFeedbackInfo;
+  string mSignalName;
+  string mHapticFeedbackPattern;
+  string mSoundFeedbackPattern;
+  string mHapticFeedbackFile;
+  string mSoundFeedbackFile;
+};
+
+typedef std::vector<SignalFeedbackInfo> SignalFeedbackInfoContainer;
+typedef SignalFeedbackInfoContainer::const_iterator SignalFeedbackInfoConstIter;
+
+struct FeedbackStyleInfo
+{
+  /**
+   * Default constructor.
+   */
+  FeedbackStyleInfo()
+  {
+  }
+
+  string mTypeName;
+
+  SignalFeedbackInfoContainer mSignalFeedbackInfoList;
+};
+
+static const FeedbackStyleInfo DEFAULT_FEEDBACK_STYLE_INFO;
+
+FeedbackStyle::FeedbackStyle()
+: mConnections( this )
+{
+  mFeedback = Dali::FeedbackPlayer::Get();
+
+  string defaultTheme;
+
+  if( mFeedback && mFeedback.LoadFile( DEFAULT_FEEDBACK_THEME_PATH, defaultTheme ) )
+  {
+    LoadTheme( defaultTheme );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "ResourceLoader::LoadTheme(%s) - loaded %d bytes\n",
+                   DEFAULT_FEEDBACK_THEME_PATH, defaultTheme.size() );
+  }
+  else
+  {
+    DALI_LOG_ERROR("ResourceLoader::LoadTheme(%s) - failed to load\n", DEFAULT_FEEDBACK_THEME_PATH);
+  }
+
+}
+
+FeedbackStyle::~FeedbackStyle()
+{
+}
+
+struct PlayFeedbackFromSignal
+{
+  PlayFeedbackFromSignal( FeedbackStyle& controller, const string& typeName, const string& signalName )
+  : mController( controller ),
+    mTypeName( typeName ),
+    mSignalName( signalName )
+  {
+  }
+
+  void operator()()
+  {
+    mController.PlayFeedback( mTypeName, mSignalName );
+  }
+
+  FeedbackStyle& mController;
+  string mTypeName;
+  string mSignalName;
+};
+
+
+void FeedbackStyle::ObjectCreated( BaseHandle handle )
+{
+  std::string typeName = handle.GetTypeName();
+
+  if( handle )
+  {
+    string type = handle.GetTypeName();
+
+    const FeedbackStyleInfo styleInfo = GetStyleInfo( type );
+
+    for( SignalFeedbackInfoConstIter iter = styleInfo.mSignalFeedbackInfoList.begin(); iter != styleInfo.mSignalFeedbackInfoList.end(); ++iter )
+    {
+      const SignalFeedbackInfo& info = *iter;
+
+      if( info.mHasHapticFeedbackInfo || info.mHasSoundFeedbackInfo )
+      {
+        if( !info.mHapticFeedbackPattern.empty() || !info.mHapticFeedbackFile.empty() ||
+            !info.mSoundFeedbackPattern.empty()  || !info.mSoundFeedbackFile.empty() )
+        {
+          handle.ConnectSignal( this,
+                                info.mSignalName,
+                                PlayFeedbackFromSignal( *this, type, info.mSignalName ) );
+
+          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FeedbackStyle::Set found Haptic pattern %s for Object type: %s, Signal Type: %s\n",
+                         info.mHapticFeedbackPattern.c_str(), type.c_str(), info.mSignalName.c_str() );
+        }
+        else
+        {
+          DALI_LOG_ERROR("FeedbackStyle::Set() Warning Inconsistent data in theme file!\n");
+        }
+      }
+    }
+  }
+}
+
+const FeedbackStyleInfo& FeedbackStyle::GetStyleInfo( const string& type ) const
+{
+  std::map<const string, FeedbackStyleInfo>::const_iterator iter( mStyleInfoLut.find( type ) );
+  if( iter != mStyleInfoLut.end() )
+  {
+    return iter->second;
+  }
+  else
+  {
+    return DEFAULT_FEEDBACK_STYLE_INFO;
+  }
+}
+
+void FeedbackStyle::StyleChanged( const std::string& userDefinedThemePath, Dali::StyleChange::Type styleChange )
+{
+  if( StyleChange::THEME_CHANGE )
+  {
+    string userDefinedTheme;
+
+    if( mFeedback && mFeedback.LoadFile( userDefinedThemePath, userDefinedTheme ) )
+    {
+      if( !LoadTheme( userDefinedTheme ) )
+      {
+        DALI_LOG_ERROR("FeedbackStyle::StyleChanged() User defined theme failed to load! \n");
+
+        //If there is any problem is using the user defined theme, then fall back to default theme
+        if( !LoadTheme( DEFAULT_FEEDBACK_THEME_PATH ) )
+        {
+          //If the default theme fails, Then No luck!
+          DALI_LOG_ERROR("FeedbackStyle::StyleChanged() Default theme failed to load! \n");
+        }
+      }
+      else
+      {
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "ResourceLoader::LoadTheme(%s) - loaded %d bytes\n",
+                       userDefinedThemePath.c_str(), userDefinedTheme.size() );
+      }
+    }
+    else
+    {
+      DALI_LOG_ERROR("ResourceLoader::LoadTheme(%s) - failed to load\n", userDefinedThemePath.c_str());
+    }
+  }
+}
+
+bool FeedbackStyle::LoadTheme( const string& data )
+{
+  bool result = false;
+
+  try
+  {
+    LoadFromString( data );
+
+    result = true;
+  }
+  catch(...)
+  {
+    //Problem in user set theme, So fallback to use default theme.
+    DALI_LOG_ERROR( "FeedbackStyle::LoadTheme() Failed to load theme\n" );
+  }
+
+  return result;
+}
+
+void FeedbackStyle::LoadFromString( const string& data )
+{
+  Toolkit::JsonParser parser = Toolkit::JsonParser::New();
+  const Toolkit::TreeNode* root = NULL;
+
+  if( !parser.Parse( data ) )
+  {
+    DALI_LOG_WARNING( "JSON Parse Error:'%s'\n", parser.GetErrorDescription().c_str() );
+    DALI_LOG_WARNING( "JSON Parse Line :'%d (%d)'\n",
+                      parser.GetErrorLineNumber(),
+                      parser.GetErrorColumn() );
+  }
+  else
+  {
+    root = parser.GetRoot();
+  }
+
+  if(root)
+  {
+    // Clear previously loaded style
+    mStyleInfoLut.clear();
+
+    // Parse style
+    if( const TreeNode* node = root->GetChild("style") )
+    {
+      Toolkit::TreeNode::ConstIterator iter = node->CBegin();
+      Toolkit::TreeNode::ConstIterator end = node->CEnd();
+      for( ; iter != end; ++iter )
+      {
+        const char* key = (*iter).first;
+        FeedbackStyleInfo themeInfo;
+        themeInfo.mTypeName = key;
+
+        if( const TreeNode* signals = (*iter).second.GetChild("signals") )
+        {
+          TreeNode::ConstIterator signalIter = signals->CBegin();
+          TreeNode::ConstIterator signalEnd = signals->CEnd();
+          for( ; signalIter != signalEnd; ++signalIter )
+          {
+            SignalFeedbackInfo signalFeedbackInfo;
+
+            const TreeNode* type = (*signalIter).second.GetChild("type");
+            DALI_ASSERT_ALWAYS(type && TreeNode::STRING == type->GetType() && "Signal must have a type");
+            signalFeedbackInfo.mSignalName = type->GetString();
+
+            GetIfString( (*signalIter).second, "haptic-feedback-pattern",
+                         signalFeedbackInfo.mHasHapticFeedbackInfo,
+                         signalFeedbackInfo.mHapticFeedbackPattern );
+
+            GetIfString( (*signalIter).second, "haptic-feedback-file",
+                         signalFeedbackInfo.mHasHapticFeedbackInfo,
+                         signalFeedbackInfo.mHapticFeedbackFile );
+
+            GetIfString( (*signalIter).second, "sound-feedback-pattern",
+                         signalFeedbackInfo.mHasSoundFeedbackInfo,
+                         signalFeedbackInfo.mSoundFeedbackPattern );
+
+            GetIfString( (*signalIter).second, "haptic-feedback-file",
+                         signalFeedbackInfo.mHasSoundFeedbackInfo,
+                         signalFeedbackInfo.mSoundFeedbackFile );
+
+            if( signalFeedbackInfo.mHasHapticFeedbackInfo || signalFeedbackInfo.mHasSoundFeedbackInfo )
+            {
+              AddSignalInfo( themeInfo, signalFeedbackInfo );
+            }
+          }
+        }
+
+        mStyleInfoLut[key] = themeInfo;
+
+      } // for styles
+    } // if(style)
+  } // if(root)
+
+} // LoadFromString()
+
+void FeedbackStyle::AddSignalInfo( FeedbackStyleInfo& styleInfo, SignalFeedbackInfo signalInfo )
+{
+  bool updated = false;
+  std::vector<SignalFeedbackInfo>::iterator iter;
+
+  // If info exists for the signal then update it, else add new
+  for( iter = styleInfo.mSignalFeedbackInfoList.begin(); iter != styleInfo.mSignalFeedbackInfoList.end(); ++iter )
+  {
+    if( (*iter).mSignalName == signalInfo.mSignalName )
+    {
+      (*iter).mHasHapticFeedbackInfo = signalInfo.mHasHapticFeedbackInfo;
+      (*iter).mHapticFeedbackPattern = signalInfo.mHapticFeedbackPattern;
+      (*iter).mHapticFeedbackFile    = signalInfo.mHapticFeedbackFile;
+      (*iter).mHasSoundFeedbackInfo  = signalInfo.mHasSoundFeedbackInfo;
+      (*iter).mSoundFeedbackPattern  = signalInfo.mSoundFeedbackPattern;
+      (*iter).mSoundFeedbackFile     = signalInfo.mSoundFeedbackFile;
+
+      updated = true;
+      break;
+    }
+  }
+
+  if( !updated )
+  {
+    styleInfo.mSignalFeedbackInfoList.push_back( signalInfo );
+  }
+}
+
+void FeedbackStyle::PlayFeedback(const string& type, const string& signalName)
+{
+  const FeedbackStyleInfo styleInfo = GetStyleInfo(type);
+  SignalFeedbackInfoConstIter iter;
+
+  for(iter = styleInfo.mSignalFeedbackInfoList.begin(); iter != styleInfo.mSignalFeedbackInfoList.end(); ++iter)
+  {
+    const SignalFeedbackInfo& info = *iter;
+
+    if(info.mSignalName == signalName)
+    {
+      if(info.mHasHapticFeedbackInfo)
+      {
+        if(!info.mHapticFeedbackPattern.empty())
+        {
+          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FeedbackStyle::PlayFeedback Playing Haptic effect: Object type: %s, Signal type: %s, pattern type: %s\n",
+              type.c_str(), signalName.c_str(), info.mHapticFeedbackPattern.c_str());
+
+          mFeedback.PlayFeedbackPattern( FEEDBACK_TYPE_VIBRATION, GetFeedbackPattern(info.mHapticFeedbackPattern) );
+        }
+        else if(!info.mHapticFeedbackFile.empty())
+        {
+          mFeedback.PlayFile( info.mHapticFeedbackFile );
+        }
+      }
+
+      if(info.mHasSoundFeedbackInfo)
+      {
+        if(!info.mSoundFeedbackPattern.empty())
+        {
+          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FeedbackStyle::PlayFeedback Playing Sound effect: Object type: %s, Signal type: %s, pattern type: %s\n",
+              type.c_str(), signalName.c_str(), info.mHapticFeedbackPattern.c_str());
+
+          mFeedback.PlayFeedbackPattern( FEEDBACK_TYPE_SOUND, GetFeedbackPattern(info.mSoundFeedbackPattern) );
+        }
+        else if(!info.mSoundFeedbackFile.empty())
+        {
+          mFeedback.PlaySound( info.mSoundFeedbackFile );
+        }
+      }
+
+      break;
+    }
+  }
+}
+
+FeedbackPattern FeedbackStyle::GetFeedbackPattern( const string &pattern )
+{
+  if( 0 == mFeedbackPatternLut.size() )
+  {
+    mFeedbackPatternLut["FEEDBACK_PATTERN_NONE"]                = Dali::FEEDBACK_PATTERN_NONE;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_TAP"]                 = Dali::FEEDBACK_PATTERN_TAP;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_SIP"]                 = Dali::FEEDBACK_PATTERN_SIP;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_SIP_BACKSPACE"]       = Dali::FEEDBACK_PATTERN_SIP_BACKSPACE;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_MAX_CHARACTER"]       = Dali::FEEDBACK_PATTERN_MAX_CHARACTER;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY0"]                = Dali::FEEDBACK_PATTERN_KEY0;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY1"]                = Dali::FEEDBACK_PATTERN_KEY1;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY2"]                = Dali::FEEDBACK_PATTERN_KEY2;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY3"]                = Dali::FEEDBACK_PATTERN_KEY3;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY4"]                = Dali::FEEDBACK_PATTERN_KEY4;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY5"]                = Dali::FEEDBACK_PATTERN_KEY5;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY6"]                = Dali::FEEDBACK_PATTERN_KEY6;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY7"]                = Dali::FEEDBACK_PATTERN_KEY7;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY8"]                = Dali::FEEDBACK_PATTERN_KEY8;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY9"]                = Dali::FEEDBACK_PATTERN_KEY9;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY_STAR"]            = Dali::FEEDBACK_PATTERN_KEY_STAR;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY_SHARP"]           = Dali::FEEDBACK_PATTERN_KEY_SHARP;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_HOLD"]                = Dali::FEEDBACK_PATTERN_HOLD;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_MULTI_TAP"]           = Dali::FEEDBACK_PATTERN_MULTI_TAP;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_HW_TAP"]              = Dali::FEEDBACK_PATTERN_HW_TAP;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_HW_HOLD"]             = Dali::FEEDBACK_PATTERN_HW_HOLD;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_MESSAGE"]             = Dali::FEEDBACK_PATTERN_MESSAGE;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_MESSAGE_ON_CALL"]     = Dali::FEEDBACK_PATTERN_MESSAGE_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_EMAIL"]               = Dali::FEEDBACK_PATTERN_EMAIL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_EMAIL_ON_CALL"]       = Dali::FEEDBACK_PATTERN_EMAIL_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_WAKEUP"]              = Dali::FEEDBACK_PATTERN_WAKEUP;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_WAKEUP_ON_CALL"]      = Dali::FEEDBACK_PATTERN_WAKEUP_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_SCHEDULE"]            = Dali::FEEDBACK_PATTERN_SCHEDULE;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_SCHEDULE_ON_CALL"]    = Dali::FEEDBACK_PATTERN_SCHEDULE_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_TIMER"]               = Dali::FEEDBACK_PATTERN_TIMER;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_TIMER_ON_CALL"]       = Dali::FEEDBACK_PATTERN_TIMER_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_GENERAL"]             = Dali::FEEDBACK_PATTERN_GENERAL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_GENERAL_ON_CALL"]     = Dali::FEEDBACK_PATTERN_GENERAL_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_POWER_ON"]            = Dali::FEEDBACK_PATTERN_POWER_ON;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_POWER_OFF"]           = Dali::FEEDBACK_PATTERN_POWER_OFF;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_CHARGERCONN"]         = Dali::FEEDBACK_PATTERN_CHARGERCONN;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_CHARGERCONN_ON_CALL"] = Dali::FEEDBACK_PATTERN_CHARGERCONN_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_FULLCHARGED"]         = Dali::FEEDBACK_PATTERN_FULLCHARGED;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_FULLCHARGED_ON_CALL"] = Dali::FEEDBACK_PATTERN_FULLCHARGED_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_LOWBATT"]             = Dali::FEEDBACK_PATTERN_LOWBATT;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_LOWBATT_ON_CALL"]     = Dali::FEEDBACK_PATTERN_LOWBATT_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_LOCK"]                = Dali::FEEDBACK_PATTERN_LOCK;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_UNLOCK"]              = Dali::FEEDBACK_PATTERN_UNLOCK;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_CALLCONNECT"]         = Dali::FEEDBACK_PATTERN_CALLCONNECT;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_DISCALLCONNECT"]      = Dali::FEEDBACK_PATTERN_DISCALLCONNECT;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_MINUTEMINDER"]        = Dali::FEEDBACK_PATTERN_MINUTEMINDER;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_VIBRATION"]           = Dali::FEEDBACK_PATTERN_VIBRATION;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_SHUTTER"]             = Dali::FEEDBACK_PATTERN_SHUTTER;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_LIST_REORDER"]        = Dali::FEEDBACK_PATTERN_LIST_REORDER;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_SLIDER_SWEEP"]        = Dali::FEEDBACK_PATTERN_SLIDER_SWEEP;
+  }
+
+  std::map<const string, FeedbackPattern>::const_iterator iter( mFeedbackPatternLut.find( pattern ) );
+
+  if( iter != mFeedbackPatternLut.end() )
+  {
+    return iter->second;
+  }
+  else
+  {
+    DALI_LOG_ERROR( "Unknown feedback pattern type: %s, So Defaulting to FEEDBACK_PATTERN_NONE!\n" );
+    return Dali::FEEDBACK_PATTERN_NONE;
+  }
+}
+
+} // namespace Toolkit
+
+} // namespace Internal
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/feedback/feedback-style.h b/dali-toolkit/internal/feedback/feedback-style.h
new file mode 100644 (file)
index 0000000..0f8d270
--- /dev/null
@@ -0,0 +1,162 @@
+#ifndef __DALI_INTERNAL_FEEDBACK_STYLE_H__
+#define __DALI_INTERNAL_FEEDBACK_STYLE_H__
+
+/*
+ * 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <map>
+#include <dali/public-api/object/base-handle.h>
+#include <dali/devel-api/adaptor-framework/feedback-player.h>
+#include <dali/public-api/signals/connection-tracker.h>
+#include <dali/public-api/adaptor-framework/style-change.h>
+#include <dali/public-api/signals/slot-delegate.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/feedback/feedback-ids.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+struct FeedbackStyleInfo;
+struct SignalFeedbackInfo;
+
+/**
+ * Plays feedback effects for Dali-Toolkit UI Controls.
+ *
+ * This functionality relies on an adaptor plugin.
+ * (And will have no effect if this is not loaded)
+ *
+ */
+class FeedbackStyle : public ConnectionTracker
+{
+public:
+
+  /**
+   * Constructor.
+   */
+  FeedbackStyle();
+
+  /**
+   * The destructor
+   */
+  ~FeedbackStyle();
+
+  /**
+   * Called to start playing feedback effects.
+   */
+  void Start();
+
+  /**
+   * Called to stop playing feedback effects.
+   */
+  void Stop();
+
+  /**
+   * Callback function to play a feedback effect when a signal is emitted for an object
+   * Plays feedback effect.
+   * @param [in] type The Object type
+   * @param [in] signalName The name of the signal
+   */
+  void PlayFeedback(const std::string& type, const std::string& signalName);
+
+  /**
+   * Connects feedback to signals for the newly created object
+   * @param [in] object Handle to the newly created object
+   */
+  void ObjectCreated( BaseHandle object );
+
+  /**
+   * Style changed so reload the theme file
+   * @param [in] userDefinedThemePath Theme filename path
+   * @param [in] styleChange The type of style change
+   */
+  void StyleChanged(const std::string& userDefinedThemePath, StyleChange::Type styleChange);
+
+private:
+
+  /**
+   * Helper to retrieve styleInfo from mStyleInfoLut
+   * @param type A string described a type of object
+   * @return The style information for the given object
+   */
+  const FeedbackStyleInfo& GetStyleInfo( const std::string& type) const;
+
+  /**
+   * Callback function for Dali::Toolkit::PushButton::SignalPressed signal
+   * Plays feedback effect.
+   * @param [in] effect The feedback effect to play
+   */
+  bool LoadTheme(const std::string& data);
+
+  /**
+   * Loads a string representation the theme.
+   * @param [in] data A string represenation of the theme.
+   * @param [in] format The string representation format ie JSON.
+   */
+  void LoadFromString( const std::string& data );
+
+  /**
+   * Helper to store signal information.
+   * @param [in] styleInfo The information will be stored here.
+   * @param [in] signalInfo The information to add.
+   */
+  void AddSignalInfo( FeedbackStyleInfo& styleInfo, SignalFeedbackInfo signalInfo );
+
+  /**
+   * Map a pattern string to feedback pattern ID.
+   * @param [in] pattern The pattern string.
+   * @return A feedback pattern ID.
+   */
+  FeedbackPattern GetFeedbackPattern( const std::string& pattern );
+
+  /**
+   * Plays a feedback effect
+   * @param [in] type The feedback type haptic or sound
+   * @param [in] effect The feedback effect to play
+   */
+  void PlayEffect(FeedbackType type, FeedbackPattern effect);
+
+  /**
+   * Plays a haptic or sound effect file
+   * @param [in] type The feedback type haptic or sound
+   * @param [in] file The path to the file containing the effect
+   */
+  void PlayFile(FeedbackType type, const std::string& file);
+
+private:
+  Dali::FeedbackPlayer mFeedback;
+
+  std::map<const std::string, FeedbackPattern>   mFeedbackPatternLut; ///< Used to convert feedback pattern strings into enumerated values
+  std::map<const std::string, FeedbackStyleInfo> mStyleInfoLut;       ///< Converts key strings into style information
+
+  SlotDelegate< FeedbackStyle > mConnections; ///< Maintains the connections to the Object registry.
+};
+
+} // namespace Toolkit
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_FEEDBACK_STYLE_H__
index 807c3a2..0b8b570 100644 (file)
@@ -51,6 +51,9 @@ toolkit_src_files = \
    $(toolkit_src_dir)/controls/text-controls/text-selection-toolbar-impl.cpp \
    $(toolkit_src_dir)/controls/tool-bar/tool-bar-impl.cpp \
    $(toolkit_src_dir)/accessibility-manager/accessibility-manager-impl.cpp \
+   \
+   $(toolkit_src_dir)/feedback/feedback-style.cpp \
+   \
    $(toolkit_src_dir)/focus-manager/keyboard-focus-manager-impl.cpp \
    $(toolkit_src_dir)/focus-manager/keyinput-focus-manager-impl.cpp \
    $(toolkit_src_dir)/filters/blur-two-pass-filter.cpp \
index e0e1d4c..c245c15 100644 (file)
@@ -27,6 +27,7 @@
 #include <dali-toolkit/public-api/controls/control.h>
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/devel-api/styling/style-manager.h>
+#include <dali-toolkit/internal/feedback/feedback-style.h>
 
 namespace
 {
@@ -99,7 +100,8 @@ Toolkit::StyleManager StyleManager::Get()
 StyleManager::StyleManager()
 : mOrientationDegrees( 0 ),  // Portrait
   mDefaultFontSize( -1 ),
-  mThemeFile( DEFAULT_THEME )
+  mThemeFile( DEFAULT_THEME ),
+  mFeedbackStyle( NULL )
 {
   // Add theme builder constants
   mThemeBuilderConstants[ PACKAGE_PATH_KEY ] = DEFAULT_PACKAGE_PATH;
@@ -111,10 +113,15 @@ StyleManager::StyleManager()
 
     mDefaultFontSize = mStyleMonitor.GetDefaultFontSize();
   }
+
+  // Sound & haptic style
+  mFeedbackStyle = new FeedbackStyle();
+
 }
 
 StyleManager::~StyleManager()
 {
+  delete mFeedbackStyle;
 }
 
 void StyleManager::SetOrientationValue( int orientation )
@@ -245,6 +252,7 @@ void StyleManager::BuildQualifiedStyleName( const std::string& styleName, const
 void StyleManager::ApplyStyle( Toolkit::Builder builder, Toolkit::Control control )
 {
   std::string styleName = control.GetStyleName();
+
   if( styleName.empty() )
   {
     // Convert control name to lower case
@@ -293,6 +301,19 @@ void StyleManager::ApplyThemeStyle( Toolkit::Control control )
   }
 }
 
+void StyleManager::ApplyThemeStyleAtInit( Toolkit::Control control )
+{
+  if( mThemeBuilder )
+  {
+    ApplyStyle( mThemeBuilder, control );
+  }
+
+  if(mFeedbackStyle)
+  {
+    mFeedbackStyle->ObjectCreated( control );
+  }
+}
+
 void StyleManager::ApplyStyle( Toolkit::Control control, const std::string& jsonFileName, const std::string& styleName )
 {
   bool builderReady = false;
@@ -361,8 +382,14 @@ void StyleManager::RequestDefaultTheme()
 void StyleManager::SetTheme()
 {
   mThemeBuilder = CreateBuilder( mThemeBuilderConstants );
-  if ( LoadJSON( mThemeBuilder, mThemeFile ) )
+
+  if( LoadJSON( mThemeBuilder, mThemeFile ) )
   {
+    if(mFeedbackStyle)
+    {
+      mFeedbackStyle->StyleChanged( mThemeFile, StyleChange::THEME_CHANGE );
+    }
+
     mStyleChangeSignal.Emit( Toolkit::StyleManager::Get(), StyleChange::THEME_CHANGE );
   }
   else
index c612f7d..86c6d4c 100644 (file)
@@ -38,6 +38,9 @@ namespace Toolkit
 
 namespace Internal
 {
+
+class FeedbackStyle;
+
 /**
  * @copydoc Toolkit::StyleManager
  */
@@ -111,6 +114,13 @@ public:
   void ApplyThemeStyle( Toolkit::Control control );
 
   /**
+   * @brief Apply the theme style to a control at initialization.
+   *
+   * @param[in] control The control to apply style.
+   */
+  void ApplyThemeStyleAtInit( Toolkit::Control control );
+
+  /**
    * @copydoc Toolkit::StyleManager::ApplyStyle
    */
   void ApplyStyle( Toolkit::Control control, const std::string& jsonFileName, const std::string& styleName );
@@ -251,6 +261,8 @@ private:
 
   BuilderMap mBuilderCache;           ///< Cache of builders keyed by JSON file name
 
+  Toolkit::Internal::FeedbackStyle* mFeedbackStyle; ///< Feedback style
+
   // Signals
   Toolkit::StyleManager::StyleChangeSignalType       mStyleChangeSignal;         ///< Emitted when the style( theme/font ) changes
 };
index a22cc90..49fe080 100644 (file)
@@ -273,6 +273,7 @@ struct Decorator::Impl : public ConnectionTracker
     mScrollThreshold( SCROLL_THRESHOLD ),
     mScrollSpeed( SCROLL_SPEED ),
     mScrollDistance( SCROLL_DISTANCE ),
+    mTextDepth( 0u ),
     mActiveCopyPastePopup( false ),
     mCursorBlinkStatus( true ),
     mPrimaryCursorVisible( false ),
@@ -296,6 +297,7 @@ struct Decorator::Impl : public ConnectionTracker
 
     // Show or hide the cursors
     CreateCursors();
+
     if( mPrimaryCursor )
     {
       const CursorImpl& cursor = mCursor[PRIMARY_CURSOR];
@@ -338,7 +340,7 @@ struct Decorator::Impl : public ConnectionTracker
         CreateGrabHandle();
 
         grabHandle.actor.SetPosition( position.x,
-                                      position.y + grabHandle.lineHeight );
+                                      grabHandle.lineHeight ); // TODO : Fix for multiline.
       }
       grabHandle.actor.SetVisible( isVisible );
     }
@@ -367,13 +369,13 @@ struct Decorator::Impl : public ConnectionTracker
         if( isPrimaryVisible )
         {
           primary.actor.SetPosition( primaryPosition.x,
-                                     primaryPosition.y + primary.lineHeight );
+                                     primary.lineHeight ); // TODO : Fix for multiline.
         }
 
         if( isSecondaryVisible )
         {
           secondary.actor.SetPosition( secondaryPosition.x,
-                                       secondaryPosition.y + secondary.lineHeight );
+                                       secondary.lineHeight ); // TODO : Fix for multiline.
         }
       }
       primary.actor.SetVisible( isPrimaryVisible );
index 1053ea9..fe8da41 100644 (file)
 // EXTERNAL INCLUDES
 #include <dali/public-api/actors/image-actor.h>
 #include <dali/public-api/common/stage.h>
+#include <dali/integration-api/debug.h>
 
 #define MAKE_SHADER(A)#A
 
 namespace
 {
+
+#if defined(DEBUG_ENABLED)
+  Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING");
+#endif
+
 const char* VERTEX_SHADER = MAKE_SHADER(
 attribute mediump vec2    aPosition;
 attribute mediump vec2    aTexCoord;
@@ -77,7 +83,8 @@ void main()
   gl_FragColor = vec4(uColor.rgb, uColor.a*color.r);
 }
 );
-}
+
+} // unnamed namespace
 
 namespace Dali
 {
@@ -95,32 +102,12 @@ AtlasGlyphManager::AtlasGlyphManager()
   mShadowShader = Shader::New( VERTEX_SHADER_SHADOW, FRAGMENT_SHADER_SHADOW, Dali::Shader::HINT_MODIFIES_GEOMETRY );
 }
 
-AtlasGlyphManager::~AtlasGlyphManager()
-{
-  // Clear up any remaining references
-  for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
-        fontGlyphRecordIt != mFontGlyphRecords.end();
-        ++fontGlyphRecordIt )
-  {
-    for ( Vector< GlyphRecordEntry >::Iterator glyphRecordEntryIt = fontGlyphRecordIt->mGlyphRecords.Begin();
-          glyphRecordEntryIt != fontGlyphRecordIt->mGlyphRecords.End();
-          ++glyphRecordEntryIt )
-    {
-      mAtlasManager.Remove( glyphRecordEntryIt->mImageId );
-    }
-  }
-}
-
-AtlasGlyphManagerPtr AtlasGlyphManager::New()
-{
-  AtlasGlyphManagerPtr internal = new AtlasGlyphManager();
-  return internal;
-}
-
 void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
                              const BufferImage& bitmap,
                              Dali::Toolkit::AtlasManager::AtlasSlot& slot )
 {
+  DALI_LOG_INFO( gLogFilter, Debug::General, "Added glyph, font: %d index: %d\n", glyph.fontId, glyph.index );
+
   mAtlasManager.Add( bitmap, slot );
 
   GlyphRecordEntry record;
@@ -166,7 +153,7 @@ void AtlasGlyphManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
 }
 
 bool AtlasGlyphManager::Cached( Text::FontId fontId,
-                                uint32_t index,
+                                Text::GlyphIndex index,
                                 Dali::Toolkit::AtlasManager::AtlasSlot& slot )
 {
   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
@@ -215,41 +202,65 @@ Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
 
 const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
 {
+  std::ostringstream verboseMetrics;
+
   mMetrics.mGlyphCount = 0u;
   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
         fontGlyphRecordIt != mFontGlyphRecords.end();
         ++fontGlyphRecordIt )
   {
     mMetrics.mGlyphCount += fontGlyphRecordIt->mGlyphRecords.Size();
+
+    verboseMetrics << "[FontId " << fontGlyphRecordIt->mFontId << " Glyph ";
+    for ( Vector< GlyphRecordEntry >::Iterator glyphRecordEntryIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+          glyphRecordEntryIt != fontGlyphRecordIt->mGlyphRecords.End();
+          ++glyphRecordEntryIt )
+    {
+      verboseMetrics << glyphRecordEntryIt->mIndex << "(" << glyphRecordEntryIt->mCount << ") ";
+    }
+    verboseMetrics << "] ";
   }
+  mMetrics.mVerboseGlyphCounts = verboseMetrics.str();
+
   mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
+
   return mMetrics;
 }
 
-void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta )
+void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta )
 {
-  for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
-        fontGlyphRecordIt != mFontGlyphRecords.end();
-        ++fontGlyphRecordIt )
+  if( 0 != delta )
   {
-    if ( fontGlyphRecordIt->mFontId == fontId )
+    DALI_LOG_INFO( gLogFilter, Debug::General, "AdjustReferenceCount %d, font: %d index: %d\n", delta, fontId, index );
+
+    for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+          fontGlyphRecordIt != mFontGlyphRecords.end();
+          ++fontGlyphRecordIt )
     {
-      for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
-            glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
-            ++glyphRecordIt )
+      if ( fontGlyphRecordIt->mFontId == fontId )
       {
-        if ( glyphRecordIt->mImageId == imageId )
+        for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+              glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
+              ++glyphRecordIt )
         {
-          glyphRecordIt->mCount += delta;
-          if ( !glyphRecordIt->mCount )
+          if ( glyphRecordIt->mIndex == index )
           {
-            mAtlasManager.Remove( glyphRecordIt->mImageId );
-            fontGlyphRecordIt->mGlyphRecords.Remove( glyphRecordIt );
+            glyphRecordIt->mCount += delta;
+            DALI_ASSERT_DEBUG( glyphRecordIt->mCount >= 0 && "Glyph ref-count should not be negative" );
+
+            if ( !glyphRecordIt->mCount )
+            {
+              mAtlasManager.Remove( glyphRecordIt->mImageId );
+              fontGlyphRecordIt->mGlyphRecords.Remove( glyphRecordIt );
+            }
+            return;
           }
-          return;
         }
       }
     }
+
+    // Should not arrive here
+    DALI_ASSERT_DEBUG( false && "Failed to adjust ref-count" );
   }
 }
 
@@ -263,6 +274,11 @@ Sampler AtlasGlyphManager::GetSampler( uint32_t atlasId ) const
   return mAtlasManager.GetSampler( atlasId );
 }
 
+AtlasGlyphManager::~AtlasGlyphManager()
+{
+  // mAtlasManager handle is automatically released here
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index 5a90d17..ce937a8 100644 (file)
@@ -62,14 +62,10 @@ public:
     Vector< GlyphRecordEntry > mGlyphRecords;
   };
 
-  AtlasGlyphManager();
-
-  virtual ~AtlasGlyphManager();
-
-/**
-   * Create a new AtlasGlyphManager
+  /**
+   * @brief Constructor
    */
-  static AtlasGlyphManagerPtr New();
+  AtlasGlyphManager();
 
   /**
    * @copydoc Toolkit::AtlasGlyphManager::Add
@@ -116,7 +112,7 @@ public:
   /**
    * @copydoc toolkit::AtlasGlyphManager::AdjustReferenceCount
    */
-  void AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta );
+  void AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta );
 
   /**
    * @copydoc Toolkit::AtlasGlyphManager::GetMaterial
@@ -149,6 +145,13 @@ public:
     return mShadowShader;
   }
 
+protected:
+
+  /**
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~AtlasGlyphManager();
+
 private:
 
   Dali::Toolkit::AtlasManager mAtlasManager;          ///> Atlas Manager created by GlyphManager
index 7e1facd..e71ad89 100644 (file)
@@ -128,9 +128,9 @@ const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
   return GetImplementation(*this).GetMetrics();
 }
 
-void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta )
+void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta )
 {
-  GetImplementation(*this).AdjustReferenceCount( fontId, imageId, delta );
+  GetImplementation(*this).AdjustReferenceCount( fontId, index, delta );
 }
 
 Shader AtlasGlyphManager::GetEffectBufferShader() const
index 6096612..a74ce28 100644 (file)
@@ -50,8 +50,9 @@ public:
     ~Metrics()
     {}
 
-    uint32_t mGlyphCount;                   // number of glyphs being managed
-    AtlasManager::Metrics mAtlasMetrics;    // metrics from the Atlas Manager
+    uint32_t mGlyphCount;                   ///< number of glyphs being managed
+    std::string mVerboseGlyphCounts;        ///< a verbose list of the glyphs + ref counts
+    AtlasManager::Metrics mAtlasMetrics;    ///< metrics from the Atlas Manager
   };
 
   /**
@@ -173,13 +174,13 @@ public:
   const Metrics& GetMetrics();
 
   /**
-   * @brief Adjust the reference count for an imageId and remove cache entry if it becomes free
+   * @brief Adjust the reference count for glyph
    *
-   * @param[in] fontId the font this image came from
-   * @param[in] imageId The imageId
-   * @param[in] delta adjustment to make to reference count
+   * @param[in] fontId The font this image came from
+   * @param[in] index The index of the glyph
+   * @param[in] delta The adjustment to make to the reference count
    */
-  void AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta );
+  void AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta );
 
   /**
    * @brief Get Shader used for rendering glyph effect buffers
index a9810c9..d0cedf4 100644 (file)
@@ -134,14 +134,11 @@ struct AtlasRenderer::Impl : public ConnectionTracker
       style = STYLE_DROP_SHADOW;
     }
 
-    if ( mTextCache.Size() )
-    {
-      // Update the glyph cache with any changes to current text
-      RemoveText( glyphs );
-    }
-
     CalculateBlocksSize( glyphs );
 
+    // Avoid emptying mTextCache (& removing references) until after incremented references for the new text
+    Vector< TextCacheEntry > newTextCache;
+
     for( uint32_t i = 0, glyphSize = glyphs.Size(); i < glyphSize; ++i )
     {
       const GlyphInfo& glyph = glyphs[ i ];
@@ -235,13 +232,18 @@ struct AtlasRenderer::Impl : public ConnectionTracker
             mGlyphManager.Add( glyph, bitmap, slot );
           }
         }
+        else
+        {
+          // We have 2+ copies of the same glyph
+          mGlyphManager.AdjustReferenceCount( glyph.fontId, glyph.index, 1/*increment*/ );
+        }
 
         // Generate mesh data for this quad, plugging in our supplied position
         mGlyphManager.GenerateMeshData( slot.mImageId, position, newMesh );
         textCacheEntry.mFontId = glyph.fontId;
         textCacheEntry.mImageId = slot.mImageId;
         textCacheEntry.mIndex = glyph.index;
-        mTextCache.PushBack( textCacheEntry );
+        newTextCache.PushBack( textCacheEntry );
 
         // Find an existing mesh data object to attach to ( or create a new one, if we can't find one using the same atlas)
         StitchTextMesh( meshContainer,
@@ -256,6 +258,10 @@ struct AtlasRenderer::Impl : public ConnectionTracker
       }
     }
 
+    // Now remove references for the old text
+    RemoveText();
+    mTextCache.Swap( newTextCache );
+
     if ( underlineEnabled )
     {
       // Check to see if any of the text needs an underline
@@ -292,9 +298,12 @@ struct AtlasRenderer::Impl : public ConnectionTracker
                                                 metrics.mGlyphCount,
                                                 metrics.mAtlasMetrics.mAtlasCount,
                                                 metrics.mAtlasMetrics.mTextureMemoryUsed / 1024 );
+
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "%s\n", metrics.mVerboseGlyphCounts.c_str() );
+
     for ( uint32_t i = 0; i < metrics.mAtlasMetrics.mAtlasCount; ++i )
     {
-      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Atlas [%i] %sPixels: %s Size: %ix%i, BlockSize: %ix%i, BlocksUsed: %i/%i\n",
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "   Atlas [%i] %sPixels: %s Size: %ix%i, BlockSize: %ix%i, BlocksUsed: %i/%i\n",
                                                  i + 1, i > 8 ? "" : " ",
                                                  metrics.mAtlasMetrics.mAtlasMetrics[ i ].mPixelFormat == Pixel::L8 ? "L8  " : "BGRA",
                                                  metrics.mAtlasMetrics.mAtlasMetrics[ i ].mSize.mWidth,
@@ -307,6 +316,15 @@ struct AtlasRenderer::Impl : public ConnectionTracker
 #endif
   }
 
+  void RemoveText()
+  {
+    for ( Vector< TextCacheEntry >::Iterator oldTextIter = mTextCache.Begin(); oldTextIter != mTextCache.End(); ++oldTextIter )
+    {
+      mGlyphManager.AdjustReferenceCount( oldTextIter->mFontId, oldTextIter->mIndex, -1/*decrement*/ );
+    }
+    mTextCache.Resize( 0 );
+  }
+
   Actor CreateMeshActor( const MeshRecord& meshRecord )
   {
     PropertyBuffer quadVertices = PropertyBuffer::New( mQuadVertexFormat, meshRecord.mMesh.mVertices.Size() );
@@ -442,58 +460,6 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     }
   }
 
-  void RemoveText( const Vector<GlyphInfo>& glyphs )
-  {
-    Vector< CheckEntry > checked;
-    CheckEntry checkEntry;
-
-    for ( Vector< TextCacheEntry >::Iterator tCit = mTextCache.Begin(); tCit != mTextCache.End(); ++tCit )
-    {
-      uint32_t index = tCit->mIndex;
-      uint32_t fontId = tCit->mFontId;
-
-      // Check that this character has not already been checked...
-      bool wasChecked = false;
-      for ( Vector< CheckEntry >::Iterator cEit = checked.Begin(); cEit != checked.End(); ++cEit )
-      {
-        if ( fontId == cEit->mFontId && index == cEit->mIndex )
-        {
-          wasChecked = true;
-        }
-      }
-
-      if ( !wasChecked )
-      {
-
-        int32_t newCount = 0;
-        int32_t oldCount = 0;
-
-        // How many times does this character occur in the old text ?
-        for ( Vector< TextCacheEntry >::Iterator oTcit = mTextCache.Begin(); oTcit != mTextCache.End(); ++oTcit )
-        {
-          if ( fontId == oTcit->mFontId && index == oTcit->mIndex )
-          {
-            oldCount++;
-          }
-        }
-
-        // And how many times in the new ?
-        for ( Vector< GlyphInfo >::Iterator cGit = glyphs.Begin(); cGit != glyphs.End(); ++cGit )
-        {
-          if ( fontId == cGit->fontId && index == cGit->index )
-          {
-            newCount++;
-          }
-        }
-        mGlyphManager.AdjustReferenceCount( fontId, tCit->mImageId, newCount - oldCount );
-        checkEntry.mIndex = index;
-        checkEntry.mFontId = fontId;
-        checked.PushBack( checkEntry );
-      }
-    }
-    mTextCache.Resize( 0 );
-  }
-
   void CalculateBlocksSize( const Vector<GlyphInfo>& glyphs )
   {
     MaxBlockSize maxBlockSize;
@@ -779,7 +745,6 @@ AtlasRenderer::AtlasRenderer()
 
 AtlasRenderer::~AtlasRenderer()
 {
-  Vector< GlyphInfo > emptyGlyphs;
-  mImpl->RemoveText( emptyGlyphs );
+  mImpl->RemoveText();
   delete mImpl;
 }
index 5c93ffe..12fbb2f 100644 (file)
@@ -81,8 +81,8 @@ namespace Text
  * @param[in] glyphIndex The index to the first glyph.
  * @param[in] numberOfGlyphs The number of glyphs.
  * @param[out] glyphMetrics Some glyph metrics (font height, advance, ascender and x bearing).
- * @param[in]
- * @param[in]
+ * @param[in] visualModel The visual model.
+ * @param[in] fontClient The font client.
  */
 void GetGlyphsMetrics( GlyphIndex glyphIndex,
                        Length numberOfGlyphs,
@@ -663,7 +663,7 @@ void Controller::Impl::OnHandleEvent( const Event& event )
 
       if( handleStopScrolling )
       {
-        mEventData->mUpdateLeftSelectionPosition = ( mEventData->mLeftSelectionPosition != handlePosition ) && ( mEventData->mRightSelectionPosition != handlePosition);
+        mEventData->mUpdateLeftSelectionPosition = ( mEventData->mRightSelectionPosition != handlePosition );
         mEventData->mScrollAfterUpdatePosition = mEventData->mUpdateLeftSelectionPosition;
 
         if( mEventData->mUpdateLeftSelectionPosition )
@@ -681,9 +681,8 @@ void Controller::Impl::OnHandleEvent( const Event& event )
 
       if( handleStopScrolling )
       {
-        mEventData->mUpdateRightSelectionPosition = ( mEventData->mRightSelectionPosition != handlePosition ) && ( mEventData->mLeftSelectionPosition != handlePosition );
+        mEventData->mUpdateRightSelectionPosition = ( mEventData->mLeftSelectionPosition != handlePosition );
         mEventData->mScrollAfterUpdatePosition = mEventData->mUpdateRightSelectionPosition;
-
         if( mEventData->mUpdateRightSelectionPosition )
         {
           mEventData->mRightSelectionPosition = handlePosition;
@@ -705,74 +704,84 @@ void Controller::Impl::OnHandleEvent( const Event& event )
 
     ClampHorizontalScroll( actualSize );
 
+    bool endOfScroll = false;
     if( Vector2::ZERO == ( currentScrollPosition - mEventData->mScrollPosition ) )
     {
       // Notify the decorator there is no more text to scroll.
       // The decorator won't send more scroll events.
       mEventData->mDecorator->NotifyEndOfScroll();
+      // Still need to set the position of the handle.
+      endOfScroll = true;
     }
-    else
-    {
-      const bool scrollRightDirection = xSpeed > 0.f;
-      const bool leftSelectionHandleEvent = Event::LEFT_SELECTION_HANDLE_EVENT == event.type;
-      const bool rightSelectionHandleEvent = Event::RIGHT_SELECTION_HANDLE_EVENT == event.type;
 
-      if( Event::GRAB_HANDLE_EVENT == event.type )
-      {
-        ChangeState( EventData::GRAB_HANDLE_PANNING );
+    // Set the position of the handle.
+    const bool scrollRightDirection = xSpeed > 0.f;
+    const bool leftSelectionHandleEvent = Event::LEFT_SELECTION_HANDLE_EVENT == event.type;
+    const bool rightSelectionHandleEvent = Event::RIGHT_SELECTION_HANDLE_EVENT == event.type;
 
-        Vector2 position = mEventData->mDecorator->GetPosition( GRAB_HANDLE );
+    if( Event::GRAB_HANDLE_EVENT == event.type )
+    {
+      ChangeState( EventData::GRAB_HANDLE_PANNING );
 
-        // Position the grag handle close to either the left or right edge.
-        position.x = scrollRightDirection ? 0.f : mControlSize.width;
+      Vector2 position = mEventData->mDecorator->GetPosition( GRAB_HANDLE );
 
-        // Get the new handle position.
-        // The grab handle's position is in decorator coords. Need to transforms to text coords.
-        const CharacterIndex handlePosition = GetClosestCursorIndex( position.x - mEventData->mScrollPosition.x - mAlignmentOffset.x,
-                                                                     position.y - mEventData->mScrollPosition.y - mAlignmentOffset.y );
+      // Position the grag handle close to either the left or right edge.
+      position.x = scrollRightDirection ? 0.f : mControlSize.width;
 
-        mEventData->mUpdateCursorPosition = mEventData->mPrimaryCursorPosition != handlePosition;
-        mEventData->mScrollAfterUpdatePosition = mEventData->mUpdateCursorPosition;
-        mEventData->mPrimaryCursorPosition = handlePosition;
-      }
-      else if( leftSelectionHandleEvent || rightSelectionHandleEvent )
-      {
-        // TODO: This is recalculating the selection box every time the text is scrolled with the selection handles.
-        //       Think if something can be done to save power.
+      // Get the new handle position.
+      // The grab handle's position is in decorator coords. Need to transforms to text coords.
+      const CharacterIndex handlePosition = GetClosestCursorIndex( position.x - mEventData->mScrollPosition.x - mAlignmentOffset.x,
+                                                                   position.y - mEventData->mScrollPosition.y - mAlignmentOffset.y );
 
-        ChangeState( EventData::SELECTION_HANDLE_PANNING );
+      mEventData->mUpdateCursorPosition = mEventData->mPrimaryCursorPosition != handlePosition;
+      mEventData->mScrollAfterUpdatePosition = mEventData->mUpdateCursorPosition;
+      mEventData->mPrimaryCursorPosition = handlePosition;
+    }
+    else if( leftSelectionHandleEvent || rightSelectionHandleEvent )
+    {
+      // TODO: This is recalculating the selection box every time the text is scrolled with the selection handles.
+      //       Think if something can be done to save power.
 
-        Vector2 position = mEventData->mDecorator->GetPosition( leftSelectionHandleEvent ? Text::LEFT_SELECTION_HANDLE : Text::RIGHT_SELECTION_HANDLE );
+      ChangeState( EventData::SELECTION_HANDLE_PANNING );
 
-        // Position the selection handle close to either the left or right edge.
-        position.x = scrollRightDirection ? 0.f : mControlSize.width;
+      Vector2 position = mEventData->mDecorator->GetPosition( leftSelectionHandleEvent ? Text::LEFT_SELECTION_HANDLE : Text::RIGHT_SELECTION_HANDLE );
 
-        // Get the new handle position.
-        // The selection handle's position is in decorator coords. Need to transforms to text coords.
-        const CharacterIndex handlePosition = GetClosestCursorIndex( position.x - mEventData->mScrollPosition.x - mAlignmentOffset.x,
-                                                                     position.y - mEventData->mScrollPosition.y - mAlignmentOffset.y );
+      // Position the selection handle close to either the left or right edge.
+      position.x = scrollRightDirection ? 0.f : mControlSize.width;
 
-        if( leftSelectionHandleEvent )
+      // Get the new handle position.
+      // The selection handle's position is in decorator coords. Need to transforms to text coords.
+      const CharacterIndex handlePosition = GetClosestCursorIndex( position.x - mEventData->mScrollPosition.x - mAlignmentOffset.x,
+                                                                   position.y - mEventData->mScrollPosition.y - mAlignmentOffset.y );
+
+      if( leftSelectionHandleEvent )
+      {
+        const bool differentHandles = ( mEventData->mLeftSelectionPosition != handlePosition ) && ( mEventData->mRightSelectionPosition != handlePosition );
+        mEventData->mUpdateLeftSelectionPosition = endOfScroll || differentHandles;
+        if( differentHandles )
         {
-          mEventData->mUpdateLeftSelectionPosition = handlePosition != mEventData->mLeftSelectionPosition;
           mEventData->mLeftSelectionPosition = handlePosition;
         }
-        else
+      }
+      else
+      {
+        const bool differentHandles = ( mEventData->mRightSelectionPosition != handlePosition ) && ( mEventData->mLeftSelectionPosition != handlePosition );
+        mEventData->mUpdateRightSelectionPosition = endOfScroll || differentHandles;
+        if( differentHandles )
         {
-          mEventData->mUpdateRightSelectionPosition = handlePosition != mEventData->mRightSelectionPosition;
           mEventData->mRightSelectionPosition = handlePosition;
         }
+      }
 
-        if( mEventData->mUpdateLeftSelectionPosition || mEventData->mUpdateRightSelectionPosition )
-        {
-          RepositionSelectionHandles( mEventData->mLeftSelectionPosition,
-                                      mEventData->mRightSelectionPosition );
+      if( mEventData->mUpdateLeftSelectionPosition || mEventData->mUpdateRightSelectionPosition )
+      {
+        RepositionSelectionHandles( mEventData->mLeftSelectionPosition,
+                                    mEventData->mRightSelectionPosition );
 
-          mEventData->mScrollAfterUpdatePosition = true;
-        }
+        mEventData->mScrollAfterUpdatePosition = true;
       }
-      mEventData->mDecoratorUpdated = true;
     }
+    mEventData->mDecoratorUpdated = true;
   } // end ( HANDLE_SCROLLING == state )
 }
 
@@ -928,8 +937,9 @@ void Controller::Impl::RepositionSelectionHandles( CharacterIndex selectionStart
     std::swap( selectionStart, selectionEnd );
   }
 
-  GlyphIndex glyphStart = *( charactersToGlyphBuffer + selectionStart );
-  GlyphIndex glyphEnd = *( charactersToGlyphBuffer + ( selectionEnd - 1u ) ) + *( glyphsPerCharacterBuffer + ( selectionEnd - 1u ) ) - 1u;
+  const GlyphIndex glyphStart = *( charactersToGlyphBuffer + selectionStart );
+  const Length numberOfGlyphs = *( glyphsPerCharacterBuffer + ( selectionEnd - 1u ) );
+  const GlyphIndex glyphEnd = *( charactersToGlyphBuffer + ( selectionEnd - 1u ) ) + ( ( numberOfGlyphs > 0 ) ? numberOfGlyphs - 1u : 0u );
 
   mEventData->mDecorator->SwapSelectionHandlesEnabled( firstLine.direction != indicesSwapped );
 
@@ -937,6 +947,7 @@ void Controller::Impl::RepositionSelectionHandles( CharacterIndex selectionStart
 
   for( GlyphIndex index = glyphStart; index <= glyphEnd; ++index )
   {
+    // TODO: Fix the LATIN ligatures. i.e ff, fi, etc...
     const GlyphInfo& glyph = *( glyphsBuffer + index );
     const Vector2& position = *( positionsBuffer + index );
 
@@ -1386,30 +1397,26 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
     return;
   }
 
-  // Get the previous logical index.
-  const CharacterIndex previousLogical = isFirstPosition ? 0u : logical - 1u;
+  // 'logical' is the logical 'cursor' index.
+  // Get the next and current logical 'character' index.
+  const CharacterIndex nextCharacterIndex = logical;
+  const CharacterIndex characterIndex = isFirstPosition ? logical : logical - 1u;
 
-  // Decrease the logical index if it's the last one.
-  if( isLastPosition )
-  {
-    --logical;
-  }
-
-  // Get the direction of the character and the previous one.
+  // Get the direction of the character and the next one.
   const CharacterDirection* const modelCharacterDirectionsBuffer = ( 0u != mLogicalModel->mCharacterDirections.Count() ) ? mLogicalModel->mCharacterDirections.Begin() : NULL;
 
   CharacterDirection isCurrentRightToLeft = false;
-  CharacterDirection isPreviousRightToLeft = false;
+  CharacterDirection isNextRightToLeft = false;
   if( NULL != modelCharacterDirectionsBuffer ) // If modelCharacterDirectionsBuffer is NULL, it means the whole text is left to right.
   {
-    isCurrentRightToLeft = *( modelCharacterDirectionsBuffer + logical );
-    isPreviousRightToLeft = *( modelCharacterDirectionsBuffer + previousLogical );
+    isCurrentRightToLeft = *( modelCharacterDirectionsBuffer + characterIndex );
+    isNextRightToLeft = *( modelCharacterDirectionsBuffer + nextCharacterIndex );
   }
 
   // Get the line where the character is laid-out.
   const LineRun* modelLines = mVisualModel->mLines.Begin();
 
-  const LineIndex lineIndex = mVisualModel->GetLineOfCharacter( logical );
+  const LineIndex lineIndex = mVisualModel->GetLineOfCharacter( characterIndex );
   const LineRun& line = *( modelLines + lineIndex );
 
   // Get the paragraph's direction.
@@ -1417,123 +1424,106 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
 
   // Check whether there is an alternative position:
 
-  cursorInfo.isSecondaryCursor = ( isCurrentRightToLeft != isPreviousRightToLeft ) ||
-    ( isLastPosition && ( isRightToLeftParagraph != isCurrentRightToLeft ) );
+  cursorInfo.isSecondaryCursor = ( !isLastPosition && ( isCurrentRightToLeft != isNextRightToLeft ) ) ||
+                                 ( isLastPosition && ( isRightToLeftParagraph != isCurrentRightToLeft ) );
 
   // Set the line height.
   cursorInfo.lineHeight = line.ascender + -line.descender;
 
-  // Convert the cursor position into the glyph position.
-  CharacterIndex characterIndex = logical;
-  if( cursorInfo.isSecondaryCursor &&
-      ( isRightToLeftParagraph != isCurrentRightToLeft ) )
+  // Calculate the primary cursor.
+
+  CharacterIndex index = characterIndex;
+  if( cursorInfo.isSecondaryCursor )
   {
-    characterIndex = previousLogical;
+    // If there is a secondary position, the primary cursor may be in a different place than the logical index.
+
+    if( isLastPosition )
+    {
+      // The position of the cursor after the last character needs special
+      // care depending on its direction and the direction of the paragraph.
+
+      // Need to find the first character after the last character with the paragraph's direction.
+      // i.e l0 l1 l2 r0 r1 should find r0.
+
+      // TODO: check for more than one line!
+      index = isRightToLeftParagraph ? line.characterRun.characterIndex : line.characterRun.characterIndex + line.characterRun.numberOfCharacters - 1u;
+      index = mLogicalModel->GetLogicalCharacterIndex( index );
+    }
+    else
+    {
+      index = ( isRightToLeftParagraph == isCurrentRightToLeft ) ? characterIndex : nextCharacterIndex;
+    }
   }
 
-  const GlyphIndex currentGlyphIndex = *( mVisualModel->mCharactersToGlyph.Begin() + characterIndex );
-  const Length numberOfGlyphs = *( mVisualModel->mGlyphsPerCharacter.Begin() + characterIndex );
-  const Length numberOfCharacters = *( mVisualModel->mCharactersPerGlyph.Begin() +currentGlyphIndex );
+  // Convert the cursor position into the glyph position.
+  const GlyphIndex primaryGlyphIndex = *( mVisualModel->mCharactersToGlyph.Begin() + index );
+  const Length primaryNumberOfGlyphs = *( mVisualModel->mGlyphsPerCharacter.Begin() + index );
+  const Length primaryNumberOfCharacters = *( mVisualModel->mCharactersPerGlyph.Begin() + primaryGlyphIndex );
 
   // Get the metrics for the group of glyphs.
   GlyphMetrics glyphMetrics;
-  GetGlyphsMetrics( currentGlyphIndex,
-                    numberOfGlyphs,
+  GetGlyphsMetrics( primaryGlyphIndex,
+                    primaryNumberOfGlyphs,
                     glyphMetrics,
                     mVisualModel,
                     mFontClient );
 
-  float interGlyphAdvance = 0.f;
+  float glyphAdvance = 0.f;
   if( !isLastPosition &&
-      ( numberOfCharacters > 1u ) )
+      ( primaryNumberOfCharacters > 1u ) )
+  {
+    const CharacterIndex firstIndex = *( mVisualModel->mGlyphsToCharacters.Begin() + primaryGlyphIndex );
+    glyphAdvance = static_cast<float>( 1u + characterIndex - firstIndex ) * glyphMetrics.advance / static_cast<float>( primaryNumberOfCharacters );
+  }
+  else
   {
-    const CharacterIndex firstIndex = *( mVisualModel->mGlyphsToCharacters.Begin() + currentGlyphIndex );
-    interGlyphAdvance = static_cast<float>( characterIndex - firstIndex ) * glyphMetrics.advance / static_cast<float>( numberOfCharacters );
+    glyphAdvance = glyphMetrics.advance;
   }
 
   // Get the glyph position and x bearing.
-  const Vector2& currentPosition = *( mVisualModel->mGlyphPositions.Begin() + currentGlyphIndex );
+  const Vector2& primaryPosition = *( mVisualModel->mGlyphPositions.Begin() + primaryGlyphIndex );
 
-  // Set the cursor's height.
-  cursorInfo.primaryCursorHeight = glyphMetrics.fontHeight;
-
-  // Set the position.
-  cursorInfo.primaryPosition.x = -glyphMetrics.xBearing + currentPosition.x + ( isCurrentRightToLeft ? glyphMetrics.advance : interGlyphAdvance );
-  cursorInfo.primaryPosition.y = line.ascender - glyphMetrics.ascender;
+  // Set the primary cursor's height.
+  cursorInfo.primaryCursorHeight = cursorInfo.isSecondaryCursor ? 0.5f * glyphMetrics.fontHeight : glyphMetrics.fontHeight;
 
+  // Set the primary cursor's position.
   if( isLastPosition )
   {
-    // The position of the cursor after the last character needs special
-    // care depending on its direction and the direction of the paragraph.
-
-    if( cursorInfo.isSecondaryCursor )
-    {
-      // Need to find the first character after the last character with the paragraph's direction.
-      // i.e l0 l1 l2 r0 r1 should find r0.
-
-      // TODO: check for more than one line!
-      characterIndex = isRightToLeftParagraph ? line.characterRun.characterIndex : line.characterRun.characterIndex + line.characterRun.numberOfCharacters - 1u;
-      characterIndex = mLogicalModel->GetLogicalCharacterIndex( characterIndex );
-
-      const GlyphIndex glyphIndex = *( mVisualModel->mCharactersToGlyph.Begin() + characterIndex );
-      const Length numberOfGlyphs = *( mVisualModel->mGlyphsPerCharacter.Begin() + characterIndex );
-
-      const Vector2& position = *( mVisualModel->mGlyphPositions.Begin() + glyphIndex );
+    cursorInfo.primaryPosition.x = -glyphMetrics.xBearing + primaryPosition.x + ( isRightToLeftParagraph ? 0.f : glyphMetrics.advance );
+  }
+  else
+  {
+    cursorInfo.primaryPosition.x = -glyphMetrics.xBearing + primaryPosition.x + ( ( ( isFirstPosition && !isCurrentRightToLeft ) || ( !isFirstPosition && isCurrentRightToLeft ) ) ? 0.f : glyphAdvance );
+  }
+  cursorInfo.primaryPosition.y = line.ascender - glyphMetrics.ascender;
 
-      // Get the metrics for the group of glyphs.
-      GlyphMetrics glyphMetrics;
-      GetGlyphsMetrics( glyphIndex,
-                        numberOfGlyphs,
-                        glyphMetrics,
-                        mVisualModel,
-                        mFontClient );
+  // Calculate the secondary cursor.
 
-      cursorInfo.primaryPosition.x = -glyphMetrics.xBearing + position.x + ( isRightToLeftParagraph ? 0.f : glyphMetrics.advance );
+  if( cursorInfo.isSecondaryCursor )
+  {
+    // Set the secondary cursor's height.
+    cursorInfo.secondaryCursorHeight = 0.5f * glyphMetrics.fontHeight;
 
-      cursorInfo.primaryPosition.y = line.ascender - glyphMetrics.ascender;
-    }
-    else
+    CharacterIndex index = characterIndex;
+    if( !isLastPosition )
     {
-      if( !isCurrentRightToLeft )
-      {
-        cursorInfo.primaryPosition.x += glyphMetrics.advance;
-      }
-      else
-      {
-        cursorInfo.primaryPosition.x -= glyphMetrics.advance;
-      }
+      index = ( isRightToLeftParagraph == isCurrentRightToLeft ) ? nextCharacterIndex : characterIndex;
     }
-  }
 
-  // Set the alternative cursor position.
-  if( cursorInfo.isSecondaryCursor )
-  {
-    // Convert the cursor position into the glyph position.
-    const CharacterIndex previousCharacterIndex = ( ( isRightToLeftParagraph != isCurrentRightToLeft ) ? logical : previousLogical );
-    const GlyphIndex previousGlyphIndex = *( mVisualModel->mCharactersToGlyph.Begin() + previousCharacterIndex );
-    const Length numberOfGlyphs = *( mVisualModel->mGlyphsPerCharacter.Begin() + previousCharacterIndex );
+    const GlyphIndex secondaryGlyphIndex = *( mVisualModel->mCharactersToGlyph.Begin() + index );
+    const Length secondaryNumberOfGlyphs = *( mVisualModel->mGlyphsPerCharacter.Begin() + index );
 
-    // Get the glyph position.
-    const Vector2& previousPosition = *( mVisualModel->mGlyphPositions.Begin() + previousGlyphIndex );
+    const Vector2& secondaryPosition = *( mVisualModel->mGlyphPositions.Begin() + index );
 
-    // Get the metrics for the group of glyphs.
-    GlyphMetrics glyphMetrics;
-    GetGlyphsMetrics( previousGlyphIndex,
-                      numberOfGlyphs,
+    GetGlyphsMetrics( secondaryGlyphIndex,
+                      secondaryNumberOfGlyphs,
                       glyphMetrics,
                       mVisualModel,
                       mFontClient );
 
-    // Set the cursor position and height.
-    cursorInfo.secondaryPosition.x = -glyphMetrics.xBearing + previousPosition.x + ( ( ( isLastPosition && !isCurrentRightToLeft ) ||
-                                                                                       ( !isLastPosition && isCurrentRightToLeft )    ) ? glyphMetrics.advance : 0.f );
-
-    cursorInfo.secondaryCursorHeight = 0.5f * glyphMetrics.fontHeight;
-
+    // Set the secondary cursor's position.
+    cursorInfo.secondaryPosition.x = -glyphMetrics.xBearing + secondaryPosition.x + ( isCurrentRightToLeft ? 0.f : glyphMetrics.advance );
     cursorInfo.secondaryPosition.y = cursorInfo.lineHeight - cursorInfo.secondaryCursorHeight - line.descender - ( glyphMetrics.fontHeight - glyphMetrics.ascender );
-
-    // Update the primary cursor height as well.
-    cursorInfo.primaryCursorHeight *= 0.5f;
   }
 }
 
index e9fc76a..1a55cf2 100644 (file)
  *
  */
 
+#include <dali/public-api/actors/layer.h>
 namespace Dali
 {
 namespace Toolkit
 {
 enum ControlDepthIndexRanges
 {
-    BACKGROUND_DEPTH_INDEX    = -10000000,
-    CONTENT_DEPTH_INDEX       =  0,
-    DECORATION_DEPTH_INDEX    =  10000000
+    BACKGROUND_DEPTH_INDEX    = static_cast<int>( -Dali::Layer::TREE_DEPTH_MULTIPLIER * 0.1f ),
+    CONTENT_DEPTH_INDEX       = 0,
+    DECORATION_DEPTH_INDEX    = static_cast<int>( Dali::Layer::TREE_DEPTH_MULTIPLIER * 0.1f )
 };
 
 }
index 74eabcb..b4b9cdb 100644 (file)
@@ -584,8 +584,8 @@ void Control::SetBackgroundColor( const Vector4& color )
     Actor actor = CreateBackground(Self(), color );
     background.actor = actor;
     mImpl->mAddRemoveBackgroundChild = true;
-    // use insert to guarantee its the first child (so that OVERLAY mode works)
-    Self().Insert( 0, actor );
+    // The actor does not need to be inserted to guarantee order.
+    Self().Add( actor );
     mImpl->mAddRemoveBackgroundChild = false;
   }
 
@@ -619,8 +619,8 @@ void Control::SetBackgroundImage( Image image )
    // Set the background actor before adding so that we do not inform derived classes
    background.actor = actor;
    mImpl->mAddRemoveBackgroundChild = true;
-   // use insert to guarantee its the first child (so that OVERLAY mode works)
-   Self().Insert( 0, actor );
+   // The actor does not need to be inserted to guarantee order.
+   Self().Add( actor );
    mImpl->mAddRemoveBackgroundChild = false;
 }
 
@@ -875,7 +875,7 @@ void Control::Initialize()
       styleManager.StyleChangeSignal().Connect( this, &Control::OnStyleChange );
 
       // Apply the current style
-      GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+      GetImpl( styleManager ).ApplyThemeStyleAtInit( Toolkit::Control( GetOwner() ) );
     }
   }
 
diff --git a/dali-toolkit/styles/default-feedback-theme.json b/dali-toolkit/styles/default-feedback-theme.json
new file mode 100644 (file)
index 0000000..25b0c7d
--- /dev/null
@@ -0,0 +1,20 @@
+//******************************************************************************
+//
+// Default feedback theme for dali-toolkit
+//
+//******************************************************************************
+{
+  "style":
+  {
+    "PushButton":
+    {
+      "signals":
+      [
+        {
+          "type": "clicked",
+          "sound-feedback-pattern": "FEEDBACK_PATTERN_TAP"
+        }
+      ]
+    }
+  }
+}
index 7831c7b..782c05b 100644 (file)
@@ -20,7 +20,7 @@
 // In this mode depth testing is turned off and order is determined by the hierachy (depth-first search order).
 // Not always recommended if there is going to be a lot of overdraw ( if lots of actors are on top of each other)
 
-Actor::SetDrawMode( DrawMode::OVERLAY ); // C++
+Actor::SetDrawMode( DrawMode::OVERLAY_2D ); // C++
 ~~~
 
 ~~~{.js}
@@ -28,7 +28,7 @@ Actor::SetDrawMode( DrawMode::OVERLAY ); // C++
 // In this mode depth testing is turned off and order is determined by the hierachy (depth-first search order).
 // Not always recommended if there is going to be a lot of overdraw ( if lots of actors are on top of each other)
 
-actor.drawMode = dali.DRAW_MODE_OVERLAY;
+actor.drawMode = dali.DRAW_MODE_OVERLAY_2D;
 ~~~
   - Use TextureAtlases ( reduces state changes in the GPU)
   - Use compressed textures
index 4938c01..70def0c 100644 (file)
@@ -543,7 +543,7 @@ INHERIT_SCALE,
  * By default a renderable actor will be drawn as a 3D object. It will be depth-tested against
  * other objects in the world i.e. it may be obscured if other objects are in front.
  *
- * If OVERLAY is used, the actor and its children will be drawn as a 2D overlay.
+ * If OVERLAY_2D is used, the actor and its children will be drawn as a 2D overlay.
  * Overlay actors are drawn in a separate pass, after all non-overlay actors within the Layer.
  * For overlay actors, the drawing order is determined by the hierachy (depth-first search order),
  * and depth-testing will not be used.
@@ -554,9 +554,9 @@ INHERIT_SCALE,
  *
  * @example
  *
- *      var actor.drawMode = dali.DRAW_MODE_NORMAL;  // binary 00. The default draw-mode
- *      var actor.drawMode = dali.DRAW_MODE_OVERLAY; // binary 01. Draw the actor and its children as an overlay
- *      var actor.drawMode = dali.DRAW_MODE_STENCIL ;// binary 11. Draw the actor and its children into the stencil buffer
+ *      var actor.drawMode = dali.DRAW_MODE_NORMAL;     // binary 00. The default draw-mode
+ *      var actor.drawMode = dali.DRAW_MODE_OVERLAY_2D; // binary 01. Draw the actor and its children as an overlay
+ *      var actor.drawMode = dali.DRAW_MODE_STENCIL ;   // binary 11. Draw the actor and its children into the stencil buffer
  *
  *
  * @type Number
index 51c869a..b10e4e6 100644 (file)
@@ -58,7 +58,7 @@ Constants accessible under the dali global object.
 
 |**actor.drawMode  **| |
 |DRAW_MODE_NORMAL                         | integer value |
-|DRAW_MODE_OVERLAY                        | integer value |
+|DRAW_MODE_OVERLAY_2D                     | integer value |
 |DRAW_MODE_STENCIL                        | integer value |
 
 |**Image load policy  **| |
index 77f8a7f..1571273 100644 (file)
@@ -154,7 +154,7 @@ const IntegerPair EnumTable[] =
     { "POSITION_INHERITANCE_DONT_INHERIT_POSITION",                      DONT_INHERIT_POSITION                      },
 
     { "DRAW_MODE_NORMAL",                                   DrawMode::NORMAL     },
-    { "DRAW_MODE_OVERLAY",                                  DrawMode::OVERLAY    },
+    { "DRAW_MODE_OVERLAY_2D",                               DrawMode::OVERLAY_2D },
     { "DRAW_MODE_STENCIL",                                  DrawMode::STENCIL    },
 
     { "IMAGE_LOAD_POLICY_IMMEDIATE",                        ResourceImage::IMMEDIATE },