#include <dali.h>
#include <dali/public-api/dali-core.h>
+#include <dali/devel-api/actors/custom-actor-devel.h>
+#include <dali/devel-api/object/csharp-type-registry.h>
#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/controls/control-wrapper.h>
#include <dali-toolkit/devel-api/controls/control-wrapper-impl.h>
#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
///////////////////////////////////////////////////////////////////////////////////////////////////
+
namespace Impl
{
struct TestCustomControl : public Toolkit::Internal::ControlWrapper
{
/**
- * Constructor
- */
+ * Constructor
+ */
TestCustomControl() : Toolkit::Internal::ControlWrapper( CustomControlBehaviour( Toolkit::Internal::ControlWrapper::DISABLE_STYLE_CHANGE_SIGNALS |
Toolkit::Internal::ControlWrapper::REQUIRES_KEYBOARD_NAVIGATION_SUPPORT )) ,
mDaliProperty( Property::INVALID_INDEX ),
virtual void OnStageConnection( int depth )
{
mDepth = depth;
+ Control::OnStageConnection(depth);
}
virtual void OnStageDisconnection()
{
+ Control::OnStageDisconnection();
}
virtual void OnChildAdd( Actor& child )
{
+ Control::OnChildAdd(child);
}
virtual void OnChildRemove( Actor& child )
{
+ Control::OnChildRemove(child);
}
virtual void OnPropertySet( Property::Index index, Property::Value propertyValue )
{
+ Control::OnPropertySet(index, propertyValue);
}
virtual void OnSizeSet( const Vector3& targetSize )
{
mSizeSet = targetSize;
+ Control::OnSizeSet( targetSize );
}
virtual void OnSizeAnimation( Animation& animation, const Vector3& targetSize )
{
mTargetSize = targetSize;
+ Control::OnSizeAnimation( animation, targetSize );
}
virtual bool OnTouchEvent( const TouchEvent& event )
{
return 0.0f;
}
+ void TestRegisterVisual( Property::Index index, Toolkit::Visual::Base visual )
+ {
+ ControlWrapper::RegisterVisual( index, visual );
+
+ VisualIndices::iterator iter = std::find( mRegisteredVisualIndices.begin(), mRegisteredVisualIndices.end(), index );
+ if( iter == mRegisteredVisualIndices.end() )
+ {
+ mRegisteredVisualIndices.push_back(index);
+ }
+ }
+
virtual void OnRelayout( const Vector2& size, RelayoutContainer& container )
{
gOnRelayout = true;
+
+ for( VisualIndices::iterator iter = mRegisteredVisualIndices.begin(); iter != mRegisteredVisualIndices.end() ; ++iter )
+ {
+ Visual::Base visual = GetVisual(*iter);
+ Property::Map map; // empty map enforces defaults
+ visual.SetTransformAndSize( map, size );
+ }
}
virtual void OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
Vector3 mTargetSize;
bool mNego;
unsigned int mDepth;
+
+ typedef std::vector<Property::Index> VisualIndices;
+ VisualIndices mRegisteredVisualIndices;
};
+
+
}
-static std::string customControlTypeName = "TestCustomControl";
+static std::string customControlTypeName = "MyTestCustomControl";
static TypeRegistration customControl( customControlTypeName, typeid(Dali::Toolkit::Control), NULL );
+
int UtcDaliControlWrapperConstructor(void)
{
ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
DALI_TEST_CHECK( ControlWrapper::DownCast( controlWrapper ) );
+ Dali::TypeInfo typeInfo = DevelCustomActor::GetTypeInfo( controlWrapper );
+
+ DALI_TEST_EQUALS( typeInfo.GetName(), customControlTypeName, TEST_LOCATION);
+
+
END_TEST;
}
END_TEST;
}
+
+void SetProperty(BaseObject* object, const char* const name, Property::Value* value)
+{
+}
+Property::Value* GetProperty(BaseObject* object, const char* const name )
+{
+ return NULL;
+}
+
+int UtcDaliControlWrapperAnimateVisual(void)
+{
+ tet_infoline("Test that the control wrapper's visuals can be animated by name when registered");
+
+ ToolkitTestApplication application;
+ Test::ObjectDestructionTracker objectDestructionTracker;
+
+ {
+ Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
+ ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
+
+ Property::Index index = Control::CONTROL_PROPERTY_END_INDEX+1;
+ std::string visualName("colorVisual");
+ CSharpTypeRegistry::RegisterProperty( customControlTypeName, visualName, index, Property::VECTOR4, SetProperty, GetProperty );
+
+ objectDestructionTracker.Start( controlWrapper );
+
+ Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
+ Toolkit::Visual::Base visual;
+
+ Property::Map map;
+ map[Visual::Property::TYPE] = Visual::COLOR;
+ map[ColorVisual::Property::MIX_COLOR] = Color::RED;
+
+ visual = visualFactory.CreateVisual( map );
+ DALI_TEST_CHECK( visual );
+
+ // Register to self
+ controlWrapperImpl->TestRegisterVisual( index, visual );
+
+ Stage::GetCurrent().Add( controlWrapper );
+ controlWrapper.SetSize( 100, 100 );
+ application.SendNotification();
+ application.Render(0); // Trigger animation start
+
+ Property::Map transition;
+ transition["target"] = visualName;
+ transition["property"] = "mixColor";
+ transition["targetValue"] = Color::GREEN;
+ Property::Map animator;
+ animator["alphaFunction"] = "LINEAR";
+ animator["duration"] = 1.0f;
+ animator["delay"] = 0.0f;
+ transition["animator"] = animator;
+
+ TransitionData transitionData = TransitionData::New(transition);
+ Animation anim = DevelControl::CreateTransition( *controlWrapperImpl, transitionData );
+ anim.Play();
+
+ application.SendNotification();
+ application.Render(0); // Trigger animation start
+
+ application.Render(1000); // animation end
+ application.Render( 10);
+
+ Property::Map visualMap;
+ visual.CreatePropertyMap( visualMap );
+ Property::Value* value = visualMap.Find(ColorVisual::Property::MIX_COLOR, "mixColor");
+ DALI_TEST_CHECK( value != NULL );
+ if( value )
+ {
+ Vector4 testColor = value->Get<Vector4>();
+ DALI_TEST_EQUALS( testColor, Color::GREEN, 0.001f, TEST_LOCATION );
+ }
+
+ DALI_TEST_EQUALS( objectDestructionTracker.IsDestroyed(), false, TEST_LOCATION ); // Control not destroyed yet
+ DALI_TEST_EQUALS( controlWrapperImpl->GetVisual( index ), visual, TEST_LOCATION );
+
+ Stage::GetCurrent().Remove( controlWrapper );
+ }
+
+ DALI_TEST_EQUALS( objectDestructionTracker.IsDestroyed(), true, TEST_LOCATION ); // Should be destroyed
+
+ END_TEST;
+}
END_TEST;
}
+int utcDaliTextEditorEvent06(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextEditorEvent06");
+
+ // Checks if the highlight actor is created.
+
+ TextEditor editor = TextEditor::New();
+ DALI_TEST_CHECK( editor );
+
+ Stage::GetCurrent().Add( editor );
+
+ editor.SetProperty( TextEditor::Property::TEXT, "Hello\nworld\nHello world" );
+ editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f );
+ editor.SetSize( 100.f, 50.f );
+ editor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ editor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+ // Avoid a crash when core load gl resources.
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Tap on the text editor
+ application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 3.f, 25.0f ) ) );
+ application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 3.f, 25.0f ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Move to seconds line of the text.
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_DOWN, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ float layoutHeight = editor.GetHeightForWidth( 100.f );
+
+
+ // Add another script characters ( glyph height is defferent )
+ application.ProcessEvent( GenerateKey( "d", "ㅁ", KEY_D_CODE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) );
+ application.ProcessEvent( GenerateKey( "d", "ኢ", KEY_D_CODE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) );
+
+ // Delete characters
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) );
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DevelKeyEvent::DeviceClass::NONE ) );
+
+ DALI_TEST_EQUALS( layoutHeight, editor.GetHeightForWidth( 100.f ), TEST_LOCATION );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( "Hello\nworld\nHello world", editor.GetProperty<std::string>( TextEditor::Property::TEXT ), TEST_LOCATION );
+
+
+
+ END_TEST;
+}
+
int utcDaliTextEditorHandles(void)
{
ToolkitTestApplication application;
Integration::ResourcePointer resourcePtr = Integration::ResourcePointer())
{
DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
- dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+ dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
if( resourcePtr )
{
Visual::Base visual = factory.CreateVisual(propertyMap);
DALI_TEST_CHECK( visual );
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
TestVisualRender( application, actor, visual );
Vector3 actualValue(Vector4::ZERO);
Visual::Base visual = factory.CreateVisual( map );
DALI_TEST_CHECK( visual );
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
TestVisualRender( application, actor, visual );
Vector3 actualValue;
Visual::Base visual = factory.CreateVisual(propertyMap);
DALI_TEST_CHECK( visual );
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
- dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+ dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
actor.SetSize(200.f, 200.f);
Stage::GetCurrent().Add( actor );
visual.SetTransformAndSize(DefaultTransform(), Vector2(200.f, 200.f));
Visual::Base visual = factory.CreateVisual( propertyMap );
DALI_TEST_CHECK( visual );
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
- dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+ dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
actor.SetSize(200.f, 200.f);
Stage::GetCurrent().Add( actor );
visual.SetTransformAndSize(DefaultTransform(), Vector2(200.f, 200.f));
DALI_TEST_CHECK( visual );
// A lookup texture is generated and pass to shader as sampler
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
TestVisualRender( application, actor, visual, 1u);
END_TEST;
DALI_TEST_CHECK( visual );
// A lookup texture is generated and pass to shader as sampler
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
TestVisualRender( application, actor, visual, 1u );
Matrix3 alignMatrix( radius, 0.f, 0.f, 0.f, radius, 0.f, center.x, center.y, 1.f );
DALI_TEST_CHECK( visual );
// A lookup texture is generated and pass to shader as sampler
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
TestVisualRender( application, actor, visual, 1u );
Stage::GetCurrent().Remove( actor );
TraceCallStack& textureTrace = gl.GetTextureTrace();
textureTrace.Enable(true);
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
TestVisualRender( application, actor, visual, 1u,
ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
ninePatchResource );
TraceCallStack& textureTrace = gl.GetTextureTrace();
textureTrace.Enable(true);
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
TestVisualRender( application, actor, visual, 1u,
ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
ninePatchResource );
TraceCallStack& textureTrace = gl.GetTextureTrace();
textureTrace.Enable(true);
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
TestVisualRender( application, actor, visual, 1u );
DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
TraceCallStack& textureTrace = gl.GetTextureTrace();
textureTrace.Enable(true);
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
TestVisualRender( application, actor, visual, 1u );
DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
TraceCallStack& textureTrace = gl.GetTextureTrace();
textureTrace.Enable(true);
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
TestVisualRender( application, actor, visual, 1u );
DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
TraceCallStack& textureTrace = gl.GetTextureTrace();
textureTrace.Enable(true);
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
TestVisualRender( application, actor, visual, 1u,
ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
ninePatchResource );
TestGlAbstraction& gl = application.GetGlAbstraction();
TraceCallStack& textureTrace = gl.GetTextureTrace();
textureTrace.Enable(true);
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
TestVisualRender( application, actor, visual, 1u,
ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
ninePatchResource );
TraceCallStack& textureTrace = gl.GetTextureTrace();
textureTrace.Enable(true);
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
TestVisualRender( application, actor, visual, 1u,
ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
ninePatchResource );
TraceCallStack& textureTrace = gl.GetTextureTrace();
textureTrace.Enable(true);
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
TestVisualRender( application, actor, visual, 1u,
ImageDimensions(ninePatchImageWidth, ninePatchImageHeight),
ninePatchResource );
TraceCallStack& textureTrace = gl.GetTextureTrace();
textureTrace.Enable(true);
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
TestVisualRender( application, actor, visual, 1u,
ImageDimensions(),
Integration::ResourcePointer(bitmap) );
TraceCallStack& drawTrace = gl.GetDrawTrace();
drawTrace.Enable(true);
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
TestVisualRender( application, actor, visual, 1u,
ImageDimensions(),
Integration::ResourcePointer(bitmap) );
TraceCallStack& textureTrace = gl.GetTextureTrace();
textureTrace.Enable(true);
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
- dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+ dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
actor.SetSize( 200.f, 200.f );
Stage::GetCurrent().Add( actor );
visual.SetTransformAndSize(DefaultTransform(), Vector2(200.f, 200.f) );
DummyControl actor = DummyControl::New(true);
DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
actor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); // Only rasterizes when it knows control size.
- dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+ dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
Stage::GetCurrent().Add( actor );
application.SendNotification();
DALI_TEST_CHECK( visual );
//Create an actor on stage to house the visual.
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
- dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+ dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
actor.SetSize( 200.f, 200.f );
Stage::GetCurrent().Add( actor );
visual.SetTransformAndSize(DefaultTransform(), Vector2( 200.f, 200.f ) );
DALI_TEST_CHECK( visual );
//Create an actor on stage to house the visual.
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
- dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+ dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
actor.SetSize( 200.f, 200.f );
Stage::GetCurrent().Add( actor );
visual.SetTransformAndSize(DefaultTransform(), Vector2( 200.f, 200.f ) );
DALI_TEST_CHECK( visual );
//Create an actor on stage to house the visual.
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
- dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+ dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
actor.SetSize( 200.f, 200.f );
Stage::GetCurrent().Add( actor );
TraceCallStack& textureTrace = gl.GetTextureTrace();
textureTrace.Enable(true);
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
- dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+ dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
actor.SetSize( 200.0f, 200.0f );
Stage::GetCurrent().Add( actor );
TraceCallStack& texParameterTrace = gl.GetTexParameterTrace();
texParameterTrace.Enable( true );
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New(true);
DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
actor.SetSize( 200.0f, 200.0f );
#include <dali/public-api/object/type-registry.h>
#include <dali/public-api/object/type-registry-helper.h>
#include <dali/devel-api/object/handle-devel.h>
+#include <dali/devel-api/actors/custom-actor-devel.h>
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control-impl.h>
}
}
+Dali::TypeInfo ControlWrapper::GetTypeInfo()
+{
+ return DevelCustomActor::GetTypeInfo(Self());
+}
+
} // namespace Internal
} // namespace Toolkit
*/
void ApplyThemeStyle();
+public:
+ /**
+ * Enable access to non-native type info from native side
+ * @return The type info that was registered on this type
+ */
+ Dali::TypeInfo GetTypeInfo();
+
protected:
/**
#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
#include <dali-toolkit/internal/visuals/visual-string-constants.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/controls/control-wrapper-impl.h>
namespace Dali
{
// ( If the control has been type registered )
if( visual.GetName().empty() )
{
- // Check if the control has been type registered:
- TypeInfo typeInfo = TypeRegistry::Get().GetTypeInfo( typeid( mControlImpl ) );
- if( typeInfo )
+ try
{
- // Check if the property index has been registered:
- Property::IndexContainer indices;
- typeInfo.GetPropertyIndices( indices );
- Property::IndexContainer::Iterator iter = std::find( indices.Begin(), indices.End(), index );
- if( iter != indices.End() )
+ std::string visualName = self.GetPropertyName( index );
+ if( !visualName.empty() )
{
- // If it has, then get it's name and use that for the visual
- std::string visualName = typeInfo.GetPropertyName( index );
+ DALI_LOG_INFO( gLogFilter, Debug::Concise, "Setting visual name for property %d to %s\n",
+ index, visualName.c_str() );
visual.SetName( visualName );
}
}
+ catch( Dali::DaliException e )
+ {
+ DALI_LOG_WARNING( "Attempting to register visual without a registered property, index: %d\n", index );
+ }
}
if( !visualReplaced ) // New registration entry
if( visual )
{
+#if defined(DEBUG_ENABLED)
+ Dali::TypeInfo typeInfo;
+ ControlWrapper* controlWrapperImpl = dynamic_cast<ControlWrapper*>(&mControlImpl);
+ if( controlWrapperImpl )
+ {
+ typeInfo = controlWrapperImpl->GetTypeInfo();
+ }
+
+ DALI_LOG_INFO( gLogFilter, Debug::Concise, "CreateTransition: Found %s visual for %s\n",
+ visual.GetName().c_str(), typeInfo?typeInfo.GetName().c_str():"Unknown" );
+#endif
Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
visualImpl.AnimateProperty( transition, *animator );
}
else
{
+ DALI_LOG_INFO( gLogFilter, Debug::Concise, "CreateTransition: Could not find visual. Trying actors");
// Otherwise, try any actor children of control (Including the control)
Actor child = mControlImpl.Self().FindChildByName( animator->objectName );
if( child )
// Set the primary cursor's height.
cursorInfo.primaryCursorHeight = cursorInfo.isSecondaryCursor ? 0.5f * glyphMetrics.fontHeight : glyphMetrics.fontHeight;
+
+ cursorInfo.glyphOffset = line.ascender - glyphMetrics.ascender;
// Set the primary cursor's position.
cursorInfo.primaryPosition.x = -glyphMetrics.xBearing + primaryPosition.x + glyphAdvance;
- cursorInfo.primaryPosition.y = cursorInfo.lineOffset + line.ascender - glyphMetrics.ascender;
+ cursorInfo.primaryPosition.y = cursorInfo.lineOffset + cursorInfo.glyphOffset;
// Transform the cursor info from line's coords to text's coords.
cursorInfo.primaryPosition.x += line.alignmentOffset;
: primaryPosition(),
secondaryPosition(),
lineOffset( 0.f ),
+ glyphOffset( 0.f ),
lineHeight( 0.f ),
primaryCursorHeight( 0.f ),
secondaryCursorHeight( 0.f ),
Vector2 primaryPosition; ///< The primary cursor's position (in text's coords).
Vector2 secondaryPosition; ///< The secondary cursor's position (in text's coords).
float lineOffset; ///< The vertical offset where the line containing the cursor starts.
+ float glyphOffset; ///< The difference of line ascender and glyph ascender.
float lineHeight; ///< The height of the line where the cursor is placed.
float primaryCursorHeight; ///< The primary cursor's height.
float secondaryCursorHeight; ///< The secondary cursor's height.
: color( Dali::Color::BLACK ),
position(),
cursorHeight( 0.0f ),
- lineHeight( 0.0f )
+ lineHeight( 0.0f ),
+ glyphOffset( 0.0f )
{
}
Vector2 position;
float cursorHeight;
float lineHeight;
+ float glyphOffset;
};
struct HandleImpl
return mImpl->mCursor[cursor].position;
}
+void Decorator::SetGlyphOffset( Cursor cursor, float glyphOffset )
+{
+ Impl::CursorImpl& cursorImpl = mImpl->mCursor[cursor];
+
+ cursorImpl.glyphOffset = glyphOffset;
+}
+
+const float Decorator::GetGlyphOffset( Cursor cursor) const
+{
+ return mImpl->mCursor[cursor].glyphOffset;
+}
+
void Decorator::SetCursorColor( Cursor cursor, const Dali::Vector4& color )
{
mImpl->mCursor[cursor].color = color;
*/
const Vector2& GetPosition( Cursor cursor ) const;
+
+ /**
+ * @brief Sets the glyph offset of a cursor.
+ *
+ * @param[in] cursor The cursor to set.
+ * @param[in] glyphoffset The difference of line ascender and glyph ascender.
+ */
+ void SetGlyphOffset( Cursor cursor, float glyphOffset );
+
+ /**
+ * @brief Retrieves the glyph offset of a cursor.
+ *
+ * @param[in] cursor The cursor to get.
+ *
+ * @return The glyph offset. glyph offset means difference of line ascender and glyph ascender.
+ */
+ const float GetGlyphOffset( Cursor cursor ) const;
+
/**
* @brief Sets the color for a cursor.
*
if( !isValidFont ) // (3)
{
// The given font has not been validated.
+ int validCharacterIndex = fontClient.GetGlyphIndex(cachedDefaultFontId, character );
- if( isValidCachedDefaultFont )
+ if( isValidCachedDefaultFont && validCharacterIndex != 0u )
{
// Use the cached default font for the script if there is one.
fontId = cachedDefaultFontId;
const Vector2 cursorPosition = cursorInfo.primaryPosition + mModel->mScrollPosition;
+ mEventData->mDecorator->SetGlyphOffset( PRIMARY_CURSOR, cursorInfo.glyphOffset );
+
// Sets the cursor position.
mEventData->mDecorator->SetPosition( PRIMARY_CURSOR,
cursorPosition.x,
// Get the current cursor position in decorator coords.
const Vector2& currentCursorPosition = mEventData->mDecorator->GetPosition( PRIMARY_CURSOR );
+ const LineIndex lineIndex = mModel->mVisualModel->GetLineOfCharacter( mEventData->mPrimaryCursorPosition );
+
+
+
// Calculate the offset to match the cursor position before the character was deleted.
mModel->mScrollPosition.x = currentCursorPosition.x - cursorInfo.primaryPosition.x;
- mModel->mScrollPosition.y = currentCursorPosition.y - cursorInfo.lineOffset;
+
+ //If text control has more than two lines and current line index is not last, calculate scrollpositionY
+ if( mModel->mVisualModel->mLines.Count() > 1u && lineIndex != mModel->mVisualModel->mLines.Count() -1u )
+ {
+ const float currentCursorGlyphOffset = mEventData->mDecorator->GetGlyphOffset( PRIMARY_CURSOR );
+ mModel->mScrollPosition.y = currentCursorPosition.y - cursorInfo.lineOffset - currentCursorGlyphOffset;
+ }
+
ClampHorizontalScroll( mModel->mVisualModel->GetLayoutSize() );
ClampVerticalScroll( mModel->mVisualModel->GetLayoutSize() );
}
}
- shader.RegisterProperty( PIXEL_ALIGNED_UNIFORM_NAME, PIXEL_ALIGN_ON ); // Set default to align
+ // Set pixel align off as default.
+ // ToDo: Pixel align causes issues such as rattling image animation.
+ // We should trun it off until issues are resolved
+ shader.RegisterProperty( PIXEL_ALIGNED_UNIFORM_NAME, PIXEL_ALIGN_OFF );
mImpl->mRenderer = Renderer::New( geometry, shader );
if( textureSet )
if( textureInfo.loadState != CANCELLED )
{
+ // textureInfo can be invalidated after this call (as the mTextureInfoContainer may be modified)
PostLoad( textureInfo, pixelData );
}
else
void TextureManager::NotifyObservers( TextureInfo& textureInfo, bool success )
{
- // If there is an observer: Notify the upload is complete
- const unsigned int observerCount = textureInfo.observerList.Count();
- for( unsigned int i = 0; i < observerCount; ++i )
+ TextureId textureId = textureInfo.textureId;
+
+ // If there is an observer: Notify the load is complete, whether successful or not:
+ // And erase it from the list
+ unsigned int observerCount = textureInfo.observerList.Count();
+ TextureInfo* info = &textureInfo;
+
+ while( observerCount )
{
- TextureUploadObserver* observer = textureInfo.observerList[i];
- if( observer )
+ TextureUploadObserver* observer = info->observerList[0];
+
+ // During UploadComplete() a Control ResourceReady() signal is emitted
+ // During that signal the app may add remove /add Textures (e.g. via ImageViews).
+ // At this point no more observers can be added to the observerList, because textureInfo.loadState = UPLOADED
+ // However it is possible for observers to be removed, hence we check the observer list count every iteration
+
+ // Also the reference to the textureInfo struct can become invalidated, because new load requests can modify
+ // the mTextureInfoContainer list (e.g. if more requests are pushed_back it can cause the list to be resized
+ // invalidating the reference to the TextureInfo ).
+ observer->UploadComplete( success, info->textureSet, info->useAtlas, info->atlasRect );
+ observer->DestructionSignal().Disconnect( this, &TextureManager::ObserverDestroyed );
+
+ // regrab the textureInfo from the container as it may have been invalidated, if textures have been removed
+ // or added during the ResourceReady() signal emission (from UploadComplete() )
+ int textureInfoIndex = GetCacheIndexFromId( textureId );
+
+ if( textureInfoIndex == INVALID_CACHE_INDEX)
{
- observer->UploadComplete( success, textureInfo.textureSet, textureInfo.useAtlas, textureInfo.atlasRect );
- observer->DestructionSignal().Disconnect( this, &TextureManager::ObserverDestroyed );
+ // texture has been removed
+ return;
}
+ info = &mTextureInfoContainer[ textureInfoIndex ];
+ observerCount = info->observerList.Count();
+ if ( observerCount > 0 )
+ {
+ // remove the observer that was just triggered if it's still in the list
+ for( TextureInfo::ObserverListType::Iterator j = info->observerList.Begin(); j != info->observerList.End(); ++j )
+ {
+ if( *j == observer )
+ {
+ info->observerList.Erase( j );
+ observerCount--;
+ break;
+ }
+ }
+ }
+
}
- textureInfo.observerList.Clear();
}
void Control::SetBackground( const Property::Map& map )
{
Toolkit::Visual::Base visual = Toolkit::VisualFactory::Get().CreateVisual( map );
+ visual.SetName("background");
if( visual )
{
mImpl->RegisterVisual( Toolkit::Control::Property::BACKGROUND, visual, DepthIndex::BACKGROUND );
const unsigned int TOOLKIT_MAJOR_VERSION = 1;
const unsigned int TOOLKIT_MINOR_VERSION = 2;
-const unsigned int TOOLKIT_MICRO_VERSION = 43;
+const unsigned int TOOLKIT_MICRO_VERSION = 44;
const char * const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali-toolkit
Summary: The OpenGLES Canvas Core Library Toolkit
-Version: 1.2.43
+Version: 1.2.44
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT