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
// Remove the previously set text
ResetText();
+ CharacterIndex lastCursorIndex = 0u;
+
if( !text.empty() )
{
// Convert text into UTF-32
DALI_ASSERT_DEBUG( text.size() >= characterCount && "Invalid UTF32 conversion length" );
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::SetText %p UTF8 size %d, UTF32 size %d\n", this, text.size(), mImpl->mLogicalModel->mText.Count() );
- // Reset the cursor position
- if( mImpl->mEventData )
- {
- mImpl->mEventData->mPrimaryCursorPosition = characterCount;
- }
+ // To reset the cursor position
+ lastCursorIndex = characterCount;
// Update the rest of the model during size negotiation
mImpl->QueueModifyEvent( ModifyEvent::TEXT_REPLACED );
ShowPlaceholderText();
}
+ // Resets the cursor position.
+ ResetCursorPosition( lastCursorIndex );
+
+ // Scrolls the text to make the cursor visible.
+ ResetScrollPosition();
+
mImpl->RequestRelayout();
if( mImpl->mEventData )
numberOfChars = currentText.Count() - cursorIndex;
}
- if( cursorIndex >= 0 &&
- (cursorIndex + numberOfChars) <= currentText.Count() )
+ if( (cursorIndex + numberOfChars) <= currentText.Count() )
{
Vector<Character>::Iterator first = currentText.Begin() + cursorIndex;
Vector<Character>::Iterator last = first + numberOfChars;
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;
}
mImpl->mLogicalModel->mText.Clear();
ClearModelData();
- // Reset the cursor position
- if( mImpl->mEventData )
- {
- mImpl->mEventData->mPrimaryCursorPosition = 0;
- }
-
// We have cleared everything including the placeholder-text
mImpl->PlaceholderCleared();
mImpl->mOperationsPending = ALL_OPERATIONS;
}
+void Controller::ResetCursorPosition( CharacterIndex cursorIndex )
+{
+ // Reset the cursor position
+ if( NULL != mImpl->mEventData )
+ {
+ mImpl->mEventData->mPrimaryCursorPosition = cursorIndex;
+
+ // Update the cursor if it's in editing mode.
+ if( ( EventData::EDITING == mImpl->mEventData->mState ) ||
+ ( EventData::EDITING_WITH_POPUP == mImpl->mEventData->mState ) )
+ {
+ mImpl->mEventData->mUpdateCursorPosition = true;
+ }
+ }
+}
+
+void Controller::ResetScrollPosition()
+{
+ if( NULL != mImpl->mEventData )
+ {
+ // Reset the scroll position.
+ mImpl->mEventData->mScrollPosition = Vector2::ZERO;
+ mImpl->mEventData->mScrollAfterUpdatePosition = true;
+ }
+}
+
void Controller::TextReplacedEvent()
{
// Reset buffers.
// Queue a cursor reposition event; this must wait until after DoRelayout()
mImpl->mEventData->mUpdateCursorPosition = true;
- mImpl->mEventData->mScrollAfterUpdateCursorPosition = true;
+ mImpl->mEventData->mScrollAfterUpdatePosition = true;
}
void Controller::TextDeletedEvent()
REORDER );
// Queue a cursor reposition event; this must wait until after DoRelayout()
- mImpl->mEventData->mUpdateCursorPosition = true;
- mImpl->mEventData->mScrollAfterUpdateCursorPosition = true;
+ mImpl->mEventData->mScrollAfterDelete = true;
}
bool Controller::DoRelayout( const Size& size,
}
} // REORDER
- // TODO: I'm working on a patch that changes the LayoutEngine::Align() method.
- // The layoutParameters is not needed and this call can be moved outside the if().
- // Then there is no need to do the layout again to change the alignment.
- if( ALIGN & operations )
- {
- mImpl->mLayoutEngine.Align( layoutParameters,
- layoutSize,
- lines,
- glyphPositions );
- }
-
// Sets the actual size.
if( UPDATE_ACTUAL_SIZE & operations )
{
layoutSize = mImpl->mVisualModel->GetActualSize();
}
+ if( ALIGN & operations )
+ {
+ // The laid-out lines.
+ Vector<LineRun>& lines = mImpl->mVisualModel->mLines;
+
+ mImpl->mLayoutEngine.Align( layoutSize,
+ lines );
+
+ viewUpdated = true;
+ }
+
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::DoRelayout, view updated %s\n", ( viewUpdated ? "true" : "false" ) );
return viewUpdated;
}
mImpl->mLayoutEngine.SetHorizontalAlignment( alignment );
// Set the flag to redo the alignment operation.
- // TODO : Is not needed re-layout and reorder again but with the current implementation it is.
- // Im working on a different patch to fix an issue with the alignment. When that patch
- // is in, this issue can be fixed.
- const OperationsMask layoutOperations = static_cast<OperationsMask>( LAYOUT |
- UPDATE_ACTUAL_SIZE |
- ALIGN |
- REORDER );
-
- mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending | layoutOperations );
+ mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending | ALIGN );
mImpl->RequestRelayout();
}
int keyCode = keyEvent.keyCode;
const std::string& keyString = keyEvent.keyPressed;
+ // Hide the grab handle.
+ mImpl->mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, false );
+
// Pre-process to separate modifying events from non-modifying input events.
if( Dali::DALI_KEY_ESCAPE == keyCode )
{
if( removed )
{
- if( 0u == mImpl->mLogicalModel->mText.Count() )
+ if( 0u != mImpl->mLogicalModel->mText.Count() ||
+ !mImpl->IsPlaceholderAvailable() )
{
- ShowPlaceholderText();
- mImpl->mEventData->mUpdateCursorPosition = true;
+ mImpl->QueueModifyEvent( ModifyEvent::TEXT_DELETED );
}
else
{
- mImpl->QueueModifyEvent( ModifyEvent::TEXT_DELETED );
+ ShowPlaceholderText();
+ mImpl->mEventData->mUpdateCursorPosition = true;
}
textChanged = true;
if( NULL != mImpl->mEventData )
{
+ const bool isShowingPlaceholderText = mImpl->IsShowingPlaceholderText();
if( 1u == tapCount )
{
bool tapDuringEditMode( EventData::EDITING == mImpl->mEventData->mState );
- if( ! mImpl->IsShowingPlaceholderText() &&
- EventData::EDITING == mImpl->mEventData->mState )
+ 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->ChangeState( EventData::EDITING );
}
- else if( mImpl->mEventData->mSelectionEnabled &&
+ else if( !isShowingPlaceholderText &&
+ 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 );
+ }
}
}
}
}
-void Controller::HandleEvent( HandleType handleType, HandleState state, float x, float y )
+void Controller::GetTargetSize( Vector2& targetSize )
{
- DALI_ASSERT_DEBUG( mImpl->mEventData && "Controller::HandleEvent. Unexpected HandleEvent" );
+ targetSize = mImpl->mControlSize;
+}
+
+void Controller::AddDecoration( Actor& actor, bool needsClipping )
+{
+ mImpl->mControlInterface.AddDecoration( actor, needsClipping );
+}
+
+void Controller::DecorationEvent( HandleType handleType, HandleState state, float x, float y )
+{
+ DALI_ASSERT_DEBUG( mImpl->mEventData && "Unexpected DecorationEvent" );
if( mImpl->mEventData )
{
}
}
+void Controller::TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Buttons button )
+{
+}
+
ImfManager::ImfCallbackData Controller::OnImfEvent( ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
{
bool update( false );