/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <cstring>
#include <dali/public-api/adaptor-framework/key.h>
#include <dali/devel-api/adaptor-framework/key-devel.h>
-#include <dali/public-api/common/stage.h>
-#include <dali/public-api/images/resource-image.h>
+#include <dali/devel-api/adaptor-framework/window-devel.h>
+#include <dali/devel-api/common/stage.h>
#include <dali/devel-api/object/property-helper-devel.h>
#include <dali/devel-api/actors/actor-devel.h>
#include <dali/public-api/object/type-registry-helper.h>
#include <dali/integration-api/debug.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/text/rendering-backend.h>
#include <dali-toolkit/public-api/text/text-enumerations.h>
#include <dali-toolkit/public-api/visuals/color-visual-properties.h>
+#include <dali-toolkit/devel-api/text/rendering-backend.h>
#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-field-devel.h>
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;
+ const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::DevelText::DEFAULT_RENDERING_BACKEND;
} // unnamed namespace
namespace
// Setup properties, signals and actions using the type-registry.
DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextField, Toolkit::Control, Create );
-DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "renderingBackend", INTEGER, RENDERING_BACKEND )
DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "text", STRING, TEXT )
DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholderText", STRING, PLACEHOLDER_TEXT )
DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholderTextFocused", STRING, PLACEHOLDER_TEXT_FOCUSED )
DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "verticalAlignment", STRING, VERTICAL_ALIGNMENT )
DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "textColor", VECTOR4, TEXT_COLOR )
DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholderTextColor", VECTOR4, PLACEHOLDER_TEXT_COLOR )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "reservedProperty01", STRING, RESERVED_PROPERTY_01 )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "reservedProperty02", STRING, RESERVED_PROPERTY_02 )
DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "primaryCursorColor", VECTOR4, PRIMARY_CURSOR_COLOR )
DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "secondaryCursorColor", VECTOR4, SECONDARY_CURSOR_COLOR )
DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "enableCursorBlink", BOOLEAN, ENABLE_CURSOR_BLINK )
DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "matchSystemLanguageDirection", BOOLEAN, MATCH_SYSTEM_LANGUAGE_DIRECTION )
DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableGrabHandlePopup", BOOLEAN, ENABLE_GRAB_HANDLE_POPUP )
DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "textBackground", VECTOR4, BACKGROUND )
+DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY( Toolkit, TextField, "selectedText", STRING, SELECTED_TEXT )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "renderingBackend", INTEGER, RENDERING_BACKEND )
DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "textChanged", SIGNAL_TEXT_CHANGED )
DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "maxLengthReached", SIGNAL_MAX_LENGTH_REACHED )
DALI_TYPE_REGISTRATION_END()
+const char * const IMAGE_MAP_FILENAME_STRING = "filename";
+
+/// Retrieves a filename from a value that is a Property::Map
+std::string GetImageFileNameFromPropertyValue( const Property::Value& value )
+{
+ std::string filename;
+ const Property::Map* map = value.GetMap();
+ if( map )
+ {
+ const Property::Value* filenameValue = map->Find( IMAGE_MAP_FILENAME_STRING );
+ if( filenameValue )
+ {
+ filenameValue->Get( filename );
+ }
+ }
+ return filename;
+}
+
} // namespace
Toolkit::TextField TextField::New()
switch( index )
{
- case Toolkit::TextField::Property::RENDERING_BACKEND:
+ case Toolkit::DevelTextField::Property::RENDERING_BACKEND:
{
int backend = value.Get< int >();
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p RENDERING_BACKEND %d\n", impl.mController.Get(), backend );
#ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING
- if( Text::RENDERING_VECTOR_BASED == backend )
+ if( DevelText::RENDERING_VECTOR_BASED == backend )
{
backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering
}
if( impl.mController )
{
// When using the vector-based rendering, the size of the GLyphs are different
- TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
+ TextAbstraction::GlyphType glyphType = (DevelText::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
impl.mController->SetGlyphType( glyphType );
}
}
}
case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
{
- const 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() );
+ const std::string imageFileName = value.Get< std::string >();
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str() );
- if( impl.mDecorator )
+ if( impl.mDecorator && imageFileName.size() )
{
- impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED, image );
+ impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED, imageFileName );
impl.RequestTextRelayout();
}
break;
}
case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
{
- const 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() );
+ const std::string imageFileName = value.Get< std::string >();
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str() );
- if( impl.mDecorator )
+ if( impl.mDecorator && imageFileName.size() )
{
- impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED, image );
+ impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED, imageFileName );
impl.RequestTextRelayout();
}
break;
}
case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
{
- const Image image = Scripting::NewImage( value );
+ const std::string filename = GetImageFileNameFromPropertyValue( value );
- if( impl.mDecorator && image )
+ if( impl.mDecorator && filename.size() )
{
- impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, image );
+ impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, filename );
impl.RequestTextRelayout();
}
break;
}
case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
{
- const Image image = Scripting::NewImage( value );
+ const std::string filename = GetImageFileNameFromPropertyValue( value );
- if( impl.mDecorator && image )
+ if( impl.mDecorator && filename.size() )
{
- impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, image );
+ impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, filename );
impl.RequestTextRelayout();
}
break;
}
case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
{
- const Image image = Scripting::NewImage( value );
+ const std::string filename = GetImageFileNameFromPropertyValue( value );
- if( impl.mDecorator && image )
+ if( impl.mDecorator && filename.size() )
{
- impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, image );
+ impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, filename );
impl.RequestTextRelayout();
}
break;
}
case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
{
- const Image image = Scripting::NewImage( value );
+ const std::string filename = GetImageFileNameFromPropertyValue( value );
- if( impl.mDecorator && image )
+ if( impl.mDecorator && filename.size() )
{
- impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, image );
+ impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, filename );
impl.RequestTextRelayout();
}
break;
}
case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
{
- const Image image = Scripting::NewImage( value );
+ const std::string filename = GetImageFileNameFromPropertyValue( value );
- if( impl.mDecorator && image )
+ if( impl.mDecorator && filename.size() )
{
- impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, image );
+ impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, filename );
impl.RequestTextRelayout();
}
break;
}
case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
{
- const Image image = Scripting::NewImage( value );
+ const std::string filename = GetImageFileNameFromPropertyValue( value );
- if( impl.mDecorator && image )
+ if( impl.mDecorator && filename.size() )
{
- impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, image );
+ impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, filename );
impl.RequestTextRelayout();
}
break;
switch( index )
{
- case Toolkit::TextField::Property::RENDERING_BACKEND:
+ case Toolkit::DevelTextField::Property::RENDERING_BACKEND:
{
value = impl.mRenderingBackend;
break;
{
if( impl.mDecorator )
{
- ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED ) );
- if( image )
- {
- value = image.GetUrl();
- }
+ value = impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED );
}
break;
}
{
if( impl.mDecorator )
{
- ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED ) );
- if( image )
- {
- value = image.GetUrl();
- }
+ value = impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED );
}
break;
}
}
break;
}
+ case Toolkit::DevelTextField::Property::SELECTED_TEXT:
+ {
+ if( impl.mController )
+ {
+ value = impl.mController->GetSelectedText( );
+ }
+ break;
+ }
} //switch
}
{
if( mController && mController->IsShowingRealText() )
{
- mController->SelectEvent( 0.f, 0.f, true );
+ mController->SelectEvent( 0.f, 0.f, SelectionType::ALL );
+ SetKeyInputFocus();
+ }
+}
+
+void TextField::SelectNone()
+{
+ if( mController && mController->IsShowingRealText() )
+ {
+ mController->SelectEvent( 0.f, 0.f, SelectionType::NONE );
SetKeyInputFocus();
}
}
mController = Text::Controller::New( this, this );
// When using the vector-based rendering, the size of the GLyphs are different
- TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
+ TextAbstraction::GlyphType glyphType = (DevelText::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
mController->SetGlyphType( glyphType );
mDecorator = Text::Decorator::New( *mController,
EnableGestureDetection( static_cast<Gesture::Type>( Gesture::Tap | Gesture::Pan | Gesture::LongPress ) );
GetTapGestureDetector().SetMaximumTapsRequired( 2 );
- self.TouchSignal().Connect( this, &TextField::OnTouched );
+ self.TouchedSignal().Connect( this, &TextField::OnTouched );
// Set BoundingBox to stage size if not already set.
Rect<int> boundingBox;
// Fill-parent area by default
self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
- self.OnStageSignal().Connect( this, &TextField::OnStageConnect );
+ self.OnSceneSignal().Connect( this, &TextField::OnSceneConnect );
DevelControl::SetInputMethodContext( *this, mInputMethodContext );
Vector2 contentSize( size.x - ( padding.start + padding.end ), size.y - ( padding.top + padding.bottom ) );
// Support Right-To-Left of padding
- Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>( self.GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
+ Dali::LayoutDirection::Type layoutDirection;
+ if( mController->IsMatchSystemLanguageDirection() )
+ {
+ layoutDirection = static_cast<Dali::LayoutDirection::Type>( DevelWindow::Get( self ).GetRootLayer().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
+ }
+ else
+ {
+ layoutDirection = static_cast<Dali::LayoutDirection::Type>( self.GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
+ }
if( Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection )
{
std::swap( padding.start, padding.end );
if( mStencil )
{
- mStencil.SetPosition( padding.start, padding.top );
+ mStencil.SetProperty( Actor::Property::POSITION, Vector2( padding.start, padding.top ));
}
if( mActiveLayer )
{
- mActiveLayer.SetPosition( padding.start, padding.top );
+ mActiveLayer.SetProperty( Actor::Property::POSITION, Vector2( padding.start, padding.top ));
}
const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize, layoutDirection );
renderableActorPositionY = scrollOffset.y + padding.top;
}
- mRenderableActor.SetPosition( renderableActorPositionX, renderableActorPositionY );
+ mRenderableActor.SetProperty( Actor::Property::POSITION, Vector2( renderableActorPositionX, renderableActorPositionY ));
// Make sure the actors are parented correctly with/without clipping
Actor self = mStencil ? mStencil : Self();
self.Add( *it );
it->LowerToBottom();
- if ( it->GetName() == "HighlightActor" )
+ if ( it->GetProperty< std::string >( Dali::Actor::Property::NAME ) == "HighlightActor" )
{
highlightActor = *it;
}
if ( mDecorator && mDecorator->IsHighlightVisible() )
{
self.Add( mBackgroundActor );
- mBackgroundActor.SetPosition( renderableActorPositionX, renderableActorPositionY); // In text field's coords.
+ mBackgroundActor.SetProperty( Actor::Property::POSITION, Vector2( renderableActorPositionX, renderableActorPositionY) ); // In text field's coords.
mBackgroundActor.LowerBelow( highlightActor );
}
else
{
mRenderableActor.Add( mBackgroundActor );
- mBackgroundActor.SetPosition( 0.0f, 0.0f ); // In renderable actor's coords.
+ mBackgroundActor.SetProperty( Actor::Property::POSITION, Vector2( 0.0f, 0.0f ) ); // In renderable actor's coords.
mBackgroundActor.LowerToBottom();
}
}
// Deliver the tap before the focus event to controller; this allows us to detect when focus is gained due to tap-gestures
Extents padding;
padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
- mController->TapEvent( gesture.numberOfTaps, gesture.localPoint.x - padding.start, gesture.localPoint.y - padding.top );
+ const Vector2& localPoint = gesture.GetLocalPoint();
+ mController->TapEvent( gesture.GetNumberOfTaps(), localPoint.x - padding.start, localPoint.y - padding.top );
SetKeyInputFocus();
}
void TextField::OnPan( const PanGesture& gesture )
{
- mController->PanEvent( gesture.state, gesture.displacement );
+ mController->PanEvent( gesture.GetState(), gesture.GetDisplacement() );
}
void TextField::OnLongPress( const LongPressGesture& gesture )
}
Extents padding;
padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
- mController->LongPressEvent( gesture.state, gesture.localPoint.x - padding.start, gesture.localPoint.y - padding.top );
+ const Vector2& localPoint = gesture.GetLocalPoint();
+ mController->LongPressEvent( gesture.GetState(), localPoint.x - padding.start, localPoint.y - padding.top );
SetKeyInputFocus();
}
bool TextField::OnKeyEvent( const KeyEvent& event )
{
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyEvent %p keyCode %d\n", mController.Get(), event.keyCode );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyEvent %p keyCode %d\n", mController.Get(), event.GetKeyCode() );
- if( Dali::DALI_KEY_ESCAPE == event.keyCode && mController->ShouldClearFocusOnEscape() )
+ if( Dali::DALI_KEY_ESCAPE == event.GetKeyCode() && mController->ShouldClearFocusOnEscape() )
{
// Make sure ClearKeyInputFocus when only key is up
- if( event.state == KeyEvent::Up )
+ if( event.GetState() == KeyEvent::UP )
{
ClearKeyInputFocus();
}
return true;
}
- else if( Dali::DevelKey::DALI_KEY_RETURN == event.keyCode )
+ else if( Dali::DevelKey::DALI_KEY_RETURN == event.GetKeyCode() )
{
// Do nothing when enter is comming.
return false;
}
else
{
- actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
- actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ actor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+ actor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
Self().Add( actor );
mActiveLayer = actor;
}
}
}
-void TextField::OnStageConnect( Dali::Actor actor )
+void TextField::OnSceneConnect( Dali::Actor actor )
{
if ( mHasBeenStaged )
{
{
if( mDecorator )
{
- ResourceImage image = ResourceImage::DownCast( mDecorator->GetHandleImage( handleType, handleImageType ) );
-
- if ( image )
- {
- Property::Map map;
- Scripting::CreatePropertyMap( image, map );
- value = map;
- }
+ Property::Map map;
+ map[ IMAGE_MAP_FILENAME_STRING ] = mDecorator->GetHandleImage( handleType, handleImageType );
+ value = map;
}
}
{
// Creates an extra control to be used as stencil buffer.
mStencil = Control::New();
- mStencil.SetAnchorPoint( AnchorPoint::TOP_LEFT );
- mStencil.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ mStencil.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+ mStencil.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
// Creates a background visual. Even if the color is transparent it updates the stencil.
mStencil.SetProperty( Toolkit::Control::Property::BACKGROUND,
}
}
-void TextField::OnStageConnection( int depth )
+void TextField::OnSceneConnection( int depth )
{
// Sets the depth to the visuals inside the text's decorator.
mDecorator->SetTextDepth( depth );
// The depth of the text renderer is set in the RenderText() called from OnRelayout().
- // Call the Control::OnStageConnection() to set the depth of the background.
- Control::OnStageConnection( depth );
+ // Call the Control::OnSceneConnection() to set the depth of the background.
+ Control::OnSceneConnection( depth );
}
-bool TextField::OnTouched( Actor actor, const TouchData& touch )
+bool TextField::OnTouched( Actor actor, const TouchEvent& touch )
{
- return true;
+ return false;
}
void TextField::OnIdleSignal()