#include <dali-toolkit/devel-api/controls/buttons/toggle-button.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/controls/popup/popup.h>
+#include <dali-toolkit/devel-api/controls/table-view/table-view.h>
#include <dali/devel-api/actors/actor-devel.h>
#include <dali/devel-api/common/stage.h>
#include <cstdlib>
actorB.SetProperty( Dali::Actor::Property::POSITION, positionB );
scrollView.Add(actorB);
+ TableView tableView = TableView::New( 2, 2 ); // 2 by 2 grid.
+ tableView.SetProperty( Actor::Property::SIZE, Vector2(100.0f, 100.0f) );
+ scrollView.Add(tableView);
+
+ PushButton actorC = PushButton::New();
+ actorC.SetProperty( Actor::Property::SIZE, Vector2(50.0f, 50.0f) );
+ tableView.AddChild( actorC, TableView::CellPosition( 0, 0 ) );
+
+ PushButton actorD = PushButton::New();
+ application.GetScene().Add( actorD );
+
Wait(application);
auto* accessibleParent = dynamic_cast<DevelControl::ControlAccessible*>(Dali::Accessibility::Accessible::Get(scrollView));
DALI_TEST_CHECK(accessibleA);
auto* accessibleB = dynamic_cast<DevelControl::ControlAccessible*>(Dali::Accessibility::Accessible::Get(actorB));
DALI_TEST_CHECK(accessibleB);
+ auto* accessibleC = dynamic_cast<DevelControl::ControlAccessible*>(Dali::Accessibility::Accessible::Get(actorC));
+ DALI_TEST_CHECK(accessibleC);
accessibleA->GrabHighlight(); // == scrollView.ScrollTo(actorA)
Wait(application);
accessibleB->GrabHighlight(); // == scrollView.ScrollTo(actorB)
Wait(application);
+ // scrollView is ancestor of actorC
+ // This should work without a crash
+ accessibleC->GrabHighlight(); // == scrollView.ScrollTo(actorC)
+ Wait(application);
+
+ // negative testcase calling ScrollToChild using non-child actor
+ accessibleParent->ScrollToChild(actorD);
+
Dali::Accessibility::TestEnableSC( false );
END_TEST;
}
#include <dali-toolkit-test-suite-utils.h>
#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
-#include <dali-toolkit/internal/visuals/wireframe/wireframe-visual.h>
-#include <dali-toolkit/internal/visuals/visual-base-impl.h>
#include <dali-toolkit/internal/visuals/text/text-visual.h>
+#include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/visuals/wireframe/wireframe-visual.h>
#include <dali-toolkit/dali-toolkit.h>
namespace
{
-const char* TEST_IMAGE_FILE_NAME = "image_01.jpg";
-const char* TEST_NPATCH_FILE_NAME = "image_01.9.jpg";
-const char* TEST_SVG_FILE_NAME = TEST_RESOURCE_DIR "/svg1.svg";
-const char* TEST_GIF_FILE_NAME = TEST_RESOURCE_DIR "/anim.gif";
+const char* TEST_IMAGE_FILE_NAME = "image_01.jpg";
+const char* TEST_NPATCH_FILE_NAME = "image_01.9.jpg";
+const char* TEST_SVG_FILE_NAME = TEST_RESOURCE_DIR "/svg1.svg";
+const char* TEST_GIF_FILE_NAME = TEST_RESOURCE_DIR "/anim.gif";
-const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
+const std::string DEFAULT_FONT_DIR("/resources/fonts");
-void TestDebugVisual( Integration::Scene scene, Visual::Base& visual, Visual::Type actualType, Vector2 expectedNaturalSize )
+void TestDebugVisual(Integration::Scene scene, Visual::Base& visual, DevelVisual::Type actualType, Vector2 expectedNaturalSize)
{
{
- auto& impl = GetImplementation( visual );
- DALI_TEST_CHECK( &typeid( Toolkit::Internal::WireframeVisual ) == &typeid( impl ) );
+ auto& impl = GetImplementation(visual);
+ DALI_TEST_CHECK(&typeid(Toolkit::Internal::WireframeVisual) == &typeid(impl));
}
Vector2 naturalSize;
- visual.GetNaturalSize( naturalSize );
- DALI_TEST_EQUALS( naturalSize, expectedNaturalSize, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+ visual.GetNaturalSize(naturalSize);
+ DALI_TEST_EQUALS(naturalSize, expectedNaturalSize, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
Property::Map propertyMap;
- visual.CreatePropertyMap( propertyMap );
- Property::Value* typeValue = propertyMap.Find( Toolkit::Visual::Property::TYPE, Property::INTEGER );
- if ( typeValue )
+ visual.CreatePropertyMap(propertyMap);
+ Property::Value* typeValue = propertyMap.Find(Toolkit::Visual::Property::TYPE, Property::INTEGER);
+ if(typeValue)
{
- DALI_TEST_CHECK( typeValue->Get<int>() == actualType );
+ DALI_TEST_CHECK(typeValue->Get<int>() == actualType);
}
- DummyControl actor = DummyControl::New();
+ DummyControl actor = DummyControl::New();
DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
- dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
- scene.Add( actor );
+ dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual);
+ scene.Add(actor);
- DALI_TEST_EQUALS( actor.GetRendererCount(), 1, TEST_LOCATION );
- if( actor.GetRendererCount() > 0 )
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 1, TEST_LOCATION);
+ if(actor.GetRendererCount() > 0)
{
- Geometry geometry = actor.GetRendererAt( 0 ).GetGeometry();
- DALI_TEST_CHECK( geometry.GetType() == Geometry::LINES );
+ Geometry geometry = actor.GetRendererAt(0).GetGeometry();
+ DALI_TEST_CHECK(geometry.GetType() == Geometry::LINES);
}
}
+void TestDebugVisual(Integration::Scene scene, Visual::Base& visual, Visual::Type actualType, Vector2 expectedNaturalSize)
+{
+ TestDebugVisual(scene, visual, (DevelVisual::Type)actualType, expectedNaturalSize);
}
+} // namespace
void dali_debug_rendering_startup(void)
{
{
EnvironmentVariable::SetTestingEnvironmentVariable(true);
ToolkitTestApplication application;
- tet_infoline( "UtcDaliDebugRenderingGetVisual1: Request visual with a Property::Map" );
+ tet_infoline("UtcDaliDebugRenderingGetVisual1: Request visual with a Property::Map");
VisualFactory factory = VisualFactory::Get();
- DALI_TEST_CHECK( factory );
+ DALI_TEST_CHECK(factory);
// Test that color visual is replaced with debug visual
Property::Map propertyMap1;
- propertyMap1.Insert(Visual::Property::TYPE, Visual::COLOR);
- propertyMap1.Insert(ColorVisual::Property::MIX_COLOR, Color::BLUE);
+ propertyMap1.Insert(Visual::Property::TYPE, Visual::COLOR);
+ propertyMap1.Insert(ColorVisual::Property::MIX_COLOR, Color::BLUE);
Visual::Base colorVisual = factory.CreateVisual(propertyMap1);
- DALI_TEST_CHECK( colorVisual );
- TestDebugVisual( application.GetScene(), colorVisual, Visual::COLOR, Vector2::ZERO );
+ DALI_TEST_CHECK(colorVisual);
+ TestDebugVisual(application.GetScene(), colorVisual, Visual::COLOR, Vector2::ZERO);
// Test that border visual is replaced with debug visual
Property::Map propertyMap2;
- propertyMap2.Insert(Visual::Property::TYPE, Visual::BORDER);
- propertyMap2.Insert(BorderVisual::Property::COLOR, Color::BLUE);
- propertyMap2.Insert(BorderVisual::Property::SIZE, 2.f);
+ propertyMap2.Insert(Visual::Property::TYPE, Visual::BORDER);
+ propertyMap2.Insert(BorderVisual::Property::COLOR, Color::BLUE);
+ propertyMap2.Insert(BorderVisual::Property::SIZE, 2.f);
Visual::Base borderVisual = factory.CreateVisual(propertyMap2);
- DALI_TEST_CHECK( borderVisual );
- TestDebugVisual( application.GetScene(), borderVisual, Visual::BORDER, Vector2::ZERO );
+ DALI_TEST_CHECK(borderVisual);
+ TestDebugVisual(application.GetScene(), borderVisual, Visual::BORDER, Vector2::ZERO);
// Test that gradient visual is replaced with debug visual
Property::Map propertyMap3;
- propertyMap3.Insert(Visual::Property::TYPE, Visual::GRADIENT);
+ propertyMap3.Insert(Visual::Property::TYPE, Visual::GRADIENT);
Vector2 start(-1.f, -1.f);
Vector2 end(1.f, 1.f);
propertyMap3.Insert(GradientVisual::Property::START_POSITION, start);
propertyMap3.Insert(GradientVisual::Property::END_POSITION, end);
propertyMap3.Insert(GradientVisual::Property::SPREAD_METHOD, GradientVisual::SpreadMethod::REPEAT);
Property::Array stopOffsets;
- stopOffsets.PushBack( 0.2f );
- stopOffsets.PushBack( 0.8f );
+ stopOffsets.PushBack(0.2f);
+ stopOffsets.PushBack(0.8f);
propertyMap3.Insert(GradientVisual::Property::STOP_OFFSET, stopOffsets);
Property::Array stopColors;
- stopColors.PushBack( Color::RED );
- stopColors.PushBack( Color::GREEN );
+ stopColors.PushBack(Color::RED);
+ stopColors.PushBack(Color::GREEN);
propertyMap3.Insert(GradientVisual::Property::STOP_COLOR, stopColors);
Visual::Base gradientVisual = factory.CreateVisual(propertyMap3);
- DALI_TEST_CHECK( gradientVisual );
- TestDebugVisual( application.GetScene(), gradientVisual, Visual::GRADIENT, Vector2::ZERO );
+ DALI_TEST_CHECK(gradientVisual);
+ TestDebugVisual(application.GetScene(), gradientVisual, Visual::GRADIENT, Vector2::ZERO);
// Test that image visual is replaced with debug visual
Property::Map propertyMap4;
- propertyMap4.Insert( Toolkit::Visual::Property::TYPE, Visual::IMAGE );
- propertyMap4.Insert( ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME );
- propertyMap4.Insert( ImageVisual::Property::DESIRED_WIDTH, 50.f );
- propertyMap4.Insert( ImageVisual::Property::DESIRED_HEIGHT, 100.f );
- Visual::Base imageVisual = factory.CreateVisual( propertyMap4 );
- DALI_TEST_CHECK( imageVisual );
- TestDebugVisual( application.GetScene(), imageVisual, Visual::IMAGE, Vector2( 50.f, 100.f ) );
+ propertyMap4.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE);
+ propertyMap4.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME);
+ propertyMap4.Insert(ImageVisual::Property::DESIRED_WIDTH, 50.f);
+ propertyMap4.Insert(ImageVisual::Property::DESIRED_HEIGHT, 100.f);
+ Visual::Base imageVisual = factory.CreateVisual(propertyMap4);
+ DALI_TEST_CHECK(imageVisual);
+ TestDebugVisual(application.GetScene(), imageVisual, Visual::IMAGE, Vector2(50.f, 100.f));
// Test that SVG visual is replaced with debug visual
// TEST_SVG_FILE:
// <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
// </svg>
Property::Map propertyMap5;
- propertyMap5.Insert( Toolkit::Visual::Property::TYPE, Visual::SVG );
- propertyMap5.Insert( ImageVisual::Property::URL, TEST_SVG_FILE_NAME );
- Visual::Base svgVisual = factory.CreateVisual( propertyMap5 );
- DALI_TEST_CHECK( svgVisual );
- TestDebugVisual( application.GetScene(), svgVisual, Visual::SVG, Vector2(100.f, 100.f) );
+ propertyMap5.Insert(Toolkit::Visual::Property::TYPE, Visual::SVG);
+ propertyMap5.Insert(ImageVisual::Property::URL, TEST_SVG_FILE_NAME);
+ Visual::Base svgVisual = factory.CreateVisual(propertyMap5);
+ DALI_TEST_CHECK(svgVisual);
+ TestDebugVisual(application.GetScene(), svgVisual, Visual::SVG, Vector2(100.f, 100.f));
// Test that AnimatedImageVisual is replaced with debug visual
// TEST_GIF_FILE: anim.gif
// resolution: 50*50, frame count: 4, frame delay: 0.2 second for each frame
Property::Map propertyMap6;
- propertyMap6.Insert( Toolkit::Visual::Property::TYPE, Visual::ANIMATED_IMAGE );
- propertyMap6.Insert( ImageVisual::Property::URL, TEST_GIF_FILE_NAME );
- Visual::Base animatedImageVisual = factory.CreateVisual( propertyMap6 );
- DALI_TEST_CHECK( animatedImageVisual );
- TestDebugVisual( application.GetScene(), animatedImageVisual, Visual::ANIMATED_IMAGE, Vector2(50.f, 50.f) );
+ propertyMap6.Insert(Toolkit::Visual::Property::TYPE, Visual::ANIMATED_IMAGE);
+ propertyMap6.Insert(ImageVisual::Property::URL, TEST_GIF_FILE_NAME);
+ Visual::Base animatedImageVisual = factory.CreateVisual(propertyMap6);
+ DALI_TEST_CHECK(animatedImageVisual);
+ TestDebugVisual(application.GetScene(), animatedImageVisual, Visual::ANIMATED_IMAGE, Vector2(50.f, 50.f));
// Test that text visual is replaced with debug visual
// Load some fonts to get the same metrics on different platforms.
TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
- fontClient.SetDpi( 96u, 96u );
+ fontClient.SetDpi(96u, 96u);
- char* pathNamePtr = get_current_dir_name();
- const std::string pathName( pathNamePtr );
- free( pathNamePtr );
+ char* pathNamePtr = get_current_dir_name();
+ const std::string pathName(pathNamePtr);
+ free(pathNamePtr);
- fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" );
+ fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf");
Property::Map propertyMap7;
- propertyMap7.Insert( Toolkit::Visual::Property::TYPE, Visual::TEXT );
- propertyMap7.Insert( TextVisual::Property::ENABLE_MARKUP, true );
- propertyMap7.Insert( TextVisual::Property::TEXT, "<font family='TizenSans' size='12'>Hello world</font>" );
- propertyMap7.Insert( TextVisual::Property::MULTI_LINE, true );
+ propertyMap7.Insert(Toolkit::Visual::Property::TYPE, Visual::TEXT);
+ propertyMap7.Insert(TextVisual::Property::ENABLE_MARKUP, true);
+ propertyMap7.Insert(TextVisual::Property::TEXT, "<font family='TizenSans' size='12'>Hello world</font>");
+ propertyMap7.Insert(TextVisual::Property::MULTI_LINE, true);
- Visual::Base textVisual = factory.CreateVisual( propertyMap7 );
- DALI_TEST_CHECK( textVisual );
+ Visual::Base textVisual = factory.CreateVisual(propertyMap7);
+ DALI_TEST_CHECK(textVisual);
{
- auto&& impl = GetImplementation( textVisual );
- DALI_TEST_CHECK( &typeid( Toolkit::Internal::WireframeVisual ) == &typeid( impl ) );
+ auto&& impl = GetImplementation(textVisual);
+ DALI_TEST_CHECK(&typeid(Toolkit::Internal::WireframeVisual) == &typeid(impl));
}
Vector2 naturalSize;
- textVisual.GetNaturalSize( naturalSize );
- DALI_TEST_EQUALS( naturalSize, Vector2( 82.f, 20.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+ textVisual.GetNaturalSize(naturalSize);
+ DALI_TEST_EQUALS(naturalSize, Vector2(82.f, 20.f), Math::MACHINE_EPSILON_1000, TEST_LOCATION);
- const float height = textVisual.GetHeightForWidth( 40.f );
- DALI_TEST_EQUALS( height, 60.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+ const float height = textVisual.GetHeightForWidth(40.f);
+ DALI_TEST_EQUALS(height, 60.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
// Test that NPatchVisual is replaced with debug visual
// TEST_NPATCH_FILE_NAME: image_01.9.jpg
Property::Map propertyMap8;
- propertyMap8.Insert( Toolkit::Visual::Property::TYPE, Visual::N_PATCH );
- propertyMap8.Insert( ImageVisual::Property::URL, TEST_NPATCH_FILE_NAME );
- Visual::Base nPatchVisual = factory.CreateVisual( propertyMap8 );
- DALI_TEST_CHECK( nPatchVisual );
- TestDebugVisual( application.GetScene(), nPatchVisual, Visual::N_PATCH, Vector2::ZERO );
+ propertyMap8.Insert(Toolkit::Visual::Property::TYPE, Visual::N_PATCH);
+ propertyMap8.Insert(ImageVisual::Property::URL, TEST_NPATCH_FILE_NAME);
+ Visual::Base nPatchVisual = factory.CreateVisual(propertyMap8);
+ DALI_TEST_CHECK(nPatchVisual);
+ TestDebugVisual(application.GetScene(), nPatchVisual, Visual::N_PATCH, Vector2::ZERO);
EnvironmentVariable::SetTestingEnvironmentVariable(false);
END_TEST;
{
EnvironmentVariable::SetTestingEnvironmentVariable(true);
ToolkitTestApplication application;
- tet_infoline( "UtcDaliDebugRenderingGetVisual2: Request visual with various parameters" );
+ tet_infoline("UtcDaliDebugRenderingGetVisual2: Request visual with various parameters");
VisualFactory factory = VisualFactory::Get();
- DALI_TEST_CHECK( factory );
+ DALI_TEST_CHECK(factory);
// Test that color visual is replaced with debug visual
Dali::Property::Map map;
- map[ Toolkit::Visual::Property::TYPE ] = Visual::COLOR;
- map[ ColorVisual::Property::MIX_COLOR ] = Color::CYAN;
+ map[Toolkit::Visual::Property::TYPE] = Visual::COLOR;
+ map[ColorVisual::Property::MIX_COLOR] = Color::CYAN;
- Visual::Base colorVisual = factory.CreateVisual( map);
- DALI_TEST_CHECK( colorVisual );
- TestDebugVisual( application.GetScene(), colorVisual, Visual::COLOR, Vector2::ZERO );
+ Visual::Base colorVisual = factory.CreateVisual(map);
+ DALI_TEST_CHECK(colorVisual);
+ TestDebugVisual(application.GetScene(), colorVisual, Visual::COLOR, Vector2::ZERO);
// Test that border visual is replaced with debug visual
map.Clear();
- map[ Toolkit::Visual::Property::TYPE ] = Visual::BORDER;
- map[ BorderVisual::Property::COLOR ] = Color::GREEN;
- map[ BorderVisual::Property::SIZE ] = 2.f;
- Visual::Base borderVisual = factory.CreateVisual( map );
- DALI_TEST_CHECK( borderVisual );
- TestDebugVisual( application.GetScene(), borderVisual, Visual::BORDER, Vector2::ZERO );
+ map[Toolkit::Visual::Property::TYPE] = Visual::BORDER;
+ map[BorderVisual::Property::COLOR] = Color::GREEN;
+ map[BorderVisual::Property::SIZE] = 2.f;
+ Visual::Base borderVisual = factory.CreateVisual(map);
+ DALI_TEST_CHECK(borderVisual);
+ TestDebugVisual(application.GetScene(), borderVisual, Visual::BORDER, Vector2::ZERO);
// Test that image visual is replaced with debug visual
map.Clear();
- map[ Toolkit::Visual::Property::TYPE ] = Visual::IMAGE;
- map[ ImageVisual::Property::URL ] = TEST_IMAGE_FILE_NAME;
- Visual::Base imageVisual = factory.CreateVisual( map );
- DALI_TEST_CHECK( imageVisual );
- TestDebugVisual( application.GetScene(), imageVisual, Visual::IMAGE, Vector2(64.0f, 64.0f /* Broken Image Size */ ));
+ map[Toolkit::Visual::Property::TYPE] = Visual::IMAGE;
+ map[ImageVisual::Property::URL] = TEST_IMAGE_FILE_NAME;
+ Visual::Base imageVisual = factory.CreateVisual(map);
+ DALI_TEST_CHECK(imageVisual);
+ TestDebugVisual(application.GetScene(), imageVisual, Visual::IMAGE, Vector2(64.0f, 64.0f /* Broken Image Size */));
// Test that n patch visual is replaced with debug visual
- Visual::Base nPatchVisual = factory.CreateVisual( TEST_NPATCH_FILE_NAME, ImageDimensions() );
- DALI_TEST_CHECK( nPatchVisual );
- TestDebugVisual( application.GetScene(), nPatchVisual, Visual::N_PATCH, Vector2::ZERO );
+ Visual::Base nPatchVisual = factory.CreateVisual(TEST_NPATCH_FILE_NAME, ImageDimensions());
+ DALI_TEST_CHECK(nPatchVisual);
+ TestDebugVisual(application.GetScene(), nPatchVisual, Visual::N_PATCH, Vector2::ZERO);
EnvironmentVariable::SetTestingEnvironmentVariable(false);
END_TEST;
}
-
int UtcDaliDebugRenderingGetVisual3(void)
{
- EnvironmentVariable::SetTestingEnvironmentVariable( true );
+ EnvironmentVariable::SetTestingEnvironmentVariable(true);
ToolkitTestApplication application;
- tet_infoline( "UtcDaliDebugRenderingGetVisual3: Request visual with various parameters" );
+ tet_infoline("UtcDaliDebugRenderingGetVisual3: Request visual with various parameters");
VisualFactory factory = VisualFactory::Get();
- DALI_TEST_CHECK( factory );
+ DALI_TEST_CHECK(factory);
// Test that image visual is replaced with debug visual
Dali::Property::Map map;
- map[ Toolkit::Visual::Property::TYPE ] = Visual::IMAGE;
- map[ ImageVisual::Property::URL ] = TEST_IMAGE_FILE_NAME;
- Visual::Base imageVisual = factory.CreateVisual( map );
- DALI_TEST_CHECK( imageVisual );
- TestDebugVisual( application.GetScene(), imageVisual, Visual::IMAGE, Vector2(64.0f, 64.0f /* Broken Image Size */ ));
+ map[Toolkit::Visual::Property::TYPE] = Visual::IMAGE;
+ map[ImageVisual::Property::URL] = TEST_IMAGE_FILE_NAME;
+ Visual::Base imageVisual = factory.CreateVisual(map);
+ DALI_TEST_CHECK(imageVisual);
+ TestDebugVisual(application.GetScene(), imageVisual, Visual::IMAGE, Vector2(64.0f, 64.0f /* Broken Image Size */));
// Test that image visual with null string don't make visual
map.Clear();
- map[ Toolkit::Visual::Property::TYPE ] = Visual::IMAGE;
- map[ ImageVisual::Property::URL ] = "";
- Visual::Base emptyVisual = factory.CreateVisual( map );
- DALI_TEST_CHECK( emptyVisual );
- TestDebugVisual( application.GetScene(), emptyVisual, Visual::WIREFRAME, Vector2::ZERO);
+ map[Toolkit::Visual::Property::TYPE] = Visual::IMAGE;
+ map[ImageVisual::Property::URL] = "";
+ Visual::Base emptyVisual = factory.CreateVisual(map);
+ DALI_TEST_CHECK(emptyVisual);
+ TestDebugVisual(application.GetScene(), emptyVisual, Visual::WIREFRAME, Vector2::ZERO);
- tet_infoline( "Check that GetVisualObject returns the actual WireframeVisual" );
- Toolkit::Internal::Visual::Base& visualImpl = GetImplementation( emptyVisual ).GetVisualObject();
- DALI_TEST_CHECK( dynamic_cast< Toolkit::Internal::WireframeVisual* >( &visualImpl ) );
+ tet_infoline("Check that GetVisualObject returns the actual WireframeVisual");
+ Toolkit::Internal::Visual::Base& visualImpl = GetImplementation(emptyVisual).GetVisualObject();
+ DALI_TEST_CHECK(dynamic_cast<Toolkit::Internal::WireframeVisual*>(&visualImpl));
- tet_infoline( "Compare the returned emptyVisual with the visual implementation, should be the same" );
- DALI_TEST_CHECK( emptyVisual.GetObjectPtr() == &visualImpl );
+ tet_infoline("Compare the returned emptyVisual with the visual implementation, should be the same");
+ DALI_TEST_CHECK(emptyVisual.GetObjectPtr() == &visualImpl);
// Test that image view with empty property map don't make visual even DebugRendering is enabled.
map.Clear();
// Test that image view with empty property value don't make visual even DebugRendering is enabled.
Property::Value emptyValue;
- ImageView imageView2 = ImageView::New();
+ ImageView imageView2 = ImageView::New();
imageView2.SetProperty(Control::Property::BACKGROUND, emptyValue);
imageView2.SetProperty(ImageView::Property::IMAGE, emptyValue);
// Test that image view with invalid property value don't make visual even DebugRendering is enabled.
Property::Value invalidValue(static_cast<int>(3));
- ImageView imageView3 = ImageView::New();
+ ImageView imageView3 = ImageView::New();
imageView3.SetProperty(Control::Property::BACKGROUND, invalidValue);
imageView3.SetProperty(ImageView::Property::IMAGE, invalidValue);
application.SendNotification();
application.Render();
- DALI_TEST_EQUALS( imageView1.GetRendererCount(), 0u, TEST_LOCATION );
- DALI_TEST_EQUALS( imageView2.GetRendererCount(), 0u, TEST_LOCATION );
- DALI_TEST_EQUALS( imageView3.GetRendererCount(), 0u, TEST_LOCATION );
+ DALI_TEST_EQUALS(imageView1.GetRendererCount(), 0u, TEST_LOCATION);
+ DALI_TEST_EQUALS(imageView2.GetRendererCount(), 0u, TEST_LOCATION);
+ DALI_TEST_EQUALS(imageView3.GetRendererCount(), 0u, TEST_LOCATION);
EnvironmentVariable::SetTestingEnvironmentVariable(false);
END_TEST;
}
+int UtcDaliDebugRenderingGetVisual4(void)
+{
+ EnvironmentVariable::SetTestingEnvironmentVariable(true);
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliDebugRenderingGetVisual4: Request visual with empty URL and empty Array");
+
+ VisualFactory factory = VisualFactory::Get();
+ DALI_TEST_CHECK(factory);
+
+ // Test that image visual with null string don't make visual
+ for(auto type : {DevelVisual::IMAGE, DevelVisual::ANIMATED_IMAGE, DevelVisual::SVG, DevelVisual::N_PATCH, DevelVisual::ANIMATED_VECTOR_IMAGE})
+ {
+ Dali::Property::Map map;
+ map[Toolkit::Visual::Property::TYPE] = type;
+ map[ImageVisual::Property::URL] = "";
+ Visual::Base emptyVisual = factory.CreateVisual(map);
+ DALI_TEST_CHECK(emptyVisual);
+ TestDebugVisual(application.GetScene(), emptyVisual, Visual::WIREFRAME, Vector2::ZERO);
+
+ tet_infoline("Check that GetVisualObject returns the actual WireframeVisual");
+ Toolkit::Internal::Visual::Base& visualImpl = GetImplementation(emptyVisual).GetVisualObject();
+ DALI_TEST_CHECK(dynamic_cast<Toolkit::Internal::WireframeVisual*>(&visualImpl));
+
+ tet_infoline("Compare the returned emptyVisual with the visual implementation, should be the same");
+ DALI_TEST_CHECK(emptyVisual.GetObjectPtr() == &visualImpl);
+ }
+
+ // Test that image visual with empty array don't make visual
+ for(auto type : {Visual::IMAGE, Visual::ANIMATED_IMAGE})
+ {
+ Dali::Property::Map map;
+ Dali::Property::Array emptyArray;
+ map[Toolkit::Visual::Property::TYPE] = type;
+ map[ImageVisual::Property::URL] = emptyArray;
+ Visual::Base emptyVisual = factory.CreateVisual(map);
+ DALI_TEST_CHECK(emptyVisual);
+ TestDebugVisual(application.GetScene(), emptyVisual, Visual::WIREFRAME, Vector2::ZERO);
+
+ tet_infoline("Check that GetVisualObject returns the actual WireframeVisual");
+ Toolkit::Internal::Visual::Base& visualImpl = GetImplementation(emptyVisual).GetVisualObject();
+ DALI_TEST_CHECK(dynamic_cast<Toolkit::Internal::WireframeVisual*>(&visualImpl));
+
+ tet_infoline("Compare the returned emptyVisual with the visual implementation, should be the same");
+ DALI_TEST_CHECK(emptyVisual.GetObjectPtr() == &visualImpl);
+ }
+
+ EnvironmentVariable::SetTestingEnvironmentVariable(false);
+ END_TEST;
+}
int UtcDaliDebugRenderingGetVisualObject01(void)
{
- EnvironmentVariable::SetTestingEnvironmentVariable( true );
+ EnvironmentVariable::SetTestingEnvironmentVariable(true);
ToolkitTestApplication application;
VisualFactory factory = VisualFactory::Get();
- DALI_TEST_CHECK( factory );
+ DALI_TEST_CHECK(factory);
- tet_infoline( "Create a TextVisual when debugging is enabled, thus creating a proxy Wireframe Visual" );
+ tet_infoline("Create a TextVisual when debugging is enabled, thus creating a proxy Wireframe Visual");
Dali::Property::Map map;
- map[ Toolkit::Visual::Property::TYPE ] = Visual::TEXT;
- map[ TextVisual::Property::TEXT ] = "Hello";
+ map[Toolkit::Visual::Property::TYPE] = Visual::TEXT;
+ map[TextVisual::Property::TEXT] = "Hello";
- Visual::Base textVisual = factory.CreateVisual( map);
- DALI_TEST_CHECK( textVisual );
+ Visual::Base textVisual = factory.CreateVisual(map);
+ DALI_TEST_CHECK(textVisual);
- tet_infoline( "Check that GetVisualObject returns the actual TextVisual" );
- Toolkit::Internal::Visual::Base& visualImpl = GetImplementation( textVisual ).GetVisualObject();
- DALI_TEST_CHECK( dynamic_cast< Toolkit::Internal::TextVisual* >( &visualImpl ) );
+ tet_infoline("Check that GetVisualObject returns the actual TextVisual");
+ Toolkit::Internal::Visual::Base& visualImpl = GetImplementation(textVisual).GetVisualObject();
+ DALI_TEST_CHECK(dynamic_cast<Toolkit::Internal::TextVisual*>(&visualImpl));
- tet_infoline( "Compare the returned TextVisual with the visual implementation, should differ" );
- DALI_TEST_CHECK( textVisual.GetObjectPtr() != &visualImpl );
+ tet_infoline("Compare the returned TextVisual with the visual implementation, should differ");
+ DALI_TEST_CHECK(textVisual.GetObjectPtr() != &visualImpl);
- EnvironmentVariable::SetTestingEnvironmentVariable( false );
+ EnvironmentVariable::SetTestingEnvironmentVariable(false);
END_TEST;
}
ToolkitTestApplication application;
VisualFactory factory = VisualFactory::Get();
- DALI_TEST_CHECK( factory );
+ DALI_TEST_CHECK(factory);
- tet_infoline( "Create a TextVisual without debugging enabled, thus no proxy Wireframe Visual" );
+ tet_infoline("Create a TextVisual without debugging enabled, thus no proxy Wireframe Visual");
Dali::Property::Map map;
- map[ Toolkit::Visual::Property::TYPE ] = Visual::TEXT;
- map[ TextVisual::Property::TEXT ] = "Hello";
+ map[Toolkit::Visual::Property::TYPE] = Visual::TEXT;
+ map[TextVisual::Property::TEXT] = "Hello";
- Visual::Base textVisual = factory.CreateVisual( map);
- DALI_TEST_CHECK( textVisual );
+ Visual::Base textVisual = factory.CreateVisual(map);
+ DALI_TEST_CHECK(textVisual);
- tet_infoline( "Check that GetVisualObject returns the actual TextVisual" );
- Toolkit::Internal::Visual::Base& visualImpl = GetImplementation( textVisual ).GetVisualObject();
- DALI_TEST_CHECK( dynamic_cast< Toolkit::Internal::TextVisual* >( &visualImpl ) );
+ tet_infoline("Check that GetVisualObject returns the actual TextVisual");
+ Toolkit::Internal::Visual::Base& visualImpl = GetImplementation(textVisual).GetVisualObject();
+ DALI_TEST_CHECK(dynamic_cast<Toolkit::Internal::TextVisual*>(&visualImpl));
- tet_infoline( "Compare the returned TextVisual with the visual implementation, should be the same" );
- DALI_TEST_CHECK( textVisual.GetObjectPtr() == &visualImpl );
+ tet_infoline("Compare the returned TextVisual with the visual implementation, should be the same");
+ DALI_TEST_CHECK(textVisual.GetObjectPtr() == &visualImpl);
END_TEST;
}
ToolkitTestApplication application;
VisualFactory factory = VisualFactory::Get();
- DALI_TEST_CHECK( factory );
+ DALI_TEST_CHECK(factory);
- tet_infoline( "Create a WireframeVisual without debugging enabled, thus no proxy Wireframe Visual either" );
+ tet_infoline("Create a WireframeVisual without debugging enabled, thus no proxy Wireframe Visual either");
Dali::Property::Map map;
- map[ Toolkit::Visual::Property::TYPE ] = Visual::WIREFRAME;
+ map[Toolkit::Visual::Property::TYPE] = Visual::WIREFRAME;
- Visual::Base textVisual = factory.CreateVisual( map);
- DALI_TEST_CHECK( textVisual );
+ Visual::Base textVisual = factory.CreateVisual(map);
+ DALI_TEST_CHECK(textVisual);
- tet_infoline( "Check that GetVisualObject returns the WireframeVisual" );
- Toolkit::Internal::Visual::Base& visualImpl = GetImplementation( textVisual ).GetVisualObject();
- DALI_TEST_CHECK( dynamic_cast< Toolkit::Internal::WireframeVisual* >( &visualImpl ) );
+ tet_infoline("Check that GetVisualObject returns the WireframeVisual");
+ Toolkit::Internal::Visual::Base& visualImpl = GetImplementation(textVisual).GetVisualObject();
+ DALI_TEST_CHECK(dynamic_cast<Toolkit::Internal::WireframeVisual*>(&visualImpl));
- tet_infoline( "Compare the returned Visual with the visual implementation, should be the same" );
- DALI_TEST_CHECK( textVisual.GetObjectPtr() == &visualImpl );
+ tet_infoline("Compare the returned Visual with the visual implementation, should be the same");
+ DALI_TEST_CHECK(textVisual.GetObjectPtr() == &visualImpl);
END_TEST;
}
int UtcDaliDebugRenderingRenderText(void)
{
- EnvironmentVariable::SetTestingEnvironmentVariable( true );
+ EnvironmentVariable::SetTestingEnvironmentVariable(true);
ToolkitTestApplication application;
- tet_infoline( "Ensure we can render text when in debug mode" );
+ tet_infoline("Ensure we can render text when in debug mode");
try
{
- Toolkit::TextLabel label = TextLabel::New( "Hello" );
- application.GetScene().Add( label );
- DALI_TEST_CHECK( true );
- } catch( ... )
+ Toolkit::TextLabel label = TextLabel::New("Hello");
+ application.GetScene().Add(label);
+ DALI_TEST_CHECK(true);
+ }
+ catch(...)
{
- DALI_TEST_CHECK( false );
+ DALI_TEST_CHECK(false);
}
END_TEST;
SET_DEPTH_COMPARE_OP = 1 << 24,
SET_DEPTH_TEST_ENABLE = 1 << 25,
SET_DEPTH_WRITE_ENABLE = 1 << 26,
+ DRAW_NATIVE = 1 << 27,
};
std::ostream& operator<<(std::ostream& os, Graphics::StencilOp op);
{
DRAW,
DRAW_INDEXED,
- DRAW_INDEXED_INDIRECT
+ DRAW_INDEXED_INDIRECT,
+ DRAW_NATIVE
};
Type type{}; ///< Type of the draw call
uint32_t drawCount;
uint32_t stride;
} drawIndexedIndirect;
+
+ struct
+ {
+ Graphics::DrawNativeInfo drawNativeInfo;
+ } drawNative;
};
};
data.bindUniformBuffers = rhs.data.bindUniformBuffers;
break;
}
+ case CommandType::DRAW_NATIVE:
+ {
+ data.draw.type = rhs.data.draw.type;
+ data.draw.drawNative = rhs.data.draw.drawNative;
+ break;
+ }
case CommandType::DRAW:
{
data.draw.type = rhs.data.draw.type;
data.bindPipeline = rhs.data.bindPipeline;
break;
}
+ case CommandType::DRAW_NATIVE:
+ {
+ data.draw.type = rhs.data.draw.type;
+ data.draw.drawNative = rhs.data.draw.drawNative;
+ break;
+ }
case CommandType::DRAW:
{
data.draw.type = rhs.data.draw.type;
mCallStack.PushCall("ExecuteCommandBuffers", "");
}
+ void DrawNative(const Graphics::DrawNativeInfo* drawInfo)
+ {
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::DRAW_NATIVE;
+ auto& cmd = mCommands.back().data.draw;
+ cmd.type = DrawCallDescriptor::Type::DRAW_NATIVE;
+ cmd.drawNative.drawNativeInfo = *drawInfo;
+ mCallStack.PushCall("DrawNative", "");
+ }
+
void Draw(
uint32_t vertexCount,
uint32_t instanceCount,
BindPipeline(currentPipeline);
break;
}
+ case CommandType::DRAW_NATIVE:
+ {
+ auto info = &cmd.data.draw.drawNative.drawNativeInfo;
+ CallbackBase::ExecuteReturn<bool>(*info->callback, info->userData);
+ break;
+ }
case CommandType::DRAW:
{
if(currentPipeline)
DALI_TEST_EQUALS(-1, control.GetProperty(DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID).Get<int>(), TEST_LOCATION);
DALI_TEST_EQUALS(-1, control.GetProperty(DevelControl::Property::UP_FOCUSABLE_ACTOR_ID).Get<int>(), TEST_LOCATION);
DALI_TEST_EQUALS(-1, control.GetProperty(DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID).Get<int>(), TEST_LOCATION);
+ DALI_TEST_EQUALS(-1, control.GetProperty( DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID ).Get< int >(), TEST_LOCATION);
+ DALI_TEST_EQUALS(-1, control.GetProperty( DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID ).Get< int >(), TEST_LOCATION);
control.SetProperty(DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID, 1);
DALI_TEST_EQUALS(1, control.GetProperty(DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID).Get<int>(), TEST_LOCATION);
DALI_TEST_EQUALS(17, control.GetProperty(DevelControl::Property::UP_FOCUSABLE_ACTOR_ID).Get<int>(), TEST_LOCATION);
control.SetProperty(DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID, 18);
DALI_TEST_EQUALS(18, control.GetProperty(DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID).Get<int>(), TEST_LOCATION);
+ control.SetProperty(DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID, 19);
+ DALI_TEST_EQUALS(19, control.GetProperty( DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID ).Get< int >(), TEST_LOCATION);
+ control.SetProperty(DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID, 20);
+ DALI_TEST_EQUALS(20, control.GetProperty( DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID ).Get< int >(), TEST_LOCATION);
END_TEST;
}
: mInterfaceVerified(interfaceVerified),
mCurrentFocusedActor(),
mProposedActorToFocus(),
- mDirection(Control::KeyboardFocus::LEFT)
+ mDirection(Control::KeyboardFocus::LEFT),
+ mDeviceName("")
{
}
- Actor GetNextFocusableActor(Actor currentFocusedActor, Actor proposedActorToFocus, Control::KeyboardFocus::Direction direction)
+ Actor GetNextFocusableActor(Actor currentFocusedActor, Actor proposedActorToFocus, Control::KeyboardFocus::Direction direction, const std::string& deviceName)
{
tet_infoline("Verifying CustomAlgorithm()");
mCurrentFocusedActor = currentFocusedActor;
mProposedActorToFocus = proposedActorToFocus;
mDirection = direction;
+ mDeviceName = deviceName;
return mProposedActorToFocus;
}
mCurrentFocusedActor = Actor();
mProposedActorToFocus = Actor();
mDirection = Control::KeyboardFocus::LEFT;
+ mDeviceName = "";
}
bool& mInterfaceVerified;
Actor mCurrentFocusedActor;
Actor mProposedActorToFocus;
Control::KeyboardFocus::Direction mDirection;
+ std::string mDeviceName;
};
// Functors to test whether PreFocusChange signal is emitted when the keyboard focus is about to change
preFocusChangeCallback.Reset();
bool customAlgorithmInterfaceVerified = false;
+ std::string deviceName = "deviceName";
CustomAlgorithm customAlgorithm(customAlgorithmInterfaceVerified);
Toolkit::DevelKeyboardFocusManager::SetCustomAlgorithm(manager, customAlgorithm);
// Move the focus towards right
- DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == false);
+ DALI_TEST_CHECK(Toolkit::DevelKeyboardFocusManager::MoveFocus(manager, Control::KeyboardFocus::RIGHT, deviceName) == false);
// Because no layout control in the stage and the first actor is focused, it should invoke CustomAlgorithm
DALI_TEST_CHECK(customAlgorithm.mInterfaceVerified);
DALI_TEST_CHECK(customAlgorithm.mCurrentFocusedActor == Actor());
DALI_TEST_CHECK(customAlgorithm.mProposedActorToFocus == Actor());
DALI_TEST_CHECK(customAlgorithm.mDirection == Control::KeyboardFocus::RIGHT);
+ DALI_TEST_EQUALS(customAlgorithm.mDeviceName, deviceName, TEST_LOCATION );
customAlgorithm.Reset();
// Check that the focus is set on the first actor
focusChangedCallback.Reset();
// Move the focus towards right
- DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == false);
+ DALI_TEST_CHECK(Toolkit::DevelKeyboardFocusManager::MoveFocus(manager, Control::KeyboardFocus::RIGHT, deviceName) == false);
// Because no layout control in the stage and the first actor is focused, it should invoke CustomAlgorithm
DALI_TEST_CHECK(customAlgorithm.mInterfaceVerified);
DALI_TEST_CHECK(customAlgorithm.mCurrentFocusedActor == first);
DALI_TEST_CHECK(customAlgorithm.mProposedActorToFocus == Actor());
DALI_TEST_CHECK(customAlgorithm.mDirection == Control::KeyboardFocus::RIGHT);
+ DALI_TEST_EQUALS(customAlgorithm.mDeviceName, deviceName, TEST_LOCATION );
customAlgorithm.Reset();
// Check that the focus is set on the second actor
focusChangedCallback.Reset();
// Move the focus towards up
- DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::UP) == false);
+ DALI_TEST_CHECK(Toolkit::DevelKeyboardFocusManager::MoveFocus(manager, Control::KeyboardFocus::UP, deviceName) == false);
// Because no layout control in the stage and no actor is focused, it should invoke CustomAlgorithm
DALI_TEST_CHECK(customAlgorithm.mInterfaceVerified);
DALI_TEST_CHECK(customAlgorithm.mCurrentFocusedActor == second);
DALI_TEST_CHECK(customAlgorithm.mProposedActorToFocus == Actor());
DALI_TEST_CHECK(customAlgorithm.mDirection == Control::KeyboardFocus::UP);
+ DALI_TEST_EQUALS(customAlgorithm.mDeviceName, deviceName, TEST_LOCATION );
customAlgorithm.Reset();
DALI_TEST_CHECK(!focusChangedCallback.mSignalVerified);
button1.SetProperty(Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID, Property::Value((int)button2.GetProperty<int>(Actor::Property::ID)));
button1.SetProperty(Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID, Property::Value((int)button2.GetProperty<int>(Actor::Property::ID)));
button1.SetProperty(Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID, Property::Value((int)button2.GetProperty<int>(Actor::Property::ID)));
+ button1.SetProperty(Toolkit::DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID, Property::Value((int)button2.GetProperty< int >( Actor::Property::ID)));
+ button1.SetProperty(Toolkit::DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID, Property::Value((int)button2.GetProperty< int >( Actor::Property::ID)));
// set the navigation properties of button2
button2.SetProperty(Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID, Property::Value((int)button1.GetProperty<int>(Actor::Property::ID)));
button2.SetProperty(Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID, Property::Value((int)button1.GetProperty<int>(Actor::Property::ID)));
button2.SetProperty(Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID, Property::Value((int)button1.GetProperty<int>(Actor::Property::ID)));
button2.SetProperty(Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID, Property::Value((int)button1.GetProperty<int>(Actor::Property::ID)));
+ button2.SetProperty(Toolkit::DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID, Property::Value((int)button1.GetProperty< int >( Actor::Property::ID)));
+ button2.SetProperty(Toolkit::DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID, Property::Value((int)button1.GetProperty< int >( Actor::Property::ID)));
// Move the focus towards left
DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::LEFT) == true);
DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button1);
focusChangedCallback.Reset();
+ // Move the focus towards clockwise
+ DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::CLOCKWISE) == true);
+
+ // Confirm whether focus is moved to button2
+ DALI_TEST_EQUALS(button2.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION );
+ DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+ DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button1);
+ DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button2);
+ focusChangedCallback.Reset();
+
+ // Move the focus towards clockwise
+ DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::COUNTER_CLOCKWISE) == true);
+
+ // Confirm whether focus is moved to button1
+ DALI_TEST_EQUALS(button1.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION );
+ DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+ DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button2);
+ DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button1);
+ focusChangedCallback.Reset();
+
// Create a 1x1 table view and try to move focus inside it
TableView tableView = TableView::New(1, 1);
application.GetScene().Add(tableView);
// button1 -- button2
button1.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f));
button2.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 0.0f));
+ button1.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ button2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
// flush the queue and render once
application.SendNotification();
// Move the focus towards left, The focus move will success because the default algorithm is enabled.
// [button1] -- button2
DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::LEFT) == true);
- // Confirm whether focus is moved to button2
+ // Confirm whether focus is moved to button1
DALI_TEST_EQUALS(button1.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION);
DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button2);
DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button1);
focusChangedCallback.Reset();
+ // Clears focus.
+ manager.ClearFocus();
+ // There is no actor focused.
+ // button1 -- button2
+ DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
+
+ // Move the focus towards right, The focus is on the actor closest to the top left of the window.
+ // [button1] -- button2
+ DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == true);
+
+ // Confirm whether focus is moved to button1
+ DALI_TEST_EQUALS(button1.GetProperty<int>(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION);
+ DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+ DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == Actor());
+ DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button1);
+ focusChangedCallback.Reset();
+
+
END_TEST;
}
END_TEST;
}
+
+int UtcDaliKeyboardFocusManagerChangeFocusDirectionByCustomWheelEvent(void)
+{
+ ToolkitTestApplication application;
+
+ tet_infoline(" UtcDaliKeyboardFocusManagerChangeFocusDirectionByCustomWheelEvent");
+ Dali::Integration::Scene scene = application.GetScene();
+
+ KeyboardFocusManager manager = KeyboardFocusManager::Get();
+ DALI_TEST_CHECK(manager);
+
+ bool focusChangedSignalVerified = false;
+ FocusChangedCallback focusChangedCallback(focusChangedSignalVerified);
+ manager.FocusChangedSignal().Connect( &focusChangedCallback, &FocusChangedCallback::Callback );
+
+ Integration::WheelEvent clockwiseEvent(Integration::WheelEvent::CUSTOM_WHEEL, 0, 0u, Vector2(0.0f, 0.0f), 1, 1000u);
+ Integration::WheelEvent counterClockwiseEvent(Integration::WheelEvent::CUSTOM_WHEEL, 0, 0u, Vector2(0.0f, 0.0f), -1, 1100u);
+
+ // Create the first button
+ PushButton first = PushButton::New();
+ first.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE,true);
+ scene.Add(first);
+
+ // Create the second button
+ PushButton second = PushButton::New();
+ second.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE,true);
+ scene.Add(second);
+
+ // set the navigation properties
+ first.SetProperty(Toolkit::DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID, Property::Value((int)second.GetProperty< int >( Actor::Property::ID )));
+ second.SetProperty(Toolkit::DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID, Property::Value((int)first.GetProperty< int >( Actor::Property::ID )));
+
+ // Set the focus to the first actor
+ DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
+ DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
+ DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+ DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == Actor());
+ DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == first);
+ focusChangedCallback.Reset();
+
+ // Send the clockwise wheel event to move the focus towards clockwise
+ application.ProcessEvent(clockwiseEvent);
+ DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
+ DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+ DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == first);
+ DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == second);
+ focusChangedCallback.Reset();
+
+ // Send the counter clockwise wheel event to move the focus towards count clockwise
+ application.ProcessEvent(counterClockwiseEvent);
+ DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
+ DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
+ DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == second);
+ DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == first);
+ focusChangedCallback.Reset();
+
+ // Clear the focus
+ manager.ClearFocus();
+
+ END_TEST;
+}
}
} // unnamed namespace
-ControlAccessible::ControlAccessible(Dali::Actor self, Dali::Accessibility::Role role, bool modal)
-: ActorAccessible(self),
- mIsModal(modal)
+ControlAccessible::ControlAccessible(Dali::Actor self)
+: ActorAccessible(self)
{
- auto control = Dali::Toolkit::Control::DownCast(Self());
+ auto control = Toolkit::Control::DownCast(self);
Internal::Control& internalControl = Toolkit::Internal::GetImplementation(control);
Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get(internalControl);
- if(controlImpl.mAccessibilityRole == Dali::Accessibility::Role::UNKNOWN)
- {
- controlImpl.mAccessibilityRole = role;
- }
- Self().PropertySetSignal().Connect(&controlImpl, [this, &controlImpl](Dali::Handle& handle, Dali::Property::Index index, Dali::Property::Value value) {
+ self.PropertySetSignal().Connect(&controlImpl, [this, &controlImpl](Dali::Handle& handle, Dali::Property::Index index, Dali::Property::Value value) {
if(this->Self() != Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
{
return;
Dali::Accessibility::States ControlAccessible::CalculateStates()
{
- Dali::Actor self = Self();
- Dali::Accessibility::States state;
- state[Dali::Accessibility::State::FOCUSABLE] = self.GetProperty<bool>(Actor::Property::KEYBOARD_FOCUSABLE);
- state[Dali::Accessibility::State::FOCUSED] = Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor() == self;
+ using Dali::Accessibility::State;
- if(self.GetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE).GetType() == Dali::Property::NONE)
- {
- state[Dali::Accessibility::State::HIGHLIGHTABLE] = false;
- }
- else
- {
- state[Dali::Accessibility::State::HIGHLIGHTABLE] = self.GetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE).Get<bool>();
- }
+ Dali::Actor self = Self();
+ Dali::Accessibility::States states;
- state[Dali::Accessibility::State::HIGHLIGHTED] = GetCurrentlyHighlightedActor() == self;
- state[Dali::Accessibility::State::ENABLED] = true;
- state[Dali::Accessibility::State::SENSITIVE] = true;
- state[Dali::Accessibility::State::VISIBLE] = self.GetProperty<bool>(Actor::Property::VISIBLE);
+ states[State::FOCUSABLE] = self.GetProperty<bool>(Actor::Property::KEYBOARD_FOCUSABLE);
+ states[State::FOCUSED] = Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor() == self;
+ states[State::HIGHLIGHTABLE] = self.GetProperty<bool>(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE);
+ states[State::HIGHLIGHTED] = GetCurrentlyHighlightedActor() == self;
+ states[State::ENABLED] = true;
+ states[State::SENSITIVE] = true;
+ states[State::VISIBLE] = self.GetProperty<bool>(Actor::Property::VISIBLE);
+ states[State::SHOWING] = IsShowing();
+ states[State::DEFUNCT] = !self.GetProperty(Dali::DevelActor::Property::CONNECTED_TO_SCENE).Get<bool>();
- if(mIsModal)
- {
- state[Dali::Accessibility::State::MODAL] = true;
- }
- state[Dali::Accessibility::State::SHOWING] = IsShowing();
- state[Dali::Accessibility::State::DEFUNCT] = !self.GetProperty(Dali::DevelActor::Property::CONNECTED_TO_SCENE).Get<bool>();
- return state;
+ return states;
}
Dali::Accessibility::States ControlAccessible::GetStates()
// Clear the old highlight.
if(oldHighlightedActor)
{
- auto oldHighlightObject = dynamic_cast<Dali::Accessibility::Component*>(Internal::Control::Impl::GetAccessibilityObject(oldHighlightedActor));
- if(oldHighlightObject)
+ auto oldHighlightedObject = Dali::Accessibility::Component::DownCast(Accessible::Get(oldHighlightedActor));
+ if(oldHighlightedObject)
{
- oldHighlightObject->ClearHighlight();
+ oldHighlightedObject->ClearHighlight();
}
}
/**
* @brief Represents the Accessible object for Dali::Toolkit::Control and derived classes
*
- * You can create a derived class (and register it using SetAccessibilityConstructor)
+ * You can create a derived class (and override Control::CreateAccessibleObject)
* in order to customize Accessibility for a given control.
*
- * @see Dali::Toolkit::DevelControl::SetAccessibilityConstructor
* @see Dali::Accessibility::Accessible
* @see Dali::Accessibility::Component
* @see Dali::Accessibility::Collection
protected:
Vector2 mLastPosition{0.0f, 0.0f};
Dali::WeakHandle<Dali::Actor> mCurrentHighlightActor;
- bool mIsModal = false;
- bool mIsRoot = false;
void ScrollToSelf();
bool IsShowing();
public:
- ControlAccessible(Dali::Actor self, Dali::Accessibility::Role role, bool modal = false);
+ ControlAccessible(Dali::Actor self);
/**
* @copydoc Dali::Accessibility::Accessible::GetName()
GetControlImplementation(control).mAccessibilityRelations.clear();
}
-void SetAccessibilityConstructor(Dali::Actor control, std::function<std::unique_ptr<Dali::Accessibility::Accessible>(Dali::Actor)> constructor)
-{
- GetControlImplementation(Toolkit::Control::DownCast(control)).mAccessibilityConstructor = constructor;
-}
-
void AppendAccessibilityAttribute(Toolkit::Control control, const std::string& key, const std::string& value)
{
GetControlImplementation(control).AppendAccessibilityAttribute(key, value);
bool ClearAccessibilityHighlight(Toolkit::Control control)
{
- auto* accessible = Dali::Accessibility::Component::DownCast(GetControlImplementation(control).GetAccessibilityObject());
-
- return accessible ? accessible->ClearHighlight() : false;
+ return GetControlImplementation(control).GetAccessibleObject()->ClearHighlight();
}
bool GrabAccessibilityHighlight(Toolkit::Control control)
{
- auto* accessible = Dali::Accessibility::Component::DownCast(GetControlImplementation(control).GetAccessibilityObject());
-
- return accessible ? accessible->GrabHighlight() : false;
+ return GetControlImplementation(control).GetAccessibleObject()->GrabHighlight();
}
Dali::Accessibility::States GetAccessibilityStates(Toolkit::Control control)
{
- auto* accessible = GetControlImplementation(control).GetAccessibilityObject();
-
- return accessible->GetStates();
+ return GetControlImplementation(control).GetAccessibleObject()->GetStates();
}
void NotifyAccessibilityStateChange(Toolkit::Control control, Dali::Accessibility::States states, bool recurse)
{
- GetControlImplementation(control).GetAccessibilityObject()->NotifyAccessibilityStateChange(std::move(states), recurse);
+ GetControlImplementation(control).GetAccessibleObject()->NotifyAccessibilityStateChange(std::move(states), recurse);
}
} // namespace DevelControl
* @note The representative Accessible object will not appear in the AT-SPI tree.
*/
ACCESSIBILITY_HIDDEN,
+
+ /**
+ * @brief The actor ID of the clockwise focusable control.
+ * @details Name "clockwiseFocusableActorId", type Property::INTEGER.
+ *
+ */
+ CLOCKWISE_FOCUSABLE_ACTOR_ID,
+
+ /**
+ * @brief The actor ID of the conter-clockwise focusable control.
+ * @details Name "counterClockwiseFocusableActorId", type Property::INTEGER.
+ *
+ */
+ COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID,
};
} // namespace Property
*/
DALI_TOOLKIT_API void NotifyAccessibilityStateChange(Toolkit::Control control, Dali::Accessibility::States states, bool recurse);
-/**
- * The method allows to set specific constructor for creating accessibility structure
- *
- * Thank to this method hierarchy of accessibility objects can be based on internal hierarchy of Actors.
- * It prevents from necessity of keeping two trees synchronized.
- * The method should be called inside OnInitialize method of all classes inheriting from Control.
- *
- * Possible usage can be as follows:
- * @code
- * SetAccessibilityConstructor( []( Dali::Actor actor ) {
- return std::unique_ptr< Dali::Accessibility::Accessible >(
- new ControlAccessible( actor, Dali::Accessibility::Role::DIALOG, true ) );
- } );
- * @endcode
- *
- * param constructor callback creating Accessible object
- */
-DALI_TOOLKIT_API void SetAccessibilityConstructor(Dali::Actor control, std::function<std::unique_ptr<Dali::Accessibility::Accessible>(Dali::Actor)> constructor);
-
} // namespace DevelControl
} // namespace Toolkit
Actor GetNearestFocusableActor(Actor rootActor, Actor focusedActor, Toolkit::Control::KeyboardFocus::Direction direction)\r
{\r
Actor nearestActor;\r
- if(!focusedActor || !rootActor)\r
+ if(!rootActor)\r
{\r
return nearestActor;\r
}\r
\r
- Rect<float> focusedRect = DevelActor::CalculateScreenExtents(focusedActor);\r
+ Rect<float> focusedRect;\r
+ if (!focusedActor)\r
+ {\r
+ // If there is no currently focused actor, it is searched based on the upper left corner of the current window.\r
+ Rect<float> rootRect = DevelActor::CalculateScreenExtents(rootActor);\r
+ focusedRect = Rect<float>(rootRect.x, rootRect.y, 0.f, 0.f);\r
+ }\r
+ else\r
+ {\r
+ focusedRect = DevelActor::CalculateScreenExtents(focusedActor);\r
+ }\r
+\r
\r
// initialize the best candidate to something impossible\r
// (so the first plausible actor will become the best choice)\r
return GetImpl(keyboardFocusManager).IsDefaultAlgorithmEnabled();
}
+bool MoveFocus(KeyboardFocusManager keyboardFocusManager, Control::KeyboardFocus::Direction direction, const std::string& deviceName)
+{
+ return GetImpl(keyboardFocusManager).MoveFocus(direction, deviceName);
+}
+
} // namespace DevelKeyboardFocusManager
} // namespace Toolkit
* @param[in] current The current focused actor
* @param[in] proposed The proposed focused actor
* @param[in] direction The direction of focus movement
+ * @param[in] deviceName The name of the device where the key event occurred.
* @return A handle to the next focusable actor
*/
- virtual Actor GetNextFocusableActor(Actor current, Actor proposed, Control::KeyboardFocus::Direction direction) = 0;
+ virtual Actor GetNextFocusableActor(Actor current, Actor proposed, Control::KeyboardFocus::Direction direction, const std::string& deviceName = "") = 0;
+
};
/**
*/
DALI_TOOLKIT_API bool IsDefaultAlgorithmEnabled(KeyboardFocusManager keyboardFocusManager);
+/**
+ * @brief Moves the focus to the next focusable actor in the focus
+ * chain in the given direction (according to the focus traversal
+ * order).
+ *
+ * @param[in] keyboardFocusManager The instance of KeyboardFocusManager
+ * @param direction The direction of focus movement
+ * @param deviceName The device name
+ * @return true if the movement was successful
+ * @pre The KeyboardFocusManager has been initialized.
+ */
+DALI_TOOLKIT_API bool MoveFocus(KeyboardFocusManager keyboardFocusManager, Control::KeyboardFocus::Direction direction, const std::string& deviceName);
+
+
} // namespace DevelKeyboardFocusManager
} // namespace Toolkit
void Alignment::OnInitialize()
{
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
}
void Alignment::OnRelayout(const Vector2& size, RelayoutContainer& container)
// bind properties for / set shader constants to defaults
SetupProperties();
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::ANIMATION));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::ANIMATION);
}
void BloomView::OnSizeSet(const Vector3& targetSize)
return OnKeyboardEnter();
}
+DevelControl::ControlAccessible* Button::CreateAccessibleObject()
+{
+ return new ButtonAccessible(Self());
+}
+
bool Button::OnTouch(Actor actor, const TouchEvent& touch)
{
if(!IsDisabled() && (actor == touch.GetHitActor(0)))
return mForegroundPadding;
}
-std::string Button::AccessibleImpl::GetNameRaw() const
+std::string Button::ButtonAccessible::GetNameRaw() const
{
std::string labelText;
auto slf = Toolkit::Button::DownCast(Self());
return labelText;
}
-Property::Index Button::AccessibleImpl::GetNamePropertyIndex()
+Property::Index Button::ButtonAccessible::GetNamePropertyIndex()
{
Property::Index label = Toolkit::Button::Property::LABEL;
Property::Map labelMap = Self().GetProperty<Property::Map>(label);
}
}
-Dali::Accessibility::States Button::AccessibleImpl::CalculateStates()
+Dali::Accessibility::States Button::ButtonAccessible::CalculateStates()
{
auto tmp = DevelControl::ControlAccessible::CalculateStates();
tmp[Dali::Accessibility::State::SELECTABLE] = true;
bool OnAccessibilityActivated() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Toolkit::Control::OnKeyboardEnter()
*/
bool OnKeyboardEnter() override;
bool mClickActionPerforming; ///< Used to manage signal emissions during action
protected:
- struct AccessibleImpl : public DevelControl::ControlAccessible
+ class ButtonAccessible : public DevelControl::ControlAccessible
{
+ public:
using DevelControl::ControlAccessible::ControlAccessible;
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+ */
Dali::Accessibility::States CalculateStates() override;
- std::string GetNameRaw() const override;
- Property::Index GetNamePropertyIndex() override;
+
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetNameRaw()
+ */
+ std::string GetNameRaw() const override;
+
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetNamePropertyIndex()
+ */
+ Property::Index GetNamePropertyIndex() override;
};
};
{
Button::OnInitialize();
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::CHECK_BOX));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::CHECK_BOX);
}
-Dali::Accessibility::States CheckBoxButton::AccessibleImpl::CalculateStates()
+DevelControl::ControlAccessible* CheckBoxButton::CreateAccessibleObject()
{
- auto state = Button::AccessibleImpl::CalculateStates();
+ return new CheckBoxButton::CheckBoxButtonAccessible(Self());
+}
+
+Dali::Accessibility::States CheckBoxButton::CheckBoxButtonAccessible::CalculateStates()
+{
+ auto state = Button::ButtonAccessible::CalculateStates();
auto self = Toolkit::Button::DownCast(Self());
if(self.GetProperty<bool>(Toolkit::Button::Property::SELECTED))
{
void CheckBoxButton::OnStateChange(State newState)
{
// TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
- if(Dali::Accessibility::IsUp() && (Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self())
- && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+ if((Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
{
- Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
+ GetAccessibleObject()->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
}
}
*/
void OnInitialize() override;
+ /**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
private:
// Undefined
CheckBoxButton(const CheckBoxButton&);
CheckBoxButton& operator=(const CheckBoxButton&);
protected:
- struct AccessibleImpl : public Button::AccessibleImpl
+ class CheckBoxButtonAccessible : public Button::ButtonAccessible
{
- using Button::AccessibleImpl::AccessibleImpl;
+ public:
+ using Button::ButtonAccessible::ButtonAccessible;
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+ */
Dali::Accessibility::States CalculateStates() override;
};
+
void OnStateChange(State newState) override;
};
Actor self = Self();
self.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::PUSH_BUTTON));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::PUSH_BUTTON);
+}
+
+DevelControl::ControlAccessible* PushButton::CreateAccessibleObject()
+{
+ return new PushButtonAccessible(Self());
}
void PushButton::SetIconAlignment(const PushButton::IconAlignment iconAlignment)
return value;
}
-Dali::Accessibility::States PushButton::AccessibleImpl::CalculateStates()
+Dali::Accessibility::States PushButton::PushButtonAccessible::CalculateStates()
{
- auto state = Button::AccessibleImpl::CalculateStates();
+ auto state = Button::ButtonAccessible::CalculateStates();
auto self = Toolkit::Button::DownCast(Self());
state[Dali::Accessibility::State::PRESSED] = self.GetProperty<bool>(Toolkit::Button::Property::SELECTED);
return state;
void PushButton::OnStateChange(State newState)
{
// TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
- if(Dali::Accessibility::IsUp() && (Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self())
- && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+ if((Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
{
- Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(Dali::Accessibility::State::PRESSED, newState == SELECTED_STATE ? 1 : 0, 0);
+ auto* accessible = GetAccessibleObject();
+
+ accessible->EmitStateChanged(Dali::Accessibility::State::PRESSED, newState == SELECTED_STATE ? 1 : 0, 0);
if(Self().GetProperty<bool>(Toolkit::Button::Property::TOGGLABLE))
{
- Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
+ accessible->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
}
}
}
*/
void OnInitialize() override;
+ /**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
private:
/**
* @brief Sets the alignment mode to use to align the icon to the label.
IconAlignment mIconAlignment; ///< The alignment of the icon against the label.
protected:
- struct AccessibleImpl : public Button::AccessibleImpl
+ class PushButtonAccessible : public Button::ButtonAccessible
{
- using Button::AccessibleImpl::AccessibleImpl;
+ public:
+ using Button::ButtonAccessible::ButtonAccessible;
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+ */
Dali::Accessibility::States CalculateStates() override;
};
+
void OnStateChange(State newState) override;
};
{
Button::OnInitialize();
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::RADIO_BUTTON));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::RADIO_BUTTON);
+}
+
+DevelControl::ControlAccessible* RadioButton::CreateAccessibleObject()
+{
+ return new RadioButtonAccessible(Self());
}
bool RadioButton::OnToggleReleased()
}
// TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
- if(Dali::Accessibility::IsUp() && (Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self())
- && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+ if((Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
{
- Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
+ GetAccessibleObject()->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
}
}
-Dali::Accessibility::States RadioButton::AccessibleImpl::CalculateStates()
+Dali::Accessibility::States RadioButton::RadioButtonAccessible::CalculateStates()
{
- auto state = Button::AccessibleImpl::CalculateStates();
+ auto state = Button::ButtonAccessible::CalculateStates();
auto self = Toolkit::Button::DownCast(Self());
if(self.GetProperty<bool>(Toolkit::Button::Property::SELECTED))
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Toolkit::Internal::Button::OnStateChange
*/
void OnStateChange(State newState) override;
RadioButton& operator=(const RadioButton& origin);
protected:
- struct AccessibleImpl : public Button::AccessibleImpl
+ class RadioButtonAccessible : public Button::ButtonAccessible
{
- using Button::AccessibleImpl::AccessibleImpl;
+ public:
+ using Button::ButtonAccessible::ButtonAccessible;
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+ */
Dali::Accessibility::States CalculateStates() override;
};
};
Actor self = Self();
self.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::TOGGLE_BUTTON));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::TOGGLE_BUTTON);
+}
+
+DevelControl::ControlAccessible* ToggleButton::CreateAccessibleObject()
+{
+ return new ToggleButtonAccessible(Self());
}
void ToggleButton::SetProperty(BaseObject* object, Property::Index propertyIndex, const Property::Value& value)
RelayoutRequest();
}
-Dali::Accessibility::States ToggleButton::AccessibleImpl::CalculateStates()
+Dali::Accessibility::States ToggleButton::ToggleButtonAccessible::CalculateStates()
{
- auto states = Button::AccessibleImpl::CalculateStates();
+ auto states = Button::ButtonAccessible::CalculateStates();
auto button = Toolkit::ToggleButton::DownCast(Self());
if(button.GetProperty<int>(Toolkit::ToggleButton::Property::CURRENT_STATE_INDEX))
{
return states;
}
-std::string ToggleButton::AccessibleImpl::GetDescriptionRaw() const
+std::string ToggleButton::ToggleButtonAccessible::GetDescriptionRaw() const
{
auto button = Toolkit::ToggleButton::DownCast(Self());
auto index = button.GetProperty<int>(Toolkit::ToggleButton::Property::CURRENT_STATE_INDEX);
return tooltips[index].Get<std::string>();
}
-Property::Index ToggleButton::AccessibleImpl::GetDescriptionPropertyIndex()
+Property::Index ToggleButton::ToggleButtonAccessible::GetDescriptionPropertyIndex()
{
return Toolkit::ToggleButton::Property::TOOLTIPS;
}
void ToggleButton::OnStateChange(State newState)
{
// TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
- if(Dali::Accessibility::IsUp() && (Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
- && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+ if((Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
{
- Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(Dali::Accessibility::State::CHECKED, mCurrentToggleIndex ? 1 : 0, 0);
- Dali::Accessibility::Accessible::Get(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::DESCRIPTION);
+ auto* accessible = GetAccessibleObject();
+
+ accessible->EmitStateChanged(Dali::Accessibility::State::CHECKED, mCurrentToggleIndex ? 1 : 0, 0);
+ accessible->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::DESCRIPTION);
}
}
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Toolkit::Internal::Button::OnRelayout
*/
void OnRelayout(const Vector2& size, RelayoutContainer& container) override;
std::vector<Toolkit::Visual::Base> mToggleDisabledSelectedVisuals; ///< Save all disabled selected visuals.
std::vector<std::string> mToggleTooltips; ///< Toggle tooltips.
unsigned int mCurrentToggleIndex; ///< The index of state.
+
protected:
- struct AccessibleImpl : public Button::AccessibleImpl
+ class ToggleButtonAccessible : public Button::ButtonAccessible
{
- using Button::AccessibleImpl::AccessibleImpl;
+ public:
+ using Button::ButtonAccessible::ButtonAccessible;
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+ */
Dali::Accessibility::States CalculateStates() override;
- std::string GetDescriptionRaw() const override;
- Property::Index GetDescriptionPropertyIndex() override;
+
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetDescriptionRaw()
+ */
+ std::string GetDescriptionRaw() const override;
+
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetDescriptionPropertyIndex()
+ */
+ Property::Index GetDescriptionPropertyIndex() override;
};
+
void OnStateChange(State newState) override;
};
// CanvasView can relayout in the OnImageReady, alternative to a signal would be to have a upcall from the Control to CanvasView
Dali::Toolkit::Control handle(GetOwner());
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::IMAGE));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::IMAGE);
Adaptor::Get().RegisterProcessor(*this, true);
}
return rect.width > 0 && rect.height > 0;
}
+Dali::Accessibility::Accessible* ExternalAccessibleGetter(Dali::Actor actor)
+{
+ auto control = Toolkit::Control::DownCast(actor);
+ if (!control)
+ {
+ return nullptr;
+ }
+
+ auto& controlImpl = Toolkit::Internal::GetImplementation(control);
+
+ return controlImpl.GetAccessibleObject();
+}
+
} // unnamed namespace
// clang-format off
const PropertyRegistration Control::Impl::PROPERTY_21(typeRegistration, "accessibilityAttributes", Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
const PropertyRegistration Control::Impl::PROPERTY_22(typeRegistration, "dispatchKeyEvents", Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
const PropertyRegistration Control::Impl::PROPERTY_23(typeRegistration, "accessibilityHidden", Toolkit::DevelControl::Property::ACCESSIBILITY_HIDDEN, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
+const PropertyRegistration Control::Impl::PROPERTY_24(typeRegistration, "clockwiseFocusableActorId", Toolkit::DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
+const PropertyRegistration Control::Impl::PROPERTY_25(typeRegistration, "counterClockwiseFocusableActorId", Toolkit::DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
// clang-format on
mRightFocusableActorId(-1),
mUpFocusableActorId(-1),
mDownFocusableActorId(-1),
+ mClockwiseFocusableActorId(-1),
+ mCounterClockwiseFocusableActorId(-1),
mStyleName(""),
mBackgroundColor(Color::TRANSPARENT),
mStartingPinchScale(nullptr),
mNeedToEmitResourceReady(false),
mDispatchKeyEvents(true)
{
- Dali::Accessibility::Accessible::RegisterExternalAccessibleGetter(
- [](Dali::Actor actor) -> Dali::Accessibility::Accessible* {
- return Control::Impl::GetAccessibilityObject(actor);
- });
-
- mAccessibilityConstructor = [](Dali::Actor actor) -> std::unique_ptr<Dali::Accessibility::Accessible> {
- return std::unique_ptr<Dali::Accessibility::Accessible>(new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::UNKNOWN));
- };
+ Dali::Accessibility::Accessible::RegisterExternalAccessibleGetter(&ExternalAccessibleGetter);
}
Control::Impl::~Impl()
void Control::Impl::CheckHighlightedObjectGeometry()
{
- auto accessible = dynamic_cast<Dali::Toolkit::DevelControl::ControlAccessible*>(mAccessibilityObject.get());
- if(!accessible)
- {
- DALI_LOG_ERROR("accessible is not a pointer to a DevelControl::ControlAccessible type");
- return;
- }
-
+ auto accessible = GetAccessibleObject();
auto lastPosition = accessible->GetLastPosition();
auto accessibleRect = accessible->GetExtents(Dali::Accessibility::CoordinateType::WINDOW);
auto rect = GetShowingGeometry(accessibleRect, accessible);
// notify AT-clients on outgoing moves only
if(mAccessibilityLastScreenRelativeMoveType != Dali::Accessibility::ScreenRelativeMoveType::INSIDE)
{
- mAccessibilityObject.get()->EmitMovedOutOfScreen(mAccessibilityLastScreenRelativeMoveType);
+ accessible->EmitMovedOutOfScreen(mAccessibilityLastScreenRelativeMoveType);
}
break;
}
{
controlImpl.mImpl->mAccessibilityHidden = hidden;
- auto* accessible = controlImpl.mImpl->GetAccessibilityObject();
+ auto* accessible = controlImpl.GetAccessibleObject();
auto* parent = dynamic_cast<Dali::Accessibility::ActorAccessible*>(accessible->GetParent());
if (parent)
{
}
break;
}
+ case Toolkit::DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID:
+ {
+ int focusId;
+ if(value.Get(focusId))
+ {
+ controlImpl.mImpl->mClockwiseFocusableActorId = focusId;
+ }
+ break;
+ }
+ case Toolkit::DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID:
+ {
+ int focusId;
+ if(value.Get(focusId))
+ {
+ controlImpl.mImpl->mCounterClockwiseFocusableActorId = focusId;
+ }
+ break;
+ }
}
}
}
value = controlImpl.mImpl->mAccessibilityHidden;
break;
}
+
+ case Toolkit::DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID:
+ {
+ value = controlImpl.mImpl->mClockwiseFocusableActorId;
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID:
+ {
+ value = controlImpl.mImpl->mCounterClockwiseFocusableActorId;
+ break;
+ }
}
}
mIdleCallback = nullptr;
}
-Dali::Accessibility::Accessible* Control::Impl::GetAccessibilityObject()
+Toolkit::DevelControl::ControlAccessible* Control::Impl::GetAccessibleObject()
{
- if(!mAccessibilityObject)
+ if(!mAccessibleObject)
{
- mAccessibilityObject = mAccessibilityConstructor(mControlImpl.Self());
+ mAccessibleObject.reset(mControlImpl.CreateAccessibleObject());
}
- return mAccessibilityObject.get();
-}
-Dali::Accessibility::Accessible* Control::Impl::GetAccessibilityObject(Dali::Actor actor)
-{
- if(actor)
- {
- auto control = Dali::Toolkit::Control::DownCast(actor);
- if(control)
- {
- auto controlImpl = static_cast<Internal::Control*>(&control.GetImplementation());
- return controlImpl->mImpl->GetAccessibilityObject();
- }
- }
- return nullptr;
+ return mAccessibleObject.get();
}
} // namespace Internal
void UpdateVisualProperties(const std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& properties);
/**
- * @brief Gets the current control's accessible object.
- *
- * @return The handle to Accessible object
- */
- Dali::Accessibility::Accessible* GetAccessibilityObject();
-
- /**
- * @brief Gets Accessible object handle.
- *
- * The method acquires Accessible handle from Actor object
- * @param actor Actor object
- * @return The handle to Accessible object
+ * @copydoc Dali::Toolkit::Internal::Control::GetAccessibleObject()
*/
- static Dali::Accessibility::Accessible* GetAccessibilityObject(Dali::Actor actor);
+ Toolkit::DevelControl::ControlAccessible* GetAccessibleObject();
private:
/**
int mRightFocusableActorId; ///< Actor ID of Right focusable control.
int mUpFocusableActorId; ///< Actor ID of Up focusable control.
int mDownFocusableActorId; ///< Actor ID of Down focusable control.
+ int mClockwiseFocusableActorId; ///< Actor ID of Clockwise focusable control.
+ int mCounterClockwiseFocusableActorId; ///< Actor ID of Counter clockwise focusable control.
RegisteredVisualContainer mVisuals; ///< Stores visuals needed by the control, non trivial type so std::vector used.
std::string mStyleName;
Dali::Accessibility::Role mAccessibilityRole = Dali::Accessibility::Role::UNKNOWN;
std::map<Dali::Accessibility::RelationType, std::set<Accessibility::Accessible*>> mAccessibilityRelations;
- std::function<std::unique_ptr<Dali::Accessibility::Accessible>(Actor)> mAccessibilityConstructor;
- std::unique_ptr<Dali::Accessibility::Accessible> mAccessibilityObject;
+ std::unique_ptr<Toolkit::DevelControl::ControlAccessible> mAccessibleObject;
// Gesture Detection
PinchGestureDetector mPinchGestureDetector;
static const PropertyRegistration PROPERTY_21;
static const PropertyRegistration PROPERTY_22;
static const PropertyRegistration PROPERTY_23;
+ static const PropertyRegistration PROPERTY_24;
+ static const PropertyRegistration PROPERTY_25;
private:
// Accessibility - notification for highlighted object to check if it is showing.
mChildrenRoot.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
self.Add(mChildrenRoot);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
}
void EffectsView::OnSizeSet(const Vector3& targetSize)
self.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
SetAsKeyboardFocusGroup(true);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
}
} // namespace Internal
mInternalRoot.Add(mVertBlurActor);
mInternalRoot.Add(mRenderDownsampledCamera);
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
}
void GaussianBlurView::OnSizeSet(const Vector3& targetSize)
Dali::Toolkit::Control handle(GetOwner());
handle.ResourceReadySignal().Connect(this, &ImageView::OnResourceReady);
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::IMAGE));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::IMAGE);
}
void ImageView::SetImage(const Property::Map& map)
constraint.AddSource(Source(self, Actor::Property::WORLD_SCALE));
constraint.Apply();
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
}
Magnifier::~Magnifier()
Shader shader = Shader::New(SHADER_MODEL3D_VIEW_SIMPLE_SHADER_VERT, SHADER_MODEL3D_VIEW_SIMPLE_SHADER_FRAG);
mRenderer = Renderer::New(mesh, shader);
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::IMAGE));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::IMAGE);
}
void Model3dView::LoadGeometry()
void NavigationView::OnInitialize()
{
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
}
void NavigationView::OnSceneConnection(int depth)
// enable the pan gesture which is attached to the control
EnableGestureDetection(GestureType::Value(GestureType::PAN));
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::PAGE_TAB_LIST));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::PAGE_TAB_LIST);
}
Shader PageTurnView::CreateShader(const Property::Map& shaderMap)
DevelControl::AppendAccessibilityAttribute(Toolkit::Control::DownCast(self), "sub-role", "Alert");
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(new AccessibleImpl(actor, Dali::Accessibility::Role::DIALOG, true));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::DIALOG);
+}
+
+DevelControl::ControlAccessible* Popup::CreateAccessibleObject()
+{
+ return new PopupAccessible(Self());
}
Popup::~Popup()
}
}
-std::string Popup::AccessibleImpl::GetNameRaw() const
+std::string Popup::PopupAccessible::GetNameRaw() const
{
auto popup = Toolkit::Popup::DownCast(Self());
std::string title;
return title;
}
-Dali::Accessibility::States Popup::AccessibleImpl::CalculateStates()
+Dali::Accessibility::States Popup::PopupAccessible::CalculateStates()
{
auto states = DevelControl::ControlAccessible::CalculateStates();
auto popup = Toolkit::Popup::DownCast(Self());
auto displayState = popup.GetProperty<std::string>(Toolkit::Popup::Property::DISPLAY_STATE);
states[Dali::Accessibility::State::SHOWING] = (displayState == "SHOWN" || displayState == "SHOWING");
+ states[Dali::Accessibility::State::MODAL] = true;
return states;
}
static Property::Value GetProperty(BaseObject* object, Property::Index propertyIndex);
protected:
- struct AccessibleImpl : public DevelControl::ControlAccessible
+ class PopupAccessible : public DevelControl::ControlAccessible
{
+ public:
using DevelControl::ControlAccessible::ControlAccessible;
- std::string GetNameRaw() const override;
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetNameRaw()
+ */
+ std::string GetNameRaw() const override;
+
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+ */
Dali::Accessibility::States CalculateStates() override;
};
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* Called whenever the popup layout is re-set up.
* Normally due to a change in contents.
* Note: This is only done when the popup is shown.
void ProgressBar::OnInitialize()
{
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::PROGRESS_BAR));
- });
- //Enable highightability
- Self().SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+ // Accessibility
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::PROGRESS_BAR);
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+}
+
+DevelControl::ControlAccessible* ProgressBar::CreateAccessibleObject()
+{
+ return new ProgressBarAccessible(Self());
}
void ProgressBar::OnRelayout(const Vector2& size, RelayoutContainer& container)
mValueChangedSignal.Emit(self, mProgressValue, mSecondaryProgressValue);
if(Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
{
- Control::Impl::GetAccessibilityObject(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
+ GetAccessibleObject()->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
}
RelayoutRequest();
}
}
}
-double ProgressBar::AccessibleImpl::GetMinimum() const
+double ProgressBar::ProgressBarAccessible::GetMinimum() const
{
return DEFAULT_LOWER_BOUND;
}
-double ProgressBar::AccessibleImpl::GetCurrent() const
+double ProgressBar::ProgressBarAccessible::GetCurrent() const
{
auto self = Toolkit::ProgressBar::DownCast(Self());
return self.GetProperty(Toolkit::ProgressBar::Property::PROGRESS_VALUE).Get<float>();
}
-double ProgressBar::AccessibleImpl::GetMaximum() const
+double ProgressBar::ProgressBarAccessible::GetMaximum() const
{
return DEFAULT_UPPER_BOUND;
}
-bool ProgressBar::AccessibleImpl::SetCurrent(double current)
+bool ProgressBar::ProgressBarAccessible::SetCurrent(double current)
{
if(current < GetMinimum() || current > GetMaximum())
{
return true;
}
-double ProgressBar::AccessibleImpl::GetMinimumIncrement() const
+double ProgressBar::ProgressBarAccessible::GetMinimumIncrement() const
{
return 0.0;
}
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* Get the range of the valid values the ProgressBar handle can move between
*
* @param[in] currentSize The current size of the ProgressBar
Property::Map mSecondaryProgressVisualMap; ///< To backup visual properties when switching determinate/indeterminate.
protected:
- struct AccessibleImpl : public DevelControl::ControlAccessible,
- public virtual Dali::Accessibility::Value
+ class ProgressBarAccessible : public DevelControl::ControlAccessible,
+ public virtual Dali::Accessibility::Value
{
+ public:
using DevelControl::ControlAccessible::ControlAccessible;
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMinimum()
+ */
double GetMinimum() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetCurrent()
+ */
double GetCurrent() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMaximum()
+ */
double GetMaximum() const override;
- bool SetCurrent(double) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::SetCurrent()
+ */
+ bool SetCurrent(double) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMinimumIncrement()
+ */
double GetMinimumIncrement() const override;
};
};
void ScrollBar::OnInitialize()
{
+ auto self = Self();
+
CreateDefaultIndicatorActor();
- Self().SetProperty(Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D);
+ self.SetProperty(Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D);
+
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::SCROLL_BAR);
+}
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::SCROLL_BAR));
- });
+DevelControl::ControlAccessible* ScrollBar::CreateAccessibleObject()
+{
+ return new ScrollBarAccessible(Self());
}
void ScrollBar::SetScrollPropertySource(Handle handle, Property::Index propertyScrollPosition, Property::Index propertyMinScrollPosition, Property::Index propertyMaxScrollPosition, Property::Index propertyScrollContentSize)
mScrollPositionIntervalReachedSignal.Emit(scrollableHandle.GetCurrentProperty<float>(mPropertyScrollPosition));
if(Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
{
- Control::Impl::GetAccessibilityObject(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
+ GetAccessibleObject()->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
}
}
}
return handle;
}
-double ScrollBar::AccessibleImpl::GetMinimum() const
+double ScrollBar::ScrollBarAccessible::GetMinimum() const
{
auto self = Toolkit::ScrollBar::DownCast(Self());
Handle scrollableHandle = GetImpl(self).mScrollableObject.GetHandle();
return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(self).mPropertyMinScrollPosition) : 0.0f;
}
-double ScrollBar::AccessibleImpl::GetCurrent() const
+double ScrollBar::ScrollBarAccessible::GetCurrent() const
{
auto self = Toolkit::ScrollBar::DownCast(Self());
Handle scrollableHandle = GetImpl(self).mScrollableObject.GetHandle();
return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(self).mPropertyScrollPosition) : 0.0f;
}
-double ScrollBar::AccessibleImpl::GetMaximum() const
+double ScrollBar::ScrollBarAccessible::GetMaximum() const
{
auto self = Toolkit::ScrollBar::DownCast(Self());
Handle scrollableHandle = GetImpl(self).mScrollableObject.GetHandle();
return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(self).mPropertyMaxScrollPosition) : 1.0f;
}
-bool ScrollBar::AccessibleImpl::SetCurrent(double current)
+bool ScrollBar::ScrollBarAccessible::SetCurrent(double current)
{
if(current < GetMinimum() || current > GetMaximum())
{
return true;
}
-double ScrollBar::AccessibleImpl::GetMinimumIncrement() const
+double ScrollBar::ScrollBarAccessible::GetMinimumIncrement() const
{
return 1.0;
}
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Toolkit::Control::OnPan
*/
void OnPan(const PanGesture& gesture) override;
bool mIndicatorFirstShow : 1; ///< True if the indicator has never been shown
protected:
- struct AccessibleImpl : public DevelControl::ControlAccessible,
- public virtual Dali::Accessibility::Value
+ class ScrollBarAccessible : public DevelControl::ControlAccessible,
+ public virtual Dali::Accessibility::Value
{
+ public:
using DevelControl::ControlAccessible::ControlAccessible;
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMinimum()
+ */
double GetMinimum() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetCurrent()
+ */
double GetCurrent() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMaximum()
+ */
double GetMaximum() const override;
- bool SetCurrent(double) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::SetCurrent()
+ */
+ bool SetCurrent(double) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMinimumIncrement()
+ */
double GetMinimumIncrement() const override;
};
};
// Connect wheel event
self.WheelEventSignal().Connect(this, &ItemView::OnWheelEvent);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(new AccessibleImpl(actor, Dali::Accessibility::Role::SCROLL_PANE));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::SCROLL_PANE);
+}
+
+DevelControl::ControlAccessible* ItemView::CreateAccessibleObject()
+{
+ return new ItemViewAccessible(Self());
}
ItemView::~ItemView()
}
}
-bool ItemView::AccessibleImpl::ScrollToChild(Actor child)
+bool ItemView::ItemViewAccessible::ScrollToChild(Actor child)
{
auto itemView = Dali::Toolkit::ItemView::DownCast(Self());
Toolkit::GetImpl(itemView).OnKeyboardFocusChangeCommitted(child);
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Toolkit::Control::OnAccessibilityPan()
*/
bool OnAccessibilityPan(PanGesture gesture) override;
void OnKeyboardFocusChangeCommitted(Actor commitedFocusableActor) override;
protected:
- struct AccessibleImpl : public Scrollable::AccessibleImpl
+ class ItemViewAccessible : public Scrollable::ScrollableAccessible
{
- using Scrollable::AccessibleImpl::AccessibleImpl;
+ public:
+ using Scrollable::ScrollableAccessible::ScrollableAccessible;
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::ScrollToChild()
+ */
bool ScrollToChild(Actor child) override;
};
// Connect wheel event
self.WheelEventSignal().Connect(this, &ScrollView::OnWheelEvent);
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::SCROLL_PANE));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::SCROLL_PANE);
+}
+
+DevelControl::ControlAccessible* ScrollView::CreateAccessibleObject()
+{
+ return new ScrollViewAccessible(Self());
}
void ScrollView::OnSceneConnection(int depth)
return mSnapStartedSignal;
}
-bool ScrollView::AccessibleImpl::ScrollToChild(Actor child)
+bool ScrollView::ScrollViewAccessible::ScrollToChild(Actor child)
{
auto scrollView = Dali::Toolkit::ScrollView::DownCast(Self());
if(Toolkit::GetImpl(scrollView).FindClosestActor() == child)
return false;
}
+ // child can be one of descendants
+ // find direct child of ScrollView to avoid the ASSERT in ScrollTo
+ auto parent = child.GetParent();
+ while (parent && parent != Self())
+ {
+ child = parent;
+ parent = child.GetParent();
+ }
+ if (!parent)
+ {
+ return false;
+ }
+
// FIXME: ScrollTo does not work (snaps back to original position)
scrollView.ScrollTo(child, scrollView.GetScrollFlickDuration());
return true;
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc CustomActorImpl::OnSceneConnection()
*/
void OnSceneConnection(int depth) override;
void WrapPosition(Vector2& position) const;
protected:
- struct AccessibleImpl : public Scrollable::AccessibleImpl
+ class ScrollViewAccessible : public Scrollable::ScrollableAccessible
{
- using Scrollable::AccessibleImpl::AccessibleImpl;
+ public:
+ using Scrollable::ScrollableAccessible::ScrollableAccessible;
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::ScrollToChild()
+ */
bool ScrollToChild(Actor child) override;
};
{
}
-bool Scrollable::AccessibleImpl::IsScrollable() const
+bool Scrollable::ScrollableAccessible::IsScrollable() const
{
return true;
}
void Scrollable::OnInitialize()
{
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::SCROLL_PANE));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::SCROLL_PANE);
+}
+
+DevelControl::ControlAccessible* Scrollable::CreateAccessibleObject()
+{
+ return new ScrollableAccessible(Self());
}
bool Scrollable::IsOvershootEnabled() const
virtual void SetOvershootSize(const Vector2& size) = 0;
protected: // From Control
- struct AccessibleImpl : public DevelControl::ControlAccessible
+ class ScrollableAccessible : public DevelControl::ControlAccessible
{
+ public:
using DevelControl::ControlAccessible::ControlAccessible;
+ /**
+ * @copydoc Dali::Accessibility::Component::IsScrollable()
+ */
bool IsScrollable() const override;
};
*/
virtual void OnInitialize() override;
+ /**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
private:
/**
* Temporary function to override EnableScrollOvershoot functionality for overshoot
blurStrengthConstraint.AddSource(Source(self, mBlurStrengthPropertyIndex));
blurStrengthConstraint.Apply();
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
}
void ShadowView::OnChildAdd(Actor& child)
// Size the Slider actor to a default
self.SetProperty(Actor::Property::SIZE, Vector2(DEFAULT_HIT_REGION.x, DEFAULT_HIT_REGION.y));
- // Set the Slider to be highlightable in Screen Reader mode
- self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
-
// Connect to the touch signal
self.TouchedSignal().Connect(this, &Slider::OnTouch);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::SLIDER));
- });
+ // Accessibility
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::SLIDER);
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+}
+
+DevelControl::ControlAccessible* Slider::CreateAccessibleObject()
+{
+ return new SliderAccessible(Self());
}
void Slider::OnRelayout(const Vector2& size, RelayoutContainer& container)
DisplayValue(mValue, true);
if(Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
{
- Control::Impl::GetAccessibilityObject(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
+ GetAccessibleObject()->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
}
}
return value;
}
-double Slider::AccessibleImpl::GetMinimum() const
+double Slider::SliderAccessible::GetMinimum() const
{
auto self = Toolkit::Slider::DownCast(Self());
return self.GetProperty(Toolkit::Slider::Property::LOWER_BOUND).Get<float>();
}
-double Slider::AccessibleImpl::GetCurrent() const
+double Slider::SliderAccessible::GetCurrent() const
{
auto self = Toolkit::Slider::DownCast(Self());
return self.GetProperty(Toolkit::Slider::Property::VALUE).Get<float>();
}
-double Slider::AccessibleImpl::GetMaximum() const
+double Slider::SliderAccessible::GetMaximum() const
{
auto self = Toolkit::Slider::DownCast(Self());
return self.GetProperty(Toolkit::Slider::Property::UPPER_BOUND).Get<float>();
}
-bool Slider::AccessibleImpl::SetCurrent(double current)
+bool Slider::SliderAccessible::SetCurrent(double current)
{
if(current < GetMinimum() || current > GetMaximum())
return false;
return true;
}
-double Slider::AccessibleImpl::GetMinimumIncrement() const
+double Slider::SliderAccessible::GetMinimumIncrement() const
{
auto self = Toolkit::Slider::DownCast(Self());
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* Hit region touch
*
* @param[in] actor The actor the event is raised for
mSnapToMarks : 1; ///< Turn on or off snapping to marks
protected:
- struct AccessibleImpl : public DevelControl::ControlAccessible,
- public virtual Dali::Accessibility::Value
+ class SliderAccessible : public DevelControl::ControlAccessible,
+ public virtual Dali::Accessibility::Value
{
+ public:
using DevelControl::ControlAccessible::ControlAccessible;
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMinimum()
+ */
double GetMinimum() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetCurrent()
+ */
double GetCurrent() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMaximum()
+ */
double GetMaximum() const override;
- bool SetCurrent(double) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::SetCurrent()
+ */
+ bool SetCurrent(double) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMinimumIncrement()
+ */
double GetMinimumIncrement() const override;
};
};
mBlurStrengthPropertyIndex = self.RegisterUniqueProperty("blurStrength", 0.f);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
}
void SuperBlurView::SetTexture(Texture texture)
self.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
SetAsKeyboardFocusGroup(true);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::TABLE));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::TABLE);
}
void TableView::ResizeContainers(unsigned int rows, unsigned int columns)
* limitations under the License.
*/
+// EXTERNAL INCLUDES
#include <dali/public-api/actors/layer.h>
+// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
+#include <dali-toolkit/internal/text/character-set-conversion.h>
+#include <dali-toolkit/internal/text/hidden-text.h>
#include <dali-toolkit/internal/text/text-view.h>
namespace Dali::Toolkit::Internal
}
}
+std::size_t TextControlAccessible::GetCharacterCount() const
+{
+ return GetWholeText().size();
+}
+
+std::size_t TextControlAccessible::GetCursorOffset() const
+{
+ return 0u;
+}
+
+Rect<> TextControlAccessible::GetRangeExtents(std::size_t startOffset, std::size_t endOffset, Accessibility::CoordinateType type)
+{
+ if(!ValidateRange(GetWholeText(), startOffset, endOffset))
+ {
+ return {0, 0, 0, 0};
+ }
+
+ auto rect = GetTextController()->GetTextBoundingRectangle(startOffset, endOffset - 1);
+ auto extents = GetExtents(type);
+
+ rect.x += extents.x;
+ rect.y += extents.y;
+
+ return rect;
+}
+
+Accessibility::Range TextControlAccessible::GetRangeOfSelection(std::size_t selectionIndex) const
+{
+ // Since DALi supports only one selection, indices other than 0 are ignored
+ if(selectionIndex > 0)
+ {
+ return {};
+ }
+
+ auto indices = GetTextController()->GetSelectionIndexes();
+ auto startOffset = static_cast<std::size_t>(indices.first);
+ auto endOffset = static_cast<std::size_t>(indices.second);
+ auto text = GetText(startOffset, endOffset);
+
+ return {startOffset, endOffset, text};
+}
+
+std::string TextControlAccessible::GetText(std::size_t startOffset, std::size_t endOffset) const
+{
+ auto text = GetWholeText();
+
+ if(!ValidateRange(text, startOffset, endOffset))
+ {
+ return {};
+ }
+
+ if(IsHiddenInput())
+ {
+ std::uint32_t substituteCharacterUtf32 = GetSubstituteCharacter();
+ std::string substituteCharacterUtf8;
+ std::string substituteText;
+
+ Toolkit::Text::Utf32ToUtf8(&substituteCharacterUtf32, 1, substituteCharacterUtf8);
+
+ while(substituteText.length() < endOffset - startOffset)
+ {
+ substituteText.append(substituteCharacterUtf8);
+ }
+
+ return substituteText;
+ }
+
+ return text.substr(startOffset, endOffset - startOffset);
+}
+
+Accessibility::Range TextControlAccessible::GetTextAtOffset(std::size_t offset, Accessibility::TextBoundary boundary) const
+{
+ Accessibility::Range range{};
+
+ if(IsHiddenInput())
+ {
+ // Returning empty object, as there is no possibility to parse the textfield
+ // when its content is hidden.
+ return range;
+ }
+
+ auto text = GetWholeText();
+ auto textSize = text.size();
+
+ switch(boundary)
+ {
+ case Dali::Accessibility::TextBoundary::CHARACTER:
+ {
+ if(offset < textSize)
+ {
+ range.content = text[offset];
+ range.startOffset = offset;
+ range.endOffset = offset + 1;
+ }
+ break;
+ }
+
+ case Dali::Accessibility::TextBoundary::WORD:
+ case Dali::Accessibility::TextBoundary::LINE:
+ {
+ std::vector<char> breaks(textSize, '\0');
+
+ if(boundary == Dali::Accessibility::TextBoundary::WORD)
+ {
+ Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast<const utf8_t*>(text.c_str()), textSize, "", breaks.data());
+ }
+ else
+ {
+ Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast<const utf8_t*>(text.c_str()), textSize, "", breaks.data());
+ }
+
+ std::size_t index = 0u;
+ std::size_t counter = 0u;
+
+ while(index < textSize && counter <= offset)
+ {
+ auto start = index;
+ if(breaks[index])
+ {
+ while(breaks[index])
+ {
+ index++;
+ }
+ counter++;
+ }
+ else
+ {
+ if(boundary == Dali::Accessibility::TextBoundary::WORD)
+ {
+ index++;
+ }
+ if(boundary == Dali::Accessibility::TextBoundary::LINE)
+ {
+ counter++;
+ }
+ }
+
+ if((counter > 0) && ((counter - 1) == offset))
+ {
+ range.content = text.substr(start, index - start + 1);
+ range.startOffset = start;
+ range.endOffset = index + 1;
+ }
+
+ if(boundary == Dali::Accessibility::TextBoundary::LINE)
+ {
+ index++;
+ }
+ }
+ break;
+ }
+
+ case Dali::Accessibility::TextBoundary::SENTENCE: // Not supported by default
+ case Dali::Accessibility::TextBoundary::PARAGRAPH: // Not supported by libunibreak library
+ default:
+ {
+ break;
+ }
+ }
+
+ return range;
+}
+
+bool TextControlAccessible::RemoveSelection(std::size_t selectionIndex)
+{
+ // Since DALi supports only one selection, indices other than 0 are ignored
+ if(selectionIndex > 0)
+ {
+ return false;
+ }
+
+ GetTextController()->SetSelection(0, 0);
+
+ return true;
+}
+
+bool TextControlAccessible::SetCursorOffset(std::size_t offset)
+{
+ return false;
+}
+
+bool TextControlAccessible::SetRangeOfSelection(std::size_t selectionIndex, std::size_t startOffset, std::size_t endOffset)
+{
+ // Since DALi supports only one selection, indices other than 0 are ignored
+ if(selectionIndex > 0)
+ {
+ return false;
+ }
+
+ // Lack of ValidateRange() is intentional
+
+ GetTextController()->SetSelection(startOffset, endOffset);
+
+ return true;
+}
+
+Accessibility::Hyperlink* TextControlAccessible::GetLink(std::int32_t linkIndex) const
+{
+ if(linkIndex < 0 || linkIndex >= GetLinkCount())
+ {
+ return nullptr;
+ }
+
+ auto anchor = GetTextAnchors()[linkIndex];
+
+ return Accessibility::Hyperlink::DownCast(Accessibility::Accessible::Get(anchor));
+}
+
+std::int32_t TextControlAccessible::GetLinkCount() const
+{
+ return static_cast<std::int32_t>(GetTextAnchors().size());
+}
+
+std::int32_t TextControlAccessible::GetLinkIndex(std::int32_t characterOffset) const
+{
+ return GetTextController()->GetAnchorIndex(static_cast<std::size_t>(characterOffset));
+}
+
+std::string TextControlAccessible::GetWholeText() const
+{
+ std::string text;
+
+ GetTextController()->GetText(text);
+
+ return text;
+}
+
+std::uint32_t TextControlAccessible::GetSubstituteCharacter() const
+{
+ return Toolkit::Text::STAR;
+}
+
+bool TextControlAccessible::IsHiddenInput() const
+{
+ return false;
+}
+
+bool TextControlAccessible::ValidateRange(const std::string& string, std::size_t begin, std::size_t end)
+{
+ auto size = string.size();
+
+ if(end <= begin || begin >= size || end > size)
+ {
+ return false;
+ }
+
+ // TODO: Check whether the range [begin, end) describes a valid substring:
+ // 1. It does not break multi-byte UTF-8 sequences.
+ // 2. It does not break graphemes (compound emojis, glyphs with combining characters etc.).
+
+ return true;
+}
+
+Accessibility::States EditableTextControlAccessible::CalculateStates()
+{
+ using Dali::Accessibility::State;
+
+ auto states = DevelControl::ControlAccessible::CalculateStates();
+ auto focusControl = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
+
+ states[State::EDITABLE] = true;
+ states[State::FOCUSABLE] = true;
+ states[State::FOCUSED] = (Self() == focusControl);
+
+ return states;
+}
+
+std::size_t EditableTextControlAccessible::GetCursorOffset() const
+{
+ return GetTextController()->GetCursorPosition();
+}
+
+bool EditableTextControlAccessible::SetCursorOffset(std::size_t offset)
+{
+ if(offset > GetCharacterCount())
+ {
+ return false;
+ }
+
+ GetTextController()->ResetCursorPosition(offset);
+ RequestTextRelayout();
+
+ return true;
+}
+
+bool EditableTextControlAccessible::CopyText(std::size_t startPosition, std::size_t endPosition)
+{
+ auto text = GetWholeText();
+
+ if(!ValidateRange(text, startPosition, endPosition))
+ {
+ return false;
+ }
+
+ GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
+
+ return true;
+}
+
+bool EditableTextControlAccessible::CutText(std::size_t startPosition, std::size_t endPosition)
+{
+ if(!CopyText(startPosition, endPosition))
+ {
+ return false;
+ }
+
+ return DeleteText(startPosition, endPosition);
+}
+
+bool EditableTextControlAccessible::DeleteText(std::size_t startPosition, std::size_t endPosition)
+{
+ auto text = GetWholeText();
+
+ if(!ValidateRange(text, startPosition, endPosition))
+ {
+ return false;
+ }
+
+ return SetTextContents(text.erase(startPosition, endPosition - startPosition));
+}
+
+bool EditableTextControlAccessible::InsertText(std::size_t startPosition, std::string newText)
+{
+ auto text = GetWholeText();
+
+ if(!ValidateRange(text, startPosition, startPosition + 1))
+ {
+ return false;
+ }
+
+ return SetTextContents(text.insert(startPosition, std::move(newText)));
+}
+
+bool EditableTextControlAccessible::SetTextContents(std::string newContents)
+{
+ GetTextController()->SetText(std::move(newContents));
+
+ return true;
+}
+
} // namespace Dali::Toolkit::Internal
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/atspi-interfaces/editable-text.h>
+#include <dali/devel-api/atspi-interfaces/hypertext.h>
+#include <dali/devel-api/atspi-interfaces/text.h>
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/common/vector-wrapper.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-accessible.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-anchor-devel.h>
#include <dali-toolkit/internal/text/decorator/text-decorator.h>
#include <dali-toolkit/internal/text/rendering/text-renderer.h>
#include <dali-toolkit/internal/text/text-controller.h>
#include <dali-toolkit/public-api/controls/control.h>
#include <dali-toolkit/public-api/controls/text-controls/text-editor.h>
-#include <dali/public-api/actors/actor.h>
-
-#include <dali/public-api/common/vector-wrapper.h>
namespace Dali::Toolkit::Internal
{
std::vector<Toolkit::TextAnchor>& anchorActors);
};
+class TextControlAccessible : public DevelControl::ControlAccessible,
+ public virtual Dali::Accessibility::Text,
+ public virtual Dali::Accessibility::Hypertext
+{
+public:
+ using DevelControl::ControlAccessible::ControlAccessible;
+
+ // Text
+
+ /**
+ * @copydoc Dali::Accessibility::Text::GetCharacterCount()
+ */
+ std::size_t GetCharacterCount() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::GetCursorOffset()
+ */
+ std::size_t GetCursorOffset() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::GetRangeExtents()
+ */
+ Rect<> GetRangeExtents(std::size_t startOffset, std::size_t endOffset, Accessibility::CoordinateType type) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
+ */
+ Accessibility::Range GetRangeOfSelection(std::size_t selectionIndex) const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::GetText()
+ */
+ std::string GetText(std::size_t startOffset, std::size_t endOffset) const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
+ */
+ Accessibility::Range GetTextAtOffset(std::size_t offset, Accessibility::TextBoundary boundary) const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::RemoveSelection()
+ */
+ bool RemoveSelection(std::size_t selectionIndex) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::SetCursorOffset()
+ */
+ bool SetCursorOffset(std::size_t offset) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
+ */
+ bool SetRangeOfSelection(std::size_t selectionIndex, std::size_t startOffset, std::size_t endOffset) override;
+
+ // Hypertext
+
+ /**
+ * @copydoc Dali::Accessibility::Hypertext::GetLink()
+ */
+ Accessibility::Hyperlink* GetLink(std::int32_t linkIndex) const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Hypertext::GetLinkCount()
+ */
+ std::int32_t GetLinkCount() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Hypertext::GetLinkIndex()
+ */
+ std::int32_t GetLinkIndex(std::int32_t characterOffset) const override;
+
+protected:
+ /**
+ * @brief Gets whole text.
+ *
+ * @return The text
+ */
+ std::string GetWholeText() const;
+
+ /**
+ * @brief Gets text anchors.
+ *
+ * @return Text anchors
+ */
+ virtual const std::vector<Toolkit::TextAnchor>& GetTextAnchors() const = 0;
+
+ /**
+ * @brief Gets text controller.
+ *
+ * @return The text controller
+ */
+ virtual Toolkit::Text::ControllerPtr GetTextController() const = 0;
+
+ /**
+ * @brief Get substitute character for hidden text.
+ *
+ * @return The substitute character (Unicode codepoint)
+ */
+ virtual std::uint32_t GetSubstituteCharacter() const;
+
+ /**
+ * @brief Checks whether text should be hidden (replaced with substitute characters).
+ *
+ * @return True if text should be hidden, false otherwise
+ */
+ virtual bool IsHiddenInput() const;
+
+ /**
+ * @brief Checks whether [startPosition, endPosition) is a valid, non-empty range within a given string.
+ *
+ * @param string Source string
+ * @param begin Start index (inclusive)
+ * @param end End index (exclusive)
+ * @return true if the range is valid, false otherwise
+ */
+ static bool ValidateRange(const std::string& string, std::size_t begin, std::size_t end);
+};
+
+class EditableTextControlAccessible : public TextControlAccessible,
+ public virtual Dali::Accessibility::EditableText
+{
+public:
+ using TextControlAccessible::TextControlAccessible;
+
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+ */
+ Accessibility::States CalculateStates() override;
+
+ // Text
+
+ /**
+ * @copydoc Dali::Accessibility::Text::GetCursorOffset()
+ */
+ std::size_t GetCursorOffset() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::SetCursorOffset()
+ */
+ bool SetCursorOffset(std::size_t offset) override;
+
+ // EditableText
+
+ /**
+ * @copydoc Dali::Accessibility::EditableText::CopyText()
+ */
+ bool CopyText(size_t startPosition, size_t endPosition) override;
+
+ /**
+ * @copydoc Dali::Accessibility::EditableText::CutText()
+ */
+ bool CutText(size_t startPosition, size_t endPosition) override;
+
+ /**
+ * @copydoc Dali::Accessibility::EditableText::DeleteText()
+ */
+ bool DeleteText(size_t startPosition, size_t endPosition) override;
+
+ /**
+ * @copydoc Dali::Accessibility::EditableText::InsertText()
+ */
+ bool InsertText(size_t startPosition, std::string text) override;
+
+ /**
+ * @copydoc Dali::Accessibility::EditableText::SetTextContents()
+ */
+ bool SetTextContents(std::string newContents) override;
+
+protected:
+ /**
+ * @brief Requests text relayout.
+ */
+ virtual void RequestTextRelayout() = 0;
+};
+
} // namespace Dali::Toolkit::Internal
#endif //DALI_TOOLKIT_INTERNAL_TEXT_CONTROLS_COMMON_TEXT_UTILS_H
{
Actor self = Self();
- // Enable highlightability
- self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+ // Accessibility
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::LINK);
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+}
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::LINK));
- });
+DevelControl::ControlAccessible* TextAnchor::CreateAccessibleObject()
+{
+ return new TextAnchorAccessible(Self());
}
TextAnchor::TextAnchor()
{
}
-int32_t TextAnchor::AccessibleImpl::GetEndIndex() const
+int32_t TextAnchor::TextAnchorAccessible::GetEndIndex() const
{
auto self = Toolkit::TextAnchor::DownCast(Self());
return self.GetProperty(Toolkit::TextAnchor::Property::END_CHARACTER_INDEX).Get<int>();
}
-int32_t TextAnchor::AccessibleImpl::GetStartIndex() const
+int32_t TextAnchor::TextAnchorAccessible::GetStartIndex() const
{
auto self = Toolkit::TextAnchor::DownCast(Self());
return self.GetProperty(Toolkit::TextAnchor::Property::START_CHARACTER_INDEX).Get<int>();
}
-int32_t TextAnchor::AccessibleImpl::GetAnchorCount() const
+int32_t TextAnchor::TextAnchorAccessible::GetAnchorCount() const
{
return 1;
}
-Dali::Accessibility::Accessible* TextAnchor::AccessibleImpl::GetAnchorAccessible(int32_t anchorIndex) const
+Dali::Accessibility::Accessible* TextAnchor::TextAnchorAccessible::GetAnchorAccessible(int32_t anchorIndex) const
{
- return Control::Impl::GetAccessibilityObject(Self());
+ return const_cast<TextAnchorAccessible*>(this);
}
-std::string TextAnchor::AccessibleImpl::GetAnchorUri(int32_t anchorIndex) const
+std::string TextAnchor::TextAnchorAccessible::GetAnchorUri(int32_t anchorIndex) const
{
auto self = Toolkit::TextAnchor::DownCast(Self());
return self.GetProperty(Toolkit::TextAnchor::Property::URI).Get<std::string>();
}
-bool TextAnchor::AccessibleImpl::IsValid() const
+bool TextAnchor::TextAnchorAccessible::IsValid() const
{
return !GetAnchorUri(0).empty();
}
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Control::OnPropertySet()
*/
// void OnPropertySet(Property::Index index, const Property::Value& propertyValue) override;
/**
* @brief This structure is to connect TextAnchor with Accessible functions.
*/
- struct AccessibleImpl : public DevelControl::ControlAccessible,
- public virtual Dali::Accessibility::Hyperlink
+ class TextAnchorAccessible : public DevelControl::ControlAccessible,
+ public virtual Dali::Accessibility::Hyperlink
{
+ public:
using DevelControl::ControlAccessible::ControlAccessible;
+
/**
* @copydoc Dali::Accessibility::Hyperlink::GetEndIndex()
*/
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/controls/control-devel.h>
-#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
#include <dali-toolkit/devel-api/text/rendering-backend.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
self.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT);
self.OnSceneSignal().Connect(this, &TextEditor::OnSceneConnect);
- //Enable highightability
- self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
-
DevelControl::SetInputMethodContext(*this, mInputMethodContext);
// Creates an extra control to be used as stencil buffer.
self.Add(mStencil);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::ENTRY));
- });
+ // Accessibility
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::ENTRY);
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
Accessibility::Bridge::EnabledSignal().Connect(this, &TextEditor::OnAccessibilityStatusChanged);
Accessibility::Bridge::DisabledSignal().Connect(this, &TextEditor::OnAccessibilityStatusChanged);
}
+DevelControl::ControlAccessible* TextEditor::CreateAccessibleObject()
+{
+ return new TextEditorAccessible(Self());
+}
+
void TextEditor::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
{
DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor::OnStyleChange\n");
void TextEditor::TextInserted(unsigned int position, unsigned int length, const std::string& content)
{
- if(Accessibility::IsUp())
- {
- Control::Impl::GetAccessibilityObject(Self())->EmitTextInserted(position, length, content);
- }
+ GetAccessibleObject()->EmitTextInserted(position, length, content);
}
void TextEditor::TextDeleted(unsigned int position, unsigned int length, const std::string& content)
{
- if(Accessibility::IsUp())
- {
- Control::Impl::GetAccessibilityObject(Self())->EmitTextDeleted(position, length, content);
- }
+ GetAccessibleObject()->EmitTextDeleted(position, length, content);
}
void TextEditor::CursorPositionChanged(unsigned int oldPosition, unsigned int newPosition)
{
- if(Accessibility::IsUp())
- {
- Control::Impl::GetAccessibilityObject(Self())->EmitTextCursorMoved(newPosition);
- }
+ GetAccessibleObject()->EmitTextCursorMoved(newPosition);
if((oldPosition != newPosition) && !mCursorPositionChanged)
{
}
}
-std::string TextEditor::AccessibleImpl::GetName() const
-{
- auto self = Toolkit::TextEditor::DownCast(Self());
- return self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-}
-
-std::string TextEditor::AccessibleImpl::GetText(size_t startOffset, size_t endOffset) const
-{
- if(endOffset <= startOffset)
- {
- return {};
- }
-
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-
- if(startOffset > text.size() || endOffset > text.size())
- {
- return {};
- }
-
- return text.substr(startOffset, endOffset - startOffset);
-}
-
-size_t TextEditor::AccessibleImpl::GetCharacterCount() const
-{
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-
- return text.size();
-}
-
-size_t TextEditor::AccessibleImpl::GetCursorOffset() const
-{
- auto slf = Toolkit::TextEditor::DownCast(Self());
- return Dali::Toolkit::GetImpl(slf).GetTextController()->GetCursorPosition();
-}
-
-bool TextEditor::AccessibleImpl::SetCursorOffset(size_t offset)
-{
- auto slf = Toolkit::TextEditor::DownCast(Self());
- auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
- if(offset > txt.size())
- {
- return false;
- }
-
- auto& slfImpl = Dali::Toolkit::GetImpl(slf);
- slfImpl.GetTextController()->ResetCursorPosition(offset);
- slfImpl.RequestTextRelayout();
-
- return true;
-}
-
-Dali::Accessibility::Range TextEditor::AccessibleImpl::GetTextAtOffset(size_t offset, Dali::Accessibility::TextBoundary boundary) const
-{
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
- auto textSize = text.size();
-
- auto range = Dali::Accessibility::Range{};
-
- switch(boundary)
- {
- case Dali::Accessibility::TextBoundary::CHARACTER:
- {
- if(offset < textSize)
- {
- range.content = text[offset];
- range.startOffset = offset;
- range.endOffset = offset + 1;
- }
- break;
- }
- case Dali::Accessibility::TextBoundary::WORD:
- case Dali::Accessibility::TextBoundary::LINE:
- {
- auto textString = text.c_str();
- auto breaks = std::vector<char>(textSize, 0);
-
- if(boundary == Dali::Accessibility::TextBoundary::WORD)
- {
- Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
- }
- else
- {
- Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
- }
-
- auto index = 0u;
- auto counter = 0u;
- while(index < textSize && counter <= offset)
- {
- auto start = index;
- if(breaks[index])
- {
- while(breaks[index])
- {
- index++;
- }
- counter++;
- }
- else
- {
- if(boundary == Dali::Accessibility::TextBoundary::WORD)
- {
- index++;
- }
- if(boundary == Dali::Accessibility::TextBoundary::LINE)
- {
- counter++;
- }
- }
-
- if((counter > 0) && ((counter - 1) == offset))
- {
- range.content = text.substr(start, index - start + 1);
- range.startOffset = start;
- range.endOffset = index + 1;
- }
-
- if(boundary == Dali::Accessibility::TextBoundary::LINE)
- {
- index++;
- }
- }
- break;
- }
- case Dali::Accessibility::TextBoundary::SENTENCE:
- {
- /* not supported by default */
- break;
- }
- case Dali::Accessibility::TextBoundary::PARAGRAPH:
- {
- /* Paragraph is not supported by libunibreak library */
- break;
- }
- default:
- break;
- }
-
- return range;
-}
-
-Dali::Accessibility::Range TextEditor::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex) const
-{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return {};
- }
-
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
- std::string value{};
- controller->RetrieveSelection(value);
- auto indices = controller->GetSelectionIndexes();
-
- return {static_cast<size_t>(indices.first), static_cast<size_t>(indices.second), value};
-}
-
-bool TextEditor::AccessibleImpl::RemoveSelection(size_t selectionIndex)
+std::string TextEditor::TextEditorAccessible::GetName() const
{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return false;
- }
-
- auto self = Toolkit::TextEditor::DownCast(Self());
- Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(0, 0);
- return true;
+ return GetWholeText();
}
-bool TextEditor::AccessibleImpl::SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset)
+const std::vector<Toolkit::TextAnchor>& TextEditor::TextEditorAccessible::GetTextAnchors() const
{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return false;
- }
-
- auto self = Toolkit::TextEditor::DownCast(Self());
- Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(startOffset, endOffset);
- return true;
-}
-
-Rect<> TextEditor::AccessibleImpl::GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type)
-{
- if (endOffset <= startOffset || endOffset <= 0)
- {
- return {0, 0, 0, 0};
- }
-
auto self = Toolkit::TextEditor::DownCast(Self());
- auto rect = Dali::Toolkit::GetImpl(self).GetTextController()->GetTextBoundingRectangle(startOffset, endOffset - 1);
-
- auto componentExtents = this->GetExtents(type);
- rect.x += componentExtents.x;
- rect.y += componentExtents.y;
-
- return rect;
+ return Toolkit::GetImpl(self).mAnchorActors;
}
-bool TextEditor::AccessibleImpl::CopyText(size_t startPosition, size_t endPosition)
+Toolkit::Text::ControllerPtr TextEditor::TextEditorAccessible::GetTextController() const
{
- if(endPosition <= startPosition)
- {
- return false;
- }
-
auto self = Toolkit::TextEditor::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
- Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
- return true;
+ return Toolkit::GetImpl(self).GetTextController();
}
-bool TextEditor::AccessibleImpl::CutText(size_t startPosition, size_t endPosition)
+void TextEditor::TextEditorAccessible::RequestTextRelayout()
{
- if(endPosition <= startPosition)
- {
- return false;
- }
+ auto self = Toolkit::TextEditor::DownCast(Self());
+ auto& selfImpl = Toolkit::GetImpl(self);
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
- Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
-
- self.SetProperty(Toolkit::TextEditor::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
-
- return true;
-}
-
-bool TextEditor::AccessibleImpl::DeleteText(size_t startPosition, size_t endPosition)
-{
- if(endPosition <= startPosition)
- {
- return false;
- }
-
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-
- self.SetProperty(Toolkit::TextEditor::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
-
- return true;
-}
-
-Dali::Accessibility::States TextEditor::AccessibleImpl::CalculateStates()
-{
- using namespace Dali::Accessibility;
-
- auto states = DevelControl::ControlAccessible::CalculateStates();
- states[State::EDITABLE] = true;
- states[State::FOCUSABLE] = true;
-
- Toolkit::Control focusControl = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
- if(Self() == focusControl)
- {
- states[State::FOCUSED] = true;
- }
-
- return states;
-}
-
-bool TextEditor::AccessibleImpl::InsertText(size_t startPosition, std::string text)
-{
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto insertedText = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-
- insertedText.insert(startPosition, text);
-
- self.SetProperty(Toolkit::TextEditor::Property::TEXT, std::move(insertedText));
-
- return true;
-}
-
-bool TextEditor::AccessibleImpl::SetTextContents(std::string newContents)
-{
- auto self = Toolkit::TextEditor::DownCast(Self());
- self.SetProperty(Toolkit::TextEditor::Property::TEXT, std::move(newContents));
- return true;
-}
-
-int32_t TextEditor::AccessibleImpl::GetLinkCount() const
-{
- auto self = Toolkit::TextEditor::DownCast(Self());
- return Dali::Toolkit::GetImpl(self).mAnchorActors.size();
-}
-
-Accessibility::Hyperlink* TextEditor::AccessibleImpl::GetLink(int32_t linkIndex) const
-{
- if(linkIndex < 0 || linkIndex >= GetLinkCount())
- {
- return nullptr;
- }
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto anchorActor = Dali::Toolkit::GetImpl(self).mAnchorActors[linkIndex];
- return dynamic_cast<Accessibility::Hyperlink*>(Dali::Accessibility::Accessible::Get(anchorActor));
-}
-
-int32_t TextEditor::AccessibleImpl::GetLinkIndex(int32_t characterOffset) const
-{
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
- return controller->GetAnchorIndex(static_cast<size_t>(characterOffset));
+ selfImpl.RequestTextRelayout();
}
} // namespace Internal
#include <dali-toolkit/devel-api/controls/scroll-bar/scroll-bar.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
#include <dali-toolkit/internal/text/decorator/text-decorator.h>
#include <dali-toolkit/internal/text/rendering/text-renderer.h>
#include <dali-toolkit/internal/text/text-anchor-control-interface.h>
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Control::OnStyleChange()
*/
void OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change) override;
/**
* @brief This structure is to connect TextEditor with Accessible functions.
*/
- struct AccessibleImpl : public DevelControl::ControlAccessible,
- public virtual Dali::Accessibility::EditableText,
- public virtual Dali::Accessibility::Hypertext
+ class TextEditorAccessible : public EditableTextControlAccessible
{
- using DevelControl::ControlAccessible::ControlAccessible;
+ public:
+ using EditableTextControlAccessible::EditableTextControlAccessible;
/**
* @copydoc Dali::Accessibility::Accessible::GetName()
*/
std::string GetName() const override;
+ protected:
/**
- * @copydoc Dali::Accessibility::Text::GetText()
- */
- std::string GetText(size_t startOffset, size_t endOffset) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetCharacterCount()
- */
- size_t GetCharacterCount() const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetCursorOffset()
- */
- size_t GetCursorOffset() const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::SetCursorOffset()
- */
- bool SetCursorOffset(size_t offset) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
- */
- Accessibility::Range GetTextAtOffset(size_t offset, Accessibility::TextBoundary boundary) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
- */
- Accessibility::Range GetRangeOfSelection(size_t selectionIndex) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::RemoveSelection()
- */
- bool RemoveSelection(size_t selectionIndex) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
- */
- bool SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetRangeExtents()
- */
- Rect<> GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type) override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::CopyText()
- */
- bool CopyText(size_t startPosition, size_t endPosition) override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::CutText()
- */
- bool CutText(size_t startPosition, size_t endPosition) override;
-
- /**
- * @copydoc Dali::Accessibility::Accessible::GetStates()
- */
- Accessibility::States CalculateStates() override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::InsertText()
- */
- bool InsertText(size_t startPosition, std::string text) override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::SetTextContents()
- */
- bool SetTextContents(std::string newContents) override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::DeleteText()
- */
- bool DeleteText(size_t startPosition, size_t endPosition) override;
-
- /**
- * @copydoc Dali::Accessibility::Hypertext::GetLink()
+ * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextAnchors()
*/
- Accessibility::Hyperlink* GetLink(int32_t linkIndex) const override;
+ const std::vector<Toolkit::TextAnchor>& GetTextAnchors() const override;
/**
- * @copydoc Dali::Accessibility::Hypertext::GetLinkIndex()
+ * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextController()
*/
- int32_t GetLinkIndex(int32_t characterOffset) const override;
+ Toolkit::Text::ControllerPtr GetTextController() const override;
/**
- * @copydoc Dali::Accessibility::Hypertext::GetLinkCount()
+ * @copydoc Dali::Toolkit::Internal::EditableTextControlAccessible::RequestTextRelayout()
*/
- int32_t GetLinkCount() const override;
+ void RequestTextRelayout() override;
};
};
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-field-devel.h>
-#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
#include <dali-toolkit/devel-api/text/rendering-backend.h>
#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
#include <dali-toolkit/internal/controls/text-controls/text-field-property-handler.h>
return fieldInputStyleMask;
}
-bool IsHiddenInput(Toolkit::TextField textField)
-{
- Property::Map hiddenInputSettings = textField.GetProperty<Property::Map>(Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS);
- auto mode = hiddenInputSettings.Find(Toolkit::HiddenInput::Property::MODE);
- if(mode && (mode->Get<int>() != Toolkit::HiddenInput::Mode::HIDE_NONE))
- {
- return true;
- }
- return false;
-}
-
-char GetSubstituteCharacter(Toolkit::TextField textField)
-{
- Property::Map hiddenInputSettings = textField.GetProperty<Property::Map>(Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS);
- auto substChar = hiddenInputSettings.Find(Toolkit::HiddenInput::Property::SUBSTITUTE_CHARACTER);
- if(substChar)
- {
- return static_cast<char>(substChar->Get<int>());
- }
- return STAR;
-}
-
} // namespace
Toolkit::TextField TextField::New()
self.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT);
self.OnSceneSignal().Connect(this, &TextField::OnSceneConnect);
- //Enable highightability
- self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
-
DevelControl::SetInputMethodContext(*this, mInputMethodContext);
if(Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy)
EnableClipping();
}
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::ENTRY));
- });
+ // Accessibility
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::ENTRY);
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
Accessibility::Bridge::EnabledSignal().Connect(this, &TextField::OnAccessibilityStatusChanged);
Accessibility::Bridge::DisabledSignal().Connect(this, &TextField::OnAccessibilityStatusChanged);
}
+DevelControl::ControlAccessible* TextField::CreateAccessibleObject()
+{
+ return new TextFieldAccessible(Self());
+}
+
void TextField::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
{
DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnStyleChange\n");
void TextField::TextInserted(unsigned int position, unsigned int length, const std::string& content)
{
- if(Accessibility::IsUp())
- {
- Control::Impl::GetAccessibilityObject(Self())->EmitTextInserted(position, length, content);
- }
+ GetAccessibleObject()->EmitTextInserted(position, length, content);
}
void TextField::TextDeleted(unsigned int position, unsigned int length, const std::string& content)
{
- if(Accessibility::IsUp())
- {
- Control::Impl::GetAccessibilityObject(Self())->EmitTextDeleted(position, length, content);
- }
+ GetAccessibleObject()->EmitTextDeleted(position, length, content);
}
void TextField::CursorPositionChanged(unsigned int oldPosition, unsigned int newPosition)
{
- if(Accessibility::IsUp())
- {
- Control::Impl::GetAccessibilityObject(Self())->EmitTextCursorMoved(newPosition);
- }
+ GetAccessibleObject()->EmitTextCursorMoved(newPosition);
if((oldPosition != newPosition) && !mCursorPositionChanged)
{
return mController->GetTextPosition(startIndex, endIndex);
}
-std::string TextField::AccessibleImpl::GetName() const
+std::string TextField::TextFieldAccessible::GetName() const
{
- auto self = Toolkit::TextField::DownCast(Self());
- if(IsHiddenInput(self))
+ if(IsHiddenInput())
{
return {};
}
- return self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
-}
-
-std::string TextField::AccessibleImpl::GetText(size_t startOffset, size_t endOffset) const
-{
- if(endOffset <= startOffset)
- {
- return {};
- }
-
- auto self = Toolkit::TextField::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
-
- if(startOffset > text.size() || endOffset > text.size())
- {
- return {};
- }
- if(IsHiddenInput(self))
- {
- return std::string(endOffset - startOffset, GetSubstituteCharacter(self));
- }
- return text.substr(startOffset, endOffset - startOffset);
+ return GetWholeText();
}
-size_t TextField::AccessibleImpl::GetCharacterCount() const
+const std::vector<Toolkit::TextAnchor>& TextField::TextFieldAccessible::GetTextAnchors() const
{
auto self = Toolkit::TextField::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
- return text.size();
+ return Toolkit::GetImpl(self).mAnchorActors;
}
-size_t TextField::AccessibleImpl::GetCursorOffset() const
+Toolkit::Text::ControllerPtr TextField::TextFieldAccessible::GetTextController() const
{
auto self = Toolkit::TextField::DownCast(Self());
- return Dali::Toolkit::GetImpl(self).GetTextController()->GetCursorPosition();
-}
-
-bool TextField::AccessibleImpl::SetCursorOffset(size_t offset)
-{
- auto self = Toolkit::TextField::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
- if(offset > text.size())
- {
- return false;
- }
-
- auto& selfImpl = Dali::Toolkit::GetImpl(self);
- selfImpl.GetTextController()->ResetCursorPosition(offset);
- selfImpl.RequestTextRelayout();
-
- return true;
-}
-
-Dali::Accessibility::Range TextField::AccessibleImpl::GetTextAtOffset(
- size_t offset, Dali::Accessibility::TextBoundary boundary) const
-{
- auto self = Toolkit::TextField::DownCast(Self());
- auto range = Dali::Accessibility::Range{};
-
- if(IsHiddenInput(self))
- {
- // Returning empty object, as there is no possibility to parse the textfield
- // when its content is hidden.
- return range;
- }
-
- auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
- auto textSize = text.size();
-
- switch(boundary)
- {
- case Dali::Accessibility::TextBoundary::CHARACTER:
- {
- if(offset < textSize)
- {
- range.content = text[offset];
- range.startOffset = offset;
- range.endOffset = offset + 1;
- }
- break;
- }
- case Dali::Accessibility::TextBoundary::WORD:
- case Dali::Accessibility::TextBoundary::LINE:
- {
- auto textString = text.c_str();
- auto breaks = std::vector<char>(textSize, 0);
-
- if(boundary == Dali::Accessibility::TextBoundary::WORD)
- {
- Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
- }
- else
- {
- Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
- }
-
- auto index = 0u;
- auto counter = 0u;
- while(index < textSize && counter <= offset)
- {
- auto start = index;
- if(breaks[index])
- {
- while(breaks[index])
- {
- index++;
- }
- counter++;
- }
- else
- {
- if(boundary == Dali::Accessibility::TextBoundary::WORD)
- {
- index++;
- }
- if(boundary == Dali::Accessibility::TextBoundary::LINE)
- {
- counter++;
- }
- }
-
- if((counter > 0) && ((counter - 1) == offset))
- {
- range.content = text.substr(start, index - start + 1);
- range.startOffset = start;
- range.endOffset = index + 1;
- }
-
- if(boundary == Dali::Accessibility::TextBoundary::LINE)
- {
- index++;
- }
- }
- break;
- }
- case Dali::Accessibility::TextBoundary::SENTENCE:
- {
- /* not supported by default */
- break;
- }
- case Dali::Accessibility::TextBoundary::PARAGRAPH:
- {
- /* Paragraph is not supported by libunibreak library */
- break;
- }
- default:
- break;
- }
- return range;
+ return Toolkit::GetImpl(self).GetTextController();
}
-Dali::Accessibility::Range TextField::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex) const
+std::uint32_t TextField::TextFieldAccessible::GetSubstituteCharacter() const
{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return {};
- }
-
- auto self = Toolkit::TextField::DownCast(Self());
- auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
- auto indices = controller->GetSelectionIndexes();
-
- auto startOffset = static_cast<size_t>(indices.first);
- auto endOffset = static_cast<size_t>(indices.second);
+ auto self = Toolkit::TextField::DownCast(Self());
+ auto hiddenInputSettings = self.GetProperty<Property::Map>(Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS);
+ auto substChar = hiddenInputSettings.Find(Toolkit::HiddenInput::Property::SUBSTITUTE_CHARACTER);
- if(IsHiddenInput(self))
- {
- return {startOffset, endOffset, std::string(endOffset - startOffset, GetSubstituteCharacter(self))};
- }
-
- std::string value{};
- controller->RetrieveSelection(value);
- return {startOffset, endOffset, value};
-}
-
-bool TextField::AccessibleImpl::RemoveSelection(size_t selectionIndex)
-{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return false;
- }
-
- auto self = Toolkit::TextField::DownCast(Self());
- Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(0, 0);
- return true;
-}
-
-bool TextField::AccessibleImpl::SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset)
-{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return false;
- }
-
- auto self = Toolkit::TextField::DownCast(Self());
- Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(startOffset, endOffset);
- return true;
-}
-
-Rect<> TextField::AccessibleImpl::GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type)
-{
- if (endOffset <= startOffset || endOffset <= 0)
- {
- return {0, 0, 0, 0};
- }
-
- auto self = Toolkit::TextField::DownCast(Self());
- auto rect = Dali::Toolkit::GetImpl(self).GetTextController()->GetTextBoundingRectangle(startOffset, endOffset - 1);
-
- auto componentExtents = this->GetExtents(type);
-
- rect.x += componentExtents.x;
- rect.y += componentExtents.y;
-
- return rect;
-}
-
-bool TextField::AccessibleImpl::CopyText(size_t startPosition, size_t endPosition)
-{
- if(endPosition <= startPosition)
- {
- return false;
- }
-
- auto self = Toolkit::TextField::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
- Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
-
- return true;
-}
-
-bool TextField::AccessibleImpl::CutText(size_t startPosition, size_t endPosition)
-{
- if(endPosition <= startPosition)
- {
- return false;
- }
-
- auto self = Toolkit::TextField::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
- Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
-
- self.SetProperty(Toolkit::TextField::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
-
- return true;
-}
-
-bool TextField::AccessibleImpl::DeleteText(size_t startPosition, size_t endPosition)
-{
- if(endPosition <= startPosition)
- {
- return false;
- }
-
- auto self = Toolkit::TextField::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
-
- self.SetProperty(Toolkit::TextField::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
-
- return true;
-}
-
-Dali::Accessibility::States TextField::AccessibleImpl::CalculateStates()
-{
- using namespace Dali::Accessibility;
-
- auto states = DevelControl::ControlAccessible::CalculateStates();
-
- states[State::EDITABLE] = true;
- states[State::FOCUSABLE] = true;
-
- Toolkit::Control focusControl = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
- if(Self() == focusControl)
+ if(substChar)
{
- states[State::FOCUSED] = true;
+ return static_cast<std::uint32_t>(substChar->Get<int>());
}
- return states;
+ return TextControlAccessible::GetSubstituteCharacter();
}
-bool TextField::AccessibleImpl::InsertText(size_t startPosition, std::string text)
+bool TextField::TextFieldAccessible::IsHiddenInput() const
{
- auto self = Toolkit::TextField::DownCast(Self());
- auto insertedText = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
-
- insertedText.insert(startPosition, text);
-
- self.SetProperty(Toolkit::TextField::Property::TEXT, std::move(insertedText));
+ auto self = Toolkit::TextField::DownCast(Self());
+ auto hiddenInputSettings = self.GetProperty<Property::Map>(Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS);
+ auto mode = hiddenInputSettings.Find(Toolkit::HiddenInput::Property::MODE);
- return true;
+ return (mode && (mode->Get<int>() != Toolkit::HiddenInput::Mode::HIDE_NONE));
}
-bool TextField::AccessibleImpl::SetTextContents(std::string newContents)
+void TextField::TextFieldAccessible::RequestTextRelayout()
{
- auto self = Toolkit::TextField::DownCast(Self());
- self.SetProperty(Toolkit::TextField::Property::TEXT, std::move(newContents));
- return true;
-}
+ auto self = Toolkit::TextField::DownCast(Self());
+ auto& selfImpl = Toolkit::GetImpl(self);
-int32_t TextField::AccessibleImpl::GetLinkCount() const
-{
- auto self = Toolkit::TextField::DownCast(Self());
- return Dali::Toolkit::GetImpl(self).mAnchorActors.size();
-}
-
-Accessibility::Hyperlink* TextField::AccessibleImpl::GetLink(int32_t linkIndex) const
-{
- if(linkIndex < 0 || linkIndex >= GetLinkCount())
- {
- return nullptr;
- }
- auto self = Toolkit::TextField::DownCast(Self());
- auto anchorActor = Dali::Toolkit::GetImpl(self).mAnchorActors[linkIndex];
- return dynamic_cast<Accessibility::Hyperlink*>(Dali::Accessibility::Accessible::Get(anchorActor));
-}
-
-int32_t TextField::AccessibleImpl::GetLinkIndex(int32_t characterOffset) const
-{
- auto self = Toolkit::TextField::DownCast(Self());
- auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
- return controller->GetAnchorIndex(static_cast<size_t>(characterOffset));
+ selfImpl.RequestTextRelayout();
}
} // namespace Internal
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-field-devel.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
#include <dali-toolkit/internal/text/decorator/text-decorator.h>
#include <dali-toolkit/internal/text/rendering/text-renderer.h>
#include <dali-toolkit/internal/text/text-anchor-control-interface.h>
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Control::OnStyleChange()
*/
void OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change) override;
/**
* @brief This structure is to connect TextField with Accessible functions.
*/
- struct AccessibleImpl : public DevelControl::ControlAccessible,
- public virtual Dali::Accessibility::EditableText,
- public virtual Dali::Accessibility::Hypertext
+ class TextFieldAccessible : public EditableTextControlAccessible
{
- using DevelControl::ControlAccessible::ControlAccessible;
+ public:
+ using EditableTextControlAccessible::EditableTextControlAccessible;
/**
* @copydoc Dali::Accessibility::Accessible::GetName()
*/
std::string GetName() const override;
+ protected:
/**
- * @copydoc Dali::Accessibility::Text::GetText()
- */
- std::string GetText(size_t startOffset, size_t endOffset) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetCharacterCount()
- */
- size_t GetCharacterCount() const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetCursorOffset()
- */
- size_t GetCursorOffset() const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::SetCursorOffset()
- */
- bool SetCursorOffset(size_t offset) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
- */
- Accessibility::Range GetTextAtOffset(size_t offset, Accessibility::TextBoundary boundary) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
- */
- Accessibility::Range GetRangeOfSelection(size_t selectionIndex) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::RemoveSelection()
- */
- bool RemoveSelection(size_t selectionIndex) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
- */
- bool SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetRangeExtents()
- */
- Rect<> GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type) override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::CopyText()
- */
- bool CopyText(size_t startPosition, size_t endPosition) override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::CutText()
- */
- bool CutText(size_t startPosition, size_t endPosition) override;
-
- /**
- * @copydoc Dali::Accessibility::Accessible::GetStates()
- */
- Accessibility::States CalculateStates() override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::InsertText()
- */
- bool InsertText(size_t startPosition, std::string text) override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::SetTextContents()
+ * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextAnchors()
*/
- bool SetTextContents(std::string newContents) override;
+ const std::vector<Toolkit::TextAnchor>& GetTextAnchors() const override;
/**
- * @copydoc Dali::Accessibility::EditableText::DeleteText()
+ * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextController()
*/
- bool DeleteText(size_t startPosition, size_t endPosition) override;
+ Toolkit::Text::ControllerPtr GetTextController() const override;
/**
- * @copydoc Dali::Accessibility::Hypertext::GetLink()
+ * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetSubstituteCharacter()
*/
- Accessibility::Hyperlink* GetLink(int32_t linkIndex) const override;
+ std::uint32_t GetSubstituteCharacter() const override;
/**
- * @copydoc Dali::Accessibility::Hypertext::GetLinkIndex()
+ * @copydoc Dali::Toolkit::Internal::TextControlAccessible::IsHiddenInput()
*/
- int32_t GetLinkIndex(int32_t characterOffset) const override;
+ bool IsHiddenInput() const override;
/**
- * @copydoc Dali::Accessibility::Hypertext::GetLinkCount()
+ * @copydoc Dali::Toolkit::Internal::EditableTextControlAccessible::RequestTextRelayout()
*/
- int32_t GetLinkCount() const override;
+ void RequestTextRelayout() override;
};
};
self.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
self.SetResizePolicy(ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT);
- // Enable highlightability
- self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
-
// Enable the text ellipsis.
mController->SetTextElideEnabled(true); // If false then text larger than control will overflow
Layout::Engine& engine = mController->GetLayoutEngine();
engine.SetCursorWidth(0u); // Do not layout space for the cursor.
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::LABEL));
- });
+ // Accessibility
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::LABEL);
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
Accessibility::Bridge::EnabledSignal().Connect(this, &TextLabel::OnAccessibilityStatusChanged);
Accessibility::Bridge::DisabledSignal().Connect(this, &TextLabel::OnAccessibilityStatusChanged);
}
+DevelControl::ControlAccessible* TextLabel::CreateAccessibleObject()
+{
+ return new TextLabelAccessible(Self());
+}
+
void TextLabel::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
{
DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextLabel::OnStyleChange\n");
return mController->GetTextPosition(startIndex, endIndex);
}
-std::string TextLabel::AccessibleImpl::GetNameRaw() const
+std::string TextLabel::TextLabelAccessible::GetNameRaw() const
{
- auto self = Toolkit::TextLabel::DownCast(Self());
- return self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
+ return GetWholeText();
}
-Property::Index TextLabel::AccessibleImpl::GetNamePropertyIndex()
+Property::Index TextLabel::TextLabelAccessible::GetNamePropertyIndex()
{
return Toolkit::TextLabel::Property::TEXT;
}
-std::string TextLabel::AccessibleImpl::GetText(size_t startOffset, size_t endOffset) const
+const std::vector<Toolkit::TextAnchor>& TextLabel::TextLabelAccessible::GetTextAnchors() const
{
- if(endOffset <= startOffset)
- {
- return {};
- }
-
auto self = Toolkit::TextLabel::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
-
- if(startOffset > text.size() || endOffset > text.size())
- {
- return {};
- }
- return text.substr(startOffset, endOffset - startOffset);
+ return Toolkit::GetImpl(self).mAnchorActors;
}
-size_t TextLabel::AccessibleImpl::GetCharacterCount() const
+Toolkit::Text::ControllerPtr TextLabel::TextLabelAccessible::GetTextController() const
{
auto self = Toolkit::TextLabel::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
-
- return text.size();
-}
-
-size_t TextLabel::AccessibleImpl::GetCursorOffset() const
-{
- return {};
-}
-
-bool TextLabel::AccessibleImpl::SetCursorOffset(size_t offset)
-{
- return {};
-}
-
-Dali::Accessibility::Range TextLabel::AccessibleImpl::GetTextAtOffset(size_t offset, Dali::Accessibility::TextBoundary boundary) const
-{
- auto self = Toolkit::TextLabel::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
- auto textSize = text.size();
- auto range = Dali::Accessibility::Range{};
-
- switch(boundary)
- {
- case Dali::Accessibility::TextBoundary::CHARACTER:
- {
- if(offset < textSize)
- {
- range.content = text[offset];
- range.startOffset = offset;
- range.endOffset = offset + 1;
- }
- break;
- }
- case Dali::Accessibility::TextBoundary::WORD:
- case Dali::Accessibility::TextBoundary::LINE:
- {
- auto textString = text.c_str();
- auto breaks = std::vector<char>(textSize, 0);
-
- if(boundary == Dali::Accessibility::TextBoundary::WORD)
- {
- Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
- }
- else
- {
- Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
- }
-
- auto index = 0u;
- auto counter = 0u;
- while(index < textSize && counter <= offset)
- {
- auto start = index;
- if(breaks[index])
- {
- while(breaks[index])
- {
- index++;
- }
- counter++;
- }
- else
- {
- if(boundary == Dali::Accessibility::TextBoundary::WORD)
- {
- index++;
- }
- if(boundary == Dali::Accessibility::TextBoundary::LINE)
- {
- counter++;
- }
- }
-
- if((counter > 0) && ((counter - 1) == offset))
- {
- range.content = text.substr(start, index - start + 1);
- range.startOffset = start;
- range.endOffset = index + 1;
- }
-
- if(boundary == Dali::Accessibility::TextBoundary::LINE)
- {
- index++;
- }
- }
- break;
- }
- case Dali::Accessibility::TextBoundary::SENTENCE:
- {
- /* not supported by default */
- break;
- }
- case Dali::Accessibility::TextBoundary::PARAGRAPH:
- {
- /* Paragraph is not supported by libunibreak library */
- break;
- }
- default:
- break;
- }
-
- return range;
-}
-
-Dali::Accessibility::Range TextLabel::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex) const
-{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return {};
- }
-
- auto self = Toolkit::TextLabel::DownCast(Self());
- auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
- std::string value{};
- controller->RetrieveSelection(value);
- auto indices = controller->GetSelectionIndexes();
-
- return {static_cast<size_t>(indices.first), static_cast<size_t>(indices.second), value};
-}
-
-bool TextLabel::AccessibleImpl::RemoveSelection(size_t selectionIndex)
-{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return false;
- }
-
- auto self = Toolkit::TextLabel::DownCast(Self());
- Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(0, 0);
- return true;
-}
-
-bool TextLabel::AccessibleImpl::SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset)
-{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return false;
- }
-
- auto self = Toolkit::TextLabel::DownCast(Self());
- Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(startOffset, endOffset);
- return true;
-}
-
-Rect<> TextLabel::AccessibleImpl::GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type)
-{
- if (endOffset <= startOffset || endOffset <= 0)
- {
- return {0, 0, 0, 0};
- }
-
- auto self = Toolkit::TextLabel::DownCast(Self());
- auto rect = Dali::Toolkit::GetImpl(self).GetTextController()->GetTextBoundingRectangle(startOffset, endOffset - 1);
-
- auto componentExtents = this->GetExtents(type);
-
- rect.x += componentExtents.x;
- rect.y += componentExtents.y;
-
- return rect;
-}
-
-int32_t TextLabel::AccessibleImpl::GetLinkCount() const
-{
- auto self = Toolkit::TextLabel::DownCast(Self());
- return Dali::Toolkit::GetImpl(self).mAnchorActors.size();
-}
-
-Accessibility::Hyperlink* TextLabel::AccessibleImpl::GetLink(int32_t linkIndex) const
-{
- if(linkIndex < 0 || linkIndex >= GetLinkCount())
- {
- return nullptr;
- }
- auto self = Toolkit::TextLabel::DownCast(Self());
- auto anchorActor = Dali::Toolkit::GetImpl(self).mAnchorActors[linkIndex];
- return dynamic_cast<Accessibility::Hyperlink*>(Dali::Accessibility::Accessible::Get(anchorActor));
-}
-
-int32_t TextLabel::AccessibleImpl::GetLinkIndex(int32_t characterOffset) const
-{
- auto self = Toolkit::TextLabel::DownCast(Self());
- auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
- return controller->GetAnchorIndex(static_cast<size_t>(characterOffset));
+ return Toolkit::GetImpl(self).GetTextController();
}
} // namespace Internal
// INTERNAL INCLUDES
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
#include <dali-toolkit/internal/text/rendering/text-renderer.h>
#include <dali-toolkit/internal/text/text-anchor-control-interface.h>
#include <dali-toolkit/internal/text/text-control-interface.h>
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Control::OnStyleChange()
*/
void OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change) override;
/**
* @brief This structure is to connect TextLabel with Accessible functions.
*/
- struct AccessibleImpl : public DevelControl::ControlAccessible,
- public virtual Dali::Accessibility::Text,
- public virtual Dali::Accessibility::Hypertext
+ class TextLabelAccessible : public TextControlAccessible
{
- using DevelControl::ControlAccessible::ControlAccessible;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetText()
- */
- std::string GetText(size_t startOffset, size_t endOffset) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetCharacterCount()
- */
- size_t GetCharacterCount() const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetCursorOffset()
- */
- size_t GetCursorOffset() const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::SetCursorOffset()
- */
- bool SetCursorOffset(size_t offset) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
- */
- Accessibility::Range GetTextAtOffset(size_t offset, Accessibility::TextBoundary boundary) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
- */
- Accessibility::Range GetRangeOfSelection(size_t selectionIndex) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::RemoveSelection()
- */
- bool RemoveSelection(size_t selectionIndex) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
- */
- bool SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetRangeExtents()
- */
- Rect<> GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type) override;
+ public:
+ using TextControlAccessible::TextControlAccessible;
/**
* @copydoc Dali::Accessibility::Text::GetNameRaw()
*/
Property::Index GetNamePropertyIndex() override;
+ protected:
/**
- * @copydoc Dali::Accessibility::Hypertext::GetLink()
- */
- Accessibility::Hyperlink* GetLink(int32_t linkIndex) const override;
-
- /**
- * @copydoc Dali::Accessibility::Hypertext::GetLinkIndex()
+ * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextAnchors()
*/
- int32_t GetLinkIndex(int32_t characterOffset) const override;
+ const std::vector<Toolkit::TextAnchor>& GetTextAnchors() const override;
/**
- * @copydoc Dali::Accessibility::Hypertext::GetLinkCount()
+ * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextController()
*/
- int32_t GetLinkCount() const override;
+ Toolkit::Text::ControllerPtr GetTextController() const override;
};
};
self.SetResizePolicy(ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS);
self.SetProperty(Actor::Property::COLOR_ALPHA, 0.0f);
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::DIALOG, true));
- });
-
- //Enable highightability
+ // Accessibility
self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+ self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::DIALOG);
+}
+
+DevelControl::ControlAccessible* TextSelectionPopup::CreateAccessibleObject()
+{
+ return new TextSelectionPopupAccessible(Self());
+}
+
+Dali::Accessibility::States TextSelectionPopup::TextSelectionPopupAccessible::CalculateStates()
+{
+ auto states = ControlAccessible::CalculateStates();
+
+ states[Dali::Accessibility::State::MODAL] = true;
+
+ return states;
}
void TextSelectionPopup::HideAnimationFinished(Animation& animation)
#include <string>
// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/controls/table-view/table-view.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-selection-toolbar.h>
*/
void OnInitialize() override;
+ /**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
private: // Implementation
void HideAnimationFinished(Animation& animation);
*/
virtual ~TextSelectionPopup();
+protected:
+ class TextSelectionPopupAccessible : public DevelControl::ControlAccessible
+ {
+ public:
+ using DevelControl::ControlAccessible::ControlAccessible;
+
+ /**
+ * @copydoc DevelControl::ControlAccessible::CalculateStates()
+ */
+ Dali::Accessibility::States CalculateStates() override;
+ };
+
private:
// Undefined copy constructor and assignment operators
TextSelectionPopup(const TextSelectionPopup&);
{
SetUp();
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::TOOL_BAR));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::TOOL_BAR);
}
void TextSelectionToolbar::OnRelayout(const Vector2& size, RelayoutContainer& container)
mLayout.SetRelativeWidth(0, mLeftRelativeSpace);
mLayout.SetRelativeWidth(1, mRightRelativeSpace);
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::TOOL_BAR));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::TOOL_BAR);
}
void ToolBar::OnChildAdd(Actor& child)
Actor self = Self();
mVideoPlayer.FinishedSignal().Connect(this, &VideoView::EmitSignalFinish);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::VIDEO));
- });
-
- //Enable highightability
- Self().SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+ // Accessibility
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::VIDEO);
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
//update self property
self.RegisterProperty(IS_VIDEO_VIEW_PROPERTY_NAME, true, Property::READ_WRITE);
#include <dali/public-api/animation/constraints.h>
#include <dali/public-api/events/key-event.h>
#include <dali/public-api/events/touch-event.h>
+#include <dali/public-api/events/wheel-event.h>
#include <dali/public-api/object/property-map.h>
#include <dali/public-api/object/type-registry-helper.h>
#include <dali/public-api/object/type-registry.h>
{
(*iter).KeyEventSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnKeyEvent);
(*iter).TouchedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnTouch);
- (*iter).WheelEventGeneratedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnWheelEvent);
+ (*iter).WheelEventGeneratedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnCustomWheelEvent);
+ (*iter).WheelEventSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnWheelEvent);
Dali::Window window = DevelWindow::DownCast(*iter);
if(window)
{
{
sceneHolder.KeyEventSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnKeyEvent);
sceneHolder.TouchedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnTouch);
- sceneHolder.WheelEventGeneratedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnWheelEvent);
+ sceneHolder.WheelEventGeneratedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnCustomWheelEvent);
+ sceneHolder.WheelEventSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnWheelEvent);
Dali::Window window = DevelWindow::DownCast(sceneHolder);
if(window)
{
return Toolkit::Control::DownCast(parent);
}
-bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction direction)
+bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction direction, const std::string& deviceName)
{
Actor currentFocusActor = GetCurrentFocusActor();
index = Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID;
break;
}
+ case Toolkit::Control::KeyboardFocus::CLOCKWISE:
+ {
+ index = Toolkit::DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID;
+ break;
+ }
+ case Toolkit::Control::KeyboardFocus::COUNTER_CLOCKWISE:
+ {
+ index = Toolkit::DevelControl::Property::COUNTER_CLOCKWISE_FOCUSABLE_ACTOR_ID;
+ break;
+ }
default:
break;
}
if(mCustomAlgorithmInterface)
{
mIsWaitingKeyboardFocusChangeCommit = true;
- nextFocusableActor = mCustomAlgorithmInterface->GetNextFocusableActor(currentFocusActor, Actor(), direction);
+ nextFocusableActor = mCustomAlgorithmInterface->GetNextFocusableActor(currentFocusActor, Actor(), direction, deviceName);
mIsWaitingKeyboardFocusChangeCommit = false;
}
else if(!mPreFocusChangeSignal.Empty())
nextFocusableActor = mPreFocusChangeSignal.Emit(currentFocusActor, Actor(), direction);
mIsWaitingKeyboardFocusChangeCommit = false;
}
- else if(mEnableDefaultAlgorithm && currentFocusActor)
+ else if (mEnableDefaultAlgorithm)
{
- // We should find it among the actors nearby.
- Integration::SceneHolder window = Integration::SceneHolder::Get(currentFocusActor);
- if(window)
+ Layer rootLayer;
+ if (currentFocusActor)
+ {
+ // Find the window of the focused actor.
+ Integration::SceneHolder window = Integration::SceneHolder::Get(currentFocusActor);
+ if (window)
+ {
+ rootLayer = window.GetRootLayer();
+ }
+ }
+ else
{
- nextFocusableActor = Toolkit::FocusFinder::GetNearestFocusableActor(window.GetRootLayer(), currentFocusActor, direction);
+ // Searches from the currently focused window.
+ rootLayer = mCurrentFocusedWindow.GetHandle();
+ }
+ if (rootLayer)
+ {
+ // We should find it among the actors nearby.
+ nextFocusableActor = Toolkit::FocusFinder::GetNearestFocusableActor(rootLayer, currentFocusActor, direction);
}
}
}
void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
{
- std::string keyName = event.GetKeyName();
+ const std::string& keyName = event.GetKeyName();
+ const std::string& deviceName = event.GetDeviceName();
if(mIsFocusIndicatorShown == UNKNOWN)
{
else
{
// Move the focus towards left
- MoveFocus(Toolkit::Control::KeyboardFocus::LEFT);
+ MoveFocus(Toolkit::Control::KeyboardFocus::LEFT, deviceName);
}
isFocusStartableKey = true;
else
{
// Move the focus towards right
- MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT);
+ MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT, deviceName);
}
isFocusStartableKey = true;
else
{
// Move the focus towards up
- MoveFocus(Toolkit::Control::KeyboardFocus::UP);
+ MoveFocus(Toolkit::Control::KeyboardFocus::UP, deviceName);
}
isFocusStartableKey = true;
else
{
// Move the focus towards down
- MoveFocus(Toolkit::Control::KeyboardFocus::DOWN);
+ MoveFocus(Toolkit::Control::KeyboardFocus::DOWN, deviceName);
}
isFocusStartableKey = true;
else
{
// Move the focus towards the previous page
- MoveFocus(Toolkit::Control::KeyboardFocus::PAGE_UP);
+ MoveFocus(Toolkit::Control::KeyboardFocus::PAGE_UP, deviceName);
}
isFocusStartableKey = true;
else
{
// Move the focus towards the next page
- MoveFocus(Toolkit::Control::KeyboardFocus::PAGE_DOWN);
+ MoveFocus(Toolkit::Control::KeyboardFocus::PAGE_DOWN, deviceName);
}
isFocusStartableKey = true;
if(!DoMoveFocusToNextFocusGroup(!event.IsShiftModifier()))
{
// If the focus group is not changed, Move the focus towards forward, "Shift-Tap" key moves the focus towards backward.
- MoveFocus(event.IsShiftModifier() ? Toolkit::Control::KeyboardFocus::BACKWARD : Toolkit::Control::KeyboardFocus::FORWARD);
+ MoveFocus(event.IsShiftModifier() ? Toolkit::Control::KeyboardFocus::BACKWARD : Toolkit::Control::KeyboardFocus::FORWARD, deviceName);
}
}
{
// No actor is focused but keyboard focus is activated by the key press
// Let's try to move the initial focus
- MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT);
+ MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT, deviceName);
}
}
}
}
}
-bool KeyboardFocusManager::OnWheelEvent(const WheelEvent& event)
+void KeyboardFocusManager::OnWheelEvent(const WheelEvent& event)
+{
+ if(event.GetType() == Dali::WheelEvent::CUSTOM_WHEEL)
+ {
+ Toolkit::Control::KeyboardFocus::Direction direction = (event.GetDelta() > 0) ? Toolkit::Control::KeyboardFocus::CLOCKWISE : Toolkit::Control::KeyboardFocus::COUNTER_CLOCKWISE;
+ // Move the focus
+ MoveFocus(direction);
+ }
+}
+
+bool KeyboardFocusManager::OnCustomWheelEvent(const WheelEvent& event)
{
bool consumed = false;
Actor actor = GetCurrentFocusActor();
if(actor)
{
// Notify the actor about the wheel event
- consumed = EmitWheelSignals(actor, event);
+ consumed = EmitCustomWheelSignals(actor, event);
}
return consumed;
}
-bool KeyboardFocusManager::EmitWheelSignals(Actor actor, const WheelEvent& event)
+bool KeyboardFocusManager::EmitCustomWheelSignals(Actor actor, const WheelEvent& event)
{
bool consumed = false;
if(parent &&
(parent == oldParent))
{
- consumed = EmitWheelSignals(parent, event);
+ consumed = EmitCustomWheelSignals(parent, event);
}
}
}
/**
* @copydoc Toolkit::KeyboardFocusManager::MoveFocus
*/
- bool MoveFocus(Toolkit::Control::KeyboardFocus::Direction direction);
+ bool MoveFocus(Toolkit::Control::KeyboardFocus::Direction direction, const std::string& deviceName = "");
/**
* @copydoc Toolkit::KeyboardFocusManager::ClearFocus
* Callback for the wheel event when the custom wheel event occurs.
* @param[in] wheel The WheelEvent information
*/
- bool OnWheelEvent(const WheelEvent& wheel);
+ bool OnCustomWheelEvent(const WheelEvent& wheel);
+
+ /**
+ * Callback for the wheel event when the wheel event occurs.
+ * @param[in] wheel The WheelEvent information
+ */
+ void OnWheelEvent(const WheelEvent& wheel);
/**
* Called when the window focus is changed.
* @param[in] event The WheelEvent.
* @return True if WheelEvent is consumed.
*/
- bool EmitWheelSignals(Actor actor, const WheelEvent& event);
+ bool EmitCustomWheelSignals(Actor actor, const WheelEvent& event);
private:
// Undefined
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
else
{
Property::Array* array = imageURLValue->GetArray();
- if(array)
+ if(array && array->Count() > 0)
{
visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), *array, propertyMap);
}
std::string imageUrl;
if(imageURLValue && imageURLValue->Get(imageUrl))
{
- visualPtr = NPatchVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
+ if(!imageUrl.empty())
+ {
+ visualPtr = NPatchVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
+ }
}
break;
}
std::string imageUrl;
if(imageURLValue && imageURLValue->Get(imageUrl))
{
- visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
+ if(!imageUrl.empty())
+ {
+ visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
+ }
}
break;
}
{
if(imageURLValue->Get(imageUrl))
{
- visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
+ if(!imageUrl.empty())
+ {
+ visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
+ }
}
else
{
Property::Array* array = imageURLValue->GetArray();
- if(array)
+ if(array && array->Count() > 0)
{
visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), *array, propertyMap);
}
std::string imageUrl;
if(imageURLValue && imageURLValue->Get(imageUrl))
{
- visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
+ if(!imageUrl.empty())
+ {
+ visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
+ }
}
break;
}
void VisualFactory::SetBrokenImageUrl(Toolkit::StyleManager& styleManager)
{
- const std::string imageDirPath = AssetManager::GetDaliImagePath();
- std::string brokenImageUrl = imageDirPath + BROKEN_IMAGE_FILE_NAME;
+ const std::string imageDirPath = AssetManager::GetDaliImagePath();
+ std::string brokenImageUrl = imageDirPath + BROKEN_IMAGE_FILE_NAME;
std::vector<std::string> customBrokenImageUrlList;
if(styleManager)
{
customBrokenImageUrlList = Toolkit::DevelStyleManager::GetBrokenImageUrlList(styleManager);
- Property::Map config = Toolkit::DevelStyleManager::GetConfigurations(styleManager);
+ Property::Map config = Toolkit::DevelStyleManager::GetConfigurations(styleManager);
config["brokenImageUrl"].Get(brokenImageUrl);
}
{
if(!mFactoryCache)
{
- mFactoryCache = std::unique_ptr<VisualFactoryCache>(new VisualFactoryCache(mPreMultiplyOnLoad));
+ mFactoryCache = std::unique_ptr<VisualFactoryCache>(new VisualFactoryCache(mPreMultiplyOnLoad));
Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
if(styleManager)
{
RelayoutRequest();
}
+Toolkit::DevelControl::ControlAccessible* Control::GetAccessibleObject()
+{
+ return mImpl->GetAccessibleObject();
+}
+
void Control::EnableGestureDetection(GestureType::Value type)
{
if((type & GestureType::PINCH) && !mImpl->mPinchGestureDetector)
return false; // Accessibility zoom action is not handled by default
}
+DevelControl::ControlAccessible* Control::CreateAccessibleObject()
+{
+ return new DevelControl::ControlAccessible(Self());
+}
+
Actor Control::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
{
return Actor();
if(Accessibility::IsUp())
{
- auto self = mImpl->GetAccessibilityObject(Self());
+ auto self = GetAccessibleObject();
self->EmitFocused(focusGained);
auto parent = self->GetParent();
if(parent && !self->GetStates()[Dali::Accessibility::State::MANAGES_DESCENDANTS])
}
case Actor::Property::VISIBLE:
{
- if(Dali::Accessibility::IsUp() && !Self().GetProperty<bool>(Toolkit::DevelControl::Property::ACCESSIBILITY_HIDDEN))
- {
- Dali::Accessibility::Accessible::Get(Self())->EmitVisible(Self().GetProperty(Actor::Property::VISIBLE).Get<bool>());
- }
+ GetAccessibleObject()->EmitVisible(Self().GetProperty<bool>(Actor::Property::VISIBLE));
break;
}
}
class StyleManager;
+namespace DevelControl
+{
+class ControlAccessible;
+
+} // namespace DevelControl
+
namespace Internal
{
*/
void ClearBackground();
+ // Accessibility
+
+ /**
+ * @brief Gets the Accessible object that represents this control.
+ *
+ * This method calls CreateAccessibleObject() if necessary, so a non-null return is expected.
+ *
+ * @return The Accessible object
+ *
+ * @see CreateAccessibleObject()
+ */
+ Toolkit::DevelControl::ControlAccessible* GetAccessibleObject();
+
// Gesture Detection
/**
*/
virtual bool OnAccessibilityZoom();
+ /**
+ * @brief This method should be overriden by deriving classes when they wish to be
+ * represented by a custom Accessible object implementation.
+ *
+ * The AT-SPI infrastructure is responsible for destroying the returned object.
+ *
+ * Currently, this method is called at most once in a given Control's lifetime, when
+ * GetAccessibleObject() is called for the first time. A future version of the
+ * AT-SPI infrastructure, however, may delete the Accessible object and request a new
+ * one to be created (by calling this method) multiple times, for example during
+ * scene connection and disconnection.
+ *
+ * @return The newly created Accessible object
+ *
+ * @see GetAccessibleObject()
+ */
+ virtual DevelControl::ControlAccessible* CreateAccessibleObject();
+
// Keyboard focus
/**
PAGE_DOWN, ///< Move keyboard focus towards the next page direction @SINCE_1_2.14
FORWARD, ///< Move keyboard focus towards the forward direction @SINCE_2_1.10
BACKWARD, ///< Move keyboard focus towards the backward direction @SINCE_2_1.10
+ CLOCKWISE, ///< Move keyboard focus towards the clockwise direction @SINCE_2_1.14
+ COUNTER_CLOCKWISE, ///< Move keyboard focus towards the counter clockwise direction @SINCE_2_1.14
};
};
{
const unsigned int TOOLKIT_MAJOR_VERSION = 2;
const unsigned int TOOLKIT_MINOR_VERSION = 1;
-const unsigned int TOOLKIT_MICRO_VERSION = 13;
+const unsigned int TOOLKIT_MICRO_VERSION = 14;
const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
+++ /dev/null
-git diff -U0 --no-color HEAD^ | clang-format-diff -i -p1
\ No newline at end of file
Name: dali2-toolkit
Summary: Dali 3D engine Toolkit
-Version: 2.1.13
+Version: 2.1.14
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT