+ if( grabHandle.verticallyFlipped )
+ {
+ // The grab handle is vertically flipped. Never is going to exceed the bottom edje of the display.
+ mVerticalGreaterThanNotification.Reset();
+
+ // The vertical distance from the center of the active layer to the top edje of the display.
+ const float topHeight = 0.5f * mControlSize.height - grabHandle.position.y + grabHandle.size.height;
+
+ mVerticalLessThanNotification = mActiveLayer.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
+ LessThanCondition( mBoundingBox.y + topHeight ) );
+
+ // Notifies the change from false to true and from true to false.
+ mVerticalLessThanNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged );
+
+ // Connects the signals with the callbacks.
+ mVerticalLessThanNotification.NotifySignal().Connect( this, &Decorator::Impl::HandleResetPosition );
+ }
+ else
+ {
+ // The grab handle is not vertically flipped. Never is going to exceed the top edje of the display.
+ mVerticalLessThanNotification.Reset();
+
+ // The vertical distance from the center of the active layer to the bottom edje of the display.
+ const float bottomHeight = -0.5f * mControlSize.height + grabHandle.position.y + grabHandle.lineHeight + grabHandle.size.height;
+
+ mVerticalGreaterThanNotification = mActiveLayer.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
+ GreaterThanCondition( mBoundingBox.w - bottomHeight ) );
+
+ // Notifies the change from false to true and from true to false.
+ mVerticalGreaterThanNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged );
+
+ // Connects the signals with the callbacks.
+ mVerticalGreaterThanNotification.NotifySignal().Connect( this, &Decorator::Impl::HandleResetPosition );
+ }
+ }
+ else // The selection handles are active
+ {
+ if( primaryHandle.verticallyFlipped && secondaryHandle.verticallyFlipped )
+ {
+ // Both selection handles are vertically flipped. Never are going to exceed the bottom edje of the display.
+ mVerticalGreaterThanNotification.Reset();
+
+ // The vertical distance from the center of the active layer to the top edje of the display.
+ const float topHeight = 0.5f * mControlSize.height + std::max( -primaryHandle.position.y + primaryHandle.size.height, -secondaryHandle.position.y + secondaryHandle.size.height );
+
+ mVerticalLessThanNotification = mActiveLayer.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
+ LessThanCondition( mBoundingBox.y + topHeight ) );
+
+ // Notifies the change from false to true and from true to false.
+ mVerticalLessThanNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged );
+
+ // Connects the signals with the callbacks.
+ mVerticalLessThanNotification.NotifySignal().Connect( this, &Decorator::Impl::HandleResetPosition );
+ }
+ else if( !primaryHandle.verticallyFlipped && !secondaryHandle.verticallyFlipped )
+ {
+ // Both selection handles aren't vertically flipped. Never are going to exceed the top edje of the display.
+ mVerticalLessThanNotification.Reset();
+
+ // The vertical distance from the center of the active layer to the bottom edje of the display.
+ const float bottomHeight = -0.5f * mControlSize.height + std::max( primaryHandle.position.y + primaryHandle.lineHeight + primaryHandle.size.height,
+ secondaryHandle.position.y + secondaryHandle.lineHeight + secondaryHandle.size.height );
+
+ mVerticalGreaterThanNotification = mActiveLayer.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
+ GreaterThanCondition( mBoundingBox.w - bottomHeight ) );
+
+ // Notifies the change from false to true and from true to false.
+ mVerticalGreaterThanNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged );
+
+ // Connects the signals with the callbacks.
+ mVerticalGreaterThanNotification.NotifySignal().Connect( this, &Decorator::Impl::HandleResetPosition );
+ }
+ else
+ {
+ // Only one of the selection handles is vertically flipped. Both vertical notifications are needed.
+
+ // The vertical distance from the center of the active layer to the top edje of the display.
+ const float topHeight = 0.5f * mControlSize.height + ( primaryHandle.verticallyFlipped ?
+ -primaryHandle.position.y + primaryHandle.size.height :
+ -secondaryHandle.position.y + secondaryHandle.size.height );
+
+ mVerticalLessThanNotification = mActiveLayer.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
+ LessThanCondition( mBoundingBox.y + topHeight ) );
+
+ // Notifies the change from false to true and from true to false.
+ mVerticalLessThanNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged );
+
+ // Connects the signals with the callbacks.
+ mVerticalLessThanNotification.NotifySignal().Connect( this, &Decorator::Impl::HandleResetPosition );
+
+ // The vertical distance from the center of the active layer to the bottom edje of the display.
+ const float bottomHeight = -0.5f * mControlSize.height + ( primaryHandle.verticallyFlipped ?
+ secondaryHandle.position.y + secondaryHandle.lineHeight + secondaryHandle.size.height :
+ primaryHandle.position.y + primaryHandle.lineHeight + primaryHandle.size.height );
+
+ mVerticalGreaterThanNotification = mActiveLayer.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
+ GreaterThanCondition( mBoundingBox.w - bottomHeight ) );
+
+ // Notifies the change from false to true and from true to false.
+ mVerticalGreaterThanNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged );
+
+ // Connects the signals with the callbacks.
+ mVerticalGreaterThanNotification.NotifySignal().Connect( this, &Decorator::Impl::HandleResetPosition );
+ }
+ }
+
+ // Horizontal notifications.
+
+ // Disconnect any previous connected callback.
+ if( mHorizontalLessThanNotification )
+ {
+ mHorizontalLessThanNotification.NotifySignal().Disconnect( this, &Decorator::Impl::HandleResetPosition );
+ mActiveLayer.RemovePropertyNotification( mHorizontalLessThanNotification );
+ }
+
+ if( mHorizontalGreaterThanNotification )
+ {
+ mHorizontalGreaterThanNotification.NotifySignal().Disconnect( this, &Decorator::Impl::HandleResetPosition );
+ mActiveLayer.RemovePropertyNotification( mHorizontalGreaterThanNotification );
+ }
+
+ if( primaryHandle.active || secondaryHandle.active )
+ {
+ // The horizontal distance from the center of the active layer to the left edje of the display.
+ const float leftWidth = 0.5f * mControlSize.width + std::max( -primaryHandle.position.x + primaryHandle.size.width,
+ -secondaryHandle.position.x + secondaryHandle.size.width );
+
+ mHorizontalLessThanNotification = mActiveLayer.AddPropertyNotification( Actor::Property::WORLD_POSITION_X,
+ LessThanCondition( mBoundingBox.x + leftWidth ) );
+
+ // Notifies the change from false to true and from true to false.
+ mHorizontalLessThanNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged );
+
+ // Connects the signals with the callbacks.
+ mHorizontalLessThanNotification.NotifySignal().Connect( this, &Decorator::Impl::HandleResetPosition );
+
+ // The horizontal distance from the center of the active layer to the right edje of the display.
+ const float rightWidth = -0.5f * mControlSize.width + std::max( primaryHandle.position.x + primaryHandle.size.width,
+ secondaryHandle.position.x + secondaryHandle.size.width );
+
+ mHorizontalGreaterThanNotification = mActiveLayer.AddPropertyNotification( Actor::Property::WORLD_POSITION_X,
+ GreaterThanCondition( mBoundingBox.z - rightWidth ) );
+
+ // Notifies the change from false to true and from true to false.
+ mHorizontalGreaterThanNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged );
+
+ // Connects the signals with the callbacks.
+ mHorizontalGreaterThanNotification.NotifySignal().Connect( this, &Decorator::Impl::HandleResetPosition );
+ }
+ }
+
+ // Popup
+
+ float AlternatePopUpPositionRelativeToCursor()
+ {
+ float alternativePosition = 0.0f;
+
+ const float popupHeight = mCopyPastePopup.actor.GetRelayoutSize( Dimension::HEIGHT );
+
+ const HandleImpl& primaryHandle = mHandle[LEFT_SELECTION_HANDLE];
+ const HandleImpl& secondaryHandle = mHandle[RIGHT_SELECTION_HANDLE];
+ const HandleImpl& grabHandle = mHandle[GRAB_HANDLE];
+ const CursorImpl& cursor = mCursor[PRIMARY_CURSOR];
+
+ if( primaryHandle.active || secondaryHandle.active )
+ {
+ const float maxHandleHeight = std::max( primaryHandle.size.height, secondaryHandle.size.height );
+ alternativePosition = 0.5f * popupHeight + cursor.lineHeight + maxHandleHeight + std::min( primaryHandle.position.y, secondaryHandle.position.y );