DALI_TEST_CHECK( !textSelectionPopup );
- textSelectionPopup = TextSelectionPopup::New();
+ textSelectionPopup = TextSelectionPopup::New( TextSelectionPopup::COPY );
DALI_TEST_CHECK( textSelectionPopup );
END_TEST;
ToolkitTestApplication application;
TextSelectionPopup textSelectionPopup;
- textSelectionPopup = TextSelectionPopup::New();
+ textSelectionPopup = TextSelectionPopup::New( TextSelectionPopup::COPY );
TextSelectionPopup copy( textSelectionPopup );
DALI_TEST_CHECK( copy == textSelectionPopup );
{
ToolkitTestApplication application;
TextSelectionPopup textSelectionPopup;
- textSelectionPopup = TextSelectionPopup::New();
+ textSelectionPopup = TextSelectionPopup::New( TextSelectionPopup::COPY );
TextSelectionPopup copy;
copy = textSelectionPopup;
{
ToolkitTestApplication application;
TextSelectionPopup textSelectionPopup;
- textSelectionPopup = TextSelectionPopup::New();
+ textSelectionPopup = TextSelectionPopup::New( TextSelectionPopup::COPY );
TextSelectionPopup cast = TextSelectionPopup::DownCast( textSelectionPopup );
namespace Toolkit
{
-TextSelectionPopup TextSelectionPopup::New()
-{
- return Internal::TextSelectionPopup::New();
-}
-
TextSelectionPopup TextSelectionPopup::New( Buttons enabledButtons )
{
return Internal::TextSelectionPopup::New( enabledButtons );
};
/**
- * Create the TextSelectionPopup control.
- * @return A handle to the TextSelectionPopup control.
- */
- static TextSelectionPopup New();
-
- /**
* Create the TextSelectionPopup control with the given set of buttons.
* @param[in] enabledButtons The given set of buttons to enable
* @return A handle to the TextSelectionPopup control.
const Dali::Vector4 DEFAULT_POPUP_LINE_COLOR( Dali::Vector4( 0.69f, 0.93f, 0.93f, 1.0f ) );
const Dali::Vector4 DEFAULT_OPTION_ICON( Dali::Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
-const Dali::Vector4 DEFAULT_OPTION_ICON_PRESSED( Dali::Vector4( 0.5f, 1.0f, 1.0f, 1.0f ) );
+const Dali::Vector4 DEFAULT_OPTION_ICON_PRESSED( Dali::Vector4( 0.12f, 0.56f, 1.0f, 1.0f ) );
const std::string DEFAULT_POPUP_BACKGROUND_IMAGE( DALI_IMAGE_DIR "selection-popup-bg#.png" );
const std::string OPTION_ICON_CLIPBOARD( DALI_IMAGE_DIR "copy_paste_icon_clipboard.png" );
BaseHandle Create()
{
- return Toolkit::TextSelectionPopup::New();
+ return Toolkit::TextSelectionPopup::New( Toolkit::TextSelectionPopup::NONE );
}
// Setup properties, signals and actions using the type-registry.
} // namespace
-Dali::Toolkit::TextSelectionPopup TextSelectionPopup::New()
-{
- // Create the implementation, temporarily owned by this handle on stack
- IntrusivePtr< TextSelectionPopup > impl = new TextSelectionPopup();
-
- // Pass ownership to CustomActor handle
- Dali::Toolkit::TextSelectionPopup handle( *impl );
-
- // Second-phase init of the implementation
- // This can only be done after the CustomActor connection has been made...
- impl->Initialize();
-
- return handle;
-}
Dali::Toolkit::TextSelectionPopup TextSelectionPopup::New( Toolkit::TextSelectionPopup::Buttons buttonsToEnable )
{
optionPressedContainer.SetDrawMode( DrawMode::OVERLAY );
optionPressedContainer.SetFitHeight( 0 );
optionPressedContainer.SetFitWidth( 0 );
- optionPressedContainer.SetBackgroundColor(Color::RED); //todo member variable
+ optionPressedContainer.SetBackgroundColor( mPressedColor );
#ifdef DECORATOR_DEBUG
optionContainer.SetName("optionContainer");
Padding padding;
padding.left = 24.0f;
padding.right = 24.0f;
- padding.top = 13.0f;
+ padding.top = 14.0f;
padding.bottom = 14.0f;
captionTextLabel.SetPadding( padding );
pressedCaptionTextLabel.SetPadding( padding );
icon.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
pressedIcon.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
icon.SetColor( mIconColor );
- pressedIcon.SetColor( mIconPressedColor );
if ( showCaption & showIcons )
{
mEnabledButtons( Toolkit::TextSelectionPopup::NONE ),
mLineColor( DEFAULT_POPUP_LINE_COLOR ),
mIconColor( DEFAULT_OPTION_ICON ),
- mIconPressedColor( DEFAULT_OPTION_ICON_PRESSED ),
+ mPressedColor( DEFAULT_OPTION_ICON_PRESSED ),
mSelectOptionPriority( 1 ),
mSelectAllOptionPriority ( 2 ),
mCutOptionPriority ( 3 ),
};
/**
- * @copydoc Dali::Toollkit::TextSelectionPopup::New()
- */
- static Toolkit::TextSelectionPopup New();
-
- /**
* @brief New constructor with provided buttons to enable.
* @param[in] buttonsToEnable bit mask of buttons to enable
* @return A handle to the TextSelectionPopup control.
Vector4 mLineColor; // Color of the line around the text input popup
Vector4 mIconColor; // Color of the popup icon.
- Vector4 mIconPressedColor; // Color of the popup icon when pressed.
+ Vector4 mPressedColor; // Color of the popup option when pressed.
// Priority of Options/Buttons in the Cut and Paste pop-up, higher priority buttons are displayed first, left to right.
std::size_t mSelectOptionPriority; // Position of Select Button
{
const Dali::Vector2 DEFAULT_MAX_SIZE( 400.0f, 65.0f ); ///< The maximum size of the Toolbar.
-} // namespace
-
BaseHandle Create()
{
return Toolkit::TextSelectionToolbar::New();
DALI_TYPE_REGISTRATION_END()
+} // namespace
+
Dali::Toolkit::TextSelectionToolbar TextSelectionToolbar::New()
{
// Create the implementation, temporarily owned by this handle on stack
const char* DEFAULT_SELECTION_HANDLE_TWO_RELEASED( DALI_IMAGE_DIR "text-input-selection-handle-right.png" );
const char* DEFAULT_SELECTION_HANDLE_TWO_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-right-press.png" );
+const int DEFAULT_POPUP_OFFSET( -100.0f ); // Vertical offset of Popup from cursor or handles position.
+
const Dali::Vector3 DEFAULT_GRAB_HANDLE_RELATIVE_SIZE( 1.5f, 2.0f, 1.0f );
const Dali::Vector3 DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE( 1.5f, 1.5f, 1.0f );
bool flipped : 1;
};
+ struct PopupImpl
+ {
+ PopupImpl()
+ : position(),
+ offset( DEFAULT_POPUP_OFFSET )
+ {
+ }
+
+ TextSelectionPopup actor;
+ Vector3 position;
+ int offset;
+ };
+
Impl( ControllerInterface& controller )
: mController( controller ),
mEnabledPopupButtons( TextSelectionPopup::NONE ),
if ( mActiveCopyPastePopup )
{
- if ( !mCopyPastePopup )
+ // todo Swap UnparentAndReset for DeterminePositionPopup() if mCopyPastePopup.actor valid Once the issue with the labels disappearing is fixed.
+ UnparentAndReset( mCopyPastePopup.actor );
+ if ( !mCopyPastePopup.actor )
{
- mCopyPastePopup = TextSelectionPopup::New( mEnabledPopupButtons );
+ mCopyPastePopup.actor = TextSelectionPopup::New( mEnabledPopupButtons );
#ifdef DECORATOR_DEBUG
- mCopyPastePopup.SetName("mCopyPastePopup");
+ mCopyPastePopup.actor.SetName("mCopyPastePopup");
#endif
- mCopyPastePopup.SetAnchorPoint( AnchorPoint::CENTER );
- mCopyPastePopup.OnRelayoutSignal().Connect( this, &Decorator::Impl::PopUpRelayoutComplete ); // Position popup after size negotiation
- mActiveLayer.Add ( mCopyPastePopup );
+ mCopyPastePopup.actor.SetAnchorPoint( AnchorPoint::CENTER );
+ mCopyPastePopup.actor.OnRelayoutSignal().Connect( this, &Decorator::Impl::PopupRelayoutComplete ); // Position popup after size negotiation
+ mActiveLayer.Add ( mCopyPastePopup.actor );
}
}
else
{
- if ( mCopyPastePopup )
+ if ( mCopyPastePopup.actor )
{
- UnparentAndReset( mCopyPastePopup );
+ UnparentAndReset( mCopyPastePopup.actor );
}
}
}
mHighlightPosition += scrollOffset;
}
- void PopUpRelayoutComplete( Actor actor )
+ void DeterminePositionPopup()
{
- // Size negotiation for CopyPastePopup complete so can get the size and constrain position within bounding box.
+ if ( !mActiveCopyPastePopup )
+ {
+ return;
+ }
- mCopyPastePopup.OnRelayoutSignal().Disconnect( this, &Decorator::Impl::PopUpRelayoutComplete );
+ if ( mHandle[LEFT_SELECTION_HANDLE].active || mHandle[RIGHT_SELECTION_HANDLE].active )
+ {
+ float minHandleXPosition = std::min ( mHandle[LEFT_SELECTION_HANDLE].position.x, mHandle[RIGHT_SELECTION_HANDLE].position.x );
+ float maxHandleXPosition = std::max ( mHandle[LEFT_SELECTION_HANDLE].position.x, mHandle[RIGHT_SELECTION_HANDLE].position.x );
- Vector3 popupPosition( mCursor[PRIMARY_CURSOR].position.x, mCursor[PRIMARY_CURSOR].position.y -100.0f , 0.0f); //todo 100 to be an offset Property
+ float minHandleYPosition = std::min ( mHandle[LEFT_SELECTION_HANDLE].position.y, mHandle[RIGHT_SELECTION_HANDLE].position.y );
- Vector3 popupSize = Vector3( mCopyPastePopup.GetRelayoutSize( Dimension::WIDTH ), mCopyPastePopup.GetRelayoutSize( Dimension::HEIGHT ), 0.0f );
+ mCopyPastePopup.position.x = minHandleXPosition + ( ( maxHandleXPosition - minHandleXPosition ) *0.5f );
+ mCopyPastePopup.position.y = minHandleYPosition + mCopyPastePopup.offset;
+ }
+ else
+ {
+ mCopyPastePopup.position = Vector3( mCursor[PRIMARY_CURSOR].position.x, mCursor[PRIMARY_CURSOR].position.y -100.0f , 0.0f ); //todo 100 to be an offset Property
+ }
+
+ Vector3 popupSize = Vector3( mCopyPastePopup.actor.GetRelayoutSize( Dimension::WIDTH ), mCopyPastePopup.actor.GetRelayoutSize( Dimension::HEIGHT ), 0.0f );
+
+ GetConstrainedPopupPosition( mCopyPastePopup.position, popupSize, AnchorPoint::CENTER, mActiveLayer, mBoundingBox );
+
+ SetUpPopupPositionNotifications();
- GetConstrainedPopupPosition( popupPosition, popupSize, AnchorPoint::CENTER, mActiveLayer, mBoundingBox );
+ mCopyPastePopup.actor.SetPosition( mCopyPastePopup.position );
+ }
- SetUpPopUpPositionNotifications();
+ void PopupRelayoutComplete( Actor actor )
+ {
+ // Size negotiation for CopyPastePopup complete so can get the size and constrain position within bounding box.
+ mCopyPastePopup.actor.OnRelayoutSignal().Disconnect( this, &Decorator::Impl::PopupRelayoutComplete );
- mCopyPastePopup.SetPosition( popupPosition ); //todo grabhandle(cursor) or selection handle positions to be used
+ DeterminePositionPopup();
}
void CreateCursor( ImageActor& cursor, const Vector4& color )
// if can't be positioned above, then position below row.
alternativeYPosition = AlternatePopUpPositionRelativeToCursor();
- mCopyPastePopup.SetY( alternativeYPosition );
+ mCopyPastePopup.actor.SetY( alternativeYPosition );
}
- void SetUpPopUpPositionNotifications( )
+ void SetUpPopupPositionNotifications( )
{
// Note Property notifications ignore any set anchor point so conditions must allow for this. Default is Top Left.
Vector4 worldCoordinatesBoundingBox;
LocalToWorldCoordinatesBoundingBox( mBoundingBox, worldCoordinatesBoundingBox );
- float popupHeight = mCopyPastePopup.GetRelayoutSize( Dimension::HEIGHT);
+ float popupHeight = mCopyPastePopup.actor.GetRelayoutSize( Dimension::HEIGHT);
- PropertyNotification verticalExceedNotification = mCopyPastePopup.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
- OutsideCondition( worldCoordinatesBoundingBox.y + popupHeight/2,
- worldCoordinatesBoundingBox.w - popupHeight/2 ) );
+ PropertyNotification verticalExceedNotification = mCopyPastePopup.actor.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
+ OutsideCondition( worldCoordinatesBoundingBox.y + popupHeight * 0.5f,
+ worldCoordinatesBoundingBox.w - popupHeight * 0.5f ) );
verticalExceedNotification.NotifySignal().Connect( this, &Decorator::Impl::PopUpLeavesVerticalBoundary );
}
}
requiredPopupPosition.x = requiredPopupPosition.x + xOffSetToKeepWithinBounds;
+
+ // Prevent pixel mis-alignment by rounding down.
+ requiredPopupPosition.x = static_cast<int>( requiredPopupPosition.x );
+ requiredPopupPosition.y = static_cast<int>( requiredPopupPosition.y );
+
}
void FlipSelectionHandleImages()
ImageActor mPrimaryCursor;
ImageActor mSecondaryCursor;
MeshActor mHighlightMeshActor; ///< Mesh Actor to display highlight
- TextSelectionPopup mCopyPastePopup;
+
+ PopupImpl mCopyPastePopup;
TextSelectionPopup::Buttons mEnabledPopupButtons; /// Bit mask of currently enabled Popup buttons
Image mHandleImages[HANDLE_TYPE_COUNT][HANDLE_IMAGE_TYPE_COUNT];
mEventData->mDecorator->SetHandleActive( RIGHT_SELECTION_HANDLE, true );
if( mEventData->mGrabHandlePopupEnabled )
{
- TextSelectionPopup::Buttons selectedButtons = TextSelectionPopup::Buttons( TextSelectionPopup::COPY );
+ TextSelectionPopup::Buttons selectedButtons = TextSelectionPopup::Buttons( TextSelectionPopup::CUT | TextSelectionPopup::COPY );
+ mEventData->mDecorator->SetEnabledPopupButtons( selectedButtons );
+ mEventData->mDecorator->SetPopupActive( true );
+ }
+ mEventData->mDecoratorUpdated = true;
+ }
+ else if ( EventData::SELECTION_CHANGED == mEventData->mState )
+ {
+ if( mEventData->mGrabHandlePopupEnabled )
+ {
+ TextSelectionPopup::Buttons selectedButtons = TextSelectionPopup::Buttons( TextSelectionPopup::CUT | TextSelectionPopup::COPY );
mEventData->mDecorator->SetEnabledPopupButtons( selectedButtons );
mEventData->mDecorator->SetPopupActive( true );
}
{
INACTIVE,
SELECTING,
+ SELECTION_CHANGED,
EDITING,
EDITING_WITH_POPUP,
GRAB_HANDLE_PANNING,
const std::string EMPTY_STRING("");
+float ConvertToEven( float value )
+{
+ int intValue(static_cast<int>( value ));
+ return static_cast<float>(intValue % 2 == 0) ? intValue : (intValue + 1);
+}
+
} // namespace
namespace Dali
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::GetNaturalSize cached %f,%f,%f\n", naturalSize.x, naturalSize.y, naturalSize.z );
}
+ naturalSize.x = ConvertToEven( naturalSize.x );
+ naturalSize.y = ConvertToEven( naturalSize.y );
+
return naturalSize;
}
if( !isShowingPlaceholderText && tapDuringEditMode )
{
- // Grab handle is not shown until a tap is received whilst EDITING
- if( tapDuringEditMode )
- {
- mImpl->mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, true );
- }
+ mImpl->mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, true );
mImpl->mEventData->mDecorator->SetPopupActive( false );
}
mImpl->mEventData->mSelectionEnabled &&
( 2u == tapCount ) )
{
- mImpl->ChangeState( EventData::SELECTING );
+ if ( mImpl->mEventData->mState == EventData::SELECTING )
+ {
+ mImpl->ChangeState( EventData::SELECTION_CHANGED );
+ }
+ else
+ {
+ mImpl->ChangeState( EventData::SELECTING );
+ }
}
}