Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_TEXT_INPUT_DECORATOR");
#endif
- const Vector3 DEFAULT_SELECTION_HANDLE_SIZE( 51.0f, 79.0f, 0.0f );
- const float TOP_HANDLE_TOP_OFFSET(-1.5f); // Offset between top handle and cutCopyPaste pop-up
- const float BOTTOM_HANDLE_BOTTOM_OFFSET(1.5f); // Offset between bottom handle and cutCopyPaste pop-up
- const float UI_Z_OFFSET( 0.2f ); // Text Selection Handles/Cursor z-offset.
- const Vector3 UI_OFFSET(0.0f, 0.0f, UI_Z_OFFSET); // Text Selection Handles/Cursor offset.
- const char* DEFAULT_CURSOR( DALI_IMAGE_DIR "cursor.png" );
- const Vector4 DEFAULT_CURSOR_IMAGE_9_BORDER( 2.0f, 2.0f, 2.0f, 2.0f );
- const std::size_t CURSOR_BLINK_INTERVAL = 500; // Cursor blink interval
- const float CURSOR_THICKNESS(6.0f);
- const Degree CURSOR_ANGLE_OFFSET(2.0f); // Offset from the angle
-
- const unsigned int SCROLL_TICK_INTERVAL = 50u;
- const float SCROLL_THRESHOLD = 10.f;
- const float SCROLL_SPEED = 15.f;
-
- /**
- * Whether the given position plus the cursor size offset is inside the given boundary.
- *
- * @param[in] position The given position.
- * @param[in] cursorSize The cursor size.
- * @param[in] controlSize The given boundary.
- * @param[in] threshold imaginary indent around boundary that will trigger the position to be outside of control.
- *
- * @return whether the given position is inside the given boundary.
- */
- bool IsPositionWithinControl( const Vector3& position, const Size& cursorSize, const Vector3& controlSize, const Vector2 threshold = Vector2::ZERO )
- {
- return ( position.x >= -Math::MACHINE_EPSILON_1000 + threshold.x ) &&
- ( position.x <= controlSize.width - threshold.x + Math::MACHINE_EPSILON_1000 ) &&
- ( position.y - cursorSize.height >= -Math::MACHINE_EPSILON_1000 + threshold.y ) &&
- ( position.y <= controlSize.height + Math::MACHINE_EPSILON_1000 - threshold.y);
- }
+const Vector3 DEFAULT_SELECTION_HANDLE_SIZE( 51.0f, 79.0f, 0.0f );
+const float TOP_HANDLE_TOP_OFFSET(-1.5f); // Offset between top handle and cutCopyPaste pop-up
+const float BOTTOM_HANDLE_BOTTOM_OFFSET(1.5f); // Offset between bottom handle and cutCopyPaste pop-up
+const float UI_Z_OFFSET( 0.2f ); // Text Selection Handles/Cursor z-offset.
+const Vector3 UI_OFFSET(0.0f, 0.0f, UI_Z_OFFSET); // Text Selection Handles/Cursor offset.
+const char* DEFAULT_CURSOR( DALI_IMAGE_DIR "cursor.png" );
+const Vector4 DEFAULT_CURSOR_IMAGE_9_BORDER( 2.0f, 2.0f, 2.0f, 2.0f );
+const std::size_t CURSOR_BLINK_INTERVAL = 500; // Cursor blink interval
+const float CURSOR_THICKNESS(6.0f);
+const Degree CURSOR_ANGLE_OFFSET(2.0f); // Offset from the angle
+
+const unsigned int SCROLL_TICK_INTERVAL = 50u;
+const float SCROLL_THRESHOLD = 10.f;
+const float SCROLL_SPEED = 15.f;
+
+/**
+ * Whether the given position plus the cursor size offset is inside the given boundary.
+ *
+ * @param[in] position The given position.
+ * @param[in] cursorSize The cursor size.
+ * @param[in] controlSize The given boundary.
+ * @param[in] threshold imaginary indent around boundary that will trigger the position to be outside of control.
+ *
+ * @return whether the given position is inside the given boundary.
+ */
+bool IsPositionWithinControl( const Vector3& position, const Size& cursorSize, const Vector3& controlSize, const Vector2 threshold = Vector2::ZERO )
+{
+ return ( position.x >= -Math::MACHINE_EPSILON_1000 + threshold.x ) &&
+ ( position.x <= controlSize.width - threshold.x + Math::MACHINE_EPSILON_1000 ) &&
+ ( position.y - cursorSize.height >= -Math::MACHINE_EPSILON_1000 + threshold.y ) &&
+ ( position.y <= controlSize.height + Math::MACHINE_EPSILON_1000 - threshold.y);
+}
+
}
namespace Dali
// Revert back to non-pressed selection handle images
if ( actor.GetParent() == mTextInputHandles.GetSelectionHandleOne() )
{
- mSelectionHandleOneActualPosition = MoveSelectionHandle( selectionHandleOne, mSelectionHandleOneActualPosition, mSelectionHandleOnePosition, gesture.displacement );
+ mSelectionHandleOneActualPosition = MoveSelectionHandle( selectionHandleOne, mSelectionHandleOneActualPosition, mSelectionHandleOnePosition, gesture.displacement );
ShowPopupCutCopyPaste();
- ShowPopUp();
}
else if ( actor.GetParent() == mTextInputHandles.GetSelectionHandleTwo() )
{
mSelectionHandleTwoActualPosition = MoveSelectionHandle( selectionHandleTwo, mSelectionHandleTwoActualPosition, mSelectionHandleTwoPosition, gesture.displacement );
ShowPopupCutCopyPaste();
- ShowPopUp();
}
else if ( actor.GetParent() == mTextInputHandles.GetGrabHandle() )
{
MoveGrabHandle( gesture.displacement );
SetCursorVisibility( true );
ShowPopupCutCopyPaste();
- ShowPopUp();
}
}
break;
mTextInputHandles.SetSelectionHandleTwoVisibility( visible );
}
-bool Decorator::OnHandleReleased()
-{
- ShowPopUp();
- return false;
-}
-
void Decorator::PositionSelectionHandles( std::size_t start, std::size_t end )
{
mSelectionHandleOnePosition = start;
mSelectionHandleOneActualPosition = PositionSelectionHandle( mTextInputHandles.GetSelectionHandleOne(), mSelectionHandleOnePosition );
mSelectionHandleTwoActualPosition = PositionSelectionHandle( mTextInputHandles.GetSelectionHandleTwo(), mSelectionHandleTwoPosition );
-
- mTextInputHandles.ReleasedSignal().Connect( this, &Decorator::OnHandleReleased );
}
Vector3 Decorator::MoveSelectionHandle( Actor selectionHandle,
// When text is selected, show popup above top handle (and text), or below bottom handle.
// topHandle: referring to the top most point of the handle or the top line of selection.
- if ( mSelectionHandleTwoActualPosition.y > mSelectionHandleOneActualPosition.y )
+ if ( mSelectionHandleTwoActualPosition.y > mSelectionHandleOneActualPosition.y ) // Handle may switch positions so calculate which is top.
{
topHandle = mSelectionHandleOneActualPosition;
rowSize= mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( mSelectionHandleOnePosition, min, max );
void SetSelectionHandlesVisibility( bool visible );
/**
- * @brief Callback for when a handle is released
- * @return bool
- */
- bool OnHandleReleased();
-
- /**
* @brief Position Selection handles at given positions within the text string.
*
* @param[in] start where to place first handle
--- /dev/null
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.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://floralicense.org/license/
+//
+// 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.
+//
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/text-input/text-input-handles-impl.h>
+#include <dali-toolkit/internal/controls/text-input/textview-character-positions-impl.h>
+
+#include <dali/dali.h>
+
+#include <dali-toolkit/internal/controls/text-input/text-input-impl.h>
+#include <dali-toolkit/internal/controls/text-view/text-processor.h>
+#include <dali-toolkit/internal/controls/text-view/text-view-impl.h>
+#include <dali-toolkit/public-api/controls/buttons/push-button.h>
+#include <dali-toolkit/public-api/controls/alignment/alignment.h>
+
+#include <dali/integration-api/debug.h>
+
+#include <math.h>
+#include <sstream>
+#include <algorithm>
+
+using namespace Dali;
+using namespace std;
+
+namespace
+{
+const char* const DEFAULT_SELECTION_HANDLE_ONE( DALI_IMAGE_DIR "text-input-selection-handle-left.png" );
+const char* const DEFAULT_SELECTION_HANDLE_TWO( DALI_IMAGE_DIR "text-input-selection-handle-right.png" );
+const char* const DEFAULT_SELECTION_HANDLE_ONE_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-left-press.png" );
+const char* const DEFAULT_SELECTION_HANDLE_TWO_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-right-press.png" );
+
+const char* const DEFAULT_GRAB_HANDLE( DALI_IMAGE_DIR "insertpoint-icon.png" );
+
+const Vector3 DEFAULT_SELECTION_HANDLE_RELATIVE_SCALE( 1.5f, 1.5f, 1.0f );
+const Vector3 DEFAULT_GRAB_HANDLE_RELATIVE_SCALE( 1.5f, 2.0f, 1.0f );
+
+const char* const SELECTION_GRAB_AREA_ONE( "SelectionHandleOneGrabArea");
+const char* const SELECTION_GRAB_AREA_TWO( "SelectionHandleTwoGrabArea");
+const char* const GRABHANDLE_GRAB_AREA( "GrabHandleGrabArea");
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "TEXT_INPUT_HANDLES" );
+#endif
+
+Actor CreateGrabArea( const std::string& name, const Vector3& relativeScale )
+{
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: CreateGrabArea\n" );
+
+ Actor handleGrabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
+ handleGrabArea.SetName( name );
+ handleGrabArea.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), RelativeToConstraint( relativeScale ) ) ); // grab area to be larger than text actor
+ handleGrabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
+
+ return handleGrabArea;
+}
+
+Actor CreateHandle( const Vector3& anchorPoint, const Image& handleImage, const std::string& name )
+{
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: CreateSelectionHandle\n" );
+
+ ImageActor selectionHandle = ImageActor::New( handleImage );
+ selectionHandle.SetName( name );
+ selectionHandle.SetAnchorPoint( anchorPoint );
+ selectionHandle.SetDrawMode( DrawMode::OVERLAY ); // ensure handle above text
+
+ return selectionHandle;
+}
+}
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+// Default constructor
+TextInputHandles::TextInputHandles():
+ mSelectionHandleOne(),
+ mSelectionHandleTwo(),
+ mSelectionHandleOneOffset( Vector3::ZERO ),
+ mSelectionHandleTwoOffset( Vector3::ZERO ),
+ mSelectionHandleOneCoordinatePosition( Vector3::ZERO ),
+ mSelectionHandleTwoCoordinatePosition( Vector3::ZERO ),
+ mSelectionHandleOneStringPosition( 0 ),
+ mSelectionHandleTwoStringPosition( 0 ),
+ mIsSelectionHandleOneFlipped( false ),
+ mIsSelectionHandleTwoFlipped( false )
+{
+}
+
+TextInputHandles::~TextInputHandles()
+{
+}
+
+void TextInputHandles::CreateSelectionHandles()
+{
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: CreateSelectionHandles\n" );
+
+ mSelectionHandleOneImage = Image::New( DEFAULT_SELECTION_HANDLE_ONE );
+ mSelectionHandleOneImagePressed = Image::New( DEFAULT_SELECTION_HANDLE_ONE_PRESSED );
+ mSelectionHandleOne = CreateHandle( AnchorPoint::TOP_RIGHT, mSelectionHandleOneImage, "SelectionHandleOne" );
+ mIsSelectionHandleOneFlipped = false;
+
+ mHandleOneGrabArea = CreateGrabArea( SELECTION_GRAB_AREA_ONE, DEFAULT_SELECTION_HANDLE_RELATIVE_SCALE );
+ mSelectionHandleOne.Add( mHandleOneGrabArea );
+ mHandleOneGrabArea.TouchedSignal().Connect(this, &TextInputHandles::OnSelectionHandleTouched);
+
+// mTapDetector.Attach( mHandleOneGrabArea );
+
+ mSelectionHandleTwoImage = Image::New( DEFAULT_SELECTION_HANDLE_TWO );
+ mSelectionHandleTwoImagePressed = Image::New( DEFAULT_SELECTION_HANDLE_TWO_PRESSED );
+ mSelectionHandleTwo = CreateHandle( AnchorPoint::TOP_LEFT, mSelectionHandleTwoImage, "SelectionHandleTwo" );
+ mIsSelectionHandleTwoFlipped = false;
+
+ mHandleTwoGrabArea = CreateGrabArea( SELECTION_GRAB_AREA_TWO, DEFAULT_SELECTION_HANDLE_RELATIVE_SCALE );
+ mSelectionHandleTwo.Add( mHandleTwoGrabArea );
+ mHandleTwoGrabArea.TouchedSignal().Connect(this, &TextInputHandles::OnSelectionHandleTouched);
+
+ // mTapDetector.Attach( mHandleTwoGrabArea );
+}
+
+void TextInputHandles::DestorySelectionHandles()
+{
+ if ( mSelectionHandleOne && mSelectionHandleTwo)
+ {
+ mSelectionHandleOne.Unparent();
+ mSelectionHandleTwo.Unparent();
+ mSelectionHandleOneImagePressed.Reset();
+ mSelectionHandleOneImage.Reset();
+ mSelectionHandleTwoImagePressed.Reset();
+ mSelectionHandleTwoImage.Reset();
+ mSelectionHandleOne.Reset();
+ mSelectionHandleTwo.Reset();
+ }
+}
+
+void TextInputHandles::SetSelectionHandleOneVisibility( bool visibility )
+{
+ if ( mSelectionHandleOne )
+ {
+ mSelectionHandleOne.SetVisible( visibility );
+ }
+}
+
+void TextInputHandles::SetSelectionHandleTwoVisibility( bool visibility )
+{
+ if ( mSelectionHandleTwo )
+ {
+ mSelectionHandleTwo.SetVisible( visibility );
+ }
+}
+
+void TextInputHandles::AttachSelectionHandlesToGivenPanGesture( PanGestureDetector& panGestureDetector )
+{
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: AttachSelectionHandlesToGivenPanGesture\n" );
+
+ panGestureDetector.Attach( mHandleOneGrabArea );
+ panGestureDetector.Attach( mHandleTwoGrabArea );
+}
+
+void TextInputHandles::AttachSelectionHandlesToGivenTapDetector(TapGestureDetector& tapGestureDetector )
+{
+ tapGestureDetector.Attach( mHandleOneGrabArea );
+ tapGestureDetector.Attach( mHandleTwoGrabArea );
+}
+
+void TextInputHandles::AttachGrabHandleToGivenPanGesture( PanGestureDetector& panGestureDetector )
+{
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: AttachGrabHandleToGivenPanGesture\n" );
+
+ panGestureDetector.Attach( mGrabHandleGrabArea );
+}
+
+Actor TextInputHandles::GetSelectionHandleOne()
+{
+ return mSelectionHandleOne;
+}
+
+Actor TextInputHandles::GetSelectionHandleTwo()
+{
+ return mSelectionHandleTwo;
+}
+
+bool TextInputHandles::OnSelectionHandleTouched(Dali::Actor actor, const TouchEvent& touch)
+{
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: OnSelectionHandleTouched\n" );
+
+ Image pressedImage;
+ Image normalImage;
+
+ ImageActor handleTouched = ImageActor::DownCast( actor.GetParent() ); // Hit actor would be the GrabArea hence get parent.
+
+ if ( handleTouched == mSelectionHandleOne )
+ {
+ pressedImage = mSelectionHandleOneImagePressed;
+ normalImage = mSelectionHandleOneImage;
+ }
+ else
+ {
+ pressedImage = mSelectionHandleTwoImagePressed;
+ normalImage = mSelectionHandleTwoImage;
+ }
+
+ if (touch.GetPoint(0).state == TouchPoint::Down)
+ {
+ handleTouched.SetImage( pressedImage );
+ }
+ else if (touch.GetPoint(0).state == TouchPoint::Up )
+ {
+ handleTouched.SetImage( normalImage );
+ }
+ return false;
+}
+
+// Grab handle
+
+Actor TextInputHandles::GetGrabHandle()
+{
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: GetGrabHandle\n" );
+
+ return mGrabHandle;
+}
+
+void TextInputHandles::CreateGrabHandle()
+{
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: CreateGrabHandle\n" );
+
+ if ( !mGrabHandle )
+ {
+ if ( !mGrabHandleImage )
+ {
+ mGrabHandleImage = Image::New( DEFAULT_GRAB_HANDLE );
+ }
+
+ mGrabHandle = CreateHandle( AnchorPoint::TOP_CENTER, mGrabHandleImage, "GrabHandle" );
+ mGrabHandleGrabArea = CreateGrabArea( GRABHANDLE_GRAB_AREA, DEFAULT_GRAB_HANDLE_RELATIVE_SCALE );
+ mGrabHandle.Add( mGrabHandleGrabArea );
+ }
+}
+
+void TextInputHandles::DestoryGrabHandle()
+{
+ if ( mGrabHandle )
+ {
+ mGrabHandle.Unparent();
+ mGrabHandleImage.Reset();
+ mGrabHandle.Reset();
+ }
+}
+
+void TextInputHandles::SetGrabHandleImage( Dali::Image image )
+{
+ if ( mGrabHandle )
+ {
+ mGrabHandleImage = image;
+ mGrabHandle.SetImage( mGrabHandleImage );
+ }
+}
+
+void TextInputHandles::SetGrabHandleVisibility( bool visibility )
+{
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: SetGrabHandleVisibility (%s) \n", ( visibility )?"true":"false" );
+
+ if ( mGrabHandle )
+ {
+ mGrabHandle.SetVisible( visibility );
+ }
+}
+
+} // Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
public:
- typedef SignalV2< bool () > HandlesReleasedSignal;
-
- /**
- * Signal emitted when a handle is released
- */
- HandlesReleasedSignal& ReleasedSignal(){ return mReleasedSignal; };
-
/**
* Default constructor
*/
- TextInputHandles() {}
+ TextInputHandles();
/**
* Destructor
*/
- ~TextInputHandles() {};
+ ~TextInputHandles();
/**
* Create the selection handles
*/
- void CreateSelectionHandles(){};
+ void CreateSelectionHandles();
/**
* Un-parents the Selection Handles and resets their Image Actors
*/
- void DestorySelectionHandles(){};
+ void DestorySelectionHandles();
/**
* Set the Actor visibility on Selection Handle One
* @param[in] visibility visibility flag
*/
- void SetSelectionHandleOneVisibility( bool visibility ){};
+ void SetSelectionHandleOneVisibility( bool visibility );
/**
* Set the Actor visibility on Selection Handle Two
* @param[in] visibility visibility flag
*/
- void SetSelectionHandleTwoVisibility( bool visibility ){};
+ void SetSelectionHandleTwoVisibility( bool visibility );
/**
* Attach the two selection handles to the pan gesture detector
* @param[in] panGestureDetector the PanGestureDetector to attach to
*/
- void AttachSelectionHandlesToGivenPanGesture(PanGestureDetector& panGestureDetector ){};
+ void AttachSelectionHandlesToGivenPanGesture(PanGestureDetector& panGestureDetector );
/**
* Attach the two selection handles to the tap gesture detector
* @param[in] tapGestureDetector the TapGestureDetector to attach to
*/
- void AttachSelectionHandlesToGivenTapDetector(TapGestureDetector& tapGestureDetector ){};
+ void AttachSelectionHandlesToGivenTapDetector(TapGestureDetector& tapGestureDetector );
/**
* Attach the grab handle to the pan gesture detector
* @param[in] panGestureDetector the PanGestureDetector to attach to
*/
- void AttachGrabHandleToGivenPanGesture( PanGestureDetector& panGestureDetector ){};
+ void AttachGrabHandleToGivenPanGesture( PanGestureDetector& panGestureDetector );
/**
* Get Selection handle one
* @return selection handle actor
*/
- Actor GetSelectionHandleOne() { return Actor(); };
+ Actor GetSelectionHandleOne();
/**
* Get Selection handle two
* @return selection handle actor
*/
- Actor GetSelectionHandleTwo() { return Actor(); };
+ Actor GetSelectionHandleTwo();
/**
* Get the grab handle
* @return grab handle Actor
*/
- Actor GetGrabHandle() { return Actor(); };
+ Actor GetGrabHandle();
/**
* Create the grab handle that positions the cursor
* @param[in] image the image to be used.
*/
- void CreateGrabHandle(){};
+ void CreateGrabHandle();
/**
* Removes and Resets GrabHandle
*/
- void DestoryGrabHandle(){};
+ void DestoryGrabHandle();
/**
* Set the image to be used as the cursor grab hander
* @pre The text input actor has been initialised.
* @param[in] image The image to be used.
*/
- void SetGrabHandleImage( Dali::Image image ){};
+ void SetGrabHandleImage( Dali::Image image );
/**
* Set the Actor visibility on the GrabHandle
* @param[in] visibility visibility flag
*/
- void SetGrabHandleVisibility( bool visibility ){};
+ void SetGrabHandleVisibility( bool visibility );
/* Touch Event Callbacks */
* @param[in] actor touched
* @param[in] touch touch event, used to determine if down or up event
*/
- bool OnSelectionHandleTouched(Dali::Actor actor, const TouchEvent& touch){ return true; };
+ bool OnSelectionHandleTouched(Dali::Actor actor, const TouchEvent& touch);
private:
ImageActor mGrabHandle; // Handle used to move cursor for editing
Actor mGrabHandleGrabArea; // invisible actor that receives pans events for the grab handle.
- HandlesReleasedSignal mReleasedSignal; // Signal emitted when a handle is released
-
bool mIsSelectionHandleOneFlipped:1; // Flag to know whether the handle one is flipped or not.
bool mIsSelectionHandleTwoFlipped:1; // Flag to know whether the handle two is flipped or not.
};
$(toolkit_base_src_dir)/controls/scrollable/scroll-view/scroll-view-wobble-effect-impl.cpp \
$(toolkit_base_src_dir)/controls/table-view/table-view-impl.cpp \
$(toolkit_base_src_dir)/controls/text-input/text-input-decorator-impl.cpp \
+ $(toolkit_base_src_dir)/controls/text-input/text-input-handles-impl.cpp \
$(toolkit_base_src_dir)/controls/text-input/text-input-impl.cpp \
$(toolkit_base_src_dir)/controls/text-input/text-input-popup-impl.cpp \
$(toolkit_base_src_dir)/controls/text-view/relayout-utilities.cpp \