// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/internal/controls/image-view/image-view-impl.h>
#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
#include <dali-toolkit/public-api/controls/image-view/image-view.h>
mControlSize = size;
// TODO - Remove this if nothing is active
- CreateActiveLayer();
+ CreateLayer(mActiveLayer, DecorationType::ACTIVE_LAYER);
+ CreateLayer(mCursorLayer, DecorationType::CURSOR_LAYER);
// Show or hide the cursors
CreateCursors();
const CursorImpl& cursor = mCursor[PRIMARY_CURSOR];
mPrimaryCursorVisible = (!mHidePrimaryCursorAndGrabHandle) && ((mControlSize.width - (cursor.position.x + mCursorWidth) > -Math::MACHINE_EPSILON_1000) &&
(cursor.position.x > -Math::MACHINE_EPSILON_1000) &&
- (mControlSize.height - (cursor.position.y + cursor.cursorHeight) > -Math::MACHINE_EPSILON_1000) &&
- (cursor.position.y > -Math::MACHINE_EPSILON_1000));
+ (mControlSize.height - cursor.position.y > -Math::MACHINE_EPSILON_1000) &&
+ (cursor.position.y + cursor.cursorHeight > -Math::MACHINE_EPSILON_1000));
if(mPrimaryCursorVisible)
{
mPrimaryCursor.SetProperty(Actor::Property::POSITION, Vector2(cursor.position.x, cursor.position.y));
const CursorImpl& cursor = mCursor[SECONDARY_CURSOR];
mSecondaryCursorVisible = ((mControlSize.width - (cursor.position.x + mCursorWidth) > -Math::MACHINE_EPSILON_1000) &&
(cursor.position.x > -Math::MACHINE_EPSILON_1000) &&
- (mControlSize.height - (cursor.position.y + cursor.cursorHeight) > -Math::MACHINE_EPSILON_1000) &&
- (cursor.position.y > -Math::MACHINE_EPSILON_1000));
+ (mControlSize.height - cursor.position.y > -Math::MACHINE_EPSILON_1000) &&
+ (cursor.position.y + cursor.cursorHeight > -Math::MACHINE_EPSILON_1000));
if(mSecondaryCursorVisible)
{
mSecondaryCursor.SetProperty(Actor::Property::POSITION, Vector2(cursor.position.x, cursor.position.y));
{
grabHandle.horizontallyVisible = ((mControlSize.width - (grabHandle.position.x + floor(0.5f * mCursorWidth)) > -Math::MACHINE_EPSILON_1000) &&
(grabHandle.position.x > -Math::MACHINE_EPSILON_1000));
- grabHandle.verticallyVisible = (((mControlSize.height - grabHandle.lineHeight) - grabHandle.position.y > -Math::MACHINE_EPSILON_1000) &&
- (grabHandle.position.y > -Math::MACHINE_EPSILON_1000));
+ grabHandle.verticallyVisible = ((fabsf(mControlSize.height - grabHandle.lineHeight) - grabHandle.position.y > -Math::MACHINE_EPSILON_1000) &&
+ (grabHandle.position.y + grabHandle.lineHeight > -Math::MACHINE_EPSILON_1000));
const bool isVisible = grabHandle.horizontallyVisible && grabHandle.verticallyVisible && (!mHidePrimaryCursorAndGrabHandle);
if(isVisible)
primary.horizontallyVisible = ((mControlSize.width - primary.position.x > -Math::MACHINE_EPSILON_1000) &&
(primary.position.x > -Math::MACHINE_EPSILON_1000));
- primary.verticallyVisible = (((mControlSize.height - primary.lineHeight) - primary.position.y > -Math::MACHINE_EPSILON_1000) &&
+ primary.verticallyVisible = ((fabsf(mControlSize.height - primary.lineHeight) - primary.position.y > -Math::MACHINE_EPSILON_1000) &&
(primary.position.y + (primary.verticallyFlipped ? 0.f : primary.lineHeight) > -Math::MACHINE_EPSILON_1000));
secondary.horizontallyVisible = ((mControlSize.width - secondary.position.x > -Math::MACHINE_EPSILON_1000) &&
(secondary.position.x > -Math::MACHINE_EPSILON_1000));
- secondary.verticallyVisible = (((mControlSize.height - secondary.lineHeight) - secondary.position.y > -Math::MACHINE_EPSILON_1000) &&
+ secondary.verticallyVisible = ((fabsf(mControlSize.height - secondary.lineHeight) - secondary.position.y > -Math::MACHINE_EPSILON_1000) &&
(secondary.position.y + (secondary.verticallyFlipped ? 0.f : secondary.lineHeight) > -Math::MACHINE_EPSILON_1000));
const bool primaryVisible = primary.horizontallyVisible && primary.verticallyVisible;
cursor.SetBackgroundColor(color);
cursor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
cursor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ cursor.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIDDEN, true);
}
// Add or Remove cursor(s) from parent
if(!mPrimaryCursor.GetParent())
{
- mActiveLayer.Add(mPrimaryCursor);
+ mCursorLayer.Add(mPrimaryCursor);
}
}
if(!mSecondaryCursor.GetParent())
{
- mActiveLayer.Add(mSecondaryCursor);
+ mCursorLayer.Add(mSecondaryCursor);
}
}
else
mPanDetector.DetectedSignal().Connect(this, &Decorator::Impl::OnPan);
}
- void CreateActiveLayer()
+ void CreateLayer(Actor& layer, DecorationType type)
{
- if(!mActiveLayer)
+ if(!layer)
{
- mActiveLayer = Actor::New();
+ layer = Actor::New();
#ifdef DECORATOR_DEBUG
- mActiveLayer.SetProperty(Actor::Property::NAME, "ActiveLayerActor");
+ if(type == DecorationType::ACTIVE_LAYER)
+ {
+ layer.SetProperty(Actor::Property::NAME, "ActiveLayerActor");
+ }
+ else if(type == DecorationType::CURSOR_LAYER)
+ {
+ layer.SetProperty(Actor::Property::NAME, "CursorLayerActor");
+ }
#endif
+ bool needsClipping = false;
+ if(type == DecorationType::CURSOR_LAYER)
+ {
+ needsClipping = true;
+ }
- mActiveLayer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
- mActiveLayer.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+ layer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ layer.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
- // Add the active layer telling the controller it doesn't need clipping.
- mController.AddDecoration(mActiveLayer, false);
+ mController.AddDecoration(layer, type, needsClipping);
}
- mActiveLayer.RaiseToTop();
+ layer.RaiseToTop();
}
void SetSelectionHandleMarkerSize(HandleImpl& handle)
}
}
+ void CreateSelectionPopup()
+ {
+ if(!mCopyPastePopup.actor)
+ {
+ mCopyPastePopup.actor = TextSelectionPopup::New(&mTextSelectionPopupCallbackInterface);
+ #ifdef DECORATOR_DEBUG
+ mCopyPastePopup.actor.SetProperty(Dali::Actor::Property::NAME, "mCopyPastePopup");
+ #endif
+ mCopyPastePopup.actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ mCopyPastePopup.actor.OnRelayoutSignal().Connect(this, &Decorator::Impl::SetPopupPosition); // Position popup after size negotiation
+ }
+ }
+
void CalculateHandleWorldCoordinates(HandleImpl& handle, Vector2& position)
{
// Gets the world position of the active layer. The active layer is where the handles are added.
// The SetGrabHandleImage() method will change the orientation.
const float yLocalPosition = grabHandle.verticallyFlipped ? grabHandle.position.y : grabHandle.position.y + grabHandle.lineHeight;
- if(grabHandle.actor)
- {
- grabHandle.actor.SetProperty(Actor::Property::POSITION, Vector2(grabHandle.position.x + floor(0.5f * mCursorWidth) + (mSmoothHandlePanEnabled ? grabHandle.grabDisplacementX : 0.f), yLocalPosition + (mSmoothHandlePanEnabled ? grabHandle.grabDisplacementY : 0.f)));
- }
+ ApplyDisplacement(grabHandle, yLocalPosition);
}
void SetSelectionHandlePosition(HandleType type)
// The SetHandleImage() method will change the orientation.
const float yLocalPosition = handle.verticallyFlipped ? handle.position.y : handle.position.y + handle.lineHeight;
- if(handle.actor)
+ ApplyDisplacement(handle, yLocalPosition);
+ }
+
+ void ApplyDisplacement(HandleImpl& handle, float yLocalPosition)
+ {
+ if( handle.actor )
+ {
+ float adjustedDisplacementX = 0.0f;
+ float adjustedDisplacementY = 0.0f;
+ if (mSmoothHandlePanEnabled)
+ {
+ adjustedDisplacementX = CalculateAdjustedDisplacement(handle.position.x, handle.grabDisplacementX, mControlSize.x);
+ adjustedDisplacementY = CalculateAdjustedDisplacement(handle.position.y, handle.grabDisplacementY, (mControlSize.y - handle.lineHeight));
+ }
+ handle.actor.SetProperty(Actor::Property::POSITION,
+ Vector2(handle.position.x + floor(0.5f * mCursorWidth) + adjustedDisplacementX,
+ yLocalPosition + adjustedDisplacementY));
+ }
+ }
+
+ float CalculateAdjustedDisplacement(float position, float displacement, float edge)
+ {
+ //Apply the displacement (on the X-axis & the Y-axis)
+ //as long as it does not exceed the control's edge.
+ float adjustedDisplacement = 0.0f;
+ if(position + displacement < 0.0f)
+ {
+ // -position to cancel it out and relocate to 0.
+ adjustedDisplacement = -position;
+ }
+ else if(position + displacement > edge)
{
- handle.actor.SetProperty(Actor::Property::POSITION, Vector2(handle.position.x + (mSmoothHandlePanEnabled ? handle.grabDisplacementX : 0.f), yLocalPosition + (mSmoothHandlePanEnabled ? handle.grabDisplacementY : 0.f)));
+ // move in a displacement which is sufficient to reach the edge.
+ adjustedDisplacement = edge - position;
}
+ else
+ {
+ // move normally in the displacement.
+ adjustedDisplacement = displacement;
+ }
+ return adjustedDisplacement;
}
void SetHandleImage(HandleType type)
}
// Add the highlight box telling the controller it needs clipping.
- mController.AddDecoration(mHighlightActor, true);
+ mController.AddDecoration(mHighlightActor, DecorationType::NONE_LAYER, true);
}
void UpdateHighlight()
Timer mScrollTimer; ///< Timer used to scroll the text when the grab handle is moved close to the edges.
Actor mActiveLayer; ///< Actor for active handles and alike that ensures they are above all else.
+ Actor mCursorLayer; ///< Actor for cursor layer. this is for cursor clipping.
PropertyNotification mHandleVerticalLessThanNotification; ///< Notifies when the 'y' coord of the active layer is less than a given value.
PropertyNotification mHandleVerticalGreaterThanNotification; ///< Notifies when the 'y' coord of the active layer is grater than a given value.
PropertyNotification mHandleHorizontalLessThanNotification; ///< Notifies when the 'x' coord of the active layer is less than a given value.
void Decorator::SetEditable(bool editable)
{
mImpl->mHidePrimaryCursorAndGrabHandle = !editable;
+ // If editable is false, all decorators should be disabled.
+ if(!editable)
+ {
+ if(IsHighlightActive())
+ {
+ SetHighlightActive(false);
+ }
+ if(IsHandleActive(LEFT_SELECTION_HANDLE))
+ {
+ SetHandleActive(LEFT_SELECTION_HANDLE, false);
+ }
+ if(IsHandleActive(RIGHT_SELECTION_HANDLE))
+ {
+ SetHandleActive(RIGHT_SELECTION_HANDLE, false);
+ }
+ if(IsPopupActive())
+ {
+ SetPopupActive(false);
+ }
+ }
+
mImpl->Relayout(mImpl->mControlSize);
}
/** Handles **/
void Decorator::SetEnabledPopupButtons(TextSelectionPopup::Buttons& enabledButtonsBitMask)
{
mImpl->mEnabledPopupButtons = enabledButtonsBitMask;
-
- if(!mImpl->mCopyPastePopup.actor)
- {
- mImpl->mCopyPastePopup.actor = TextSelectionPopup::New(&mImpl->mTextSelectionPopupCallbackInterface);
-#ifdef DECORATOR_DEBUG
- mImpl->mCopyPastePopup.actor.SetProperty(Dali::Actor::Property::NAME, "mCopyPastePopup");
-#endif
- mImpl->mCopyPastePopup.actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
- mImpl->mCopyPastePopup.actor.OnRelayoutSignal().Connect(mImpl, &Decorator::Impl::SetPopupPosition); // Position popup after size negotiation
- }
-
+ mImpl->CreateSelectionPopup();
mImpl->mCopyPastePopup.actor.EnableButtons(mImpl->mEnabledPopupButtons);
}
return mImpl->mEnabledPopupButtons;
}
+void Decorator::SetSelectionPopupStyle(const Property::Map& options)
+{
+ mImpl->CreateSelectionPopup();
+ mImpl->mCopyPastePopup.actor.SetProperties(options);
+}
+
+void Decorator::GetSelectionPopupStyle(Property::Map& options)
+{
+ if(mImpl->mCopyPastePopup.actor)
+ {
+ mImpl->mCopyPastePopup.actor.GetProperties(options);
+ }
+}
+
/** Scroll **/
void Decorator::SetScrollThreshold(float threshold)