# List of test case sources (Only these get parsed for test cases)
SET(TC_SOURCES
utc-Dali-Alignment.cpp
- utc-Dali-BendyEffect.cpp
- utc-Dali-BlindEffect.cpp
utc-Dali-BloomView.cpp
utc-Dali-BubbleEmitter.cpp
utc-Dali-Builder.cpp
- utc-Dali-CarouselEffect.cpp
utc-Dali-CheckBoxButton.cpp
utc-Dali-CubeTransitionEffect.cpp
- utc-Dali-DisplacementEffect.cpp
- utc-Dali-DistanceFieldEffect.cpp
+ utc-Dali-EffectsView.cpp
utc-Dali-GaussianBlurView.cpp
utc-Dali-JsonParser.cpp
utc-Dali-KeyInputFocusManager.cpp
- utc-Dali-OverlayEffect.cpp
- utc-Dali-PageTurnEffect.cpp
utc-Dali-PageTurnView.cpp
utc-Dali-ScrollBar.cpp
utc-Dali-ScrollView.cpp
+ utc-Dali-ShaderEffects.cpp
utc-Dali-ShadowView.cpp
- utc-Dali-ShearEffect.cpp
utc-Dali-Slider.cpp
- utc-Dali-SoftButtonEffect.cpp
- utc-Dali-SpotEffect.cpp
- utc-Dali-SquareDissolveEffect.cpp
utc-Dali-TableView.cpp
utc-Dali-TextField.cpp
utc-Dali-TextLabel.cpp
utc-Dali-TextSelectionPopup.cpp
utc-Dali-ToolBar.cpp
- utc-Dali-WaterEffect.cpp
utc-Dali-Button.cpp
utc-Dali-Control.cpp
utc-Dali-ControlImpl.cpp
utc-Dali-DefaultControls.cpp
- utc-Dali-DissolveEffect.cpp
utc-Dali-AccessibilityFocusManager.cpp
- utc-Dali-IrisEffect.cpp
utc-Dali-ItemLayout.cpp
utc-Dali-ItemView.cpp
utc-Dali-KeyboardFocusManager.cpp
- utc-Dali-MaskEffect.cpp
+ utc-Dali-Magnifier.cpp
utc-Dali-NinePatchMaskEffect.cpp
utc-Dali-Popup.cpp
utc-Dali-PushButton.cpp
utc-Dali-RadioButton.cpp
- utc-Dali-Ripple2DEffect.cpp
- utc-Dali-RippleEffect.cpp
utc-Dali-ScrollViewEffect.cpp
utc-Dali-StyleManager.cpp
utc-Dali-SuperBlurView.cpp
- utc-Dali-SwirlEffect.cpp
)
# Append list of test harness files (Won't get parsed for test cases)
#include <dali-toolkit-test-suite-utils.h>
#include <dali.h>
+#include <dali/devel-api/rendering/renderer.h>
#include <dali-toolkit/dali-toolkit.h>
-#include <dali/devel-api/actors/mesh-actor.h>
-#include <dali/devel-api/modeling/material.h>
#include <dali-toolkit/devel-api/controls/bubble-effect/bubble-emitter.h>
using namespace Dali;
END_TEST;
}
+int UtcDaliBubbleEmitterDownCast01(void)
+{
+ ToolkitTestApplication application;
+
+ tet_infoline(" UtcDaliBubbleEmitterDownCast01 ");
+
+ Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+ BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 200, Vector2( 5.f, 10.f ));
+
+ BaseHandle handle(emitter);
+ BubbleEmitter emitter2 = BubbleEmitter::DownCast(handle);
+ DALI_TEST_EQUALS( (bool)emitter2, true, TEST_LOCATION );
+ END_TEST;
+}
+
+int UtcDaliBubbleEmitterDownCast02(void)
+{
+ ToolkitTestApplication application;
+
+ tet_infoline(" UtcDaliBubbleEmitterDownCast02 ");
+
+ Handle handle = Handle::New(); // Create a custom object
+ BubbleEmitter emitter = BubbleEmitter::DownCast(handle);
+ DALI_TEST_EQUALS( (bool)emitter, false, TEST_LOCATION );
+ END_TEST;
+}
+
int UtcDaliBubbleEmitterGetRootActor(void)
{
ToolkitTestApplication application;
tet_infoline( " UtcDaliBubbleEmitterGetRootActor " );
Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
- BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 200, Vector2( 5.f, 10.f ));
+ BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 270, Vector2( 5.f, 10.f ));
Actor root = emitter.GetRootActor();
DALI_TEST_CHECK( root );
END_TEST;
}
-int UtcDaliBubbleEmitterSetShapeImage(void)
+//TODO: test case for BubbleEmitter::SetShapeImage(Image)
+// To test that the bubble-shape image is successfully switched in the sampler
+/*int UtcDaliBubbleEmitterSetShapeImage(void)
{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliBubbleEmitterSetShapeImage " );
-
- Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
- BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
-
- Actor root = emitter.GetRootActor();
- MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
- Material material = bubbleMesh.GetMaterial();
-
- DALI_TEST_CHECK( material.GetDiffuseTexture() == shapeImage1 );
-
- Image shapeImage2 = CreateSolidColorImage( application, Color::RED, 8, 8 );
- emitter.SetShapeImage( shapeImage2 );
-
- DALI_TEST_CHECK( material.GetDiffuseTexture() == shapeImage2 );
- END_TEST;
-}
+}*/
int UtcDaliBubbleEmitterSetBubbleScale(void)
{
ToolkitTestApplication application;
tet_infoline( " UtcDaliBubbleEmitterSetBubbleScale " );
- Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
- BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
-
+ Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+ BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 150, Vector2( 5.f, 10.f ));
++ DALI_TEST_CHECK(emitter);
Actor root = emitter.GetRootActor();
- MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
- ShaderEffect effect = bubbleMesh.GetShaderEffect();
- DALI_TEST_CHECK( effect );
+ Stage::GetCurrent().Add( root );
++ root.SetPosition( Vector3::ZERO );
++ root.SetParentOrigin( ParentOrigin::CENTER );
++ root.SetAnchorPoint( AnchorPoint::CENTER );
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+
+ Wait(application);
- Property::Index scalePropertyIndex = effect.GetPropertyIndex( "uDynamicScale" );
float scaleValue;
- (effect.GetProperty(scalePropertyIndex)).Get( scaleValue );
- DALI_TEST_EQUALS(scaleValue, 1.f, TEST_LOCATION );
+ DALI_TEST_CHECK( gl.GetUniformValue<float>( "uDynamicScale", scaleValue ) );
+ DALI_TEST_EQUALS( scaleValue, 1.f, TEST_LOCATION );
emitter.SetBubbleScale( 2.f );
- application.SendNotification();
- application.Render();
- (effect.GetProperty(scalePropertyIndex)).Get( scaleValue );
- DALI_TEST_EQUALS(scaleValue, 2.f, TEST_LOCATION );
+ Wait(application);
+ DALI_TEST_CHECK( gl.GetUniformValue<float>( "uDynamicScale", scaleValue ) );
+ DALI_TEST_EQUALS( scaleValue, 2.f, TEST_LOCATION );
emitter.SetBubbleScale( 0.5f );
- application.SendNotification();
- application.Render();
- (effect.GetProperty(scalePropertyIndex)).Get( scaleValue );
- DALI_TEST_EQUALS(scaleValue, 0.5f, TEST_LOCATION );
+ Wait(application);
+ DALI_TEST_CHECK( gl.GetUniformValue<float>( "uDynamicScale", scaleValue ) );
+ DALI_TEST_EQUALS( scaleValue, 0.5f, TEST_LOCATION );
++
END_TEST;
}
ToolkitTestApplication application;
tet_infoline( " UtcDaliBubbleEmitterSetBubbleDensity " );
- Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
- BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
+ Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+ BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 200, Vector2( 5.f, 10.f ));
try
{
ToolkitTestApplication application;
tet_infoline( " UtcDaliBubbleEmitterSetBubbleDensity " );
- Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
- BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
+ Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+ BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 200, Vector2( 5.f, 10.f ));
try
{
ToolkitTestApplication application;
tet_infoline( " UtcDaliBubbleEmitterSetBlendMode " );
- Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
- BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
-
+ Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+ BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 150, Vector2( 5.f, 10.f ));
++ DALI_TEST_CHECK(emitter);
Actor root = emitter.GetRootActor();
- MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
-
- BlendingFactor::Type srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha;
+ Stage::GetCurrent().Add( root );
++ root.SetPosition( Vector3::ZERO );
++ root.SetParentOrigin( ParentOrigin::CENTER );
++ root.SetAnchorPoint( AnchorPoint::CENTER );
+
+ TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+ Wait(application);
+ DALI_TEST_EQUALS( (GLenum)GL_SRC_ALPHA, glAbstraction.GetLastBlendFuncSrcRgb(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ONE_MINUS_SRC_ALPHA, glAbstraction.GetLastBlendFuncDstRgb(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ONE, glAbstraction.GetLastBlendFuncSrcAlpha(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ONE_MINUS_SRC_ALPHA, glAbstraction.GetLastBlendFuncDstAlpha(), TEST_LOCATION );
emitter.SetBlendMode( true );
- bubbleMesh.GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
- DALI_TEST_CHECK( srcFactorRgb == BlendingFactor::SRC_ALPHA );
- DALI_TEST_CHECK( destFactorRgb == BlendingFactor::ONE );
- DALI_TEST_CHECK( srcFactorAlpha == BlendingFactor::ZERO );
- DALI_TEST_CHECK( destFactorAlpha == BlendingFactor::ONE );
+ Wait(application);
+ DALI_TEST_EQUALS( (GLenum)GL_SRC_ALPHA, glAbstraction.GetLastBlendFuncSrcRgb(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ONE, glAbstraction.GetLastBlendFuncDstRgb(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ZERO, glAbstraction.GetLastBlendFuncSrcAlpha(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ONE, glAbstraction.GetLastBlendFuncDstAlpha(), TEST_LOCATION );
emitter.SetBlendMode( false );
- bubbleMesh.GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
- DALI_TEST_CHECK( srcFactorRgb == BlendingFactor::SRC_ALPHA );
- DALI_TEST_CHECK( destFactorRgb == BlendingFactor::ONE_MINUS_SRC_ALPHA );
- DALI_TEST_CHECK( srcFactorAlpha == BlendingFactor::ONE );
- DALI_TEST_CHECK( destFactorAlpha == BlendingFactor::ONE_MINUS_SRC_ALPHA );
+ Wait(application);
+ DALI_TEST_EQUALS( (GLenum)GL_SRC_ALPHA, glAbstraction.GetLastBlendFuncSrcRgb(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ONE_MINUS_SRC_ALPHA, glAbstraction.GetLastBlendFuncDstRgb(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ONE, glAbstraction.GetLastBlendFuncSrcAlpha(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ONE_MINUS_SRC_ALPHA, glAbstraction.GetLastBlendFuncDstAlpha(), TEST_LOCATION );
+
END_TEST;
}
BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
Actor root = emitter.GetRootActor();
- MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
- ShaderEffect effect = bubbleMesh.GetShaderEffect();
- DALI_TEST_CHECK( effect );
+ Actor bubbleMesh = root.GetChildAt( 0 );
+ Stage::GetCurrent().Add( root );
+ DALI_TEST_CHECK( bubbleMesh );
- Property::Index propertyIndex0 = effect.GetPropertyIndex( "uPercentage[0]" );
- Property::Index propertyIndex1 = effect.GetPropertyIndex( "uPercentage[1]" );
+ Property::Index propertyIndex0 = bubbleMesh.GetPropertyIndex( "uPercentage[0]" );
+ Property::Index propertyIndex1 = bubbleMesh.GetPropertyIndex( "uPercentage[1]" );
float value0, value1;
Animation animation = Animation::New( 0.5f );
emitter.EmitBubble( animation, Vector2(40.f,40.f), Vector2(-5.f,-5.f), Vector2(30.f,30.f) );
emitter.EmitBubble( animation, Vector2(10.f,10.f), Vector2(5.f,5.f), Vector2(30.f,30.f) );
- (effect.GetProperty(propertyIndex0)).Get( value0 );
- (effect.GetProperty(propertyIndex1)).Get( value1 );
+ (bubbleMesh.GetProperty(propertyIndex0)).Get( value0 );
+ (bubbleMesh.GetProperty(propertyIndex1)).Get( value1 );
DALI_TEST_EQUALS(value0, 0.f, TEST_LOCATION );
DALI_TEST_EQUALS(value1, 0.f, TEST_LOCATION );
animation.Play();
Wait(application, 300);
- (effect.GetProperty(propertyIndex0)).Get( value0 );
- (effect.GetProperty(propertyIndex1)).Get( value1 );
+ propertyIndex0 = bubbleMesh.GetPropertyIndex( "uPercentage[0]" );
+ propertyIndex1 = bubbleMesh.GetPropertyIndex( "uPercentage[1]" );
+ (bubbleMesh.GetProperty(propertyIndex0)).Get( value0 );
+ (bubbleMesh.GetProperty(propertyIndex1)).Get( value1 );
DALI_TEST_CHECK( value0 >= 0.6f );
DALI_TEST_CHECK( value1 >= 0.6f );
- Wait(application, 600);
- (effect.GetProperty(propertyIndex0)).Get( value0 );
- (effect.GetProperty(propertyIndex1)).Get( value1 );
+ Wait(application,500);
+ (bubbleMesh.GetProperty(propertyIndex0)).Get( value0 );
+ (bubbleMesh.GetProperty(propertyIndex1)).Get( value1 );
DALI_TEST_EQUALS(value0, 1.f, TEST_LOCATION );
DALI_TEST_EQUALS(value1, 1.f, TEST_LOCATION );
END_TEST;
}
-int UtcDaliBubbleEmitterStartExplosion(void)
+int UtcDaliBubbleEmitterRestore(void)
{
ToolkitTestApplication application;
- tet_infoline( " UtcDaliBubbleEmitterStartExplosion " );
+ tet_infoline( " UtcDaliBubbleEmitterRestore " );
- Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
- BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
+ Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+ BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 90, Vector2( 5.f, 10.f ));
Actor root = emitter.GetRootActor();
- MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
- ShaderEffect effect = bubbleMesh.GetShaderEffect();
- DALI_TEST_CHECK( effect );
-
- Property::Index propertyIndex = effect.GetPropertyIndex( "uMagnification" );
- float value;
- (effect.GetProperty(propertyIndex)).Get( value );
- DALI_TEST_EQUALS(value, 1.f, TEST_LOCATION );
-
- emitter.StartExplosion( 0.4, 4.f );
+ Stage::GetCurrent().Add( root );
++ root.SetPosition( Vector3::ZERO );
++ root.SetParentOrigin( ParentOrigin::CENTER );
++ root.SetAnchorPoint( AnchorPoint::CENTER );
- Wait(application, 200); // 0.2s
- (effect.GetProperty(propertyIndex)).Get( value );
- DALI_TEST_CHECK( value >= 2.f );
+ Actor bubbleMesh = root.GetChildAt( 0 );
+ Renderer renderer = bubbleMesh.GetRendererAt( 0 );
+ DALI_TEST_CHECK( renderer );
- Wait(application, 100); // 0.3s
- (effect.GetProperty(propertyIndex)).Get( value );
- DALI_TEST_CHECK( value >= 3.f );
+ TestGlAbstraction& gl = application.GetGlAbstraction();
- Wait(application, 100); // 0.4s
- (effect.GetProperty(propertyIndex)).Get( value );
- DALI_TEST_EQUALS(value, 1.f, TEST_LOCATION );
- END_TEST;
-}
+ float percentageValue;
+ Vector4 startEndPosValue;
-int UtcDaliBubbleEmitterRestore(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliBubbleEmitterRestore " );
+ Animation animation = Animation::New( 0.5f );
+ emitter.EmitBubble( animation, Vector2(40.f,40.f), Vector2(-5.f,-5.f), Vector2(30.f,30.f) );
- Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
- BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
- Actor root = emitter.GetRootActor();
- MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
- ShaderEffect effect = bubbleMesh.GetShaderEffect();
- DALI_TEST_CHECK( effect );
+ Wait(application);
- Property::Index percentagePropertyIndex = effect.GetPropertyIndex( "uPercentage[0]" );
- float percentage;
+ DALI_TEST_CHECK( gl.GetUniformValue<float>( "uPercentage[0]", percentageValue ) );
+ DALI_TEST_EQUALS( percentageValue, 0.f, TEST_LOCATION );
- Animation animation = Animation::New( 0.5f );
- emitter.EmitBubble( animation, Vector2(40.f,40.f), Vector2(-5.f,-5.f), Vector2(30.f,30.f) );
- (effect.GetProperty(percentagePropertyIndex)).Get( percentage );
- DALI_TEST_EQUALS(percentage, 0.f, TEST_LOCATION );
+ DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uStartEndPosition[0]", startEndPosValue ) );
+ DALI_TEST_EQUALS( startEndPosValue.x, 40.f, TEST_LOCATION );
+ DALI_TEST_EQUALS( startEndPosValue.y, 40.f, TEST_LOCATION );
animation.Play();
Wait(application, 200);
animation.Clear();
- (effect.GetProperty(percentagePropertyIndex)).Get( percentage );
- DALI_TEST_CHECK( percentage < 0.5f && percentage >= 0.4);
+ DALI_TEST_CHECK( gl.GetUniformValue<float>( "uPercentage[0]", percentageValue ) );
+ DALI_TEST_CHECK( percentageValue < 0.5f && percentageValue >= 0.4);
+
+ DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uStartEndPosition[0]", startEndPosValue ) );
+ DALI_TEST_EQUALS( startEndPosValue.x, 40.f, TEST_LOCATION );
+ DALI_TEST_EQUALS( startEndPosValue.y, 40.f, TEST_LOCATION );
emitter.Restore();
application.SendNotification();
application.Render();
- (effect.GetProperty(percentagePropertyIndex)).Get( percentage );
- DALI_TEST_EQUALS(percentage, 1.f, TEST_LOCATION );
+ DALI_TEST_CHECK( gl.GetUniformValue<float>( "uPercentage[0]", percentageValue ) );
+ DALI_TEST_EQUALS( percentageValue, 0.f, TEST_LOCATION );
+
+ DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uStartEndPosition[0]", startEndPosValue ) );
+ DALI_TEST_EQUALS( startEndPosValue, Vector4::ZERO, TEST_LOCATION );
++
END_TEST;
}
#include <iostream>
#include <stdlib.h>
#include <dali/integration-api/events/key-event-integ.h>
-#include <dali/devel-api/actors/mesh-actor.h>
+ #include <dali/integration-api/events/tap-gesture-event.h>
#include <dali-toolkit-test-suite-utils.h>
#include <dali-toolkit/dali-toolkit.h>
#include <dali-toolkit/devel-api/styling/style-manager.h>
namespace
{
- const char* const PROPERTY_NAME_RENDERING_BACKEND = "rendering-backend";
- const char* const PROPERTY_NAME_PLACEHOLDER_TEXT = "placeholder-text";
- const char* const PROPERTY_NAME_TEXT = "text";
- const char* const PROPERTY_NAME_FONT_FAMILY = "font-family";
- const char* const PROPERTY_NAME_FONT_STYLE = "font-style";
- const char* const PROPERTY_NAME_POINT_SIZE = "point-size";
- const char* const PROPERTY_NAME_EXCEED_POLICY = "exceed-policy";
- const char* const PROPERTY_NAME_PRIMARY_CURSOR_COLOR = "primary-cursor-color";
- const char* const PROPERTY_NAME_SECONDARY_CURSOR_COLOR = "secondary-cursor-color";
- const char* const PROPERTY_NAME_ENABLE_CURSOR_BLINK = "enable-cursor-blink";
- const char* const PROPERTY_NAME_CURSOR_BLINK_INTERVAL = "cursor-blink-interval";
- const char* const PROPERTY_NAME_CURSOR_BLINK_DURATION = "cursor-blink-duration";
- const char* const PROPERTY_NAME_GRAB_HANDLE_IMAGE = "grab-handle-image";
- const char* const PROPERTY_NAME_DECORATION_BOUNDING_BOX = "decoration-bounding-box";
- const char* const PROPERTY_NAME_HORIZONTAL_ALIGNMENT = "horizontal-alignment";
- const char* const PROPERTY_NAME_VERTICAL_ALIGNMENT = "vertical-alignment";
+ const char* const PROPERTY_NAME_RENDERING_BACKEND = "rendering-backend";
+ const char* const PROPERTY_NAME_TEXT = "text";
+ const char* const PROPERTY_NAME_PLACEHOLDER_TEXT = "placeholder-text";
+ const char* const PROPERTY_NAME_PLACEHOLDER_TEXT_FOCUSED = "placeholder-text-focused";
+ const char* const PROPERTY_NAME_FONT_FAMILY = "font-family";
+ const char* const PROPERTY_NAME_FONT_STYLE = "font-style";
+ const char* const PROPERTY_NAME_POINT_SIZE = "point-size";
+ const char* const PROPERTY_NAME_MAX_LENGTH = "max-length";
+ const char* const PROPERTY_NAME_EXCEED_POLICY = "exceed-policy";
+ const char* const PROPERTY_NAME_HORIZONTAL_ALIGNMENT = "horizontal-alignment";
+ const char* const PROPERTY_NAME_VERTICAL_ALIGNMENT = "vertical-alignment";
+ const char* const PROPERTY_NAME_TEXT_COLOR = "text-color";
+ const char* const PROPERTY_NAME_PLACEHOLDER_TEXT_COLOR = "placeholder-text-color";
+ const char* const PROPERTY_NAME_SHADOW_OFFSET = "shadow-offset";
+ const char* const PROPERTY_NAME_SHADOW_COLOR = "shadow-color";
+ const char* const PROPERTY_NAME_PRIMARY_CURSOR_COLOR = "primary-cursor-color";
+ const char* const PROPERTY_NAME_SECONDARY_CURSOR_COLOR = "secondary-cursor-color";
+ const char* const PROPERTY_NAME_ENABLE_CURSOR_BLINK = "enable-cursor-blink";
+ const char* const PROPERTY_NAME_CURSOR_BLINK_INTERVAL = "cursor-blink-interval";
+ const char* const PROPERTY_NAME_CURSOR_BLINK_DURATION = "cursor-blink-duration";
+ const char* const PROPERTY_NAME_GRAB_HANDLE_IMAGE = "grab-handle-image";
+ const char* const PROPERTY_NAME_GRAB_HANDLE_PRESSED_IMAGE = "grab-handle-pressed-image";
+ const char* const PROPERTY_NAME_SCROLL_THRESHOLD = "scroll-threshold";
+ const char* const PROPERTY_NAME_SCROLL_SPEED = "scroll-speed";
+ const char* const PROPERTY_NAME_SELECTION_HANDLE_IMAGE_LEFT = "selection-handle-image-left";
+ const char* const PROPERTY_NAME_SELECTION_HANDLE_IMAGE_RIGHT = "selection-handle-image-right";
+ const char* const PROPERTY_NAME_SELECTION_HANDLE_PRESSED_IMAGE_LEFT = "selection-handle-pressed-image-left";
+ const char* const PROPERTY_NAME_SELECTION_HANDLE_PRESSED_IMAGE_RIGHT = "selection-handle-pressed-image-right";
+ const char* const PROPERTY_NAME_SELECTION_HIGHLIGHT_COLOR = "selection-highlight-color";
+ const char* const PROPERTY_NAME_DECORATION_BOUNDING_BOX = "decoration-bounding-box";
+ const char* const PROPERTY_NAME_INPUT_METHOD_SETTINGS = "input-method-settings";
+
+ const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
+
+ const Vector4 PLACEHOLDER_TEXT_COLOR( 0.8f, 0.8f, 0.8f, 0.8f );
+ const Dali::Vector4 LIGHT_BLUE( (0xb2 / 255.0f), (0xeb / 255.0f), (0xf2 / 255.0f), 0.5f ); // The text highlight color.
+
+ const unsigned int CURSOR_BLINK_INTERVAL = 500u; // Cursor blink interval
+ const float TO_MILLISECONDS = 1000.f;
+ const float TO_SECONDS = 1.f / TO_MILLISECONDS;
+
+ const float SCROLL_THRESHOLD = 10.f;
+ const float SCROLL_SPEED = 300.f;
static bool gTextChangedCallBackCalled;
static bool gMaxCharactersCallBackCalled;
gMaxCharactersCallBackCalled = true;
}
+ // Generate a TapGestureEvent to send to Core.
+ Integration::TapGestureEvent GenerateTap(
+ Gesture::State state,
+ unsigned int numberOfTaps,
+ unsigned int numberOfTouches,
+ Vector2 point)
+ {
+ Integration::TapGestureEvent tap( state );
+
+ tap.numberOfTaps = numberOfTaps;
+ tap.numberOfTouches = numberOfTouches;
+ tap.point = point;
+
+ return tap;
+ }
+
+ // Generate a KeyEvent to send to Core.
+ Integration::KeyEvent GenerateKey( const std::string& keyName,
+ const std::string& keyString,
+ int keyCode,
+ int keyModifier,
+ unsigned long timeStamp,
+ const Integration::KeyEvent::State& keyState )
+ {
+ return Integration::KeyEvent( keyName,
+ keyString,
+ keyCode,
+ keyModifier,
+ timeStamp,
+ keyState );
+ }
+
} // namespace
int UtcDaliToolkitTextFieldConstructorP(void)
END_TEST;
}
- int UtcDaliTextFieldGetPropertyN(void)
- {
- ToolkitTestApplication application;
- tet_infoline(" UtcDaliToolkitTextFieldGetPropertyN");
- TextField field = TextField::New();
- DALI_TEST_CHECK( field );
-
- bool assert = false;
- try
- {
- Property::Value value = field.GetProperty<bool>( 0 );
- }
- catch ( ... )
- {
- assert = true;
- }
- if ( assert )
- {
- tet_result(TET_PASS);
- }
- else
- {
- tet_result(TET_FAIL);
- }
- END_TEST;
- }
-
// Positive test case for a method
int UtcDaliTextFieldGetPropertyP(void)
{
// Check Property Indices are correct
DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_RENDERING_BACKEND ) == TextField::Property::RENDERING_BACKEND );
- DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_PLACEHOLDER_TEXT ) == TextField::Property::PLACEHOLDER_TEXT );
DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_TEXT ) == TextField::Property::TEXT );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_PLACEHOLDER_TEXT ) == TextField::Property::PLACEHOLDER_TEXT );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_PLACEHOLDER_TEXT_FOCUSED ) == TextField::Property::PLACEHOLDER_TEXT_FOCUSED );
DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_FONT_FAMILY ) == TextField::Property::FONT_FAMILY );
DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_FONT_STYLE ) == TextField::Property::FONT_STYLE );
DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_POINT_SIZE ) == TextField::Property::POINT_SIZE );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_MAX_LENGTH ) == TextField::Property::MAX_LENGTH );
DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_EXCEED_POLICY ) == TextField::Property::EXCEED_POLICY );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_HORIZONTAL_ALIGNMENT ) == TextField::Property::HORIZONTAL_ALIGNMENT );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_VERTICAL_ALIGNMENT ) == TextField::Property::VERTICAL_ALIGNMENT );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_TEXT_COLOR ) == TextField::Property::TEXT_COLOR );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_PLACEHOLDER_TEXT_COLOR ) == TextField::Property::PLACEHOLDER_TEXT_COLOR );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SHADOW_OFFSET ) == TextField::Property::SHADOW_OFFSET );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SHADOW_COLOR ) == TextField::Property::SHADOW_COLOR );
DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_PRIMARY_CURSOR_COLOR ) == TextField::Property::PRIMARY_CURSOR_COLOR );
DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SECONDARY_CURSOR_COLOR ) == TextField::Property::SECONDARY_CURSOR_COLOR );
DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_ENABLE_CURSOR_BLINK ) == TextField::Property::ENABLE_CURSOR_BLINK );
DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_CURSOR_BLINK_INTERVAL ) == TextField::Property::CURSOR_BLINK_INTERVAL );
DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_CURSOR_BLINK_DURATION ) == TextField::Property::CURSOR_BLINK_DURATION );
DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_GRAB_HANDLE_IMAGE ) == TextField::Property::GRAB_HANDLE_IMAGE );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_GRAB_HANDLE_PRESSED_IMAGE ) == TextField::Property::GRAB_HANDLE_PRESSED_IMAGE );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SCROLL_THRESHOLD ) == TextField::Property::SCROLL_THRESHOLD );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SCROLL_SPEED ) == TextField::Property::SCROLL_SPEED );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_IMAGE_LEFT ) == TextField::Property::SELECTION_HANDLE_IMAGE_LEFT );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_IMAGE_RIGHT ) == TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_PRESSED_IMAGE_LEFT ) == TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_PRESSED_IMAGE_RIGHT ) == TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_SELECTION_HIGHLIGHT_COLOR ) == TextField::Property::SELECTION_HIGHLIGHT_COLOR );
DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_DECORATION_BOUNDING_BOX ) == TextField::Property::DECORATION_BOUNDING_BOX );
- DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_HORIZONTAL_ALIGNMENT ) == TextField::Property::HORIZONTAL_ALIGNMENT );
- DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_VERTICAL_ALIGNMENT ) == TextField::Property::VERTICAL_ALIGNMENT );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_METHOD_SETTINGS ) == TextField::Property::INPUT_METHOD_SETTINGS );
END_TEST;
}
TextField field = TextField::New();
DALI_TEST_CHECK( field );
- // Check exceed policy
- field.SetProperty( TextField::Property::EXCEED_POLICY, TextField::EXCEED_POLICY_CLIP );
+ // Check defaults.
+ DALI_TEST_EQUALS( field.GetProperty<unsigned int>( TextField::Property::RENDERING_BACKEND ), DEFAULT_RENDERING_BACKEND, TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::TEXT ), std::string(""), TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::PLACEHOLDER_TEXT ), std::string(""), TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::PLACEHOLDER_TEXT_FOCUSED ), std::string(""), TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::FONT_FAMILY ), std::string(""), TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::FONT_STYLE ), std::string(""), TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::POINT_SIZE ), 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<int>( TextField::Property::MAX_LENGTH ), 50u, TEST_LOCATION );
DALI_TEST_EQUALS( field.GetProperty<int>( TextField::Property::EXCEED_POLICY ), TextField::EXCEED_POLICY_CLIP, TEST_LOCATION );
-
- // Check cursor properties
- field.SetProperty( TextField::Property::ENABLE_CURSOR_BLINK, true );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::HORIZONTAL_ALIGNMENT ), "BEGIN", TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::VERTICAL_ALIGNMENT ), "TOP", TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::TEXT_COLOR ), Color::BLACK, TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<Vector2>( TextField::Property::SHADOW_OFFSET ), Vector2::ZERO, TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::PLACEHOLDER_TEXT_COLOR ), PLACEHOLDER_TEXT_COLOR, TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::SHADOW_COLOR ), Color::BLACK, TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::PRIMARY_CURSOR_COLOR ), Color::BLACK, TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::SECONDARY_CURSOR_COLOR ), Color::BLACK, TEST_LOCATION );
DALI_TEST_EQUALS( field.GetProperty<bool>( TextField::Property::ENABLE_CURSOR_BLINK ), true, TEST_LOCATION );
- field.SetProperty( TextField::Property::PRIMARY_CURSOR_COLOR, Color::RED );
- DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::PRIMARY_CURSOR_COLOR ), Color::RED, TEST_LOCATION );
- field.SetProperty( TextField::Property::SECONDARY_CURSOR_COLOR, Color::BLUE );
- DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::SECONDARY_CURSOR_COLOR ), Color::BLUE, TEST_LOCATION );
- field.SetProperty( TextField::Property::CURSOR_BLINK_DURATION, 10.0f );
- DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::CURSOR_BLINK_DURATION ), 10.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::CURSOR_BLINK_INTERVAL ), CURSOR_BLINK_INTERVAL * TO_SECONDS, TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::CURSOR_BLINK_DURATION ), 0.f, TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::SCROLL_THRESHOLD ), SCROLL_THRESHOLD, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::SCROLL_SPEED ), SCROLL_SPEED, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+ DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::SELECTION_HIGHLIGHT_COLOR ), LIGHT_BLUE, TEST_LOCATION );
- // Blink interval
- field.SetProperty( TextField::Property::CURSOR_BLINK_INTERVAL, 1.0f );
- DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::CURSOR_BLINK_INTERVAL ), 1.0f, TEST_LOCATION );
+ // Check the render backend property.
+ field.SetProperty( TextField::Property::RENDERING_BACKEND, Text::RENDERING_BASIC );
+ DALI_TEST_EQUALS( field.GetProperty<unsigned int>( TextField::Property::RENDERING_BACKEND ), Text::RENDERING_BASIC, TEST_LOCATION );
- // Decoration bounding box
- field.SetProperty( TextField::Property::DECORATION_BOUNDING_BOX, Rect<int>( 0, 0, 1, 1 ) );
- DALI_TEST_EQUALS( field.GetProperty<Rect <int > >( TextField::Property::DECORATION_BOUNDING_BOX ), Rect<int>( 0, 0, 1, 1 ), TEST_LOCATION );
-
- // Check that the Alignment properties can be correctly set
- field.SetProperty( TextField::Property::HORIZONTAL_ALIGNMENT, "BEGIN" );
- DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::HORIZONTAL_ALIGNMENT ), "BEGIN", TEST_LOCATION );
- field.SetProperty( TextField::Property::VERTICAL_ALIGNMENT, "CENTER" );
- DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::VERTICAL_ALIGNMENT ), "CENTER", TEST_LOCATION );
-
- // Set text
+ // Check text property.
field.SetProperty( TextField::Property::TEXT, "Setting Text" );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::TEXT ), std::string("Setting Text"), TEST_LOCATION );
+
+ // Check placeholder text properties.
+ field.SetProperty( TextField::Property::PLACEHOLDER_TEXT, "Setting Placeholder Text" );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::PLACEHOLDER_TEXT ), std::string("Setting Placeholder Text"), TEST_LOCATION );
- // Set placeholder text (currently not implemented)
- field.SetProperty( TextField::Property::PLACEHOLDER_TEXT, "Setting Text" );
+ field.SetProperty( TextField::Property::PLACEHOLDER_TEXT_FOCUSED, "Setting Placeholder Text Focused" );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::PLACEHOLDER_TEXT_FOCUSED ), std::string("Setting Placeholder Text Focused"), TEST_LOCATION );
- // Set Grab Handle image
- field.SetProperty( TextField::Property::GRAB_HANDLE_IMAGE, "" );
+ // Check font properties.
+ field.SetProperty( TextField::Property::FONT_FAMILY, "Setting font family" );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::FONT_FAMILY ), std::string("Setting font family"), TEST_LOCATION );
+ field.SetProperty( TextField::Property::FONT_STYLE, "Setting font style" );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::FONT_STYLE ), std::string("Setting font style"), TEST_LOCATION );
+ field.SetProperty( TextField::Property::POINT_SIZE, 10.f );
+ DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::POINT_SIZE ), 10.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
// Check that the MAX_LENGTH property can be correctly set
const int maxNumberOfCharacters = 20;
field.SetProperty( TextField::Property::MAX_LENGTH, maxNumberOfCharacters );
DALI_TEST_EQUALS( field.GetProperty<int>( TextField::Property::MAX_LENGTH ), maxNumberOfCharacters, TEST_LOCATION );
- END_TEST;
- }
+ // Check exceed policy
+ // Set a different exceed policy is not implemented.
- // Negative test case for a method
- int UtcDaliTextFieldSetPropertyN(void)
- {
- ToolkitTestApplication application;
- tet_infoline(" UtcDaliToolkitTextFieldSetPropertyN");
- TextField field = TextField::New();
- DALI_TEST_CHECK( field );
+ // Check that the Alignment properties can be correctly set
+ field.SetProperty( TextField::Property::HORIZONTAL_ALIGNMENT, "END" );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::HORIZONTAL_ALIGNMENT ), "END", TEST_LOCATION );
+ field.SetProperty( TextField::Property::VERTICAL_ALIGNMENT, "CENTER" );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::VERTICAL_ALIGNMENT ), "CENTER", TEST_LOCATION );
+
+ // Check text's color property
+ field.SetProperty( TextField::Property::TEXT_COLOR, Color::WHITE );
+ DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::TEXT_COLOR ), Color::WHITE, TEST_LOCATION );
+
+ // Check placeholder text's color property.
+ field.SetProperty( TextField::Property::PLACEHOLDER_TEXT_COLOR, Color::RED );
+ DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::PLACEHOLDER_TEXT_COLOR ), Color::RED, TEST_LOCATION );
+
+ // Check shadow properties.
+ field.SetProperty( TextField::Property::SHADOW_OFFSET, Vector2( 1.f, 1.f ) );
+ DALI_TEST_EQUALS( field.GetProperty<Vector2>( TextField::Property::SHADOW_OFFSET ), Vector2( 1.f, 1.f ), TEST_LOCATION );
+ field.SetProperty( TextField::Property::SHADOW_COLOR, Color::GREEN );
+ DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::SHADOW_COLOR ), Color::GREEN, TEST_LOCATION );
+
+ // Check cursor properties
+ field.SetProperty( TextField::Property::PRIMARY_CURSOR_COLOR, Color::RED );
+ DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::PRIMARY_CURSOR_COLOR ), Color::RED, TEST_LOCATION );
+ field.SetProperty( TextField::Property::SECONDARY_CURSOR_COLOR, Color::BLUE );
+ DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::SECONDARY_CURSOR_COLOR ), Color::BLUE, TEST_LOCATION );
+
+ field.SetProperty( TextField::Property::ENABLE_CURSOR_BLINK, false );
+ DALI_TEST_EQUALS( field.GetProperty<bool>( TextField::Property::ENABLE_CURSOR_BLINK ), false, TEST_LOCATION );
+ field.SetProperty( TextField::Property::CURSOR_BLINK_INTERVAL, 1.f );
+ DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::CURSOR_BLINK_INTERVAL ), 1.f, TEST_LOCATION );
+ field.SetProperty( TextField::Property::CURSOR_BLINK_DURATION, 10.f );
+ DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::CURSOR_BLINK_DURATION ), 10.f, TEST_LOCATION );
+
+ // Check scroll properties.
+ field.SetProperty( TextField::Property::SCROLL_THRESHOLD, 1.f );
+ DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::SCROLL_THRESHOLD ), 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+ field.SetProperty( TextField::Property::SCROLL_SPEED, 100.f );
+ DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::SCROLL_SPEED ), 100.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+ // Check handle images
+ field.SetProperty( TextField::Property::GRAB_HANDLE_IMAGE, "image1" );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::GRAB_HANDLE_IMAGE ), "image1", TEST_LOCATION );
+ field.SetProperty( TextField::Property::GRAB_HANDLE_PRESSED_IMAGE, "image2" );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::GRAB_HANDLE_PRESSED_IMAGE ), "image2", TEST_LOCATION );
+ field.SetProperty( TextField::Property::SELECTION_HANDLE_IMAGE_LEFT, "image3" );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::SELECTION_HANDLE_IMAGE_LEFT ), "image3", TEST_LOCATION );
+ field.SetProperty( TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT, "image4" );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT ), "image4", TEST_LOCATION );
+ field.SetProperty( TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT, "image5" );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT ), "image5", TEST_LOCATION );
+ field.SetProperty( TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT, "image6" );
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT ), "image6", TEST_LOCATION );
+
+ // Check the highlight color
+ field.SetProperty( TextField::Property::SELECTION_HIGHLIGHT_COLOR, Color::GREEN );
+ DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::SELECTION_HIGHLIGHT_COLOR ), Color::GREEN, TEST_LOCATION );
+
+ // Decoration bounding box
+ field.SetProperty( TextField::Property::DECORATION_BOUNDING_BOX, Rect<int>( 0, 0, 1, 1 ) );
+ DALI_TEST_EQUALS( field.GetProperty<Rect <int > >( TextField::Property::DECORATION_BOUNDING_BOX ), Rect<int>( 0, 0, 1, 1 ), TEST_LOCATION );
- bool assert = false;
- try
- {
- field.SetProperty( 0, true );
- }
- catch ( ... )
- {
- assert = true;
- }
- if ( assert )
- {
- tet_result(TET_PASS);
- }
- else
- {
- tet_result(TET_FAIL);
- }
END_TEST;
}
field.SetProperty( TextField::Property::HORIZONTAL_ALIGNMENT, "BEGIN" );
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+ Stage::GetCurrent().Add( field );
+
try
{
// Render some text with the basic backend
DALI_TEST_CHECK( field );
field.SetProperty( TextField::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
+
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+ Stage::GetCurrent().Add( field );
+
try
{
// Render some text with the shared atlas backend
TextField field = TextField::New();
DALI_TEST_CHECK( field );
- Stage::GetCurrent().Add(field);
+ Stage::GetCurrent().Add( field );
field.TextChangedSignal().Connect(&TestTextChangedCallback);
field.SetKeyInputFocus();
- Dali::Integration::KeyEvent keyevent;
- keyevent.keyName = "D";
- keyevent.keyString = "D";
- keyevent.keyCode = 0;
- keyevent.keyModifier = 0;
- keyevent.time = 0;
- keyevent.state = Integration::KeyEvent::Down;
-
gTextChangedCallBackCalled = false;
- application.ProcessEvent( keyevent );
+ application.ProcessEvent( GenerateKey( "D", "D", 0, 0, 0, Integration::KeyEvent::Down ) );
DALI_TEST_CHECK( gTextChangedCallBackCalled );
END_TEST;
TextField field = TextField::New();
DALI_TEST_CHECK( field );
- Stage::GetCurrent().Add(field);
+ Stage::GetCurrent().Add( field );
field.TextChangedSignal().Connect(&TestTextChangedCallback);
gTextChangedCallBackCalled = false;
field.SetProperty( TextField::Property::PLACEHOLDER_TEXT, "ABC" ); // Setting placeholder, not TEXT
- DALI_TEST_CHECK( ! gTextChangedCallBackCalled );
+ DALI_TEST_CHECK( !gTextChangedCallBackCalled );
END_TEST;
}
TextField field = TextField::New();
DALI_TEST_CHECK( field );
- Stage::GetCurrent().Add(field);
+ Stage::GetCurrent().Add( field );
const int maxNumberOfCharacters = 1;
field.SetProperty( TextField::Property::MAX_LENGTH, maxNumberOfCharacters );
gMaxCharactersCallBackCalled = false;
field.MaxLengthReachedSignal().Connect(&TestMaxLengthReachedCallback);
- Dali::Integration::KeyEvent keyevent;
- keyevent.keyName = "a";
- keyevent.keyString = "a";
- keyevent.keyCode = 0;
- keyevent.keyModifier = 0;
- keyevent.time = 0;
- keyevent.state = Integration::KeyEvent::Down;
-
- application.ProcessEvent( keyevent );
-
- application.ProcessEvent( keyevent );
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
DALI_TEST_CHECK( gMaxCharactersCallBackCalled );
TextField field = TextField::New();
DALI_TEST_CHECK( field );
- Stage::GetCurrent().Add(field);
+ Stage::GetCurrent().Add( field );
const int maxNumberOfCharacters = 3;
field.SetProperty( TextField::Property::MAX_LENGTH, maxNumberOfCharacters );
gMaxCharactersCallBackCalled = false;
field.MaxLengthReachedSignal().Connect(&TestMaxLengthReachedCallback);
- Dali::Integration::KeyEvent keyevent;
- keyevent.keyName = "a";
- keyevent.keyString = "a";
- keyevent.keyCode = 0;
- keyevent.keyModifier = 0;
- keyevent.time = 0;
- keyevent.state = Integration::KeyEvent::Down;
-
- application.ProcessEvent( keyevent );
- application.ProcessEvent( keyevent );
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
DALI_TEST_CHECK( !gMaxCharactersCallBackCalled );
END_TEST;
}
+
+ int utcDaliTextFieldEvent01(void)
+ {
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextFieldEvent01");
+
+ // Creates a tap event. After creating a tap event the text field should
+ // have the focus and add text with key events should be possible.
+
+ TextField field = TextField::New();
+ DALI_TEST_CHECK( field );
+
+ Stage::GetCurrent().Add( field );
+
+ field.SetSize( 300.f, 50.f );
+ field.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ field.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();
+
+ // Add a key event but as the text field has not the focus it should do nothing.
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::TEXT ), std::string(""), TEST_LOCATION );
+
+ // Create a tap event to touch the text field.
+ application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+ application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Now the text field has the focus, so it can handle the key events.
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::TEXT ), std::string("aa"), TEST_LOCATION );
+
+ // Create a second text field and send key events to it.
+ TextField field2 = TextField::New();
+
+ field2.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ field2.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ field2.SetSize( 100.f, 100.f );
+ field2.SetPosition( 100.f, 100.f );
+
+ Stage::GetCurrent().Add( field2 );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Create a tap event on the second text field.
+ application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 125.0f ) ) );
+ application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 125.0f ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // The second text field has the focus. It should handle the key events.
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Check the text has been added to the second text field.
+ DALI_TEST_EQUALS( field2.GetProperty<std::string>( TextField::Property::TEXT ), std::string("aa"), TEST_LOCATION );
+
+ END_TEST;
+ }
+
+ int utcDaliTextFieldEvent02(void)
+ {
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextFieldEvent02");
+
+ // Checks if the right number of actors are created.
+
+ TextField field = TextField::New();
+ DALI_TEST_CHECK( field );
+
+ Stage::GetCurrent().Add( field );
+
+ field.SetSize( 300.f, 50.f );
+ field.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ field.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();
+
+ // Check there are the expected number of children ( active layer, offscreen root actor, and the offscreen image actor
+ DALI_TEST_EQUALS( field.GetChildCount(), 3u, TEST_LOCATION );
+
+ Actor layer = field.GetChildAt( 0u );
+ DALI_TEST_CHECK( layer.IsLayer() );
+
+ Actor offscreenRoot = field.GetChildAt( 1u );
+ DALI_TEST_CHECK( offscreenRoot.IsLayer() );
+ DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor.
+
+ Actor offscreenImage = field.GetChildAt( 2u );
+ ImageActor imageActor = ImageActor::DownCast( offscreenImage );
+ DALI_TEST_CHECK( imageActor );
+
+ // Create a tap event to touch the text field.
+ application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+ application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( layer.GetChildCount(), 1u, TEST_LOCATION ); // The cursor.
+ DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor.
+
+ // Now the text field has the focus, so it can handle the key events.
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Checks the cursor and the renderer have been created.
+ DALI_TEST_EQUALS( layer.GetChildCount(), 1u, TEST_LOCATION ); // The cursor.
+ DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 2u, TEST_LOCATION ); // The camera actor and the renderer
+
+ ImageActor cursor = ImageActor::DownCast( layer.GetChildAt( 0u ) );
+ DALI_TEST_CHECK( cursor );
+
+ CameraActor camera = CameraActor::DownCast( offscreenRoot.GetChildAt( 0u ) );
+ DALI_TEST_CHECK( camera );
+
+ RenderableActor renderer = RenderableActor::DownCast( offscreenRoot.GetChildAt( 1u ) );
+ DALI_TEST_CHECK( renderer );
+
+ // Move the cursor and check the position changes.
+ Vector3 position1 = cursor.GetCurrentPosition();
+
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down ) );
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ Vector3 position2 = cursor.GetCurrentPosition();
+
+ DALI_TEST_CHECK( position2.x < position1.x );
+
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_RIGHT, 0, 0, Integration::KeyEvent::Down ) );
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_RIGHT, 0, 0, Integration::KeyEvent::Down ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ Vector3 position3 = cursor.GetCurrentPosition();
+
+ DALI_TEST_EQUALS( position1, position3, TEST_LOCATION ); // Should be in the same position1.
+
+ // Send some taps and check the cursor positions.
+
+ // Try to tap at the beginning.
+ 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();
+
+ // Cursor position should be the same than position1.
+ Vector3 position4 = cursor.GetCurrentPosition();
+
+ DALI_TEST_EQUALS( position2, position4, TEST_LOCATION ); // Should be in the same position2.
+
+ // Try to tap at the end.
+ application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 13.f, 25.0f ) ) );
+ application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 13.0f, 25.0f ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Cursor position should be the same than position1.
+ Vector3 position5 = cursor.GetCurrentPosition();
+
+ DALI_TEST_EQUALS( position1, position5, TEST_LOCATION ); // Should be in the same position1.
+
+ // Remove some text.
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down ) );
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Cursor position should be the same than position2.
+ Vector3 position6 = cursor.GetCurrentPosition();
+
+ DALI_TEST_EQUALS( Vector3( 0.f, position2.y, position2.z ), position6, TEST_LOCATION ); // TODO Should be in the same position2.
+
+ // Should not be renderer.
+ DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor only.
+
+ END_TEST;
+ }
+
+ int utcDaliTextFieldEvent03(void)
+ {
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextFieldEvent03");
+
+ // Checks if the highlight actor is created.
+
+ TextField field = TextField::New();
+ DALI_TEST_CHECK( field );
+
+ Stage::GetCurrent().Add( field );
+
+ field.SetProperty( TextField::Property::TEXT, "This is a long text for the size of the text-field." );
+ field.SetSize( 30.f, 50.f );
+ field.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ field.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 first to get the focus.
+ 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();
+
+ // Double tap to select a word.
+ application.ProcessEvent( GenerateTap( Gesture::Possible, 2u, 1u, Vector2( 3.f, 25.0f ) ) );
+ application.ProcessEvent( GenerateTap( Gesture::Started, 2u, 1u, Vector2( 3.f, 25.0f ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // The offscreen root actor should have three actors: the camera, a renderer and the highlight actor.
+ Actor offscreenRoot = field.GetChildAt( 1u );
+ DALI_TEST_CHECK( offscreenRoot.IsLayer() );
+
+ CameraActor camera = CameraActor::DownCast( offscreenRoot.GetChildAt( 0u ) );
+ DALI_TEST_CHECK( camera );
+
+ RenderableActor renderer = RenderableActor::DownCast( offscreenRoot.GetChildAt( 1u ) );
+ DALI_TEST_CHECK( renderer );
+
+ MeshActor highlight = MeshActor::DownCast( offscreenRoot.GetChildAt( 2u ) );
+ DALI_TEST_CHECK( highlight );
+
+ END_TEST;
+ }
[enable_debug=$enableval],
[enable_debug=no])
+ AC_ARG_ENABLE([i18n],
+ [AC_HELP_STRING([--enable-i18n],
+ [Turns on internationalisation])],
+ [enable_i18n=$enableval],
+ [enable_i18n=no])
+
# option to build JavaScript plugin
# configure settings and output
# --enable-javascript // enable_javascript = yes
[AC_HELP_STRING([--enable-javascript],
[Enable JavaScript plugin])] ,
[enable_javascript=$enableval],
- [enable_javascript=automatic])
+ [enable_javascript=no])
if test "x$enable_debug" = "xyes"; then
DALI_TOOLKIT_CFLAGS="$DALI_TOOLKIT_CFLAGS -fvisibility=hidden -DHIDE_DALI_INTERNALS"
fi
-
-
+ if test "x$enable_i18n" = "xyes"; then
+ DALI_TOOLKIT_CFLAGS="$DALI_TOOLKIT_CFLAGS -DDGETTEXT_ENABLED "
+ fi
# Tizen Profile options
AC_ARG_ENABLE([profile],
develapisuperblurviewdir = $(develapicontrolsdir)/super-blur-view
develapifocusmanagerdir = $(develapidir)/focus-manager
develapiscriptingdir = $(develapidir)/scripting
-develapibubbleeffectdir = $(develapidir)/shader-effects/bubble-effect
develapishadereffectsdir = $(develapidir)/shader-effects
develapitransitioneffectsdir = $(develapidir)/transition-effects
develapistylingdir = $(develapidir)/styling
develapitoolbardir = $(develapicontrolsdir)/tool-bar
+ develapitextselectionpopupdir = $(develapicontrolsdir)/text-controls
# devel headers
develapibloomview_HEADERS = $(devel_api_bloom_view_header_files)
develapibubbleemitter_HEADERS = $(devel_api_bubble_emitter_header_files)
-develapibubbleeffect_HEADERS = $(devel_api_bubble_effect_header_files)
develapibuilder_HEADERS = $(devel_api_builder_header_files)
develapieffectsview_HEADERS = $(devel_api_effects_view_header_files)
develapifocusmanager_HEADERS = $(devel_api_focus_manager_header_files)
develapisuperblurview_HEADERS = $(devel_api_super_blur_view_header_files)
develapitoolbar_HEADERS = $(devel_api_tool_bar_header_files)
develapitransitioneffects_HEADERS = $(devel_api_transition_effects_header_files)
+ develapitextselectionpopup_HEADERS = $(devel_api_text_selection_popup_header_files)
# public api source
publicapidir = $(topleveldir)/public-api
$(devel_api_src_dir)/controls/slider/slider.cpp \
$(devel_api_src_dir)/controls/super-blur-view/super-blur-view.cpp \
$(devel_api_src_dir)/controls/text-controls/text-selection-popup.cpp \
+ $(devel_api_src_dir)/controls/text-controls/text-selection-toolbar.cpp \
$(devel_api_src_dir)/controls/tool-bar/tool-bar.cpp \
$(devel_api_src_dir)/focus-manager/keyinput-focus-manager.cpp \
$(devel_api_src_dir)/styling/style-manager.cpp \
$(devel_api_src_dir)/scripting/script.cpp \
- $(devel_api_src_dir)/shader-effects/bubble-effect/bubble-effect.cpp \
- $(devel_api_src_dir)/shader-effects/bubble-effect/color-adjuster.cpp \
- $(devel_api_src_dir)/shader-effects/alpha-discard-effect.cpp \
- $(devel_api_src_dir)/shader-effects/bendy-effect.cpp \
- $(devel_api_src_dir)/shader-effects/blind-effect.cpp \
- $(devel_api_src_dir)/shader-effects/bouncing-effect.cpp \
- $(devel_api_src_dir)/shader-effects/carousel-effect.cpp \
- $(devel_api_src_dir)/shader-effects/displacement-effect.cpp \
- $(devel_api_src_dir)/shader-effects/dissolve-effect.cpp \
- $(devel_api_src_dir)/shader-effects/dissolve-local-effect.cpp \
- $(devel_api_src_dir)/shader-effects/distance-field-effect.cpp \
- $(devel_api_src_dir)/shader-effects/image-region-effect.cpp \
- $(devel_api_src_dir)/shader-effects/iris-effect.cpp \
- $(devel_api_src_dir)/shader-effects/mask-effect.cpp \
- $(devel_api_src_dir)/shader-effects/mirror-effect.cpp \
- $(devel_api_src_dir)/shader-effects/motion-blur-effect.cpp \
- $(devel_api_src_dir)/shader-effects/motion-stretch-effect.cpp \
- $(devel_api_src_dir)/shader-effects/nine-patch-mask-effect.cpp \
- $(devel_api_src_dir)/shader-effects/overlay-effect.cpp \
- $(devel_api_src_dir)/shader-effects/page-turn-book-spine-effect.cpp \
- $(devel_api_src_dir)/shader-effects/page-turn-effect.cpp \
- $(devel_api_src_dir)/shader-effects/quadratic-bezier.cpp \
- $(devel_api_src_dir)/shader-effects/ripple-effect.cpp \
- $(devel_api_src_dir)/shader-effects/ripple2d-effect.cpp \
- $(devel_api_src_dir)/shader-effects/shear-effect.cpp \
- $(devel_api_src_dir)/shader-effects/soft-button-effect.cpp \
- $(devel_api_src_dir)/shader-effects/spot-effect.cpp \
- $(devel_api_src_dir)/shader-effects/square-dissolve-effect.cpp \
- $(devel_api_src_dir)/shader-effects/swirl-effect.cpp \
- $(devel_api_src_dir)/shader-effects/water-effect.cpp \
$(devel_api_src_dir)/transition-effects/cube-transition-cross-effect.cpp \
$(devel_api_src_dir)/transition-effects/cube-transition-effect.cpp \
$(devel_api_src_dir)/transition-effects/cube-transition-fold-effect.cpp \
devel_api_bloom_view_header_files = \
$(devel_api_src_dir)/controls/bloom-view/bloom-view.h
-devel_api_bubble_effect_header_files = \
- $(devel_api_src_dir)/shader-effects/bubble-effect/bubble-effect.h \
- $(devel_api_src_dir)/shader-effects/bubble-effect/color-adjuster.h
-
devel_api_bubble_emitter_header_files = \
$(devel_api_src_dir)/controls/bubble-effect/bubble-emitter.h
$(devel_api_src_dir)/shader-effects/motion-stretch-effect.h \
$(devel_api_src_dir)/shader-effects/nine-patch-mask-effect.h \
$(devel_api_src_dir)/shader-effects/overlay-effect.h \
- $(devel_api_src_dir)/shader-effects/page-turn-book-spine-effect.h \
- $(devel_api_src_dir)/shader-effects/page-turn-effect.h \
$(devel_api_src_dir)/shader-effects/quadratic-bezier.h \
$(devel_api_src_dir)/shader-effects/ripple-effect.h \
$(devel_api_src_dir)/shader-effects/ripple2d-effect.h \
$(devel_api_src_dir)/shader-effects/soft-button-effect.h \
$(devel_api_src_dir)/shader-effects/spot-effect.h \
$(devel_api_src_dir)/shader-effects/square-dissolve-effect.h \
- $(devel_api_src_dir)/shader-effects/swirl-effect.h \
- $(devel_api_src_dir)/shader-effects/water-effect.h
+ $(devel_api_src_dir)/shader-effects/swirl-effect.h
devel_api_super_blur_view_header_files = \
$(devel_api_src_dir)/controls/super-blur-view/super-blur-view.h
- devel_api_text_selection_popup_header_files = \
- $(devel_api_src_dir)/controls/text-controls/text-selection-popup.h
+ devel_api_text_controls_header_files = \
+ $(devel_api_src_dir)/controls/text-controls/text-selection-popup.h \
+ $(devel_api_src_dir)/controls/text-controls/text-selection-toolbar.h
devel_api_tool_bar_header_files = \
$(devel_api_src_dir)/controls/tool-bar/tool-bar.h
// EXTERNAL INCLUDE
#include <iostream>
#include <string.h>
+#include <dali/devel-api/rendering/sampler.h>
+#include <dali/devel-api/rendering/shader.h>
#include <dali/integration-api/debug.h>
namespace Dali
const uint32_t DOUBLE_PIXEL_PADDING( SINGLE_PIXEL_PADDING << 1 );
const uint32_t FILLED_PIXEL( -1 );
Toolkit::AtlasManager::AtlasSize EMPTY_SIZE;
+
+ #define MAKE_SHADER(A)#A
+
+ const char* VERTEX_SHADER = MAKE_SHADER(
+ attribute mediump vec2 aPosition;
+ attribute mediump vec2 aTexCoord;
+ uniform mediump mat4 uMvpMatrix;
+ uniform mediump vec3 uSize;
+ varying mediump vec2 vTexCoord;
+
+ void main()
+ {
+ mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
+ position.xyz *= uSize;
+ gl_Position = uMvpMatrix * position;
+ vTexCoord = aTexCoord;
+ }
+ );
+
+ const char* FRAGMENT_SHADER_L8 = MAKE_SHADER(
+ uniform lowp vec4 uColor;
+ uniform sampler2D sTexture;
+ varying mediump vec2 vTexCoord;
+
+ void main()
+ {
+ mediump vec4 color = texture2D( sTexture, vTexCoord );
+ gl_FragColor = vec4( uColor.rgb, uColor.a * color.r );
+ }
+ );
+
+ const char* FRAGMENT_SHADER_RGBA = MAKE_SHADER(
+ uniform sampler2D sTexture;
+ varying mediump vec2 vTexCoord;
+
+ void main()
+ {
+ gl_FragColor = texture2D( sTexture, vTexCoord );
+ }
+ );
+
}
AtlasManager::AtlasManager()
mNewAtlasSize.mHeight = DEFAULT_ATLAS_HEIGHT;
mNewAtlasSize.mBlockWidth = DEFAULT_BLOCK_WIDTH;
mNewAtlasSize.mBlockHeight = DEFAULT_BLOCK_HEIGHT;
+ mShaderL8 = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_L8 );
+ mShaderRgba = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_RGBA );
}
AtlasManagerPtr AtlasManager::New()
AtlasManager::~AtlasManager()
{
- for ( uint32_t i = 0; i < mAtlasList.size(); ++i )
+ for ( SizeType i = 0; i < mAtlasList.size(); ++i )
{
+ mAtlasList[ i ].mAtlas.UploadedSignal().Disconnect( this, &AtlasManager::OnUpload );
delete[] mAtlasList[ i ].mStripBuffer;
}
+
+ // Are there any upload signals pending? Free up those buffer images now.
+ for ( SizeType i = 0; i < mUploadedImages.Size(); ++i )
+ {
+ delete[] mUploadedImages[ i ];
+ }
+}
+
+void AtlasManager::OnUpload( Image image )
+{
+ if ( mUploadedImages.Size() )
+ {
+ delete[] mUploadedImages[ 0 ];
+ mUploadedImages.Erase( mUploadedImages.Begin() );
+ }
+ else
+ {
+ DALI_LOG_ERROR("Atlas Image Upload List should not be empty\n");
+ }
}
Toolkit::AtlasManager::AtlasId AtlasManager::CreateAtlas( const Toolkit::AtlasManager::AtlasSize& size, Pixel::Format pixelformat )
atlasDescriptor.mAtlas = atlas;
atlasDescriptor.mSize = size;
atlasDescriptor.mPixelFormat = pixelformat;
- std::stringstream materialLabel;
- materialLabel << "Atlas Material - ";
- materialLabel << mAtlasList.size();
- atlasDescriptor.mMaterial = Material::New( materialLabel.str() );
- atlasDescriptor.mMaterial.SetDiffuseTexture( atlas );
atlasDescriptor.mNextFreeBlock = 1u; // indicate next free block will be the first ( +1 )
+ atlas.UploadedSignal().Connect( this, &AtlasManager::OnUpload );
// What size do we need for this atlas' strip buffer ( assume 32bit pixel format )?
- uint32_t neededStripSize =( blockWidth > blockHeight - DOUBLE_PIXEL_PADDING ? blockWidth : blockHeight - DOUBLE_PIXEL_PADDING ) << 2;
+ SizeType neededStripSize =( blockWidth > blockHeight - DOUBLE_PIXEL_PADDING ? blockWidth : blockHeight - DOUBLE_PIXEL_PADDING ) << 2;
atlasDescriptor.mStripBuffer = new PixelBuffer[ neededStripSize ];
memset( atlasDescriptor.mStripBuffer, 0, neededStripSize );
SINGLE_PIXEL_PADDING,
blockHeight - DOUBLE_PIXEL_PADDING,
pixelformat );
+ mUploadedImages.PushBack( NULL );
atlasDescriptor.mFilledPixelImage = BufferImage::New( reinterpret_cast< PixelBuffer* >( &mFilledPixel ), 1, 1, pixelformat );
atlas.Upload( atlasDescriptor.mFilledPixelImage, 0, 0 );
+
+ Sampler sampler = Sampler::New( atlas, "sTexture" );
+ sampler.SetProperty( Sampler::Property::AFFECTS_TRANSPARENCY, true );
+ atlasDescriptor.mMaterial = Material::New( pixelformat == Pixel::L8 ? mShaderL8 : mShaderRgba );
+ atlasDescriptor.mMaterial.AddSampler( sampler );
+ atlasDescriptor.mSampler = sampler;
+ atlasDescriptor.mMaterial.SetBlendMode( BlendingMode::ON );
mAtlasList.push_back( atlasDescriptor );
return mAtlasList.size();
}
if ( Toolkit::AtlasManager::FAIL_ON_ADD_FAILS == mAddFailPolicy || !foundAtlas-- )
{
// Haven't found an atlas for this image!!!!!!
- return;
+ return;
}
}
const Vector2& position,
SizeType widthInBlocks,
SizeType heightInBlocks,
- Dali::MeshData& meshData,
+ Toolkit::AtlasManager::Mesh2D& mesh,
AtlasSlotDescriptor& desc )
{
- Dali::MeshData::Vertex vertex;
- Dali::MeshData::VertexContainer vertices;
- Dali::MeshData::FaceIndices faces;
- Dali::MeshData::FaceIndex faceIndex = 0;
- meshData.SetHasNormals( false );
- meshData.SetHasColor( true );
- meshData.SetHasTextureCoords( true );
+
+ Toolkit::AtlasManager::Vertex2D vertex;
+ uint32_t faceIndex = 0; // TODO change to unsigned short when property type is available
SizeType blockWidth = mAtlasList[ atlas ].mSize.mBlockWidth;
SizeType blockHeight = mAtlasList[ atlas ].mSize.mBlockHeight;
}
// Top left
- vertex.x = topLeft.x;
- vertex.y = topLeft.y;
- vertex.z = 0.0f;
- vertex.u = fBlockX;
- vertex.v = fBlockY;
+ vertex.mPosition.x = topLeft.x;
+ vertex.mPosition.y = topLeft.y;
+ vertex.mTexCoords.x = fBlockX;
+ vertex.mTexCoords.y = fBlockY;
- vertices.push_back( vertex );
+ mesh.mVertices.PushBack( vertex );
// Top Right
- vertex.x = topLeft.x + ndcVWidth;
- vertex.y = topLeft.y;
- vertex.z = 0.0f;
- vertex.u = fBlockX + ndcWidth;
- vertex.v = fBlockY;
+ vertex.mPosition.x = topLeft.x + ndcVWidth;
+ vertex.mPosition.y = topLeft.y;
+ vertex.mTexCoords.x = fBlockX + ndcWidth;
+ vertex.mTexCoords.y = fBlockY;
- vertices.push_back( vertex );
+ mesh.mVertices.PushBack( vertex );
// Bottom Left
- vertex.x = topLeft.x;
- vertex.y = topLeft.y + ndcVHeight;
- vertex.z = 0.0f;
- vertex.u = fBlockX;
- vertex.v = fBlockY + ndcHeight;
+ vertex.mPosition.x = topLeft.x;
+ vertex.mPosition.y = topLeft.y + ndcVHeight;
+ vertex.mTexCoords.x = fBlockX;
+ vertex.mTexCoords.y = fBlockY + ndcHeight;
- vertices.push_back( vertex );
+ mesh.mVertices.PushBack( vertex );
// Bottom Right
topLeft.x += ndcVWidth;
- vertex.x = topLeft.x;
- vertex.y = topLeft.y + ndcVHeight;
- vertex.z = 0.0f;
- vertex.u = fBlockX + ndcWidth;
- vertex.v = fBlockY + ndcHeight;
+ vertex.mPosition.x = topLeft.x;
+ vertex.mPosition.y = topLeft.y + ndcVHeight;
+ vertex.mTexCoords.x = fBlockX + ndcWidth;
+ vertex.mTexCoords.y = fBlockY + ndcHeight;
- vertices.push_back( vertex );
+ mesh.mVertices.PushBack( vertex );
// Six indices in counter clockwise winding
- faces.push_back( faceIndex + 1u );
- faces.push_back( faceIndex );
- faces.push_back( faceIndex + 2u );
- faces.push_back( faceIndex + 2u );
- faces.push_back( faceIndex + 3u );
- faces.push_back( faceIndex + 1u );
+ mesh.mIndices.PushBack( faceIndex + 1u );
+ mesh.mIndices.PushBack( faceIndex );
+ mesh.mIndices.PushBack( faceIndex + 2u );
+ mesh.mIndices.PushBack( faceIndex + 2u );
+ mesh.mIndices.PushBack( faceIndex + 3u );
+ mesh.mIndices.PushBack( faceIndex + 1u );
faceIndex += 4;
}
// If there's only one block then skip this next vertex optimisation
if ( widthInBlocks * heightInBlocks > 1 )
{
- Dali::MeshData::VertexContainer optimizedVertices;
- OptimizeVertices( vertices, faces, optimizedVertices );
- meshData.SetVertices( optimizedVertices );
- }
- else
- {
- meshData.SetVertices( vertices );
+ Toolkit::AtlasManager::Mesh2D optimizedMesh;
+ OptimizeMesh( mesh, optimizedMesh );
}
-
- meshData.SetFaceIndices( faces );
- meshData.SetMaterial( mAtlasList[ atlas ].mMaterial );
+ //PrintMeshData( mesh );
}
-void AtlasManager::PrintMeshData( const MeshData& meshData )
+void AtlasManager::PrintMeshData( const Toolkit::AtlasManager::Mesh2D& mesh )
{
- std::cout << "\nMesh Data for Image: VertexCount = " << meshData.GetVertexCount();
- std::cout << ", Triangles = " << meshData.GetFaceCount() << std::endl;
+ uint32_t vertexCount = mesh.mVertices.Size();
+ uint32_t indexCount = mesh.mIndices.Size();
+ std::cout << "\nMesh Data for Image: VertexCount = " << vertexCount;
+ std::cout << ", Triangles = " << indexCount / 3 << std::endl;
- Dali::MeshData::VertexContainer vertices = meshData.GetVertices();
- Dali::MeshData::FaceIndices faces = meshData.GetFaces();
-
- for ( SizeType v = 0; v < vertices.size(); ++v )
+ for ( SizeType v = 0; v < vertexCount; ++v )
{
- std::cout << " Vertex(" << v << ") x = " << vertices[v].x << ", ";
- std::cout << "y = " << vertices[v].y << ", " << "z = " << vertices[v].z << ", ";
- std::cout << "u = " << vertices[v].u << ", " << "v = " << vertices[v].v << std::endl;
+ std::cout << " Vertex(" << v << ") x = " << mesh.mVertices[v].mPosition.x << ", ";
+ std::cout << "y = " << mesh.mVertices[v].mPosition.y << ", ";
+ std::cout << "u = " << mesh.mVertices[v].mTexCoords.x << ", ";
+ std::cout << "v = " << mesh.mVertices[v].mTexCoords.y << std::endl;
}
std::cout << "\n Indices: ";
- for ( SizeType i = 0; i < faces.size(); ++i )
+ for ( SizeType i = 0; i < indexCount; ++i )
{
- std::cout << " " << faces[ i ];
+ std::cout << " " << mesh.mIndices[ i ];
}
std::cout << std::endl;
}
-void AtlasManager::OptimizeVertices( const MeshData::VertexContainer& in,
- MeshData::FaceIndices& faces,
- MeshData::VertexContainer& out )
+void AtlasManager::OptimizeMesh( const Toolkit::AtlasManager::Mesh2D& in,
+ Toolkit::AtlasManager::Mesh2D& out )
{
unsigned short vertexIndex = 0;
// We could check to see if blocks are next to each other, but it's probably just as quick to compare verts
- for ( SizeType i = 0; i < faces.size(); ++i )
+ for ( SizeType i = 0; i < in.mIndices.Size(); ++i )
{
// Fetch a vertex, has it already been assigned?
bool foundVertex = false;
- Dali::MeshData::Vertex v = in[ faces [ i ] ];
- for ( SizeType j = 0; j < vertexIndex; ++j )
+ Toolkit::AtlasManager::Vertex2D v = in.mVertices[ in.mIndices[ i ] ];
+ for ( SizeType j = 0; j < out.mVertices.Size(); ++j )
{
- if ( v.x == out[ j ].x && v.y == out[ j ].y && v.z == out[ j ].z &&
- v.u == out[ j ].u && v.v == out[ j ].v && v.nX == out[ j ].nX &&
- v.nY == out[ j ].nY && v.nZ == out[ j ].nZ )
+ if ( v.mPosition.x == out.mVertices[ j ].mPosition.x && v.mPosition.y == out.mVertices[ j ].mPosition.y &&
+ v.mTexCoords.x == out.mVertices[ j ].mTexCoords.x && v.mTexCoords.y == out.mVertices[ j ].mTexCoords.y )
{
// Yes, so store this down as the vertex to use
- faces[ i ] = j;
+ out.mIndices.PushBack( j );
foundVertex = true;
break;
}
// Did we find a vertex ?
if ( !foundVertex )
{
- // Add a new vertex
- faces[ i ] = vertexIndex++;
- out.push_back( v );
+ // No so add a new one
+ out.mVertices.PushBack( v );
+ vertexIndex++;
}
}
}
-void AtlasManager::StitchMesh( MeshData& first,
- const MeshData& second,
+void AtlasManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
+ const Toolkit::AtlasManager::Mesh2D& second,
bool optimize )
{
+ uint32_t vc = first.mVertices.Size();
- // Would be much quicker to be able to get a non-const reference to these containers and update in situ
- MeshData::VertexContainer v1 = first.GetVertices();
- MeshData::VertexContainer v2 = second.GetVertices();
- MeshData::FaceIndices f1 = first.GetFaces();
- MeshData::FaceIndices f2 = second.GetFaces();
-
- uint32_t vc1 = first.GetVertexCount();
- uint32_t vc2 = second.GetVertexCount();
-
- for ( uint32_t v = 0; v < vc2; ++v )
+ for ( uint32_t v = 0; v < second.mVertices.Size(); ++v )
{
- v1.push_back( v2[ v ] );
+ first.mVertices.PushBack( second.mVertices[ v ] );
}
- for ( uint32_t f = 0; f < f2.size(); ++f )
+ for ( uint32_t i = 0; i < second.mIndices.Size(); ++i )
{
- f1.push_back( f2[ f ] + vc1 );
+ first.mIndices.PushBack( second.mIndices[ i ] + vc );
}
if ( optimize )
{
- MeshData::VertexContainer optimizedVertices;
- OptimizeVertices( v1, f1, optimizedVertices );
- first.SetVertices( optimizedVertices );
- }
- else
- {
- first.SetVertices( v1 );
+ Toolkit::AtlasManager::Mesh2D optimizedMesh;
+ OptimizeMesh( first, optimizedMesh );
+ first = optimizedMesh;
}
-
- first.SetFaceIndices( f1 );
}
-void AtlasManager::StitchMesh( const MeshData& first,
- const MeshData& second,
- MeshData& out,
+void AtlasManager::StitchMesh( const Toolkit::AtlasManager::Mesh2D& first,
+ const Toolkit::AtlasManager::Mesh2D& second,
+ Toolkit::AtlasManager::Mesh2D& out,
bool optimize )
{
- MeshData::VertexContainer v1 = first.GetVertices();
- MeshData::VertexContainer v2 = second.GetVertices();
- MeshData::FaceIndices f1 = first.GetFaces();
- MeshData::FaceIndices f2 = second.GetFaces();
-
- uint32_t vc1 = first.GetVertexCount();
- uint32_t vc2 = second.GetVertexCount();
-
- MeshData::VertexContainer vertices;
-
- MeshData::FaceIndices faces;
-
- MeshData::Vertex vertex;
+ uint32_t vc = first.mVertices.Size();
- for ( uint32_t v = 0; v < vc1; ++v )
+ for ( uint32_t v = 0; v < vc; ++v )
{
- vertices.push_back( v1[ v ] );
+ out.mVertices.PushBack( first.mVertices[ v ] );
}
- for ( uint32_t v = 0; v < vc2; ++v )
+ for ( uint32_t v = 0; v < second.mVertices.Size(); ++v )
{
- vertices.push_back( v2[ v ] );
+ out.mVertices.PushBack( second.mVertices[ v ] );
}
- for ( uint32_t f = 0; f < f1.size(); ++f )
+ for ( uint32_t i = 0; i < first.mIndices.Size(); ++i )
{
- faces.push_back( f1[ f ] );
+ out.mIndices.PushBack( first.mIndices[ i ] );
}
- for ( uint32_t f = 0; f < f2.size(); ++f )
+ for ( uint32_t i = 0; i < second.mIndices.Size(); ++i )
{
- faces.push_back( f2[ f ] + vc1 );
+ out.mIndices.PushBack( second.mIndices[ i ] + vc );
}
if ( optimize )
{
- MeshData::VertexContainer optimizedVertices;
- OptimizeVertices( vertices, faces, optimizedVertices );
- out.SetVertices( optimizedVertices );
+ Toolkit::AtlasManager::Mesh2D optimizedMesh;
+ OptimizeMesh( out, optimizedMesh );
+ out = optimizedMesh;
}
- else
- {
- out.SetVertices( vertices );
- }
-
- out.SetMaterial( first.GetMaterial() );
- out.SetFaceIndices( faces );
}
void AtlasManager::UploadImage( const BufferImage& image,
{
DALI_LOG_ERROR("Uploading image to Atlas Failed!.\n");
}
+ else
+ {
+ mUploadedImages.PushBack( const_cast< BufferImage& >( image ).GetBuffer() );
+ }
// If this is the first block then we need to keep the first pixel free for underline texture
if ( block )
{
DALI_LOG_ERROR("Uploading top strip to Atlas Failed!\n");
}
+ else
+ {
+ mUploadedImages.PushBack( NULL );
+ }
// Blit left strip
if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mVerticalStrip,
{
DALI_LOG_ERROR("Uploading left strip to Atlas Failed!\n");
}
+ else
+ {
+ mUploadedImages.PushBack( NULL );
+ }
}
// Blit bottom strip
{
DALI_LOG_ERROR("Uploading bottom strip to Atlas Failed!.\n");
}
+ else
+ {
+ mUploadedImages.PushBack( NULL );
+ }
}
// Blit right strip
{
DALI_LOG_ERROR("Uploading right strip to Atlas Failed!.\n");
}
+ else
+ {
+ mUploadedImages.PushBack( NULL );
+ }
}
}
void AtlasManager::GenerateMeshData( ImageId id,
const Vector2& position,
- Toolkit::AtlasManager::Mesh2D& meshData )
- MeshData& meshData,
++ Toolkit::AtlasManager::Mesh2D& meshData,
+ bool addReference )
{
// Read the atlas Id to use for this image
SizeType imageId = id - 1u;
CreateMesh( atlas, width, height, position, widthInBlocks, heightInBlocks, meshData, mImageList[ imageId ] );
- // Mesh created so increase the reference count
- mImageList[ imageId ].mCount++;
+ // Mesh created so increase the reference count, if we're asked to
+ if ( addReference )
+ {
+ mImageList[ imageId ].mCount++;
+ }
}
Dali::Atlas AtlasManager::GetAtlasContainer( AtlasId atlas ) const
metrics.mTextureMemoryUsed = textureMemoryUsed;
}
+Material AtlasManager::GetMaterial( AtlasId atlas ) const
+{
+ if ( atlas && atlas <= mAtlasList.size() )
+ {
+ return mAtlasList[ atlas -1u ].mMaterial;
+ }
+ Material null;
+ return null;
+}
+
+Sampler AtlasManager::GetSampler( AtlasId atlas ) const
+{
+ if ( atlas && atlas <= mAtlasList.size() )
+ {
+ return mAtlasList[ atlas -1u ].mSampler;
+ }
+ Sampler null;
+ return null;
+}
+
} // namespace Internal
} // namespace Toolkit
class AtlasManager;
typedef IntrusivePtr<AtlasManager> AtlasManagerPtr;
-class AtlasManager : public Dali::BaseObject
+class AtlasManager : public Dali::BaseObject, public ConnectionTracker
{
public:
BufferImage mFilledPixelImage; // Image used by atlas for operations such as underline
PixelBuffer* mStripBuffer; // Blank image buffer used to pad upload
Material mMaterial; // material used for atlas texture
+ Sampler mSampler; // sampler used for atlas texture
SizeType mNextFreeBlock; // next free block will be placed here ( actually +1 )
Dali::Vector< SizeType > mFreeBlocksList; // unless there are any previously freed blocks
};
*/
void GenerateMeshData( ImageId id,
const Vector2& position,
- Toolkit::AtlasManager::Mesh2D& mesh );
- MeshData& mesh,
++ Toolkit::AtlasManager::Mesh2D& mesh,
+ bool addReference );
/**
* @copydoc Toolkit::AtlasManager::StitchMesh
*/
- void StitchMesh( MeshData& first,
- const MeshData& second,
+ void StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
+ const Toolkit::AtlasManager::Mesh2D& second,
bool optimize );
/**
* @copydoc Toolkit::AtlasManager::StitchMesh
*/
- void StitchMesh( const MeshData& first,
- const MeshData& second,
- MeshData& out, bool optimize );
+ void StitchMesh( const Toolkit::AtlasManager::Mesh2D& first,
+ const Toolkit::AtlasManager::Mesh2D& second,
+ Toolkit::AtlasManager::Mesh2D& out,
+ bool optimize );
/**
* @copydoc Toolkit::AtlasManager::Remove
*/
void GetMetrics( Toolkit::AtlasManager::Metrics& metrics );
+ /**
+ * @copydoc Toolkit::AtlasManager::GetMaterial
+ */
+ Material GetMaterial( AtlasId atlas ) const;
+
+/**
+ * @copydoc Toolkit::AtlasManager::GetSampler
+ */
+ Sampler GetSampler( AtlasId atlas ) const;
+
private:
- std::vector< AtlasDescriptor > mAtlasList; // List of atlases created
- std::vector< AtlasSlotDescriptor > mImageList; // List of bitmaps store in atlases
+ std::vector< AtlasDescriptor > mAtlasList; // List of atlases created
+ std::vector< AtlasSlotDescriptor > mImageList; // List of bitmaps store in atlases
+ Vector< PixelBuffer* > mUploadedImages; // List of PixelBuffers passed to UploadedSignal
+ Toolkit::AtlasManager::AtlasSize mNewAtlasSize; // Atlas size to use in next creation
+ Toolkit::AtlasManager::AddFailPolicy mAddFailPolicy; // Policy for faling to add an Image
+ SizeType mFilledPixel; // 32Bit pixel image for underlining
SizeType CheckAtlas( SizeType atlas,
SizeType width,
const Vector2& position,
SizeType widthInBlocks,
SizeType heightInBlocks,
- Dali::MeshData& meshData,
+ Toolkit::AtlasManager::Mesh2D& mesh,
AtlasSlotDescriptor& desc );
- void OptimizeVertices( const MeshData::VertexContainer& in,
- MeshData::FaceIndices& faces,
- MeshData::VertexContainer& out );
+ void OptimizeMesh( const Toolkit::AtlasManager::Mesh2D& in,
+ Toolkit::AtlasManager::Mesh2D& out );
void UploadImage( const BufferImage& image,
const AtlasSlotDescriptor& desc );
- void PrintMeshData( const MeshData& meshData );
+ void PrintMeshData( const Toolkit::AtlasManager::Mesh2D& mesh );
+
+ void OnUpload( Image image );
+
+ Shader mShaderL8;
+ Shader mShaderRgba;
- Toolkit::AtlasManager::AtlasSize mNewAtlasSize;
- Toolkit::AtlasManager::AddFailPolicy mAddFailPolicy;
- uint32_t mFilledPixel;
};
} // namespace Internal
void AtlasManager::GenerateMeshData( ImageId id,
const Vector2& position,
- Mesh2D& mesh )
- MeshData& meshData,
++ Mesh2D& mesh,
+ bool addReference )
{
GetImplementation(*this).GenerateMeshData( id,
position,
- mesh );
- meshData,
++ mesh,
+ addReference );
}
-void AtlasManager::StitchMesh( MeshData& first,
- const MeshData& second,
+void AtlasManager::StitchMesh( Mesh2D& first,
+ const Mesh2D& second,
bool optimize )
{
GetImplementation(*this).StitchMesh( first, second, optimize );
}
-void AtlasManager::StitchMesh( const MeshData& first,
- const MeshData& second,
- MeshData& out,
+void AtlasManager::StitchMesh( const Mesh2D& first,
+ const Mesh2D& second,
+ Mesh2D& out,
bool optimize )
{
GetImplementation(*this).StitchMesh( first, second, out, optimize );
void AtlasManager::GetMetrics( Metrics& metrics )
{
- return GetImplementation(*this).GetMetrics( metrics );
+ GetImplementation(*this).GetMetrics( metrics );
+}
+
+Material AtlasManager::GetMaterial( AtlasId atlas ) const
+{
+ return GetImplementation(*this).GetMaterial( atlas );
+}
+
+Sampler AtlasManager::GetSampler( AtlasId atlas ) const
+{
+ return GetImplementation(*this).GetSampler( atlas );
}
} // namespace Toolkit
// EXTERNAL INCLUDES
#include <stdint.h>
#include <dali/public-api/common/dali-vector.h>
-#include <dali/devel-api/geometry/mesh-data.h>
-#include <dali/devel-api/images/atlas.h>
#include <dali/public-api/images/buffer-image.h>
+#include <dali/devel-api/images/atlas.h>
+#include <dali/devel-api/rendering/material.h>
namespace Dali
{
Dali::Vector< AtlasMetricsEntry > mAtlasMetrics; // container of atlas information
};
+ struct Vertex2D
+ {
+ Vector2 mPosition;
+ Vector2 mTexCoords;
+ };
+
+ struct Mesh2D
+ {
+ Vector< Vertex2D > mVertices;
+ Vector< unsigned int> mIndices;
+ };
+
/**
* Create an AtlasManager handle; this can be initialised with AtlasManager::New()
* Calling member functions with an uninitialised handle is not allowed.
* @param[in] id Image Id returned in the AtlasSlot from the add operation
* @param[in] position position of the resulting mesh in model space
* @param[out] mesh Mesh Data Object to populate with mesh data
+ * @param[in] addReference Whether to increase the internal reference count for image or not
*/
void GenerateMeshData( ImageId id,
const Vector2& position,
- Mesh2D& mesh );
- MeshData& mesh,
++ Mesh2D& mesh,
+ bool addReference = true );
/**
* @brief Append second mesh to the first mesh
* @param[in] second Second mesh
* @param[in] optimize should we optimize vertex data
*/
- void StitchMesh( MeshData& first,
- const MeshData& second,
+ void StitchMesh( Mesh2D& first,
+ const Mesh2D& second,
bool optimize = false );
/**
* @param[in] optimize should we optimize vertex data
* @param[out] out resulting mesh
*/
- void StitchMesh( const MeshData& first,
- const MeshData& second,
- MeshData& out,
+ void StitchMesh( const Mesh2D& first,
+ const Mesh2D& second,
+ Mesh2D& out,
bool optimize = false );
/**
*/
void GetMetrics( Metrics& metrics );
+ /**
+ * @brief Get Material used by atlas
+ *
+ * @param atlas[in] atlas AtlasId
+ *
+ * @return Material used by atlas
+ */
+ Material GetMaterial( AtlasId atlas ) const;
+
+ /**
+ * @brief Get Sampler used by atlas
+ *
+ * @param atlas[in] atlas AtlasId
+ *
+ * @return Sampler used by atlas
+ */
+ Sampler GetSampler( AtlasId atlas ) const;
private:
explicit DALI_INTERNAL AtlasManager(Internal::AtlasManager *impl);
} // namespace Dali
-#endif // __DALI_TOOLKIT_ATLAS_MANAGER_H__
+#endif // __DALI_TOOLKIT_ATLAS_MANAGER_H__
// EXTERNAL INCLUDES
#include <dali/public-api/actors/layer.h>
-#include <dali/public-api/actors/renderable-actor.h>
+#include <dali/public-api/actors/image-actor.h>
#include <dali/integration-api/debug.h>
// INTERNAL INCLUDES
}
else
{
- DALI_ASSERT_ALWAYS( iter != alphaFunctionLut.end() && "Unknown Anchor Constant" );
+ DALI_ASSERT_ALWAYS( iter != alphaFunctionLut.end() && "Unknown Alpha Constant" );
return Dali::AlphaFunction::DEFAULT;
}
}
// to allow animating shader uniforms
if( propIndex == Property::INVALID_INDEX )
{
- RenderableActor renderable = RenderableActor::DownCast( targetHandle );
- if( renderable )
+ ImageActor imageActor = ImageActor::DownCast( targetHandle );
+ if( imageActor )
{
// A limitation here is that its possible that between creation of animation
// and running it the ShaderEffect of the actor has been changed.
// However this is a unlikely use case especially when using scripts.
- if( ShaderEffect effect = renderable.GetShaderEffect() )
+ if( ShaderEffect effect = imageActor.GetShaderEffect() )
{
propIndex = effect.GetPropertyIndex( *property );
if(propIndex != Property::INVALID_INDEX)
ret = std::string("Map Size=") + ToString( value.Get<Property::Map>().Count() );
break;
}
- case Property::TYPE_COUNT:
- {
- ret = "";
- break;
- }
}
return ret;
// special field 'effect' references the shader effect instances
if(key == "effect")
{
- RenderableActor actor = RenderableActor::DownCast(handle);
+ ImageActor actor = ImageActor::DownCast(handle);
if( actor )
{
OptionalString str = constant.IsString( keyChild.second );
if( Property::INVALID_INDEX == index )
{
- RenderableActor actor = RenderableActor::DownCast(handle);
+ ImageActor actor = ImageActor::DownCast(handle);
if( actor )
{
if( ShaderEffect effect = actor.GetShaderEffect() )
{
if( OptionalChild image = IsChild( *images, name ) )
{
- Dali::Property::Value propertyMap(Property::MAP);
- if( SetPropertyFromNode( *image, Property::MAP, propertyMap, constant ) )
+ Dali::Property::Value property(Property::MAP);
+ if( SetPropertyFromNode( *image, Property::MAP, property, constant ) )
{
- propertyMap.SetValue(KEYNAME_TYPE, Property::Value(std::string("FrameBufferImage")));
- ret = FrameBufferImage::DownCast( Dali::Scripting::NewImage( propertyMap ) );
+ Property::Map* map = property.GetMap();
+ (*map)[ KEYNAME_TYPE ] = Property::Value(std::string("FrameBufferImage") );
+ ret = FrameBufferImage::DownCast( Dali::Scripting::NewImage( property ) );
mFrameBufferImageLut[ name ] = ret;
}
}
#include <dali/public-api/common/stage.h>
#include <dali/public-api/render-tasks/render-task-list.h>
#include <dali/public-api/images/resource-image.h>
+ #include <dali/public-api/object/type-registry.h>
+ #include <dali/devel-api/object/type-registry-helper.h>
- using namespace Dali;
+ namespace Dali
+ {
+
+ namespace Toolkit
+ {
+
+ namespace Internal
+ {
namespace // unnamed namespace
{
+
+ Dali::BaseHandle Create()
+ {
+ return Toolkit::Magnifier::New();
+ }
+
+ DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Magnifier, Toolkit::Control, Create )
+
+ DALI_PROPERTY_REGISTRATION( Toolkit, Magnifier, "frame-visibility", BOOLEAN, FRAME_VISIBILITY )
+ DALI_PROPERTY_REGISTRATION( Toolkit, Magnifier, "magnification-factor", FLOAT, MAGNIFICATION_FACTOR )
+
+ DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, Magnifier, "source-position", VECTOR3, SOURCE_POSITION )
+
+ DALI_TYPE_REGISTRATION_END()
+
const char* DEFAULT_FRAME_IMAGE_PATH = DALI_IMAGE_DIR "magnifier-image-frame.png";
const float IMAGE_BORDER_INDENT = 14.0f; ///< Indent of border in pixels.
}
};
- }
-
- namespace Dali
- {
-
- namespace Toolkit
- {
-
- namespace Internal
- {
+ } // unnamed namespace
///////////////////////////////////////////////////////////////////////////////////////////////////
// Magnifier
Magnifier::Magnifier()
: Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ),
- mPropertySourcePosition(Property::INVALID_INDEX),
mDefaultCameraDistance(1000.f),
mActorSize(Vector3::ZERO),
mMagnificationFactor(1.0f)
mTask.SetSourceActor( actor );
}
- void Magnifier::SetSourcePosition(const Vector3& position)
- {
- Self().SetProperty(mPropertySourcePosition, position);
- }
-
void Magnifier::Initialize()
{
Actor self = Self();
- mPropertySourcePosition = self.RegisterProperty( Toolkit::Magnifier::SOURCE_POSITION_PROPERTY_NAME, Vector3::ZERO );
Vector2 stageSize(Stage::GetCurrent().GetSize());
// NOTE:
Stage().GetCurrent().Add(mSourceActor);
mSourceActor.SetParentOrigin(ParentOrigin::CENTER);
Constraint constraint = Constraint::New<Vector3>( mSourceActor, Actor::Property::POSITION, EqualToConstraint() );
- constraint.AddSource( Source( self, mPropertySourcePosition ) );
+ constraint.AddSource( Source( self, Toolkit::Magnifier::Property::SOURCE_POSITION ) );
constraint.Apply();
// create the render task this will render content on top of everything
Image image = ResourceImage::New( DEFAULT_FRAME_IMAGE_PATH );
mFrame = ImageActor::New( image );
- mFrame.SetDrawMode(DrawMode::OVERLAY);
mFrame.SetStyle( ImageActor::STYLE_NINE_PATCH );
mFrame.SetPositionInheritanceMode(DONT_INHERIT_POSITION);
mFrame.SetInheritScale(true);
mCameraActor.SetAspectRatio( worldSize.width / worldSize.height );
}
+ void Magnifier::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+ {
+ Toolkit::Magnifier magnifier = Toolkit::Magnifier::DownCast( Dali::BaseHandle( object ) );
+
+ if( magnifier )
+ {
+ Magnifier& magnifierImpl( GetImpl( magnifier ) );
+ switch( index )
+ {
+ case Toolkit::Magnifier::Property::FRAME_VISIBILITY:
+ {
+ magnifierImpl.SetFrameVisibility( value.Get< bool >() );
+ break;
+ }
+ case Toolkit::Magnifier::Property::MAGNIFICATION_FACTOR:
+ {
+ magnifierImpl.SetMagnificationFactor( value.Get< float >() );
+ break;
+ }
+ }
+ }
+ }
+
+ Property::Value Magnifier::GetProperty( BaseObject* object, Property::Index index )
+ {
+ Property::Value value;
+
+ Toolkit::Magnifier magnifier = Toolkit::Magnifier::DownCast( Dali::BaseHandle( object ) );
+
+ if( magnifier )
+ {
+ Magnifier& magnifierImpl( GetImpl( magnifier ) );
+ switch( index )
+ {
+ case Toolkit::Magnifier::Property::FRAME_VISIBILITY:
+ {
+ value = magnifierImpl.GetFrameVisibility();
+ break;
+ }
+ case Toolkit::Magnifier::Property::MAGNIFICATION_FACTOR:
+ {
+ value = magnifierImpl.GetMagnificationFactor();
+ break;
+ }
+ }
+ }
+
+ return value;
+ }
+
} // namespace Internal
} // namespace Toolkit
// EXTERNAL INCLUDES
#include <cstring> // for strcmp
- #include <dali/integration-api/debug.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/constraints.h>
+ #include <dali/public-api/images/resource-image.h>
#include <dali/public-api/object/type-registry.h>
+ #include <dali/public-api/object/property-array.h>
#include <dali/devel-api/object/type-registry-helper.h>
- #include <dali/public-api/images/resource-image.h>
+ #include <dali/integration-api/debug.h>
+
// INTERNAL INCLUDES
#include <dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h>
Actor self = Self();
self.Add(mIndicator);
- self.SetDrawMode(DrawMode::OVERLAY);
if( !mPanGestureDetector )
{
}
case Toolkit::ScrollBar::Property::SCROLL_POSITION_INTERVALS:
{
- Dali::Vector<float> positions;
- size_t positionCount = value.GetSize();
- positions.Resize( positionCount );
-
- for( size_t i = 0; i != positionCount; ++i )
+ Property::Array* array = value.GetArray();
+ if( array )
{
- value.GetItem(i).Get( positions[i] );
+ Dali::Vector<float> positions;
+ size_t positionCount = array->Count();
+ positions.Resize( positionCount );
+ for( size_t i = 0; i != positionCount; ++i )
+ {
+ array->GetElementAt( i ).Get( positions[i] );
+ }
+
+ scrollBarImpl.SetScrollPositionIntervals(positions);
}
-
- scrollBarImpl.SetScrollPositionIntervals(positions);
break;
}
}
}
case Toolkit::ScrollBar::Property::SCROLL_POSITION_INTERVALS:
{
- Property::Value value;
+ Property::Value value( Property::ARRAY );
+ Property::Array* array = value.GetArray();
Dali::Vector<float> positions = scrollBarImpl.GetScrollPositionIntervals();
- size_t positionCount( positions.Size() );
+ size_t positionCount( array->Count() );
for( size_t i( 0 ); i != positionCount; ++i )
{
- value.AppendItem( positions[i] );
+ array->PushBack( positions[i] );
}
break;
}
DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layout-orientation", INTEGER, LAYOUT_ORIENTATION)
DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scroll-content-size", FLOAT, SCROLL_CONTENT_SIZE)
+ DALI_SIGNAL_REGISTRATION( Toolkit, ItemView, "layout-activated", LAYOUT_ACTIVATED_SIGNAL )
+
DALI_TYPE_REGISTRATION_END()
const float DEFAULT_MINIMUM_SWIPE_SPEED = 1.0f;
mScrollAnimation.FinishedSignal().Connect(this, &ItemView::OnLayoutActivationScrollFinished);
mScrollAnimation.Play();
}
+ else
+ {
+ // Emit the layout activated signal
+ mLayoutActivatedSignal.Emit();
+ }
AnimateScrollOvershoot(0.0f);
mScrollOvershoot = 0.0f;
RemoveAnimation(mScrollAnimation);
mRefreshEnabled = true;
DoRefresh(GetCurrentLayoutPosition(0), true);
+
+ // Emit the layout activated signal
+ mLayoutActivatedSignal.Emit();
}
void ItemView::OnOvershootOnFinished(Animation& animation)
mOvershootOverlay.SetColor(mOvershootEffectColor);
mOvershootOverlay.SetParentOrigin(ParentOrigin::TOP_LEFT);
mOvershootOverlay.SetAnchorPoint(AnchorPoint::TOP_LEFT);
- mOvershootOverlay.SetDrawMode(DrawMode::OVERLAY);
self.Add(mOvershootOverlay);
Constraint constraint = Constraint::New<Vector3>( mOvershootOverlay, Actor::Property::SIZE, OvershootOverlaySizeConstraint );
DoRefresh(position, false); // No need to cache extra items.
}
+ bool ItemView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
+ {
+ Dali::BaseHandle handle( object );
+
+ bool connected( true );
+ Toolkit::ItemView itemView = Toolkit::ItemView::DownCast( handle );
+
+ if( 0 == strcmp( signalName.c_str(), LAYOUT_ACTIVATED_SIGNAL ) )
+ {
+ itemView.LayoutActivatedSignal().Connect( tracker, functor );
+ }
+ else
+ {
+ // signalName does not match any signal
+ connected = false;
+ }
+
+ return connected;
+ }
+
} // namespace Internal
} // namespace Toolkit
mHandleValueTextLabel.SetAnchorPoint( AnchorPoint::CENTER );
mHandleValueTextLabel.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
mHandleValueTextLabel.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
- mHandleValueTextLabel.SetDrawMode( DrawMode::OVERLAY );
mHandle.Add( mHandleValueTextLabel );
}
}
const float MARK_TOLERANCE = GetMarkTolerance();
float mark;
- for( std::size_t i = 0; i < mMarks.Size(); ++i)
+ for( MarkList::SizeType i = 0; i < mMarks.Count(); ++i)
{
const Property::Value& propertyValue = mMarks[i];
propertyValue.Get( mark );
float closestDist = std::numeric_limits<float>::max();
float mark;
- for( std::size_t i = 0; i < mMarks.Size(); ++i)
+ for( MarkList::SizeType i = 0; i < mMarks.Count(); ++i)
{
const Property::Value& propertyValue = mMarks[i];
propertyValue.Get( mark );
namespace
{
- const Scripting::StringEnum< Toolkit::Text::LayoutEngine::HorizontalAlignment > HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
+ const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
{
{ "BEGIN", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN },
{ "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
};
const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
- const Scripting::StringEnum< Toolkit::Text::LayoutEngine::VerticalAlignment > VERTICAL_ALIGNMENT_STRING_TABLE[] =
+ const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
{
{ "TOP", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP },
{ "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER },
const 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() );
- const LayoutEngine::HorizontalAlignment alignment = Scripting::GetEnumeration< LayoutEngine::HorizontalAlignment >( alignStr.c_str(),
- HORIZONTAL_ALIGNMENT_STRING_TABLE,
- HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
-
- impl.mController->SetHorizontalAlignment( alignment );
+ LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
+ if( Scripting::GetEnumeration< LayoutEngine::HorizontalAlignment >( alignStr.c_str(),
+ HORIZONTAL_ALIGNMENT_STRING_TABLE,
+ HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
+ alignment ) )
+ {
+ impl.mController->SetHorizontalAlignment( alignment );
+ }
}
break;
}
const 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::VerticalAlignment alignment = Scripting::GetEnumeration< LayoutEngine::VerticalAlignment >( alignStr.c_str(),
- VERTICAL_ALIGNMENT_STRING_TABLE,
- VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
-
- impl.mController->SetVerticalAlignment( alignment );
+ LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM );
+ if( Scripting::GetEnumeration< LayoutEngine::VerticalAlignment >( alignStr.c_str(),
+ VERTICAL_ALIGNMENT_STRING_TABLE,
+ VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
+ alignment ) )
+ {
+ impl.mController->SetVerticalAlignment( alignment );
+ }
}
break;
}
{
if( impl.mController )
{
- value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetLayoutEngine().GetHorizontalAlignment(),
- HORIZONTAL_ALIGNMENT_STRING_TABLE,
- HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT ) );
+ const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetLayoutEngine().GetHorizontalAlignment(),
+ HORIZONTAL_ALIGNMENT_STRING_TABLE,
+ HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+ if( name )
+ {
+ value = std::string( name );
+ }
}
break;
}
{
if( impl.mController )
{
- value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetLayoutEngine().GetVerticalAlignment(),
- VERTICAL_ALIGNMENT_STRING_TABLE,
- VERTICAL_ALIGNMENT_STRING_TABLE_COUNT ) );
+ const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetLayoutEngine().GetVerticalAlignment(),
+ VERTICAL_ALIGNMENT_STRING_TABLE,
+ VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
+ if( name )
+ {
+ value = std::string( name );
+ }
}
break;
}
mController = Text::Controller::New( *this );
- mDecorator = Text::Decorator::New( *this, *mController );
+ mDecorator = Text::Decorator::New( *mController,
+ *mController );
mController->GetLayoutEngine().SetLayout( LayoutEngine::SINGLE_LINE_BOX );
// 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 );
}
void TextField::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
}
- RenderableActor renderableActor;
- if( mRenderer )
- {
- renderableActor = mRenderer->Render( mController->GetView() );
- }
-
+ RenderText();
EnableClipping( (Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy), size );
+ }
+}
- if( renderableActor != mRenderableActor )
- {
- UnparentAndReset( mRenderableActor );
- mRenderableActor = renderableActor;
- }
+void TextField::RenderText()
+{
+ Actor renderableActor;
+ if( mRenderer )
+ {
+ renderableActor = mRenderer->Render( mController->GetView(), mDepth );
+ }
- if( mRenderableActor )
- {
- const Vector2 offset = mController->GetScrollPosition() + mController->GetAlignmentOffset();
+ if( renderableActor != mRenderableActor )
+ {
+ UnparentAndReset( mRenderableActor );
+ mRenderableActor = renderableActor;
+ }
- mRenderableActor.SetPosition( offset.x, offset.y );
+ if( mRenderableActor )
+ {
+ const Vector2 offset = mController->GetScrollPosition() + mController->GetAlignmentOffset();
- // Make sure the actor is parented correctly with/without clipping
- if( mClipper )
- {
- mClipper->GetRootActor().Add( mRenderableActor );
- }
- else
- {
- Self().Add( mRenderableActor );
- }
+ mRenderableActor.SetPosition( offset.x, offset.y );
+
+ // Make sure the actor is parented correctly with/without clipping
+ if( mClipper )
+ {
+ mClipper->GetRootActor().Add( mRenderableActor );
+ }
+ else
+ {
+ Self().Add( mRenderableActor );
}
+
+ for( std::vector<Actor>::const_iterator it = mClippingDecorationActors.begin(),
+ endIt = mClippingDecorationActors.end();
+ it != endIt;
+ ++it )
+ {
+ Actor actor = *it;
+
+ if( mClipper )
+ {
+ mClipper->GetRootActor().Add( actor );
+ }
+ else
+ {
+ Self().Add( actor );
+ }
+ }
+ mClippingDecorationActors.clear();
}
}
return mController->KeyEvent( event );
}
- ImfManager::ImfCallbackData TextField::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
+ void TextField::AddDecoration( Actor& actor, bool needsClipping )
{
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
- return mController->OnImfEvent( imfManager, imfEvent );
+ if( actor )
+ {
+ if( needsClipping )
+ {
+ mClippingDecorationActors.push_back( actor );
+ }
+ else
+ {
+ Self().Add( actor );
+ }
+ }
}
void TextField::RequestTextRelayout()
mTextChangedSignal.Emit( handle );
}
+void TextField::OnStageConnect( Dali::Actor actor )
+{
+ if ( mHasBeenStaged )
+ {
+ RenderText();
+ }
+ else
+ {
+ mHasBeenStaged = true;
+ }
+}
+
void TextField::MaxLengthReached()
{
Dali::Toolkit::TextField handle( GetOwner() );
mMaxLengthReachedSignal.Emit( handle );
}
+ ImfManager::ImfCallbackData TextField::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
+ return mController->OnImfEvent( imfManager, imfEvent );
+ }
+
void TextField::EnableClipping( bool clipping, const Vector2& size )
{
if( clipping )
}
}
+void TextField::OnStageConnection( unsigned int depth )
+{
+ mDepth = depth;
+}
+
bool TextField::OnTouched( Actor actor, const TouchEvent& event )
{
return true;
TextField::TextField()
: Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
- mExceedPolicy( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP )
+ mExceedPolicy( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP ),
+ mDepth( 0 ),
+ mHasBeenStaged( false )
{
}
virtual void OnPan( const PanGesture& gesture );
/**
+ * @copydoc Control::OnStageConnection()
+ */
+ virtual void OnStageConnection( unsigned int depth );
+
+ /**
* @copydoc Dali::CustomActorImpl::OnKeyEvent(const KeyEvent&)
*/
virtual bool OnKeyEvent(const KeyEvent& event);
/**
- * @copydoc Dali::Toolkit::Text::Controller::(ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent)
+ * @copydoc Text::ControlInterface::AddDecoration()
*/
- ImfManager::ImfCallbackData OnImfEvent( ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent );
+ virtual void AddDecoration( Actor& actor, bool needsClipping );
/**
* @copydoc Text::ControlInterface::RequestTextRelayout()
*/
virtual void MaxLengthReached();
+ /**
+ * @copydoc Dali::Toolkit::Text::Controller::(ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent)
+ */
+ ImfManager::ImfCallbackData OnImfEvent( ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent );
+
private: // Implementation
/**
TextField(const TextField&);
TextField& operator=(const TextField& rhs);
+ /**
+ * @brief Render view, create and attach actor(s) to this Text Field.
+ */
+ void RenderText();
+
+ // Connection needed to re-render text, when a Text Field returns to the stage.
+ void OnStageConnect( Dali::Actor actor );
+
private: // Data
// Signals
Text::RendererPtr mRenderer;
Text::DecoratorPtr mDecorator;
Text::ClipperPtr mClipper; ///< For EXCEED_POLICY_CLIP
+ std::vector<Actor> mClippingDecorationActors; ///< Decoration actors which need clipping.
- RenderableActor mRenderableActor;
+ Actor mRenderableActor;
int mRenderingBackend;
int mExceedPolicy;
+ unsigned int mDepth;
+ bool mHasBeenStaged:1;
};
} // namespace Internal
namespace
{
- const Scripting::StringEnum< Toolkit::Text::LayoutEngine::HorizontalAlignment > HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
+ const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
{
{ "BEGIN", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN },
{ "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
};
const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
- const Scripting::StringEnum< Toolkit::Text::LayoutEngine::VerticalAlignment > VERTICAL_ALIGNMENT_STRING_TABLE[] =
+ const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
{
{ "TOP", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP },
{ "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER },
{
if( impl.mController )
{
- 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 );
-
- impl.mController->SetHorizontalAlignment( alignment );
+ LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
+ if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( value.Get< std::string >().c_str(),
+ HORIZONTAL_ALIGNMENT_STRING_TABLE,
+ HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
+ alignment ) )
+ {
+ impl.mController->SetHorizontalAlignment( alignment );
+ }
}
break;
}
{
if( impl.mController )
{
- 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 );
-
- impl.mController->SetVerticalAlignment( alignment );
+ LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM );
+ if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( value.Get< std::string >().c_str(),
+ VERTICAL_ALIGNMENT_STRING_TABLE,
+ VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
+ alignment ) )
+ {
+ impl.mController->SetVerticalAlignment( alignment );
+ }
}
break;
}
{
if( impl.mController )
{
- value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetHorizontalAlignment(),
- HORIZONTAL_ALIGNMENT_STRING_TABLE,
- HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT ) );
+ const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetHorizontalAlignment(),
+ HORIZONTAL_ALIGNMENT_STRING_TABLE,
+ HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+ if( name )
+ {
+ value = std::string( name );
+ }
}
break;
}
{
if( impl.mController )
{
- value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetVerticalAlignment(),
- VERTICAL_ALIGNMENT_STRING_TABLE,
- VERTICAL_ALIGNMENT_STRING_TABLE_COUNT ) );
+ const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetVerticalAlignment(),
+ VERTICAL_ALIGNMENT_STRING_TABLE,
+ VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
+ if( name )
+ {
+ value = std::string( name );
+ }
}
break;
}
// Enable the text ellipsis.
LayoutEngine& engine = mController->GetLayoutEngine();
engine.SetTextEllipsisEnabled( true );
+ self.OnStageSignal().Connect( this, &TextLabel::OnStageConnect );
}
void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
{
mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
}
+ RenderText();
+ }
+}
- RenderableActor renderableActor;
- if( mRenderer )
- {
- renderableActor = mRenderer->Render( mController->GetView() );
- }
+void TextLabel::RequestTextRelayout()
+{
+ RelayoutRequest();
+}
- if( renderableActor != mRenderableActor )
- {
- UnparentAndReset( mRenderableActor );
+void TextLabel::RenderText()
+{
+ Actor renderableActor;
+ if( mRenderer )
+ {
+ renderableActor = mRenderer->Render( mController->GetView(), mDepth );
+ }
- if( renderableActor )
- {
- const Vector2& alignmentOffset = mController->GetAlignmentOffset();
- renderableActor.SetPosition( alignmentOffset.x, alignmentOffset.y );
+ if( renderableActor != mRenderableActor )
+ {
+ UnparentAndReset( mRenderableActor );
- Self().Add( renderableActor );
- }
+ if( renderableActor )
+ {
+ const Vector2& alignmentOffset = mController->GetAlignmentOffset();
+ renderableActor.SetPosition( alignmentOffset.x, alignmentOffset.y );
- mRenderableActor = renderableActor;
+ Self().Add( renderableActor );
}
+ mRenderableActor = renderableActor;
+ }
+}
+
+void TextLabel::OnStageConnect( Dali::Actor actor )
+{
+ if ( mHasBeenStaged )
+ {
+ RenderText();
+ }
+ else
+ {
+ mHasBeenStaged = true;
}
}
-void TextLabel::RequestTextRelayout()
+ void TextLabel::AddDecoration( Actor& actor, bool needsClipping )
+ {
+ // TextLabel does not show decorations
+ }
+
+void TextLabel::OnStageConnection( unsigned int depth )
{
- RelayoutRequest();
+ mDepth = depth;
}
void TextLabel::TextChanged()
TextLabel::TextLabel()
: Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
- mRenderingBackend( DEFAULT_RENDERING_BACKEND )
+ mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
+ mDepth( 0 ),
+ mHasBeenStaged( false )
{
}
virtual float GetHeightForWidth( float width );
/**
+ * @copydoc Text::ControlInterface::AddDecoration()
+ */
+ virtual void AddDecoration( Actor& actor, bool needsClipping );
+
+ /**
+ * @copydoc Control::OnStageConnection()
+ */
+ virtual void OnStageConnection( unsigned int depth );
+
+ /**
* @copydoc Text::ControlInterface::RequestTextRelayout()
*/
virtual void RequestTextRelayout();
TextLabel(const TextLabel&);
TextLabel& operator=(const TextLabel& rhs);
+ // Connection needed to re-render text, when a Text Label returns to the stage
+ void OnStageConnect( Dali::Actor actor );
+
+ /**
+ * @brief Render view, create and attach actor(s) to this Text Label
+ */
+ void RenderText();
+
private: // Data
Text::ControllerPtr mController;
Text::RendererPtr mRenderer;
- RenderableActor mRenderableActor;
-
+ Actor mRenderableActor;
int mRenderingBackend;
+ unsigned int mDepth;
+ bool mHasBeenStaged:1;
};
} // namespace Internal
#include <dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.h>
// INTERNAL INCLUDES
- #include <dali-toolkit/public-api/controls/buttons/push-button.h>
+ #include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup-callback-interface.h>
+#include <dali-toolkit/public-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
#include <dali-toolkit/public-api/controls/text-controls/text-label.h>
#include <dali/public-api/images/resource-image.h>
#include <dali/public-api/math/vector2.h>
#include <dali/public-api/math/vector4.h>
+ #include <dali/devel-api/object/type-registry-helper.h>
#include <libintl.h>
#include <cfloat>
- // todo Move this to adaptor??
- #define GET_LOCALE_TEXT(string) dgettext("elementary", string)
-
namespace Dali
{
namespace
{
- const Dali::Vector4 DEFAULT_POPUP_BACKGROUND( Dali::Vector4( .20f, 0.29f, 0.44f, 1.0f ) );
- const Dali::Vector4 DEFAULT_POPUP_BACKGROUND_PRESSED( Dali::Vector4( 0.07f, 0.10f, 0.17f, 1.0f ) );
- const Dali::Vector4 DEFAULT_POPUP_LINE_COLOR( Dali::Vector4( 0.36f, 0.45f, 0.59f, 1.0f ) );
+ // todo Move this to adaptor??
+ #define GET_LOCALE_TEXT(string) dgettext("elementary", string)
+
+ const Dali::Vector4 DEFAULT_POPUP_LINE_COLOR( Dali::Vector4( 0.69f, 0.93f, 0.93f, 1.0f ) );
const Dali::Vector4 DEFAULT_OPTION_ICON( Dali::Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
- const Dali::Vector4 DEFAULT_OPTION_ICON_PRESSED( Dali::Vector4( 0.5f, 1.0f, 1.0f, 1.0f ) );
- const Dali::Vector4 DEFAULT_OPTION_TEXT( Dali::Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
- const Dali::Vector4 DEFAULT_OPTION_TEXT_PRESSED( Dali::Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
+ const Dali::Vector4 DEFAULT_OPTION_ICON_PRESSED( Dali::Vector4( 0.12f, 0.56f, 1.0f, 1.0f ) );
- const std::string DEFAULT_POPUP_BACKGROUND_IMAGE( DALI_IMAGE_DIR "popup_bubble_bg.#.png" );
+ const std::string DEFAULT_POPUP_BACKGROUND_IMAGE( DALI_IMAGE_DIR "selection-popup-bg#.png" );
const std::string OPTION_ICON_CLIPBOARD( DALI_IMAGE_DIR "copy_paste_icon_clipboard.png" );
const std::string OPTION_ICON_COPY( DALI_IMAGE_DIR "copy_paste_icon_copy.png" );
const std::string OPTION_ICON_CUT( DALI_IMAGE_DIR "copy_paste_icon_cut.png" );
const std::string OPTION_ICON_SELECT( DALI_IMAGE_DIR "copy_paste_icon_select.png" );
const std::string OPTION_ICON_SELECT_ALL( DALI_IMAGE_DIR "copy_paste_icon_select_all.png" );
- const Dali::Vector2 DEFAULT_POPUP_MAX_SIZE( 450.0f, 100.0f ); ///< The maximum size of the popup.
-
- const Dali::Vector2 OPTION_ICON_SIZE( 65.0f, 65.0f ); ///< The size of the icon.
const float OPTION_MARGIN_WIDTH( 10.f ); ///< The margin between the right or lefts edge and the text or icon.
- const float OPTION_MAX_WIDTH( 110.0f ); ///< The maximum width of the option //todo Make Property
- const float OPTION_MIN_WIDTH( 86.0f ); ///< The minimum width of the option. //todo Make Property
- const float POPUP_DIVIDER_WIDTH( 3.f ); ///< The size of the divider.
- const Dali::Vector2 POPUP_TAIL_SIZE( 20.0f, 16.0f ); ///< The size of the tail.
- const float POPUP_TAIL_Y_OFFSET( 5.f ); ///< The y offset of the tail (when its position is on the bottom).
- const float POPUP_TAIL_TOP_Y_OFFSET( 3.f ); ///< The y offset of the tail (when its position is on the top).
+ #ifdef DGETTEXT_ENABLED
+
+ #define POPUP_CUT_STRING GET_LOCALE_TEXT("IDS_COM_BODY_CUT")
+ #define POPUP_COPY_STRING GET_LOCALE_TEXT("IDS_COM_BODY_COPY")
+ #define POPUP_PASTE_STRING GET_LOCALE_TEXT("IDS_COM_BODY_PASTE")
+ #define POPUP_SELECT_STRING GET_LOCALE_TEXT("IDS_COM_SK_SELECT")
+ #define POPUP_SELECT_ALL_STRING GET_LOCALE_TEXT("IDS_COM_BODY_SELECT_ALL")
+ #define POPUP_CLIPBOARD_STRING GET_LOCALE_TEXT("IDS_COM_BODY_CLIPBOARD")
+
+ #else
- const float HIDE_POPUP_ANIMATION_DURATION( 0.2f ); ///< Duration of popup hide animation in seconds.
- const float SHOW_POPUP_ANIMATION_DURATION( 0.2f ); ///< Duration of popup show animation in seconds.
+ #define POPUP_CUT_STRING "Cut"
+ #define POPUP_COPY_STRING "Copy"
+ #define POPUP_PASTE_STRING "Paste"
+ #define POPUP_SELECT_STRING "Select"
+ #define POPUP_SELECT_ALL_STRING "Select All"
+ #define POPUP_CLIPBOARD_STRING "Clipboard"
+
+ #endif
const char* const OPTION_SELECT_WORD = "option-select_word"; // "Select Word" popup option.
const char* const OPTION_SELECT_ALL("option-select_all"); // "Select All" popup option.
const char* const OPTION_PASTE("option-paste"); // "Paste" popup option.
const char* const OPTION_CLIPBOARD("option-clipboard"); // "Clipboard" popup option.
- } // namespace
+ BaseHandle Create()
+ {
+ return Toolkit::TextSelectionPopup::New( Toolkit::TextSelectionPopup::NONE, NULL );
+ }
+
+ // Setup properties, signals and actions using the type-registry.
+
+ DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextSelectionPopup, Toolkit::Control, Create );
- //// Comparison function for ButtonRequirement Priority
- //bool TextSelectionPopup::PriorityCompare( ButtonRequirement const& a, ButtonRequirement const& b )
- //{
- // return a.priority < b.priority;
- //}
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-max-size", VECTOR2, POPUP_MAX_SIZE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-min-size", VECTOR2, POPUP_MIN_SIZE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "option-max-size", VECTOR2, OPTION_MAX_SIZE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "option-min-size", VECTOR2, OPTION_MIN_SIZE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "option-divider-size", VECTOR2, OPTION_DIVIDER_SIZE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-clipboard-button-image", STRING, POPUP_CLIPBOARD_BUTTON_ICON_IMAGE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-cut-button-image", STRING, POPUP_CUT_BUTTON_ICON_IMAGE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-copy-button-image", STRING, POPUP_COPY_BUTTON_ICON_IMAGE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-paste-button-image", STRING, POPUP_PASTE_BUTTON_ICON_IMAGE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-select-button-image", STRING, POPUP_SELECT_BUTTON_ICON_IMAGE )
+ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-select-all-button-image", STRING, POPUP_SELECT_ALL_BUTTON_ICON_IMAGE )
+ DALI_TYPE_REGISTRATION_END()
- Dali::Toolkit::TextSelectionPopup TextSelectionPopup::New()
+ } // namespace
+
+
+ Dali::Toolkit::TextSelectionPopup TextSelectionPopup::New( Toolkit::TextSelectionPopup::Buttons buttonsToEnable,
+ TextSelectionPopupCallbackInterface* callbackInterface )
{
- // Create the implementation, temporarily owned by this handle on stack
- IntrusivePtr< TextSelectionPopup > impl = new TextSelectionPopup();
+ // Create the implementation, temporarily owned by this handle on stack
+ IntrusivePtr< TextSelectionPopup > impl = new TextSelectionPopup( callbackInterface );
// Pass ownership to CustomActor handle
Dali::Toolkit::TextSelectionPopup handle( *impl );
+ impl->mEnabledButtons = buttonsToEnable;
+
// Second-phase init of the implementation
// This can only be done after the CustomActor connection has been made...
impl->Initialize();
{
case Toolkit::TextSelectionPopup::Property::POPUP_MAX_SIZE:
{
- impl.SetPopupMaxSize( value.Get< Vector2 >() );
+ impl.SetDimensionToCustomise( POPUP_MAXIMUM_SIZE, value.Get< Vector2 >() );
break;
}
- case Toolkit::TextSelectionPopup::Property::POPUP_BACKGROUND_IMAGE:
+ case Toolkit::TextSelectionPopup::Property::POPUP_MIN_SIZE:
{
- ResourceImage image = ResourceImage::New( value.Get< std::string >() );
- impl.SetPopupImage( POPUP_BACKGROUND, image );
+ impl.SetDimensionToCustomise( POPUP_MINIMUM_SIZE, value.Get< Vector2 >() );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::OPTION_MAX_SIZE:
+ {
+ impl.SetDimensionToCustomise( OPTION_MAXIMUM_SIZE, value.Get< Vector2 >() );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::OPTION_MIN_SIZE:
+ {
+ impl.SetDimensionToCustomise( OPTION_MINIMUM_SIZE, value.Get< Vector2>() );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::OPTION_DIVIDER_SIZE:
+ {
+ impl.SetDimensionToCustomise( OPTION_DIVIDER_SIZE, value.Get< Vector2>() );
break;
}
case Toolkit::TextSelectionPopup::Property::POPUP_CLIPBOARD_BUTTON_ICON_IMAGE:
{
ResourceImage image = ResourceImage::New( value.Get< std::string >() );
- impl.SetPopupImage( POPUP_CLIPBOARD_BUTTON, image );
+ impl.SetButtonImage( Toolkit::TextSelectionPopup::CLIPBOARD, image );
break;
}
case Toolkit::TextSelectionPopup::Property::POPUP_CUT_BUTTON_ICON_IMAGE:
{
ResourceImage image = ResourceImage::New( value.Get< std::string >() );
- impl.SetPopupImage( POPUP_CUT_BUTTON_ICON, image );
+ impl.SetButtonImage( Toolkit::TextSelectionPopup::CUT, image );
break;
}
case Toolkit::TextSelectionPopup::Property::POPUP_COPY_BUTTON_ICON_IMAGE:
{
ResourceImage image = ResourceImage::New( value.Get< std::string >() );
- impl.SetPopupImage( POPUP_COPY_BUTTON_ICON, image );
+ impl.SetButtonImage( Toolkit::TextSelectionPopup::COPY, image );
break;
}
case Toolkit::TextSelectionPopup::Property::POPUP_PASTE_BUTTON_ICON_IMAGE:
{
ResourceImage image = ResourceImage::New( value.Get< std::string >() );
- impl.SetPopupImage( POPUP_PASTE_BUTTON_ICON, image );
+ impl.SetButtonImage( Toolkit::TextSelectionPopup::PASTE, image );
break;
}
case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_BUTTON_ICON_IMAGE:
{
ResourceImage image = ResourceImage::New( value.Get< std::string >() );
- impl.SetPopupImage( POPUP_SELECT_BUTTON_ICON, image );
+ impl.SetButtonImage( Toolkit::TextSelectionPopup::SELECT, image );
break;
}
case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_ALL_BUTTON_ICON_IMAGE:
{
ResourceImage image = ResourceImage::New( value.Get< std::string >() );
- impl.SetPopupImage( POPUP_SELECT_ALL_BUTTON_ICON, image );
+ impl.SetButtonImage( Toolkit::TextSelectionPopup::SELECT_ALL, image );
break;
}
} // switch
{
case Toolkit::TextSelectionPopup::Property::POPUP_MAX_SIZE:
{
- value = impl.GetPopupMaxSize();
+ value = impl.GetDimensionToCustomise( POPUP_MAXIMUM_SIZE );
break;
}
- case Toolkit::TextSelectionPopup::Property::POPUP_BACKGROUND_IMAGE:
+ case Toolkit::TextSelectionPopup::Property::OPTION_MAX_SIZE:
{
- ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_BACKGROUND ) );
- if( image )
- {
- value = image.GetUrl();
- }
+ value = impl.GetDimensionToCustomise( OPTION_MAXIMUM_SIZE );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::OPTION_MIN_SIZE:
+ {
+ value = impl.GetDimensionToCustomise( OPTION_MINIMUM_SIZE );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::Property::OPTION_DIVIDER_SIZE:
+ {
+ value = impl.GetDimensionToCustomise( OPTION_DIVIDER_SIZE );
break;
}
case Toolkit::TextSelectionPopup::Property::POPUP_CLIPBOARD_BUTTON_ICON_IMAGE:
{
- ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_CLIPBOARD_BUTTON ) );
+ ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::CLIPBOARD ) );
if( image )
{
value = image.GetUrl();
}
case Toolkit::TextSelectionPopup::Property::POPUP_CUT_BUTTON_ICON_IMAGE:
{
- ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_CUT_BUTTON_ICON ) );
+ ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::CUT ) );
if( image )
{
value = image.GetUrl();
}
case Toolkit::TextSelectionPopup::Property::POPUP_COPY_BUTTON_ICON_IMAGE:
{
- ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_COPY_BUTTON_ICON ) );
+ ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::COPY ) );
if( image )
{
value = image.GetUrl();
}
case Toolkit::TextSelectionPopup::Property::POPUP_PASTE_BUTTON_ICON_IMAGE:
{
- ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_PASTE_BUTTON_ICON ) );
+ ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::PASTE ) );
if( image )
{
value = image.GetUrl();
}
case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_BUTTON_ICON_IMAGE:
{
- ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_SELECT_BUTTON_ICON ) );
+ ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::SELECT ) );
if( image )
{
value = image.GetUrl();
}
case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_ALL_BUTTON_ICON_IMAGE:
{
- ResourceImage image = ResourceImage::DownCast( impl.GetPopupImage( POPUP_SELECT_ALL_BUTTON_ICON ) );
+ ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::SELECT_ALL ) );
if( image )
{
value = image.GetUrl();
CreatePopup();
}
- void TextSelectionPopup::OnRelayout( const Vector2& size, RelayoutContainer& container )
+ bool TextSelectionPopup::OnCutButtonPressed( Toolkit::Button button )
{
+ if( mCallbackInterface )
+ {
+ mCallbackInterface->TextPopupButtonTouched( Toolkit::TextSelectionPopup::CUT );
+ }
+ return true;
}
- void TextSelectionPopup::SetPopupMaxSize( const Size& maxSize )
+ bool TextSelectionPopup::OnCopyButtonPressed( Toolkit::Button button )
{
- mMaxSize = maxSize;
+ if( mCallbackInterface )
+ {
+ mCallbackInterface->TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::COPY );
+ }
+
+ return true;
}
- const Dali::Vector2& TextSelectionPopup::GetPopupMaxSize() const
+ bool TextSelectionPopup::OnPasteButtonPressed( Toolkit::Button button )
{
- return mMaxSize;
+ if( mCallbackInterface )
+ {
+ mCallbackInterface->TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::PASTE );
+ }
+
+ return true;
}
- void TextSelectionPopup::SetPopupImage( PopupParts part, Dali::Image image )
+ bool TextSelectionPopup::OnSelectButtonPressed( Toolkit::Button button )
{
- switch ( part )
- {
- case POPUP_BACKGROUND :
+ if( mCallbackInterface )
+ {
+ mCallbackInterface->TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::SELECT );
+ }
+
+ return true;
+ }
+
+ bool TextSelectionPopup::OnSelectAllButtonPressed( Toolkit::Button button )
+ {
+ if( mCallbackInterface )
+ {
+ mCallbackInterface->TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::SELECT_ALL );
+ }
+
+ return true;
+ }
+
+ bool TextSelectionPopup::OnClipboardButtonPressed( Toolkit::Button button )
+ {
+ if( mCallbackInterface )
+ {
+ mCallbackInterface->TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::CLIPBOARD );
+ }
+
+ return true;
+ }
+
+ void TextSelectionPopup::SetDimensionToCustomise( const PopupCustomisations& settingToCustomise, const Size& dimension )
+ {
+ switch( settingToCustomise )
+ {
+ case POPUP_MAXIMUM_SIZE :
+ {
+ Actor self = Self();
+ mMaxSize = dimension;
+ if ( mToolbar )
+ {
+ mToolbar.SetProperty( Toolkit::TextSelectionToolbar::Property::MAX_SIZE, mMaxSize );
+ }
+ break;
+ }
+ case POPUP_MINIMUM_SIZE :
+ {
+ Actor self = Self();
+ mMinSize = dimension;
+ // Option can not be smaller than this if only one.
+ break;
+ }
+ case OPTION_MAXIMUM_SIZE :
+ {
+ mOptionMaxSize = dimension;
+ // Option max size not currently currently supported
+
+ break;
+ }
+ case OPTION_MINIMUM_SIZE :
+ {
+ mOptionMinSize = dimension;
+ // Option min size not currently currently supported
+ break;
+ }
+ case OPTION_DIVIDER_SIZE :
+ {
+ mOptionDividerSize = dimension;
+ if ( mToolbar )
+ {
+ // Resize Dividers not currently supported
+ }
+ break;
+ }
+ } // switch
+ }
+
+ Size TextSelectionPopup::GetDimensionToCustomise( const PopupCustomisations& settingToCustomise )
+ {
+ switch( settingToCustomise )
+ {
+ case POPUP_MAXIMUM_SIZE :
+ {
+ return mMaxSize;
+ }
+ case POPUP_MINIMUM_SIZE :
+ {
+ return mMinSize;
+ }
+ case OPTION_MAXIMUM_SIZE :
+ {
+ return mOptionMaxSize;
+ }
+ case OPTION_MINIMUM_SIZE :
+ {
+ return mOptionMinSize;
+ }
+ case OPTION_DIVIDER_SIZE :
+ {
+ return mOptionDividerSize;
+ }
+ } // switch
+
+ return Size::ZERO;
+ }
+
+ void TextSelectionPopup::SetButtonImage( Toolkit::TextSelectionPopup::Buttons button, Dali::Image image )
+ {
+ switch ( button )
{
- mBackgroundImage = image;
- }
break;
- case POPUP_CLIPBOARD_BUTTON :
+ case Toolkit::TextSelectionPopup::CLIPBOARD:
{
mClipboardIconImage = image;
}
break;
- case POPUP_CUT_BUTTON_ICON :
+ case Toolkit::TextSelectionPopup::CUT :
{
mCutIconImage = image;
}
break;
- case POPUP_COPY_BUTTON_ICON :
+ case Toolkit::TextSelectionPopup::COPY :
{
mCopyIconImage = image;
}
break;
- case POPUP_PASTE_BUTTON_ICON :
+ case Toolkit::TextSelectionPopup::PASTE :
{
mPasteIconImage = image;
}
break;
- case POPUP_SELECT_BUTTON_ICON :
+ case Toolkit::TextSelectionPopup::SELECT :
{
mSelectIconImage = image;
}
break;
- case POPUP_SELECT_ALL_BUTTON_ICON :
+ case Toolkit::TextSelectionPopup::SELECT_ALL :
{
mSelectAllIconImage = image;
}
break;
-
+ default :
+ {
+ DALI_ASSERT_DEBUG( "TextSelectionPopup SetPopupImage Unknown Button" );
+ }
} // switch
}
- Dali::Image TextSelectionPopup::GetPopupImage( PopupParts part )
+ Dali::Image TextSelectionPopup::GetButtonImage( Toolkit::TextSelectionPopup::Buttons button )
{
- switch ( part )
+ switch ( button )
{
- case POPUP_BACKGROUND :
- {
- return mBackgroundImage;
- }
- break;
- case POPUP_CLIPBOARD_BUTTON :
+ case Toolkit::TextSelectionPopup::CLIPBOARD :
{
return mClipboardIconImage;
}
break;
- case POPUP_CUT_BUTTON_ICON :
+ case Toolkit::TextSelectionPopup::CUT :
{
return mCutIconImage;
}
break;
- case POPUP_COPY_BUTTON_ICON :
+ case Toolkit::TextSelectionPopup::COPY :
{
return mCopyIconImage;
}
break;
- case POPUP_PASTE_BUTTON_ICON :
+ case Toolkit::TextSelectionPopup::PASTE :
{
return mPasteIconImage;
}
break;
- case POPUP_SELECT_BUTTON_ICON :
+ case Toolkit::TextSelectionPopup::SELECT :
{
return mSelectIconImage;
}
break;
- case POPUP_SELECT_ALL_BUTTON_ICON :
+ case Toolkit::TextSelectionPopup::SELECT_ALL :
{
return mSelectAllIconImage;
}
break;
default :
{
- DALI_ASSERT_DEBUG( "Unknown Popup Part" );
+ DALI_ASSERT_DEBUG( "TextSelectionPopup GetPopupImage Unknown Button" );
}
} // switch
{
mCutIconImage = ResourceImage::New( OPTION_ICON_CUT );
}
- mOrderListOfButtons.push_back( ButtonRequirement( ButtonsCut, mCutOptionPriority, OPTION_CUT, GET_LOCALE_TEXT("IDS_COM_BODY_CUT"), mCutIconImage, true ) );
+ mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::CUT, mCutOptionPriority, OPTION_CUT, POPUP_CUT_STRING , mCutIconImage, ( mEnabledButtons & Toolkit::TextSelectionPopup::CUT) ) );
if ( !mCopyIconImage )
{
mCopyIconImage = ResourceImage::New( OPTION_ICON_COPY );
}
- mOrderListOfButtons.push_back( ButtonRequirement( ButtonsCopy, mCopyOptionPriority, OPTION_COPY, GET_LOCALE_TEXT("IDS_COM_BODY_COPY"), mCopyIconImage, true ) );
+ mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::COPY, mCopyOptionPriority, OPTION_COPY, POPUP_COPY_STRING, mCopyIconImage, ( mEnabledButtons & Toolkit::TextSelectionPopup::COPY) ) );
if ( !mPasteIconImage )
{
mPasteIconImage = ResourceImage::New( OPTION_ICON_PASTE );
}
- mOrderListOfButtons.push_back( ButtonRequirement( ButtonsPaste, mPasteOptionPriority, OPTION_PASTE, GET_LOCALE_TEXT("IDS_COM_BODY_PASTE"), mPasteIconImage, true ) );
+ mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::PASTE, mPasteOptionPriority, OPTION_PASTE, POPUP_PASTE_STRING, mPasteIconImage, ( mEnabledButtons & Toolkit::TextSelectionPopup::PASTE) ) );
if ( !mSelectIconImage )
mSelectIconImage = ResourceImage::New( OPTION_ICON_SELECT );
- mOrderListOfButtons.push_back( ButtonRequirement( ButtonsSelect, mSelectOptionPriority, OPTION_SELECT_WORD, GET_LOCALE_TEXT("IDS_COM_SK_SELECT"), mSelectIconImage, true ) );
+ mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::SELECT, mSelectOptionPriority, OPTION_SELECT_WORD, POPUP_SELECT_STRING, mSelectIconImage, ( mEnabledButtons & Toolkit::TextSelectionPopup::SELECT) ) );
if ( !mSelectAllIconImage )
{
mSelectAllIconImage = ResourceImage::New( OPTION_ICON_SELECT_ALL );
}
- mOrderListOfButtons.push_back( ButtonRequirement( ButtonsSelectAll, mSelectAllOptionPriority, OPTION_SELECT_ALL, GET_LOCALE_TEXT("IDS_COM_BODY_SELECT_ALL"), mSelectAllIconImage, true ) );
+ mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::SELECT_ALL, mSelectAllOptionPriority, OPTION_SELECT_ALL, POPUP_SELECT_ALL_STRING, mSelectAllIconImage, ( mEnabledButtons & Toolkit::TextSelectionPopup::SELECT_ALL) ) );
if ( !mClipboardIconImage )
{
mClipboardIconImage = ResourceImage::New( OPTION_ICON_CLIPBOARD );
}
- mOrderListOfButtons.push_back( ButtonRequirement( ButtonsClipboard, mClipboardOptionPriority, OPTION_CLIPBOARD, GET_LOCALE_TEXT("IDS_COM_BODY_CLIPBOARD"), mClipboardIconImage, true ) );
+ mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::CLIPBOARD, mClipboardOptionPriority, OPTION_CLIPBOARD, POPUP_CLIPBOARD_STRING, mClipboardIconImage, ( mEnabledButtons & Toolkit::TextSelectionPopup::CLIPBOARD) ) );
// Sort the buttons according their priorities.
std::sort( mOrderListOfButtons.begin(), mOrderListOfButtons.end(), TextSelectionPopup::ButtonPriorityCompare() );
}
- void TextSelectionPopup::CreateBackground()
+ void TextSelectionPopup::AddOption( const ButtonRequirement& button, bool showDivider, bool showIcons, bool showCaption )
{
- if ( mBackgroundImage )
- {
- SetBackgroundImage ( mBackgroundImage );
- }
- SetBackgroundColor( mBackgroundColor );
- }
+ const std::string& name = button.name;
+ const std::string& caption = button.caption;
+ Image iconImage = button.icon;
- void TextSelectionPopup::AddOption( Dali::Toolkit::TableView& parent, const std::string& name, const std::string& caption, const Image iconImage, bool finalOption, bool showIcons, bool showCaption, std::size_t& indexInTable )
- {
// 1. Create the backgrounds for the popup option both normal and pressed.
// Both containers will be added to a button.
- Toolkit::TableView optionContainer = Toolkit::TableView::New( (showIcons)?2:1 , 1 );
- optionContainer.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
- optionContainer.SetMinimumSize( Vector2( OPTION_MIN_WIDTH, 0 ) );
+ Toolkit::TableView optionContainer = Toolkit::TableView::New( (showIcons&showCaption)?2:1 , 1 );
- optionContainer.SetDrawMode( DrawMode::OVERLAY );
+ optionContainer.SetFitHeight( 0 );
optionContainer.SetFitWidth( 0 );
- Toolkit::TableView optionPressedContainer = Toolkit::TableView::New( (showIcons)?2:1 , 1 );
- optionPressedContainer.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
- optionPressedContainer.SetMinimumSize( Vector2( OPTION_MIN_WIDTH, 0 ) );
+ Toolkit::TableView optionPressedContainer = Toolkit::TableView::New( (showIcons&showCaption)?2:1 , 1 );
- optionPressedContainer.SetDrawMode( DrawMode::OVERLAY );
+ optionPressedContainer.SetFitHeight( 0 );
optionPressedContainer.SetFitWidth( 0 );
+ optionPressedContainer.SetBackgroundColor( mPressedColor );
+
#ifdef DECORATOR_DEBUG
optionContainer.SetName("optionContainer");
optionPressedContainer.SetName("optionPressedContainer");
if ( showCaption )
{
- Toolkit::TextLabel captionTextLabel = Toolkit::TextLabel::New();
- captionTextLabel.SetProperty( Toolkit::TextLabel::Property::TEXT, caption );
- optionContainer.SetFitHeight( 0 );
-
- Toolkit::TextLabel pressedCaptionTextLabel = Toolkit::TextLabel::New();
- pressedCaptionTextLabel.SetProperty( Toolkit::TextLabel::Property::TEXT, caption );
- optionPressedContainer.SetFitHeight( 0 );
-
- captionTextLabel.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::WIDTH );
- captionTextLabel.SetMaximumSize( Vector2( OPTION_MAX_WIDTH - 2.f * OPTION_MARGIN_WIDTH , FLT_MAX ) ); //todo FLT_MAX Size negotiation feature needed
-
- pressedCaptionTextLabel.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::WIDTH );
- pressedCaptionTextLabel.SetMaximumSize( Vector2( OPTION_MAX_WIDTH - 2.f * OPTION_MARGIN_WIDTH , FLT_MAX) ); //todo FLT_MAX Size negotiation feature needed
-
- optionContainer.AddChild( captionTextLabel, Toolkit::TableView::CellPosition( 1, 0 ) ); // todo Labels need ellipsis or similar
- optionPressedContainer.AddChild( pressedCaptionTextLabel, Toolkit::TableView::CellPosition( 1, 0 ) ); // todo Labels need ellipsis or similar
+ Toolkit::TextLabel captionTextLabel = Toolkit::TextLabel::New();
+ captionTextLabel.SetProperty( Toolkit::TextLabel::Property::TEXT, caption );
+ captionTextLabel.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
+
+ Toolkit::TextLabel pressedCaptionTextLabel = Toolkit::TextLabel::New();
+ pressedCaptionTextLabel.SetProperty( Toolkit::TextLabel::Property::TEXT, caption );
+ pressedCaptionTextLabel.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
+
+ Padding padding;
+ padding.left = 24.0f;
+ padding.right = 24.0f;
+ padding.top = 14.0f;
+ padding.bottom = 14.0f;
+ captionTextLabel.SetPadding( padding );
+ pressedCaptionTextLabel.SetPadding( padding );
+
+ optionContainer.AddChild( captionTextLabel, Toolkit::TableView::CellPosition(( showIcons&showCaption)?1:0, 0 ) );
+ optionPressedContainer.AddChild( pressedCaptionTextLabel, Toolkit::TableView::CellPosition(( showIcons&showCaption)?1:0, 0 ) );
}
+ // 3. Create the icons
if ( showIcons )
{
- // 3. Create the icons
ImageActor pressedIcon = ImageActor::New( iconImage );
ImageActor icon = ImageActor::New( iconImage );
- icon.SetName("image-icon-2014");
+ icon.SetSortModifier( DECORATION_DEPTH_INDEX - 1 );
+ pressedIcon.SetSortModifier( DECORATION_DEPTH_INDEX - 1 );
+
icon.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
pressedIcon.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
- pressedIcon.SetColor( mIconPressedColor );
- optionContainer.SetFitHeight( 0 );
- optionPressedContainer.SetFitHeight( 0 );
+ icon.SetColor( mIconColor );
+
+ if ( showCaption & showIcons )
+ {
+ optionContainer.SetFitHeight( 1 );
+ optionContainer.SetFitWidth( 1 );
+ optionPressedContainer.SetFitHeight( 1 );
+ optionPressedContainer.SetFitWidth( 1 );
+ }
+
optionContainer.AddChild( icon, Toolkit::TableView::CellPosition( 0, 0 ) );
optionPressedContainer.AddChild( pressedIcon, Toolkit::TableView::CellPosition( 0, 0 ) );
+
icon.SetPadding( Padding( 10.0f, 10.0f, 10.0f, 10.0f ) );
pressedIcon.SetPadding( Padding( 10.0f, 10.0f, 10.0f, 10.0f ) );
}
- // 5. Create a option.
+ // 4. Create a option.
Toolkit::PushButton option = Toolkit::PushButton::New();
option.SetName( name );
option.SetAnimationTime( 0.0f );
- option.SetSize( OPTION_ICON_SIZE );
- //option.ClickedSignal().Connect( this, &TextInputPopup::OnButtonPressed );
+ option.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
- // 6. Set the normal option image.
+ switch( button.id )
+ {
+ case Toolkit::TextSelectionPopup::CUT:
+ {
+ option.ClickedSignal().Connect( this, &TextSelectionPopup::OnCutButtonPressed );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::COPY:
+ {
+ option.ClickedSignal().Connect( this, &TextSelectionPopup::OnCopyButtonPressed );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::PASTE:
+ {
+ option.ClickedSignal().Connect( this, &TextSelectionPopup::OnPasteButtonPressed );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::SELECT:
+ {
+ option.ClickedSignal().Connect( this, &TextSelectionPopup::OnSelectButtonPressed );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::SELECT_ALL:
+ {
+ option.ClickedSignal().Connect( this, &TextSelectionPopup::OnSelectAllButtonPressed );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::CLIPBOARD:
+ {
+ option.ClickedSignal().Connect( this, &TextSelectionPopup::OnClipboardButtonPressed );
+ break;
+ }
+ case Toolkit::TextSelectionPopup::NONE:
+ {
+ // Nothing to do:
+ break;
+ }
+ }
+
+ // 5. Set the normal option image.
option.SetButtonImage( optionContainer );
- // 7. Set the pressed option image
+ // 6. Set the pressed option image
option.SetSelectedImage( optionPressedContainer );
- // 9 Add option to table view
- parent.SetFitWidth( indexInTable );
- parent.AddChild( option, Toolkit::TableView::CellPosition( 0, indexInTable ) );
- indexInTable++;
+ // 7 Add option to tool bar
+ mToolbar.AddOption( option );
- // 10. Add the divider
- if( !finalOption )
+ // 8. Add the divider
+ if( showDivider )
{
- const Size size( POPUP_DIVIDER_WIDTH, 0.0f ); // Height FILL_TO_PARENT
+ const Size size( mOptionDividerSize.width, 0.0f ); // Height FILL_TO_PARENT
ImageActor divider = Toolkit::CreateSolidColorActor( Color::WHITE );
-
divider.SetSize( size );
divider.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
- parent.SetFitWidth( indexInTable );
- parent.AddChild( divider, Toolkit::TableView::CellPosition( 0, indexInTable ) );
- indexInTable++;
+ divider.SetColor( mLineColor );
+ mToolbar.AddDivider( divider );
}
}
- void TextSelectionPopup::SetUpPopup()
- {
- Actor self = Self();
- self.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
-
- // Create Layer and Stencil.
- mStencilLayer = Layer::New();
- mStencilLayer.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
- mStencilLayer.SetParentOrigin( ParentOrigin::CENTER );
-
- ImageActor stencil = CreateSolidColorActor( Color::RED );
- stencil.SetDrawMode( DrawMode::STENCIL );
- stencil.SetVisible( true );
- stencil.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
- stencil.SetParentOrigin( ParentOrigin::CENTER );
-
- Actor scrollview = Actor::New(); //todo make a scrollview
- scrollview.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
- scrollview.SetParentOrigin( ParentOrigin::CENTER );
-
- mTableOfButtons.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
- mTableOfButtons.SetFitHeight( 0 );
- mTableOfButtons.SetParentOrigin( ParentOrigin::CENTER );
-
- mStencilLayer.Add( stencil );
- mStencilLayer.Add( scrollview );
- scrollview.Add( mTableOfButtons );
- self.Add( mStencilLayer );
- //self.Add ( mTableOfButtons );
- }
-
- void TextSelectionPopup::AddPopupOptions( bool createTail, bool showIcons, bool showCaptions )
+ std::size_t TextSelectionPopup::GetNumberOfEnabledOptions()
{
- mContentSize = Vector2::ZERO;
-
- // Add the options into the buttons container.
-
- // 1. Determine how many buttons are active and should be added to container.
std::size_t numberOfOptions = 0u;
for( std::vector<ButtonRequirement>::const_iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt ); ++it )
{
}
}
- // 2. Iterate list of buttons and add active ones.
- std::size_t optionsAdded = 0u;
-
- numberOfOptions = ( numberOfOptions*2 ) - 1 ; // Last Option does not get a divider so -1 or if only one option then also no divider
-
- mTableOfButtons = Dali::Toolkit::TableView::New( 1, numberOfOptions );
+ return numberOfOptions;
+ }
+ void TextSelectionPopup::AddPopupOptionsToToolbar( bool showIcons, bool showCaptions )
+ {
+ // Iterate list of buttons and add active ones to Toolbar
+ std::size_t numberOfOptionsRequired = GetNumberOfEnabledOptions();
+ std::size_t numberOfOptionsAdded = 0u;
for( std::vector<ButtonRequirement>::const_iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt ); ++it )
{
const ButtonRequirement& button( *it );
if ( button.enabled )
{
- AddOption( mTableOfButtons, button.name, button.caption, button.icon, optionsAdded == numberOfOptions - 1, showIcons, showCaptions, optionsAdded ); // -1 to ignore the last divider
+ numberOfOptionsAdded++;
+ AddOption( button, ( numberOfOptionsAdded < numberOfOptionsRequired ) , showIcons, showCaptions );
}
}
}
void TextSelectionPopup::CreatePopup()
{
- if ( !mStencilLayer )
+ Actor self = Self();
+ CreateOrderedListOfPopupOptions(); //todo Currently causes all options to be shown
+ self.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
+ SetBackgroundImage( NinePatchImage::New( DEFAULT_POPUP_BACKGROUND_IMAGE ) );
+
+ if ( !mToolbar )
{
- CreateOrderedListOfPopupOptions(); //todo Currently causes all options to be shown
- CreateBackground();
- AddPopupOptions( true, true, false ); // todo false so not to show Labels until ellipses or similar possible.
- SetUpPopup();
+ mToolbar = Toolkit::TextSelectionToolbar::New();
+ mToolbar.SetParentOrigin( ParentOrigin::CENTER );
+ mToolbar.SetProperty( Toolkit::TextSelectionToolbar::Property::MAX_SIZE, mMaxSize );
+ self.Add( mToolbar );
+ AddPopupOptionsToToolbar( mShowIcons, mShowCaptions );
}
-
- mStencilLayer.RaiseToTop();
}
- TextSelectionPopup::TextSelectionPopup()
- : Control( ControlBehaviour( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ) ),
- mMaxSize ( DEFAULT_POPUP_MAX_SIZE ),
- mVisiblePopUpSize( DEFAULT_POPUP_MAX_SIZE ),
- mRequiredPopUpSize( DEFAULT_POPUP_MAX_SIZE ),
- mBackgroundColor( DEFAULT_POPUP_BACKGROUND ),
- mBackgroundPressedColor( DEFAULT_POPUP_BACKGROUND_PRESSED ),
+ TextSelectionPopup::TextSelectionPopup( TextSelectionPopupCallbackInterface* callbackInterface )
+ : Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
+ mToolbar(),
+ mMaxSize(),
+ mMinSize(),
+ mOptionDividerSize( Size( 2.0f, 0.0f) ),
+ mEnabledButtons( Toolkit::TextSelectionPopup::NONE ),
+ mCallbackInterface( callbackInterface ),
mLineColor( DEFAULT_POPUP_LINE_COLOR ),
mIconColor( DEFAULT_OPTION_ICON ),
- mIconPressedColor( DEFAULT_OPTION_ICON_PRESSED ),
- mTextColor( DEFAULT_OPTION_TEXT ),
- mTextPressedColor( DEFAULT_OPTION_TEXT_PRESSED ),
+ mPressedColor( DEFAULT_OPTION_ICON_PRESSED ),
mSelectOptionPriority( 1 ),
mSelectAllOptionPriority ( 2 ),
mCutOptionPriority ( 3 ),
mCopyOptionPriority ( 4 ),
mPasteOptionPriority ( 5 ),
mClipboardOptionPriority( 6 ),
- mShowIcons( true ),
- mShowCaptions( false )
+ mShowIcons( false ),
+ mShowCaptions( true )
{
}
} // namespace Toolkit
} // namespace Dali
+
+
$(toolkit_src_dir)/controls/alignment/alignment-impl.cpp \
$(toolkit_src_dir)/controls/bloom-view/bloom-view-impl.cpp \
$(toolkit_src_dir)/controls/bubble-effect/bubble-emitter-impl.cpp \
+ $(toolkit_src_dir)/controls/bubble-effect/bubble-actor.cpp \
$(toolkit_src_dir)/controls/buttons/button-impl.cpp \
$(toolkit_src_dir)/controls/buttons/check-box-button-impl.cpp \
$(toolkit_src_dir)/controls/buttons/push-button-impl.cpp \
$(toolkit_src_dir)/controls/popup/popup-impl.cpp \
$(toolkit_src_dir)/controls/popup/popup-style-impl.cpp \
$(toolkit_src_dir)/controls/page-turn-view/page-turn-portrait-view-impl.cpp \
+ $(toolkit_src_dir)/controls/page-turn-view/page-turn-effect.cpp \
$(toolkit_src_dir)/controls/page-turn-view/page-turn-landscape-view-impl.cpp \
$(toolkit_src_dir)/controls/page-turn-view/page-turn-view-impl.cpp \
$(toolkit_src_dir)/controls/scroll-bar/scroll-bar-impl.cpp \
$(toolkit_src_dir)/controls/text-controls/text-field-impl.cpp \
$(toolkit_src_dir)/controls/text-controls/text-label-impl.cpp \
$(toolkit_src_dir)/controls/text-controls/text-selection-popup-impl.cpp \
+ $(toolkit_src_dir)/controls/text-controls/text-selection-toolbar-impl.cpp \
$(toolkit_src_dir)/controls/tool-bar/tool-bar-impl.cpp \
$(toolkit_src_dir)/focus-manager/accessibility-focus-manager-impl.cpp \
$(toolkit_src_dir)/focus-manager/keyboard-focus-manager-impl.cpp \
$(toolkit_src_dir)/filters/emboss-filter.cpp \
$(toolkit_src_dir)/filters/image-filter.cpp \
$(toolkit_src_dir)/filters/spread-filter.cpp \
- $(toolkit_src_dir)/shader-effects/page-turn-effect-impl.cpp \
- $(toolkit_src_dir)/shader-effects/water-effect-impl.cpp \
$(toolkit_src_dir)/styling/style-manager-impl.cpp \
$(toolkit_src_dir)/text/bidirectional-support.cpp \
$(toolkit_src_dir)/text/character-set-conversion.cpp \
#include <dali/public-api/adaptor-framework/timer.h>
#include <dali/public-api/actors/image-actor.h>
#include <dali/public-api/actors/layer.h>
-#include <dali/devel-api/actors/mesh-actor.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/common/constants.h>
#include <dali/public-api/common/stage.h>
#include <dali/public-api/events/touch-event.h>
#include <dali/public-api/events/pan-gesture.h>
#include <dali/public-api/events/pan-gesture-detector.h>
-#include <dali/devel-api/geometry/mesh.h>
-#include <dali/devel-api/geometry/mesh-data.h>
#include <dali/public-api/images/resource-image.h>
#include <dali/public-api/math/rect.h>
#include <dali/public-api/math/vector2.h>
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control.h>
+#include <dali-toolkit/public-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/public-api/controls/buttons/push-button.h>
#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
const char* DEFAULT_GRAB_HANDLE_IMAGE_RELEASED( DALI_IMAGE_DIR "insertpoint-icon.png" );
const char* DEFAULT_GRAB_HANDLE_IMAGE_PRESSED( DALI_IMAGE_DIR "insertpoint-icon-pressed.png" );
- const char* DEFAULT_SELECTION_HANDLE_ONE( DALI_IMAGE_DIR "text-input-selection-handle-left.png" );
- const char* DEFAULT_SELECTION_HANDLE_TWO( DALI_IMAGE_DIR "text-input-selection-handle-right.png" );
+ const char* DEFAULT_SELECTION_HANDLE_ONE_RELEASED( DALI_IMAGE_DIR "text-input-selection-handle-left.png" );
+ const char* DEFAULT_SELECTION_HANDLE_ONE_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-left-press.png" );
+ const char* DEFAULT_SELECTION_HANDLE_TWO_RELEASED( DALI_IMAGE_DIR "text-input-selection-handle-right.png" );
+ const char* DEFAULT_SELECTION_HANDLE_TWO_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-right-press.png" );
- const Dali::Vector3 DEFAULT_GRAB_HANDLE_RELATIVE_SIZE( 1.5f, 2.0f, 1.0f );
- const Dali::Vector3 DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE( 1.5f, 1.5f, 1.0f );
+ const int DEFAULT_POPUP_OFFSET( -100.0f ); // Vertical offset of Popup from cursor or handles position.
- const Dali::Vector4 LIGHT_BLUE( 0.07f, 0.41f, 0.59f, 1.0f ); // The text highlight color.
+ const Dali::Vector3 DEFAULT_GRAB_HANDLE_RELATIVE_SIZE( 1.25f, 1.5f, 1.0f );
+ const Dali::Vector3 DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE( 1.25f, 1.5f, 1.0f );
+
+ const Dali::Vector4 LIGHT_BLUE( (0xb2 / 255.0f), (0xeb / 255.0f), (0xf2 / 255.0f), 0.5f ); // The text highlight color.
const unsigned int CURSOR_BLINK_INTERVAL = 500u; // Cursor blink interval
const float TO_MILLISECONDS = 1000.f;
grabDisplacementY( 0.f ),
active( false ),
visible( false ),
+ pressed( false ),
flipped( false )
{
}
float grabDisplacementY;
bool active : 1;
bool visible : 1;
+ bool pressed : 1;
bool flipped : 1;
};
- Impl( Dali::Toolkit::Internal::Control& parent, Observer& observer )
- : mTextControlParent( parent ),
- mObserver( observer ),
+ struct PopupImpl
+ {
+ PopupImpl()
+ : position(),
+ offset( DEFAULT_POPUP_OFFSET )
+ {
+ }
+
+ TextSelectionPopup actor;
+ Vector3 position;
+ int offset;
+ };
+
+ Impl( ControllerInterface& controller,
+ TextSelectionPopupCallbackInterface& callbackInterface )
+ : mController( controller ),
+ mEnabledPopupButtons( TextSelectionPopup::NONE ),
+ mTextSelectionPopupCallbackInterface( callbackInterface ),
mBoundingBox( Rect<int>() ),
mHighlightColor( LIGHT_BLUE ),
+ mHighlightPosition( Vector2::ZERO ),
mActiveCursor( ACTIVE_CURSOR_NONE ),
mCursorBlinkInterval( CURSOR_BLINK_INTERVAL ),
mCursorBlinkDuration( 0.0f ),
mActiveCopyPastePopup( false ),
mCursorBlinkStatus( true ),
mPrimaryCursorVisible( false ),
- mSecondaryCursorVisible( false )
+ mSecondaryCursorVisible( false ),
+ mSwapSelectionHandles( false ),
+ mNotifyEndOfScroll( false )
{
}
// TODO - Remove this if nothing is active
CreateActiveLayer();
+ /*
// Show or hide the cursors
CreateCursors();
if( mPrimaryCursor )
if( mPrimaryCursorVisible )
{
Vector2 position = cursor.position;
- if( GRAB_HANDLE == mHandleScrolling )
- {
- if( mScrollDirection == SCROLL_RIGHT )
- {
- position.x = 0.f;
- }
- else
- {
- position.x = size.width;
- }
- }
mPrimaryCursor.SetPosition( position.x,
position.y );
}
mSecondaryCursor.SetVisible( mSecondaryCursorVisible );
}
-
+ */
// Show or hide the grab handle
HandleImpl& grabHandle = mHandle[GRAB_HANDLE];
if( grabHandle.active )
{
Vector2 position = grabHandle.position;
- if( GRAB_HANDLE == mHandleScrolling )
- {
- if( mScrollDirection == SCROLL_RIGHT )
- {
- position.x = 0.f;
- }
- else
- {
- position.x = size.width;
- }
- }
-
const bool isVisible = ( position.x <= size.width ) && ( position.x >= 0.f );
if( isVisible )
HandleImpl& secondary = mHandle[ RIGHT_SELECTION_HANDLE ];
if( primary.active || secondary.active )
{
- SetupTouchEvents();
+ Vector2 primaryPosition = primary.position;
+ Vector2 secondaryPosition = secondary.position;
+
+ const bool isPrimaryVisible = ( primaryPosition.x <= size.width ) && ( primaryPosition.x >= 0.f );
+ const bool isSecondaryVisible = ( secondaryPosition.x <= size.width ) && ( secondaryPosition.x >= 0.f );
+
+ if( isPrimaryVisible || isSecondaryVisible )
+ {
+ SetupTouchEvents();
- CreateSelectionHandles();
+ CreateSelectionHandles();
- primary.actor.SetPosition( primary.position.x,
- primary.position.y + primary.lineHeight );
+ if( isPrimaryVisible )
+ {
+ primary.actor.SetPosition( primaryPosition.x,
+ primaryPosition.y + primary.lineHeight );
+ }
- secondary.actor.SetPosition( secondary.position.x,
- secondary.position.y + secondary.lineHeight );
+ if( isSecondaryVisible )
+ {
+ secondary.actor.SetPosition( secondaryPosition.x,
+ secondaryPosition.y + secondary.lineHeight );
+ }
+ }
+ primary.actor.SetVisible( isPrimaryVisible );
+ secondary.actor.SetVisible( isSecondaryVisible );
CreateHighlight();
UpdateHighlight();
{
UnparentAndReset( primary.actor );
UnparentAndReset( secondary.actor );
- UnparentAndReset( mHighlightMeshActor );
+ //UnparentAndReset( mHighlightMeshActor );
}
if ( mActiveCopyPastePopup )
{
- if ( !mCopyPastePopup )
+ // todo Swap UnparentAndReset for DeterminePositionPopup() if mCopyPastePopup.actor valid Once the issue with the labels disappearing is fixed.
+ UnparentAndReset( mCopyPastePopup.actor );
+ if ( !mCopyPastePopup.actor )
{
- mCopyPastePopup = TextSelectionPopup::New();
+ mCopyPastePopup.actor = TextSelectionPopup::New( mEnabledPopupButtons, &mTextSelectionPopupCallbackInterface );
#ifdef DECORATOR_DEBUG
- mCopyPastePopup.SetName("mCopyPastePopup");
+ mCopyPastePopup.actor.SetName("mCopyPastePopup");
#endif
- mCopyPastePopup.SetAnchorPoint( AnchorPoint::CENTER );
- mCopyPastePopup.OnRelayoutSignal().Connect( this, &Decorator::Impl::PopUpRelayoutComplete ); // Position popup after size negotiation
- mActiveLayer.Add ( mCopyPastePopup );
+ mCopyPastePopup.actor.SetAnchorPoint( AnchorPoint::CENTER );
+ mCopyPastePopup.actor.OnRelayoutSignal().Connect( this, &Decorator::Impl::PopupRelayoutComplete ); // Position popup after size negotiation
+ mActiveLayer.Add ( mCopyPastePopup.actor );
}
}
else
{
- if ( mCopyPastePopup )
+ if ( mCopyPastePopup.actor )
{
- UnparentAndReset( mCopyPastePopup );
+ UnparentAndReset( mCopyPastePopup.actor );
}
}
}
mHandle[ GRAB_HANDLE ].position += scrollOffset;
mHandle[ LEFT_SELECTION_HANDLE ].position += scrollOffset;
mHandle[ RIGHT_SELECTION_HANDLE ].position += scrollOffset;
-
- // TODO Highlight box??
+ mHighlightPosition += scrollOffset;
}
- void PopUpRelayoutComplete( Actor actor )
+ void DeterminePositionPopup()
{
- // Size negotiation for CopyPastePopup complete so can get the size and constrain position within bounding box.
+ if ( !mActiveCopyPastePopup )
+ {
+ return;
+ }
- mCopyPastePopup.OnRelayoutSignal().Disconnect( this, &Decorator::Impl::PopUpRelayoutComplete );
+ if ( mHandle[LEFT_SELECTION_HANDLE].active || mHandle[RIGHT_SELECTION_HANDLE].active )
+ {
+ float minHandleXPosition = std::min ( mHandle[LEFT_SELECTION_HANDLE].position.x, mHandle[RIGHT_SELECTION_HANDLE].position.x );
+ float maxHandleXPosition = std::max ( mHandle[LEFT_SELECTION_HANDLE].position.x, mHandle[RIGHT_SELECTION_HANDLE].position.x );
- Vector3 popupPosition( mCursor[PRIMARY_CURSOR].position.x, mCursor[PRIMARY_CURSOR].position.y -100.0f , 0.0f); //todo 100 to be an offset Property
+ float minHandleYPosition = std::min ( mHandle[LEFT_SELECTION_HANDLE].position.y, mHandle[RIGHT_SELECTION_HANDLE].position.y );
- Vector3 popupSize = Vector3( mCopyPastePopup.GetRelayoutSize( Dimension::WIDTH ), mCopyPastePopup.GetRelayoutSize( Dimension::HEIGHT ), 0.0f );
+ mCopyPastePopup.position.x = minHandleXPosition + ( ( maxHandleXPosition - minHandleXPosition ) *0.5f );
+ mCopyPastePopup.position.y = minHandleYPosition + mCopyPastePopup.offset;
+ }
+ else
+ {
+ mCopyPastePopup.position = Vector3( mCursor[PRIMARY_CURSOR].position.x, mCursor[PRIMARY_CURSOR].position.y -100.0f , 0.0f ); //todo 100 to be an offset Property
+ }
+
+ Vector3 popupSize = Vector3( mCopyPastePopup.actor.GetRelayoutSize( Dimension::WIDTH ), mCopyPastePopup.actor.GetRelayoutSize( Dimension::HEIGHT ), 0.0f );
- GetConstrainedPopupPosition( popupPosition, popupSize, AnchorPoint::CENTER, mActiveLayer, mBoundingBox );
+ GetConstrainedPopupPosition( mCopyPastePopup.position, popupSize, AnchorPoint::CENTER, mActiveLayer, mBoundingBox );
- SetUpPopUpPositionNotifications();
+ SetUpPopupPositionNotifications();
+
+ mCopyPastePopup.actor.SetPosition( mCopyPastePopup.position );
+ }
+
+ void PopupRelayoutComplete( Actor actor )
+ {
+ // Size negotiation for CopyPastePopup complete so can get the size and constrain position within bounding box.
+ mCopyPastePopup.actor.OnRelayoutSignal().Disconnect( this, &Decorator::Impl::PopupRelayoutComplete );
- mCopyPastePopup.SetPosition( popupPosition ); //todo grabhandle(cursor) or selection handle positions to be used
+ DeterminePositionPopup();
}
void CreateCursor( ImageActor& cursor, const Vector4& color )
{
cursor = CreateSolidColorActor( color );
+ cursor.SetSortModifier( DECORATION_DEPTH_INDEX );
cursor.SetParentOrigin( ParentOrigin::TOP_LEFT ); // Need to set the default parent origin as CreateSolidColorActor() sets a different one.
cursor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
}
// Add or Remove cursor(s) from parent
void CreateCursors()
{
+ /*
if( mActiveCursor == ACTIVE_CURSOR_NONE )
{
UnparentAndReset( mPrimaryCursor );
}
else
{
- /* Create Primary and or Secondary Cursor(s) if active and add to parent */
+ // Create Primary and or Secondary Cursor(s) if active and add to parent
if ( mActiveCursor == ACTIVE_CURSOR_PRIMARY ||
mActiveCursor == ACTIVE_CURSOR_BOTH )
{
UnparentAndReset( mSecondaryCursor );
}
}
+ */
}
bool OnCursorBlinkTimerTick()
{
+ /*
// Cursor blinking
if ( mPrimaryCursor )
{
}
mCursorBlinkStatus = !mCursorBlinkStatus;
-
+ */
return true;
}
{
if( !mActiveLayer )
{
- Actor parent = mTextControlParent.Self();
-
mActiveLayer = Layer::New();
#ifdef DECORATOR_DEBUG
mActiveLayer.SetName ( "ActiveLayerActor" );
mActiveLayer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
mActiveLayer.SetPositionInheritanceMode( USE_PARENT_POSITION );
- parent.Add( mActiveLayer );
+ // Add the active layer telling the controller it doesn't need clipping.
+ mController.AddDecoration( mActiveLayer, false );
}
mActiveLayer.RaiseToTop();
}
grabHandle.actor = ImageActor::New( mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED] );
+ grabHandle.actor.SetSortModifier( DECORATION_DEPTH_INDEX );
grabHandle.actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
- grabHandle.actor.SetDrawMode( DrawMode::OVERLAY );
// Area that Grab handle responds to, larger than actual handle so easier to move
#ifdef DECORATOR_DEBUG
grabHandle.actor.SetName( "GrabHandleActor" );
{
if( !mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] )
{
- mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE );
+ mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE_RELEASED );
+ }
+ if( !mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED] )
+ {
+ mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE_PRESSED );
}
primary.actor = ImageActor::New( mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] );
primary.actor.SetName("SelectionHandleOne");
#endif
primary.actor.SetAnchorPoint( AnchorPoint::TOP_RIGHT ); // Change to BOTTOM_RIGHT if Look'n'Feel requires handle above text.
- primary.actor.SetDrawMode( DrawMode::OVERLAY ); // ensure grab handle above text
+ primary.actor.SetSortModifier( DECORATION_DEPTH_INDEX );
primary.flipped = false;
primary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
primary.grabArea.SetName("SelectionHandleOneGrabArea");
#endif
primary.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
+ primary.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
+ primary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
primary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
- primary.grabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
mTapDetector.Attach( primary.grabArea );
mPanGestureDetector.Attach( primary.grabArea );
{
if( !mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] )
{
- mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO );
+ mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO_RELEASED );
+ }
+ if( !mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED] )
+ {
+ mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO_PRESSED );
}
secondary.actor = ImageActor::New( mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] );
secondary.actor.SetName("SelectionHandleTwo");
#endif
secondary.actor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); // Change to BOTTOM_LEFT if Look'n'Feel requires handle above text.
- secondary.actor.SetDrawMode( DrawMode::OVERLAY ); // ensure grab handle above text
+ secondary.actor.SetSortModifier( DECORATION_DEPTH_INDEX );
secondary.flipped = false;
secondary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
secondary.grabArea.SetName("SelectionHandleTwoGrabArea");
#endif
secondary.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
+ secondary.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
+ secondary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
secondary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
- secondary.grabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
mTapDetector.Attach( secondary.grabArea );
mPanGestureDetector.Attach( secondary.grabArea );
void CreateHighlight()
{
+ /*
if ( !mHighlightMeshActor )
{
mHighlightMaterial = Material::New( "HighlightMaterial" );
mHighlightMeshActor.SetName( "HighlightMeshActor" );
#endif
mHighlightMeshActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
- mHighlightMeshActor.SetPosition( 0.0f, 0.0f, DISPLAYED_HIGHLIGHT_Z_OFFSET );
- Actor parent = mTextControlParent.Self();
- parent.Add( mHighlightMeshActor );
+ // Add the highlight box telling the controller it needs clipping.
+ mController.AddDecoration( mHighlightMeshActor, true );
}
+
+ mHighlightMeshActor.SetPosition( mHighlightPosition.x, mHighlightPosition.y, DISPLAYED_HIGHLIGHT_Z_OFFSET );
+ */
}
void UpdateHighlight()
// 9* *7
//
+ /*
if ( mHighlightMesh && mHighlightMaterial && !mHighlightQuadList.empty() )
{
MeshData::VertexContainer vertices;
mHighlightMeshData.SetData( vertices, faceIndices, bones, mHighlightMaterial );
mHighlightMesh.UpdateMeshData( mHighlightMeshData );
}
+ */
}
void OnTap( Actor actor, const TapGesture& tap )
if( Gesture::Started == gesture.state ||
Gesture::Continuing == gesture.state )
{
+ Vector2 targetSize;
+ mController.GetTargetSize( targetSize );
+
if( x < mScrollThreshold )
{
mScrollDirection = SCROLL_RIGHT;
mHandleScrolling = type;
StartScrollTimer();
}
- else if( x > mTextControlParent.Self().GetTargetSize().width - mScrollThreshold )
+ else if( x > targetSize.width - mScrollThreshold )
{
mScrollDirection = SCROLL_LEFT;
mHandleScrolling = type;
{
mHandleScrolling = HANDLE_TYPE_COUNT;
StopScrollTimer();
- mObserver.HandleEvent( type, HANDLE_PRESSED, x, y );
+ mController.DecorationEvent( type, HANDLE_PRESSED, x, y );
}
}
else if( Gesture::Finished == gesture.state ||
Gesture::Cancelled == gesture.state )
{
- if( mScrollTimer && mScrollTimer.IsRunning() )
+ if( mScrollTimer &&
+ ( mScrollTimer.IsRunning() || mNotifyEndOfScroll ) )
{
+ mNotifyEndOfScroll = false;
mHandleScrolling = HANDLE_TYPE_COUNT;
StopScrollTimer();
- mObserver.HandleEvent( type, HANDLE_STOP_SCROLLING, x, y );
+ mController.DecorationEvent( type, HANDLE_STOP_SCROLLING, x, y );
}
else
{
- mObserver.HandleEvent( type, HANDLE_RELEASED, x, y );
+ mController.DecorationEvent( type, HANDLE_RELEASED, x, y );
}
- handle.actor.SetImage( mHandleImages[type][HANDLE_IMAGE_RELEASED] );
+
+ if( GRAB_HANDLE == type )
+ {
+ handle.actor.SetImage( mHandleImages[type][HANDLE_IMAGE_RELEASED] );
+ }
+ else
+ {
+ HandleType selectionHandleType = type;
+
+ if( mSwapSelectionHandles != handle.flipped )
+ {
+ selectionHandleType = ( LEFT_SELECTION_HANDLE == type ) ? RIGHT_SELECTION_HANDLE : LEFT_SELECTION_HANDLE;
+ }
+
+ handle.actor.SetImage( mHandleImages[selectionHandleType][HANDLE_IMAGE_RELEASED] );
+ }
+ handle.pressed = false;
}
}
{
const TouchPoint& point = event.GetPoint(0);
- if( TouchPoint::Down == point.state &&
- mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_PRESSED] )
+ if( TouchPoint::Down == point.state )
{
- mHandle[GRAB_HANDLE].actor.SetImage( mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_PRESSED] );
+ mHandle[GRAB_HANDLE].pressed = true;
+ Image imagePressed = mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_PRESSED];
+ if( imagePressed )
+ {
+ mHandle[GRAB_HANDLE].actor.SetImage( imagePressed );
+ }
}
- else if( TouchPoint::Up == point.state &&
- mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED] )
+ else if( TouchPoint::Up == point.state )
{
- mHandle[GRAB_HANDLE].actor.SetImage( mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED] );
+ mHandle[GRAB_HANDLE].pressed = false;
+ Image imageReleased = mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED];
+ if( imageReleased )
+ {
+ mHandle[GRAB_HANDLE].actor.SetImage( imageReleased );
+ }
}
}
return true;
}
- bool OnHandleOneTouched( Actor actor, const TouchEvent& touch )
+ bool OnHandleOneTouched( Actor actor, const TouchEvent& event )
{
- // TODO
+ // Switch between pressed/release selection handle images
+ if( event.GetPointCount() > 0 &&
+ mHandle[LEFT_SELECTION_HANDLE].actor )
+ {
+ const TouchPoint& point = event.GetPoint(0);
+
+ const bool flip = mSwapSelectionHandles != mHandle[LEFT_SELECTION_HANDLE].flipped;
+ if( TouchPoint::Down == point.state )
+ {
+ mHandle[LEFT_SELECTION_HANDLE].pressed = true;
+ Image imagePressed = mHandleImages[flip ? RIGHT_SELECTION_HANDLE : LEFT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED];
+ if( imagePressed )
+ {
+ mHandle[LEFT_SELECTION_HANDLE].actor.SetImage( imagePressed );
+ }
+ }
+ else if( TouchPoint::Up == point.state )
+ {
+ mHandle[LEFT_SELECTION_HANDLE].pressed = false;
+ Image imageReleased = mHandleImages[flip ? RIGHT_SELECTION_HANDLE : LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED];
+ if( imageReleased )
+ {
+ mHandle[LEFT_SELECTION_HANDLE].actor.SetImage( imageReleased );
+ }
+ }
+ }
+
// Consume to avoid pop-ups accidentally closing, when handle is outside of pop-up area
return true;
}
- bool OnHandleTwoTouched( Actor actor, const TouchEvent& touch )
+ bool OnHandleTwoTouched( Actor actor, const TouchEvent& event )
{
- // TODO
+ // Switch between pressed/release selection handle images
+ if( event.GetPointCount() > 0 &&
+ mHandle[RIGHT_SELECTION_HANDLE].actor )
+ {
+ const TouchPoint& point = event.GetPoint(0);
+
+ const bool flip = mSwapSelectionHandles != mHandle[RIGHT_SELECTION_HANDLE].flipped;
+ if( TouchPoint::Down == point.state )
+ {
+ Image imagePressed = mHandleImages[flip ? LEFT_SELECTION_HANDLE : RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED];
+ mHandle[RIGHT_SELECTION_HANDLE].pressed = true;
+ if( imagePressed )
+ {
+ mHandle[RIGHT_SELECTION_HANDLE].actor.SetImage( imagePressed );
+ }
+ }
+ else if( TouchPoint::Up == point.state )
+ {
+ Image imageReleased = mHandleImages[flip ? LEFT_SELECTION_HANDLE : RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED];
+ mHandle[RIGHT_SELECTION_HANDLE].pressed = false;
+ if( imageReleased )
+ {
+ mHandle[RIGHT_SELECTION_HANDLE].actor.SetImage( imageReleased );
+ }
+ }
+ }
+
// Consume to avoid pop-ups accidentally closing, when handle is outside of pop-up area
return true;
}
{
float alternativePosition=0.0f;;
+ /*
if ( mPrimaryCursor ) // Secondary cursor not used for paste
{
Cursor cursor = PRIMARY_CURSOR;
alternativePosition = mCursor[cursor].position.y;
}
-
+ */
const float popupHeight = 120.0f; // todo Set as a MaxSize Property in Control or retrieve from CopyPastePopup class.
if( mHandle[GRAB_HANDLE].active )
// if can't be positioned above, then position below row.
alternativeYPosition = AlternatePopUpPositionRelativeToCursor();
- mCopyPastePopup.SetY( alternativeYPosition );
+ mCopyPastePopup.actor.SetY( alternativeYPosition );
}
- void SetUpPopUpPositionNotifications( )
+ void SetUpPopupPositionNotifications( )
{
// Note Property notifications ignore any set anchor point so conditions must allow for this. Default is Top Left.
Vector4 worldCoordinatesBoundingBox;
LocalToWorldCoordinatesBoundingBox( mBoundingBox, worldCoordinatesBoundingBox );
- float popupHeight = mCopyPastePopup.GetRelayoutSize( Dimension::HEIGHT);
+ float popupHeight = mCopyPastePopup.actor.GetRelayoutSize( Dimension::HEIGHT);
- PropertyNotification verticalExceedNotification = mCopyPastePopup.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
- OutsideCondition( worldCoordinatesBoundingBox.y + popupHeight/2,
- worldCoordinatesBoundingBox.w - popupHeight/2 ) );
+ PropertyNotification verticalExceedNotification = mCopyPastePopup.actor.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y,
+ OutsideCondition( worldCoordinatesBoundingBox.y + popupHeight * 0.5f,
+ worldCoordinatesBoundingBox.w - popupHeight * 0.5f ) );
verticalExceedNotification.NotifySignal().Connect( this, &Decorator::Impl::PopUpLeavesVerticalBoundary );
}
}
requiredPopupPosition.x = requiredPopupPosition.x + xOffSetToKeepWithinBounds;
+
+ // Prevent pixel mis-alignment by rounding down.
+ requiredPopupPosition.x = static_cast<int>( requiredPopupPosition.x );
+ requiredPopupPosition.y = static_cast<int>( requiredPopupPosition.y );
+
+ }
+
+ void FlipSelectionHandleImages()
+ {
+ SetupTouchEvents();
+
+ CreateSelectionHandles();
+
+ HandleImpl& leftHandle = mHandle[LEFT_SELECTION_HANDLE];
+ HandleImpl& rightHandle = mHandle[RIGHT_SELECTION_HANDLE];
+
+ const HandleImageType leftImageType = leftHandle.pressed ? HANDLE_IMAGE_PRESSED : HANDLE_IMAGE_RELEASED;
+ const HandleImageType rightImageType = rightHandle.pressed ? HANDLE_IMAGE_PRESSED : HANDLE_IMAGE_RELEASED;
+ const bool leftFlipped = mSwapSelectionHandles != leftHandle.flipped;
+ const bool rightFlipped = mSwapSelectionHandles != rightHandle.flipped;
+
+ leftHandle.actor.SetImage( leftFlipped ? mHandleImages[RIGHT_SELECTION_HANDLE][leftImageType] : mHandleImages[LEFT_SELECTION_HANDLE][leftImageType] );
+
+ leftHandle.actor.SetAnchorPoint( leftFlipped ? AnchorPoint::TOP_LEFT : AnchorPoint::TOP_RIGHT );
+
+ rightHandle.actor.SetImage( rightFlipped ? mHandleImages[LEFT_SELECTION_HANDLE][rightImageType] : mHandleImages[RIGHT_SELECTION_HANDLE][rightImageType] );
+
+ rightHandle.actor.SetAnchorPoint( rightFlipped ? AnchorPoint::TOP_RIGHT : AnchorPoint::TOP_LEFT );
}
void SetScrollThreshold( float threshold )
return mScrollSpeed;
}
+ void NotifyEndOfScroll()
+ {
+ StopScrollTimer();
+
+ if( mScrollTimer )
+ {
+ mNotifyEndOfScroll = true;
+ }
+ }
+
/**
* Creates and starts a timer to scroll the text when handles are close to the edges of the text.
*
{
if( HANDLE_TYPE_COUNT != mHandleScrolling )
{
- mObserver.HandleEvent( mHandleScrolling,
- HANDLE_SCROLLING,
- mScrollDirection == SCROLL_RIGHT ? mScrollDistance : -mScrollDistance,
- 0.f );
+ mController.DecorationEvent( mHandleScrolling,
+ HANDLE_SCROLLING,
+ mScrollDirection == SCROLL_RIGHT ? mScrollDistance : -mScrollDistance,
+ 0.f );
}
return true;
}
- Internal::Control& mTextControlParent;
- Observer& mObserver;
+ ControllerInterface& mController;
TapGestureDetector mTapDetector;
PanGestureDetector mPanGestureDetector;
Timer mScrollTimer; ///< Timer used to scroll the text when the grab handle is moved close to the edges.
Layer mActiveLayer; ///< Layer for active handles and alike that ensures they are above all else.
- ImageActor mPrimaryCursor;
- ImageActor mSecondaryCursor;
- MeshActor mHighlightMeshActor; ///< Mesh Actor to display highlight
+ //ImageActor mPrimaryCursor;
+ //ImageActor mSecondaryCursor;
+ //MeshActor mHighlightMeshActor; ///< Mesh Actor to display highlight
- TextSelectionPopup mCopyPastePopup;
+
+ PopupImpl mCopyPastePopup;
+ TextSelectionPopup::Buttons mEnabledPopupButtons; /// Bit mask of currently enabled Popup buttons
+ TextSelectionPopupCallbackInterface& mTextSelectionPopupCallbackInterface;
Image mHandleImages[HANDLE_TYPE_COUNT][HANDLE_IMAGE_TYPE_COUNT];
Image mCursorImage;
- Mesh mHighlightMesh; ///< Mesh for highlight
- MeshData mHighlightMeshData; ///< Mesh Data for highlight
- Material mHighlightMaterial; ///< Material used for highlight
+ //Mesh mHighlightMesh; ///< Mesh for highlight
+ //MeshData mHighlightMeshData; ///< Mesh Data for highlight
+ //Material mHighlightMaterial; ///< Material used for highlight
CursorImpl mCursor[CURSOR_COUNT];
HandleImpl mHandle[HANDLE_TYPE_COUNT];
Rect<int> mBoundingBox;
Vector4 mHighlightColor; ///< Color of the highlight
+ Vector2 mHighlightPosition; ///< The position of the highlight actor.
unsigned int mActiveCursor;
unsigned int mCursorBlinkInterval;
float mScrollThreshold; ///< Defines a square area inside the control, close to the edge. A cursor entering this area will trigger scroll events.
float mScrollSpeed; ///< The scroll speed in pixels per second.
float mScrollDistance; ///< Distance the text scrolls during a scroll interval.
- unsigned int mScrollInterval; ///< Time in milliseconds of a scroll interval.
bool mActiveCopyPastePopup : 1;
bool mCursorBlinkStatus : 1; ///< Flag to switch between blink on and blink off.
bool mPrimaryCursorVisible : 1; ///< Whether the primary cursor is visible.
bool mSecondaryCursorVisible : 1; ///< Whether the secondary cursor is visible.
+ bool mSwapSelectionHandles : 1; ///< Whether to swap the selection handle images.
+ bool mNotifyEndOfScroll : 1; ///< Whether to notify the end of the scroll.
};
- DecoratorPtr Decorator::New( Internal::Control& parent, Observer& observer )
+ DecoratorPtr Decorator::New( ControllerInterface& controller,
+ TextSelectionPopupCallbackInterface& callbackInterface )
{
- return DecoratorPtr( new Decorator(parent, observer) );
+ return DecoratorPtr( new Decorator( controller,
+ callbackInterface ) );
}
void Decorator::SetBoundingBox( const Rect<int>& boundingBox )
height = handle.lineHeight;
}
+ const Vector2& Decorator::GetPosition( HandleType handleType ) const
+ {
+ return mImpl->mHandle[handleType].position;
+ }
+
+ void Decorator::SwapSelectionHandlesEnabled( bool enable )
+ {
+ mImpl->mSwapSelectionHandles = enable;
+
+ mImpl->FlipSelectionHandleImages();
+ }
+
void Decorator::AddHighlight( float x1, float y1, float x2, float y2 )
{
mImpl->mHighlightQuadList.push_back( QuadCoordinates(x1, y1, x2, y2) );
void Decorator::ClearHighlights()
{
mImpl->mHighlightQuadList.clear();
+ mImpl->mHighlightPosition = Vector2::ZERO;
}
void Decorator::SetHighlightColor( const Vector4& color )
return mImpl->mActiveCopyPastePopup ;
}
+ void Decorator::SetEnabledPopupButtons( TextSelectionPopup::Buttons& enabledButtonsBitMask )
+ {
+ mImpl->mEnabledPopupButtons = enabledButtonsBitMask;
+ }
+
+ TextSelectionPopup::Buttons& Decorator::GetEnabledPopupButtons()
+ {
+ return mImpl->mEnabledPopupButtons;
+ }
+
/** Scroll **/
void Decorator::SetScrollThreshold( float threshold )
return mImpl->GetScrollSpeed();
}
+ void Decorator::NotifyEndOfScroll()
+ {
+ mImpl->NotifyEndOfScroll();
+ }
+
Decorator::~Decorator()
{
delete mImpl;
}
- Decorator::Decorator( Dali::Toolkit::Internal::Control& parent, Observer& observer )
+ Decorator::Decorator( ControllerInterface& controller,
+ TextSelectionPopupCallbackInterface& callbackInterface )
: mImpl( NULL )
{
- mImpl = new Decorator::Impl( parent, observer );
+ mImpl = new Decorator::Impl( controller, callbackInterface );
}
} // namespace Text
#include <dali/public-api/actors/image-actor.h>
#include <dali/public-api/common/stage.h>
+#define MAKE_SHADER(A)#A
+
+namespace
+{
+const char* VERTEX_SHADER = MAKE_SHADER(
+attribute mediump vec2 aPosition;
+attribute mediump vec2 aTexCoord;
+uniform mediump mat4 uMvpMatrix;
+uniform mediump vec3 uSize;
+varying mediump vec2 vTexCoord;
+
+void main()
+{
+ mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
+ position.xyz *= uSize;
+ gl_Position = uMvpMatrix * position;
+ vTexCoord = aTexCoord;
+}
+);
+
+const char* FRAGMENT_SHADER = MAKE_SHADER(
+uniform sampler2D sTexture;
+varying mediump vec2 vTexCoord;
+
+void main()
+{
+ gl_FragColor = texture2D( sTexture, vTexCoord );
+}
+);
+
+const char* VERTEX_SHADER_SHADOW = MAKE_SHADER(
+attribute mediump vec2 aPosition;
+attribute mediump vec2 aTexCoord;
+uniform mediump vec3 uSize;
+varying mediump vec2 vTexCoord;
+
+void main()
+{
+ mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
+ position.xyz *= uSize;
+ gl_Position = position;
+ vTexCoord = aTexCoord;
+}
+);
+
+const char* FRAGMENT_SHADER_SHADOW = MAKE_SHADER(
+uniform sampler2D sTexture;
+uniform lowp vec4 uColor;
+varying mediump vec2 vTexCoord;
+
+void main()
+{
+ mediump vec4 color = texture2D( sTexture, vTexCoord );
+ gl_FragColor = vec4(uColor.rgb, uColor.a*color.r);
+}
+);
+}
+
namespace Dali
{
namespace Internal
{
-//#define DISPLAY_ATLAS
-
AtlasGlyphManager::AtlasGlyphManager()
-: mCount( 0 )
{
mAtlasManager = Dali::Toolkit::AtlasManager::New();
+ mEffectBufferShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
+ mShadowShader = Shader::New( VERTEX_SHADER_SHADOW, FRAGMENT_SHADER_SHADOW, Dali::Shader::HINT_MODIFIES_GEOMETRY );
}
AtlasGlyphManager::~AtlasGlyphManager()
{
+ // Clear up any remaining references
+ for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+ fontGlyphRecordIt != mFontGlyphRecords.end();
+ ++fontGlyphRecordIt )
+ {
+ for ( Vector< GlyphRecordEntry >::Iterator glyphRecordEntryIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+ glyphRecordEntryIt != fontGlyphRecordIt->mGlyphRecords.End();
+ ++glyphRecordEntryIt )
+ {
+ mAtlasManager.Remove( glyphRecordEntryIt->mImageId );
+ }
+ }
}
AtlasGlyphManagerPtr AtlasGlyphManager::New()
return internal;
}
- void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
+ void AtlasGlyphManager::Add( Text::FontId fontId,
+ const Text::GlyphInfo& glyph,
const BufferImage& bitmap,
Dali::Toolkit::AtlasManager::AtlasSlot& slot )
{
- GlyphRecord record;
- record.mFontId = glyph.fontId;
- record.mIndex = glyph.index;
-
mAtlasManager.Add( bitmap, slot );
+
+ GlyphRecordEntry record;
+ record.mIndex = glyph.index;
record.mImageId = slot.mImageId;
- mGlyphRecords.PushBack( record );
+ record.mCount = 1;
+
+ // Have glyph records been created for this fontId ?
+ bool foundGlyph = false;
+ for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+ fontGlyphRecordIt != mFontGlyphRecords.end(); ++fontGlyphRecordIt )
+ {
+ if ( fontGlyphRecordIt->mFontId == fontId )
+ {
+ fontGlyphRecordIt->mGlyphRecords.PushBack( record );
+ foundGlyph = true;
+ break;
+ }
+ }
+
+ if ( !foundGlyph )
+ {
+ // We need to add a new font entry
+ FontGlyphRecord fontGlyphRecord;
+ fontGlyphRecord.mFontId = fontId;
+ fontGlyphRecord.mGlyphRecords.PushBack( record );
+ mFontGlyphRecords.push_back( fontGlyphRecord );
+ }
-
-#ifdef DISPLAY_ATLAS
- {
- uint32_t atlasCount = mAtlasManager.GetAtlasCount();
- if ( atlasCount > mCount )
- {
- for ( uint32_t i = 0; i < atlasCount; ++i )
- {
- ImageActor actor = ImageActor::New( mAtlasManager.GetAtlasContainer( i + 1u ) );
- actor.SetParentOrigin( Vector3( 0.5f, 0.25f + ( static_cast< float >( i ) * 0.25f ), 0.5f ) );
- actor.SetAnchorPoint( AnchorPoint::CENTER );
- actor.SetSize( 256.0f, 256.0f );
- Stage::GetCurrent().Add( actor );
- }
- }
- mCount = atlasCount;
- }
-#endif
}
void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
const Vector2& position,
- MeshData& meshData )
+ Toolkit::AtlasManager::Mesh2D& mesh )
{
- mAtlasManager.GenerateMeshData( imageId, position, mesh );
+ // Generate mesh data and tell Atlas Manager not to handle reference counting ( we'll do it )
- mAtlasManager.GenerateMeshData( imageId, position, meshData, false );
++ mAtlasManager.GenerateMeshData( imageId, position, mesh, false );
}
-void AtlasGlyphManager::StitchMesh( MeshData& first,
- const MeshData& second )
+void AtlasGlyphManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
+ const Toolkit::AtlasManager::Mesh2D& second )
{
mAtlasManager.StitchMesh( first, second );
}
- void AtlasGlyphManager::Cached( Text::FontId fontId,
+ bool AtlasGlyphManager::Cached( Text::FontId fontId,
uint32_t index,
Dali::Toolkit::AtlasManager::AtlasSlot& slot )
{
- for ( uint32_t i = 0; i < mGlyphRecords.Size(); ++i )
+ for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+ fontGlyphRecordIt != mFontGlyphRecords.end();
+ ++fontGlyphRecordIt )
{
- if ( fontId == mGlyphRecords[ i ].mFontId && index == mGlyphRecords[ i ].mIndex )
+ if ( fontGlyphRecordIt->mFontId == fontId )
{
- slot.mImageId = mGlyphRecords[ i ].mImageId;
- slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
- return;
+ for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+ glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
+ ++glyphRecordIt )
+ {
+ if ( glyphRecordIt->mIndex == index )
+ {
+ slot.mImageId = glyphRecordIt->mImageId;
+ slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
+ return true;
+ }
+ }
}
}
slot.mImageId = 0;
+ return false;
}
Vector2 AtlasGlyphManager::GetAtlasSize( uint32_t atlasId )
mAtlasManager.SetNewAtlasSize( size );
}
- void AtlasGlyphManager::Remove( uint32_t imageId )
+ Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
+ {
+ return mAtlasManager.GetPixelFormat( atlasId );
+ }
+
+ const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
+ {
+ mMetrics.mGlyphCount = mFontGlyphRecords.size();
+ mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
+ return mMetrics;
+ }
+
+ void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta )
{
- if ( mAtlasManager.Remove( imageId ) )
+ for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+ fontGlyphRecordIt != mFontGlyphRecords.end();
+ ++fontGlyphRecordIt )
{
- for ( uint32_t i = 0; i < mGlyphRecords.Size(); ++i )
+ if ( fontGlyphRecordIt->mFontId == fontId )
{
- if ( mGlyphRecords[ i ].mImageId == imageId )
+ for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+ glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
+ ++glyphRecordIt )
{
- mGlyphRecords.Remove( mGlyphRecords.Begin() + i );
- return;
+ if ( glyphRecordIt->mImageId == imageId )
+ {
+ glyphRecordIt->mCount += delta;
+ if ( !glyphRecordIt->mCount )
+ {
+ mAtlasManager.Remove( glyphRecordIt->mImageId );
+ fontGlyphRecordIt->mGlyphRecords.Remove( glyphRecordIt );
+ }
+ return;
+ }
}
}
}
}
- Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
- {
- return mAtlasManager.GetPixelFormat( atlasId );
- }
-
+Material AtlasGlyphManager::GetMaterial( uint32_t atlasId ) const
+{
+ return mAtlasManager.GetMaterial( atlasId );
+}
+
+Sampler AtlasGlyphManager::GetSampler( uint32_t atlasId ) const
+{
+ return mAtlasManager.GetSampler( atlasId );
+}
+
- const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
- {
- mMetrics.mGlyphCount = mGlyphRecords.Size();
- mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
- return mMetrics;
- }
-
} // namespace Internal
} // namespace Toolkit
{
public:
- struct GlyphRecord
+ struct GlyphRecordEntry
{
- Text::FontId mFontId;
Text::GlyphIndex mIndex;
uint32_t mImageId;
+ int32_t mCount;
+ };
+
+ struct FontGlyphRecord
+ {
+ Text::FontId mFontId;
+ Vector< GlyphRecordEntry > mGlyphRecords;
};
AtlasGlyphManager();
/**
* @copydoc Toolkit::AtlasGlyphManager::Add
*/
- void Add( const Text::GlyphInfo& glyph,
+ void Add( Text::FontId fontId,
+ const Text::GlyphInfo& glyph,
const BufferImage& bitmap,
Dali::Toolkit::AtlasManager::AtlasSlot& slot );
*/
void GenerateMeshData( uint32_t imageId,
const Vector2& position,
- MeshData& meshData );
+ Toolkit::AtlasManager::Mesh2D& mesh );
/**
* @copydoc Toolkit::AtlasGlyphManager::StitchMesh
*/
- void StitchMesh( MeshData& first,
- const MeshData& second );
+ void StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
+ const Toolkit::AtlasManager::Mesh2D& second );
/**
* @copydoc Toolkit::AtlasGlyphManager::Cached
*/
- void Cached( Text::FontId fontId,
+ bool Cached( Text::FontId fontId,
Text::GlyphIndex index,
Dali::Toolkit::AtlasManager::AtlasSlot& slot );
void SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight );
/**
- * @copydoc Toolkit::AtlasGlyphManager::Remove
- * @copydoc toolkit::AtlasGlyphManager::GetPixelFormat
++ * @copydoc Toolkit::AtlasGlyphManager::GetPixelFormat
*/
- void Remove( uint32_t imageId );
+ Pixel::Format GetPixelFormat( uint32_t atlasId );
/**
- * @copydoc Toolkit::AtlasGlyphManager::GetPixelFormat
- * @copydoc toolkit::AtlasGlyphManager::GetMetrics
++ * @copydoc toolkit::AtlasGlyphManager::AdjustReferenceCount
+ */
- Pixel::Format GetPixelFormat( uint32_t atlasId );
++ void AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta );
+
+ /**
+ * @copydoc Toolkit::AtlasGlyphManager::GetMaterial
+ */
+ Material GetMaterial( uint32_t atlasId ) const;
+
+ /**
+ * @copydoc Toolkit::AtlasGlyphManager::GetMaterial
+ */
+ Sampler GetSampler( uint32_t atlasId ) const;
+
+ /**
+ * @copydoc Toolkit::AtlasGlyphManager::GetMetrics
*/
const Toolkit::AtlasGlyphManager::Metrics& GetMetrics();
/**
- * @copydoc toolkit::AtlasGlyphManager::AdjustReferenceCount
+ * @copydoc Toolkit::AtlasGlyphManager::GetEffectBufferShader
*/
- void AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta );
+ Shader GetEffectBufferShader() const
+ {
+ return mEffectBufferShader;
+ }
+
+ /**
+ * @copydoc Toolkit::AtlasGlyphManager::GetGlyphShadowShader
+ */
+ Shader GetGlyphShadowShader() const
+ {
+ return mShadowShader;
+ }
private:
- Dali::Toolkit::AtlasManager mAtlasManager;
+ Dali::Toolkit::AtlasManager mAtlasManager; ///> Atlas Manager created by GlyphManager
- Vector< GlyphRecord > mGlyphRecords; ///> Cached glyph information
+ std::vector< FontGlyphRecord > mFontGlyphRecords;
- uint32_t mCount;
- Toolkit::AtlasGlyphManager::Metrics mMetrics;
+ Toolkit::AtlasGlyphManager::Metrics mMetrics; ///> Metrics to pass back on GlyphManager status
+ Shader mEffectBufferShader; ///> Shader used to render drop shadow buffer textures
+ Shader mShadowShader; ///> Shader used to render drop shadow into buffer
};
} // namespace Internal
} // namespace Dali
-- #endif // __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__
++ #endif // __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__
{
}
- void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
+ void AtlasGlyphManager::Add( Text::FontId fontId,
+ const Text::GlyphInfo& glyph,
const BufferImage& bitmap,
AtlasManager::AtlasSlot& slot )
{
- GetImplementation(*this).Add( glyph, bitmap, slot );
+ GetImplementation(*this).Add( fontId, glyph, bitmap, slot );
}
void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
const Vector2& position,
- MeshData& meshData )
+ Toolkit::AtlasManager::Mesh2D& mesh )
{
GetImplementation(*this).GenerateMeshData( imageId,
position,
- meshData );
+ mesh );
}
-void AtlasGlyphManager::StitchMesh( MeshData& first,
- const MeshData& second )
+void AtlasGlyphManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
+ const Toolkit::AtlasManager::Mesh2D& second )
{
GetImplementation(*this).StitchMesh( first, second );
}
- void AtlasGlyphManager::Cached( Text::FontId fontId,
+ bool AtlasGlyphManager::Cached( Text::FontId fontId,
Text::GlyphIndex index,
AtlasManager::AtlasSlot& slot )
{
- GetImplementation(*this).Cached( fontId, index, slot );
+ return GetImplementation(*this).Cached( fontId, index, slot );
}
void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight )
return GetImplementation(*this).GetAtlasSize( atlasId );
}
- void AtlasGlyphManager::Remove( uint32_t imageId )
- {
- GetImplementation(*this).Remove( imageId );
- }
-
Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
{
return GetImplementation(*this).GetPixelFormat( atlasId );
}
+Material AtlasGlyphManager::GetMaterial( uint32_t atlasId ) const
+{
+ return GetImplementation(*this).GetMaterial( atlasId );
+}
+
+Sampler AtlasGlyphManager::GetSampler( uint32_t atlasId ) const
+{
+ return GetImplementation(*this).GetSampler( atlasId );
+}
+
const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
{
return GetImplementation(*this).GetMetrics();
}
+ void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta )
+ {
+ GetImplementation(*this).AdjustReferenceCount( fontId, imageId, delta );
+ }
+
+Shader AtlasGlyphManager::GetEffectBufferShader() const
+{
+ return GetImplementation(*this).GetEffectBufferShader();
+}
+
+Shader AtlasGlyphManager::GetGlyphShadowShader() const
+{
+ return GetImplementation(*this).GetGlyphShadowShader();
+}
+
} // namespace Toolkit
} // namespace Dali
/**
* @brief Ask Atlas Manager to add a glyph
*
+ * @param[in] fontId fontId glyph comes from
* @param[in] glyph glyph to add to an atlas
* @param[in] bitmap bitmap to use for glyph addition
* @param[out] slot information returned by atlas manager for addition
*/
- void Add( const Text::GlyphInfo& glyph,
+ void Add( Text::FontId fontId,
+ const Text::GlyphInfo& glyph,
const BufferImage& bitmap,
AtlasManager::AtlasSlot& slot );
*/
void GenerateMeshData( uint32_t imageId,
const Vector2& position,
- MeshData& meshData );
+ Toolkit::AtlasManager::Mesh2D& mesh );
/**
* @brief Stitch Two Meshes together
* @param[in] first first mesh
* @param[in] second second mesh
*/
- void StitchMesh( MeshData& first,
- const MeshData& second );
+ void StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
+ const Toolkit::AtlasManager::Mesh2D& second );
/**
* @brief Check to see if a glyph is being cached
* @param[in] fontId The font that this glyph comes from
* @param[in] index The GlyphIndex of this glyph
* @param[out] slot container holding information about the glyph( mImage = 0 indicates not being cached )
+ *
+ * @return Whether glyph is cached or not ?
*/
- void Cached( Text::FontId fontId,
+ bool Cached( Text::FontId fontId,
Text::GlyphIndex index,
AtlasManager::AtlasSlot& slot );
void SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight );
/**
- * @brief Unreference an image from the atlas and remove from cache if no longer needed
- *
- * @param[in] imageId ID of the image
- */
- void Remove( uint32_t imageId );
-
- /**
* @brief Get the Pixel Format used by an atlas
*
* @param[in] atlasId Id of atlas to check
Pixel::Format GetPixelFormat( uint32_t atlasId );
/**
+ * @brief Get the material used by an atlas
+ *
+ * @param[in] atlasId Id of an atlas
+ *
+ * @return The material used by the atlas
+ */
+ Material GetMaterial( uint32_t atlasId ) const;
+
+ /**
+ * @brief Get the sampler used by an atlas
+ *
+ * @param[in] atlasId Id of an atlas
+ *
+ * @return The sampler used by the atlas
+ */
+ Sampler GetSampler( uint32_t atlasId ) const;
+
+ /**
* @brief Get Glyph Manager metrics
*
* @return const reference to glyph manager metrics
const Metrics& GetMetrics();
/**
+ * @brief Adjust the reference count for an imageId and remove cache entry if it becomes free
+ *
+ * @param[in] fontId the font this image came from
+ * @param[in] imageId The imageId
+ * @param[in] delta adjustment to make to reference count
+ */
+ void AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta );
+
++ /**
+ * @brief Get Shader used for rendering glyph effect buffers
+ *
+ * @return Handle of shader needed
+ */
+ Shader GetEffectBufferShader() const;
+
+ /**
+ * @brief Get Shader used rendering Glyph Shadows
+ *
+ * @return Handle of shader needed
+ */
+ Shader GetGlyphShadowShader() const;
+
private:
explicit DALI_INTERNAL AtlasGlyphManager(Internal::AtlasGlyphManager *impl);
// EXTERNAL INCLUDES
#include <dali/dali.h>
-#include <dali/integration-api/debug.h>
+#include <dali/devel-api/object/property-buffer.h>
+#include <dali/devel-api/rendering/geometry.h>
+#include <dali/devel-api/rendering/renderer.h>
+#include <dali/devel-api/rendering/sampler.h>
+#include <dali/devel-api/rendering/shader.h>
#include <dali/devel-api/text-abstraction/font-client.h>
-#include <dali/devel-api/actors/mesh-actor.h>
-#include <dali/devel-api/geometry/mesh.h>
-
-
+#include <dali/integration-api/debug.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/internal/atlas-manager/atlas-manager.h>
-#include <dali-toolkit/internal/text/line-run.h>
+#include <dali-toolkit/public-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h>
-#include <dali-toolkit/internal/text/rendering/shaders/text-basic-shader.h>
-#include <dali-toolkit/internal/text/rendering/shaders/text-bgra-shader.h>
-#include <dali-toolkit/internal/text/rendering/shaders/text-basic-shadow-shader.h>
using namespace Dali;
using namespace Dali::Toolkit;
Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING");
#endif
- const float ZERO( 0.0f );
- const float HALF( 0.5f );
- const float ONE( 1.0f );
- const float TWO( 2.0f );
- const uint32_t DEFAULT_ATLAS_WIDTH = 512u;
- const uint32_t DEFAULT_ATLAS_HEIGHT = 512u;
+const float ZERO( 0.0f );
+const float HALF( 0.5f );
+const float ONE( 1.0f );
+const float TWO( 2.0f );
+const uint32_t DEFAULT_ATLAS_WIDTH = 512u;
+const uint32_t DEFAULT_ATLAS_HEIGHT = 512u;
}
-
struct AtlasRenderer::Impl : public ConnectionTracker
{
{
Vector4 mColor;
uint32_t mAtlasId;
- MeshData mMeshData;
+ AtlasManager::Mesh2D mMesh;
FrameBufferImage mBuffer;
bool mIsUnderline;
};
uint32_t mMeshRecordIndex;
};
- struct AtlasRecord
+ struct MaxBlockSize
{
- uint32_t mImageId;
+ FontId mFontId;
+ uint32_t mNeededBlockWidth;
+ uint32_t mNeededBlockHeight;
+ };
+
+ struct CheckEntry
+ {
+ FontId mFontId;
Text::GlyphIndex mIndex;
};
- struct MaxBlockSize
+ struct TextCacheEntry
{
FontId mFontId;
- uint32_t mNeededBlockWidth;
- uint32_t mNeededBlockHeight;
+ Text::GlyphIndex mIndex;
+ uint32_t mImageId;
};
Impl()
{
mGlyphManager = AtlasGlyphManager::Get();
mFontClient = TextAbstraction::FontClient::Get();
- mBasicShader = BasicShader::New();
- mBgraShader = BgraShader::New();
- mBasicShadowShader = BasicShadowShader::New();
- mFace.reserve( 6u );
- mFace.push_back( 0 ); mFace.push_back( 2u ); mFace.push_back( 1u );
- mFace.push_back( 1u ); mFace.push_back( 2u ); mFace.push_back( 3u );
+ mQuadVertexFormat[ "aPosition" ] = Property::VECTOR2;
+ mQuadVertexFormat[ "aTexCoord" ] = Property::VECTOR2;
+ mQuadIndexFormat[ "indices" ] = Property::UNSIGNED_INTEGER;
}
void AddGlyphs( const std::vector<Vector2>& positions,
const Vector4& shadowColor,
bool underlineEnabled,
const Vector4& underlineColor,
- float underlineHeight )
+ float underlineHeight,
+ unsigned int depth )
{
AtlasManager::AtlasSlot slot;
std::vector< MeshRecord > meshContainer;
Vector< Extent > extents;
+ TextCacheEntry textCacheEntry;
+ mDepth = static_cast< int >( depth );
float currentUnderlinePosition = ZERO;
float currentUnderlineThickness = underlineHeight;
style = STYLE_DROP_SHADOW;
}
- if ( mImageIds.Size() )
+ if ( mTextCache.Size() )
{
- // Unreference any currently used glyphs
- RemoveText();
+ // Update the glyph cache with any changes to current text
+ RemoveText( glyphs );
}
CalculateBlocksSize( glyphs );
}
const Vector2& position = positions[ i ];
- MeshData newMeshData;
+ AtlasManager::Mesh2D newMesh;
- mGlyphManager.Cached( glyph.fontId, glyph.index, slot );
- if ( slot.mImageId )
- {
- // This glyph already exists so generate mesh data plugging in our supplied position
- mGlyphManager.GenerateMeshData( slot.mImageId, position, newMesh );
- mImageIds.PushBack( slot.mImageId );
- }
- else
+ if ( !mGlyphManager.Cached( glyph.fontId, glyph.index, slot ) )
{
-
// Select correct size for new atlas if needed....?
if ( lastFontId != glyph.fontId )
{
}
// Locate a new slot for our glyph
- mGlyphManager.Add( glyph, bitmap, slot );
-
- // Generate mesh data for this quad, plugging in our supplied position
- if ( slot.mImageId )
- {
- mGlyphManager.GenerateMeshData( slot.mImageId, position, newMesh );
- mImageIds.PushBack( slot.mImageId );
- }
+ mGlyphManager.Add( glyph.fontId, glyph, bitmap, slot );
}
}
- mGlyphManager.GenerateMeshData( slot.mImageId, position, newMeshData );
+
+ // Generate mesh data for this quad, plugging in our supplied position
++ mGlyphManager.GenerateMeshData( slot.mImageId, position, newMesh );
+ textCacheEntry.mFontId = glyph.fontId;
+ textCacheEntry.mImageId = slot.mImageId;
+ textCacheEntry.mIndex = glyph.index;
+ mTextCache.PushBack( textCacheEntry );
+
// Find an existing mesh data object to attach to ( or create a new one, if we can't find one using the same atlas)
StitchTextMesh( meshContainer,
- newMeshData,
+ newMesh,
extents,
textColor,
position.y + glyph.yBearing,
currentUnderlinePosition,
currentUnderlineThickness,
slot );
- lastFontId = glyph.fontId;
+ lastFontId = glyph.fontId;
}
}
{
for ( std::vector< MeshRecord >::iterator mIt = meshContainer.begin(); mIt != meshContainer.end(); ++mIt )
{
- MeshActor actor = MeshActor::New( Mesh::New( mIt->mMeshData ) );
- actor.SetColor( mIt->mColor );
+ Actor actor = CreateMeshActor( *mIt );
- // Ensure that text rendering is unfiltered
- actor.SetFilterMode( FilterMode::NEAREST, FilterMode::NEAREST );
- if ( mIt->mIsUnderline )
+ // Create an effect if necessary
+ if ( style == STYLE_DROP_SHADOW )
{
- actor.SetColorMode( USE_OWN_COLOR );
- }
- else
- {
- actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
- }
-
- // Check to see what pixel format the shader should be
- if ( mGlyphManager.GetPixelFormat( mIt->mAtlasId ) == Pixel::L8 )
- {
- // Create an effect if necessary
- if ( style == STYLE_DROP_SHADOW )
- {
- actor.Add( GenerateShadow( *mIt, shadowOffset, shadowColor ) );
- }
- actor.SetShaderEffect( mBasicShader );
- }
- else
- {
- actor.SetShaderEffect( mBgraShader );
+ actor.Add( GenerateShadow( *mIt, shadowOffset, shadowColor ) );
}
if ( mActor )
mActor = actor;
}
}
- mActor.OffStageSignal().Connect( this, &AtlasRenderer::Impl::OffStageDisconnect );
}
#if defined(DEBUG_ENABLED)
Toolkit::AtlasGlyphManager::Metrics metrics = mGlyphManager.GetMetrics();
#endif
}
+ Actor CreateMeshActor( const MeshRecord& meshRecord )
+ {
+ PropertyBuffer quadVertices = PropertyBuffer::New( mQuadVertexFormat, meshRecord.mMesh.mVertices.Size() );
+ PropertyBuffer quadIndices = PropertyBuffer::New( mQuadIndexFormat, meshRecord.mMesh.mIndices.Size() );
+ quadVertices.SetData( const_cast< AtlasManager::Vertex2D* >( &meshRecord.mMesh.mVertices[ 0 ] ) );
+ quadIndices.SetData( const_cast< unsigned int* >( &meshRecord.mMesh.mIndices[ 0 ] ) );
+
+ Geometry quadGeometry = Geometry::New();
+ quadGeometry.AddVertexBuffer( quadVertices );
+ quadGeometry.SetIndexBuffer( quadIndices );
+
+ Material material = mGlyphManager.GetMaterial( meshRecord.mAtlasId );
+ Dali::Renderer renderer = Dali::Renderer::New( quadGeometry, material );
+ renderer.SetDepthIndex( mDepth );
+ Actor actor = Actor::New();
+ actor.AddRenderer( renderer );
+ actor.SetSize( 1.0f, 1.0f );
+ actor.SetColor( meshRecord.mColor );
+
+ if ( meshRecord.mIsUnderline )
+ {
+ actor.SetColorMode( USE_OWN_COLOR );
+ }
+ else
+ {
+ actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
+ }
+ return actor;
+ }
+
void StitchTextMesh( std::vector< MeshRecord >& meshContainer,
- MeshData& newMeshData,
+ AtlasManager::Mesh2D& newMesh,
Vector< Extent >& extents,
const Vector4& color,
float baseLine,
{
if ( slot.mImageId )
{
- MeshData::VertexContainer verts = newMeshData.GetVertices();
- float left = verts[ 0 ].x;
- float right = verts[ 1 ].x;
+ float left = newMesh.mVertices[ 0 ].mPosition.x;
+ float right = newMesh.mVertices[ 1 ].mPosition.x;
// Check to see if there's a mesh data object that references the same atlas ?
uint32_t index = 0;
if ( slot.mAtlasId == mIt->mAtlasId && color == mIt->mColor )
{
// Stitch the mesh to the existing mesh and adjust any extents
- mGlyphManager.StitchMesh( mIt->mMeshData, newMeshData );
+ mGlyphManager.StitchMesh( mIt->mMesh, newMesh );
AdjustExtents( extents,
meshContainer,
index,
// No mesh data object currently exists that references this atlas, so create a new one
MeshRecord meshRecord;
meshRecord.mAtlasId = slot.mAtlasId;
- meshRecord.mMeshData = newMeshData;
+ meshRecord.mMesh = newMesh;
meshRecord.mColor = color;
meshRecord.mIsUnderline = false;
meshContainer.push_back( meshRecord );
}
}
- // Unreference any glyphs that were used with this actor
- void OffStageDisconnect( Dali::Actor actor )
+ void RemoveText( const Vector<GlyphInfo>& glyphs )
{
- RemoveText();
- }
+ Vector< CheckEntry > checked;
+ CheckEntry checkEntry;
- void RemoveText()
- {
- for ( uint32_t i = 0; i < mImageIds.Size(); ++i )
+ for ( Vector< TextCacheEntry >::Iterator tCit = mTextCache.Begin(); tCit != mTextCache.End(); ++tCit )
{
- mGlyphManager.Remove( mImageIds[ i ] );
+ uint32_t index = tCit->mIndex;
+ uint32_t fontId = tCit->mFontId;
+
+ // Check that this character has not already been checked...
+ bool wasChecked = false;
+ for ( Vector< CheckEntry >::Iterator cEit = checked.Begin(); cEit != checked.End(); ++cEit )
+ {
+ if ( fontId == cEit->mFontId && index == cEit->mIndex )
+ {
+ wasChecked = true;
+ }
+ }
+
+ if ( !wasChecked )
+ {
+
+ int32_t newCount = 0;
+ int32_t oldCount = 0;
+
+ // How many times does this character occur in the old text ?
+ for ( Vector< TextCacheEntry >::Iterator oTcit = mTextCache.Begin(); oTcit != mTextCache.End(); ++oTcit )
+ {
+ if ( fontId == oTcit->mFontId && index == oTcit->mIndex )
+ {
+ oldCount++;
+ }
+ }
+
+ // And how many times in the new ?
+ for ( Vector< GlyphInfo >::Iterator cGit = glyphs.Begin(); cGit != glyphs.End(); ++cGit )
+ {
+ if ( fontId == cGit->fontId && index == cGit->index )
+ {
+ newCount++;
+ }
+ }
+ mGlyphManager.AdjustReferenceCount( fontId, tCit->mImageId, newCount - oldCount );
+ checkEntry.mIndex = index;
+ checkEntry.mFontId = fontId;
+ checked.PushBack( checkEntry );
+ }
}
- mImageIds.Resize( 0 );
+ mTextCache.Resize( 0 );
}
void CalculateBlocksSize( const Vector<GlyphInfo>& glyphs )
const Vector4& underlineColor,
const Vector4& textColor )
{
- MeshData newMeshData;
+ AtlasManager::Mesh2D newMesh;
+ unsigned short faceIndex = 0;
for ( Vector< Extent >::ConstIterator eIt = extents.Begin(); eIt != extents.End(); ++eIt )
{
- MeshData::VertexContainer newVerts;
- newVerts.reserve( 4u );
+ AtlasManager::Vertex2D vert;
uint32_t index = eIt->mMeshRecordIndex;
Vector2 uv = mGlyphManager.GetAtlasSize( meshRecords[ index ].mAtlasId );
float tlx = eIt->mLeft;
float brx = eIt->mRight;
- newVerts.push_back( MeshData::Vertex( Vector3( tlx, baseLine, ZERO ),
- Vector2::ZERO,
- Vector3::ZERO ) );
-
- newVerts.push_back( MeshData::Vertex( Vector3( brx, baseLine, ZERO ),
- Vector2( u, ZERO ),
- Vector3::ZERO ) );
-
- newVerts.push_back( MeshData::Vertex( Vector3( tlx, baseLine + thickness, ZERO ),
- Vector2( ZERO, v ),
- Vector3::ZERO ) );
-
- newVerts.push_back( MeshData::Vertex( Vector3( brx, baseLine + thickness, ZERO ),
- Vector2( u, v ),
- Vector3::ZERO ) );
-
- newMeshData.SetVertices( newVerts );
- newMeshData.SetFaceIndices( mFace );
+ vert.mPosition.x = tlx;
+ vert.mPosition.y = baseLine;
+ vert.mTexCoords.x = ZERO;
+ vert.mTexCoords.y = ZERO;
+ newMesh.mVertices.PushBack( vert );
+
+ vert.mPosition.x = brx;
+ vert.mPosition.y = baseLine;
+ vert.mTexCoords.x = u;
+ newMesh.mVertices.PushBack( vert );
+
+ vert.mPosition.x = tlx;
+ vert.mPosition.y = baseLine + thickness;
+ vert.mTexCoords.x = ZERO;
+ vert.mTexCoords.y = v;
+ newMesh.mVertices.PushBack( vert );
+
+ vert.mPosition.x = brx;
+ vert.mPosition.y = baseLine + thickness;
+ vert.mTexCoords.x = u;
+ newMesh.mVertices.PushBack( vert );
+
+ // Six indices in counter clockwise winding
+ newMesh.mIndices.PushBack( faceIndex + 1u );
+ newMesh.mIndices.PushBack( faceIndex );
+ newMesh.mIndices.PushBack( faceIndex + 2u );
+ newMesh.mIndices.PushBack( faceIndex + 2u );
+ newMesh.mIndices.PushBack( faceIndex + 3u );
+ newMesh.mIndices.PushBack( faceIndex + 1u );
+ faceIndex += 4;
if ( underlineColor == textColor )
{
- mGlyphManager.StitchMesh( meshRecords[ index ].mMeshData, newMeshData );
+ mGlyphManager.StitchMesh( meshRecords[ index ].mMesh, newMesh );
}
else
{
MeshRecord record;
- newMeshData.SetMaterial( meshRecords[ index ].mMeshData.GetMaterial() );
- newMeshData.SetHasNormals( true );
- newMeshData.SetHasColor( false );
- newMeshData.SetHasTextureCoords( true );
- record.mMeshData = newMeshData;
+ record.mMesh = newMesh;
record.mAtlasId = meshRecords[ index ].mAtlasId;
record.mColor = underlineColor;
record.mIsUnderline = true;
}
}
- MeshActor GenerateShadow( MeshRecord& meshRecord,
- const Vector2& shadowOffset,
- const Vector4& shadowColor )
+ Actor GenerateShadow( MeshRecord& meshRecord,
+ const Vector2& shadowOffset,
+ const Vector4& shadowColor )
{
// Scan vertex buffer to determine width and height of effect buffer needed
- MeshData::VertexContainer verts = meshRecord.mMeshData.GetVertices();
- float tlx = verts[ 0 ].x;
- float tly = verts[ 0 ].y;
+ const Vector< AtlasManager::Vertex2D >& verts = meshRecord.mMesh.mVertices;
+ float tlx = verts[ 0 ].mPosition.x;
+ float tly = verts[ 0 ].mPosition.y;
float brx = ZERO;
float bry = ZERO;
- for ( uint32_t i = 0; i < verts.size(); ++i )
+ for ( uint32_t i = 0; i < verts.Size(); ++i )
{
- if ( verts[ i ].x < tlx )
+ if ( verts[ i ].mPosition.x < tlx )
{
- tlx = verts[ i ].x;
+ tlx = verts[ i ].mPosition.x;
}
- if ( verts[ i ].y < tly )
+ if ( verts[ i ].mPosition.y < tly )
{
- tly = verts[ i ].y;
+ tly = verts[ i ].mPosition.y;
}
- if ( verts[ i ].x > brx )
+ if ( verts[ i ].mPosition.x > brx )
{
- brx = verts[ i ].x;
+ brx = verts[ i ].mPosition.x;
}
- if ( verts[ i ].y > bry )
+ if ( verts[ i ].mPosition.y > bry )
{
- bry = verts[ i ].y;
+ bry = verts[ i ].mPosition.y;
}
}
// Create a buffer to render to
meshRecord.mBuffer = FrameBufferImage::New( width, height );
- // Create a mesh actor to contain the post-effect render
- MeshData::VertexContainer vertices;
- MeshData::FaceIndices face;
-
- vertices.push_back( MeshData::Vertex( Vector3( tlx + shadowOffset.x, tly + shadowOffset.y, ZERO ),
- Vector2::ZERO,
- Vector3::ZERO ) );
-
- vertices.push_back( MeshData::Vertex( Vector3( brx + shadowOffset.x, tly + shadowOffset.y, ZERO ),
- Vector2( ONE, ZERO ),
- Vector3::ZERO ) );
-
- vertices.push_back( MeshData::Vertex( Vector3( tlx + shadowOffset.x, bry + shadowOffset.y, ZERO ),
- Vector2( ZERO, ONE ),
- Vector3::ZERO ) );
-
- vertices.push_back( MeshData::Vertex( Vector3( brx + shadowOffset.x, bry + shadowOffset.y, ZERO ),
- Vector2::ONE,
- Vector3::ZERO ) );
-
- MeshData meshData;
- Material newMaterial = Material::New("effect buffer");
- newMaterial.SetDiffuseTexture( meshRecord.mBuffer );
- meshData.SetMaterial( newMaterial );
- meshData.SetVertices( vertices );
- meshData.SetFaceIndices( mFace );
- meshData.SetHasNormals( true );
- meshData.SetHasColor( false );
- meshData.SetHasTextureCoords( true );
- MeshActor actor = MeshActor::New( Mesh::New( meshData ) );
- actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
- actor.SetShaderEffect( mBgraShader );
- actor.SetFilterMode( FilterMode::LINEAR, FilterMode::LINEAR );
- actor.SetSortModifier( 0.1f ); // force behind main text
-
- // Create a sub actor to render once with normalized vertex positions
- MeshData newMeshData;
- MeshData::VertexContainer newVerts;
- MeshData::FaceIndices newFaces;
- MeshData::FaceIndices faces = meshRecord.mMeshData.GetFaces();
- for ( uint32_t i = 0; i < verts.size(); ++i )
- {
- MeshData::Vertex vertex = verts[ i ];
- vertex.x = ( ( vertex.x - tlx ) * divWidth ) - ONE;
- vertex.y = ( ( vertex.y - tly ) * divHeight ) - ONE;
- newVerts.push_back( vertex );
- }
+ // We will render a quad into this buffer
+ unsigned int indices[ 6 ] = { 1, 0, 2, 2, 3, 1 };
+ PropertyBuffer quadVertices = PropertyBuffer::New( mQuadVertexFormat, 4u );
+ PropertyBuffer quadIndices = PropertyBuffer::New( mQuadIndexFormat, sizeof(indices)/sizeof(indices[0]) );
+
+ AtlasManager::Vertex2D vertices[ 4 ] = {
+ { Vector2( tlx + shadowOffset.x, tly + shadowOffset.y ), Vector2( ZERO, ZERO ) },
+ { Vector2( brx + shadowOffset.x, tly + shadowOffset.y ), Vector2( ONE, ZERO ) },
+ { Vector2( tlx + shadowOffset.x, bry + shadowOffset.y ), Vector2( ZERO, ONE ) },
+ { Vector2( brx + shadowOffset.x, bry + shadowOffset.y ), Vector2( ONE, ONE ) } };
+
+ quadVertices.SetData( vertices );
+ quadIndices.SetData( indices );
+
+ Geometry quadGeometry = Geometry::New();
+ quadGeometry.AddVertexBuffer( quadVertices );
+ quadGeometry.SetIndexBuffer( quadIndices );
+
+ Sampler sampler = Sampler::New( meshRecord.mBuffer, "sTexture" );
+ Material material = Material::New( mGlyphManager.GetEffectBufferShader() );
+ material.AddSampler( sampler );
- // Reverse triangle winding order
- uint32_t faceCount = faces.size() / 3;
- for ( uint32_t i = 0; i < faceCount; ++i )
+ Dali::Renderer renderer = Dali::Renderer::New( quadGeometry, material );
+
+ // Ensure shadow is behind the text...
+ renderer.SetDepthIndex( mDepth + CONTENT_DEPTH_INDEX - 1 );
+ Actor actor = Actor::New();
+ actor.AddRenderer( renderer );
+ actor.SetSize( 1.0f, 1.0f );
+
+ // Create a sub actor to render the source with normalized vertex positions
+ Vector< AtlasManager::Vertex2D > normVertexList;
+ for ( uint32_t i = 0; i < verts.Size(); ++i )
{
- uint32_t index = i * 3;
- newFaces.push_back( faces[ index + 2 ] );
- newFaces.push_back( faces[ index + 1 ] );
- newFaces.push_back( faces[ index ] );
+ AtlasManager::Vertex2D vertex = verts[ i ];
+ vertex.mPosition.x = ( ( vertex.mPosition.x - tlx ) * divWidth ) - ONE;
+ vertex.mPosition.y = ( ( vertex.mPosition.y - tly ) * divHeight ) - ONE;
+ normVertexList.PushBack( vertex );
}
- newMeshData.SetMaterial( meshRecord.mMeshData.GetMaterial() );
- newMeshData.SetVertices( newVerts );
- newMeshData.SetFaceIndices( newFaces );
- newMeshData.SetHasNormals( true );
- newMeshData.SetHasColor( false );
- newMeshData.SetHasTextureCoords( true );
-
- MeshActor subActor = MeshActor::New( Mesh::New( newMeshData ) );
+ PropertyBuffer normVertices = PropertyBuffer::New( mQuadVertexFormat, normVertexList.Size() );
+ PropertyBuffer normIndices = PropertyBuffer::New( mQuadIndexFormat, meshRecord.mMesh.mIndices.Size() );
+ normVertices.SetData( const_cast< AtlasManager::Vertex2D* >( &normVertexList[ 0 ] ) );
+ normIndices.SetData( const_cast< unsigned int* >( &meshRecord.mMesh.mIndices[ 0 ] ) );
+
+ Geometry normGeometry = Geometry::New();
+ normGeometry.AddVertexBuffer( normVertices );
+ normGeometry.SetIndexBuffer( normIndices );
+
+ Material normMaterial = Material::New( mGlyphManager.GetGlyphShadowShader() );
+ Sampler normSampler = mGlyphManager.GetSampler( meshRecord.mAtlasId );
+ normMaterial.AddSampler( normSampler );
+ Dali::Renderer normRenderer = Dali::Renderer::New( normGeometry, normMaterial );
+ Actor subActor = Actor::New();
+ subActor.AddRenderer( normRenderer );
+ subActor.SetSize( 1.0f, 1.0f );
subActor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
subActor.SetColor( shadowColor );
- subActor.SetShaderEffect( mBasicShadowShader );
- subActor.SetFilterMode( FilterMode::NEAREST, FilterMode::NEAREST );
// Create a render task to render the effect
RenderTask task = Stage::GetCurrent().GetRenderTaskList().CreateTask();
task.SetRefreshRate( RenderTask::REFRESH_ONCE );
task.FinishedSignal().Connect( this, &AtlasRenderer::Impl::RenderComplete );
actor.Add( subActor );
+
return actor;
}
}
}
- RenderableActor mActor; ///< The actor parent which renders the text
+ Actor mActor; ///< The actor parent which renders the text
AtlasGlyphManager mGlyphManager; ///< Glyph Manager to handle upload and caching
- Vector< uint32_t > mImageIds; ///< A list of imageIDs used by the renderer
TextAbstraction::FontClient mFontClient; ///> The font client used to supply glyph information
- ShaderEffect mBasicShader; ///> Shader used to render L8 glyphs
- ShaderEffect mBgraShader; ///> Shader used to render BGRA glyphs
- ShaderEffect mBasicShadowShader; ///> Shader used to render drop shadow into buffer
std::vector< MaxBlockSize > mBlockSizes; ///> Maximum size needed to contain a glyph in a block within a new atlas
- std::vector< MeshData::FaceIndex > mFace; ///> Face indices for a quad
+ std::vector< uint32_t > mFace; ///> Face indices for a quad
+ Vector< TextCacheEntry > mTextCache;
+ Property::Map mQuadVertexFormat;
+ Property::Map mQuadIndexFormat;
+ int mDepth;
};
Text::RendererPtr AtlasRenderer::New()
return Text::RendererPtr( new AtlasRenderer() );
}
-RenderableActor AtlasRenderer::Render( Text::ViewInterface& view )
+Actor AtlasRenderer::Render( Text::ViewInterface& view, unsigned int depth )
{
UnparentAndReset( mImpl->mActor );
view.GetShadowColor(),
view.IsUnderlineEnabled(),
view.GetUnderlineColor(),
- view.GetUnderlineHeight() );
+ view.GetUnderlineHeight(),
+ depth );
}
return mImpl->mActor;
AtlasRenderer::~AtlasRenderer()
{
+ Vector< GlyphInfo > emptyGlyphs;
+ mImpl->RemoveText( emptyGlyphs );
delete mImpl;
}
#include <limits>
#include <stack>
#include <dali/public-api/actors/image-actor.h>
-#include <dali/devel-api/actors/mesh-actor.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/constraints.h>
-#include <dali/devel-api/geometry/mesh.h>
#include <dali/public-api/object/type-registry.h>
+#include <dali/public-api/size-negotiation/relayout-container.h>
#include <dali/devel-api/object/type-registry-helper.h>
+#include <dali/devel-api/rendering/renderer.h>
#include <dali/devel-api/scripting/scripting.h>
-#include <dali/public-api/size-negotiation/relayout-container.h>
#include <dali/integration-api/debug.h>
// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
#include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
#include <dali-toolkit/public-api/controls/control.h>
*/
struct Background
{
- Actor actor; ///< Either a MeshActor or an ImageActor
+ Actor actor; ///< Background actor
Vector4 color; ///< The color of the actor.
/**
}
};
-/**
- * Creates a white coloured Mesh.
- */
-Mesh CreateMesh()
-{
- Vector3 white( Color::WHITE );
-
- MeshData meshData;
+unsigned int gQuadIndex[6] = { 0, 2, 1, 1, 2, 3 };
- // Create vertices with a white color (actual color is set by actor color)
- MeshData::VertexContainer vertices(4);
- vertices[ 0 ] = MeshData::Vertex( Vector3( -0.5f, -0.5f, 0.0f ), Vector2::ZERO, white );
- vertices[ 1 ] = MeshData::Vertex( Vector3( 0.5f, -0.5f, 0.0f ), Vector2::ZERO, white );
- vertices[ 2 ] = MeshData::Vertex( Vector3( -0.5f, 0.5f, 0.0f ), Vector2::ZERO, white );
- vertices[ 3 ] = MeshData::Vertex( Vector3( 0.5f, 0.5f, 0.0f ), Vector2::ZERO, white );
+Vector2 gQuad[] = {
+ Vector2( -0.5f, -0.5f ),
+ Vector2( 0.5f, -0.5f ),
+ Vector2( -0.5f, 0.5f ),
+ Vector2( 0.5f, 0.5f )
+};
- // Specify all the faces
- MeshData::FaceIndices faces;
- faces.reserve( 6 ); // 2 triangles in Quad
- faces.push_back( 0 ); faces.push_back( 3 ); faces.push_back( 1 );
- faces.push_back( 0 ); faces.push_back( 2 ); faces.push_back( 3 );
+struct VertexWithTexture
+{
+ Vector2 position;
+ Vector2 texCoord;
+};
- // Create the mesh data from the vertices and faces
- meshData.SetMaterial( Material::New( "ControlMaterial" ) );
- meshData.SetVertices( vertices );
- meshData.SetFaceIndices( faces );
- meshData.SetHasColor( true );
+VertexWithTexture gQuadWithTexture[] = {
+ { Vector2( -0.5f, -0.5f ), Vector2( 0.0f, 0.0f ) },
+ { Vector2( 0.5f, -0.5f ), Vector2( 1.0f, 0.0f ) },
+ { Vector2( -0.5f, 0.5f ), Vector2( 0.0f, 1.0f ) },
+ { Vector2( 0.5f, 0.5f ), Vector2( 1.0f, 1.0f ) }
+};
- return Mesh::New( meshData );
-}
+const char* VERTEX_SHADER_COLOR = DALI_COMPOSE_SHADER(
+ attribute mediump vec2 aPosition;\n
+ uniform mediump mat4 uMvpMatrix;\n
+ void main()\n
+ {\n
+ gl_Position = uMvpMatrix * vec4( aPosition, 0.0, 1.0 );\n
+ }\n
+);
+
+const char* FRAGMENT_SHADER_COLOR = DALI_COMPOSE_SHADER(
+ uniform lowp vec4 uBackgroundColor;\n
+ uniform lowp vec4 uColor;\n
+ void main()\n
+ {\n
+ gl_FragColor = uBackgroundColor * uColor;\n
+ }\n
+);
+
+const char* VERTEX_SHADER_TEXTURE = DALI_COMPOSE_SHADER(
+ attribute mediump vec2 aPosition;\n
+ attribute mediump vec2 aTexCoord;\n
+ uniform mediump mat4 uMvpMatrix;\n
+ varying mediump vec2 vTexCoord;\n
+ void main()\n
+ {\n
+ gl_Position = uMvpMatrix * vec4( aPosition, 0.0, 1.0 );\n
+ vTexCoord = aTexCoord;\n
+ }\n
+);
+
+const char* FRAGMENT_SHADER_TEXTURE = DALI_COMPOSE_SHADER(
+ uniform lowp vec4 uBackgroundColor;\n
+ uniform lowp vec4 uColor;\n
+ uniform sampler2D sTexture;\n
+ varying mediump vec2 vTexCoord;\n
+
+ void main()\n
+ {\n
+ gl_FragColor = texture2D( sTexture, vTexCoord ) * uBackgroundColor * uColor;\n
+ }\n
+);
/**
- * Sets all the required properties for the background actor.
+ * @brief Create the background actor for the control.
*
- * @param[in] actor The actor to set the properties on.
- * @param[in] color The required color of the actor.
- */
-void SetupBackgroundActor( Actor actor, const Vector4& color )
-{
- actor.SetColor( color );
- actor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
- actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
- actor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
-}
-
-/**
- * Sets all the required properties for the background actor.
+ * @param[in] actor The parent actor of the background
+ * @param[in] color The background color
+ * @param[in] image If a valid image is supplied this will be the texture used by the background
+ *
+ * @return An actor which will render the background
*
- * @param[in] actor The actor to set the properties on.
- * @param[in] constrainingIndex The property index to constrain the parent's size on.
- * @param[in] color The required color of the actor.
*/
-void SetupBackgroundActorConstrained( Actor actor, Property::Index constrainingIndex, const Vector4& color )
+Actor CreateBackground( Actor parent, const Vector4& color, Image image = Image() )
{
- actor.SetColor( color );
- actor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
- actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
+ PropertyBuffer vertexBuffer;
+ Shader shader;
+ Material material;
+ if( image )
+ {
+ Property::Map vertexFormat;
+ vertexFormat["aPosition"] = Property::VECTOR2;
+ vertexFormat["aTexCoord"] = Property::VECTOR2;
+
+ //Create a vertex buffer for vertex positions and texture coordinates
+ vertexBuffer = PropertyBuffer::New( vertexFormat, 4u );
+ vertexBuffer.SetData( gQuadWithTexture );
+
+ shader = Shader::New( VERTEX_SHADER_TEXTURE, FRAGMENT_SHADER_TEXTURE );
+ Sampler textureSampler = Sampler::New( image, "sTexture" );
+ material = Material::New( shader );
+ material.AddSampler(textureSampler);
+ }
+ else
+ {
+ Property::Map vertexFormat;
+ vertexFormat["aPosition"] = Property::VECTOR2;
+
+ //Create a vertex buffer for vertex positions
+ vertexBuffer = PropertyBuffer::New( vertexFormat, 4u );
+ vertexBuffer.SetData( gQuad );
+
+ shader = Shader::New( VERTEX_SHADER_COLOR, FRAGMENT_SHADER_COLOR );
+ material = Material::New( shader );
+ }
- Constraint constraint = Constraint::New<Vector3>( actor,
- constrainingIndex,
+ //Create the index buffer
+ Property::Map indexFormat;
+ indexFormat["indices"] = Property::UNSIGNED_INTEGER;
+ PropertyBuffer indexBuffer = PropertyBuffer::New( indexFormat, 6u );
+ indexBuffer.SetData(gQuadIndex);
+
+ //Create the geometry
+ Geometry mesh = Geometry::New();
+ mesh.AddVertexBuffer( vertexBuffer );
+ mesh.SetIndexBuffer( indexBuffer );
+
+ //Add uniforms to the shader
+ shader.RegisterProperty( "uBackgroundColor", color );
+
+ //Create the renderer
+ Renderer renderer = Renderer::New( mesh, material );
+ renderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX );
+
+ //Create the actor
+ Actor meshActor = Actor::New();
+ meshActor.SetSize( Vector3::ONE );
+ meshActor.AddRenderer( renderer );
+ meshActor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
+ meshActor.SetColorMode( USE_PARENT_COLOR );
+
+ //Constraint scale of the mesh actor to the size of the control
+ Constraint constraint = Constraint::New<Vector3>( meshActor,
+ Actor::Property::SCALE,
EqualToConstraint() );
constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
constraint.Apply();
+
+ return meshActor;
}
} // unnamed namespace
// Construction & Destruction
Impl(Control& controlImpl)
- : mControlImpl( controlImpl ),
- mStyleName(""),
- mBackground( NULL ),
- mStartingPinchScale( NULL ),
- mKeyEventSignal(),
- mPinchGestureDetector(),
- mPanGestureDetector(),
- mTapGestureDetector(),
- mLongPressGestureDetector(),
- mFlags( Control::ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ),
- mIsKeyboardNavigationSupported( false ),
- mIsKeyboardFocusGroup( false ),
- mAddRemoveBackgroundChild( false )
- {
- }
+: mControlImpl( controlImpl ),
+ mStyleName(""),
+ mBackground( NULL ),
+ mStartingPinchScale( NULL ),
+ mKeyEventSignal(),
+ mPinchGestureDetector(),
+ mPanGestureDetector(),
+ mTapGestureDetector(),
+ mLongPressGestureDetector(),
+ mFlags( Control::ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ),
+ mIsKeyboardNavigationSupported( false ),
+ mIsKeyboardFocusGroup( false ),
+ mAddRemoveBackgroundChild( false )
+{
+}
~Impl()
{
case Toolkit::Control::Property::BACKGROUND_IMAGE:
{
- if ( value.HasKey( "image" ) )
+ Image image = Scripting::NewImage( value );
+ if ( image )
{
- Property::Map imageMap = value.GetValue( "image" ).Get< Property::Map >();
- Image image = Scripting::NewImage( imageMap );
-
- if ( image )
- {
- controlImpl.SetBackgroundImage( image );
- }
+ controlImpl.SetBackgroundImage( image );
}
- else if ( value.Get< Property::Map >().Empty() )
+ else
{
// An empty map means the background is no longer required
controlImpl.ClearBackground();
Property::Map map;
Background* back = controlImpl.mImpl->mBackground;
- if( back )
+ if ( back && back->actor && back->actor.GetRendererAt(0).GetMaterial().GetNumberOfSamplers() > 0)
{
- ImageActor imageActor = ImageActor::DownCast( back->actor );
- if ( imageActor )
+ Image image = back->actor.GetRendererAt(0).GetMaterial().GetSamplerAt(0).GetImage();
+ if ( image )
{
- Property::Map imageMap;
- Scripting::CreatePropertyMap( image, imageMap );
- map[ "image" ] = imageMap;
- Image image = imageActor.GetImage();
+ Scripting::CreatePropertyMap( image, map );
}
}
if ( background.actor )
{
- // Just set the actor color
- background.actor.SetColor( color );
+ Shader shader = background.actor.GetRendererAt(0).GetMaterial().GetShader();
+ shader.SetProperty( shader.GetPropertyIndex("uBackgroundColor"), color );
}
else
{
// Create Mesh Actor
- MeshActor meshActor = MeshActor::New( CreateMesh() );
-
- SetupBackgroundActorConstrained( meshActor, Actor::Property::SCALE, color );
-
- background.actor = meshActor;
- // Set the flag to avoid notifying children
+ Actor actor = CreateBackground(Self(), color );
+ background.actor = actor;
mImpl->mAddRemoveBackgroundChild = true;
// use insert to guarantee its the first child (so that OVERLAY mode works)
- Self().Insert( 0, meshActor );
+ Self().Insert( 0, actor );
mImpl->mAddRemoveBackgroundChild = false;
}
void Control::SetBackgroundImage( Image image )
{
Background& background( mImpl->GetBackground() );
-
- if ( background.actor )
+ if( !background.actor || background.actor.GetRendererAt(0).GetMaterial().GetNumberOfSamplers() == 0)
{
- // Remove Current actor, unset AFTER removal
+ // Remove current actor as it has not texture coordinates
+ if( background.actor )
+ {
+ mImpl->mAddRemoveBackgroundChild = true;
+ Self().Remove( background.actor );
+ mImpl->mAddRemoveBackgroundChild = false;
+ background.actor.Reset();
+ }
+
+ //Create a new actor with texture coordinates
+ Actor actor = CreateBackground(Self(), background.color, image);
mImpl->mAddRemoveBackgroundChild = true;
- Self().Remove( background.actor );
+ // use insert to guarantee its the first child (so that OVERLAY mode works)
+ Self().Insert( 0, actor );
mImpl->mAddRemoveBackgroundChild = false;
- background.actor.Reset();
+ background.actor = actor;
+ }
+ else
+ {
+ //Change sampler image
+ Sampler sampler = background.actor.GetRendererAt(0).GetMaterial().GetSamplerAt(0);
+ sampler.SetImage(image);
}
-
- ImageActor imageActor = ImageActor::New( image );
- SetupBackgroundActor( imageActor, background.color );
-
- // Set the background actor before adding so that we do not inform derived classes
- background.actor = imageActor;
- mImpl->mAddRemoveBackgroundChild = true;
- // use insert to guarantee its the first child (so that OVERLAY mode works)
- Self().Insert( 0, imageActor );
- mImpl->mAddRemoveBackgroundChild = false;
}
void Control::ClearBackground()
void Control::Initialize()
{
+ // Call deriving classes so initialised before styling is applied to them.
+ OnInitialize();
+
if( mImpl->mFlags & REQUIRES_STYLE_CHANGE_SIGNALS )
{
Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
// Register for style changes
styleManager.StyleChangeSignal().Connect( this, &Control::OnStyleChange );
- // SetTheme
+ // Apply the current style
GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
}
{
SetKeyboardNavigationSupport( true );
}
-
- // Calling deriving classes
- OnInitialize();
}
void Control::OnInitialize()
if ( focusGained )
{
- // signals are allocated dynamically when someone connects
- if ( !mImpl->mKeyInputFocusGainedSignal.Empty() )
- {
+ // signals are allocated dynamically when someone connects
+ if ( !mImpl->mKeyInputFocusGainedSignal.Empty() )
+ {
mImpl->mKeyInputFocusGainedSignal.Emit( handle );
- }
+ }
}
else
{
}
}
-void Control::OnStageConnection()
+void Control::OnStageConnection( unsigned int depth )
{
+ unsigned int controlRendererCount = Self().GetRendererCount();
+ for( unsigned int i(0); i<controlRendererCount; ++i )
+ {
+ Renderer controlRenderer = Self().GetRendererAt(i);
+ if( controlRenderer )
+ {
+ controlRenderer.SetDepthIndex( CONTENT_DEPTH_INDEX+depth );
+ }
+ }
+
+ if( mImpl->mBackground )
+ {
+ Renderer backgroundRenderer = mImpl->mBackground->actor.GetRendererAt( 0 );
+ if(backgroundRenderer)
+ {
+ backgroundRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX+depth );
+ }
+ }
}
void Control::OnStageDisconnection()
Vector3 Control::GetNaturalSize()
{
+ //Control's natural size is the size of its background image if it has been set, or ZERO otherwise
+ Vector3 naturalSize = Vector3::ZERO;
if( mImpl->mBackground )
{
- Actor actor = mImpl->mBackground->actor;
- if( actor )
+ Material backgroundMaterial = mImpl->mBackground->actor.GetRendererAt(0).GetMaterial();
+ if( backgroundMaterial.GetNumberOfSamplers() > 0 )
{
- return actor.GetNaturalSize();
+ Image backgroundImage = backgroundMaterial.GetSamplerAt(0).GetImage();
+ if( backgroundImage )
+ {
+ naturalSize.x = backgroundImage.GetWidth();
+ naturalSize.y = backgroundImage.GetHeight();
+ }
}
}
- return Vector3();
+
+ return naturalSize;
}
float Control::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
/**
* @copydoc CustomActorImpl::OnStageConnection()
*/
- virtual void OnStageConnection();
+ virtual void OnStageConnection( unsigned int depth );
/**
* @copydoc CustomActorImpl::OnStageDisconnection()
* @param handle
* @return implementation
*/
- Internal::Control& GetImplementation( Dali::Toolkit::Control& handle );
+ DALI_IMPORT_API Internal::Control& GetImplementation( Dali::Toolkit::Control& handle );
/**
* @brief Get implementation from the handle
* @param handle
* @return implementation
*/
- const Internal::Control& GetImplementation( const Dali::Toolkit::Control& handle );
+ DALI_IMPORT_API const Internal::Control& GetImplementation( const Dali::Toolkit::Control& handle );
} // namespace Internal