{
// If popup shown then hide it by switching to Editing state
if( ( EventData::SELECTING == mImpl->mEventData->mState ) ||
- ( EventData::SELECTION_CHANGED == mImpl->mEventData->mState ) ||
( EventData::EDITING_WITH_POPUP == mImpl->mEventData->mState ) ||
( EventData::EDITING_WITH_GRAB_HANDLE == mImpl->mEventData->mState ) )
{
return mImpl->mMaximumNumberOfCharacters;
}
-void Controller::SetDefaultFontFamily( const std::string& defaultFontFamily, bool userDefined )
+void Controller::SetDefaultFontFamily( const std::string& defaultFontFamily )
{
if( !mImpl->mFontDefaults )
{
}
mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily;
- DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s userDefined: %s\n", defaultFontFamily.c_str(), userDefined ? "true":"false" );
- mImpl->mUserDefinedFontFamily = userDefined;
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str());
+ mImpl->mUserDefinedFontFamily = true;
// Clear the font-specific data
ClearFontData();
{
DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange");
- ClearFontData();
-
if ( !mImpl->mUserDefinedFontFamily ) // If user defined font then should not update when system font changes
{
DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange newDefaultFont(%s)\n", newDefaultFont.c_str() );
+ ClearFontData();
mImpl->mFontDefaults->mFontDescription.family = newDefaultFont;
mImpl->UpdateModel( ALL_OPERATIONS );
mImpl->QueueModifyEvent( ModifyEvent::TEXT_REPLACED );
cursorIndex = oldCursorIndex + cursorOffset;
}
- if( (cursorIndex + numberOfChars) > currentText.Count() )
+ if( ( cursorIndex + numberOfChars ) > currentText.Count() )
{
numberOfChars = currentText.Count() - cursorIndex;
}
- if( (cursorIndex + numberOfChars) <= currentText.Count() )
+ if( ( cursorIndex + numberOfChars ) <= currentText.Count() )
{
Vector<Character>::Iterator first = currentText.Begin() + cursorIndex;
Vector<Character>::Iterator last = first + numberOfChars;
ProcessModifyEvents();
Size layoutSize;
- if( width != mImpl->mVisualModel->mControlSize.width )
+ if( fabsf( width - mImpl->mVisualModel->mControlSize.width ) > Math::MACHINE_EPSILON_1000 )
{
// Operations that can be done only once until the text changes.
const OperationsMask onlyOnceOperations = static_cast<OperationsMask>( CONVERT_TO_UTF32 |
return glyphsRemoved;
}
- if( size != mImpl->mVisualModel->mControlSize )
+ const bool newSize = ( size != mImpl->mVisualModel->mControlSize );
+
+ if( newSize )
{
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "new size (previous size %f,%f)\n", mImpl->mVisualModel->mControlSize.width, mImpl->mVisualModel->mControlSize.height );
// Do not re-do any operation until something changes.
mImpl->mOperationsPending = NO_OPERATION;
- // Keep the current offset and alignment as it will be used to update the decorator's positions.
+ // Keep the current offset and alignment as it will be used to update the decorator's positions (if the size changes).
Vector2 offset;
- if( mImpl->mEventData )
+ if( newSize && mImpl->mEventData )
{
offset = mImpl->mAlignmentOffset + mImpl->mEventData->mScrollPosition;
}
if( mImpl->mEventData )
{
- // If there is a nex size, the scroll position needs to be clamped.
- mImpl->ClampHorizontalScroll( layoutSize );
+ if( newSize )
+ {
+ // If there is a new size, the scroll position needs to be clamped.
+ mImpl->ClampHorizontalScroll( layoutSize );
- // Update the decorator's positions.
- mImpl->mEventData->mDecorator->UpdatePositions( mImpl->mAlignmentOffset + mImpl->mEventData->mScrollPosition - offset );
+ // Update the decorator's positions is needed if there is a new size.
+ mImpl->mEventData->mDecorator->UpdatePositions( mImpl->mAlignmentOffset + mImpl->mEventData->mScrollPosition - offset );
+ }
// Move the cursor, grab handle etc.
updated = mImpl->ProcessInputEvents() || updated;
for( unsigned int i=0; i<events.size(); ++i )
{
- if( ModifyEvent::TEXT_REPLACED == events[0].type )
+ if( ModifyEvent::TEXT_REPLACED == events[i].type )
{
// A (single) replace event should come first, otherwise we wasted time processing NOOP events
DALI_ASSERT_DEBUG( 0 == i && "Unexpected TEXT_REPLACED event" );
TextReplacedEvent();
}
- else if( ModifyEvent::TEXT_INSERTED == events[0].type )
+ else if( ModifyEvent::TEXT_INSERTED == events[i].type )
{
TextInsertedEvent();
}
- else if( ModifyEvent::TEXT_DELETED == events[0].type )
+ else if( ModifyEvent::TEXT_DELETED == events[i].type )
{
// Placeholder-text cannot be deleted
if( !mImpl->IsShowingPlaceholderText() )
REORDER );
// Queue a cursor reposition event; this must wait until after DoRelayout()
- if( 0u == mImpl->mLogicalModel->mText.Count() )
- {
- mImpl->mEventData->mUpdateCursorPosition = true;
- }
- else
+ mImpl->mEventData->mUpdateCursorPosition = true;
+ if( 0u != mImpl->mLogicalModel->mText.Count() )
{
mImpl->mEventData->mScrollAfterDelete = true;
}
}
case LayoutEngine::HORIZONTAL_ALIGN_CENTER:
{
- const int intOffset = static_cast<int>( 0.5f * ( size.width - actualSize.width ) ); // try to avoid pixel alignment.
- mImpl->mAlignmentOffset.x = static_cast<float>( intOffset );
+ mImpl->mAlignmentOffset.x = floorf( 0.5f * ( size.width - actualSize.width ) ); // try to avoid pixel alignment.
break;
}
case LayoutEngine::HORIZONTAL_ALIGN_END:
}
case LayoutEngine::VERTICAL_ALIGN_CENTER:
{
- const int intOffset = static_cast<int>( 0.5f * ( size.height - actualSize.height ) ); // try to avoid pixel alignment.
- mImpl->mAlignmentOffset.y = static_cast<float>( intOffset );
+ mImpl->mAlignmentOffset.y = floorf( 0.5f * ( size.height - actualSize.height ) ); // try to avoid pixel alignment.
break;
}
case LayoutEngine::VERTICAL_ALIGN_BOTTOM:
{
bool textRemoved( false );
- if ( EventData::SELECTING == mImpl->mEventData->mState ||
- EventData::SELECTION_CHANGED == mImpl->mEventData->mState )
+ if( EventData::SELECTING == mImpl->mEventData->mState )
{
std::string removedString;
mImpl->RetrieveSelection( removedString, true );
else if( EventData::EDITING != mImpl->mEventData->mState &&
EventData::EDITING_WITH_GRAB_HANDLE != mImpl->mEventData->mState )
{
- if( mImpl->IsShowingPlaceholderText() && ! mImpl->IsFocusedPlaceholderAvailable() )
+ if( mImpl->IsShowingPlaceholderText() && !mImpl->IsFocusedPlaceholderAvailable() )
{
// Hide placeholder text
ResetText();
{
if( mImpl->mEventData )
{
- if ( mImpl->mEventData->mState == EventData::SELECTING )
- {
- mImpl->ChangeState( EventData::SELECTION_CHANGED );
- }
- else
- {
- mImpl->ChangeState( EventData::SELECTING );
- }
+ mImpl->ChangeState( EventData::SELECTING );
if( selectAll )
{
InsertText( stringToPaste, Text::Controller::COMMIT );
mImpl->ChangeState( EventData::EDITING );
mImpl->RequestRelayout();
+
+ // Do this last since it provides callbacks into application code
+ mImpl->mControlInterface.TextChanged();
}
void Controller::PasteClipboardItemEvent()
{
+ // Retrieve the clipboard contents first
ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
std::string stringToPaste( notifier.GetContent() );
+
+ // Commit the current pre-edit text; the contents of the clipboard should be appended
+ mImpl->ResetImfManager();
+
+ // Paste
PasteText( stringToPaste );
}
ImfManager::ImfCallbackData Controller::OnImfEvent( ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
{
- bool update( false );
+ bool update = false;
bool requestRelayout = false;
std::string text;
case ImfManager::COMMIT:
{
InsertText( imfEvent.predictiveString, Text::Controller::COMMIT );
+ update=true;
requestRelayout = true;
break;
}
bool removed( false );
- if ( EventData::SELECTING == mImpl->mEventData->mState ||
- EventData::SELECTION_CHANGED == mImpl->mEventData->mState )
+ if( EventData::SELECTING == mImpl->mEventData->mState )
{
removed = RemoveSelectedText();
}
if( removed )
{
- // This is to reset the virtual keyboard to Upper-case
- if( 0u == mImpl->mLogicalModel->mText.Count() )
- {
- NotifyImfManager();
- }
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::KeyEvent %p DALI_KEY_BACKSPACE RemovedText\n", this );
+ // Notifiy the IMF manager after text changed
+ // Automatic Upper-case and restarting prediction on an existing word require this.
+ NotifyImfManager();
if( 0u != mImpl->mLogicalModel->mText.Count() ||
!mImpl->IsPlaceholderAvailable() )
{
if( mImpl->mEventData )
{
- ImfManager imfManager = ImfManager::Get();
-
- if( imfManager )
+ if( mImpl->mEventData->mImfManager )
{
// Notifying IMF of a cursor change triggers a surrounding text request so updating it now.
std::string text;
GetText( text );
- imfManager.SetSurroundingText( text );
+ mImpl->mEventData->mImfManager.SetSurroundingText( text );
- imfManager.SetCursorPosition( GetLogicalCursorPosition() );
- imfManager.NotifyCursorPosition();
+ mImpl->mEventData->mImfManager.SetCursorPosition( GetLogicalCursorPosition() );
+ mImpl->mEventData->mImfManager.NotifyCursorPosition();
}
}
}