#include <dali/public-api/object/type-registry.h>
#include <dali/public-api/object/type-registry-helper.h>
#include <dali/public-api/scripting/scripting.h>
-#include <dali/integration-api/debug.h>
#include <dali/public-api/adaptor-framework/virtual-keyboard.h>
+#include <dali/integration-api/debug.h>
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/text/rendering-backend.h>
namespace Internal
{
-namespace
+namespace // unnamed namespace
{
+
+#if defined(DEBUG_ENABLED)
+ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
+#endif
+
const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
-}
+
+} // unnamed namespace
namespace
{
case Toolkit::TextField::Property::RENDERING_BACKEND:
{
int backend = value.Get< int >();
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p RENDERING_BACKEND %d\n", impl.mController.Get(), backend );
if( impl.mRenderingBackend != backend )
{
{
if( impl.mController )
{
- impl.mController->SetText( value.Get< std::string >() );
+ std::string text = value.Get< std::string >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p TEXT %s\n", impl.mController.Get(), text.c_str() );
+
+ impl.mController->SetText( text );
}
break;
}
{
if( impl.mController )
{
- impl.mController->SetPlaceholderText( PLACEHOLDER_TYPE_INACTIVE, value.Get< std::string >() );
+ std::string text = value.Get< std::string >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT %s\n", impl.mController.Get(), text.c_str() );
+
+ impl.mController->SetPlaceholderText( PLACEHOLDER_TYPE_INACTIVE, text );
}
break;
}
{
if( impl.mController )
{
- impl.mController->SetPlaceholderText( PLACEHOLDER_TYPE_ACTIVE, value.Get< std::string >() );
+ std::string text = value.Get< std::string >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_FOCUSED %s\n", impl.mController.Get(), text.c_str() );
+
+ impl.mController->SetPlaceholderText( PLACEHOLDER_TYPE_ACTIVE, text );
}
break;
}
if( impl.mController )
{
std::string fontFamily = value.Get< std::string >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
if( impl.mController->GetDefaultFontFamily() != fontFamily )
{
if( impl.mController )
{
std::string fontStyle = value.Get< std::string >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p FONT_STYLE %s\n", impl.mController.Get(), fontStyle.c_str() );
if( impl.mController->GetDefaultFontStyle() != fontStyle )
{
if( impl.mController )
{
float pointSize = value.Get< float >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p FONT_STYLE %f\n", impl.mController.Get(), pointSize );
if( !Equals( impl.mController->GetDefaultPointSize(), pointSize ) )
{
}
case Toolkit::TextField::Property::EXCEED_POLICY:
{
- impl.mExceedPolicy = value.Get< int >();
+ // TODO
break;
}
case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
{
- LayoutEngine& engine = impl.mController->GetLayoutEngine();
- const LayoutEngine::HorizontalAlignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( value.Get< std::string >().c_str(),
- HORIZONTAL_ALIGNMENT_STRING_TABLE,
- HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
-
- if( engine.GetHorizontalAlignment() != alignment )
+ if( impl.mController )
{
- engine.SetHorizontalAlignment( alignment );
- impl.RequestTextRelayout();
+ std::string alignStr = value.Get< std::string >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p HORIZONTAL_ALIGNMENT %f\n", impl.mController.Get(), alignStr.c_str() );
+
+ LayoutEngine& engine = impl.mController->GetLayoutEngine();
+ LayoutEngine::HorizontalAlignment alignment = Scripting::GetEnumeration< LayoutEngine::HorizontalAlignment >( alignStr.c_str(),
+ HORIZONTAL_ALIGNMENT_STRING_TABLE,
+ HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+
+ if( engine.GetHorizontalAlignment() != alignment )
+ {
+ engine.SetHorizontalAlignment( alignment );
+ impl.RequestTextRelayout();
+ }
}
break;
}
case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
{
- LayoutEngine& engine = impl.mController->GetLayoutEngine();
- const LayoutEngine::VerticalAlignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( value.Get< std::string >().c_str(),
- VERTICAL_ALIGNMENT_STRING_TABLE,
- VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
-
- if( engine.GetVerticalAlignment() != alignment )
+ if( impl.mController )
{
- engine.SetVerticalAlignment( alignment );
- impl.RequestTextRelayout();
+ std::string alignStr = value.Get< std::string >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p VERTICAL_ALIGNMENT %f\n", impl.mController.Get(), alignStr.c_str() );
+
+ LayoutEngine& engine = impl.mController->GetLayoutEngine();
+ LayoutEngine::VerticalAlignment alignment = Scripting::GetEnumeration< LayoutEngine::VerticalAlignment >( alignStr.c_str(),
+ VERTICAL_ALIGNMENT_STRING_TABLE,
+ VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
+
+ if( engine.GetVerticalAlignment() != alignment )
+ {
+ engine.SetVerticalAlignment( alignment );
+ impl.RequestTextRelayout();
+ }
}
break;
}
if ( impl.mController )
{
Vector4 textColor = value.Get< Vector4 >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a );
+
if ( impl.mController->GetTextColor() != textColor )
{
impl.mController->SetTextColor( textColor );
if ( impl.mController )
{
Vector4 textColor = value.Get< Vector4 >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a );
+
if ( impl.mController->GetPlaceholderTextColor() != textColor )
{
impl.mController->SetPlaceholderTextColor( textColor );
if( impl.mController )
{
Vector2 shadowOffset = value.Get< Vector2 >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SHADOW_OFFSET %f,%f\n", impl.mController.Get(), shadowOffset.x, shadowOffset.y );
+
if ( impl.mController->GetShadowOffset() != shadowOffset )
{
impl.mController->SetShadowOffset( shadowOffset );
if( impl.mController )
{
Vector4 shadowColor = value.Get< Vector4 >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SHADOW_COLOR %f,%f,%f,%f\n", impl.mController.Get(), shadowColor.r, shadowColor.g, shadowColor.b, shadowColor.a );
+
if ( impl.mController->GetShadowColor() != shadowColor )
{
impl.mController->SetShadowColor( shadowColor );
{
if( impl.mDecorator )
{
- impl.mDecorator->SetColor( PRIMARY_CURSOR, value.Get< Vector4 >() );
+ Vector4 color = value.Get< Vector4 >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PRIMARY_CURSOR_COLOR %f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
+
+ impl.mDecorator->SetColor( PRIMARY_CURSOR, color );
}
break;
}
{
if( impl.mDecorator )
{
- impl.mDecorator->SetColor( SECONDARY_CURSOR, value.Get< Vector4 >() );
+ Vector4 color = value.Get< Vector4 >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SECONDARY_CURSOR_COLOR %f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
+
+ impl.mDecorator->SetColor( SECONDARY_CURSOR, color );
}
break;
}
{
if( impl.mController )
{
- impl.mController->SetEnableCursorBlink( value.Get< bool >() );
+ bool enable = value.Get< bool >();
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable );
+
+ impl.mController->SetEnableCursorBlink( enable );
}
break;
}
{
if( impl.mDecorator )
{
- impl.mDecorator->SetCursorBlinkInterval( value.Get< float >() );
+ float interval = value.Get< float >();
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval );
+
+ impl.mDecorator->SetCursorBlinkInterval( interval );
}
break;
}
{
if( impl.mDecorator )
{
- impl.mDecorator->SetCursorBlinkDuration( value.Get< float >() );
+ float duration = value.Get< float >();
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), duration );
+
+ impl.mDecorator->SetCursorBlinkDuration( duration );
}
break;
}
case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
{
ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), image.GetUrl().c_str() );
if( impl.mDecorator )
{
case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
{
ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), image.GetUrl().c_str() );
if( impl.mDecorator )
{
case Toolkit::TextField::Property::SCROLL_THRESHOLD:
{
float threshold = value.Get< float >();
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SCROLL_THRESHOLD %f\n", impl.mController.Get(), threshold );
if( impl.mDecorator )
{
case Toolkit::TextField::Property::SCROLL_SPEED:
{
float speed = value.Get< float >();
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SCROLL_SPEED %f\n", impl.mController.Get(), speed );
if( impl.mDecorator )
{
case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
{
ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SELECTION_HANDLE_IMAGE_LEFT %f\n", impl.mController.Get(), image.GetUrl().c_str() );
if( impl.mDecorator )
{
case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
{
ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SELECTION_HANDLE_IMAGE_RIGHT %f\n", impl.mController.Get(), image.GetUrl().c_str() );
if( impl.mDecorator )
{
case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
{
ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SELECTION_HANDLE_PRESSED_IMAGE_LEFT %f\n", impl.mController.Get(), image.GetUrl().c_str() );
if( impl.mDecorator )
{
case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
{
ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SELECTION_HANDLE_PRESSED_IMAGE_RIGHT %f\n", impl.mController.Get(), image.GetUrl().c_str() );
if( impl.mDecorator )
{
case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
{
Vector4 color = value.Get< Vector4 >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SELECTION_HIGHLIGHT_COLOR %f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
if( impl.mDecorator )
{
{
if( impl.mDecorator )
{
- impl.mDecorator->SetBoundingBox( value.Get< Rect<int> >() );
+ Rect<int> box = value.Get< Rect<int> >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p DECORATION_BOUNDING_BOX %d,%d %dx%d\n", impl.mController.Get(), box.x, box.y, box.width, box.height );
+
+ impl.mDecorator->SetBoundingBox( box );
}
break;
}
{
if( impl.mController )
{
- impl.mController->SetMaximumNumberOfCharacters( value.Get< int >() );
+ int max = value.Get< int >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p MAX_LENGTH %d\n", impl.mController.Get(), max );
+
+ impl.mController->SetMaximumNumberOfCharacters( max );
}
break;
}
{
std::string text;
impl.mController->GetText( text );
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p returning text: %s\n", impl.mController.Get(), text.c_str() );
value = text;
}
break;
if( mController->Relayout( size ) ||
!mRenderer )
{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnRelayout %p Displaying new contents\n", mController.Get() );
+
if( mDecorator )
{
mDecorator->Relayout( size );
void TextField::OnKeyInputFocusGained()
{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyInputFocusGained %p\n", mController.Get() );
+
VirtualKeyboard::StatusChangedSignal().Connect( this, &TextField::KeyboardStatusChanged );
ImfManager imfManager = ImfManager::Get();
void TextField::OnKeyInputFocusLost()
{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField:OnKeyInputFocusLost %p\n", mController.Get() );
+
VirtualKeyboard::StatusChangedSignal().Disconnect( this, &TextField::KeyboardStatusChanged );
ImfManager imfManager = ImfManager::Get();
void TextField::OnTap( const TapGesture& gesture )
{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnTap %p\n", mController.Get() );
+
// Show the keyboard if it was hidden.
if (!VirtualKeyboard::IsVisible())
{
bool TextField::OnKeyEvent( const KeyEvent& event )
{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyEvent %p keyCode %d\n", mController.Get(), event.keyCode );
+
if( Dali::DALI_KEY_ESCAPE == event.keyCode ||
"Return" == event.keyPressedName ) // Make a Dali key code for this
{
ImfManager::ImfCallbackData TextField::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnImfEvent %p eventName %d\n", imfEvent.eventName );
+
bool update( false );
std::string text;
void TextField::KeyboardStatusChanged(bool keyboardShown)
{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::KeyboardStatusChanged %p keyboardShown %d\n", keyboardShown );
+
// Just hide the grab handle when keyboard is hidden.
if (!keyboardShown )
{
return mEventData->mDecoratorUpdated;
}
-void Controller::Impl::ReplaceTextWithPlaceholder()
-{
- DALI_ASSERT_DEBUG( mEventData && "No placeholder text available" );
- if( !mEventData )
- {
- return;
- }
-
- // Disable handles when showing place-holder text
- mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, false );
- mEventData->mDecorator->SetHandleActive( LEFT_SELECTION_HANDLE, false );
- mEventData->mDecorator->SetHandleActive( RIGHT_SELECTION_HANDLE, false );
-
- const char* text( NULL );
- size_t size( 0 );
-
- if( EventData::INACTIVE != mEventData->mState &&
- 0u != mEventData->mPlaceholderTextActive.c_str() )
- {
- text = mEventData->mPlaceholderTextActive.c_str();
- size = mEventData->mPlaceholderTextActive.size();
- }
-
- else
- {
- text = mEventData->mPlaceholderTextInactive.c_str();
- size = mEventData->mPlaceholderTextInactive.size();
- }
-
- // Reset buffers.
- mLogicalModel->mText.Clear();
- mLogicalModel->mScriptRuns.Clear();
- mLogicalModel->mFontRuns.Clear();
- mLogicalModel->mLineBreakInfo.Clear();
- mLogicalModel->mWordBreakInfo.Clear();
- mLogicalModel->mBidirectionalParagraphInfo.Clear();
- mLogicalModel->mCharacterDirections.Clear();
- mLogicalModel->mBidirectionalLineInfo.Clear();
- mLogicalModel->mLogicalToVisualMap.Clear();
- mLogicalModel->mVisualToLogicalMap.Clear();
- mVisualModel->mGlyphs.Clear();
- mVisualModel->mGlyphsToCharacters.Clear();
- mVisualModel->mCharactersToGlyph.Clear();
- mVisualModel->mCharactersPerGlyph.Clear();
- mVisualModel->mGlyphsPerCharacter.Clear();
- mVisualModel->mGlyphPositions.Clear();
- mVisualModel->mLines.Clear();
- mVisualModel->ClearCaches();
- mVisualModel->SetTextColor( mEventData->mPlaceholderTextColor );
-
- // Convert text into UTF-32
- Vector<Character>& utf32Characters = mLogicalModel->mText;
- utf32Characters.Resize( size );
-
- // This is a bit horrible but std::string returns a (signed) char*
- const uint8_t* utf8 = reinterpret_cast<const uint8_t*>( text );
-
- // Transform a text array encoded in utf8 into an array encoded in utf32.
- // It returns the actual number of characters.
- Length characterCount = Utf8ToUtf32( utf8, size, utf32Characters.Begin() );
- utf32Characters.Resize( characterCount );
-
- // Reset the cursor position
- mEventData->mPrimaryCursorPosition = 0;
-
- // The natural size needs to be re-calculated.
- mRecalculateNaturalSize = true;
-
- // Apply modifications to the model
- mOperationsPending = ALL_OPERATIONS;
- UpdateModel( ALL_OPERATIONS );
- mOperationsPending = static_cast<OperationsMask>( LAYOUT |
- ALIGN |
- UPDATE_ACTUAL_SIZE |
- REORDER );
-}
-
void Controller::Impl::UpdateModel( OperationsMask operationsRequired )
{
// Calculate the operations to be done.
if( mEventData->mState != newState )
{
- // Show different placeholder when switching between active & inactive
- bool updatePlaceholder( false );
- if( IsShowingPlaceholderText() &&
- ( EventData::INACTIVE == newState ||
- EventData::INACTIVE == mEventData->mState ) )
- {
- updatePlaceholder = true;
- }
-
mEventData->mState = newState;
- if( updatePlaceholder )
- {
- ReplaceTextWithPlaceholder();
- mEventData->mDecoratorUpdated = true;
- }
-
if( EventData::INACTIVE == mEventData->mState )
{
mEventData->mDecorator->SetActiveCursor( ACTIVE_CURSOR_NONE );
{
enum Type
{
- PLACEHOLDER_TEXT, ///< Show the placeholder text if necessary
TEXT_REPLACED, ///< The entire text was replaced
- TEXT_INSERTED, ///< Insert characters at the current cursor position
+ TEXT_INSERTED, ///< Insert characters at the current cursor position
TEXT_DELETED ///< Characters were deleted
};
return ( mEventData && mEventData->mIsShowingPlaceholderText );
}
- void ShowPlaceholderText()
- {
- if( IsPlaceholderAvailable() )
- {
- mEventData->mIsShowingPlaceholderText = true;
-
- // Placeholder-text is dependent on focus state i.e. replace after event processing
- QueueModifyEvent( ModifyEvent::PLACEHOLDER_TEXT );
- }
- }
-
/**
* @brief Called when placeholder-text is hidden
*/
}
}
- /**
- * @brief Called when placeholder-text is shown
- */
- void ReplaceTextWithPlaceholder();
-
void UpdateModel( OperationsMask operationsRequired );
/**
#include <limits>
#include <iostream>
#include <dali/public-api/adaptor-framework/key.h>
+#include <dali/integration-api/debug.h>
// INTERNAL INCLUDES
#include <dali-toolkit/internal/text/bidirectional-support.h>
namespace
{
+#if defined(DEBUG_ENABLED)
+ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
+#endif
+
const float MAX_FLOAT = std::numeric_limits<float>::max();
const std::string EMPTY_STRING("");
return ControllerPtr( new Controller( controlInterface ) );
}
+void Controller::EnableTextInput( DecoratorPtr decorator )
+{
+ if( !mImpl->mEventData )
+ {
+ mImpl->mEventData = new EventData( decorator );
+ }
+}
+
void Controller::SetText( const std::string& text )
{
// Cancel previously queued inserts etc.
Length characterCount = Utf8ToUtf32( utf8, text.size(), utf32Characters.Begin() );
utf32Characters.Resize( characterCount );
+ 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 )
{
}
else
{
- mImpl->ShowPlaceholderText();
+ ShowPlaceholderText();
}
if( mImpl->mEventData )
Utf32ToUtf8( &utf32Characters[0], utf32Characters.Count(), reinterpret_cast<uint8_t*>(&text[0]) );
}
}
+ else
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::GetText %p empty (but showing placeholder)\n", this );
+ }
}
unsigned int Controller::GetLogicalCursorPosition() const
mImpl->mEventData->mPlaceholderTextActive = text;
}
- mImpl->ShowPlaceholderText();
+ ShowPlaceholderText();
}
}
}
mImpl->mFontDefaults->mDefaultFontFamily = defaultFontFamily;
- mImpl->mFontDefaults->mFontId = 0u; // Remove old font ID
- mImpl->mOperationsPending = ALL_OPERATIONS;
- mImpl->mRecalculateNaturalSize = true;
// Clear the font-specific data
- mImpl->mLogicalModel->mFontRuns.Clear();
- mImpl->mVisualModel->mGlyphs.Clear();
- mImpl->mVisualModel->mGlyphsToCharacters.Clear();
- mImpl->mVisualModel->mCharactersToGlyph.Clear();
- mImpl->mVisualModel->mCharactersPerGlyph.Clear();
- mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
- mImpl->mVisualModel->mGlyphPositions.Clear();
- mImpl->mVisualModel->mLines.Clear();
- mImpl->mVisualModel->ClearCaches();
+ ClearFontData();
+
+ mImpl->mOperationsPending = ALL_OPERATIONS;
+ mImpl->mRecalculateNaturalSize = true;
mImpl->RequestRelayout();
}
}
mImpl->mFontDefaults->mDefaultFontStyle = defaultFontStyle;
- mImpl->mFontDefaults->mFontId = 0u; // Remove old font ID
- mImpl->mOperationsPending = ALL_OPERATIONS;
- mImpl->mRecalculateNaturalSize = true;
// Clear the font-specific data
- mImpl->mLogicalModel->mFontRuns.Clear();
- mImpl->mVisualModel->mGlyphs.Clear();
- mImpl->mVisualModel->mGlyphsToCharacters.Clear();
- mImpl->mVisualModel->mCharactersToGlyph.Clear();
- mImpl->mVisualModel->mCharactersPerGlyph.Clear();
- mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
- mImpl->mVisualModel->mGlyphPositions.Clear();
- mImpl->mVisualModel->mLines.Clear();
- mImpl->mVisualModel->ClearCaches();
+ ClearFontData();
+
+ mImpl->mOperationsPending = ALL_OPERATIONS;
+ mImpl->mRecalculateNaturalSize = true;
mImpl->RequestRelayout();
}
}
mImpl->mFontDefaults->mDefaultPointSize = pointSize;
- mImpl->mFontDefaults->mFontId = 0u; // Remove old font ID
- mImpl->mOperationsPending = ALL_OPERATIONS;
- mImpl->mRecalculateNaturalSize = true;
// Clear the font-specific data
- mImpl->mLogicalModel->mFontRuns.Clear();
- mImpl->mVisualModel->mGlyphs.Clear();
- mImpl->mVisualModel->mGlyphsToCharacters.Clear();
- mImpl->mVisualModel->mCharactersToGlyph.Clear();
- mImpl->mVisualModel->mCharactersPerGlyph.Clear();
- mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
- mImpl->mVisualModel->mGlyphPositions.Clear();
- mImpl->mVisualModel->mLines.Clear();
- mImpl->mVisualModel->ClearCaches();
+ ClearFontData();
+
+ mImpl->mOperationsPending = ALL_OPERATIONS;
+ mImpl->mRecalculateNaturalSize = true;
mImpl->RequestRelayout();
}
{
bool removed( false );
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::RemoveText %p mText.Count() %d cursor %d cursorOffset %d numberOfChars %d\n",
+ this, mImpl->mLogicalModel->mText.Count(), mImpl->mEventData->mPrimaryCursorPosition, cursorOffset, numberOfChars );
+
if( ! mImpl->IsShowingPlaceholderText() )
{
// Delete at current cursor position
// Cursor position retreat
oldCursorIndex = cursorIndex;
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::RemoveText %p removed %d\n", this, numberOfChars );
removed = true;
}
}
return mImpl->mVisualModel->GetUnderlineHeight();
}
-void Controller::EnableTextInput( DecoratorPtr decorator )
-{
- if( !mImpl->mEventData )
- {
- mImpl->mEventData = new EventData( decorator );
- }
-}
-
void Controller::SetEnableCursorBlink( bool enable )
{
DALI_ASSERT_DEBUG( NULL != mImpl->mEventData && "TextInput disabled" );
bool Controller::Relayout( const Size& size )
{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::Relayout %p --> size %f,%f\n", this, size.width, size.height );
+
if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
{
bool glyphsRemoved( false );
glyphsRemoved = true;
}
// Not worth to relayout if width or height is equal to zero.
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::Relayout <-- (skipped)\n" );
return glyphsRemoved;
}
if( size != mImpl->mControlSize )
{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "new size (previous size %f,%f)\n", mImpl->mControlSize.width, mImpl->mControlSize.height );
+
// Operations that need to be done if the size changes.
mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending |
LAYOUT |
updated = mImpl->ProcessInputEvents() || updated;
}
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::Relayout <--\n" );
return updated;
}
for( unsigned int i=0; i<events.size(); ++i )
{
- if( ModifyEvent::PLACEHOLDER_TEXT == events[0].type )
- {
- // Use placeholder if text is empty
- if( 0u == mImpl->mLogicalModel->mText.Count() &&
- mImpl->IsShowingPlaceholderText() )
- {
- mImpl->ReplaceTextWithPlaceholder();
- }
- }
- else if( ModifyEvent::TEXT_REPLACED == events[0].type )
+ if( ModifyEvent::TEXT_REPLACED == events[0].type )
{
// A (single) replace event should come first, otherwise we wasted time processing NOOP events
DALI_ASSERT_DEBUG( 0 == i && "Unexpected TEXT_REPLACED event" );
{
// Reset buffers.
mImpl->mLogicalModel->mText.Clear();
- mImpl->mLogicalModel->mScriptRuns.Clear();
- mImpl->mLogicalModel->mFontRuns.Clear();
- mImpl->mLogicalModel->mLineBreakInfo.Clear();
- mImpl->mLogicalModel->mWordBreakInfo.Clear();
- mImpl->mLogicalModel->mBidirectionalParagraphInfo.Clear();
- mImpl->mLogicalModel->mCharacterDirections.Clear();
- mImpl->mLogicalModel->mBidirectionalLineInfo.Clear();
- mImpl->mLogicalModel->mLogicalToVisualMap.Clear();
- mImpl->mLogicalModel->mVisualToLogicalMap.Clear();
- mImpl->mVisualModel->mGlyphs.Clear();
- mImpl->mVisualModel->mGlyphsToCharacters.Clear();
- mImpl->mVisualModel->mCharactersToGlyph.Clear();
- mImpl->mVisualModel->mCharactersPerGlyph.Clear();
- mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
- mImpl->mVisualModel->mGlyphPositions.Clear();
- mImpl->mVisualModel->mLines.Clear();
- mImpl->mVisualModel->ClearCaches();
+ ClearModelData();
// Reset the cursor position
if( mImpl->mEventData )
void Controller::TextReplacedEvent()
{
// Reset buffers.
- mImpl->mLogicalModel->mScriptRuns.Clear();
- mImpl->mLogicalModel->mFontRuns.Clear();
- mImpl->mLogicalModel->mLineBreakInfo.Clear();
- mImpl->mLogicalModel->mWordBreakInfo.Clear();
- mImpl->mLogicalModel->mBidirectionalParagraphInfo.Clear();
- mImpl->mLogicalModel->mCharacterDirections.Clear();
- mImpl->mLogicalModel->mBidirectionalLineInfo.Clear();
- mImpl->mLogicalModel->mLogicalToVisualMap.Clear();
- mImpl->mLogicalModel->mVisualToLogicalMap.Clear();
- mImpl->mVisualModel->mGlyphs.Clear();
- mImpl->mVisualModel->mGlyphsToCharacters.Clear();
- mImpl->mVisualModel->mCharactersToGlyph.Clear();
- mImpl->mVisualModel->mCharactersPerGlyph.Clear();
- mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
- mImpl->mVisualModel->mGlyphPositions.Clear();
- mImpl->mVisualModel->mLines.Clear();
- mImpl->mVisualModel->ClearCaches();
+ ClearModelData();
// The natural size needs to be re-calculated.
mImpl->mRecalculateNaturalSize = true;
DALI_ASSERT_DEBUG( NULL != mImpl->mEventData && "Unexpected TextInsertedEvent" );
// TODO - Optimize this
- mImpl->mLogicalModel->mScriptRuns.Clear();
- mImpl->mLogicalModel->mFontRuns.Clear();
- mImpl->mLogicalModel->mLineBreakInfo.Clear();
- mImpl->mLogicalModel->mWordBreakInfo.Clear();
- mImpl->mLogicalModel->mBidirectionalParagraphInfo.Clear();
- mImpl->mLogicalModel->mCharacterDirections.Clear();
- mImpl->mLogicalModel->mBidirectionalLineInfo.Clear();
- mImpl->mLogicalModel->mLogicalToVisualMap.Clear();
- mImpl->mLogicalModel->mVisualToLogicalMap.Clear();
- mImpl->mVisualModel->mGlyphs.Clear();
- mImpl->mVisualModel->mGlyphsToCharacters.Clear();
- mImpl->mVisualModel->mCharactersToGlyph.Clear();
- mImpl->mVisualModel->mCharactersPerGlyph.Clear();
- mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
- mImpl->mVisualModel->mGlyphPositions.Clear();
- mImpl->mVisualModel->mLines.Clear();
- mImpl->mVisualModel->ClearCaches();
+ ClearModelData();
// The natural size needs to be re-calculated.
mImpl->mRecalculateNaturalSize = true;
DALI_ASSERT_DEBUG( NULL != mImpl->mEventData && "Unexpected TextDeletedEvent" );
// TODO - Optimize this
- mImpl->mLogicalModel->mScriptRuns.Clear();
- mImpl->mLogicalModel->mFontRuns.Clear();
- mImpl->mLogicalModel->mLineBreakInfo.Clear();
- mImpl->mLogicalModel->mWordBreakInfo.Clear();
- mImpl->mLogicalModel->mBidirectionalParagraphInfo.Clear();
- mImpl->mLogicalModel->mCharacterDirections.Clear();
- mImpl->mLogicalModel->mBidirectionalLineInfo.Clear();
- mImpl->mLogicalModel->mLogicalToVisualMap.Clear();
- mImpl->mLogicalModel->mVisualToLogicalMap.Clear();
- mImpl->mVisualModel->mGlyphs.Clear();
- mImpl->mVisualModel->mGlyphsToCharacters.Clear();
- mImpl->mVisualModel->mCharactersToGlyph.Clear();
- mImpl->mVisualModel->mCharactersPerGlyph.Clear();
- mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
- mImpl->mVisualModel->mGlyphPositions.Clear();
- mImpl->mVisualModel->mLines.Clear();
- mImpl->mVisualModel->ClearCaches();
+ ClearModelData();
// The natural size needs to be re-calculated.
mImpl->mRecalculateNaturalSize = true;
{
if( 0u == mImpl->mLogicalModel->mText.Count() )
{
- mImpl->ShowPlaceholderText();
+ ShowPlaceholderText();
}
else
{
bool removedPreEdit( false );
bool maxLengthReached( false );
+ DALI_ASSERT_DEBUG( NULL != mImpl->mEventData && "Unexpected InsertText" )
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::InsertText %p %s (%s) mPreEditFlag %d cursor %d\n",
+ this, text.c_str(), (COMMIT == type ? "COMMIT" : "PRE_EDIT"), mImpl->mEventData->mPreEditFlag, mImpl->mEventData->mPrimaryCursorPosition );
+
if( ! text.empty() )
{
if( mImpl->IsShowingPlaceholderText() )
// Record the start of the pre-edit text
mImpl->mEventData->mPreEditStartPosition = mImpl->mEventData->mPrimaryCursorPosition;
mImpl->mEventData->mPreEditLength = text.size();
+
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "mPreEditStartPosition %d mPreEditLength %d\n", mImpl->mEventData->mPreEditStartPosition, mImpl->mEventData->mPreEditLength );
}
mImpl->mEventData->mPreEditFlag = true;
Length characterCount = Utf8ToUtf32( utf8, text.size(), utf32Characters.Begin() );
utf32Characters.Resize( characterCount );
+ DALI_ASSERT_DEBUG( text.size() >= utf32Characters.Count() && "Invalid UTF32 conversion length" );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "UTF8 size %d, UTF32 size %d\n", text.size(), utf32Characters.Count() );
+
const Length numberOfCharactersInModel = mImpl->mLogicalModel->GetNumberOfCharacters();
// Restrict new text to fit within Maximum characters setting
}
cursorIndex += maxSizeOfNewText;
+
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Inserted %d characters, new size %d new cursor %d\n", maxSizeOfNewText, mImpl->mLogicalModel->mText.Count(), mImpl->mEventData->mPrimaryCursorPosition );
}
if( removedPreEdit || !text.empty() )
if( maxLengthReached )
{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "MaxLengthReached (%d)\n", mImpl->mLogicalModel->mText.Count() );
+
mImpl->mControlInterface.MaxLengthReached();
mImpl->PreEditReset();
delete mImpl;
}
+void Controller::ShowPlaceholderText()
+{
+ if( mImpl->IsPlaceholderAvailable() )
+ {
+ DALI_ASSERT_DEBUG( mImpl->mEventData && "No placeholder text available" );
+
+ mImpl->mEventData->mIsShowingPlaceholderText = true;
+
+ // Disable handles when showing place-holder text
+ mImpl->mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, false );
+ mImpl->mEventData->mDecorator->SetHandleActive( LEFT_SELECTION_HANDLE, false );
+ mImpl->mEventData->mDecorator->SetHandleActive( RIGHT_SELECTION_HANDLE, false );
+
+ const char* text( NULL );
+ size_t size( 0 );
+
+ // TODO - Switch placeholder text styles when changing state
+ if( EventData::INACTIVE != mImpl->mEventData->mState &&
+ 0u != mImpl->mEventData->mPlaceholderTextActive.c_str() )
+ {
+ text = mImpl->mEventData->mPlaceholderTextActive.c_str();
+ size = mImpl->mEventData->mPlaceholderTextActive.size();
+ }
+ else
+ {
+ text = mImpl->mEventData->mPlaceholderTextInactive.c_str();
+ size = mImpl->mEventData->mPlaceholderTextInactive.size();
+ }
+
+ // Reset model for showing placeholder.
+ mImpl->mLogicalModel->mText.Clear();
+ ClearModelData();
+ mImpl->mVisualModel->SetTextColor( mImpl->mEventData->mPlaceholderTextColor );
+
+ // Convert text into UTF-32
+ Vector<Character>& utf32Characters = mImpl->mLogicalModel->mText;
+ utf32Characters.Resize( size );
+
+ // This is a bit horrible but std::string returns a (signed) char*
+ const uint8_t* utf8 = reinterpret_cast<const uint8_t*>( text );
+
+ // Transform a text array encoded in utf8 into an array encoded in utf32.
+ // It returns the actual number of characters.
+ Length characterCount = Utf8ToUtf32( utf8, size, utf32Characters.Begin() );
+ utf32Characters.Resize( characterCount );
+
+ // Reset the cursor position
+ mImpl->mEventData->mPrimaryCursorPosition = 0;
+
+ // The natural size needs to be re-calculated.
+ mImpl->mRecalculateNaturalSize = true;
+
+ // Apply modifications to the model
+ mImpl->mOperationsPending = ALL_OPERATIONS;
+ mImpl->QueueModifyEvent( ModifyEvent::TEXT_REPLACED );
+ }
+}
+
+void Controller::ClearModelData()
+{
+ // n.b. This does not Clear the mText from mLogicalModel
+ mImpl->mLogicalModel->mScriptRuns.Clear();
+ mImpl->mLogicalModel->mFontRuns.Clear();
+ mImpl->mLogicalModel->mLineBreakInfo.Clear();
+ mImpl->mLogicalModel->mWordBreakInfo.Clear();
+ mImpl->mLogicalModel->mBidirectionalParagraphInfo.Clear();
+ mImpl->mLogicalModel->mCharacterDirections.Clear();
+ mImpl->mLogicalModel->mBidirectionalLineInfo.Clear();
+ mImpl->mLogicalModel->mLogicalToVisualMap.Clear();
+ mImpl->mLogicalModel->mVisualToLogicalMap.Clear();
+ mImpl->mVisualModel->mGlyphs.Clear();
+ mImpl->mVisualModel->mGlyphsToCharacters.Clear();
+ mImpl->mVisualModel->mCharactersToGlyph.Clear();
+ mImpl->mVisualModel->mCharactersPerGlyph.Clear();
+ mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
+ mImpl->mVisualModel->mGlyphPositions.Clear();
+ mImpl->mVisualModel->mLines.Clear();
+ mImpl->mVisualModel->ClearCaches();
+}
+
+void Controller::ClearFontData()
+{
+ mImpl->mFontDefaults->mFontId = 0u; // Remove old font ID
+ mImpl->mLogicalModel->mFontRuns.Clear();
+ mImpl->mVisualModel->mGlyphs.Clear();
+ mImpl->mVisualModel->mGlyphsToCharacters.Clear();
+ mImpl->mVisualModel->mCharactersToGlyph.Clear();
+ mImpl->mVisualModel->mCharactersPerGlyph.Clear();
+ mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
+ mImpl->mVisualModel->mGlyphPositions.Clear();
+ mImpl->mVisualModel->mLines.Clear();
+ mImpl->mVisualModel->ClearCaches();
+}
+
Controller::Controller( ControlInterface& controlInterface )
: mImpl( NULL )
{
static ControllerPtr New( ControlInterface& controlInterface );
/**
+ * @brief Called to enable text input.
+ *
+ * @note Selectable or editable controls should call this once after Controller::New().
+ * @param[in] decorator Used to create cursor, selection handle decorations etc.
+ */
+ void EnableTextInput( DecoratorPtr decorator );
+
+ /**
* @brief Replaces any text previously set.
*
* @note This will be converted into UTF-32 when stored in the text model.
float GetUnderlineHeight() const;
/**
- * @brief Called to enable text input.
- *
- * @note Only selectable or editable controls should calls this.
- * @param[in] decorator Used to create cursor, selection handle decorations etc.
- */
- void EnableTextInput( DecoratorPtr decorator );
-
- /**
* @brief Called to enable/disable cursor blink.
*
* @note Only editable controls should calls this.
private:
/**
+ * @brief Helper to clear font-specific data.
+ */
+ void ShowPlaceholderText();
+
+ /**
+ * @brief Helper to clear all the model data except for LogicalModel::mText.
+ */
+ void ClearModelData();
+
+ /**
+ * @brief Helper to clear font-specific data (only).
+ */
+ void ClearFontData();
+
+ /**
* @brief Private constructor.
*/
Controller( ControlInterface& controlInterface );