do
echo -e "$ASCII_BOLD"
echo -e "Executing $mod$ASCII_RESET"
- build/src/$mod/tct-$mod-core $opt_serial $opt_noFailedRerun
+ dbus-launch build/src/$mod/tct-$mod-core $opt_serial $opt_noFailedRerun
done
summary_end
summary_start
module=$1
shift;
- build/src/$module/tct-$module-core $opt_serial $opt_noFailedRerun $*
+ dbus-launch build/src/$module/tct-$module-core $opt_serial $opt_noFailedRerun $*
summary_end
else
if [ $ret -ne 6 ] ; then
if [ $opt_debug -ne 0 ] ; then
echo DEBUGGING:
- gdb --args build/src/$mod/tct-$mod-core $1
+ dbus-launch gdb --args build/src/$mod/tct-$mod-core $1
else
echo $output
# List of test case sources (Only these get parsed for test cases)
SET(TC_SOURCES
utc-Dali-AddOns.cpp
+ utc-Dali-Accessibility-Accessible.cpp
+ utc-Dali-Accessibility-Controls.cpp
+ utc-Dali-Accessibility-Controls-BridgeUp.cpp
+ utc-Dali-Accessibility-Text.cpp
+ utc-Dali-Accessibility-Value.cpp
utc-Dali-BidirectionalSupport.cpp
utc-Dali-ColorConversion.cpp
utc-Dali-Control-internal.cpp
# Append list of test harness files (Won't get parsed for test cases)
LIST(APPEND TC_SOURCES
../dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp
- ../dali-toolkit/dali-toolkit-test-utils/toolkit-accessibility-adaptor.cpp
../dali-toolkit/dali-toolkit-test-utils/toolkit-application.cpp
../dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard.cpp
../dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard-event-notifier.cpp
dali-toolkit-test-utils/toolkit-text-utils.cpp
dali-toolkit-test-utils/dummy-visual.cpp
dali-toolkit-test-utils/test-addon-manager.cpp
+ dali-toolkit-test-utils/accessibility-test-utils.cpp
+ dali-toolkit-test-utils/dbus-wrapper.cpp
)
PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED
dali2-core
dali2-adaptor
dali2-toolkit
+ eldbus
+ ecore-input
+ eina
)
+MESSAGE("Libraries to link with:>${${CAPI_LIB}_LIBRARIES}")
+
ADD_COMPILE_OPTIONS( -O0 -ggdb --coverage -Wall -Werror -DDEBUG_ENABLED -fPIC )
ADD_COMPILE_OPTIONS( ${${CAPI_LIB}_CFLAGS_OTHER} )
SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -L${directory}")
ENDFOREACH(directory ${CAPI_LIB_LIBRARY_DIRS})
+STRING(STRIP ${CMAKE_CXX_LINK_FLAGS} CMAKE_CXX_LINK_FLAGS)
+
INCLUDE_DIRECTORIES(
../../../
${${CAPI_LIB}_INCLUDE_DIRS}
--- /dev/null
+#include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/accessibility-test-utils.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali/devel-api/common/stage.h>
+#include <dali/devel-api/adaptor-framework/accessibility-impl.h>
+#include "dbus-wrapper.h"
+
+namespace Dali {
+ namespace Accessibility {
+
+ using MethodType = TestDBusWrapper::MethodType;
+ using MessagePtr = DBusWrapper::MessagePtr;
+
+ void TestEnableSC(bool b) {
+ static bool firstTime = true;
+ if (b && firstTime) {
+ firstTime = false;
+ auto bridge = Accessibility::Bridge::GetCurrentBridge();
+ Dali::Stage stage = Dali::Stage::GetCurrent();
+ auto accessible = Accessibility::Accessible::Get( stage.GetRootLayer() );
+// bridge->SetApplicationChild( accessible ); // BART
+ bridge->AddTopLevelWindow( accessible ); // BART
+ bridge->SetApplicationName( "TestApp" );
+ bridge->Initialize();
+
+ static bool ScreenReaderEnabled = false;
+ static bool IsEnabled = false;
+
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+
+ wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/bus", "org.a11y.Status", "ScreenReaderEnabled", MethodType::Getter}] = [wr](const MessagePtr &m) -> MessagePtr {
+ auto reply = wr->newReplyMessage(m);
+ wr->Encode(reply, std::tuple<TestDBusWrapper::Variant<bool>>{ ScreenReaderEnabled });
+ return reply;
+ };
+ wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/bus", "org.a11y.Status", "IsEnabled", MethodType::Getter}] = [wr](const MessagePtr &m) -> MessagePtr {
+ auto reply = wr->newReplyMessage(m);
+ wr->Encode(reply, std::tuple<TestDBusWrapper::Variant<bool>>{ IsEnabled });
+ return reply;
+ };
+ wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/bus", "org.a11y.Bus", "GetAddress", MethodType::Method}] = [wr](const MessagePtr &m) -> MessagePtr {
+ auto reply = wr->newReplyMessage(m);
+ wr->Encode(reply, std::tuple<const char*>{ "bus" });
+ return reply;
+ };
+ wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible/root", "org.a11y.atspi.Socket", "Embed", MethodType::Method}] = [wr](const MessagePtr &m) -> MessagePtr {
+ auto reply = wr->newReplyMessage(m);
+ wr->Encode(reply, std::tuple<Address>{ {"bus", "root"} });
+ return reply;
+ };
+ wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "PropertyChange", MethodType::Method}] =
+ [wr](const MessagePtr &m) -> MessagePtr {
+ return wr->newReplyMessage(m);
+ };
+ wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "StateChanged", MethodType::Method}] =
+ [wr](const MessagePtr &m) -> MessagePtr {
+ return wr->newReplyMessage(m);
+ };
+ wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "BoundsChanged", MethodType::Method}] =
+ [wr](const MessagePtr &m) -> MessagePtr {
+ return wr->newReplyMessage(m);
+ };
+ wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "ActiveDescendantChanged", MethodType::Method}] =
+ [wr](const MessagePtr &m) -> MessagePtr {
+ return wr->newReplyMessage(m);
+ };
+ wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "TextChanged", MethodType::Method}] =
+ [wr](const MessagePtr &m) -> MessagePtr {
+ return wr->newReplyMessage(m);
+ };
+ wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "TextCaretMoved", MethodType::Method}] =
+ [wr](const MessagePtr &m) -> MessagePtr {
+ return wr->newReplyMessage(m);
+ };
+ }
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ wr->fromTestChangeProperty("/org/a11y/bus", "org.a11y.Status", "ScreenReaderEnabled", b);
+ wr->fromTestChangeProperty("/org/a11y/bus", "org.a11y.Status", "IsEnabled", b);
+ }
+
+ std::vector<Address> TestGetChildren(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall<std::vector<Address>>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetChildren", std::tuple<>());
+ return std::move(std::get<0>(chs));
+ }
+
+ std::string TestGetName(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto name = wr->fromTestGet<std::string>(adr.GetPath(), "org.a11y.atspi.Accessible", "Name");
+ return name;
+ }
+
+ std::string TestGetDescription(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto description = wr->fromTestGet<std::string>(adr.GetPath(), "org.a11y.atspi.Accessible", "Description");
+ return description;
+ }
+
+ uint32_t TestGetRole(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall<uint32_t>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetRole", std::tuple<>());
+ return std::move(std::get<0>(chs));
+ }
+
+ std::string TestGetRoleName(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall<std::string>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetRoleName", std::tuple<>());
+ return std::move(std::get<0>(chs));
+ }
+
+ Address TestGetParent(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestGet< Address >(adr.GetPath(), "org.a11y.atspi.Accessible", "Parent");
+ return chs;
+ }
+
+ std::string TestGetLocalizedRoleName(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall<std::string>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetLocalizedRoleName", std::tuple<>());
+ return std::move(std::get<0>(chs));
+ }
+
+ std::array< uint32_t, 2 > TestGetStates(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall<std::array< uint32_t, 2 >>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetState", std::tuple<>());
+ return std::move(std::get<0>(chs));
+ }
+
+ std::unordered_map< std::string, std::string > TestGetAttributes(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall<std::unordered_map< std::string, std::string >>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetAttributes", std::tuple<>());
+ return std::move(std::get<0>(chs));
+ }
+
+ bool TestDoGesture(const Address &adr, Dali::Accessibility::Gesture type, int32_t xBeg, int32_t xEnd, int32_t yBeg, int32_t yEnd, Dali::Accessibility::GestureState state, uint32_t eventTime)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Accessible", "DoGesture",
+ std::tuple< Dali::Accessibility::Gesture, int32_t, int32_t, int32_t, int32_t, Dali::Accessibility::GestureState, uint32_t >(type, xBeg, xEnd, yBeg, yEnd, state, eventTime ));
+ return std::move(std::get<0>(chs));
+ }
+
+ std::vector< std::tuple< uint32_t, std::vector< Dali::Accessibility::Address > > > TestGetRelationSet(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< std::vector< std::tuple< uint32_t, std::vector< Dali::Accessibility::Address > > > >(adr.GetPath(), "org.a11y.atspi.Accessible", "GetRelationSet", std::tuple<>());
+ return std::move(std::get<0>(chs));
+ }
+
+ Address TestGetChildAtIndex(const Address &adr, int index)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< Address >(adr.GetPath(), "org.a11y.atspi.Accessible", "GetChildAtIndex", std::tuple< int >( index ));
+ return std::move(std::get<0>(chs));
+ }
+
+ ComponentLayer TestGetLayer(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< Dali::Accessibility::ComponentLayer >(adr.GetPath(), "org.a11y.atspi.Component", "GetLayer", std::tuple<>());
+ return std::move(std::get<0>(chs));
+ }
+
+ int TestGetIndexInParent(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< int >(adr.GetPath(), "org.a11y.atspi.Accessible", "GetIndexInParent", std::tuple<>());
+ return std::move(std::get<0>(chs));
+ }
+
+ bool TestGrabFocus(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Component", "GrabFocus", std::tuple<>());
+ return std::move(std::get<0>(chs));
+ }
+
+ bool TestGrabHighlight(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Component", "GrabHighlight", std::tuple<>());
+ return std::move(std::get<0>(chs));
+ }
+
+ bool TestClearHighlight(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Component", "ClearHighlight", std::tuple<>());
+ return std::move(std::get<0>(chs));
+ }
+
+ std::tuple< int32_t, int32_t, int32_t, int32_t > TestGetExtents(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< std::tuple< int32_t, int32_t, int32_t, int32_t > >(adr.GetPath(), "org.a11y.atspi.Component", "GetExtents", std::tuple<uint32_t>(0));
+ return std::move(std::get<0>(chs));
+ }
+
+ int TestGetMdiZOrder(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< int16_t >(adr.GetPath(), "org.a11y.atspi.Component", "GetMDIZOrder", std::tuple<>());
+ return std::move(std::get<0>(chs));
+ }
+
+ double TestGetAlpha(const Address &adr)
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< double >(adr.GetPath(), "org.a11y.atspi.Component", "GetAlpha", std::tuple<>());
+ return std::move(std::get<0>(chs));
+ }
+
+ std::string TestGetActionName( const Address &adr, size_t index )
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< std::string >(adr.GetPath(), "org.a11y.atspi.Action", "GetName", std::tuple< int32_t >( index ));
+ return std::move(std::get<0>(chs));
+ }
+
+ std::string TestGetLocalizedActionName( const Address &adr, size_t index )
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< std::string >(adr.GetPath(), "org.a11y.atspi.Action", "GetLocalizedName", std::tuple< int32_t >( index ));
+ return std::move(std::get<0>(chs));
+ }
+
+ size_t TestGetActionCount( const Address &adr )
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto count = wr->fromTestGet< int32_t >(adr.GetPath(), "org.a11y.atspi.Action", "NActions");
+ return count;
+ }
+
+ bool TestDoAction ( const Address &adr, size_t index )
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Action", "DoAction", std::tuple< int32_t >( index ));
+ return std::move(std::get<0>(chs));
+ }
+
+ bool TestDoAction ( const Address &adr, const std::string& name )
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Action", "DoActionName", std::tuple< std::string >( name ));
+ return std::move(std::get<0>(chs));
+ }
+
+ std::string TestGetActionKeyBinding ( const Address &adr, size_t index )
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< std::string >(adr.GetPath(), "org.a11y.atspi.Action", "GetKeyBinding", std::tuple< int32_t >( index ));
+ return std::move(std::get<0>(chs));
+ }
+
+ std::string TestGetActionDescription ( const Address &adr, size_t index )
+ {
+ auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ auto chs = wr->fromTestCall< std::string >(adr.GetPath(), "org.a11y.atspi.Action", "GetDescription", std::tuple< int32_t >( index ));
+ return std::move(std::get<0>(chs));
+ }
+
+
+ void printTree(const Address &root, size_t depth)
+ {
+ auto name = TestGetName(root);
+ printf("%10s", root.GetPath().c_str());
+ for(unsigned int i = 0; i < depth; ++i) printf(" ");
+ printf("%s\n", name.c_str());
+ auto chs = TestGetChildren(root);
+ for(auto &c : chs)
+ printTree(c, depth + 1);
+ }
+
+ bool Find( const std::vector< std::string > &collection, const std::string &key)
+ {
+ for ( auto& it : collection)
+ if( it == key )
+ return true;
+ return false;
+ }
+ }
+}
--- /dev/null
+#ifndef __DALI_TOOLKIT_ACCESSIBILITY_TEST_UTILS__
+#define __DALI_TOOLKIT_ACCESSIBILITY_TEST_UTILS__
+
+#include <dali/devel-api/adaptor-framework/accessibility.h>
+
+
+namespace Dali {
+ namespace Accessibility {
+ void TestEnableSC(bool b);
+ std::vector<Address> TestGetChildren(const Address &adr);
+ std::string TestGetName(const Address &adr);
+ std::string TestGetDescription(const Address &adr);
+ uint32_t TestGetRole(const Address &adr);
+ std::string TestGetRoleName(const Address &adr);
+ Address TestGetParent(const Address &adr);
+ std::string TestGetLocalizedRoleName(const Address &adr);
+ std::array< uint32_t, 2 > TestGetStates(const Address &adr);
+ std::unordered_map< std::string, std::string > TestGetAttributes(const Address &adr);
+ bool TestDoGesture(const Address &adr, Dali::Accessibility::Gesture type, int32_t xBeg, int32_t xEnd, int32_t yBeg, int32_t yEnd, Dali::Accessibility::GestureState state, uint32_t eventTime);
+ std::vector< std::tuple< uint32_t, std::vector< Dali::Accessibility::Address > > > TestGetRelationSet(const Address &adr);
+ Address TestGetChildAtIndex(const Address &adr, int index);
+ ComponentLayer TestGetLayer(const Address &adr);
+ int TestGetIndexInParent(const Address &adr);
+ bool TestGrabFocus(const Address &adr);
+ bool TestGrabHighlight(const Address &adr);
+ bool TestClearHighlight(const Address &adr);
+ std::tuple< int32_t, int32_t, int32_t, int32_t > TestGetExtents(const Address &adr);
+ int TestGetMdiZOrder(const Address &adr);
+ double TestGetAlpha(const Address &adr);
+ void printTree(const Address &root, size_t depth = 0);
+ bool Find( const std::vector< std::string > &collection, const std::string &key);
+ std::string TestGetActionName( const Address &adr, size_t index );
+ std::string TestGetLocalizedActionName( const Address &adr, size_t index );
+ size_t TestGetActionCount( const Address &adr );
+ bool TestDoAction ( const Address &adr, size_t index );
+ bool TestDoAction ( const Address &adr, const std::string& name );
+ std::string TestGetActionKeyBinding ( const Address &adr, size_t index );
+ std::string TestGetActionDescription ( const Address &adr, size_t index );
+
+ }
+}
+
+#endif //__DALI_TOOLKIT_ACCESSIBILITY_TEST_UTILS__
--- /dev/null
+/*
+ * Copyright 2019 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// CLASS HEADER
+#include "dbus-wrapper.h"
+
+//#include <dali/internal/accessibility/bridge/accessibility-common.h>
+
+// EXTERNAL INCLUDES
+#include <sstream>
+#include <iostream>
+#include <mutex>
+
+#include <Eldbus.h>
+#include <Ecore_Input.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/dali-adaptor-common.h>
+
+#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
+
+#undef EINA_FALSE
+#undef EINA_TRUE
+#define EINA_TRUE static_cast< Eina_Bool >( 1 )
+#define EINA_FALSE static_cast< Eina_Bool >( 0 )
+
+//#define DBUS_DEBUG(...) do { DBus::debugPrint(__FILE__, __LINE__, __VA_ARGS__); } while (0)
+
+// BART QUICK HACK
+#undef assert
+#define assert(x) do{}while(0)
+
+std::atomic< unsigned int > DBus::detail::CallId::LastId{0};
+static std::function< void( const char*, size_t ) > debugPrinter;
+static std::mutex debugLock;
+
+thread_local std::string DBus::DBusServer::currentObjectPath;
+thread_local DBusWrapper::ConnectionPtr DBus::DBusServer::currentConnection;
+
+void DBus::setDebugPrinter( std::function< void( const char*, size_t ) > printer )
+{
+ std::lock_guard< std::mutex > lock( debugLock );
+ debugPrinter = std::move( printer );
+}
+
+void DBus::debugPrint( const char* file, size_t line, const char* format, ... )
+{
+ std::function< void( const char*, size_t ) > debugPrintFunc;
+ {
+ std::lock_guard< std::mutex > lock( debugLock );
+ if( !debugPrinter )
+ return;
+ debugPrintFunc = debugPrinter;
+ }
+ std::vector< char > buf( 4096 );
+ int offset;
+ while( true )
+ {
+ offset = snprintf( buf.data(), buf.size(), "%s:%u: ", file, static_cast< unsigned int >( line ) );
+ if( offset < 0 )
+ return;
+ if( static_cast< size_t >( offset ) < buf.size() )
+ break;
+ buf.resize( offset + 1 );
+ }
+
+ while( true )
+ {
+ va_list args;
+ va_start( args, format );
+ int z = vsnprintf( buf.data() + offset, buf.size() - offset, format, args );
+ va_end( args );
+ if( z < 0 )
+ return;
+ bool done = static_cast< size_t >( z ) + static_cast< size_t >( offset ) < buf.size();
+ buf.resize( static_cast< size_t >( z ) + static_cast< size_t >( offset ) );
+ if( done )
+ break;
+ }
+ debugPrintFunc( buf.data(), buf.size() );
+}
+
+DBusWrapper::ConnectionPtr DBus::getDBusConnectionByName( const std::string& name )
+{
+ return DBUS_W->eldbus_address_connection_get_impl( name );
+}
+
+DBusWrapper::ConnectionPtr DBus::getDBusConnectionByType( ConnectionType connectionType )
+{
+ return DBUS_W->eldbus_connection_get_impl(connectionType);
+}
+
+DBus::DBusClient::DBusClient( std::string busName, std::string pathName, std::string interfaceName, ConnectionType tp ) : DBusClient( std::move( busName ), std::move( pathName ), std::move( interfaceName ), getDBusConnectionByType( tp ) )
+{
+}
+
+DBus::DBusClient::DBusClient( std::string busName, std::string pathName, std::string interfaceName, const DBusWrapper::ConnectionPtr &conn )
+{
+ if( !conn )
+ connectionState->connection = getDBusConnectionByType( ConnectionType::SESSION );
+ else
+ connectionState->connection = conn;
+
+ std::ostringstream o;
+ o << "bus = " << busName << " path = " << pathName << " connection = " << DBUS_W->eldbus_connection_unique_name_get_impl( connectionState->connection );
+ info = o.str();
+
+ connectionState->object = DBUS_W->eldbus_object_get_impl( connectionState->connection, busName.c_str(), pathName.c_str() );
+ if( connectionState->object )
+ {
+ connectionState->proxy = DBUS_W->eldbus_proxy_get_impl( connectionState->object, interfaceName );
+ if( interfaceName != DBUS_INTERFACE_PROPERTIES )
+ {
+ connectionState->propertiesProxy = DBUS_W->eldbus_proxy_get_impl( connectionState->object, DBUS_INTERFACE_PROPERTIES );
+ }
+ else
+ {
+ connectionState->propertiesProxy = DBUS_W->eldbus_proxy_copy_impl( connectionState->proxy );
+ }
+ }
+ connectionInfo = std::make_shared< ConnectionInfo >();
+ connectionInfo->busName = std::move( busName );
+ connectionInfo->pathName = std::move( pathName );
+ connectionInfo->interfaceName = std::move( interfaceName );
+}
+
+DBus::DBusServer::DBusServer( ConnectionType tp ) : DBus::DBusServer( DBus::getDBusConnectionByType( tp ) )
+{
+}
+
+DBus::DBusServer::DBusServer( const DBusWrapper::ConnectionPtr &conn )
+{
+ if( !conn )
+ connection = getDBusConnectionByType( ConnectionType::SESSION );
+ else
+ connection = conn;
+}
+
+DBus::DBusInterfaceDescription::DBusInterfaceDescription( std::string interfaceName ) : interfaceName( std::move( interfaceName ) )
+{
+}
+
+void DBus::DBusServer::addInterface( const std::string& pathName, DBusInterfaceDescription& dscr, bool fallback )
+{
+ DBUS_W->add_interface_impl( fallback, pathName, connection, destructorObject->destructors, dscr.interfaceName, dscr.methods, dscr.properties, dscr.signals );
+}
+
+std::string DBus::DBusServer::getBusName() const
+{
+ return getConnectionName( connection );
+}
+
+std::string DBus::getConnectionName( const DBusWrapper::ConnectionPtr &c )
+{
+ return DBUS_W->eldbus_connection_unique_name_get_impl( c );
+}
+
+bool DBus::DBusClient::getFromEinaValue(const _Eina_Value *v, void *dst)
+{
+ return eina_value_get(const_cast<Eina_Value*>(v), dst);
+}
+
+/// \cond
+static std::unique_ptr<DBusWrapper> InstalledWrapper;
+
+struct DefaultDBusWrapper : public DBusWrapper {
+ constexpr static int ELDBUS_CALL_TIMEOUT = 1000;
+
+ DefaultDBusWrapper() {
+ }
+ ~DefaultDBusWrapper() {
+ }
+ #define DEFINE_GS(name, eldbus_name, unref_call) \
+ static eldbus_name *get(const std::shared_ptr<name> &a) { \
+ return static_cast<name ## Impl*>(a.get())->Value; \
+ } \
+ static eldbus_name *release(const std::shared_ptr<name> &a) { \
+ auto z = static_cast<name ## Impl*>(a.get())->Value; \
+ static_cast<name ## Impl*>(a.get())->Value = nullptr; \
+ return z; \
+ } \
+ template <typename ... ARGS> static std::shared_ptr<name> create(const eldbus_name *v, ARGS && ... args) { \
+ return std::make_shared<name ## Impl>(const_cast<eldbus_name*>(v), std::forward<ARGS>(args)...); \
+ }
+
+ #define DEFINE_TYPE(name, eldbus_name, unref_call) \
+ struct name ## Impl : public name { \
+ eldbus_name *Value = nullptr; \
+ bool EraseOnExit = false; \
+ name ## Impl(eldbus_name *Value, bool EraseOnExit = false) : Value(Value), EraseOnExit(EraseOnExit) { } \
+ ~name ## Impl() { \
+ if (EraseOnExit && Value) { unref_call; } \
+ } \
+ }; \
+ DEFINE_GS(name, eldbus_name, unref_call)
+
+ struct ConnectionImpl : public Connection {
+ Eldbus_Connection *Value = nullptr;
+ bool EraseOnExit = false;
+ ConnectionImpl(Eldbus_Connection *Value, bool EraseOnExit = false) : Value(Value), EraseOnExit(EraseOnExit) {
+ ecore_event_init();
+ eldbus_init();
+ }
+ ~ConnectionImpl() {
+ if (EraseOnExit && Value) {
+ eldbus_connection_unref( Value );
+ }
+ eldbus_shutdown();
+ ecore_event_shutdown();
+ }
+ };
+ struct MessageIterImpl : public MessageIter {
+ Eldbus_Message_Iter *Value = nullptr, *Parent = nullptr;
+ bool EraseOnExit = false;
+ MessageIterImpl(Eldbus_Message_Iter *Value, Eldbus_Message_Iter *Parent, bool EraseOnExit = false) : Value(Value), Parent(Parent), EraseOnExit(EraseOnExit) { }
+ ~MessageIterImpl() {
+ if (EraseOnExit && Value && Parent)
+ eldbus_message_iter_container_close(Parent, Value);
+ }
+ };
+
+ DEFINE_GS(Connection, Eldbus_Connection, )
+ DEFINE_GS(MessageIter, Eldbus_Message_Iter, )
+ DEFINE_TYPE(Message, Eldbus_Message, eldbus_message_unref( Value ))
+ DEFINE_TYPE(Proxy, Eldbus_Proxy, )
+ DEFINE_TYPE(Object, Eldbus_Object, eldbus_object_unref( Value ))
+ DEFINE_TYPE(Pending, Eldbus_Pending, )
+ DEFINE_TYPE(EventPropertyChanged, Eldbus_Proxy_Event_Property_Changed, )
+ #undef DEFINE_TYPE
+
+ std::shared_ptr<Connection> eldbus_address_connection_get_impl(const std::string &addr) override {
+ eldbus_init();
+ auto p = eldbus_address_connection_get(addr.c_str());
+ auto w = create(p, true);
+ eldbus_shutdown();
+ return w;
+ }
+
+#define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
+ void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type src) override { \
+ eldbus_message_iter_arguments_append( get(it), #sig, src ); \
+ } \
+ bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type &dst) override { \
+ return eldbus_message_iter_get_and_next( get(it), (#sig)[0], &dst ); \
+ }
+
+ eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
+ eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
+ eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
+ eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
+ eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
+ eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
+ eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
+ eldbus_message_iter_arguments_append_impl_basic(double, d)
+
+#undef eldbus_message_iter_arguments_append_impl_basic
+
+ void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, bool src) override {
+ eldbus_message_iter_arguments_append( get(it), "b", src ? 1 : 0 );
+ }
+ bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, bool &dst) override {
+ unsigned char q;
+ auto z = eldbus_message_iter_get_and_next( get(it), 'b', &q );
+ dst = q != 0;
+ return z;
+ }
+ void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, const std::string &src) override {
+ eldbus_message_iter_arguments_append( get(it), "s", src.c_str() );
+ }
+ bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, std::string &dst) override {
+ auto iter = get(it);
+ const char* q;
+ if( !eldbus_message_iter_get_and_next( iter, 's', &q ) )
+ {
+ if( !eldbus_message_iter_get_and_next( iter, 'o', &q ) )
+ return false;
+ }
+ dst = q;
+ return true;
+ }
+ void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, const ObjectPath &src) override {
+ eldbus_message_iter_arguments_append( get(it), "o", src.value.c_str() );
+ }
+ bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, ObjectPath &dst) override {
+ const char* q;
+ if( !eldbus_message_iter_get_and_next( get(it), 'o', &q ) )
+ return false;
+ dst.value = q;
+ return true;
+ }
+
+ MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr &it, int type, const std::string &sig) override {
+ auto z = eldbus_message_iter_container_new( get(it), type, !sig.empty() ? sig.c_str() : NULL );
+ return create(z, get(it), true);
+ }
+ MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) override {
+ Eldbus_Message_Iter* entry;
+ if (!eldbus_message_iter_get_and_next( get(it), type, &entry ) ) return {};
+ return create(entry, get(it), false);
+ }
+ MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &msg, bool) override {
+ return create(eldbus_message_iter_get(get(msg)), nullptr, false);
+ }
+ MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) {
+ return create(eldbus_proxy_method_call_new( get(proxy), funcName.c_str() ) );
+ }
+ MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) override {
+ return create(eldbus_proxy_send_and_block(get(proxy), release(msg), ELDBUS_CALL_TIMEOUT) );
+ }
+ bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) override {
+ const char *errname, *errmsg;
+ if( eldbus_message_error_get( get(msg), &errname, &errmsg ) ) {
+ name = errname;
+ text = errmsg;
+ return true;
+ }
+ return false;
+ }
+ std::string eldbus_message_signature_get_impl(const MessagePtr &msg) override {
+ return eldbus_message_signature_get(get(msg));
+ }
+
+ static void callAsyncCb( void* data, const Eldbus_Message *msg, Eldbus_Pending *pending )
+ {
+ auto d = static_cast< SendCallback* >( data );
+ (*d)( create(msg, false) );
+ }
+ static void pendingFreeCb( void* data, const void* )
+ {
+ auto d = static_cast< SendCallback* >( data );
+ delete d;
+ }
+ static void listenerCallbackFree( void* data, const void* )
+ {
+ auto d = static_cast< std::function< void( const Eldbus_Message* msg ) >* >( data );
+ delete d;
+ }
+
+ PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) override {
+ auto cb = new SendCallback{ callback };
+ auto pending = eldbus_proxy_send( get(proxy), release(msg), callAsyncCb, cb, ELDBUS_CALL_TIMEOUT );
+ if( pending )
+ {
+ eldbus_pending_free_cb_add( pending, pendingFreeCb, cb );
+ }
+ else
+ {
+ delete cb;
+ }
+ return create(pending, false);
+ }
+ std::string eldbus_proxy_interface_get_impl(const ProxyPtr &proxy) override {
+ return eldbus_proxy_interface_get( get(proxy) );
+ }
+ static void listenerCallback( void* data, const Eldbus_Message* msg )
+ {
+ auto p = static_cast< std::function< void( const Eldbus_Message* msg ) >* >( data );
+ ( *p )( msg );
+ }
+ void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) override {
+ auto tmp = new std::function< void( const Eldbus_Message* msg ) >{
+ [cb](const Eldbus_Message* msg) {
+ cb(create(msg, false));
+ }
+ };
+ auto handler = eldbus_proxy_signal_handler_add( get(proxy), member.c_str(), listenerCallback, tmp );
+ if( handler )
+ eldbus_proxy_free_cb_add( get(proxy), listenerCallbackFree, tmp );
+ else
+ delete tmp;
+ }
+ std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) override {
+ return eldbus_message_iter_signature_get( get(iter) );
+ }
+ MessagePtr eldbus_message_method_return_new_impl( const MessagePtr &msg) override {
+ return create(eldbus_message_method_return_new( get(msg) ) );
+ }
+ MessagePtr eldbus_message_error_new_impl( const MessagePtr &msg, const std::string &err, const std::string &txt ) override {
+ return create(eldbus_message_error_new( get(msg), err.c_str(), txt.c_str() ) );
+ }
+ PendingPtr eldbus_connection_send_impl(const ConnectionPtr &conn, const MessagePtr &msg) override {
+ return create(eldbus_connection_send( get(conn), get(msg), NULL, NULL, -1 ) );
+ }
+ MessagePtr eldbus_message_signal_new_impl(const std::string &path, const std::string &iface, const std::string &name) override {
+ return create(eldbus_message_signal_new( path.c_str(), iface.c_str(), name.c_str() ) );
+ }
+ MessagePtr eldbus_message_ref_impl(const MessagePtr &msg) override {
+ return create(eldbus_message_ref( get(msg) ), true );
+ }
+ ConnectionPtr eldbus_connection_get_impl(ConnectionType type) override {
+ Eldbus_Connection_Type eldbusType = ELDBUS_CONNECTION_TYPE_SYSTEM;
+
+ switch( type )
+ {
+ case ConnectionType::SYSTEM:
+ {
+ eldbusType = ELDBUS_CONNECTION_TYPE_SYSTEM;
+ break;
+ }
+ case ConnectionType::SESSION:
+ {
+ eldbusType = ELDBUS_CONNECTION_TYPE_SESSION;
+ break;
+ }
+ }
+
+ eldbus_init();
+ auto p = eldbus_connection_get( eldbusType );
+ auto w = create(p, true);
+ eldbus_shutdown();
+ return w;
+ }
+ std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr &conn) override {
+ return eldbus_connection_unique_name_get( get(conn) );
+ }
+ ObjectPtr eldbus_object_get_impl( const ConnectionPtr &conn, const std::string &bus, const std::string &path ) override {
+ return create(eldbus_object_get(get(conn), bus.c_str(), path.c_str() ), true );
+ }
+ ProxyPtr eldbus_proxy_get_impl( const ObjectPtr &obj, const std::string &interface ) override {
+ return create(eldbus_proxy_get(get(obj), interface.c_str() ), false );
+ }
+ ProxyPtr eldbus_proxy_copy_impl( const ProxyPtr &ptr) override {
+ return create(get(ptr), false );
+ }
+
+
+
+
+
+
+ struct Implementation
+ {
+ Eldbus_Service_Interface_Desc dsc;
+ std::vector< std::vector< Eldbus_Arg_Info > > argsInfos;
+ std::vector< Eldbus_Method > methods;
+ std::vector< Eldbus_Signal > signals;
+ std::vector< Eldbus_Property > properties;
+
+ std::unordered_map< std::string, DBusWrapper::MethodInfo > methodsMap;
+ std::unordered_map< std::string, DBusWrapper::PropertyInfo > propertiesMap;
+ std::unordered_map< unsigned int, DBusWrapper::SignalInfo > signalsMap;
+
+ DBusWrapper::ConnectionWeakPtr connection;
+ };
+
+ static std::unordered_map< const Eldbus_Service_Interface*, std::unique_ptr< Implementation > > globalEntries;
+ static std::mutex globalEntriesMutex;
+
+#undef EINA_FALSE
+#undef EINA_TRUE
+#define EINA_FALSE static_cast<Eina_Bool>(0)
+#define EINA_TRUE static_cast<Eina_Bool>(1)
+
+ static Eina_Bool property_get_callback( const Eldbus_Service_Interface* iface, const char* propertyName, Eldbus_Message_Iter* iter,
+ const Eldbus_Message* message, Eldbus_Message** error )
+ {
+ Implementation* impl = nullptr;
+ {
+ std::lock_guard< std::mutex > lock( globalEntriesMutex );
+ auto it = globalEntries.find( iface );
+ if( it != globalEntries.end() )
+ impl = it->second.get();
+ }
+ if( !impl )
+ return EINA_FALSE;
+
+ auto it = impl->propertiesMap.find( propertyName );
+ if( it == impl->propertiesMap.end() || !it->second.getCallback )
+ return EINA_FALSE;
+
+ auto connection = impl->connection.lock();
+ if( !connection )
+ return EINA_FALSE;
+
+ DBus::DBusServer::CurrentObjectSetter currentObjectSetter( connection, eldbus_message_path_get( message ) );
+ auto reply = it->second.getCallback( create(message, false), create(iter, nullptr, false) );
+ if( !reply.empty() )
+ {
+ if( error )
+ *error = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", reply.c_str() );
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+ }
+
+ static Eldbus_Message* property_set_callback( const Eldbus_Service_Interface* iface, const char* propertyName, Eldbus_Message_Iter* iter,
+ const Eldbus_Message* message )
+ {
+ Implementation* impl = nullptr;
+ {
+ std::lock_guard< std::mutex > lock( globalEntriesMutex );
+ auto it = globalEntries.find( iface );
+ if( it != globalEntries.end() )
+ impl = it->second.get();
+ }
+ if( !impl )
+ {
+ auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Unknown interface" );
+ return ret;
+ }
+ auto it = impl->propertiesMap.find( propertyName );
+ if( it == impl->propertiesMap.end() || !it->second.setCallback )
+ {
+ auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Unknown setter" );
+ return ret;
+ }
+ auto connection = impl->connection.lock();
+ if( !connection )
+ {
+ auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Connection lost" );
+ return ret;
+ }
+
+ DBus::DBusServer::CurrentObjectSetter currentObjectSetter( connection, eldbus_message_path_get( message ) );
+ auto reply = it->second.setCallback( create(message, false), create(iter, nullptr, false) );
+
+ Eldbus_Message* ret = nullptr;
+ if( !reply.empty() )
+ {
+ ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", reply.c_str() );
+ }
+ else
+ {
+ ret = eldbus_message_method_return_new( message );
+ }
+ return ret;
+ }
+
+ static Eldbus_Message* method_callback( const Eldbus_Service_Interface* iface, const Eldbus_Message* message )
+ {
+ Implementation* impl = nullptr;
+ {
+ std::lock_guard< std::mutex > lock( globalEntriesMutex );
+ auto it = globalEntries.find( iface );
+ if( it != globalEntries.end() )
+ impl = it->second.get();
+ }
+ if( !impl )
+ {
+ auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Unknown interface" );
+ return ret;
+ }
+ std::string memberName = eldbus_message_member_get( message );
+ auto it = impl->methodsMap.find( memberName );
+ if( it == impl->methodsMap.end() )
+ {
+ auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Unknown method" );
+ return ret;
+ }
+ auto connection = impl->connection.lock();
+ if( !connection )
+ {
+ auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Connection lost" );
+ return ret;
+ }
+ DBus::DBusServer::CurrentObjectSetter currentObjectSetter( connection, eldbus_message_path_get( message ) );
+ auto reply = it->second.callback( create(message) );
+ return release(reply);
+ }
+
+ void add_interface_impl( bool fallback, const std::string& pathName,
+ const ConnectionPtr &connection,
+ std::vector<std::function<void()>> &destructors,
+ const std::string& interfaceName,
+ std::vector< MethodInfo >& dscrMethods,
+ std::vector< PropertyInfo >& dscrProperties,
+ std::vector< SignalInfo >& dscrSignals ) override
+ {
+ std::vector< Eldbus_Method > methods;
+ std::vector< Eldbus_Signal > signals;
+ std::vector< Eldbus_Property > properties;
+ std::vector< std::vector< Eldbus_Arg_Info > > argsInfos;
+ std::unordered_map< std::string, DBus::DBusInterfaceDescription::MethodInfo > methodsMap;
+ std::unordered_map< std::string, DBus::DBusInterfaceDescription::PropertyInfo > propertiesMap;
+ std::unordered_map< unsigned int, DBus::DBusInterfaceDescription::SignalInfo > signalsMap;
+
+ DBUS_DEBUG( "interface %s path %s on bus %s", interfaceName.c_str(), pathName.c_str(), DBus::getConnectionName( connection ).c_str() );
+ auto makeArgInfo = [&](const std::vector<std::pair<std::string, std::string>> &input) {
+ argsInfos.push_back({});
+ auto &dst = argsInfos.back();
+ for(auto &s : input) {
+ auto a = Strings.add(s.first);
+ auto b = Strings.add(s.second);
+ dst.push_back({ a, b });
+ }
+ dst.push_back({ nullptr, nullptr });
+ return dst.data();
+ };
+ for( auto& ee : dscrMethods )
+ {
+ auto key = ee.memberName;
+ DBUS_DEBUG( "adding method %s", ee.memberName.c_str() );
+ for( auto& r : ee.in )
+ {
+ DBUS_DEBUG( "in %s '%s'", r.first.c_str(), r.second.c_str() );
+ }
+ for( auto& r : ee.out )
+ {
+ DBUS_DEBUG( "out %s '%s'", r.first.c_str(), r.second.c_str() );
+ }
+ auto& e = ( methodsMap[key] = std::move( ee ) );
+ methods.push_back( {} );
+ auto& m = methods.back();
+ m.member = e.memberName.c_str();
+ m.in = makeArgInfo(e.in);
+ m.out = makeArgInfo(e.out);
+ m.cb = method_callback;
+ m.flags = 0;
+ }
+ for( auto& ee : dscrProperties )
+ {
+ auto key = ee.memberName;
+ DBUS_DEBUG( "adding property %s", ee.memberName.c_str() );
+ auto& e = ( propertiesMap[key] = std::move( ee ) );
+ properties.push_back( {} );
+ auto& m = properties.back();
+ m.name = e.memberName.c_str();
+ m.type = e.typeSignature.c_str();
+ m.get_func = e.getCallback ? property_get_callback : nullptr;
+ m.set_func = e.setCallback ? property_set_callback : nullptr;
+ m.flags = 0;
+ }
+ dscrMethods.clear();
+ dscrProperties.clear();
+ dscrSignals.clear();
+
+ methods.push_back( {nullptr, nullptr, nullptr, nullptr, 0} );
+ signals.push_back( {nullptr, nullptr, 0} );
+ properties.push_back( {nullptr, nullptr, nullptr, nullptr, 0} );
+
+ auto impl = std::unique_ptr< Implementation >( new Implementation{
+ {interfaceName.c_str(),
+ methods.data(),
+ signals.data(),
+ properties.data(),
+ nullptr,
+ nullptr},
+ std::move( argsInfos ),
+ std::move( methods ),
+ std::move( signals ),
+ std::move( properties ),
+ std::move( methodsMap ),
+ std::move( propertiesMap ),
+ std::move( signalsMap ),
+ connection} );
+
+ {
+ std::lock_guard< std::mutex > lock( globalEntriesMutex );
+ auto v = fallback ? eldbus_service_interface_fallback_register( get(connection), pathName.c_str(), &impl->dsc ) : eldbus_service_interface_register( get(connection), pathName.c_str(), &impl->dsc );
+ assert( v );
+ globalEntries[v] = std::move( impl );
+ DBUS_DEBUG( "registering interface %p (%d)", v, fallback ? 1 : 0 );
+ destructors.push_back([=]() {
+ DBUS_DEBUG( "unregistering interface %p", v );
+ eldbus_service_interface_unregister( v );
+ std::lock_guard< std::mutex > lock( globalEntriesMutex );
+ globalEntries.erase( v );
+ });
+ }
+ }
+ static void listenerEventChangedCallback( void* data, Eldbus_Proxy* proxy EINA_UNUSED, void* event )
+ {
+ auto p = static_cast< std::function< void( Eldbus_Proxy_Event_Property_Changed* ) >* >( data );
+ ( *p )( static_cast< Eldbus_Proxy_Event_Property_Changed* >( event ) );
+ }
+ static void ProxyEventCallbackDelCb( void* data, const void *obj )
+ {
+ auto d = static_cast< std::function< void( Eldbus_Proxy_Event_Property_Changed* ) >* >( data );
+ delete d;
+ }
+ void add_property_changed_event_listener_impl( const ProxyPtr &proxy, const std::string &interface, const std::string &name, std::function< void( const Eina_Value * ) > cb) override {
+ auto callbackLambdaPtr = new std::function< void( Eldbus_Proxy_Event_Property_Changed *epc ) >{
+ [cb, name, interface]( Eldbus_Proxy_Event_Property_Changed *ev ) {
+ const char* ifc = eldbus_proxy_interface_get( ev->proxy );
+ if( ev->name && ev->name == name && ifc && interface == ifc )
+ {
+ cb(ev->value);
+ }
+ } };
+ auto p = get(proxy);
+ eldbus_proxy_event_callback_add( p, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
+ listenerEventChangedCallback, callbackLambdaPtr );
+ eldbus_proxy_free_cb_add( p, ProxyEventCallbackDelCb, callbackLambdaPtr );
+ }
+};
+
+std::unordered_map< const Eldbus_Service_Interface*, std::unique_ptr< DefaultDBusWrapper::Implementation > > DefaultDBusWrapper::globalEntries;
+std::mutex DefaultDBusWrapper::globalEntriesMutex;
+
+DBusWrapper *DBusWrapper::Installed()
+{
+ if (!InstalledWrapper)
+ InstalledWrapper.reset(new DefaultDBusWrapper);
+ return InstalledWrapper.get();
+}
+
+void DBusWrapper::Install(std::unique_ptr<DBusWrapper> w)
+{
+ InstalledWrapper = std::move(w);
+}
+
+
+struct TestDBusWrapper::ConnectionImpl : public TestDBusWrapper::Connection {
+};
+
+TestDBusWrapper::TestDBusWrapper()
+{
+ eina_init();
+ connection = std::make_shared<ConnectionImpl>();
+ testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/bus", "org.a11y.Status", "ScreenReaderEnabled", MethodType::Getter}] =
+ testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/bus", "org.a11y.Status", "IsEnabled", MethodType::Getter}] =
+ [this](const DBusWrapper::MessagePtr &m) -> MessagePtr {
+ auto reply = newReplyMessage(m);
+ Encode(reply, std::tuple<TestDBusWrapper::Variant<bool>>{ TestDBusWrapper::Variant<bool>{ false} });
+ return reply;
+ };
+}
+TestDBusWrapper::~TestDBusWrapper()
+{
+ eina_shutdown();
+}
+
+TestDBusWrapper::ConnectionPtr TestDBusWrapper::eldbus_address_connection_get_impl(const std::string &addr)
+{
+ return connection;
+}
+
+struct TestDBusWrapper::MessageIterImpl : public TestDBusWrapper::MessageIter {
+ MessagePtr msg;
+ Element *elem;
+ bool write;
+ std::list<Element>::iterator it;
+ MessageIterImpl(MessagePtr msg, Element *elem, bool write) : msg(std::move(msg)), elem(elem), write(write) {
+ if (!write) it = elem->get<ElementList>().begin();
+ }
+ MessageIterImpl(MessagePtr msg, Element *elem, bool write, std::list<Element>::iterator it) : msg(std::move(msg)), elem(elem), write(write), it(it) { }
+};
+
+struct TestDBusWrapper::MessageImpl : public TestDBusWrapper::Message {
+ std::string bus, path, interface, name;
+ Element data;
+ bool reply, error = false;
+ std::string error_a, error_b;
+
+ MessageImpl(std::string bus, std::string path, std::string interface, std::string name, bool reply) :
+ bus(std::move(bus)), path(std::move(path)), interface(std::move(interface)), name(std::move(name)), data{ ElementList{} }, reply(reply) { }
+ MessageImpl(std::string bus, std::string path, std::string interface, std::string name, std::string error_a, std::string error_b) :
+ bus(std::move(bus)), path(std::move(path)), interface(std::move(interface)), name(std::move(name)), data{ ElementList{} },
+ reply(true), error(true), error_a(std::move(error_a)), error_b(std::move(error_b)) { }
+};
+
+struct TestDBusWrapper::ProxyImpl : public TestDBusWrapper::Proxy {
+ std::string bus, path, interface;
+ ProxyImpl(std::string bus, std::string path, std::string interface) : bus(std::move(bus)), path(std::move(path)), interface(std::move(interface)) { }
+};
+struct TestDBusWrapper::ObjectImpl : public TestDBusWrapper::Object {
+ std::string bus, path;
+ ObjectImpl(std::string bus, std::string path) : bus(std::move(bus)), path(std::move(path)) { }
+};
+#define DEFINE_TYPE(name) TestDBusWrapper::name ## Impl *TestDBusWrapper::get(const name ## Ptr &v) { return static_cast<name ## Impl*>(v.get()); }
+ DEFINE_TYPE(Connection)
+ DEFINE_TYPE(Proxy)
+ DEFINE_TYPE(Object)
+ DEFINE_TYPE(Message)
+ DEFINE_TYPE(MessageIter)
+#undef DEFINE_TYPE
+
+template <typename T> void TestDBusWrapperAppendBasic(const TestDBusWrapper::MessageIterPtr &it, T src) {
+ auto m = TestDBusWrapper::get(it);
+ if (!m->write) throw TestDBusWrapper::error{};
+ if (!m->elem->isContainer()) throw TestDBusWrapper::error{};
+ m->elem->get<TestDBusWrapper::ElementList>().push_back(TestDBusWrapper::Element{ src });
+}
+template <typename T> bool TestDBusWrapperGetBasicAndNext(const TestDBusWrapper::MessageIterPtr &it, T &src) {
+ auto m = TestDBusWrapper::get(it);
+ if (m->write) throw TestDBusWrapper::error{};
+ if (!m->elem->isContainer()) return false;
+ auto &lst = m->elem->get<TestDBusWrapper::ElementList>();
+ if (m->it == lst.end()) return false;
+ if (!m->it->is<T>()) return false;
+ src = m->it->get<T>();
+ ++m->it;
+ return true;
+}
+
+#define eldbus_message_iter_arguments_append_impl_basic_impl(type_set, type_get, sig) \
+void TestDBusWrapper::eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type_set src) { \
+ TestDBusWrapperAppendBasic(it, src); \
+} \
+bool TestDBusWrapper::eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type_get &dst) { \
+ return TestDBusWrapperGetBasicAndNext(it, dst); \
+}
+#define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
+eldbus_message_iter_arguments_append_impl_basic_impl(type, type, sig)
+
+eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
+eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
+eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
+eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
+eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
+eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
+eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
+eldbus_message_iter_arguments_append_impl_basic(double, d)
+eldbus_message_iter_arguments_append_impl_basic(bool, b)
+eldbus_message_iter_arguments_append_impl_basic_impl(const std::string &, std::string, s)
+eldbus_message_iter_arguments_append_impl_basic_impl(const ObjectPath &, ObjectPath, o)
+
+#undef eldbus_message_iter_arguments_append_impl_basic
+#undef eldbus_message_iter_arguments_append_impl_basic_impl
+
+TestDBusWrapper::MessageIterPtr TestDBusWrapper::eldbus_message_iter_container_new_impl(const MessageIterPtr &it, int type, const std::string &sig) {
+ auto m = get(it);
+ if (!m->write) throw error{};
+ if (!m->elem->isContainer()) throw error{};
+ auto &lst = m->elem->get<ElementList>();
+ if (type == 'r' || type == 'e' || type == 'a' || type == 'v') {
+ lst.push_back({ ElementList{}, type });
+ return std::make_shared<MessageIterImpl>(MessageIterImpl{ m->msg, &lst.back(), true });
+ }
+ throw error{};
+}
+
+TestDBusWrapper::MessageIterPtr TestDBusWrapper::eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) {
+ auto m = get(it);
+ if (m->write) throw error{};
+ if (!m->elem->isContainer()) throw error{} << "not a container";
+ auto &lst = m->elem->get<ElementList>();
+ if (m->it == lst.end()) return {};
+ if (m->it->signature() != type) return {};
+ auto v = std::make_shared<MessageIterImpl>(MessageIterImpl{ m->msg, &*m->it, false });
+ ++m->it;
+ return v;
+}
+
+TestDBusWrapper::MessageIterPtr TestDBusWrapper::eldbus_message_iter_get_impl(const MessagePtr &it, bool write) {
+ auto m = get(it);
+ return std::make_shared<MessageIterImpl>(MessageIterImpl{ it, &m->data, write, m->data.get<ElementList>().begin() });
+}
+
+bool TestDBusWrapper::completed(const MessageIterPtr &iter)
+{
+ auto m = get(iter);
+ assert(!m->write);
+ return m->it == m->elem->get<ElementList>().end();
+}
+
+TestDBusWrapper::MessagePtr TestDBusWrapper::eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) {
+ auto p = get(proxy);
+ return std::make_shared<MessageImpl>(MessageImpl{
+ p->bus, p->path, p->interface, funcName, false
+ });
+}
+TestDBusWrapper::MessagePtr TestDBusWrapper::call(
+ std::unordered_map<std::tuple<std::string, std::string, std::string, MethodType>, std::function<MessagePtr(const MessagePtr&)>> &mp,
+ const std::string &mpName, const MessagePtr &msg, MethodType type) {
+ auto m = get(msg);
+ auto findMethod = [&](std::string path, const std::string &iname, const std::string &name, MethodType type) {
+ if (path.empty()) throw error{};
+ if (path[0] != '/') {
+ path = "/org/a11y/atspi/accessible/" + path;
+ m->path = path;
+ }
+ while(!path.empty()) {
+ auto it = mp.find(std::tuple<std::string, std::string, std::string, MethodType> { path, iname, name, type });
+ if (it != mp.end()) return it;
+ auto index = path.rfind('/');
+ if (index == std::string::npos) break;
+ path.resize(index);
+ }
+ return mp.end();
+ };
+ std::string iname, name;
+ if (type == MethodType::Method && m->interface == "org.freedesktop.DBus.Properties") {
+ type = m->name == "Get" ? MethodType::Getter : MethodType::Setter;
+ auto &lst = m->data.get<ElementList>();
+ assert(lst.size() >= 2);
+ iname = lst.front().get<std::string>();
+ lst.pop_front();
+ name = lst.front().get<std::string>();
+ lst.pop_front();
+ }
+ else {
+ iname = m->interface;
+ name = m->name;
+ }
+ auto it = findMethod(m->path, iname, name, type);
+ if (it == mp.end()) {
+ const char *mt;
+ if (type == MethodType::Method) mt = "MethodType::Method";
+ else if (type == MethodType::Getter) mt = "MethodType::Getter";
+ else if (type == MethodType::Setter) mt = "MethodType::Setter";
+ else assert(0);
+ throw error{} << "missing {\"" << m->path << "\", \"" << iname << "\", \"" << name << "\", " << mt << "} in " << mpName;
+ }
+ DBus::DBusServer::CurrentObjectSetter setter{ connection, m->path };
+ return it->second(msg);
+}
+TestDBusWrapper::MessagePtr TestDBusWrapper::eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) {
+// BART
+// auto p = get(proxy);
+// auto m = get(msg);
+// assert(p->bus == m->bus);
+// assert(p->path == m->path);
+// assert(p->interface == m->interface);
+ return call(testMethods, "testMethods", msg, MethodType::Method);
+}
+
+bool TestDBusWrapper::eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) {
+ auto m = get(msg);
+ name = m->error_a;
+ text = m->error_b;
+ return m->error;
+}
+static void calculate_signature(std::ostringstream &ostr, TestDBusWrapper::Element &e)
+{
+ ostr << static_cast<char>(e.signature());
+ if (e.isContainer()) {
+ ostr << "(";
+ auto &lst = e.get<TestDBusWrapper::ElementList>();
+ for(auto &q : lst) calculate_signature(ostr, q);
+ ostr << ")";
+ }
+}
+std::string TestDBusWrapper::eldbus_message_signature_get_impl(const MessagePtr &msg) {
+ auto m = get(msg);
+ std::ostringstream ostr;
+ for(auto &q : m->data.get<ElementList>())
+ calculate_signature(ostr, q);
+ return ostr.str();
+}
+TestDBusWrapper::PendingPtr TestDBusWrapper::eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) {
+// BART
+// auto p = get(proxy);
+// auto m = get(msg);
+// assert(p->bus == m->bus);
+// assert(p->path == m->path);
+// assert(p->interface == m->interface);
+ asyncCalls.push_back([this, msg, callback]() {
+ auto r = call(testMethods, "testMethods", msg, MethodType::Method);
+ callback(r);
+ });
+ return {};
+}
+std::string TestDBusWrapper::eldbus_proxy_interface_get_impl(const ProxyPtr &proxy) {
+ auto p = get(proxy);
+ return p->interface;
+}
+void TestDBusWrapper::eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) {
+ auto p = get(proxy);
+ daliSignals[std::tuple<std::string, std::string, std::string> { p->path, p->interface, member }] = cb;
+}
+std::string TestDBusWrapper::eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) {
+ auto m = get(iter);
+ if (m->write) throw error{};
+ if (!m->elem->isContainer()) throw error{};
+ std::ostringstream ostr;
+ auto &lst = m->elem->get<ElementList>();
+ for(auto it = m->it; it != lst.end(); ++it)
+ calculate_signature(ostr, *it);
+ return ostr.str();
+}
+TestDBusWrapper::MessagePtr TestDBusWrapper::eldbus_message_method_return_new_impl( const MessagePtr &msg) {
+ auto m = get(msg);
+ return std::make_shared<MessageImpl>(MessageImpl{
+ m->bus, m->path, m->interface, m->name, true
+ });
+}
+TestDBusWrapper::MessagePtr TestDBusWrapper::eldbus_message_error_new_impl( const MessagePtr &msg, const std::string &err, const std::string &txt ) {
+ auto m = get(msg);
+ return std::make_shared<MessageImpl>(MessageImpl{
+ m->bus, m->path, m->interface, m->name, err, txt
+ });
+}
+TestDBusWrapper::PendingPtr TestDBusWrapper::eldbus_connection_send_impl(const ConnectionPtr &conn, const MessagePtr &msg) {
+ call(testMethods, "testMethods", msg, MethodType::Method);
+ return {};
+}
+std::shared_ptr<Eina_Value> TestDBusWrapper::createEinaValue(bool b) {
+ Eina_Value *value = eina_value_new(EINA_VALUE_TYPE_UCHAR);
+ eina_value_set(value, b);
+ return std::shared_ptr<Eina_Value>(value, [](Eina_Value *v) {
+ eina_value_free(v);
+ });
+}
+
+TestDBusWrapper::MessagePtr TestDBusWrapper::newMessage(const std::string &path, const std::string &interface, const std::string &name, bool reply) {
+ return std::make_shared<MessageImpl>(MessageImpl{
+ "bus", path, interface, name, reply
+ });
+}
+
+TestDBusWrapper::MessagePtr TestDBusWrapper::newReplyMessage(const MessagePtr &msg) {
+ auto m = get(msg);
+ return newMessage(m->path, m->interface, m->name, true);
+}
+
+TestDBusWrapper::MessagePtr TestDBusWrapper::eldbus_message_signal_new_impl(const std::string &path, const std::string &iface, const std::string &name) {
+ return std::make_shared<MessageImpl>(MessageImpl{
+ "bus", path, iface, name, true
+ });
+}
+TestDBusWrapper::MessagePtr TestDBusWrapper::eldbus_message_ref_impl(const MessagePtr &msg) {
+ return msg;
+}
+TestDBusWrapper::ConnectionPtr TestDBusWrapper::eldbus_connection_get_impl(ConnectionType type) {
+ return connection;
+}
+std::string TestDBusWrapper::eldbus_connection_unique_name_get_impl(const ConnectionPtr &conn) {
+ return "bus";
+}
+TestDBusWrapper::ObjectPtr TestDBusWrapper::eldbus_object_get_impl( const ConnectionPtr &conn, const std::string &bus, const std::string &path ) {
+ return std::make_shared<ObjectImpl>(ObjectImpl{
+ bus, path
+ });
+}
+TestDBusWrapper::ProxyPtr TestDBusWrapper::eldbus_proxy_get_impl( const ObjectPtr &obj, const std::string &interface ) {
+ auto o = get(obj);
+ return std::make_shared<ProxyImpl>(ProxyImpl{ o->bus, o->path, interface });
+}
+TestDBusWrapper::ProxyPtr TestDBusWrapper::eldbus_proxy_copy_impl( const ProxyPtr &ptr) {
+ return ptr;
+}
+void TestDBusWrapper::add_property_changed_event_listener_impl( const ProxyPtr &proxy, const std::string &interface, const std::string &name, std::function< void( const Eina_Value * ) > cb) {
+ auto p = get(proxy);
+ propertyChangeListeners[std::tuple<std::string, std::string, std::string>{ p->path, interface, name }] = cb;
+}
+void TestDBusWrapper::add_interface_impl( bool fallback, const std::string& path_,
+ const ConnectionPtr &connection,
+ std::vector<std::function<void()>> &destructors,
+ const std::string& interface,
+ std::vector< MethodInfo >& dscrMethods,
+ std::vector< PropertyInfo >& dscrProperties,
+ std::vector< SignalInfo >& dscrSignals ) {
+ std::string bus = "bus";
+ std::string path = path_;
+ while(!path.empty() && path.back() == '/') path.pop_back();
+ for(auto &m : dscrMethods) {
+ auto key = std::make_tuple( "/org/a11y/atspi/accessible" + path, interface, m.memberName, MethodType::Method );
+ daliMethods[key] = m.callback;
+ }
+ for(auto &m : dscrProperties) {
+ auto key = std::make_tuple( "/org/a11y/atspi/accessible" + path, interface, m.memberName, MethodType::Getter );
+ daliMethods[key] = [=](const MessagePtr &msg) -> MessagePtr {
+ auto ret = std::make_shared<MessageImpl>(MessageImpl{
+ "bus", path, interface, m.memberName, true
+ });
+ auto v = m.getCallback(msg, std::make_shared<MessageIterImpl>(MessageIterImpl{ ret, &ret->data, true }));
+ ret->error = !v.empty();
+ if (ret->error) {
+ ret->error_a = "call failed";
+ ret->error_b = std::move(v);
+ }
+ return ret;
+ };
+ std::get<3>(key) = MethodType::Setter;
+ daliMethods[key] = [=](const MessagePtr &msg) -> MessagePtr {
+ auto v = m.setCallback(msg, std::make_shared<MessageIterImpl>(MessageIterImpl{ msg, &get(msg)->data, false }));
+ return v.empty() ? std::make_shared<MessageImpl>(MessageImpl{
+ "bus", path, interface, m.memberName, true,
+ }) : std::make_shared<MessageImpl>(MessageImpl{
+ "bus", path, interface, m.memberName, "call failed", v
+ });
+ // interface is probably wrong, due to retarded way properties are handlded by dbus
+ };
+ }
+ for(auto &m : dscrSignals) {
+ daliSignalsMap[std::tuple<std::string, std::string, unsigned int>{ "/org/a11y/atspi/accessible" + path, interface, m.uniqueId }] = m.memberName;
+ }
+}
+
+/// \endcond
--- /dev/null
+#ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
+#define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
+
+/*
+ * Copyright 2019 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// EXTERNAL INCLUDES
+#include <memory>
+#include <array>
+#include <atomic>
+#include <cstdint>
+#include <cstring>
+#include <map>
+#include <list>
+#include <sstream>
+#include <string>
+#include <thread>
+#include <tuple>
+#include <type_traits>
+#include <unordered_map>
+#include <vector>
+#include <functional>
+
+// INTERNAL INCLUDES
+//#include <dali/public-api/adaptor-framework/accessibility.h>
+//#include <dali/internal/accessibility/bridge/optional.h>
+
+#include <dali/devel-api/adaptor-framework/accessibility.h>
+
+#define ATSPI_PREFIX_PATH "/org/a11y/atspi/accessible/"
+#define ATSPI_NULL_PATH "/org/a11y/atspi/null"
+
+
+//// BART QUICK HACK
+#define bart_assert(x) do{}while(0)
+
+struct _Eina_Value;
+
+/// \cond
+struct ObjectPath
+{
+ std::string value;
+};
+
+struct DBusWrapper
+{
+ virtual ~DBusWrapper() = default;
+
+ enum class ConnectionType
+ {
+ SYSTEM,
+ SESSION
+ };
+
+#define DEFINE_TYPE(name, eldbus_name, unref_call) \
+ struct name { virtual ~name() = default; }; \
+ using name ## Ptr = std::shared_ptr<name>; \
+ using name ## WeakPtr = std::weak_ptr<name>; \
+
+ DEFINE_TYPE(Connection, Eldbus_Connection, )
+ DEFINE_TYPE(MessageIter, Eldbus_Message_Iter, eldbus_message_iter_container_close( Value ))
+ DEFINE_TYPE(Message, Eldbus_Message, eldbus_message_unref( Value ))
+ DEFINE_TYPE(Proxy, Eldbus_Proxy, eldbus_proxy_unref( Value ))
+ DEFINE_TYPE(Object, Eldbus_Object, eldbus_object_unref( Value ))
+ DEFINE_TYPE(Pending, Eldbus_Pending, )
+ DEFINE_TYPE(EventPropertyChanged, Eldbus_Proxy_Event_Property_Changed, )
+
+#undef DEFINE_TYPE
+ virtual ConnectionPtr eldbus_address_connection_get_impl(const std::string &addr) = 0;
+
+#define eldbus_message_iter_arguments_append_impl_basic_impl(type_set, type_get, sig) \
+ virtual void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type_set src) = 0; \
+ virtual bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type_get &dst) = 0;
+#define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
+ eldbus_message_iter_arguments_append_impl_basic_impl(type, type, sig)
+
+ eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
+ eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
+ eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
+ eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
+ eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
+ eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
+ eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
+ eldbus_message_iter_arguments_append_impl_basic(double, d)
+ eldbus_message_iter_arguments_append_impl_basic(bool, b)
+ eldbus_message_iter_arguments_append_impl_basic_impl(const std::string &, std::string, s)
+ eldbus_message_iter_arguments_append_impl_basic_impl(const ObjectPath &, ObjectPath, o)
+
+#undef eldbus_message_iter_arguments_append_impl_basic
+#undef eldbus_message_iter_arguments_append_impl_basic_impl
+
+ virtual MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr &it, int type, const std::string &sig) = 0;
+ virtual MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) = 0;
+ virtual MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &it, bool write) = 0;
+ virtual MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) = 0;
+ virtual MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) = 0;
+ virtual bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) = 0;
+ virtual std::string eldbus_message_signature_get_impl(const MessagePtr &msg) = 0;
+
+ using SendCallback = std::function<void(const MessagePtr &msg)>;
+ virtual PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) = 0;
+ virtual std::string eldbus_proxy_interface_get_impl(const ProxyPtr &) = 0;
+ virtual void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) = 0;
+ virtual std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) = 0;
+ virtual MessagePtr eldbus_message_method_return_new_impl( const MessagePtr &msg) = 0;
+ virtual MessagePtr eldbus_message_error_new_impl( const MessagePtr &msg, const std::string &err, const std::string &txt ) = 0;
+ virtual PendingPtr eldbus_connection_send_impl(const ConnectionPtr &conn, const MessagePtr &msg) = 0;
+ virtual MessagePtr eldbus_message_signal_new_impl(const std::string &path, const std::string &iface, const std::string &name) = 0;
+ virtual MessagePtr eldbus_message_ref_impl(const MessagePtr &msg) = 0;
+ virtual ConnectionPtr eldbus_connection_get_impl(ConnectionType type) = 0;
+ virtual std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr &conn) = 0;
+ virtual ObjectPtr eldbus_object_get_impl( const ConnectionPtr &conn, const std::string &bus, const std::string &path ) = 0;
+ virtual ProxyPtr eldbus_proxy_get_impl( const ObjectPtr &obj, const std::string &interface ) = 0;
+ virtual ProxyPtr eldbus_proxy_copy_impl( const ProxyPtr &ptr) = 0;
+
+ class StringStorage
+ {
+ public:
+ struct char_ptr_deleter
+ {
+ void operator()( char* p )
+ {
+ free( p );
+ }
+ };
+ std::vector< std::unique_ptr< char, char_ptr_deleter > > storage;
+
+ const char* add( const char* txt )
+ {
+ auto ptr = strdup( txt );
+ storage.push_back( std::unique_ptr< char, char_ptr_deleter >( ptr ) );
+ return storage.back().get();
+ }
+ const char* add( const std::string& txt )
+ {
+ return add( txt.c_str() );
+ }
+ };
+
+ struct CallId
+ {
+ static std::atomic< unsigned int > LastId;
+ unsigned int id = ++LastId;
+ };
+ struct MethodInfo
+ {
+ CallId id;
+ std::string memberName;
+ std::vector< std::pair<std::string, std::string> > in, out; // _Eldbus_Arg_Info
+ std::function< DBusWrapper::MessagePtr( const DBusWrapper::MessagePtr &msg ) > callback;
+ };
+ struct SignalInfo
+ {
+ CallId id;
+ std::string memberName;
+ std::vector< std::pair<std::string, std::string> > args;
+ unsigned int uniqueId;
+ };
+ struct PropertyInfo
+ {
+ CallId setterId, getterId;
+ std::string memberName, typeSignature;
+ std::function< std::string( const DBusWrapper::MessagePtr &src, const DBusWrapper::MessageIterPtr &dst ) > getCallback, setCallback;
+ };
+ struct SignalId
+ {
+ CallId id;
+
+ SignalId() = default;
+ SignalId( CallId id ) : id( id ) {}
+ };
+ virtual void add_interface_impl( bool fallback, const std::string& pathName,
+ const ConnectionPtr &connection,
+ std::vector<std::function<void()>> &destructors,
+ const std::string& interfaceName,
+ std::vector< MethodInfo >& dscrMethods,
+ std::vector< PropertyInfo >& dscrProperties,
+ std::vector< SignalInfo >& dscrSignals ) = 0;
+ virtual void add_property_changed_event_listener_impl( const ProxyPtr &proxy, const std::string &interface, const std::string &name, std::function< void( const _Eina_Value * ) > cb) = 0;
+ static DBusWrapper *Installed();
+ static void Install(std::unique_ptr<DBusWrapper>);
+
+ StringStorage Strings;
+};
+
+namespace detail {
+ enum class MethodType {
+ Method, Getter, Setter
+ };
+}
+
+namespace std {
+ template <> struct hash<std::tuple<std::string, std::string, std::string>> {
+ size_t operator () (const std::tuple<std::string, std::string, std::string> &a) const {
+ auto a1 = std::hash<std::string>()(std::get<0>(a));
+ auto a2 = std::hash<std::string>()(std::get<1>(a));
+ auto a3 = std::hash<std::string>()(std::get<2>(a));
+ size_t v = a1;
+ v = (v * 11400714819323198485llu) + a2;
+ v = (v * 11400714819323198485llu) + a3;
+ return v;
+ }
+ };
+ template <> struct hash<std::tuple<std::string, std::string, std::string, detail::MethodType>> {
+ size_t operator () (const std::tuple<std::string, std::string, std::string, detail::MethodType> &a) const {
+ auto a1 = std::hash<std::string>()(std::get<0>(a));
+ auto a2 = std::hash<std::string>()(std::get<1>(a));
+ auto a3 = std::hash<std::string>()(std::get<2>(a));
+ auto a4 = static_cast<size_t>(std::get<3>(a));
+ size_t v = a1;
+ v = (v * 11400714819323198485llu) + a2;
+ v = (v * 11400714819323198485llu) + a3;
+ v = (v * 11400714819323198485llu) + a4;
+ return v;
+ }
+ };
+ template <> struct hash<std::tuple<std::string, std::string, unsigned int>> {
+ size_t operator () (const std::tuple<std::string, std::string, unsigned int> &a) const {
+ auto a1 = std::hash<std::string>()(std::get<0>(a));
+ auto a2 = std::hash<std::string>()(std::get<1>(a));
+ auto a3 = std::get<2>(a);
+ size_t v = a1;
+ v = (v * 11400714819323198485llu) + a2;
+ v = (v * 11400714819323198485llu) + a3;
+ return v;
+ }
+ };
+}
+namespace detail {
+ template <typename T> struct DBusSigImpl { enum { value = 0, end = 0 }; };
+ template <typename T> struct DBusSig { enum { value = DBusSigImpl<typename std::decay<T>::type>::value, end = DBusSigImpl<typename std::decay<T>::type>::end }; };
+ template <typename T, typename Q, size_t I, size_t S> struct IndexFromTypeTupleImpl {
+ enum { value = std::is_same<typename std::decay<typename std::tuple_element<I, T>::type>::type, Q>::value ? I : IndexFromTypeTupleImpl<T, Q, I + 1, S>::value };
+ };
+ template <typename T, typename Q, size_t S> struct IndexFromTypeTupleImpl<T, Q, S, S> { enum { value = S }; };
+ template <typename T, typename Q> struct IndexFromTypeTuple {
+ enum { value = IndexFromTypeTupleImpl<T, typename std::decay<Q>::type, 0, std::tuple_size<T>::value>::value };
+ };
+ template <typename T, typename = void> struct Encoder;
+ template <size_t I, size_t S, typename ... ARGS> struct EncoderTuple;
+}
+struct TestDBusWrapper : public DBusWrapper
+{
+ using MethodType = detail::MethodType;
+ ConnectionPtr connection;
+ std::unordered_map<std::tuple<std::string, std::string, std::string, MethodType>, std::function<MessagePtr(const MessagePtr&)>> testMethods;
+ std::unordered_map<std::tuple<std::string, std::string, std::string, MethodType>, std::function<MessagePtr(const MessagePtr&)>> daliMethods;
+ std::unordered_map<std::tuple<std::string, std::string, unsigned int>, std::string> daliSignalsMap;
+ std::unordered_map<std::tuple<std::string, std::string, std::string>, std::function<void(const MessagePtr&)>> daliSignals;
+ std::unordered_map<std::tuple<std::string, std::string, std::string>, std::function<void(const _Eina_Value *)>> propertyChangeListeners;
+
+ std::vector<std::function<void()>> asyncCalls;
+
+ template <typename T> struct Variant {
+ T value;
+ Variant() = default;
+ Variant(T t) : value(std::move(t)) { }
+ };
+ template <typename ... ARGS> void Encode(const MessagePtr &m, const std::tuple<ARGS...> &args) {
+ auto iter = eldbus_message_iter_get_impl(m, true);
+ detail::EncoderTuple<0, sizeof...(ARGS), ARGS...>::encode(*this, iter, args);
+ }
+ template <typename ... ARGS> void Decode(const MessagePtr &m, std::tuple<ARGS...> &args) {
+ auto iter = eldbus_message_iter_get_impl(m, false);
+ detail::EncoderTuple<0, sizeof...(ARGS), ARGS...>::decode(*this, args, iter);
+ }
+ MessagePtr newMessage(const std::string &path, const std::string &interface, const std::string &name, bool reply);
+ MessagePtr newReplyMessage(const MessagePtr &m);
+
+ template <typename ... ARGS> void fromTestEmitSignal(std::string path, const std::string &interface, const std::string &name, const std::tuple<ARGS...> &args) {
+ if (path.empty()) throw error{};
+ if (path[0] != '/') path = "/org/a11y/atspi/accessible/" + path;
+ auto msg = newMessage(path, interface, name, false);
+ Encode(msg, args);
+ auto it = daliSignals.find(std::tuple<std::string, std::string, std::string>{ path, interface, name });
+ if (it == daliSignals.end()) throw error{};
+ it->second(msg);
+ }
+ static std::shared_ptr<_Eina_Value> createEinaValue(bool);
+ template <typename T> void fromTestChangeProperty(std::string path, const std::string &interface, const std::string &name, T new_value) {
+ auto v = createEinaValue(new_value);
+ if (path.empty()) throw error{};
+ if (path[0] != '/') path = "/org/a11y/atspi/accessible/" + path;
+ auto it = propertyChangeListeners.find(std::tuple<std::string, std::string, std::string>{ path, interface, name });
+ if (it == propertyChangeListeners.end()) throw error{};
+ it->second(v.get());
+ }
+ template <typename ... ARGS1, typename ... ARGS2> std::tuple<ARGS1...> fromTestCall(const std::string &path, const std::string &interface, const std::string &name, const std::tuple<ARGS2...> &args) {
+ auto msg = newMessage(path, interface, name, false);
+ Encode(msg, args);
+ auto res = call(daliMethods, "daliMethods", msg, MethodType::Method);
+ std::string a, b;
+ if (eldbus_message_error_get_impl(res, a, b)) throw error{} << "call to " << path << " " << interface << " " << name << " failed: " << a << ": " << b;
+ std::tuple<ARGS1...> tmp;
+ Decode(res, tmp);
+ return tmp;
+ }
+ template <typename T> T fromTestGet(const std::string &path, const std::string &interface, const std::string &name) {
+ auto msg = newMessage(path, interface, name, false);
+ auto res = call(daliMethods, "daliMethods", msg, MethodType::Getter);
+ std::string a, b;
+ if (eldbus_message_error_get_impl(res, a, b)) throw error{} << "call to " << path << " " << interface << " " << name << " failed: " << a << ": " << b;
+ std::tuple<T> tmp;
+ Decode(res, tmp);
+ return std::move(std::get<0>(tmp));
+ }
+ template <typename ... ARGS1, typename T> std::tuple<ARGS1...> fromTestSet(const std::string &path, const std::string &interface, const std::string &name, const T &arg) {
+ auto msg = newMessage(path, interface, name, false);
+ Encode(msg, TestDBusWrapper::Variant<T>{ arg });
+ auto res = call(daliMethods, "daliMethods", msg, MethodType::Setter);
+ std::string a, b;
+ if (eldbus_message_error_get_impl(res, a, b)) throw error{} << "call to " << path << " " << interface << " " << name << " failed: " << a << ": " << b;
+ std::tuple<ARGS1...> tmp;
+ Decode(res, tmp);
+ return tmp;
+ }
+
+ TestDBusWrapper();
+ ~TestDBusWrapper();
+
+ class error : public std::exception {
+ std::shared_ptr<std::ostringstream> temp = std::make_shared<std::ostringstream>();
+ mutable std::string text;
+ public:
+ error() = default;
+
+ template <typename T> error &operator << (T &&t) {
+ *temp << std::forward<T>(t);
+ return *this;
+ }
+ const char *what() const noexcept override {
+ text = temp->str();
+ return text.c_str();
+ }
+ };
+ #define DEFINE_TYPE(name) struct name ## Impl; static name ## Impl *get(const name ## Ptr &);
+ DEFINE_TYPE(Connection)
+ DEFINE_TYPE(Proxy)
+ DEFINE_TYPE(Object)
+ DEFINE_TYPE(Message)
+ DEFINE_TYPE(MessageIter)
+ #undef DEFINE_TYPE
+
+ class Element;
+ using ElementList = std::list<Element>;
+ using ElementMap = std::map<std::string, std::string>;
+ using ElementTuple = std::tuple<
+ uint8_t, uint16_t, uint32_t, uint64_t, int16_t, int32_t, int64_t, double, bool, std::string, ObjectPath,
+ ElementList
+ >;
+
+ class Element {
+ ElementTuple data;
+ char signature_ = 0, end_ = 0, index_ = 0;
+ template <typename T> void set(T &&t, char signature = detail::DBusSig<T>::value) {
+ signature_ = signature;
+ end_ = detail::DBusSig<T>::end;
+ index_ = static_cast<char>(detail::IndexFromTypeTuple<ElementTuple, T>::value);
+ get<T>() = std::forward<T>(t);
+ }
+ public:
+ template <typename T> Element(T &&t, typename std::enable_if<detail::DBusSig<T>::value != 0>::type* = nullptr) { set(std::forward<T>(t)); }
+ Element(ElementList t, int signature) { set(std::move(t), static_cast<char>(signature)); }
+
+ char signature() const { return signature_; }
+ char end() const { return end_; }
+ char index() const { return index_; }
+ bool isContainer() const { return index_ == detail::IndexFromTypeTuple<ElementTuple, ElementList>::value; }
+ template <typename T, typename = typename std::enable_if<detail::DBusSig<T>::value != 0>::type>
+ bool is() const { return index_ == detail::IndexFromTypeTuple<ElementTuple, T>::value; }
+ template <typename T, typename = typename std::enable_if<detail::DBusSig<T>::value != 0>::type>
+ const T &get() const { if (!is<T>()) throw error{}; return std::get<detail::IndexFromTypeTuple<ElementTuple, T>::value>(data); }
+ template <typename T, typename = typename std::enable_if<detail::DBusSig<T>::value != 0>::type>
+ T &get() { if (!is<T>()) throw error{}; return std::get<detail::IndexFromTypeTuple<ElementTuple, T>::value>(data); }
+ };
+
+ ConnectionPtr eldbus_address_connection_get_impl(const std::string &addr) override;
+
+#define eldbus_message_iter_arguments_append_impl_basic_impl(type_set, type_get, sig) \
+ void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type_set src) override; \
+ bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type_get &dst) override;
+#define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
+ eldbus_message_iter_arguments_append_impl_basic_impl(type, type, sig)
+
+ eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
+ eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
+ eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
+ eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
+ eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
+ eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
+ eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
+ eldbus_message_iter_arguments_append_impl_basic(double, d)
+ eldbus_message_iter_arguments_append_impl_basic(bool, b)
+ eldbus_message_iter_arguments_append_impl_basic_impl(const std::string &, std::string, s)
+ eldbus_message_iter_arguments_append_impl_basic_impl(const ObjectPath &, ObjectPath, o)
+
+#undef eldbus_message_iter_arguments_append_impl_basic
+#undef eldbus_message_iter_arguments_append_impl_basic_impl
+
+ MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr &it, int type, const std::string &sig) override;
+ MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) override;
+ MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &it, bool write) override;
+ MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) override;
+ MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) override;
+ bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) override;
+ std::string eldbus_message_signature_get_impl(const MessagePtr &msg) override;
+ PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) override;
+ std::string eldbus_proxy_interface_get_impl(const ProxyPtr &) override;
+ void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) override;
+ std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) override;
+ MessagePtr eldbus_message_method_return_new_impl( const MessagePtr &msg) override;
+ MessagePtr eldbus_message_error_new_impl( const MessagePtr &msg, const std::string &err, const std::string &txt ) override;
+ PendingPtr eldbus_connection_send_impl(const ConnectionPtr &conn, const MessagePtr &msg) override;
+ MessagePtr eldbus_message_signal_new_impl(const std::string &path, const std::string &iface, const std::string &name) override;
+ MessagePtr eldbus_message_ref_impl(const MessagePtr &msg) override;
+ ConnectionPtr eldbus_connection_get_impl(ConnectionType type) override;
+ std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr &conn) override;
+ ObjectPtr eldbus_object_get_impl( const ConnectionPtr &conn, const std::string &bus, const std::string &path ) override;
+ ProxyPtr eldbus_proxy_get_impl( const ObjectPtr &obj, const std::string &interface ) override;
+ ProxyPtr eldbus_proxy_copy_impl( const ProxyPtr &ptr) override;
+ void add_property_changed_event_listener_impl( const ProxyPtr &proxy, const std::string &interface, const std::string &name, std::function< void( const _Eina_Value * ) > cb) override;
+ void add_interface_impl( bool fallback, const std::string& pathName,
+ const ConnectionPtr &connection,
+ std::vector<std::function<void()>> &destructors,
+ const std::string& interfaceName,
+ std::vector< MethodInfo >& dscrMethods,
+ std::vector< PropertyInfo >& dscrProperties,
+ std::vector< SignalInfo >& dscrSignals ) override;
+ static bool completed(const MessageIterPtr &iter);
+private:
+ MessagePtr call(std::unordered_map<std::tuple<std::string, std::string, std::string, MethodType>, std::function<MessagePtr(const MessagePtr&)>> &mp, const std::string &name, const MessagePtr &msg, MethodType type);
+};
+
+namespace detail {
+ template <> struct DBusSigImpl<uint8_t> { enum { value = 'y', end = 0 }; };
+ template <> struct DBusSigImpl<uint16_t> { enum { value = 'q', end = 0 }; };
+ template <> struct DBusSigImpl<uint32_t> { enum { value = 'u', end = 0 }; };
+ template <> struct DBusSigImpl<uint64_t> { enum { value = 't', end = 0 }; };
+ template <> struct DBusSigImpl<int16_t> { enum { value = 'n', end = 0 }; };
+ template <> struct DBusSigImpl<int32_t> { enum { value = 'i', end = 0 }; };
+ template <> struct DBusSigImpl<int64_t> { enum { value = 'x', end = 0 }; };
+ template <> struct DBusSigImpl<double> { enum { value = 'd', end = 0 }; };
+ template <> struct DBusSigImpl<bool> { enum { value = 'b', end = 0 }; };
+ template <> struct DBusSigImpl<std::string> { enum { value = 's', end = 0 }; };
+ template <> struct DBusSigImpl<ObjectPath> { enum { value = 'o', end = 0 }; };
+ template <> struct DBusSigImpl<TestDBusWrapper::ElementList> { enum { value = '(', end = ')' }; };
+ template <> struct DBusSigImpl<TestDBusWrapper::ElementMap> { enum { value = '{', end = '}' }; };
+
+ template <typename T> struct Encoder<T, decltype(TestDBusWrapper().eldbus_message_iter_arguments_append_impl(TestDBusWrapper::MessageIterPtr(), T()))> {
+ static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
+ w.eldbus_message_iter_arguments_append_impl(tgt, src);
+ }
+ static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+ if (!w.eldbus_message_iter_get_and_next_impl(src, tgt)) throw TestDBusWrapper::error{};
+ }
+ };
+ template <typename T> struct Encoder<T, typename std::enable_if<std::is_enum<T>::value>::type> {
+ static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
+ Encoder<typename std::underlying_type<T>::type>::encode(w, tgt, static_cast<typename std::underlying_type<T>::type>(src));
+ }
+ static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+ typename std::underlying_type<T>::type v = 0;
+ Encoder<typename std::underlying_type<T>::type>::decode(w, v, src);
+ tgt = static_cast<T>(v);
+ }
+ };
+ template <typename T> struct Encoder<const T> {
+ static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
+ Encoder<T>::encode(w, tgt, src);
+ }
+ static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+ Encoder<T>::decode(w, tgt, src);
+ }
+ };
+ template <typename T> struct Encoder<const T &> {
+ static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
+ Encoder<T>::encode(w, tgt, src);
+ }
+ static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+ Encoder<T>::decode(w, tgt, src);
+ }
+ };
+ template <typename T> struct Encoder<T &> {
+ static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
+ Encoder<T>::encode(w, tgt, src);
+ }
+ static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+ Encoder<T>::decode(w, tgt, src);
+ }
+ };
+ template <size_t I, size_t S, typename ... ARGS> struct EncoderTuple {
+ static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple<ARGS...> &src) {
+ Encoder<typename std::tuple_element<I, std::tuple<ARGS...>>::type>::encode(w, tgt, std::get<I>(src));
+ EncoderTuple<I + 1, S, ARGS...>::encode(w, tgt, src);
+ }
+ static void decode(TestDBusWrapper &w, std::tuple<ARGS...> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+ Encoder<typename std::tuple_element<I, std::tuple<ARGS...>>::type>::decode(w, std::get<I>(tgt), src);
+ EncoderTuple<I + 1, S, ARGS...>::decode(w, tgt, src);
+ }
+ };
+ template <size_t S, typename ... ARGS> struct EncoderTuple<S, S, ARGS...> {
+ static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple<ARGS...> &src) { }
+ static void decode(TestDBusWrapper &w, std::tuple<ARGS...> &tgt, const TestDBusWrapper::MessageIterPtr &src) { }
+ };
+ template <typename ...ARGS> struct Encoder<std::tuple<ARGS...>> {
+ static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple<ARGS...> &src) {
+ auto var = w.eldbus_message_iter_container_new_impl( tgt, 'r', "");
+ EncoderTuple<0, sizeof...(ARGS), ARGS...>::encode(w, var, src);
+ }
+ static void decode(TestDBusWrapper &w, std::tuple<ARGS...> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+ auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'r' );
+ if( !s ) throw TestDBusWrapper::error{};
+ EncoderTuple<0, sizeof...(ARGS), ARGS...>::decode(w, tgt, s);
+ }
+ };
+ template <typename A, typename B> struct Encoder<std::pair<A, B>> {
+ static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::pair<A, B> &src, char type = 'r') {
+ auto var = w.eldbus_message_iter_container_new_impl( tgt, type, "");
+ Encoder<A>::encode(w, var, src.first);
+ Encoder<B>::encode(w, var, src.second);
+ }
+ static void decode(TestDBusWrapper &w, std::pair<A, B> &tgt, const TestDBusWrapper::MessageIterPtr &src, char type = 'r') {
+ auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, type );
+ if( !s ) throw TestDBusWrapper::error{};
+ Encoder<A>::decode(w, tgt.first, s);
+ Encoder<B>::decode(w, tgt.second, s);
+ }
+ };
+ template <typename T> struct Encoder<TestDBusWrapper::Variant<T>> {
+ static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const TestDBusWrapper::Variant<T> &src) {
+ //w.eldbus_message_iter_arguments_append_impl(tgt, src);
+ auto var = w.eldbus_message_iter_container_new_impl( tgt, 'v', "");
+ Encoder<T>::encode(w, var, src.value);
+ }
+ static void decode(TestDBusWrapper &w, TestDBusWrapper::Variant<T> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+ auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'v' );
+ if( !s ) throw TestDBusWrapper::error{};
+ Encoder<T>::decode(w, tgt.value, s);
+ }
+ };
+ template <typename T> struct Encoder<std::vector<T>> {
+ static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::vector<T> &src) {
+ auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', "");
+ for(auto &q : src)
+ Encoder<T>::encode(w, var, q);
+ }
+ static void decode(TestDBusWrapper &w, std::vector<T> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+ auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'a' );
+ if( !s ) throw TestDBusWrapper::error{};
+ while(!TestDBusWrapper::completed(s)) {
+ tgt.push_back({});
+ Encoder<T>::decode(w, tgt.back(), s);
+ }
+ }
+ };
+ template <typename K, typename V> struct Encoder<std::unordered_map<K,V>> {
+ static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::unordered_map<K,V> &src) {
+ auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', "");
+ for(auto &q : src){
+ Encoder<typename std::unordered_map<K,V>::value_type>::encode(w, var, q, 'e');
+ }
+ }
+ static void decode(TestDBusWrapper &w, std::unordered_map<K,V> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+ auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'a' );
+ if( !s ) throw TestDBusWrapper::error{};
+ while(!TestDBusWrapper::completed(s)) {
+ std::pair<K, V> tmp;
+ Encoder<std::pair<K,V>>::decode(w, tmp, s, 'e');
+ tgt.insert(std::move(tmp));
+ }
+ }
+ };
+ template <typename T, size_t I> struct Encoder<std::array<T, I>> {
+ static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::array<T, I> &src) {
+ auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', "");
+ for(auto &q : src)
+ Encoder<T>::encode(w, var, q);
+ }
+ static void decode(TestDBusWrapper &w, std::array<T, I> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+ auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'a' );
+ if( !s ) throw TestDBusWrapper::error{};
+ size_t i = 0;
+ while(!TestDBusWrapper::completed(s)) {
+ if(i >= tgt.size()) throw TestDBusWrapper::error{};
+ Encoder<T>::decode(w, tgt[i], s);
+ ++i;
+ }
+ if( i!=tgt.size()) throw TestDBusWrapper::error{};
+ }
+ };
+ template <> struct Encoder<Dali::Accessibility::Address> {
+ static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const Dali::Accessibility::Address &src) {
+ Encoder<std::tuple<std::string, ObjectPath>>::encode(w, tgt,std::tuple<std::string, ObjectPath> {
+ src.GetBus(), ObjectPath{ "/org/a11y/atspi/accessible/" + src.GetPath() } }
+ );
+ }
+ static void decode(TestDBusWrapper &w, Dali::Accessibility::Address &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+ std::tuple<std::string, ObjectPath> tmp;
+ Encoder<std::tuple<std::string, ObjectPath>>::decode(w, tmp, src);
+ static const size_t prefixSize = std::string{ "/org/a11y/atspi/accessible/" }.size();
+ tgt = { std::move(std::get<0>(tmp)), std::get<1>(tmp).value.substr(prefixSize) };
+ }
+ };
+ template <> struct Encoder<const char*> {
+ static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const char *src) {
+ Encoder<std::string>::encode(w, tgt, src);
+ }
+ };
+}
+/// \endcond
+
+#define DBUS_DEBUG( ... ) \
+ do \
+ { \
+ DBus::debugPrint( __FILE__, __LINE__, __VA_ARGS__ ); \
+ } while( 0 )
+
+#define DBUS_W DBusWrapper::Installed()
+
+/**
+ * @brief Template based, single file, wrapper library around eldbus for DBUS based communication.
+ *
+ * Main motivation was missing asynchronous calls in AT-SPI library and difficulties,
+ * when using eldbus from C++.
+ *
+ * The library:
+ * - takes care of marshalling arguments to and from DBUS calls.
+ * - allows synchronous and asynchronous calls.
+ * - allows synchronous and asynchronous listeners on signals.
+ * - manages all involved objects' lifetimes.
+ * - errors are passed as optional-alike objects, no exceptions are used.
+ * - allows setting additional debug-print function for more details about
+ * what's going on
+ *
+ * DBUS's method signatures (and expected return values) are specified as template argument,
+ * using functor syntax. For example:
+ * \code{.cpp}
+ * auto dbus = DBusClient{ ... };
+ * auto v = dbus.method<std::tuple<int, float>(float, float, std::string)>("foo").call(1.0f, 2.0f, "qwe");
+ * \endcode
+ * means (synchronous) call on dbus object, which takes three arguments (thus making call signature \b dds)
+ * of types float, float and string (float will be automatically converted to double).
+ * Expected return value is std::tuple<int, float>, which gives signature <B>(id)</B> - std::tuple acts
+ * as struct container. Returned value v will be of type ValueOrError<std::tuple<int, float>>.\n
+ * Slightly different (asynchronous) example:
+ * \code{.cpp}
+ * auto dbus = DBusClient{ ... };
+ * std::function<void(ValueOrError<int, float>)> callback;
+ * dbus.method<ValueOrError<int, float>(float, float, std::string)>("foo").asyncCall(callback, 1.0f, 2.0f, "qwe");
+ * \endcode
+ * Now the call takes the same arguments and has the same signature. But expected values are different -
+ * now the signature is simply \b id. ValueOrError acts in this case as placeholder for list of values,
+ * which DBUS allows as return data. The call itself is asynchronous - instead of expecting reply
+ * you need to pass a callback, which will be called either with received data and error message.
+ *
+ * Library is not thread-safe, the same object shouldn't be called from different threads without
+ * synchronization. There's no guarantee, that callbacks will be executed on the same thread.
+ */
+namespace DBus
+{
+/// \cond
+class DBusServer;
+class DBusClient;
+class DBusInterfaceDescription;
+
+/**
+ * @brief Formats debug message and calls debug printer (if any) with it
+ */
+void debugPrint( const char* file, size_t line, const char* format, ... );
+
+/**
+ * @brief Sets debug printer callback, which will be called with debug messages
+ *
+ * Callback will be called in various moments of DBus activity. First value passed to callback
+ * is pointer to text, second it's length. Text is ended with 0 (not counted towards it's size),
+ * user can safely printf it.
+ */
+void setDebugPrinter( std::function< void( const char*, size_t ) > );
+
+struct Error
+{
+ std::string message;
+
+ Error() = default;
+ Error( std::string msg ) : message( std::move( msg ) )
+ {
+ bart_assert( !message.empty() );
+ }
+};
+
+struct Success
+{
+};
+/// \endcond
+
+/**
+ * @brief Value representing data, that came from DBUS or error message
+ *
+ * Object of this class either helds series of values (of types ARGS...)
+ * or error message. This object will be true in boolean context, if has data
+ * and false, if an error occured.
+ * It's valid to create ValueOrError object with empty argument list or void:
+ * \code{.cpp}
+ * ValueOrError<> v1;
+ * ValueOrError<void> v2;
+ * \endcode
+ * Both mean the same - ValueOrError containing no real data and being a marker,
+ * wherever operation successed or failed and containing possible error message.
+ */
+template < typename... ARGS >
+class ValueOrError
+{
+public:
+ /**
+ * @brief Empty constructor. Valid only, if all ARGS types are default constructible.
+ */
+ ValueOrError() = default;
+
+ /**
+ * @brief Value constructor.
+ *
+ * This will be initialized as success with passed in values.
+ */
+ ValueOrError( ARGS... t ) : value( std::move( t )... ) {}
+
+ /**
+ * @brief Alternative Value constructor.
+ *
+ * This will be initialized as success with passed in values.
+ */
+ ValueOrError( std::tuple< ARGS... > t ) : value( std::move( t ) ) {}
+
+ /**
+ * @brief Error constructor. This will be initialized as failure with given error message.
+ */
+ ValueOrError( Error e ) : error( std::move( e ) )
+ {
+ bart_assert( !error.message.empty() );
+ }
+
+ /**
+ * @brief bool operator.
+ *
+ * Returns true, if operation was successful (getValues member is callable), or false
+ * when operation failed (getError is callable).
+ */
+ explicit operator bool() const
+ {
+ return error.message.empty();
+ }
+
+ /**
+ * @brief Returns error message object.
+ *
+ * Returns object containing error message associated with the failed operation.
+ * Only callable, if operation actually failed, otherwise will bart_assert.
+ */
+ const Error& getError() const
+ {
+ return error;
+ }
+
+ /**
+ * @brief Returns modifiable tuple of held data.
+ *
+ * Returns reference to the internal tuple containing held data.
+ * User can modify (or move) data safely.
+ * Only callable, if operation actually successed, otherwise will bart_assert.
+ */
+ std::tuple< ARGS... >& getValues()
+ {
+ bart_assert( *this );
+ return value;
+ }
+
+ /**
+ * @brief Returns const tuple of held data.
+ *
+ * Returns const reference to the internal tuple containing held data.
+ * Only callable, if operation actually successed, otherwise will bart_assert.
+ */
+ const std::tuple< ARGS... >& getValues() const
+ {
+ bart_assert( *this );
+ return value;
+ }
+
+protected:
+ /// \cond
+ std::tuple< ARGS... > value;
+ Error error;
+ /// \endcond
+};
+
+/// \cond
+template <>
+class ValueOrError<>
+{
+public:
+ ValueOrError() = default;
+ ValueOrError( std::tuple<> t ) {}
+ ValueOrError( Error e ) : error( std::move( e ) )
+ {
+ bart_assert( !error.message.empty() );
+ }
+
+ explicit operator bool() const
+ {
+ return error.message.empty();
+ }
+ const Error& getError() const
+ {
+ return error;
+ }
+ std::tuple<>& getValues()
+ {
+ bart_assert( *this );
+ static std::tuple<> t;
+ return t;
+ }
+ std::tuple<> getValues() const
+ {
+ bart_assert( *this );
+ return {};
+ }
+
+protected:
+ Error error;
+};
+
+template <>
+class ValueOrError< void >
+{
+public:
+ ValueOrError() = default;
+ ValueOrError( Success ) {}
+ ValueOrError( Error e ) : error( std::move( e ) )
+ {
+ bart_assert( !error.message.empty() );
+ }
+
+ explicit operator bool() const
+ {
+ return error.message.empty();
+ }
+ const Error& getError() const
+ {
+ return error;
+ }
+ std::tuple<>& getValues()
+ {
+ bart_assert( *this );
+ static std::tuple<> t;
+ return t;
+ }
+ std::tuple<> getValues() const
+ {
+ bart_assert( *this );
+ return {};
+ }
+
+protected:
+ Error error;
+};
+
+using ObjectPath = ObjectPath;
+
+/// \endcond
+
+/**
+ * @brief Class used to marshall DBUS's variant type
+ *
+ * Minimalistic class, that allows user to specify DBUS variant type
+ * as argument or return value. You need to pass real type hidden under variant as
+ * template type \b A. At this point library doesn't allow to expected one of few classes
+ * as return data in variant. So for example user can't specify method call, which on return
+ * expects DBUS variant holding either string or int.
+ */
+template < typename A >
+struct EldbusVariant
+{
+ A value;
+};
+
+/**
+ * @brief Namespace for private, internal functions and classes
+ */
+namespace detail
+{
+/// \cond
+template < typename T, typename = void >
+struct signature;
+template < typename... ARGS >
+struct signature< std::tuple< ARGS... > >;
+template < typename A, typename B >
+struct signature< std::pair< A, B > >;
+template < typename A >
+struct signature< std::vector< A > >;
+template < typename A, size_t N >
+struct signature< std::array< A, N > >;
+template < typename A, typename B >
+struct signature< std::unordered_map< A, B > >;
+template < typename A, typename B >
+struct signature< std::map< A, B > >;
+/// \endcond
+
+/**
+ * @brief Signature class for marshalling uint8 type.
+ */
+template <>
+struct signature< uint8_t >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "uint8_t";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "y";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, uint8_t v )
+ {
+ DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, uint8_t& v )
+ {
+ return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+ }
+};
+
+/**
+ * @brief Signature class for marshalling uint16 type.
+ */
+template <>
+struct signature< uint16_t >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "uint16_t";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "q";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, uint16_t v )
+ {
+ DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, uint16_t& v )
+ {
+ return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+ }
+};
+
+/**
+ * @brief Signature class for marshalling uint32 type.
+ */
+template <>
+struct signature< uint32_t >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "uint32_t";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "u";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, uint32_t v )
+ {
+ DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, uint32_t& v )
+ {
+ return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+ }
+};
+
+/**
+ * @brief Signature class for marshalling uint64 type.
+ */
+template <>
+struct signature< uint64_t >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "uint64_t";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "t";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, uint64_t v )
+ {
+ DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, uint64_t& v )
+ {
+ return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+ }
+};
+
+/**
+ * @brief Signature class for marshalling int16 type.
+ */
+template <>
+struct signature< int16_t >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "int16_t";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "n";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, int16_t v )
+ {
+ DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, int16_t& v )
+ {
+ return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+ }
+};
+
+/**
+ * @brief Signature class for marshalling int32 type.
+ */
+template <>
+struct signature< int32_t >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "int32_t";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "i";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, int32_t v )
+ {
+ DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, int32_t& v )
+ {
+ return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+ }
+};
+
+/**
+ * @brief Signature class for marshalling int64 type.
+ */
+template <>
+struct signature< int64_t >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "int64_t";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "x";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, int64_t v )
+ {
+ DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, int64_t& v )
+ {
+ return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+ }
+};
+
+/**
+ * @brief Signature class for marshalling double type.
+ */
+template <>
+struct signature< double >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "double";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "d";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, double v )
+ {
+ DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, double& v )
+ {
+ return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, float& v2 )
+ {
+ double v = 0;
+ auto r = DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+ v2 = static_cast< float >( v );
+ return r;
+ }
+};
+
+/**
+ * @brief Signature class for marshalling float type.
+ */
+template <>
+struct signature< float >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "float";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "d";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, float v )
+ {
+ DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, double& v )
+ {
+ return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, float& v2 )
+ {
+ double v = 0;
+ auto r = DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+ v2 = static_cast< float >( v );
+ return r;
+ }
+};
+
+/**
+ * @brief Signature class for marshalling boolean type.
+ */
+template <>
+struct signature< bool >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "bool";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "b";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, bool v )
+ {
+ DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, bool& v )
+ {
+ return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+ }
+};
+
+template < typename T >
+struct signature< T, typename std::enable_if< std::is_enum< T >::value, void >::type >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "enum";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return signature<typename std::underlying_type<T>::type>::sig();
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, T v )
+ {
+ signature<typename std::underlying_type<T>::type>::set(iter, static_cast< int64_t >( v ));
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, T& v )
+ {
+ typename std::underlying_type<T>::type q = 0;
+ if (!signature<typename std::underlying_type<T>::type>::get(iter, q))
+ return false;
+
+ v = static_cast< T >( q );
+ return true;
+ }
+};
+
+/**
+ * @brief Signature class for marshalling string type.
+ *
+ * Both (const) char * and std::string types are accepted as value to send.
+ * Only std::string is accepted as value to receive.
+ */
+template <>
+struct signature< std::string >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "string";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "s";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const std::string& v )
+ {
+ DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+ }
+
+// /**
+// * @brief Marshals value v as marshalled type into message
+// */
+// static void set( const DBusWrapper::MessageIterPtr &iter, const char* v )
+// {
+// DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+// }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, std::string& v )
+ {
+ return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+ }
+};
+
+template <>
+struct signature< ObjectPath >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "path";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "o";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const std::string& v )
+ {
+ DBUS_W->eldbus_message_iter_arguments_append_impl(iter, ObjectPath{ v });
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const ObjectPath& v )
+ {
+ DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const char* v )
+ {
+ DBUS_W->eldbus_message_iter_arguments_append_impl(iter, ObjectPath{ v });
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, ObjectPath& v )
+ {
+ return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, std::string& v )
+ {
+ ObjectPath q;
+ if (!DBUS_W->eldbus_message_iter_get_and_next_impl(iter, q)) return false;
+ v = std::move(q.value);
+ return true;
+ }
+};
+
+/**
+ * @brief Signature class for marshalling (const) char * type.
+ *
+ * Both (const) char * and std::string types are accepted as value to send.
+ * You can't use (const) char * variable type to receive value.
+ */
+template <>
+struct signature< char* >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "string";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "s";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const std::string& v )
+ {
+ DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const char* v )
+ {
+ DBUS_W->eldbus_message_iter_arguments_append_impl(iter, std::string{ v });
+ }
+};
+/// \cond
+
+template < size_t INDEX, typename A, typename... ARGS >
+struct signature_tuple_element_type_helper
+{
+ using type = typename signature_tuple_element_type_helper< INDEX - 1, ARGS... >::type;
+};
+
+template < typename A, typename... ARGS >
+struct signature_tuple_element_type_helper< 0, A, ARGS... >
+{
+ using type = A;
+};
+/// \endcond
+
+/**
+ * @brief Helper class to marshall tuples
+ *
+ * This class marshals all elements of the tuple value starting at the index INDEX
+ * and incrementing. This class recursively calls itself with increasing INDEX value
+ * until INDEX is equal to SIZE, where recursive calling ends.
+ */
+template < size_t INDEX, size_t SIZE, typename... ARGS >
+struct signature_tuple_helper
+{
+ using current_type = typename signature_tuple_element_type_helper< INDEX, ARGS... >::type;
+
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ if( INDEX + 1 >= SIZE )
+ return signature< current_type >::name();
+ return signature< current_type >::name() + ", " + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::name();
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return signature< current_type >::sig() + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::sig();
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const std::tuple< ARGS... >& args )
+ {
+ signature< current_type >::set( iter, std::get< INDEX >( args ) );
+ signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::set( iter, args );
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, std::tuple< ARGS... >& args )
+ {
+ return signature< current_type >::get( iter, std::get< INDEX >( args ) ) &&
+ signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::get( iter, args );
+ }
+};
+
+/**
+ * @brief Helper class to marshall tuples
+ *
+ * This class marks end of the tuple marshalling. Members of this class are called
+ * when INDEX value is equal to SIZE.
+ */
+template < size_t SIZE, typename... ARGS >
+struct signature_tuple_helper< SIZE, SIZE, ARGS... >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const std::tuple< ARGS... >& args )
+ {
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, std::tuple< ARGS... >& args )
+ {
+ return true;
+ }
+};
+
+/**
+ * @brief Signature class for marshalling tuple of values
+ *
+ * This class marshalls tuple of values. This represents
+ * DBUS struct typle, encoded with character 'r'
+ */
+template < typename... ARGS >
+struct signature< std::tuple< ARGS... > >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "tuple<" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name() + ">";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "(" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::sig() + ")";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const std::tuple< ARGS... >& args )
+ {
+ auto entry = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'r', "");
+ signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::set( entry, args );
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, std::tuple< ARGS... >& args )
+ {
+ auto entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'r' );
+ if (!entry) return false;
+ return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::get( entry, args );
+ }
+};
+
+/**
+ * @brief Signature class for marshalling ValueOrError template type
+ *
+ * ValueOrError template type is used to marshall list of values passed to
+ * DBUS (or received from) at the "top" level. For example ss(s) is represented as
+ * \code{.cpp} ValueOrError<std::string, std::string, std::tuple<std::string>> \endcode
+ * While (ss(s)) is represented as
+ * \code{.cpp} std::tuple<std::string, std::string, std::tuple<std::string>> \endcode
+ * or
+ * \code{.cpp} ValueOrError<std::tuple<std::string, std::string, std::tuple<std::string>>> \endcode
+ */
+template < typename... ARGS >
+struct signature< ValueOrError< ARGS... > >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "ValueOrError<" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name() + ">";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::sig();
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const ValueOrError< ARGS... >& args )
+ {
+ signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::set( iter, args.getValues() );
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, ValueOrError< ARGS... >& args )
+ {
+ return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::get( iter, args.getValues() );
+ }
+};
+
+/**
+ * @brief Signature class for marshalling ValueOrError<void> type
+ */
+template <>
+struct signature< ValueOrError< void > >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "ValueOrError<void>";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const ValueOrError< void >& args )
+ {
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, ValueOrError< void >& args )
+ {
+ return true;
+ }
+};
+
+/**
+ * @brief Signature class for marshalling ValueOrError<> type
+ */
+template <>
+struct signature< ValueOrError<> >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "ValueOrError<>";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const ValueOrError<>& args )
+ {
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, ValueOrError<>& args )
+ {
+ return true;
+ }
+};
+
+/**
+ * @brief Signature class for marshalling pair of types
+ */
+template < typename A, typename B >
+struct signature< std::pair< A, B > >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "pair<" + signature_tuple_helper< 0, 2, A, B >::name() + ">";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "(" + signature_tuple_helper< 0, 2, A, B >::sig() + ")";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const std::pair< A, B >& ab, bool dictionary = false )
+ {
+ auto entry = DBUS_W->eldbus_message_iter_container_new_impl( iter, dictionary ? 'e' : 'r', "");
+ signature_tuple_helper< 0, 2, A, B >::set( entry, ab );
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, std::pair< A, B >& ab )
+ {
+ auto entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'r' );
+ if (!entry) {
+ entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, '{' );
+ if (!entry) return false;
+ }
+
+ std::tuple< A, B > ab_tmp;
+ auto z = signature_tuple_helper< 0, 2, A, B >::get( entry, ab_tmp );
+ if( z )
+ {
+ ab.first = std::move( std::get< 0 >( ab_tmp ) );
+ ab.second = std::move( std::get< 1 >( ab_tmp ) );
+ }
+ return z;
+ }
+};
+
+/**
+ * @brief Signature class for marshalling std::vector template type
+ *
+ * This marshals container's content as DBUS a ascii character type code.
+ */
+template < typename A >
+struct signature< std::vector< A > >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "vector<" + signature< A >::name() + ">";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "a" + signature< A >::sig();
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const std::vector< A >& v )
+ {
+ auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', signature< A >::sig());
+ bart_assert( lst );
+ for( auto& a : v )
+ {
+ signature< A >::set( lst, a );
+ }
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, std::vector< A >& v )
+ {
+ auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
+ if (!s) return false;
+ v.clear();
+ A a;
+ while( signature< A >::get( s, a ) )
+ v.push_back( std::move( a ) );
+
+ return true;
+ }
+};
+
+/**
+ * @brief Signature class for marshalling std::array template type
+ *
+ * This marshals container's content as DBUS a ascii character type code.
+ */
+template < typename A, size_t N >
+struct signature< std::array< A, N > >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "array<" + signature< A >::name() + ", " + std::to_string( N ) + ">";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "a" + signature< A >::sig();
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const std::array< A, N >& v )
+ {
+ auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', signature< A >::sig());
+ bart_assert( lst );
+ for( auto& a : v )
+ {
+ signature< A >::set( lst, a );
+ }
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, std::array< A, N >& v )
+ {
+ auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
+ if ( !s )
+ return false;
+ for( auto& a : v )
+ {
+ if( !signature< A >::get( s, a ) )
+ return false;
+ }
+ return true;
+ }
+};
+
+/**
+ * @brief Signature class for marshalling EldbusVariant type
+ *
+ * This marshals variant's content as DBUS v ascii character type code.
+ */
+template < typename A >
+struct signature< EldbusVariant< A > >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "variant<" + signature< A >::name() + ">";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "v";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const EldbusVariant< A >& v )
+ {
+ set( iter, v.value );
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
+ {
+ auto var = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'v', signature< A >::sig());
+ signature< A >::set( var, v );
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, EldbusVariant< A >& v )
+ {
+ auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'v' );
+ if( !s )
+ return false;
+ return signature< A >::get( s, v.value );
+ }
+};
+
+/**
+ * @brief Signature class for marshalling std::unordered_map template type
+ *
+ * This marshals container's content as DBUS {} ascii character type code.
+ * Note, that library doesnt check, if the key is basic type, as DBUS
+ * specification mandates.
+ * User can always exchange std::unordered_map for std::map and the reverse.
+ * User can receive such values as std::vector of std::pair<key, value> values.
+ * Order of such values is unspecified.
+ */
+template < typename A, typename B >
+struct signature< std::unordered_map< A, B > >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "unordered_map<" + signature< A >::name() + ", " + signature< B >::name() + ">";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const std::unordered_map< A, B >& v )
+ {
+ auto sig = "{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
+ auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', sig);
+ bart_assert( lst );
+ for( auto& a : v )
+ {
+ signature< std::pair< A, B > >::set( lst, a, true );
+ }
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, std::unordered_map< A, B >& v )
+ {
+ auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
+ v.clear();
+ if( !s )
+ return false;
+ std::pair< A, B > a;
+ while( signature< std::pair< A, B > >::get( s, a ) )
+ v.insert( std::move( a ) );
+ return true;
+ }
+};
+
+/**
+ * @brief Signature class for marshalling std::unordered_map template type
+ *
+ * This marshals container's content as DBUS {} ascii character type code.
+ * Note, that library doesnt check, if the key is basic type, as DBUS
+ * specification mandates.
+ * User can always exchange std::unordered_map for std::map and the reverse.
+ * User can receive such values as std::vector of std::pair<key, value> values.
+ * Order of such values is unspecified.
+ */
+template < typename A, typename B >
+struct signature< std::map< A, B > >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "map<" + signature< A >::name() + ", " + signature< B >::name() + ">";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const std::map< A, B >& v )
+ {
+ auto sig = "{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
+ auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', sig);
+ bart_assert( lst );
+ for( auto& a : v )
+ {
+ signature< std::pair< A, B > >::set( lst, a, true );
+ }
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static bool get( const DBusWrapper::MessageIterPtr &iter, std::map< A, B >& v )
+ {
+ auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
+ if( !s )
+ return false;
+ std::pair< A, B > a;
+ while( signature< std::pair< A, B > >::get( s, a ) )
+ v.insert( std::move( a ) );
+ return true;
+ }
+};
+
+/**
+ * @brief Signature helper class for marshalling const reference types
+ */
+template < typename A >
+struct signature< const A& >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "const " + signature< A >::name() + "&";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return signature< A >::sig();
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
+ {
+ signature< A >::set( iter, v );
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static void get( const DBusWrapper::MessageIterPtr &iter, A& v )
+ {
+ signature< A >::get( iter, v );
+ }
+};
+
+/**
+ * @brief Signature helper class for marshalling reference types
+ */
+template < typename A >
+struct signature< A& >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return signature< A >::name() + "&";
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return signature< A >::sig();
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
+ {
+ signature< A >::set( iter, v );
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static void get( const DBusWrapper::MessageIterPtr &iter, A& v )
+ {
+ signature< A >::get( iter, v );
+ }
+};
+
+/**
+ * @brief Signature helper class for marshalling const types
+ */
+template < typename A >
+struct signature< const A >
+{
+ /**
+ * @brief Returns name of type marshalled, for informative purposes
+ */
+ static std::string name()
+ {
+ return "const " + signature< A >::name();
+ }
+
+ /**
+ * @brief Returns DBUS' signature of type marshalled
+ */
+ static std::string sig()
+ {
+ return signature< A >::sig();
+ }
+
+ /**
+ * @brief Marshals value v as marshalled type into message
+ */
+ static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
+ {
+ signature< A >::set( iter, v );
+ }
+
+ /**
+ * @brief Marshals value from marshalled type into variable v
+ */
+ static void get( const DBusWrapper::MessageIterPtr &iter, A& v )
+ {
+ signature< A >::get( iter, v );
+ }
+};
+
+/// \cond
+using CallId = DBusWrapper::CallId;
+
+template < typename ValueType >
+ValueType unpackValues( CallId callId, const DBusWrapper::MessagePtr &msg )
+{
+ auto iter = DBUS_W->eldbus_message_iter_get_impl( msg, false );
+ ValueType r;
+
+ if( iter )
+ {
+ if( !signature< ValueType >::get( iter, r ) )
+ {
+ DBUS_DEBUG( "ValueType is %s", signature< ValueType >::name().c_str() );
+ r = Error{"call " + std::to_string( callId.id ) + ": failed to unpack values, got signature '" +
+ DBUS_W->eldbus_message_signature_get_impl( msg ) + "', expected '" + signature< ValueType >::sig() + "'"};
+ }
+ }
+ else
+ {
+ r = Error{"call " + std::to_string( callId.id ) + ": failed to get iterator"};
+ }
+ return r;
+}
+
+inline void packValues_helper( const DBusWrapper::MessageIterPtr& ) {}
+
+template < typename A, typename... ARGS >
+void packValues_helper( const DBusWrapper::MessageIterPtr &iter, A&& a, ARGS&&... r )
+{
+ signature< A >::set( iter, std::forward< A >( a ) );
+ packValues_helper( iter, std::forward< ARGS >( r )... );
+}
+
+template < typename... ARGS >
+void packValues( CallId callId, const DBusWrapper::MessagePtr &msg, ARGS&&... r )
+{
+ auto iter = DBUS_W->eldbus_message_iter_get_impl( msg, true );
+ packValues_helper( iter, std::forward< ARGS >( r )... );
+}
+
+template < typename >
+struct ReturnType;
+template < typename R, typename... ARGS >
+struct ReturnType< R( ARGS... ) >
+{
+ using type = R;
+};
+
+template < typename R, typename... ARGS >
+struct ReturnType< std::function< R( ARGS... ) > >
+{
+ using type = R;
+};
+
+template < int... >
+struct sequence
+{
+};
+
+template < int N, int... S >
+struct sequence_gen : sequence_gen< N - 1, N - 1, S... >
+{
+};
+
+template < int... S >
+struct sequence_gen< 0, S... >
+{
+ typedef sequence< S... > type;
+};
+
+template < typename C, typename... ARGS >
+struct apply_helper
+{
+ const std::function< C >& c;
+ const std::tuple< ARGS... >& args;
+
+ template < int... S >
+ auto apply_2( sequence< S... > ) const -> decltype( c( std::get< S >( args )... ) )
+ {
+ return c( std::get< S >( args )... );
+ }
+ auto apply_1() const -> decltype( apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() ) )
+ {
+ return apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() );
+ }
+};
+
+template < typename C, typename A, typename... ARGS >
+struct apply_helper_2
+{
+ const std::function< C >& c;
+ const A& a;
+ const std::tuple< ARGS... >& args;
+
+ template < int... S >
+ auto apply_2( sequence< S... > ) const -> decltype( c( a, std::get< S >( args )... ) )
+ {
+ return c( a, std::get< S >( args )... );
+ }
+ auto apply_1() const -> decltype( apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() ) )
+ {
+ return apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() );
+ }
+};
+
+template < typename C, typename... ARGS >
+auto apply( const std::function< C >& c, const std::tuple< ARGS... >& args ) -> typename ReturnType< C >::type
+{
+ apply_helper< C, ARGS... > ah{c, args};
+ return ah.apply_1();
+}
+
+template < typename C, typename D, typename... ARGS >
+auto apply( const std::function< C >& c, const D& d, const std::tuple< ARGS... >& args ) -> typename ReturnType< C >::type
+{
+ apply_helper_2< C, D, ARGS... > ah{c, d, args};
+ return ah.apply_1();
+}
+
+struct ConnectionState
+{
+ DBusWrapper::ConnectionPtr connection;
+ DBusWrapper::ObjectPtr object;
+ DBusWrapper::ProxyPtr proxy, propertiesProxy;
+};
+
+template < typename RETTYPE, typename... ARGS >
+RETTYPE call( CallId callId, const ConnectionState& connectionState, bool property, const std::string& funcName, const ARGS&... args )
+{
+ const auto &proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
+ if( !proxy )
+ {
+ DBUS_DEBUG( "call %d: not initialized", callId.id );
+ return Error{"not initialized"};
+ }
+
+ DBUS_DEBUG( "call %d: calling '%s'", callId.id, funcName.c_str() );
+ auto msg = DBUS_W->eldbus_proxy_method_call_new_impl(proxy, funcName);
+ if( !msg )
+ {
+ DBUS_DEBUG( "call %d: failed", callId.id );
+ return Error{"failed to create message"};
+ }
+
+ detail::packValues( callId, msg, args... );
+ auto reply = DBUS_W->eldbus_proxy_send_and_block_impl( proxy, msg );
+ DBUS_DEBUG( "call %d: calling '%s' done", callId.id, funcName.c_str() );
+ if( !reply )
+ {
+ DBUS_DEBUG( "call %d: failed", callId.id );
+ return Error{"eldbus returned null as reply"};
+ }
+ std::string errname, errmsg;
+ if( DBUS_W->eldbus_message_error_get_impl( reply, errname, errmsg ) )
+ {
+ DBUS_DEBUG( "call %d: %s: %s", callId.id, errname.c_str(), errmsg.c_str() );
+ return Error{errname + ": " + errmsg};
+ }
+ DBUS_DEBUG( "call %d: got reply with signature '%s'", callId.id,
+ DBUS_W->eldbus_message_signature_get_impl( reply ).c_str() );
+ return detail::unpackValues< RETTYPE >( callId, reply );
+}
+
+template < typename RETTYPE, typename... ARGS >
+void asyncCall( CallId callId, const ConnectionState &connectionState,
+ bool property, const std::string& funcName,
+ std::function< void( RETTYPE ) > callback, const ARGS&... args )
+{
+ const auto &proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
+ if( !proxy )
+ {
+ DBUS_DEBUG( "call %d: not initialized", callId.id );
+ callback( Error{"not initialized"} );
+ return;
+ }
+
+ auto msg = DBUS_W->eldbus_proxy_method_call_new_impl( proxy, funcName );
+ if( !msg )
+ {
+ DBUS_DEBUG( "call %d: failed", callId.id );
+ callback( Error{"failed to create message"} );
+ return;
+ }
+
+ detail::packValues( callId, msg, args... );
+ auto pending = DBUS_W->eldbus_proxy_send_impl( proxy, msg, [callback, callId, proxy]( const DBusWrapper::MessagePtr &reply ) {
+ DBUS_DEBUG( "call %d: calling done", callId.id );
+ if( !reply )
+ {
+ DBUS_DEBUG( "call %d: failed", callId.id );
+ callback( Error{"eldbus returned null as reply"} );
+ }
+ else
+ {
+ std::string errname, errmsg;
+ if( DBUS_W->eldbus_message_error_get_impl( reply, errname, errmsg ) )
+ {
+ DBUS_DEBUG( "call %d: %s: %s", callId.id, errname.c_str(), errmsg.c_str() );
+ callback( Error{errname + ": " + errmsg} );
+ }
+ else
+ {
+ DBUS_DEBUG( "call %d: got reply with signature '%s'", callId.id,
+ DBUS_W->eldbus_message_signature_get_impl( reply ).c_str() );
+ callback( detail::unpackValues< RETTYPE >( callId, reply ) );
+ }
+ }
+ }
+ );
+ if( pending )
+ {
+ DBUS_DEBUG( "call %d: call sent", callId.id );
+ }
+ else
+ {
+ DBUS_DEBUG( "call %d: failed to send call", callId.id );
+ callback( Error{"failed to send call"} );
+ }
+}
+
+inline void displayDebugCallInfo( CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName )
+{
+ DBUS_DEBUG( "call %d: %s iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str() );
+}
+
+inline void displayDebugCallInfoSignal( CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName )
+{
+ DBUS_DEBUG( "call %d: %s signal iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str() );
+}
+
+inline void displayDebugCallInfoProperty( CallId callId, const std::string& funcName, std::string info, const std::string& interfaceName,
+ const std::string& propertyName )
+{
+ DBUS_DEBUG( "call %d: %s iname = %s pname = %s", callId.id, info.c_str(), interfaceName.c_str(), propertyName.c_str() );
+}
+
+using StringStorage = DBusWrapper::StringStorage;
+
+template < typename A, typename... ARGS >
+struct EldbusArgGenerator_Helper
+{
+ static void add( std::vector< std::pair<std::string, std::string> >& r )
+ {
+ auto s = r.size();
+ auto sig = signature< A >::sig();
+ bart_assert( !sig.empty() );
+ auto name = "p" + std::to_string( s + 1 );
+ r.push_back({ std::move(sig), std::move(name) });
+ EldbusArgGenerator_Helper<ARGS...>::add( r );
+ }
+};
+
+template <>
+struct EldbusArgGenerator_Helper< void >
+{
+ static void add( std::vector< std::pair<std::string, std::string> >& )
+ {
+ }
+};
+
+template <>
+struct EldbusArgGenerator_Helper< ValueOrError< void >, void >
+{
+ static void add( std::vector< std::pair<std::string, std::string> >& )
+ {
+ }
+};
+template <>
+struct EldbusArgGenerator_Helper< ValueOrError<>, void >
+{
+ static void add( std::vector< std::pair<std::string, std::string> >& )
+ {
+ }
+};
+
+template < typename... ARGS >
+struct EldbusArgGenerator_Helper< std::tuple< ARGS... > >
+{
+ static void add( std::vector< std::pair<std::string, std::string> >& r )
+ {
+ EldbusArgGenerator_Helper< ARGS..., void >::add( r );
+ }
+};
+
+template < typename RetType >
+struct dbus_interface_return_type_traits
+{
+ using type = ValueOrError< RetType >;
+};
+
+template < typename... ARGS >
+struct dbus_interface_return_type_traits< ValueOrError< ARGS... > >
+{
+ using type = ValueOrError< ARGS... >;
+};
+
+template < typename T >
+struct dbus_interface_traits;
+template < typename RetType, typename... ARGS >
+struct dbus_interface_traits< RetType( ARGS... ) >
+{
+ using Ret = typename dbus_interface_return_type_traits< RetType >::type;
+ using SyncCB = std::function< Ret( ARGS... ) >;
+ using AsyncCB = std::function< void( std::function< void( Ret ) >, ARGS... ) >;
+ using VEArgs = ValueOrError< ARGS... >;
+};
+
+template < typename T >
+struct EldbusArgGenerator_Args;
+template < typename RetType, typename... ARGS >
+struct EldbusArgGenerator_Args< RetType( ARGS... ) >
+{
+ static std::string name()
+ {
+ return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name();
+ }
+ static std::vector< std::pair<std::string, std::string> > get()
+ {
+ std::vector< std::pair<std::string, std::string> > tmp;
+ EldbusArgGenerator_Helper< ARGS..., void >::add( tmp );
+ return tmp;
+ }
+};
+
+template < typename T >
+struct EldbusArgGenerator_ReturnType;
+template < typename RetType, typename... ARGS >
+struct EldbusArgGenerator_ReturnType< RetType( ARGS... ) >
+{
+ static std::string name()
+ {
+ return signature< RetType >::name();
+ }
+ static std::vector< std::pair<std::string, std::string> > get( )
+ {
+ std::vector< std::pair<std::string, std::string> > tmp;
+ EldbusArgGenerator_Helper< RetType, void >::add( tmp );
+ return tmp;
+ }
+};
+
+template < typename T >
+struct EldbusArgGenerator_ReturnType;
+template < typename... ARGS >
+struct EldbusArgGenerator_ReturnType< void( ARGS... ) >
+{
+ static std::string name()
+ {
+ return "";
+ }
+ static std::vector< std::pair<std::string, std::string> > get( )
+ {
+ return {};
+ }
+};
+/// \endcond
+}
+
+using ConnectionType = DBusWrapper::ConnectionType;
+
+/**
+ * @brief Class representing client's end of DBUS connection
+ *
+ * Allows calling (synchronous and asynchronos) methods on selected interface
+ * Allows (synchronous and asynchronos) setting / getting properties.
+ * Allows registering signals.
+ */
+class DBusClient
+{
+ /// \cond
+ struct ConnectionInfo
+ {
+ std::string interfaceName, busName, pathName;
+ };
+ /// \endcond
+public:
+ /**
+ * @brief Default constructor, creates non-connected object.
+ */
+ DBusClient() = default;
+
+ /**
+ * @brief Connects to dbus choosen by tp, using given arguments
+ *
+ * @param bus_name name of the bus to connect to
+ * @param path_name object's path
+ * @param interface_name interface name
+ */
+ DBusClient( std::string busName_, std::string pathName_, std::string interfaceName_,
+ ConnectionType tp );
+
+ /**
+ * @brief Connects to dbus using connection conn
+ *
+ * @param bus_name name of the bus to connect to
+ * @param path_name object's path
+ * @param interface_name interface name
+ * @param conn connection object from getDBusConnectionByType call
+ */
+ DBusClient( std::string busName_, std::string pathName_, std::string interfaceName_,
+ const DBusWrapper::ConnectionPtr &conn = {} );
+
+ /**
+ * @brief Destructor object.
+ *
+ * All signals added will be disconnected.
+ * All asynchronous calls will be cancelled, their callback's will be called
+ * with failure message.
+ */
+ ~DBusClient() = default;
+ DBusClient( const DBusClient& ) = delete;
+ DBusClient( DBusClient&& ) = default;
+
+ DBusClient& operator=( DBusClient&& ) = default;
+ DBusClient& operator=( const DBusClient& ) = delete;
+
+ /**
+ * @brief bool operator
+ *
+ * Returns true, if object is connected to DBUS
+ */
+ explicit operator bool() const
+ {
+ return bool( connectionState->proxy );
+ }
+
+ /**
+ * @brief Helper class for calling a method
+ *
+ * Template type T defines both arguments sent to the method
+ * and expected values. Receiving different values will be reported as
+ * error. For example:
+ * \code{.cpp} Method<int(float, float)> \endcode
+ * defines method, which takes two arguments (two floats) and return
+ * single value of type int.
+ */
+ template < typename T >
+ struct Method
+ {
+ /// \cond
+ using RetType = typename detail::dbus_interface_traits< T >::Ret;
+ const detail::ConnectionState &connectionState;
+ std::string funcName;
+ std::string info;
+ std::shared_ptr< ConnectionInfo > connectionInfo;
+ /// \endcond
+
+ /**
+ * @brief Executes synchronous call on DBUS's method
+ *
+ * The function returns ValueOrError<...> object, which
+ * contains either received values or error message.
+ *
+ * @param args arguments to pass to the method
+ */
+ template < typename... ARGS >
+ RetType call( const ARGS&... args )
+ {
+ detail::CallId callId;
+ detail::displayDebugCallInfo( callId, funcName, info, connectionInfo->interfaceName );
+ return detail::call< RetType >( callId, connectionState, false, funcName, args... );
+ }
+
+ /**
+ * @brief Executes asynchronous call on DBUS's method
+ *
+ * The function calls callback with either received values or error message.
+ *
+ * @param callback callback functor, which will be called with return value(s) or error message
+ * @param args arguments to pass to the method
+ */
+ template < typename... ARGS >
+ void asyncCall( std::function< void( RetType ) > callback, const ARGS&... args )
+ {
+ detail::CallId callId;
+ detail::displayDebugCallInfo( callId, funcName, info, connectionInfo->interfaceName );
+ detail::asyncCall< RetType >( callId, connectionState, false, funcName, std::move( callback ), args... );
+ }
+ };
+
+ /**
+ * @brief Helper class for calling a property
+ *
+ * Template type T defines type of the value hidden under property.
+ * Note, that library automatically wraps both sent and received value into
+ * DBUS's wrapper type.
+ */
+ template < typename T >
+ struct Property
+ {
+ /// \cond
+ using RetType = typename detail::dbus_interface_return_type_traits< T >::type;
+ using VariantRetType = typename detail::dbus_interface_return_type_traits< EldbusVariant< T > >::type;
+ const detail::ConnectionState &connectionState;
+ std::string propName;
+ std::string info;
+ std::shared_ptr< ConnectionInfo > connectionInfo;
+ /// \endcond
+
+ /**
+ * @brief executes synchronous get on property
+ *
+ * The function returns ValueOrError<...> object, which
+ * contains either received values or error message.
+ */
+ RetType get()
+ {
+ detail::CallId callId;
+ detail::displayDebugCallInfoProperty( callId, "Get", info, connectionInfo->interfaceName, propName );
+ auto z = detail::call< VariantRetType >( callId, connectionState, true, "Get", connectionInfo->interfaceName, propName );
+ if( !z )
+ return z.getError();
+ return {std::get< 0 >( z.getValues() ).value};
+ }
+
+ /**
+ * @brief executes asynchronous get on property
+ *
+ * The function calls callback with either received values or error message.
+ *
+ * @param callback callback functor, which will be called with return value(s) or error message
+ */
+ void asyncGet( std::function< void( RetType ) > callback )
+ {
+ detail::CallId callId;
+ detail::displayDebugCallInfoProperty( callId, "Get", info, connectionInfo->interfaceName, propName );
+ auto cc = [callback]( VariantRetType reply ) {
+ if( reply )
+ callback( std::move( std::get< 0 >( reply.getValues() ).value ) );
+ else
+ callback( reply.getError() );
+ };
+ detail::asyncCall< VariantRetType >( callId, connectionState, true, "Get", std::move( cc ), connectionInfo->interfaceName, propName );
+ }
+
+ /**
+ * @brief executes synchronous set on property
+ *
+ * The function returns ValueOrError<void> object, with
+ * possible error message.
+ */
+ ValueOrError< void > set( const T& r )
+ {
+ detail::CallId callId;
+ detail::displayDebugCallInfoProperty( callId, "Set", info, connectionInfo->interfaceName, propName );
+ EldbusVariant< T > variantValue{std::move( r )};
+ return detail::call< ValueOrError< void > >( callId, connectionState, true, "Set", connectionInfo->interfaceName, propName, variantValue );
+ }
+
+ /**
+ * @brief executes asynchronous get on property
+ *
+ * The function calls callback with either received values or error message.
+ *
+ * @param callback callback functor, which will be called with return value(s) or error message
+ */
+ void asyncSet( std::function< void( ValueOrError< void > ) > callback, const T& r )
+ {
+ detail::CallId callId;
+ detail::displayDebugCallInfoProperty( callId, "Set", info, connectionInfo->interfaceName, propName );
+ EldbusVariant< T > variantValue{std::move( r )};
+ detail::asyncCall< ValueOrError< void > >( callId, connectionState, true, "Set", std::move( callback ), connectionInfo->interfaceName, propName, variantValue );
+ }
+ };
+
+ /**
+ * @brief Constructs Property<...> object for calling properties
+ *
+ * The function constructs and returns proxy object for calling property.
+ *
+ * @param propName property name to set and / or query
+ */
+ template < typename PropertyType >
+ Property< PropertyType > property( std::string propName )
+ {
+ return Property< PropertyType >{*connectionState, std::move( propName ), info, connectionInfo};
+ }
+
+ /**
+ * @brief Constructs Method<...> object for calling methods
+ *
+ * The function constructs and returns proxy object for calling method.
+ *
+ * @param funcName function name to call
+ */
+ template < typename MethodType >
+ Method< MethodType > method( std::string funcName )
+ {
+ return Method< MethodType >{*connectionState, std::move( funcName ), info, connectionInfo};
+ }
+
+ /**
+ * @brief Registers notification callback, when property has changed
+ *
+ * The callback will be called with new value, when property's value has changed.
+ * Note, that template type V must match expected type, otherwise undefined behavior will occur,
+ * there's no check for this.
+ */
+ template < typename V >
+ void addPropertyChangedEvent( std::string propertyName, std::function< void( V ) > callback )
+ {
+ detail::CallId callId;
+ detail::displayDebugCallInfoSignal( callId, propertyName, info, connectionInfo->interfaceName );
+ DBUS_DEBUG( "call %d: adding property", callId.id );
+ auto &cI = this->connectionInfo;
+ DBUS_W->add_property_changed_event_listener_impl(connectionState->proxy, cI->interfaceName, propertyName,
+ [callback]( const _Eina_Value *newValue ) {
+ V val = 0;
+ if( !getFromEinaValue( newValue, &val ) )
+ {
+ DBUS_DEBUG( "unable to get property's value" );
+ return;
+ }
+ callback( val );
+ });
+ }
+
+ /**
+ * @brief Registers callback on the DBUS' signal
+ *
+ * The function registers callback signalName. When signal comes, callback will be called.
+ * Callback object will exists as long as signal is registered. You can unregister signal
+ * by destroying DBusClient object.
+ *
+ * @param signalName name of the signal to register
+ * @param callback callback to call
+ */
+ template < typename SignalType >
+ void addSignal( std::string signalName, std::function< SignalType > callback )
+ {
+ detail::CallId callId;
+ detail::displayDebugCallInfoSignal( callId, signalName, info, connectionInfo->interfaceName );
+ DBUS_W->eldbus_proxy_signal_handler_add_impl( connectionState->proxy, signalName,
+ [callId, callback, signalName]( const DBusWrapper::MessagePtr &msg ) -> void {
+ std::string errname, aux;
+ if( DBUS_W->eldbus_message_error_get_impl( msg, errname, aux ) )
+ {
+ DBUS_DEBUG( "call %d: Eldbus error: %s %s", callId.id, errname.c_str(), aux.c_str() );
+ return;
+ }
+ DBUS_DEBUG( "call %d: received signal with signature '%s'", callId.id, DBUS_W->eldbus_message_signature_get_impl( msg ).c_str() );
+ using ParamsType = typename detail::dbus_interface_traits< SignalType >::VEArgs;
+ auto params = detail::unpackValues< ParamsType >( callId, msg );
+ if( !params )
+ {
+ DBUS_DEBUG( "call %d: failed: %s", callId.id, params.getError().message.c_str() );
+ return;
+ }
+ try
+ {
+ detail::apply( callback, params.getValues() );
+ }
+ catch( ... )
+ {
+ DBUS_DEBUG( "unhandled exception" );
+ bart_assert( 0 );
+ }
+ });
+ }
+
+private:
+ /// \cond
+ std::unique_ptr<detail::ConnectionState> connectionState{ new detail::ConnectionState };
+ std::string info;
+ std::shared_ptr< ConnectionInfo > connectionInfo;
+
+ static bool getFromEinaValue(const _Eina_Value *v, void *dst);
+ /// \endcond
+};
+
+/**
+ * @brief Helper class describing DBUS's server interface
+ *
+ */
+class DBusInterfaceDescription
+{
+ friend class DBusServer;
+
+public:
+ /// \cond
+ using MethodInfo = DBusWrapper::MethodInfo;
+ using SignalInfo = DBusWrapper::SignalInfo;
+ using PropertyInfo = DBusWrapper::PropertyInfo;
+ using SignalId = DBusWrapper::SignalId;
+ /// \endcond
+
+ /**
+ * @brief Creates empty interface description with given name
+ *
+ * @param interfaceName name of the interface
+ */
+ DBusInterfaceDescription( std::string interfaceName );
+
+ /**
+ * @brief adds new, synchronous method to the interface
+ *
+ * When method memberName is called on DBUS, callback functor will be called
+ * with values received from DBUS. callback won't be called, if method was
+ * called with invalid signature. Value returned from functor (or error message)
+ * will be marshalled back to the caller.
+ *
+ * Template type T defines both arguments sent to the method
+ * and expected values. Receiving different values will be reported as
+ * error. For example:
+ * \code{.cpp} Method<int(float, float)> \endcode
+ * defines method, which takes two arguments (two floats) and return
+ * single value of type int.
+ *
+ * @param memberName name of the method
+ * @param callback functor, which will be called
+ */
+ template < typename T >
+ void addMethod( const std::string& memberName, typename detail::dbus_interface_traits< T >::SyncCB callback )
+ {
+ detail::CallId callId;
+ MethodInfo mi;
+ methods.push_back( std::move( mi ) );
+ auto& z = methods.back();
+ z.in = detail::EldbusArgGenerator_Args< T >::get( );
+ z.out = detail::EldbusArgGenerator_ReturnType< T >::get( );
+ z.memberName = memberName;
+ DBUS_DEBUG( "call %d: method %s, in %s, out %s", callId.id, memberName.c_str(),
+ detail::EldbusArgGenerator_Args< T >::name().c_str(),
+ detail::EldbusArgGenerator_ReturnType< T >::name().c_str() );
+ z.callback = construct< T >( callId, callback );
+ z.id = callId;
+ }
+
+ /**
+ * @brief adds new, synchronous property to the interface
+ *
+ * When property memberName is called on DBUS, respective callback functor will be called
+ * with values received from DBUS. callback won't be called, if method was
+ * called with invalid signature. Value returned from functor (or error message)
+ * will be marshalled back to the caller.
+ *
+ * Template type T defines type of the value hidden under property.
+ * Note, that library automatically wraps both sent and received value into
+ * DBUS's wrapper type.
+ *
+ * @param memberName name of the method
+ * @param getter functor, which will be called when property is being read
+ * @param setter functor, which will be called when property is being set
+ */
+ template < typename T >
+ void addProperty( const std::string& memberName, std::function< ValueOrError< T >() > getter, std::function< ValueOrError< void >( T ) > setter )
+ {
+ properties.push_back( {} );
+ auto& z = properties.back();
+ z.memberName = memberName;
+ z.typeSignature = detail::signature< T >::sig();
+ if( getter )
+ {
+ detail::CallId getterId;
+ z.getterId = getterId;
+ DBUS_DEBUG( "call %d: property %s (get) type %s", getterId.id, memberName.c_str(), detail::signature< T >::name().c_str() );
+ z.getCallback = [=]( const DBusWrapper::MessagePtr &src, const DBusWrapper::MessageIterPtr &dst ) -> std::string {
+ try
+ {
+ auto v = detail::apply( getter, std::tuple<>{} );
+ if( v )
+ {
+ detail::signature< T >::set( dst, std::get< 0 >( v.getValues() ) );
+ DBUS_DEBUG( "call %d: success", getterId.id );
+ return "";
+ }
+ DBUS_DEBUG( "call %d: failed: %s", getterId.id, v.getError().message.c_str() );
+ return v.getError().message;
+ }
+ catch( std::exception& e )
+ {
+ return std::string( "unhandled exception (" ) + e.what() + ")";
+ }
+ catch( ... )
+ {
+ return "unhandled exception";
+ }
+ };
+ }
+ if( setter )
+ {
+ detail::CallId setterId;
+ z.setterId = setterId;
+ DBUS_DEBUG( "call %d: property %s (set) type %s", setterId.id, memberName.c_str(), detail::signature< T >::name().c_str() );
+ z.setCallback = [=]( const DBusWrapper::MessagePtr &src, const DBusWrapper::MessageIterPtr &src_iter ) -> std::string {
+ std::tuple< T > value;
+ auto src_signature = DBUS_W->eldbus_message_iter_signature_get_impl( src_iter );
+ if( detail::signature< T >::get( src_iter, std::get< 0 >( value ) ) )
+ {
+ try
+ {
+ auto v = detail::apply( setter, std::move( value ) );
+ if( v )
+ {
+ DBUS_DEBUG( "call %d: success", setterId.id );
+ return "";
+ }
+ DBUS_DEBUG( "call %d: failed: %s", setterId.id, v.getError().message.c_str() );
+ return v.getError().message;
+ }
+ catch( std::exception& e )
+ {
+ return std::string( "unhandled exception (" ) + e.what() + ")";
+ }
+ catch( ... )
+ {
+ return "unhandled exception";
+ }
+ }
+ DBUS_DEBUG( "call %d: failed to unpack values, got signature '%s', expected '%s'", setterId.id,
+ src_signature.c_str(), detail::signature< T >::sig().c_str() );
+ return "call " + std::to_string( setterId.id ) + ": failed to unpack values, got signature '" +
+ src_signature + "', expected '" + detail::signature< T >::sig() + "'";
+ };
+ }
+ }
+
+ /**
+ * @brief adds new signal to the interface
+ *
+ * Template types ARGS defines values, which will be emited with the signal
+ *
+ * @param memberName name of the method
+ */
+ template < typename... ARGS >
+ SignalId addSignal( const std::string& memberName )
+ {
+ detail::CallId callId;
+ signals.push_back( {} );
+ auto& z = signals.back();
+ z.memberName = memberName;
+ z.args = detail::EldbusArgGenerator_Args< void( ARGS... ) >::get( DBUS_W->Strings );
+ z.id = callId;
+ DBUS_DEBUG( "call %d: signal %s", callId.id, memberName.c_str() );
+ return SignalId{callId};
+ }
+
+private:
+ /// \cond
+ std::vector< MethodInfo > methods;
+ std::vector< PropertyInfo > properties;
+ std::vector< SignalInfo > signals;
+ std::string interfaceName;
+
+ template < typename T >
+ std::function< DBusWrapper::MessagePtr( const DBusWrapper::MessagePtr &msg ) > construct( detail::CallId callId,
+ typename detail::dbus_interface_traits< T >::SyncCB callback )
+ {
+ using VEArgs = typename detail::dbus_interface_traits< T >::VEArgs;
+ return [=]( const DBusWrapper::MessagePtr &msg ) -> DBusWrapper::MessagePtr {
+ DBUS_DEBUG( "call %d: entering", callId.id );
+ DBusWrapper::MessagePtr ret = {};
+ auto args = detail::unpackValues< VEArgs >( callId, msg );
+ if( args )
+ {
+ try
+ {
+ auto v = detail::apply( callback, std::move( args.getValues() ) );
+ if( v )
+ {
+ DBUS_DEBUG( "call %d: success", callId.id );
+ ret = DBUS_W->eldbus_message_method_return_new_impl( msg );
+ detail::packValues( callId, ret, v );
+ }
+ else
+ {
+ DBUS_DEBUG( "call %d: failed: %s", callId.id, v.getError().message.c_str() );
+ ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.Failed", v.getError().message );
+ }
+ }
+ catch( std::exception& e )
+ {
+ auto txt = std::string( "unhandled exception (" ) + e.what() + ")";
+ DBUS_DEBUG( "call %d: failed: %s", callId.id, txt.c_str() );
+ ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.Failed", txt );
+ }
+ catch( ... )
+ {
+ DBUS_DEBUG( "call %d: failed: %s", callId.id, "unhandled exception" );
+ ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.Failed", "unhandled exception" );
+ }
+ }
+ else
+ {
+ std::ostringstream err;
+ err << "expected signature '" << detail::signature< VEArgs >::sig() << "', got '" << DBUS_W->eldbus_message_signature_get_impl( msg ) << "'";
+ auto str = err.str();
+ DBUS_DEBUG( "call %d: failed: %s", callId.id, str.c_str() );
+ ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.InvalidArgs", str );
+ }
+ return ret;
+ };
+ }
+ /// \endcond
+};
+
+/**
+ * @brief Class representing server's end of DBUS connection
+ *
+ * Allows listening (synchronously and asynchronosly) on methods on selected interface
+ * Allows listening (synchronously and asynchronosly) on setting / getting properties.
+ * Allows emiting signals.
+ */
+class DBusServer
+{
+public:
+ /**
+ * @brief Constructs non-connected dbus server.
+ */
+ DBusServer() = default;
+
+ /**
+ * @brief Constructs dbus server on either system or user dbus connection.
+ */
+ DBusServer( ConnectionType tp );
+
+ /**
+ * @brief Constructs dbus server on connection from getDBusConnectionByType
+ */
+ DBusServer( const DBusWrapper::ConnectionPtr &conn );
+
+ /**
+ * @brief Destructor
+ *
+ * Destructor will properly destroy everything. Destructor will cancel
+ * pending replies.
+ */
+ ~DBusServer() = default;
+
+ DBusServer( const DBusServer& ) = delete;
+ DBusServer( DBusServer&& ) = default;
+
+ DBusServer& operator=( DBusServer&& ) = default;
+ DBusServer& operator=( const DBusServer& ) = delete;
+
+ /**
+ * @brief Registers interface on given path name
+ *
+ * @param pathName path object to register interface on.
+ * @param dscr
+ * @param fallback
+ */
+ void addInterface( const std::string& pathName, DBusInterfaceDescription& dscr, bool fallback = false );
+
+ /**
+ * @brief Gets bus name of the current connection (must be connected)
+ */
+ std::string getBusName() const;
+
+ /**
+ * @brief Returns connection object for this dbus server object
+ *
+ * @return connection object
+ */
+ DBusWrapper::ConnectionPtr getConnection();
+
+ /**
+ * @brief Emits signal
+ *
+ * Emits signal based only on data passed to the function
+ *
+ * @param signal identifier of the signal
+ * @param args values to emit
+ */
+ template < typename... ARGS >
+ void emit2( const std::string& path, const std::string& interfaceName,
+ const std::string& signalName, const ARGS&... args )
+ {
+ auto msg = DBUS_W->eldbus_message_signal_new_impl( path, interfaceName, signalName );
+ detail::CallId id;
+ detail::packValues( id, msg, args... );
+ DBUS_W->eldbus_connection_send_impl( connection, msg );
+ }
+
+ /**
+ * @brief Returns current object path, when handling call to property / method
+ *
+ * User can call this function from inside callback used to handle property / method calls.
+ * It will retrieve object's path used in the call. Note, that in asynchronous handling
+ * of those calls user need to retrieve and store the current object / current connection
+ * as the value will change at the moment user's callback handling will exit. For example:
+ * \code{.cpp}
+ * DBusInterfaceDescription interface{"name"};
+ * auto handler_later = [](std::function<void(void)> done_cb) {
+ * // process something later on
+ * DBusServer::getCurrentObjectPath(); // this will return empty string
+ * };
+ * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
+ * DBusServer::getCurrentObjectPath(); // this will current object's path
+ *
+ * // do some processing later on and call done_cb, when it's done
+ * register_to_call_sometime_later_on(std::move(done_cb));
+ * };
+ * \endcode
+ */
+ static std::string getCurrentObjectPath() { return currentObjectPath; }
+
+ /**
+ * @brief Returns current connection object, when handling call to property / method
+ *
+ * User can call this function from inside callback used to handle property / method calls.
+ * It will retrieve object's path used in the call. Note, that in asynchronous handling
+ * of those calls user need to retrieve and store the current object / current connection
+ * as the value will change at the moment user's callback handling will exit. For example:
+ * \code{.cpp}
+ * DBusInterfaceDescription interface{"name"};
+ * auto handler_later = [](std::function<void(void)> done_cb) {
+ * // process something later on
+ * DBusServer::getCurrentObjectPath(); // this will return empty string
+ * };
+ * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
+ * DBusServer::getCurrentObjectPath(); // this will current object's path
+ *
+ * // do some processing later on and call done_cb, when it's done
+ * register_to_call_sometime_later_on(std::move(done_cb));
+ * };
+ * \endcode
+ */
+ static const DBusWrapper::ConnectionPtr &getCurrentConnection() { return currentConnection; }
+
+ /// \cond
+ class CurrentObjectSetter
+ {
+ public:
+ CurrentObjectSetter( DBusWrapper::ConnectionPtr con, std::string path )
+ {
+ currentObjectPath = std::move(path);
+ currentConnection = std::move( con );
+ }
+ ~CurrentObjectSetter()
+ {
+ currentObjectPath = "";
+ currentConnection = {};
+ }
+ CurrentObjectSetter( const CurrentObjectSetter& ) = delete;
+ CurrentObjectSetter( CurrentObjectSetter&& ) = delete;
+ void operator=( const CurrentObjectSetter& ) = delete;
+ void operator=( CurrentObjectSetter&& ) = delete;
+ };
+ /// \endcond
+
+private:
+ /// \cond
+ DBusWrapper::ConnectionPtr connection;
+ struct DestructorObject {
+ std::vector<std::function<void()>> destructors;
+ ~DestructorObject() {
+ for(auto &a : destructors) a();
+ }
+ };
+
+ std::unique_ptr<DestructorObject> destructorObject { new DestructorObject() };
+ static thread_local std::string currentObjectPath;
+ static thread_local DBusWrapper::ConnectionPtr currentConnection;
+
+ /// \endcond
+};
+
+/// \cond
+DBusWrapper::ConnectionPtr getDBusConnectionByType( ConnectionType tp );
+DBusWrapper::ConnectionPtr getDBusConnectionByName( const std::string& name );
+std::string getConnectionName( const DBusWrapper::ConnectionPtr& );
+/// \endcond
+}
+
+/// \cond
+namespace std
+{
+template < size_t INDEX, typename... ARGS >
+inline auto get( DBus::ValueOrError< ARGS... >& v ) -> decltype( std::get< INDEX >( v.getValues() ) ) &
+{
+ return std::get< INDEX >( v.getValues() );
+}
+
+template < size_t INDEX, typename... ARGS >
+inline auto get( const DBus::ValueOrError< ARGS... >& v ) -> decltype( std::get< INDEX >( v.getValues() ) )
+{
+ return std::get< INDEX >( v.getValues() );
+}
+}
+/// \endcond
+
+#endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
--- /dev/null
+/**
+ * Copyright (c) 2017 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Need to override adaptor classes for toolkit test harness, so include
+// test harness headers before dali headers.
+#include <dali-toolkit-test-suite-utils.h>
+
+#include <dali.h>
+#include <dali-toolkit/dali-toolkit.h>
+
+#include <dali/devel-api/adaptor-framework/accessibility.h>
+#include <dali/devel-api/adaptor-framework/accessibility-impl.h>
+
+#include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dbus-wrapper.h>
+
+void utc_dali_toolkit_accessibility_accessible_startup(void)
+{
+ test_return_value = TET_UNDEF;
+ DBusWrapper::Install(std::unique_ptr<DBusWrapper>(new TestDBusWrapper));
+}
+
+void utc_dali_toolkit_accessibility_accessible_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+int utcDaliAccessibilityCheckBoxButtonGetStates(void)
+{
+ ToolkitTestApplication application;
+
+ auto check_box_button = Toolkit::CheckBoxButton::New();
+ auto q = Dali::Accessibility::Accessible::Get( check_box_button );
+ DALI_TEST_CHECK( q );
+ auto states = q->GetStates();
+ DALI_TEST_EQUALS( (int) states[ Dali::Accessibility::State::SELECTABLE ], (int) true, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityCheckLabelText(void)
+{
+ ToolkitTestApplication application;
+
+ auto check_box_button = Toolkit::CheckBoxButton::New();
+ //check_box_button.SetLabelText( "button" );
+ check_box_button.SetProperty(Toolkit::Button::Property::LABEL, "button");
+ auto q = Dali::Accessibility::Accessible::Get( check_box_button );
+ DALI_TEST_CHECK( q );
+ DALI_TEST_EQUALS( q->GetName(), "button", TEST_LOCATION );
+
+ END_TEST;
+}
--- /dev/null
+#include <dali-toolkit-test-suite-utils.h>
+#include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/accessibility-test-utils.h>
+#include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dbus-wrapper.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali/devel-api/adaptor-framework/accessibility.h>
+#include <dali/devel-api/adaptor-framework/accessibility-impl.h>
+#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/devel-api/actors/actor-devel.h>
+#include <dali/devel-api/common/stage.h>
+#include <cstdlib>
+
+#include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dbus-wrapper.h>
+
+using namespace Dali::Toolkit;
+
+void utc_dali_accessibility_controls_bridge_up_startup(void)
+{
+ test_return_value = TET_UNDEF;
+ DBusWrapper::Install(std::unique_ptr<DBusWrapper>(new TestDBusWrapper));
+}
+
+void utc_dali_accessibility_controls_bridge_up_cleanup(void)
+{
+ test_return_value = TET_PASS;
+ //DBusWrapper::Install({}) is a de-install
+ DBusWrapper::Install({});
+}
+
+namespace Dali {
+ namespace Accessibility {
+ std::ostream & operator<< (std::ostream & stream, const Address & address)
+ {
+ stream << address.ToString();
+ return stream;
+ }
+ }
+}
+
+int UtcDaliControlAccessibilityRaiseBridge(void)
+{
+ DALI_TEST_CHECK(!Accessibility::IsUp());
+
+ ToolkitTestApplication application;
+
+ Dali::Accessibility::TestEnableSC(true);
+
+ DALI_TEST_CHECK(Accessibility::IsUp());
+
+ // auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+ // for(auto &a : wr->daliMethods) {
+ // const char *mt;
+ // if (std::get<3>(a.first) == MethodType::Method) mt = "MethodType::Method";
+ // else if (std::get<3>(a.first) == MethodType::Getter) mt = "MethodType::Getter";
+ // else if (std::get<3>(a.first) == MethodType::Setter) mt = "MethodType::Setter";
+ // else assert(0);
+ // printf("%s %s %s %s\n", std::get<0>(a.first).c_str(), std::get<1>(a.first).c_str(), std::get<2>(a.first).c_str(), mt);
+ // }
+
+ Dali::Accessibility::TestEnableSC(false);
+
+ DALI_TEST_CHECK(!Accessibility::IsUp());
+
+ END_TEST;
+}
+
+int UtcDaliControlAccessibilityName(void)
+{
+ ToolkitTestApplication application;
+
+ auto control = Control::New();
+ Stage::GetCurrent().Add( control );
+
+ auto q = Dali::Accessibility::Accessible::Get( control );
+ DALI_TEST_CHECK( q );
+
+ DALI_TEST_EQUALS( "" , q->GetName(), TEST_LOCATION );
+
+ control.SetProperty( DevelControl::Property::ACCESSIBILITY_NAME, "Accessibility_Name" );
+ DALI_TEST_EQUALS( "Accessibility_Name" , q->GetName(), TEST_LOCATION );
+ DALI_TEST_EQUALS( control.GetProperty( DevelControl::Property::ACCESSIBILITY_NAME ).Get< std::string >() , "Accessibility_Name", TEST_LOCATION );
+
+ DevelControl::AccessibilityGetNameSignal(control).Connect( [] (std::string &accessibility_name) {
+ accessibility_name = "Accessibility_Name_With_Callback"; } );
+
+ DALI_TEST_EQUALS( "Accessibility_Name_With_Callback" , q->GetName(), TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC(true);
+
+ DALI_TEST_EQUALS( "Accessibility_Name_With_Callback" , TestGetName( q->GetAddress()), TEST_LOCATION );
+
+ //TODO test emission of name change signal
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliControlAccessibilityDescription(void)
+{
+ ToolkitTestApplication application;
+
+ auto control = Control::New();
+
+ auto q = Dali::Accessibility::Accessible::Get( control );
+ DALI_TEST_CHECK( q );
+
+ DALI_TEST_EQUALS( "" , q->GetDescription(), TEST_LOCATION );
+
+ control.SetProperty( DevelControl::Property::ACCESSIBILITY_DESCRIPTION, "Accessibility_Description" );
+ DALI_TEST_EQUALS( "Accessibility_Description" , q->GetDescription(), TEST_LOCATION );
+
+ auto property = control.GetProperty( DevelControl::Property::ACCESSIBILITY_DESCRIPTION ).Get<std::string>();
+ DALI_TEST_EQUALS( "Accessibility_Description", property, TEST_LOCATION );
+
+ DevelControl::AccessibilityGetDescriptionSignal(control).Connect( [] (std::string &accessibility_description) {
+ accessibility_description = "Accessibility_Description_With_Callback"; } );
+
+ DALI_TEST_EQUALS( "Accessibility_Description_With_Callback" , q->GetDescription(), TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ DALI_TEST_EQUALS( "Accessibility_Description_With_Callback" , TestGetDescription( q->GetAddress()), TEST_LOCATION );
+
+ //TODO test emission of description change signal
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliControlAccessibilityRole(void)
+{
+ ToolkitTestApplication application;
+
+ auto control = Control::New();
+ auto role_unknown = Dali::Accessibility::Role::UNKNOWN;
+ auto role_pushbutton = Dali::Accessibility::Role::PUSH_BUTTON;
+
+ DALI_TEST_EQUALS( role_unknown,control.GetProperty( DevelControl::Property::ACCESSIBILITY_ROLE ).Get< Dali::Accessibility::Role >(), TEST_LOCATION );
+
+ auto q = Dali::Accessibility::Accessible::Get( control );
+ DALI_TEST_EQUALS( role_unknown , q->GetRole(), TEST_LOCATION);
+ DALI_TEST_EQUALS( "unknown" , q->GetRoleName(), TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( true );
+ DALI_TEST_CHECK( q );
+ DALI_TEST_EQUALS( static_cast< uint32_t >( role_unknown ), TestGetRole( q->GetAddress() ), TEST_LOCATION );
+ DALI_TEST_EQUALS( "unknown" , TestGetRoleName( q->GetAddress() ), TEST_LOCATION );
+ DALI_TEST_EQUALS( "unknown" , TestGetLocalizedRoleName( q->GetAddress() ), TEST_LOCATION );
+
+ control.SetProperty( DevelControl::Property::ACCESSIBILITY_ROLE, role_pushbutton );
+
+ DALI_TEST_EQUALS( static_cast< uint32_t >( role_pushbutton ), TestGetRole( q->GetAddress() ), TEST_LOCATION );
+ DALI_TEST_EQUALS( "push button" ,TestGetRoleName( q->GetAddress() ), TEST_LOCATION );
+ DALI_TEST_EQUALS( "push button" , TestGetLocalizedRoleName( q->GetAddress() ), TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ DALI_TEST_EQUALS( role_pushbutton , q->GetRole(), TEST_LOCATION);
+ DALI_TEST_EQUALS( "push button" , q->GetRoleName(), TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliControlAccessibilityRoleToggleButton(void)
+{
+ ToolkitTestApplication application;
+
+ auto control = Dali::Toolkit::ToggleButton::New();
+ auto button = Dali::Accessibility::Role::TOGGLE_BUTTON;
+
+ control.SetProperty(Toolkit::ToggleButton::Property::TOOLTIPS,
+ Property::Array{"option1", "option2"});
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ control.SetProperty( DevelControl::Property::ACCESSIBILITY_ROLE, button );
+ auto q = Dali::Accessibility::Accessible::Get( control );
+
+ DALI_TEST_EQUALS( button , q->GetRole(), TEST_LOCATION);
+ DALI_TEST_EQUALS( "toggle button" , q->GetRoleName(), TEST_LOCATION );
+
+ Dali::Accessibility::States states = q->GetStates();
+ DALI_TEST_EQUALS( true , (bool)states[Dali::Accessibility::State::VISIBLE], TEST_LOCATION);
+
+ DALI_TEST_EQUALS( "option1", q->GetDescription(), TEST_LOCATION );
+
+ auto i = dynamic_cast<Dali::Accessibility::Component*>(q);
+ if (i)
+ i->GrabHighlight();
+
+ control.SetProperty( Toolkit::Button::Property::LABEL, "ToggleButton2" );
+ DALI_TEST_EQUALS( "ToggleButton2", TestGetName( q->GetAddress() ), TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliControlAccessibilityButtonLabel(void)
+{
+ ToolkitTestApplication application;
+
+ auto control = Dali::Toolkit::PushButton::New();
+ auto button = Dali::Accessibility::Role::PUSH_BUTTON;
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ control.SetProperty( DevelControl::Property::ACCESSIBILITY_ROLE, button );
+
+ auto q = Dali::Accessibility::Accessible::Get( control );
+ auto i = dynamic_cast<Dali::Accessibility::Component*>(q);
+
+ if (i)
+ i->GrabHighlight();
+
+ control.SetProperty( Toolkit::Button::Property::LABEL, "Button2" );
+
+ DALI_TEST_EQUALS( "Button2" , TestGetName( q->GetAddress() ), TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliControlAccessibilityState(void)
+{
+ ToolkitTestApplication application;
+
+ auto control = Control::New();
+ auto q = Dali::Accessibility::Accessible::Get( control );
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto states_by_bridge = Dali::Accessibility::States { TestGetStates( q->GetAddress() )};
+ auto states = DevelControl::GetAccessibilityStates(control);
+ DALI_TEST_CHECK( states_by_bridge == states );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliControlAccessibilityModal(void)
+{
+ ToolkitTestApplication application;
+
+ auto control = Dali::Toolkit::Popup::New();
+ auto q = Dali::Accessibility::Accessible::Get( control );
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto states_by_bridge = Dali::Accessibility::States { TestGetStates( q->GetAddress() )};
+ DALI_TEST_CHECK( states_by_bridge[Dali::Accessibility::State::MODAL] );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliControlAccessibilityHighlightable(void)
+{
+ ToolkitTestApplication application;
+ auto control = Control::New();
+
+ auto noneset = control.GetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE );
+ DALI_TEST_EQUALS( Property::NONE, noneset.GetType(), TEST_LOCATION );
+
+ // negative testcase - trying to set unconvertible value
+ control.SetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, "deadbeef" );
+ noneset = control.GetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE );
+ DALI_TEST_EQUALS( Property::NONE, noneset.GetType(), TEST_LOCATION );
+
+ auto q = Dali::Accessibility::Accessible::Get( control );
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto states_by_bridge = Dali::Accessibility::States { TestGetStates( q->GetAddress() )};
+ DALI_TEST_CHECK( !states_by_bridge[ Dali::Accessibility::State::HIGHLIGHTABLE ] );
+
+ control.SetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true );
+ DALI_TEST_EQUALS( Property::BOOLEAN, control.GetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE ).GetType(), TEST_LOCATION );
+ DALI_TEST_EQUALS( true, control.GetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE ).Get< bool >(), TEST_LOCATION );
+
+ states_by_bridge = Dali::Accessibility::States { TestGetStates( q->GetAddress() )};
+ DALI_TEST_CHECK( states_by_bridge[ Dali::Accessibility::State::HIGHLIGHTABLE ] );
+
+ control.SetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, false );
+ DALI_TEST_EQUALS( Property::BOOLEAN, control.GetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE ).GetType(), TEST_LOCATION );
+ DALI_TEST_EQUALS( false, control.GetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE ).Get< bool >(), TEST_LOCATION );
+
+ states_by_bridge = Dali::Accessibility::States { TestGetStates( q->GetAddress() )};
+ DALI_TEST_CHECK( !states_by_bridge[ Dali::Accessibility::State::HIGHLIGHTABLE ] );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliControlAccessibilityHighlightBridgeUp(void)
+{
+ ToolkitTestApplication application;
+
+ auto controla = Control::New();
+ auto controlb = Control::New();
+ controla.Add(controlb);
+
+ controla.SetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true );
+ controlb.SetProperty( DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true );
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto accessible_a = Dali::Accessibility::Accessible::Get( controla );
+ auto accessible_b = Dali::Accessibility::Accessible::Get( controlb );
+
+ auto a = dynamic_cast<Dali::Accessibility::Component*>( accessible_a );
+ auto b = dynamic_cast<Dali::Accessibility::Component*>( accessible_b );
+
+ auto states_by_bridge_a = Dali::Accessibility::States { TestGetStates( a->GetAddress() )};
+ auto states_by_bridge_b = Dali::Accessibility::States { TestGetStates( b->GetAddress() )};
+
+ DALI_TEST_CHECK( !states_by_bridge_a[ Dali::Accessibility::State::HIGHLIGHTED ] );
+ DALI_TEST_CHECK( !states_by_bridge_b[ Dali::Accessibility::State::HIGHLIGHTED ] );
+
+ DALI_TEST_EQUALS( true, DevelControl::GrabAccessibilityHighlight(controla), TEST_LOCATION );
+
+ states_by_bridge_a = Dali::Accessibility::States { TestGetStates( a->GetAddress() )};
+ states_by_bridge_b = Dali::Accessibility::States { TestGetStates( b->GetAddress() )};
+
+ DALI_TEST_CHECK( states_by_bridge_a[ Dali::Accessibility::State::HIGHLIGHTED ] );
+ DALI_TEST_CHECK( !states_by_bridge_b[ Dali::Accessibility::State::HIGHLIGHTED ] );
+
+ DALI_TEST_EQUALS( true, DevelControl::GrabAccessibilityHighlight(controlb), TEST_LOCATION );
+ DALI_TEST_EQUALS( true, DevelControl::GrabAccessibilityHighlight(controlb), TEST_LOCATION );
+
+ states_by_bridge_a = Dali::Accessibility::States { TestGetStates( a->GetAddress() )};
+ states_by_bridge_b = Dali::Accessibility::States { TestGetStates( b->GetAddress() )};
+
+ DALI_TEST_CHECK( !states_by_bridge_a[ Dali::Accessibility::State::HIGHLIGHTED ] );
+ DALI_TEST_CHECK( states_by_bridge_b[ Dali::Accessibility::State::HIGHLIGHTED ] );
+
+ DALI_TEST_EQUALS( false, DevelControl::ClearAccessibilityHighlight(controla), TEST_LOCATION );
+
+ states_by_bridge_a = Dali::Accessibility::States { TestGetStates( a->GetAddress() )};
+ states_by_bridge_b = Dali::Accessibility::States { TestGetStates( b->GetAddress() )};
+
+ DALI_TEST_CHECK( !states_by_bridge_a[ Dali::Accessibility::State::HIGHLIGHTED ] );
+ DALI_TEST_CHECK( states_by_bridge_b[ Dali::Accessibility::State::HIGHLIGHTED ] );
+
+ DALI_TEST_EQUALS( true, DevelControl::ClearAccessibilityHighlight(controlb), TEST_LOCATION );
+
+ states_by_bridge_a = Dali::Accessibility::States { TestGetStates( a->GetAddress() )};
+ states_by_bridge_b = Dali::Accessibility::States { TestGetStates( b->GetAddress() )};
+
+ DALI_TEST_CHECK( !states_by_bridge_a[ Dali::Accessibility::State::HIGHLIGHTED ] );
+ DALI_TEST_CHECK( !states_by_bridge_b[ Dali::Accessibility::State::HIGHLIGHTED ] );
+
+ DALI_TEST_CHECK( TestGrabHighlight( a -> GetAddress() ) );
+
+ states_by_bridge_a = Dali::Accessibility::States { TestGetStates( a->GetAddress() )};
+ states_by_bridge_b = Dali::Accessibility::States { TestGetStates( b->GetAddress() )};
+
+ DALI_TEST_CHECK( states_by_bridge_a[ Dali::Accessibility::State::HIGHLIGHTED ] );
+ DALI_TEST_CHECK( !states_by_bridge_b[ Dali::Accessibility::State::HIGHLIGHTED ] );
+
+ DALI_TEST_CHECK( TestGrabHighlight( b -> GetAddress() ) );
+
+ states_by_bridge_a = Dali::Accessibility::States { TestGetStates( a->GetAddress() )};
+ states_by_bridge_b = Dali::Accessibility::States { TestGetStates( b->GetAddress() )};
+
+ DALI_TEST_CHECK( !states_by_bridge_a[ Dali::Accessibility::State::HIGHLIGHTED ] );
+ DALI_TEST_CHECK( states_by_bridge_b[ Dali::Accessibility::State::HIGHLIGHTED ] );
+
+ DALI_TEST_CHECK( TestClearHighlight( b -> GetAddress() ) );
+
+ states_by_bridge_a = Dali::Accessibility::States { TestGetStates( a->GetAddress() )};
+ states_by_bridge_b = Dali::Accessibility::States { TestGetStates( b->GetAddress() )};
+
+ DALI_TEST_CHECK( !states_by_bridge_a[ Dali::Accessibility::State::HIGHLIGHTED ] );
+ DALI_TEST_CHECK( !states_by_bridge_b[ Dali::Accessibility::State::HIGHLIGHTED ] );
+
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityControlAttributes(void)
+{
+ ToolkitTestApplication application;
+ auto check_box_button = Toolkit::Control::New();
+
+ std::string value;
+
+
+ auto attributes = check_box_button.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES );
+ auto attributes_map = attributes.GetMap();
+
+ auto position = attributes_map->Find( "access_key1" );
+ DALI_TEST_CHECK( !position );
+
+ DevelControl::AppendAccessibilityAttribute( check_box_button, "access_key1", "access_value1" );
+ attributes = check_box_button.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES );
+ attributes_map = attributes.GetMap();
+
+ DALI_TEST_EQUALS( (attributes_map->Find( "access_key1" ))->Get<std::string>(), "access_value1", TEST_LOCATION );
+
+ DevelControl::AppendAccessibilityAttribute( check_box_button, "access_key2", "access_value2_a" );
+ attributes = check_box_button.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES );
+ attributes_map = attributes.GetMap();
+
+ DALI_TEST_EQUALS( (attributes_map->Find( "access_key1" ))->Get<std::string>(), "access_value1", TEST_LOCATION );
+ DALI_TEST_EQUALS( (attributes_map->Find( "access_key2" ))->Get<std::string>(), "access_value2_a", TEST_LOCATION );
+
+ DevelControl::AppendAccessibilityAttribute( check_box_button, "access_key2", "access_value2_b" );
+ attributes = check_box_button.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES );
+ attributes_map = attributes.GetMap();
+
+ DALI_TEST_EQUALS( (attributes_map->Find( "access_key2" ))->Get<std::string>(), "access_value2_b", TEST_LOCATION );
+
+ DevelControl::RemoveAccessibilityAttribute( check_box_button, "access_key2" );
+ attributes = check_box_button.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES );
+ attributes_map = attributes.GetMap();
+
+ // In case when we are removing one of attributes the property is setting for NONE type.
+ DALI_TEST_EQUALS( (attributes_map->Find( "access_key2" ))->GetType(), Property::NONE, TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto ptr = Dali::Accessibility::Accessible::Get( check_box_button );
+ auto attribute_map_bridge = TestGetAttributes( ptr->GetAddress() );
+ auto counter = 0u;
+ for (auto i = 0u; i<attributes_map->Count();++i)
+ if((attributes_map->GetValue(i)).GetType() != Property::NONE )
+ ++counter;
+
+ DALI_TEST_EQUALS( counter, attribute_map_bridge.size(), TEST_LOCATION );
+
+ for (auto it : attribute_map_bridge)
+ DALI_TEST_EQUALS( (attributes_map->Find( it.first ))->Get<std::string>(), it.second, TEST_LOCATION );
+
+ DevelControl::ClearAccessibilityAttributes(check_box_button);
+ attributes = check_box_button.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES );
+ attributes_map = attributes.GetMap();
+
+ position = attributes_map->Find( "access_key1" );
+ DALI_TEST_CHECK( !position );
+
+ position = attributes_map->Find( "access_key2" );
+ DALI_TEST_CHECK( !position );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliControlReadingInfoType(void)
+{
+ ToolkitTestApplication application;
+ auto control = Control::New();
+
+ auto reading_info_type = DevelControl::GetAccessibilityReadingInfoType(control);
+ reading_info_type[Dali::Accessibility::ReadingInfoType::DESCRIPTION] = true;
+ reading_info_type[Dali::Accessibility::ReadingInfoType::STATE] = true;
+ reading_info_type[Dali::Accessibility::ReadingInfoType::NAME] = true;
+ reading_info_type[Dali::Accessibility::ReadingInfoType::ROLE] = true;
+
+ DevelControl::SetAccessibilityReadingInfoType(control, reading_info_type);
+
+ auto q = control.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES );
+ auto z = q.GetMap();
+
+ DALI_TEST_EQUALS( (z->Find( "reading_info_type" ))->Get<std::string>(), "name|role|description|state", TEST_LOCATION );
+ reading_info_type = DevelControl::GetAccessibilityReadingInfoType(control);
+ for ( auto i = 0u; i < 4; ++i)
+ DALI_TEST_CHECK ( reading_info_type[ static_cast< Dali::Accessibility::ReadingInfoType >( i ) ]);
+
+ END_TEST;
+}
+
+int UtcDaliControlDoGesture(void)
+{
+ ToolkitTestApplication application;
+ auto control = Control::New();
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( control );
+ auto gesture_one = Dali::Accessibility::GestureInfo { Dali::Accessibility::Gesture::ONE_FINGER_FLICK_LEFT, 600, 100, 500, 500, Dali::Accessibility::GestureState::BEGIN, 1000 };
+ auto gesture_two = Dali::Accessibility::GestureInfo { Dali::Accessibility::Gesture::ONE_FINGER_FLICK_RIGHT, 600, 100, 500, 500, Dali::Accessibility::GestureState::BEGIN, 1000 };
+
+ DALI_TEST_CHECK( !accessible->DoGesture( gesture_one ) );
+ DALI_TEST_CHECK( !TestDoGesture( accessible->GetAddress(), Dali::Accessibility::Gesture::ONE_FINGER_FLICK_LEFT, 600, 100, 500, 500, Dali::Accessibility::GestureState::BEGIN, 1000 ) );
+
+ DevelControl::AccessibilityDoGestureSignal(control).Connect( [] ( std::pair< Dali::Accessibility::GestureInfo, bool > &gesture ) {
+ if ( gesture.first.type == Dali::Accessibility::Gesture::ONE_FINGER_FLICK_LEFT )
+ gesture.second = true;
+ else
+ gesture.second = false;
+ } );
+
+ DALI_TEST_CHECK( accessible->DoGesture( gesture_one ) );
+ DALI_TEST_CHECK( TestDoGesture( accessible->GetAddress(), Dali::Accessibility::Gesture::ONE_FINGER_FLICK_LEFT, 600, 100, 500, 500, Dali::Accessibility::GestureState::BEGIN, 1000 ) );
+
+ DALI_TEST_CHECK( !accessible->DoGesture( gesture_two ) );
+ DALI_TEST_CHECK( !TestDoGesture( accessible->GetAddress(), Dali::Accessibility::Gesture::ONE_FINGER_FLICK_RIGHT, 600, 100, 500, 500, Dali::Accessibility::GestureState::BEGIN, 1000 ) );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityRelation(void)
+{
+ ToolkitTestApplication application;
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto rel = Accessibility::RelationType::FLOWS_TO;
+ auto number = static_cast< size_t >( rel );
+ auto control = Control::New();
+ auto destination1 = Control::New();
+ auto destination2 = Control::New();
+
+ DevelControl::AppendAccessibilityRelation( control, destination1, rel );
+ auto relations = DevelControl::GetAccessibilityRelations(control);
+ DALI_TEST_CHECK( relations[ number ].size() == 1 );
+
+ DevelControl::AppendAccessibilityRelation( control, destination2, rel );
+ relations = DevelControl::GetAccessibilityRelations(control);
+ DALI_TEST_CHECK( relations[ number ].size() == 2 );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( control );
+ auto accessible_destination1 = Dali::Accessibility::Accessible::Get( destination1 );
+ auto accessible_destination2 = Dali::Accessibility::Accessible::Get( destination2 );
+ auto relationset = accessible->GetRelationSet();
+
+ DALI_TEST_CHECK( relationset[0].relationType == rel );
+ DALI_TEST_CHECK( relationset[0].targets[0] == accessible_destination1->GetAddress() || relationset[0].targets[1] == accessible_destination1->GetAddress() );
+ DALI_TEST_CHECK( relationset[0].targets[0] == accessible_destination2->GetAddress() || relationset[0].targets[1] == accessible_destination2->GetAddress() );
+
+ auto relationset_bridge = TestGetRelationSet( accessible -> GetAddress() );
+ DALI_TEST_CHECK( static_cast< uint32_t >( relationset[0].relationType ) == std::get<0>( relationset_bridge[0] ) );
+
+ DALI_TEST_CHECK( relationset[0].targets[0] == std::get<1>( relationset_bridge[0] )[0] || relationset[0].targets[1] == std::get<1>( relationset_bridge[0] )[0] );
+ DALI_TEST_CHECK( relationset[0].targets[0] == std::get<1>( relationset_bridge[0] )[1] || relationset[0].targets[1] == std::get<1>( relationset_bridge[0] )[1] );
+
+ DevelControl::RemoveAccessibilityRelation(control,destination2,rel);
+ relations = DevelControl::GetAccessibilityRelations(control);
+ DALI_TEST_CHECK( relations[ number ].size() == 1 );
+
+ DevelControl::ClearAccessibilityRelations(control);
+ relations = DevelControl::GetAccessibilityRelations(control);
+ DALI_TEST_CHECK( relations[ number ].size() == 0 );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityParentChildren(void)
+{
+ ToolkitTestApplication application;
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto parent = Control::New();
+ auto child_1 = Control::New();
+ auto child_2 = Control::New();
+
+ auto parent_accessible = Dali::Accessibility::Accessible::Get( parent );
+ auto child_1_accessible = Dali::Accessibility::Accessible::Get( child_1 );
+ auto child_2_accessible = Dali::Accessibility::Accessible::Get( child_2 );
+
+ auto children = TestGetChildren( parent_accessible -> GetAddress() );
+ DALI_TEST_EQUALS( children.size(), 0, TEST_LOCATION );
+
+ try
+ {
+ TestGetIndexInParent( child_1_accessible -> GetAddress() );
+ DALI_ABORT("Object has parent, test abort");
+ }
+ catch(TestDBusWrapper::error &){}
+
+ try
+ {
+ TestGetChildAtIndex( parent_accessible -> GetAddress(), -1 );
+ DALI_ABORT("Positive index, test abort");
+ }
+ catch(TestDBusWrapper::error &){}
+
+ DALI_TEST_EQUALS( parent_accessible -> GetChildCount(), 0, TEST_LOCATION );
+
+ try
+ {
+ child_1_accessible -> GetIndexInParent();
+ DALI_ABORT("Object has parent, test abort");
+ }
+ catch (Dali::DaliException &){}
+
+ parent.Add(child_1);
+ parent.Add(child_2);
+
+ children = TestGetChildren( parent_accessible -> GetAddress() );
+ DALI_TEST_EQUALS( children.size(), 2, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( parent_accessible -> GetAddress(), TestGetParent( child_1_accessible -> GetAddress() ), TEST_LOCATION );
+ DALI_TEST_EQUALS( child_2_accessible -> GetAddress(), TestGetChildAtIndex( parent_accessible -> GetAddress(), TestGetIndexInParent( child_2_accessible -> GetAddress() ) ), TEST_LOCATION );
+
+ DALI_TEST_EQUALS( parent_accessible, child_1_accessible -> GetParent(), TEST_LOCATION );
+ DALI_TEST_EQUALS( child_2_accessible, parent_accessible -> GetChildAtIndex( child_2_accessible -> GetIndexInParent() ) , TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityGetLayer(void)
+{
+ ToolkitTestApplication application;
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto control = Control::New();
+ auto accessible_obj = Dali::Accessibility::Accessible::Get( control );
+ auto accessible_component = dynamic_cast<Dali::Accessibility::Component*>(accessible_obj);
+ DALI_TEST_CHECK( accessible_component );
+ DALI_TEST_EQUALS( Dali::Accessibility::ComponentLayer::WINDOW, accessible_component -> GetLayer(), TEST_LOCATION );
+ DALI_TEST_EQUALS( Dali::Accessibility::ComponentLayer::WINDOW, TestGetLayer( accessible_component -> GetAddress() ), TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityGrabFocus(void)
+{
+ ToolkitTestApplication application;
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto controla = Control::New();
+ auto controlb = Control::New();
+
+ Stage::GetCurrent().Add( controla );
+ Stage::GetCurrent().Add( controlb );
+
+ controla.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
+ controlb.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
+
+ auto a = Dali::Accessibility::Accessible::Get( controla );
+ auto b = Dali::Accessibility::Accessible::Get( controlb );
+
+ auto a_component = dynamic_cast<Dali::Accessibility::Component*>( a );
+ auto b_component = dynamic_cast<Dali::Accessibility::Component*>( b );
+
+ auto states_by_bridge_a = Dali::Accessibility::States { TestGetStates( a_component -> GetAddress() )};
+ auto states_by_bridge_b = Dali::Accessibility::States { TestGetStates( b_component -> GetAddress() )};
+
+ DALI_TEST_CHECK( !states_by_bridge_a[ Dali::Accessibility::State::FOCUSED ] );
+ DALI_TEST_CHECK( !states_by_bridge_b[ Dali::Accessibility::State::FOCUSED ] );
+
+ DALI_TEST_CHECK( a_component -> GrabFocus() );
+
+ states_by_bridge_a = Dali::Accessibility::States { TestGetStates( a_component -> GetAddress() )};
+ states_by_bridge_b = Dali::Accessibility::States { TestGetStates( b_component -> GetAddress() )};
+
+ DALI_TEST_CHECK( states_by_bridge_a[ Dali::Accessibility::State::FOCUSED ] );
+ DALI_TEST_CHECK( !states_by_bridge_b[ Dali::Accessibility::State::FOCUSED ] );
+
+ DALI_TEST_CHECK( TestGrabFocus( b_component -> GetAddress() ) );
+
+ states_by_bridge_a = Dali::Accessibility::States { TestGetStates( a_component -> GetAddress() )};
+ states_by_bridge_b = Dali::Accessibility::States { TestGetStates( b_component -> GetAddress() )};
+
+ DALI_TEST_CHECK( !states_by_bridge_a[ Dali::Accessibility::State::FOCUSED ] );
+ DALI_TEST_CHECK( states_by_bridge_b[ Dali::Accessibility::State::FOCUSED ] );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityGetExtents(void)
+{
+ ToolkitTestApplication application;
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto control = Control::New();
+ Stage::GetCurrent().GetRootLayer().Add( control );
+
+ control.SetProperty(Actor::Property::POSITION, Vector3(10, 10, 100));
+ control.SetProperty(Actor::Property::SIZE, Vector2(10, 10));
+
+ application.SendNotification();
+ application.Render( 1 );
+
+ auto a = Dali::Accessibility::Accessible::Get( control );
+ auto a_component = dynamic_cast<Dali::Accessibility::Component*>( a );
+
+ auto extents = a_component->GetExtents(Dali::Accessibility::CoordType::SCREEN);
+ DALI_TEST_EQUALS( extents.x, 5.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( extents.y, 5.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( extents.height, 10.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( extents.width, 10.0f, TEST_LOCATION );
+
+ auto bridge_extents = TestGetExtents( a_component -> GetAddress() );
+ DALI_TEST_EQUALS( std::get< 0 >( bridge_extents ), 5, TEST_LOCATION );
+ DALI_TEST_EQUALS( std::get< 1 >( bridge_extents ), 5, TEST_LOCATION );
+ DALI_TEST_EQUALS( std::get< 2 >( bridge_extents ), 10, TEST_LOCATION );
+ DALI_TEST_EQUALS( std::get< 3 >( bridge_extents ), 10, TEST_LOCATION );
+
+ control.SetProperty( Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT, false );
+ application.SendNotification();
+ application.Render( 1 );
+
+ extents = a_component->GetExtents(Dali::Accessibility::CoordType::SCREEN);
+ DALI_TEST_EQUALS( extents.x, 10.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( extents.y, 10.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( extents.height, 10.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( extents.width, 10.0f, TEST_LOCATION );
+
+ bridge_extents = TestGetExtents( a_component -> GetAddress() );
+ DALI_TEST_EQUALS( std::get< 0 >( bridge_extents ), 10, TEST_LOCATION );
+ DALI_TEST_EQUALS( std::get< 1 >( bridge_extents ), 10, TEST_LOCATION );
+ DALI_TEST_EQUALS( std::get< 2 >( bridge_extents ), 10, TEST_LOCATION );
+ DALI_TEST_EQUALS( std::get< 3 >( bridge_extents ), 10, TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityGetAlpha(void)
+{
+ ToolkitTestApplication application;
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto control = Control::New();
+ auto a = Dali::Accessibility::Accessible::Get( control );
+ auto a_component = dynamic_cast<Dali::Accessibility::Component*>( a );
+
+ DALI_TEST_EQUALS( 0.0, a_component -> GetAlpha(), TEST_LOCATION );
+ DALI_TEST_EQUALS( 0.0, TestGetAlpha( a_component -> GetAddress() ), TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityGetMdiZOrder(void)
+{
+ ToolkitTestApplication application;
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto control = Control::New();
+ auto a = Dali::Accessibility::Accessible::Get( control );
+ auto a_component = dynamic_cast<Dali::Accessibility::Component*>( a );
+
+ DALI_TEST_EQUALS( 0, static_cast< int >( a_component -> GetMdiZOrder() ), TEST_LOCATION );
+ DALI_TEST_EQUALS( 0, TestGetMdiZOrder( a_component -> GetAddress() ), TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityAction(void)
+{
+ ToolkitTestApplication application;
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto control = Control::New( );
+ auto a = Dali::Accessibility::Accessible::Get( control );
+ auto b = dynamic_cast<Dali::Accessibility::Action*>( a );
+
+ std::vector< std::string > actions { "activate", "accessibilityActivated", "ReadingSkipped", "ReadingCancelled", "ReadingStopped", "ReadingPaused", "ReadingResumed", "show", "hide" };
+ auto count = b -> GetActionCount();
+
+ DALI_TEST_EQUALS( count, 9, TEST_LOCATION );
+
+ for (auto i = 0u; i<count; ++i)
+ {
+ DALI_TEST_CHECK( Dali::Accessibility::Find( actions, b -> GetActionName( i ) ) );
+ DALI_TEST_EQUALS( b -> GetActionName( i ), b -> GetLocalizedActionName( i ), TEST_LOCATION );
+ DALI_TEST_EQUALS( b -> GetActionDescription( i ), "", TEST_LOCATION );
+ DALI_TEST_EQUALS( b -> GetActionKeyBinding( i ), "", TEST_LOCATION );
+ }
+
+ // Empty strings should be returned for invalid indices
+ DALI_TEST_EQUALS(b->GetActionDescription(count), "", TEST_LOCATION);
+ DALI_TEST_EQUALS(b->GetActionName(count), "", TEST_LOCATION);
+ DALI_TEST_EQUALS(b->GetLocalizedActionName(count), "", TEST_LOCATION);
+ DALI_TEST_EQUALS(b->GetActionKeyBinding(count), "", TEST_LOCATION);
+
+ count = TestGetActionCount(b -> GetAddress());
+
+ DALI_TEST_EQUALS( count, 9, TEST_LOCATION );
+
+ for (auto i = 0u; i<count; ++i)
+ {
+ DALI_TEST_CHECK( Dali::Accessibility::Find( actions, TestGetActionName( b->GetAddress(), i ) ) );
+ DALI_TEST_EQUALS( TestGetActionName( b->GetAddress(), i ), TestGetLocalizedActionName( b->GetAddress(), i ), TEST_LOCATION );
+ DALI_TEST_EQUALS( TestGetActionDescription( b->GetAddress(), i ), "", TEST_LOCATION );
+ DALI_TEST_EQUALS( TestGetActionKeyBinding( b->GetAddress(), i ), "", TEST_LOCATION );
+ }
+
+ DALI_TEST_EQUALS(TestGetActionDescription(b->GetAddress(), count), "", TEST_LOCATION);
+ DALI_TEST_EQUALS(TestGetActionName(b->GetAddress(), count), "", TEST_LOCATION);
+ DALI_TEST_EQUALS(TestGetLocalizedActionName(b->GetAddress(), count), "", TEST_LOCATION);
+ DALI_TEST_EQUALS(TestGetActionKeyBinding(b->GetAddress(), count), "", TEST_LOCATION);
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityDoAction(void)
+{
+ ToolkitTestApplication application;
+
+ Dali::Accessibility::TestEnableSC( true );
+ thread_local std::vector< bool > actions_done { false, false, false, false, false, false };
+
+ auto control = Control::New( );
+ auto a = Dali::Accessibility::Accessible::Get( control );
+ auto b = dynamic_cast<Dali::Accessibility::Action*>( a );
+ std::vector< std::string > actions { "activate", "accessibilityActivated", "ReadingSkipped", "ReadingCancelled", "ReadingStopped", "ReadingPaused", "ReadingResumed", "show", "hide" };
+
+ // Test calling action by name
+ DALI_TEST_CHECK( b -> DoAction( actions[2] ) ); // ReadingSkipped
+ DALI_TEST_CHECK( b -> DoAction( actions[4] ) ); // ReadingStopped
+ DALI_TEST_CHECK( b -> DoAction( actions[4] ) ); // ReadingStopped
+
+ // Negative test of calling action with not defined name
+ DALI_TEST_CHECK( !b -> DoAction( "undefined" ) );
+
+ DevelControl::AccessibilityReadingSkippedSignal(control).Connect( [] () {
+ actions_done[ 1 ] = true;
+ } );
+ DevelControl::AccessibilityReadingCancelledSignal(control).Connect( [] () {
+ actions_done[ 2 ] = true;
+ } );
+ DevelControl::AccessibilityReadingStoppedSignal(control).Connect( [] () {
+ actions_done[ 3 ] = true;
+ } );
+ DevelControl::AccessibilityReadingPausedSignal(control).Connect( [] () {
+ actions_done[ 4 ] = true;
+ } );
+ DevelControl::AccessibilityReadingResumedSignal(control).Connect( [] () {
+ actions_done[ 5 ] = true;
+ } );
+ DevelControl::AccessibilityActivateSignal(control).Connect( [] () {
+ actions_done[ 0 ] = true;
+ } );
+
+ // Test calling action by index
+ DALI_TEST_CHECK( b -> DoAction( 1 ) );
+ DALI_TEST_CHECK( b -> DoAction( 2 ) );
+ DALI_TEST_CHECK( b -> DoAction( 3 ) );
+ DALI_TEST_CHECK( b -> DoAction( 4 ) );
+ DALI_TEST_CHECK( b -> DoAction( 5 ) );
+ DALI_TEST_CHECK( b -> DoAction( 6 ) );
+
+ for ( auto i = 0u; i < actions_done.size(); ++i )
+ {
+ DALI_TEST_CHECK( actions_done[ i ] );
+ actions_done[ i ] = false;
+ }
+
+ DALI_TEST_CHECK( TestDoAction( b -> GetAddress(), 1 ) );
+ DALI_TEST_CHECK( TestDoAction( b -> GetAddress(), 2 ) );
+ DALI_TEST_CHECK( TestDoAction( b -> GetAddress(), 3 ) );
+ DALI_TEST_CHECK( TestDoAction( b -> GetAddress(), 4 ) );
+ DALI_TEST_CHECK( TestDoAction( b -> GetAddress(), 5 ) );
+ DALI_TEST_CHECK( TestDoAction( b -> GetAddress(), 6 ) );
+
+ for ( auto i = 0u; i < actions_done.size(); ++i )
+ {
+ DALI_TEST_CHECK( actions_done[ i ] );
+ actions_done[ i ] = false;
+ }
+
+ DALI_TEST_CHECK( TestDoAction( b -> GetAddress(), actions[ 1 ] ) );
+ DALI_TEST_CHECK( TestDoAction( b -> GetAddress(), actions[ 2 ] ) );
+ DALI_TEST_CHECK( TestDoAction( b -> GetAddress(), actions[ 3 ] ) );
+ DALI_TEST_CHECK( TestDoAction( b -> GetAddress(), actions[ 4 ] ) );
+ DALI_TEST_CHECK( TestDoAction( b -> GetAddress(), actions[ 5 ] ) );
+ DALI_TEST_CHECK( TestDoAction( b -> GetAddress(), actions[ 6 ] ) );
+
+ for ( auto i = 0u; i < actions_done.size(); ++i )
+ DALI_TEST_CHECK( actions_done[ i ] );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+void TestVoidCallback()
+{
+}
+
+int UtcDaliAccessibilitySignals(void)
+{
+ ToolkitTestApplication application;
+ ConnectionTracker connectionTracker;
+ Control control = Control::New();
+
+ DALI_TEST_CHECK( DevelControl::AccessibilityGetNameSignal(control).Empty() );
+ control.ConnectSignal( &connectionTracker, "getName", &TestVoidCallback );
+ DALI_TEST_CHECK( !DevelControl::AccessibilityGetNameSignal(control).Empty() );
+
+ DALI_TEST_CHECK( DevelControl::AccessibilityGetDescriptionSignal(control).Empty() );
+ control.ConnectSignal( &connectionTracker, "getDescription", &TestVoidCallback );
+ DALI_TEST_CHECK( !DevelControl::AccessibilityGetDescriptionSignal(control).Empty() );
+
+ DALI_TEST_CHECK( DevelControl::AccessibilityDoGestureSignal(control).Empty() );
+ control.ConnectSignal( &connectionTracker, "doGesture", &TestVoidCallback );
+ DALI_TEST_CHECK( !DevelControl::AccessibilityDoGestureSignal(control).Empty() );
+
+ END_TEST;
+}
--- /dev/null
+#include <dali-toolkit-test-suite-utils.h>
+#include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/accessibility-test-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/controls/table-view/table-view.h>
+#include <dali/devel-api/adaptor-framework/accessibility-impl.h>
+
+#include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dbus-wrapper.h>
+
+using namespace Dali::Toolkit;
+
+void utc_dali_accessibility_controls_startup(void)
+{
+ test_return_value = TET_UNDEF;
+ DBusWrapper::Install(std::unique_ptr<DBusWrapper>(new TestDBusWrapper));
+}
+
+void utc_dali_accessibility_controls_cleanup(void)
+{
+ test_return_value = TET_PASS;
+ //DBusWrapper::Install({}) is a de-install
+ DBusWrapper::Install({});
+}
+
+int UtcDaliControlPropertyAccessibilityTranslationDomain(void)
+{
+ ToolkitTestApplication application;
+
+ auto control = Control::New();
+
+ auto accessibility_translation_domain = DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN;
+ DALI_TEST_EQUALS( Property::NONE , control.GetProperty( accessibility_translation_domain ).GetType(), TEST_LOCATION );
+
+ control.SetProperty( accessibility_translation_domain, "translation_domain_test_1" );
+ DALI_TEST_EQUALS( "translation_domain_test_1" , control.GetProperty( accessibility_translation_domain ).Get< std::string >(), TEST_LOCATION );
+
+ control.SetProperty( accessibility_translation_domain, "translation_domain_test_2" );
+ DALI_TEST_EQUALS( "translation_domain_test_2" , control.GetProperty( accessibility_translation_domain ).Get< std::string >(), TEST_LOCATION );
+
+ END_TEST;
+}
+
+// This test shows that when the accessibility bridge is
+// not up, there is no possibility to grab or clear highlight
+int UtcDaliControlAccessibilityHighlight(void)
+{
+ ToolkitTestApplication application;
+ auto controla = Control::New();
+ auto controlb = Control::New();
+
+ DALI_TEST_EQUALS( false, DevelControl::GrabAccessibilityHighlight(controla), TEST_LOCATION );
+ DALI_TEST_EQUALS( false, DevelControl::GrabAccessibilityHighlight(controlb), TEST_LOCATION );
+ DALI_TEST_EQUALS( false, DevelControl::ClearAccessibilityHighlight(controla), TEST_LOCATION );
+ DALI_TEST_EQUALS( false, DevelControl::ClearAccessibilityHighlight(controlb), TEST_LOCATION );
+
+ END_TEST;
+}
+
+#include <dali-toolkit/devel-api/controls/tool-bar/tool-bar.h>
+int UtcDaliAccessibilityToolBarConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto toolbar = ToolBar::New();
+ DALI_TEST_CHECK( toolbar );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( toolbar );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::TOOL_BAR, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityPushButtonConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto pushbutton = PushButton::New();
+ DALI_TEST_CHECK( pushbutton );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( pushbutton );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::PUSH_BUTTON, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityPushButtonStates(void)
+{
+ ToolkitTestApplication application;
+
+ auto pushbutton = PushButton::New();
+ DALI_TEST_CHECK( pushbutton );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( pushbutton );
+ DALI_TEST_CHECK( accessible );
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto states = accessible->GetStates();
+ DALI_TEST_EQUALS( static_cast< unsigned int >( states[ Accessibility::State::PRESSED ] ), false, TEST_LOCATION );
+
+ // auto button = dynamic_cast<Dali::Toolkit::Button* >( accessible ) ;
+ pushbutton.SetProperty( Toolkit::Button::Property::TOGGLABLE, true );
+ pushbutton.SetProperty( Toolkit::Button::Property::SELECTED, true );
+
+ states = accessible->GetStates();
+ DALI_TEST_EQUALS( static_cast< unsigned int >( states[ Accessibility::State::PRESSED ] ), true, TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+#include <dali-toolkit/devel-api/controls/buttons/toggle-button.h>
+int UtcDaliAccessibilityToggleButtonConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto togglebutton = ToggleButton::New();
+ DALI_TEST_CHECK( togglebutton );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( togglebutton );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::TOGGLE_BUTTON, TEST_LOCATION );
+
+ END_TEST;
+}
+
+#include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup.h>
+int UtcDaliAccessibilityTextSelectionPopupConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto textselectionpopup = TextSelectionPopup::New( NULL );
+ DALI_TEST_CHECK( textselectionpopup );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( textselectionpopup );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::DIALOG, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityAlignmentConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto alignment = Alignment::New();
+ DALI_TEST_CHECK( alignment );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( alignment );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::FILLER, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityRadioButtonStates(void)
+{
+ ToolkitTestApplication application;
+
+ auto radiobutton = RadioButton::New();
+ DALI_TEST_CHECK( radiobutton );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( radiobutton );
+ DALI_TEST_CHECK( accessible );
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto states = accessible->GetStates();
+ DALI_TEST_CHECK( states );
+ DALI_TEST_EQUALS( static_cast< unsigned int >( states[ Accessibility::State::CHECKED ] ), false, TEST_LOCATION );
+ radiobutton.SetProperty( Toolkit::RadioButton::Property::SELECTED, true );
+ states = accessible->GetStates();
+ DALI_TEST_CHECK( states );
+ DALI_TEST_EQUALS( static_cast< unsigned int >( states[ Accessibility::State::CHECKED ] ), true, TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityFlexContainerConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto flexcontainer = FlexContainer::New();
+ DALI_TEST_CHECK( flexcontainer );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( flexcontainer );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::FILLER, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityCheckBoxButton(void)
+{
+ ToolkitTestApplication application;
+
+ auto checkboxbutton = CheckBoxButton::New();
+ DALI_TEST_CHECK( checkboxbutton );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( checkboxbutton );
+ DALI_TEST_CHECK( accessible );
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ auto states = accessible->GetStates();
+ DALI_TEST_EQUALS( static_cast< unsigned int >( states[ Accessibility::State::CHECKED ] ), false, TEST_LOCATION );
+ checkboxbutton.SetProperty( Toolkit::CheckBoxButton::Property::SELECTED, true );
+ states = accessible->GetStates();
+ DALI_TEST_EQUALS( static_cast< unsigned int >( states[ Accessibility::State::CHECKED ] ), true, TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+#include <dali-toolkit/devel-api/controls/text-controls/text-selection-toolbar.h>
+int UtcDaliAccessibilityTextSelectionConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto textselectiontoolbar = TextSelectionToolbar::New();
+ DALI_TEST_CHECK( textselectiontoolbar );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( textselectiontoolbar );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::TOOL_BAR, TEST_LOCATION );
+
+ END_TEST;
+}
+
+#include <dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.h>
+int UtcDaliAccessibilityManager(void)
+{
+ using attr = Toolkit::AccessibilityManager::AccessibilityAttribute;
+
+ ToolkitTestApplication application;
+
+ Dali::Accessibility::TestEnableSC(true);
+
+ auto accessmanager = new Dali::Toolkit::Internal::AccessibilityManager;
+ auto actor = Control::New();
+
+ const std::string name = "Name";
+ const std::string descr = "Description";
+
+ accessmanager->SetAccessibilityAttribute(actor, attr::ACCESSIBILITY_LABEL, name);
+ DALI_TEST_EQUALS( accessmanager->GetAccessibilityAttribute(actor, attr::ACCESSIBILITY_LABEL), name, TEST_LOCATION );
+ DALI_TEST_EQUALS( actor.GetProperty<std::string>(DevelControl::Property::ACCESSIBILITY_NAME), name, TEST_LOCATION );
+
+ accessmanager->SetAccessibilityAttribute(actor, attr::ACCESSIBILITY_TRAIT, "Whatever");
+ DALI_TEST_EQUALS( accessmanager->GetAccessibilityAttribute(actor, attr::ACCESSIBILITY_TRAIT), "", TEST_LOCATION );
+
+ accessmanager->SetAccessibilityAttribute(actor, attr::ACCESSIBILITY_VALUE, "Whatever");
+ DALI_TEST_EQUALS( accessmanager->GetAccessibilityAttribute(actor, attr::ACCESSIBILITY_VALUE), "", TEST_LOCATION );
+
+ accessmanager->SetAccessibilityAttribute(actor, attr::ACCESSIBILITY_HINT, descr);
+ DALI_TEST_EQUALS( accessmanager->GetAccessibilityAttribute(actor, attr::ACCESSIBILITY_HINT), descr, TEST_LOCATION );
+ DALI_TEST_EQUALS( actor.GetProperty<std::string>(DevelControl::Property::ACCESSIBILITY_DESCRIPTION), descr, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( accessmanager->GetFocusOrder(actor), 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( accessmanager->GenerateNewFocusOrder(), 1, TEST_LOCATION );
+
+ accessmanager->SetFocusOrder({}, 0);
+ accessmanager->SetFocusOrder(Control::New(), 1);
+ accessmanager->SetFocusOrder(actor, 2);
+ accessmanager->SetFocusOrder(Control::New(), 3);
+
+ DALI_TEST_EQUALS( accessmanager->GetFocusOrder(actor), 2, TEST_LOCATION );
+ DALI_TEST_EQUALS( accessmanager->GetActorByFocusOrder(2), actor, TEST_LOCATION );
+
+ accessmanager->SetCurrentFocusActor(actor);
+ DALI_TEST_EQUALS( accessmanager->GetCurrentFocusActor(), actor, TEST_LOCATION );
+ DALI_TEST_EQUALS( accessmanager->GetCurrentFocusOrder(), 2, TEST_LOCATION );
+
+ accessmanager->MoveFocusForward();
+ accessmanager->MoveFocusBackward();
+ DALI_TEST_EQUALS( accessmanager->GetCurrentFocusActor(), actor, TEST_LOCATION );
+ accessmanager->SetCurrentFocusActor({});
+
+ accessmanager->Reset();
+ accessmanager->MoveFocusBackward();
+ accessmanager->MoveFocusForward();
+
+ accessmanager->GetCurrentFocusGroup();
+ DALI_TEST_EQUALS( accessmanager->IsFocusGroup(actor), false, TEST_LOCATION );
+ accessmanager->GetFocusGroup(actor);
+
+ DALI_TEST_EQUALS( accessmanager->GetGroupMode(), false, TEST_LOCATION );
+ DALI_TEST_EQUALS( accessmanager->GetWrapMode(), true, TEST_LOCATION );
+
+ auto vector = accessmanager->GetReadPosition();
+ DALI_TEST_EQUALS( vector.x, 0.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( vector.y, 0.0f, TEST_LOCATION );
+
+ accessmanager->SetFocusIndicatorActor(Dali::Actor{});
+ accessmanager->GetFocusIndicatorActor();
+
+ Dali::Accessibility::TestEnableSC(false);
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityModel3dViewConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto model3dview = Model3dView::New();
+ DALI_TEST_CHECK( model3dview );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( model3dview );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::IMAGE, TEST_LOCATION );
+
+ END_TEST;
+}
+
+#include <dali-toolkit/internal/controls/effects-view/effects-view-impl.h>
+int UtcDaliAccessibilityEffectsViewConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto etype = Dali::Toolkit::EffectsView::EffectType::DROP_SHADOW;
+ auto effectsview = EffectsView::New( etype );
+ DALI_TEST_CHECK( effectsview );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( effectsview );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::FILLER, TEST_LOCATION );
+
+ END_TEST;
+}
+
+#include <dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.h>
+int UtcDaliAccessibilitySuperBlurViewConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto superblurview = SuperBlurView::New( 1 );
+ DALI_TEST_CHECK( superblurview );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( superblurview );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::FILLER, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityImageViewConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto imageview = ImageView::New();
+ DALI_TEST_CHECK( imageview );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( imageview );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::IMAGE, TEST_LOCATION );
+
+ END_TEST;
+}
+
+#include <dali-toolkit/devel-api/controls/page-turn-view/page-factory.h>
+class TestPageFactory : public PageFactory
+{
+public:
+
+ TestPageFactory( bool returnValidTexture = true )
+ : mValidTexture( returnValidTexture )
+ {
+ mTotalPageNumber = 100;
+ }
+
+ /**
+ * Query the number of pages available from the factory.
+ * The maximum available page has an ID of GetNumberOfPages()-1.
+ */
+ virtual unsigned int GetNumberOfPages()
+ {
+ return mTotalPageNumber;
+ }
+
+ /**
+ * Create an texture to represent a page content.
+ * @param[in] pageId The ID of the page to create.
+ * @return An image, or an empty handle if the ID is out of range.
+ */
+ virtual Texture NewPage( unsigned int pageId )
+ {
+ if( mValidTexture )
+ {
+ return Texture::New( Dali::TextureType::TEXTURE_2D, Pixel::RGB888, 100, 100 );
+ }
+ return Texture(); // empty handle
+ }
+
+private:
+ unsigned int mTotalPageNumber;
+ bool mValidTexture;
+};
+
+#include <dali-toolkit/internal/controls/page-turn-view/page-turn-landscape-view-impl.h>
+int UtcDaliAccessibilityPageTurnViewConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto testpagefactory = TestPageFactory();
+ auto vector2 = Vector2( 1.0, 1.0 );
+ auto pageturnlandscapeview = PageTurnLandscapeView::New( testpagefactory, vector2 );
+ DALI_TEST_CHECK( pageturnlandscapeview );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( pageturnlandscapeview );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::PAGE_TAB_LIST, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityGaussianBlurViewConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto gaussianblurview = GaussianBlurView::New();
+ DALI_TEST_CHECK( gaussianblurview );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( gaussianblurview );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::FILLER, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityShadowViewConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto shadowview = ShadowView::New();
+ DALI_TEST_CHECK( shadowview );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( shadowview );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::FILLER, TEST_LOCATION );
+
+ END_TEST;
+}
+
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.h>
+int UtcDaliAccessibilityScrollableConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto scrollview = ScrollView::New();
+ DALI_TEST_CHECK( scrollview );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( scrollview );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::SCROLL_PANE, TEST_LOCATION );
+
+ END_TEST;
+}
+
+#include <dali-toolkit/internal/controls/magnifier/magnifier-impl.h>
+int UtcDaliAccessibilityMagnifierConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto magnifier = Magnifier::New();
+ DALI_TEST_CHECK( magnifier );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( magnifier );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::FILLER, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityTableViewConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto tableview = TableView::New( 10, 10 );
+ DALI_TEST_CHECK( tableview );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( tableview );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::TABLE, TEST_LOCATION );
+
+ END_TEST;
+}
+
+#include <dali-toolkit/internal/controls/bloom-view/bloom-view-impl.h>
+int UtcDaliAccessibilityBloomViewConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto bloomview = BloomView::New();
+ DALI_TEST_CHECK( bloomview );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( bloomview );
+ DALI_TEST_CHECK( accessible );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::ANIMATION, TEST_LOCATION );
+
+ END_TEST;
+}
+
+#include <dali-toolkit/internal/controls/text-controls/text-field-impl.h>
+int UtcDaliAccessibilityTextField(void)
+{
+ ToolkitTestApplication application;
+
+ auto textfield = TextField::New();
+ DALI_TEST_CHECK( textfield );
+
+ textfield.SetProperty(Actor::Property::NAME, "test" );
+ DALI_TEST_EQUALS( textfield.GetProperty<std::string>(Actor::Property::NAME), "test", TEST_LOCATION );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( textfield );
+ DALI_TEST_CHECK( accessible );
+
+ DALI_TEST_EQUALS( accessible->GetName(), "", TEST_LOCATION );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::ENTRY, TEST_LOCATION );
+ auto states = accessible->GetStates();
+ DALI_TEST_EQUALS( static_cast< unsigned int >( states[ Accessibility::State::EDITABLE ] ), true, TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ textfield.SetProperty( Toolkit::TextField::Property::TEXT, "test" );
+ auto text = dynamic_cast< Dali::Accessibility::Text* >( accessible );
+ DALI_TEST_CHECK( text );
+ DALI_TEST_EQUALS( text->GetText( 0, 10 ), "", TEST_LOCATION );
+ DALI_TEST_EQUALS( text->SetCaretOffset(100), false, TEST_LOCATION );
+ DALI_TEST_EQUALS( text->SetCaretOffset(2), true, TEST_LOCATION );
+ DALI_TEST_EQUALS( text->GetCaretOffset(), 2, TEST_LOCATION );
+
+ auto editabletext = dynamic_cast< Dali::Accessibility::EditableText* >( accessible );
+ DALI_TEST_CHECK( editabletext );
+ DALI_TEST_EQUALS( editabletext->CopyText( 3, 1 ), false, TEST_LOCATION );
+ DALI_TEST_EQUALS( editabletext->CopyText( 1, 3 ), true, TEST_LOCATION );
+ DALI_TEST_EQUALS( editabletext->CutText( 3, 1 ), false, TEST_LOCATION );
+ DALI_TEST_EQUALS( editabletext->CutText( 1, 3 ), true, TEST_LOCATION );
+ DALI_TEST_EQUALS( text->GetText( 0, 1 ), "t", TEST_LOCATION );
+
+ auto range = text->GetSelection( 1 );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.content, "", TEST_LOCATION );
+ DALI_TEST_EQUALS( text->SetSelection( 1, 0, 1 ), false, TEST_LOCATION );
+ DALI_TEST_EQUALS( text->RemoveSelection( 1 ), false, TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+#include <dali-toolkit/internal/controls/text-controls/text-editor-impl.h>
+int UtcDaliAccessibilityTextEditor(void)
+{
+ ToolkitTestApplication application;
+
+ auto texteditor = TextEditor::New();
+ DALI_TEST_CHECK( texteditor );
+
+ texteditor.SetProperty(Actor::Property::NAME, "test" );
+ DALI_TEST_EQUALS( texteditor.GetProperty<std::string>(Actor::Property::NAME), "test", TEST_LOCATION );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( texteditor );
+ DALI_TEST_CHECK( accessible );
+
+ DALI_TEST_EQUALS( accessible->GetName(), "", TEST_LOCATION );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::ENTRY, TEST_LOCATION );
+ auto states = accessible->GetStates();
+ DALI_TEST_EQUALS( static_cast< unsigned int >( states[ Accessibility::State::EDITABLE ] ), true, TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ texteditor.SetProperty( Toolkit::TextEditor::Property::TEXT, "test" );
+ auto text = dynamic_cast< Dali::Accessibility::Text* >( accessible );
+ DALI_TEST_CHECK( text );
+ DALI_TEST_EQUALS( text->GetText( 0, 10 ), "", TEST_LOCATION );
+ DALI_TEST_EQUALS( text->SetCaretOffset(100), false, TEST_LOCATION );
+ DALI_TEST_EQUALS( text->SetCaretOffset(2), true, TEST_LOCATION );
+ DALI_TEST_EQUALS( text->GetCaretOffset(), 2, TEST_LOCATION );
+
+ auto editabletext = dynamic_cast< Dali::Accessibility::EditableText* >( accessible );
+ DALI_TEST_CHECK( editabletext );
+ DALI_TEST_EQUALS( editabletext->CopyText( 3, 1 ), false, TEST_LOCATION );
+ DALI_TEST_EQUALS( editabletext->CopyText( 1, 3 ), true, TEST_LOCATION );
+ DALI_TEST_EQUALS( editabletext->CutText( 3, 1 ), false, TEST_LOCATION );
+ DALI_TEST_EQUALS( editabletext->CutText( 1, 3 ), true, TEST_LOCATION );
+ DALI_TEST_EQUALS( text->GetText( 0, 1 ), "t", TEST_LOCATION );
+
+ auto range = text->GetSelection( 1 );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.content, "", TEST_LOCATION );
+ DALI_TEST_EQUALS( text->SetSelection( 1, 0, 1 ), false, TEST_LOCATION );
+ DALI_TEST_EQUALS( text->RemoveSelection( 1 ), false, TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityTextLabel(void)
+{
+ ToolkitTestApplication application;
+
+ auto textlabel = TextLabel::New();
+ DALI_TEST_CHECK( textlabel );
+
+ textlabel.SetProperty(Actor::Property::NAME, "test" );
+ DALI_TEST_EQUALS( textlabel.GetProperty<std::string>(Actor::Property::NAME), "test", TEST_LOCATION );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( textlabel );
+ DALI_TEST_CHECK( accessible );
+
+ DALI_TEST_EQUALS( accessible->GetName(), "test", TEST_LOCATION );
+ DALI_TEST_EQUALS( accessible->GetRole(), Accessibility::Role::LABEL, TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( true );
+
+ textlabel.SetProperty( Toolkit::TextLabel::Property::TEXT, "test" );
+ auto text = dynamic_cast< Dali::Accessibility::Text* >( accessible );
+ DALI_TEST_CHECK( text );
+ DALI_TEST_EQUALS( text->GetText( 0, 10 ), "", TEST_LOCATION );
+ DALI_TEST_EQUALS( text->GetText( 0, 4 ), "test", TEST_LOCATION );
+ DALI_TEST_EQUALS( text->SetCaretOffset(0), false, TEST_LOCATION );
+ DALI_TEST_EQUALS( text->GetCaretOffset(), 0, TEST_LOCATION );
+
+ auto range = text->GetSelection( 1 );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.content, "", TEST_LOCATION );
+ DALI_TEST_EQUALS( text->SetSelection( 1, 0, 1 ), false, TEST_LOCATION );
+ DALI_TEST_EQUALS( text->RemoveSelection( 1 ), false, TEST_LOCATION );
+
+ Dali::Accessibility::TestEnableSC( false );
+
+ END_TEST;
+}
+
+#include <dali-toolkit/internal/controls/navigation-view/navigation-view-impl.h>
+int UtcDaliAccessibilityNavigationViewConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto navigationview = NavigationView::New();
+ DALI_TEST_CHECK( navigationview );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( navigationview );
+ DALI_TEST_CHECK( accessible );
+
+ DALI_TEST_EQUALS( accessible->GetRole(), Dali::Accessibility::Role::FILLER, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliAccessibilityVideoViewConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ auto videoview = VideoView::New();
+ DALI_TEST_CHECK( videoview );
+
+ auto accessible = Dali::Accessibility::Accessible::Get( videoview );
+ DALI_TEST_CHECK( accessible );
+
+ DALI_TEST_EQUALS( accessible->GetRole(), Dali::Accessibility::Role::VIDEO, TEST_LOCATION );
+
+ END_TEST;
+}
--- /dev/null
+/**
+ * Copyright (c) 2017 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Need to override adaptor classes for toolkit test harness, so include
+// test harness headers before dali headers.
+#include <dali-toolkit-test-suite-utils.h>
+
+#include <dali.h>
+#include <dali-toolkit/dali-toolkit.h>
+
+#include <dali/devel-api/adaptor-framework/accessibility.h>
+#include <dali-toolkit/internal/controls/text-controls/text-editor-impl.h>
+
+#include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dbus-wrapper.h>
+
+void utc_dali_toolkit_accessibility_text_startup(void)
+{
+ test_return_value = TET_UNDEF;
+ DBusWrapper::Install(std::unique_ptr<DBusWrapper>(new TestDBusWrapper));
+}
+
+void utc_dali_toolkit_accessibility_text_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+int utcDaliAccessibilityTextEditorGetName(void)
+{
+ ToolkitTestApplication application;
+
+ auto editor = Dali::Toolkit::TextEditor::New();
+ DALI_TEST_EQUALS( editor.GetProperty<std::string>(Actor::Property::NAME), "", TEST_LOCATION );
+ editor.SetProperty(Actor::Property::NAME, "editor");
+ DALI_TEST_EQUALS( editor.GetProperty<std::string>(Actor::Property::NAME), "editor", TEST_LOCATION );
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityTextEditorGetText(void)
+{
+ ToolkitTestApplication application;
+
+ auto editor = Dali::Toolkit::TextEditor::New();
+ auto q = Dali::Accessibility::Accessible::Get( editor );
+ auto x = dynamic_cast< Dali::Accessibility::Text* >( q );
+ DALI_TEST_CHECK( x );
+ if( x )
+ {
+ DALI_TEST_EQUALS( x->GetText( 0, 0 ), "", TEST_LOCATION );
+ editor.SetProperty( Toolkit::TextEditor::Property::TEXT, "exemplary_text" );
+ DALI_TEST_EQUALS( x->GetText( 0, 9 ), "exemplary", TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityTextEditorGetCharacterCount(void)
+{
+ ToolkitTestApplication application;
+
+ auto editor = Dali::Toolkit::TextEditor::New();
+ auto q = Dali::Accessibility::Accessible::Get( editor );
+ auto x = dynamic_cast< Dali::Accessibility::Text* >( q );
+ DALI_TEST_CHECK( x );
+ if( x )
+ {
+ DALI_TEST_EQUALS( x->GetCharacterCount(), 0, TEST_LOCATION );
+ editor.SetProperty( Toolkit::TextEditor::Property::TEXT, "editor" );
+ DALI_TEST_EQUALS( x->GetCharacterCount(), 6, TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityTextEditorGetTextAtOffset(void)
+{
+ ToolkitTestApplication application;
+
+ auto editor = Dali::Toolkit::TextEditor::New();
+ auto q = Dali::Accessibility::Accessible::Get( editor );
+ auto x = dynamic_cast< Dali::Accessibility::Text* >( q );
+ DALI_TEST_CHECK( x );
+ if( x )
+ {
+ auto range = x->GetTextAtOffset( 0, Dali::Accessibility::TextBoundary::LINE );
+ DALI_TEST_EQUALS( range.content, "", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+
+ editor.SetProperty( Toolkit::TextEditor::Property::TEXT, "text editor test sentence" );
+ range = x->GetTextAtOffset( 5, Dali::Accessibility::TextBoundary::CHARACTER );
+ DALI_TEST_EQUALS( range.content, "e", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 5, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 6, TEST_LOCATION );
+
+ editor.SetProperty( Toolkit::TextEditor::Property::TEXT, "text \n\n\n\n\n\n editor \n\n test sentence" );
+ range = x->GetTextAtOffset( 3, Dali::Accessibility::TextBoundary::WORD );
+ DALI_TEST_EQUALS( range.content, "sentence", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 28, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 36, TEST_LOCATION );
+
+ editor.SetProperty( Toolkit::TextEditor::Property::TEXT, "text \n\n\n\n\n\n editor \n\n test sentence" );
+ range = x->GetTextAtOffset( 4, Dali::Accessibility::TextBoundary::WORD );
+ DALI_TEST_EQUALS( range.content, "", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+
+ editor.SetProperty( Toolkit::TextEditor::Property::TEXT, "text \n\n\n\n\n\n editor \n\n test sentence" );
+ range = x->GetTextAtOffset( 0, Dali::Accessibility::TextBoundary::LINE );
+ DALI_TEST_EQUALS( range.content, "text \n", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 9, TEST_LOCATION );
+
+ editor.SetProperty( Toolkit::TextEditor::Property::TEXT, "text \n\n\n\n\n\n editor \n\n test sentence" );
+ range = x->GetTextAtOffset( 6, Dali::Accessibility::TextBoundary::LINE );
+ DALI_TEST_EQUALS( range.content, " editor \n", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 14, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 24, TEST_LOCATION );
+
+ editor.SetProperty( Toolkit::TextEditor::Property::TEXT, "text \n\n\n\n\n\n editor \n\n test sentence" );
+ range = x->GetTextAtOffset( 8, Dali::Accessibility::TextBoundary::LINE );
+ DALI_TEST_EQUALS( range.content, " test sentence", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 25, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 39, TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityTextEditorGetSetSelection(void)
+{
+ ToolkitTestApplication application;
+
+ auto editor = Dali::Toolkit::TextEditor::New();
+ auto q = Dali::Accessibility::Accessible::Get( editor );
+ auto x = dynamic_cast< Dali::Accessibility::Text* >( q );
+ DALI_TEST_CHECK( x );
+ if( x )
+ {
+ auto range = x->GetSelection( 0 );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.content, "", TEST_LOCATION );
+
+ x->SetSelection( 0, 4, 9 );
+ editor.SetProperty( Toolkit::TextEditor::Property::TEXT, "exemplary_text" );
+ range = x->GetSelection( 0 );
+
+ DALI_TEST_EQUALS( range.startOffset, 4, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 9, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.content, "plary", TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityTextEditorRemoveSelection(void)
+{
+ ToolkitTestApplication application;
+
+ auto editor = Dali::Toolkit::TextEditor::New();
+ auto q = Dali::Accessibility::Accessible::Get( editor );
+ auto x = dynamic_cast< Dali::Accessibility::Text* >( q );
+ DALI_TEST_CHECK( x );
+ if( x )
+ {
+ auto range = x->GetSelection( 0 );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+
+ x->SetSelection( 0, 4, 9 );
+ range = x->GetSelection( 0 );
+ DALI_TEST_EQUALS( range.startOffset, 4, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 9, TEST_LOCATION );
+
+ x->RemoveSelection( 0 );
+ range = x->GetSelection( 0 );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityTextFieldGetName(void)
+{
+ ToolkitTestApplication application;
+
+ auto field = Toolkit::TextField::New();
+ DALI_TEST_EQUALS( field.GetProperty<std::string>(Actor::Property::NAME), "", TEST_LOCATION );
+ field.SetProperty(Actor::Property::NAME, "field");
+ DALI_TEST_EQUALS( field.GetProperty<std::string>(Actor::Property::NAME), "field", TEST_LOCATION );
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityTextFieldGetText(void)
+{
+ ToolkitTestApplication application;
+
+ auto field = Dali::Toolkit::TextField::New();
+ auto q = Dali::Accessibility::Accessible::Get( field );
+ auto x = dynamic_cast< Dali::Accessibility::Text* >( q );
+ DALI_TEST_CHECK( x );
+ if( x )
+ {
+ DALI_TEST_EQUALS( x->GetText( 0, 0 ), "", TEST_LOCATION );
+ field.SetProperty( Toolkit::TextField::Property::TEXT, "exemplary_text" );
+ DALI_TEST_EQUALS( x->GetText( 0, 9 ), "exemplary", TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityTextFieldGetCharacterCount(void)
+{
+ ToolkitTestApplication application;
+
+ auto field = Dali::Toolkit::TextField::New();
+ auto q = Dali::Accessibility::Accessible::Get( field );
+ auto x = dynamic_cast< Dali::Accessibility::Text* >( q );
+ DALI_TEST_CHECK( x );
+ if( x )
+ {
+ DALI_TEST_EQUALS( x->GetCharacterCount(), 0, TEST_LOCATION );
+ field.SetProperty( Toolkit::TextField::Property::TEXT, "field" );
+ DALI_TEST_EQUALS( x->GetCharacterCount(), 5, TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityTextFieldGetTextAtOffset(void)
+{
+ ToolkitTestApplication application;
+
+ auto field = Dali::Toolkit::TextField::New();
+ auto q = Dali::Accessibility::Accessible::Get( field );
+ auto x = dynamic_cast< Dali::Accessibility::Text* >( q );
+ DALI_TEST_CHECK( x );
+ if( x )
+ {
+ auto range = x->GetTextAtOffset( 0, Dali::Accessibility::TextBoundary::LINE );
+ DALI_TEST_EQUALS( range.content, "", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+
+ field.SetProperty( Toolkit::TextField::Property::TEXT, "text editor test sentence" );
+ range = x->GetTextAtOffset( 5, Dali::Accessibility::TextBoundary::CHARACTER );
+ DALI_TEST_EQUALS( range.content, "e", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 5, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 6, TEST_LOCATION );
+
+ field.SetProperty( Toolkit::TextField::Property::TEXT, "text \n\n\n\n\n\n editor \n\n test sentence" );
+ range = x->GetTextAtOffset( 3, Dali::Accessibility::TextBoundary::WORD );
+ DALI_TEST_EQUALS( range.content, "sentence", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 28, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 36, TEST_LOCATION );
+
+ field.SetProperty( Toolkit::TextField::Property::TEXT, "text \n\n\n\n\n\n editor \n\n test sentence" );
+ range = x->GetTextAtOffset( 4, Dali::Accessibility::TextBoundary::WORD );
+ DALI_TEST_EQUALS( range.content, "", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+
+ field.SetProperty( Toolkit::TextField::Property::TEXT, "text \n\n\n\n\n\n editor \n\n test sentence" );
+ range = x->GetTextAtOffset( 0, Dali::Accessibility::TextBoundary::LINE );
+ DALI_TEST_EQUALS( range.content, "text \n", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 9, TEST_LOCATION );
+
+ field.SetProperty( Toolkit::TextField::Property::TEXT, "text \n\n\n\n\n\n editor \n\n test sentence" );
+ range = x->GetTextAtOffset( 6, Dali::Accessibility::TextBoundary::LINE );
+ DALI_TEST_EQUALS( range.content, " editor \n", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 14, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 24, TEST_LOCATION );
+
+ field.SetProperty( Toolkit::TextField::Property::TEXT, "text \n\n\n\n\n\n editor \n\n test sentence" );
+ range = x->GetTextAtOffset( 8, Dali::Accessibility::TextBoundary::LINE );
+ DALI_TEST_EQUALS( range.content, " test sentence", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 25, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 39, TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityTextFieldGetSetSelection(void)
+{
+ ToolkitTestApplication application;
+
+ auto field = Dali::Toolkit::TextField::New();
+ auto q = Dali::Accessibility::Accessible::Get( field );
+ auto x = dynamic_cast< Dali::Accessibility::Text* >( q );
+ DALI_TEST_CHECK( x );
+ if( x )
+ {
+ auto range = x->GetSelection( 0 );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.content, "", TEST_LOCATION );
+
+ x->SetSelection( 0, 4, 9 );
+ field.SetProperty( Toolkit::TextEditor::Property::TEXT, "exemplary_text" );
+ range = x->GetSelection( 0 );
+
+ DALI_TEST_EQUALS( range.startOffset, 4, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 9, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.content, "plary", TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityTextFieldRemoveSelection(void)
+{
+ ToolkitTestApplication application;
+
+ auto field = Dali::Toolkit::TextField::New();
+ auto q = Dali::Accessibility::Accessible::Get( field );
+ auto x = dynamic_cast< Dali::Accessibility::Text* >( q );
+ DALI_TEST_CHECK( x );
+ if( x )
+ {
+ auto range = x->GetSelection( 0 );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+
+ x->SetSelection( 0, 4, 9 );
+ range = x->GetSelection( 0 );
+ DALI_TEST_EQUALS( range.startOffset, 4, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 9, TEST_LOCATION );
+
+ x->RemoveSelection( 0 );
+ range = x->GetSelection( 0 );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityTextLabelGetName(void)
+{
+ ToolkitTestApplication application;
+
+ auto label = Toolkit::TextLabel::New();
+ DALI_TEST_EQUALS( label.GetProperty<std::string>(Actor::Property::NAME), "", TEST_LOCATION );
+ label.SetProperty(Actor::Property::NAME, "label");
+ DALI_TEST_EQUALS( label.GetProperty<std::string>(Actor::Property::NAME), "label", TEST_LOCATION );
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityTextLabelGetText(void)
+{
+ ToolkitTestApplication application;
+
+ auto label = Dali::Toolkit::TextLabel::New();
+ auto q = Dali::Accessibility::Accessible::Get( label );
+ auto x = dynamic_cast< Dali::Accessibility::Text* >( q );
+ DALI_TEST_CHECK( x );
+ if( x )
+ {
+ DALI_TEST_EQUALS( x->GetText( 0, 0 ), "", TEST_LOCATION );
+ label.SetProperty( Toolkit::TextField::Property::TEXT, "exemplary_text" );
+ DALI_TEST_EQUALS( x->GetText( 0, 9 ), "exemplary", TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityTextLabelGetCharacterCount(void)
+{
+ ToolkitTestApplication application;
+
+ auto label = Dali::Toolkit::TextLabel::New();
+ auto q = Dali::Accessibility::Accessible::Get( label );
+ auto x = dynamic_cast< Dali::Accessibility::Text* >( q );
+ DALI_TEST_CHECK( x );
+ if( x )
+ {
+ DALI_TEST_EQUALS( x->GetCharacterCount(), 0, TEST_LOCATION );
+ label.SetProperty( Toolkit::TextField::Property::TEXT, "field" );
+ DALI_TEST_EQUALS( x->GetCharacterCount(), 5, TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityTextLabelGetTextAtOffset(void)
+{
+ ToolkitTestApplication application;
+
+ auto label = Dali::Toolkit::TextLabel::New();
+ auto q = Dali::Accessibility::Accessible::Get( label );
+ auto x = dynamic_cast< Dali::Accessibility::Text* >( q );
+ DALI_TEST_CHECK( x );
+ if( x )
+ {
+ auto range = x->GetTextAtOffset( 0, Dali::Accessibility::TextBoundary::LINE );
+ DALI_TEST_EQUALS( range.content, "", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+
+ label.SetProperty( Toolkit::TextLabel::Property::TEXT, "text editor test sentence" );
+ range = x->GetTextAtOffset( 5, Dali::Accessibility::TextBoundary::CHARACTER );
+ DALI_TEST_EQUALS( range.content, "e", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 5, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 6, TEST_LOCATION );
+
+ label.SetProperty( Toolkit::TextLabel::Property::TEXT, "text \n\n\n\n\n\n editor \n\n test sentence" );
+ range = x->GetTextAtOffset( 3, Dali::Accessibility::TextBoundary::WORD );
+ DALI_TEST_EQUALS( range.content, "sentence", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 28, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 36, TEST_LOCATION );
+
+ label.SetProperty( Toolkit::TextLabel::Property::TEXT, "text \n\n\n\n\n\n editor \n\n test sentence" );
+ range = x->GetTextAtOffset( 4, Dali::Accessibility::TextBoundary::WORD );
+ DALI_TEST_EQUALS( range.content, "", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+
+ label.SetProperty( Toolkit::TextLabel::Property::TEXT, "text \n\n\n\n\n\n editor \n\n test sentence" );
+ range = x->GetTextAtOffset( 0, Dali::Accessibility::TextBoundary::LINE );
+ DALI_TEST_EQUALS( range.content, "text \n", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 9, TEST_LOCATION );
+
+ label.SetProperty( Toolkit::TextLabel::Property::TEXT, "text \n\n\n\n\n\n editor \n\n test sentence" );
+ range = x->GetTextAtOffset( 6, Dali::Accessibility::TextBoundary::LINE );
+ DALI_TEST_EQUALS( range.content, " editor \n", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 14, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 24, TEST_LOCATION );
+
+ label.SetProperty( Toolkit::TextLabel::Property::TEXT, "text \n\n\n\n\n\n editor \n\n test sentence" );
+ range = x->GetTextAtOffset( 8, Dali::Accessibility::TextBoundary::LINE );
+ DALI_TEST_EQUALS( range.content, " test sentence", TEST_LOCATION );
+ DALI_TEST_EQUALS( range.startOffset, 25, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 39, TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityTextLabelRemoveSelection( void )
+{
+ ToolkitTestApplication application;
+
+ auto label = Dali::Toolkit::TextLabel::New();
+ auto q = Dali::Accessibility::Accessible::Get( label );
+ auto x = dynamic_cast< Dali::Accessibility::Text* >( q );
+ DALI_TEST_CHECK( x );
+ if( x )
+ {
+ auto range = x->GetSelection( 0 );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+
+ x->SetSelection( 0, 4, 9 );
+ range = x->GetSelection( 0 );
+ DALI_TEST_EQUALS( range.startOffset, 4, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 9, TEST_LOCATION );
+
+ x->RemoveSelection( 0 );
+ range = x->GetSelection( 0 );
+ DALI_TEST_EQUALS( range.startOffset, 0, TEST_LOCATION );
+ DALI_TEST_EQUALS( range.endOffset, 0, TEST_LOCATION );
+ }
+
+ END_TEST;
+}
--- /dev/null
+/**
+ * Copyright (c) 2017 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Need to override adaptor classes for toolkit test harness, so include
+// test harness headers before dali headers.
+#include <dali-toolkit-test-suite-utils.h>
+
+#include <dali.h>
+#include <dali/devel-api/common/stage.h>
+#include <dali-toolkit/dali-toolkit.h>
+
+#include <dali/devel-api/adaptor-framework/accessibility.h>
+#include <dali/devel-api/adaptor-framework/accessibility-impl.h>
+
+#include <dali-toolkit/devel-api/controls/scroll-bar/scroll-bar.h>
+
+#include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dbus-wrapper.h>
+
+using namespace Dali::Accessibility;
+
+void utc_dali_toolkit_accessibility_value_startup(void)
+{
+ test_return_value = TET_UNDEF;
+ DBusWrapper::Install(std::unique_ptr<DBusWrapper>(new TestDBusWrapper));
+}
+
+void utc_dali_toolkit_accessibility_value_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+int utcDaliAccessibilityProgressBarGetMinimum(void)
+{
+ ToolkitTestApplication application;
+
+ Toolkit::ProgressBar progress_bar = Toolkit::ProgressBar::New();
+ auto q = Dali::Accessibility::Accessible::Get( progress_bar );
+ auto x = dynamic_cast< Dali::Accessibility::Value* >( q );
+ DALI_TEST_CHECK( x );
+ DALI_TEST_EQUALS( x->GetMinimum(), 0.0, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityProgressBarGetMaximum(void)
+{
+ ToolkitTestApplication application;
+
+ Toolkit::ProgressBar progress_bar = Toolkit::ProgressBar::New();
+ auto q = Dali::Accessibility::Accessible::Get( progress_bar );
+ auto x = dynamic_cast< Dali::Accessibility::Value* >( q );
+ DALI_TEST_CHECK( x );
+ DALI_TEST_EQUALS( x->GetMaximum(), 1.0, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityProgressBarGetMinimumIncrement(void)
+{
+ ToolkitTestApplication application;
+
+ Toolkit::ProgressBar progress_bar = Toolkit::ProgressBar::New();
+ auto q = Dali::Accessibility::Accessible::Get(progress_bar);
+ auto x = dynamic_cast< Dali::Accessibility::Value* >( q );
+ DALI_TEST_CHECK( x );
+ DALI_TEST_EQUALS( x->GetMinimumIncrement(), 0.0, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityProgressBarGetSetCurrent(void)
+{
+ ToolkitTestApplication application;
+
+ Toolkit::ProgressBar progress_bar = Toolkit::ProgressBar::New();
+ auto q = Dali::Accessibility::Accessible::Get(progress_bar);
+ auto x = dynamic_cast< Dali::Accessibility::Value* >( q );
+ DALI_TEST_CHECK( x );
+ DALI_TEST_EQUALS( x->GetCurrent(), 0.0, TEST_LOCATION );
+ DALI_TEST_EQUALS( x->SetCurrent( 2.0 ), false, TEST_LOCATION );
+ DALI_TEST_EQUALS( x->SetCurrent( 0.25 ), true, TEST_LOCATION );
+ DALI_TEST_EQUALS( x->GetCurrent(), 0.25, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityScrollBarGetMinimum(void)
+{
+ ToolkitTestApplication application;
+
+ // Create a source actor that owns the scroll properties required by the scroll bar
+ Actor sourceActor = Actor::New();
+ Stage::GetCurrent().Add( sourceActor );
+
+ // Register the scroll properties
+ Property::Index propertyScrollPosition = sourceActor.RegisterProperty( "sourcePosition", 0.0f );
+ Property::Index propertyMinScrollPosition = sourceActor.RegisterProperty( "sourcePositionMin", 10.0f );
+ Property::Index propertyMaxScrollPosition = sourceActor.RegisterProperty( "sourcePositionMax", 100.0f );
+ Property::Index propertyScrollContentSize = sourceActor.RegisterProperty( "sourceContentSize", 500.0f );
+
+ Toolkit::ScrollBar scroll_bar = Toolkit::ScrollBar::New();
+
+ scroll_bar.SetScrollPropertySource(sourceActor, propertyScrollPosition, propertyMinScrollPosition, propertyMaxScrollPosition, propertyScrollContentSize);
+
+ auto q = Dali::Accessibility::Accessible::Get(scroll_bar);
+ auto x = dynamic_cast< Dali::Accessibility::Value* >( q );
+ DALI_TEST_CHECK( x );
+ DALI_TEST_EQUALS( x->GetMinimum(), 10.0, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityScrollBarGetMaximum(void)
+{
+ ToolkitTestApplication application;
+
+ // Create a source actor that owns the scroll properties required by the scroll bar
+ Actor sourceActor = Actor::New();
+ Stage::GetCurrent().Add( sourceActor );
+
+ // Register the scroll properties
+ Property::Index propertyScrollPosition = sourceActor.RegisterProperty( "sourcePosition", 0.0f );
+ Property::Index propertyMinScrollPosition = sourceActor.RegisterProperty( "sourcePositionMin", 0.0f );
+ Property::Index propertyMaxScrollPosition = sourceActor.RegisterProperty( "sourcePositionMax", 100.0f );
+ Property::Index propertyScrollContentSize = sourceActor.RegisterProperty( "sourceContentSize", 500.0f );
+
+ Toolkit::ScrollBar scroll_bar = Toolkit::ScrollBar::New();
+
+ scroll_bar.SetScrollPropertySource(sourceActor, propertyScrollPosition, propertyMinScrollPosition, propertyMaxScrollPosition, propertyScrollContentSize);
+
+ auto q = Dali::Accessibility::Accessible::Get(scroll_bar);
+ auto x = dynamic_cast< Dali::Accessibility::Value* >( q );
+ DALI_TEST_CHECK( x );
+ DALI_TEST_EQUALS( x->GetMaximum(), 100.0, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityScrollBarGetMinimumIncrement(void)
+{
+ ToolkitTestApplication application;
+
+ Toolkit::ScrollBar scroll_bar = Toolkit::ScrollBar::New();
+ auto q = Dali::Accessibility::Accessible::Get(scroll_bar);
+ auto x = dynamic_cast< Dali::Accessibility::Value* >( q );
+ DALI_TEST_CHECK( x );
+ DALI_TEST_EQUALS( x->GetMinimumIncrement(), 1.0, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int utcDaliAccessibilityScrollBarGetSetCurrent(void)
+{
+ ToolkitTestApplication application;
+
+ // Create a source actor that owns the scroll properties required by the scroll bar
+ Actor sourceActor = Actor::New();
+ Stage::GetCurrent().Add( sourceActor );
+
+ // Register the scroll properties
+ Property::Index propertyScrollPosition = sourceActor.RegisterProperty( "sourcePosition", 0.0f );
+ Property::Index propertyMinScrollPosition = sourceActor.RegisterProperty( "sourcePositionMin", 0.0f );
+ Property::Index propertyMaxScrollPosition = sourceActor.RegisterProperty( "sourcePositionMax", 100.0f );
+ Property::Index propertyScrollContentSize = sourceActor.RegisterProperty( "sourceContentSize", 500.0f );
+
+ Toolkit::ScrollBar scroll_bar = Toolkit::ScrollBar::New();
+
+ scroll_bar.SetScrollPropertySource(sourceActor, propertyScrollPosition, propertyMinScrollPosition, propertyMaxScrollPosition, propertyScrollContentSize);
+
+ //sourceActor.SetProperty(propertyScrollPosition, 20.0f);
+
+ auto q = Dali::Accessibility::Accessible::Get(scroll_bar);
+ auto x = dynamic_cast< Dali::Accessibility::Value* >( q );
+ DALI_TEST_CHECK( x );
+ DALI_TEST_EQUALS( x->GetCurrent(), 0.0, TEST_LOCATION );
+ DALI_TEST_EQUALS( x->SetCurrent( 1000.0 ), false, TEST_LOCATION );
+ DALI_TEST_EQUALS( x->SetCurrent( 50.0 ), false, TEST_LOCATION );
+ DALI_TEST_EQUALS( x->GetCurrent(), 0.0, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int utcDaliAccessibilitySliderGetMinimum(void)
+{
+ ToolkitTestApplication application;
+
+ Toolkit::Slider slider = Toolkit::Slider::New();
+ auto q = Dali::Accessibility::Accessible::Get(slider);
+ auto x = dynamic_cast< Dali::Accessibility::Value* >( q );
+ DALI_TEST_CHECK( x );
+ DALI_TEST_EQUALS( x->GetMinimum(), 0.0, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int utcDaliAccessibilitySliderGetMaximum(void)
+{
+ ToolkitTestApplication application;
+
+ Toolkit::Slider slider = Toolkit::Slider::New();
+ auto q = Dali::Accessibility::Accessible::Get(slider);
+ auto x = dynamic_cast< Dali::Accessibility::Value* >( q );
+ DALI_TEST_CHECK( x );
+ DALI_TEST_EQUALS( x->GetMaximum(), 1.0, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int utcDaliAccessibilitySliderGetMinimumIncrement(void)
+{
+ ToolkitTestApplication application;
+
+ Toolkit::Slider slider = Toolkit::Slider::New();
+ auto q = Dali::Accessibility::Accessible::Get(slider);
+ auto x = dynamic_cast< Dali::Accessibility::Value* >( q );
+ DALI_TEST_CHECK( x );
+ DALI_TEST_EQUALS<float>( x->GetMinimumIncrement(), 0.0, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int utcDaliAccessibilitySliderGetSetCurrent(void)
+{
+ ToolkitTestApplication application;
+
+ Toolkit::Slider slider = Toolkit::Slider::New();
+ auto q = Dali::Accessibility::Accessible::Get(slider);
+ auto x = dynamic_cast< Dali::Accessibility::Value* >( q );
+ DALI_TEST_CHECK( x );
+ DALI_TEST_EQUALS( x->GetCurrent(), 0.0, TEST_LOCATION );
+ DALI_TEST_EQUALS( x->SetCurrent( 2.0 ), false, TEST_LOCATION );
+ DALI_TEST_EQUALS( x->SetCurrent( 0.25 ), true, TEST_LOCATION );
+ DALI_TEST_EQUALS( x->GetCurrent(), 0.25, TEST_LOCATION );
+
+ const float MIN_BOUND = 0.0f;
+ const float MAX_BOUND = 1.0f;
+ const int NUM_MARKS = 5;
+ Property::Array marks;
+ for( int i = 0; i < NUM_MARKS; ++i )
+ {
+ marks.PushBack( MIN_BOUND + ( static_cast<float>(i) / ( NUM_MARKS - 1) ) * ( MAX_BOUND - MIN_BOUND ) );
+ }
+ slider.SetProperty( Toolkit::Slider::Property::MARKS, marks );
+ // when current value is not a mark, set new value to the closest mark
+ DALI_TEST_CHECK( x->SetCurrent( 0.1f ) );
+ slider.SetProperty( Toolkit::Slider::Property::SNAP_TO_MARKS, true );
+ DALI_TEST_CHECK( x->SetCurrent( 0.7f ) );
+ DALI_TEST_EQUALS( static_cast<float>( x->GetCurrent() ), marks[3].Get<float>(), TEST_LOCATION );
+ // when current value is a mark at index i set new value to the mark at index i +/- 1
+ // depending if the new value is greater/less than current value
+ DALI_TEST_CHECK( x->SetCurrent( 0.2f ) );
+ DALI_TEST_EQUALS( static_cast<float>( x->GetCurrent() ), marks[2].Get<float>(), TEST_LOCATION );
+ END_TEST;
+}
#include <dali-toolkit-test-suite-utils.h>
#include <dali-toolkit/internal/helpers/color-conversion.h>
+#include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dbus-wrapper.h>
+
using namespace Dali;
using namespace Dali::Toolkit;
void dali_color_conversion_startup(void)
{
test_return_value = TET_UNDEF;
+ DBusWrapper::Install(std::unique_ptr<DBusWrapper>(new TestDBusWrapper));
}
void dali_color_conversion_cleanup(void)
#include <dali-toolkit/dali-toolkit.h>
#include <toolkit-environment-variable.h> // for setting environment variable: DALI_DEBUG_RENDERING
+
+#include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dbus-wrapper.h>
+
#include "dummy-control.h"
using namespace Dali;
void dali_debug_rendering_startup(void)
{
test_return_value = TET_UNDEF;
+ DBusWrapper::Install(std::unique_ptr<DBusWrapper>(new TestDBusWrapper));
}
void dali_debug_rendering_cleanup(void)
#include <dali-toolkit-test-suite-utils.h>
#include <dali-toolkit/internal/helpers/property-helper.h>
+#include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dbus-wrapper.h>
+
using namespace Dali;
using namespace Dali::Toolkit;
void dali_property_helper_startup(void)
{
test_return_value = TET_UNDEF;
+ DBusWrapper::Install(std::unique_ptr<DBusWrapper>(new TestDBusWrapper));
}
void dali_property_helper_cleanup(void)
#include <dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.h>
#undef private
+#include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dbus-wrapper.h>
+
using namespace Dali;
using namespace Toolkit;
void dali_textselectionpopupinternal_startup(void)
{
test_return_value = TET_UNDEF;
+ DBusWrapper::Install(std::unique_ptr<DBusWrapper>(new TestDBusWrapper));
}
void dali_textselectionpopupinternal_cleanup(void)
#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
#include <dali-toolkit/internal/visuals/image-atlas-manager.h>
-using namespace Dali::Toolkit::Internal;
+#include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dbus-wrapper.h>
+using namespace Dali::Toolkit::Internal;
void utc_dali_toolkit_texture_manager_startup(void)
{
setenv( "LOG_TEXTURE_MANAGER", "3", 1 );
test_return_value = TET_UNDEF;
+ DBusWrapper::Install(std::unique_ptr<DBusWrapper>(new TestDBusWrapper));
}
void utc_dali_toolkit_texture_manager_cleanup(void)
LIST(APPEND TC_SOURCES
../dali-toolkit/dali-toolkit-test-utils/test-harness.cpp
../dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp
- ../dali-toolkit/dali-toolkit-test-utils/toolkit-accessibility-adaptor.cpp
../dali-toolkit/dali-toolkit-test-utils/toolkit-application.cpp
../dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard.cpp
../dali-toolkit/dali-toolkit-test-utils/toolkit-color-controller.cpp
PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED
dali2-core
+ dali2-adaptor
dali2-toolkit
)
# Append list of test harness files (Won't get parsed for test cases)
LIST(APPEND TC_SOURCES
+ ../dali-toolkit/dali-toolkit-test-utils/toolkit-application.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard-event-notifier.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/toolkit-event-thread-callback.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/toolkit-environment-variable.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/toolkit-input-method-context.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/toolkit-orientation.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/toolkit-physical-keyboard.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/toolkit-style-monitor.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/toolkit-timer.cpp
+ ../dali-toolkit/dali-toolkit-test-utils/toolkit-tts-player.cpp
../dali-toolkit/dali-toolkit-test-utils/dali-test-suite-utils.cpp
../dali-toolkit/dali-toolkit-test-utils/mesh-builder.cpp
../dali-toolkit/dali-toolkit-test-utils/test-actor-utils.cpp
utc-Dali-Button.cpp
utc-Dali-Control.cpp
utc-Dali-ControlImpl.cpp
- utc-Dali-AccessibilityManager.cpp
utc-Dali-ItemLayout.cpp
utc-Dali-ItemView.cpp
utc-Dali-KeyboardFocusManager.cpp
# Append list of test harness files (Won't get parsed for test cases)
LIST(APPEND TC_SOURCES
dali-toolkit-test-utils/toolkit-adaptor.cpp
- dali-toolkit-test-utils/toolkit-accessibility-adaptor.cpp
dali-toolkit-test-utils/toolkit-application.cpp
dali-toolkit-test-utils/toolkit-clipboard.cpp
dali-toolkit-test-utils/toolkit-clipboard-event-notifier.cpp
#include <sys/types.h>
#include <sys/wait.h>
#include <testcase.h>
+
+#include <time.h>
#include <unistd.h>
+#include <chrono>
#include <cstring>
#include <map>
#include <vector>
{
typedef std::map<int32_t, TestCase> RunningTestCases;
+const double MAXIMUM_CHILD_LIFETIME(60.0f); // 1 minute
+
const char* basename(const char* path)
{
const char* ptr = path;
else // Parent process
{
TestCase tc(nextTestCase, tc_array[nextTestCase].name);
+ tc.startTime = std::chrono::steady_clock::now();
+
children[pid] = tc;
nextTestCase++;
numRunningChildren++;
}
}
- // Wait for the next child to finish
-
+ // Check to see if any children have finished yet
int32_t status = 0;
- int32_t childPid = waitpid(-1, &status, 0);
- if(childPid == -1)
+ int32_t childPid = waitpid(-1, &status, WNOHANG);
+ if(childPid == 0)
+ {
+ // No children have finished.
+ // Check if any have exceeded execution time
+ auto endTime = std::chrono::steady_clock::now();
+
+ for(auto& tc : children)
+ {
+ std::chrono::steady_clock::duration timeSpan = endTime - tc.second.startTime;
+ std::chrono::duration<double> seconds = std::chrono::duration_cast<std::chrono::duration<double>>(timeSpan);
+ if(seconds.count() > MAXIMUM_CHILD_LIFETIME)
+ {
+ // Kill the child process. A subsequent call to waitpid will process signal result below.
+ kill(tc.first, SIGKILL);
+ }
+ }
+ }
+ else if(childPid == -1) // waitpid errored
{
perror("waitpid");
exit(EXIT_STATUS_WAITPID_FAILED);
}
-
- if(WIFEXITED(status))
+ else // a child has finished
{
- if(childPid > 0)
+ if(WIFEXITED(status))
{
int32_t testResult = WEXITSTATUS(status);
if(testResult)
}
numRunningChildren--;
}
- }
-
- else if(WIFSIGNALED(status) || WIFSTOPPED(status))
- {
- status = WIFSIGNALED(status) ? WTERMSIG(status) : WSTOPSIG(status);
- if(childPid > 0)
+ else if(WIFSIGNALED(status) || WIFSTOPPED(status))
{
+ status = WIFSIGNALED(status) ? WTERMSIG(status) : WSTOPSIG(status);
+
RunningTestCases::iterator iter = children.find(childPid);
if(iter != children.end())
{
#include <stdio.h>
#include <testcase.h>
+#include <chrono>
#include <cstdint>
namespace TestHarness
struct TestCase
{
- int32_t testCase;
- const char* testCaseName;
+ int32_t testCase;
+ const char* testCaseName;
+ std::chrono::steady_clock::time_point startTime;
TestCase()
: testCase(0),
- testCaseName(NULL)
+ testCaseName(NULL),
+ startTime()
{
}
TestCase(int32_t tc, const char* name)
: testCase(tc),
- testCaseName(name)
+ testCaseName(name),
+ startTime()
{
}
TestCase(const TestCase& rhs)
: testCase(rhs.testCase),
- testCaseName(rhs.testCaseName)
+ testCaseName(rhs.testCaseName),
+ startTime(rhs.startTime)
{
}
TestCase& operator=(const TestCase& rhs)
{
testCase = rhs.testCase;
testCaseName = rhs.testCaseName;
+ startTime = rhs.startTime;
return *this;
}
};
+++ /dev/null
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <dali/public-api/object/base-object.h>
-#include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
-#include <dali/devel-api/adaptor-framework/accessibility-action-handler.h>
-#include <dali/devel-api/adaptor-framework/accessibility-gesture-handler.h>
-#include <dali/devel-api/adaptor-framework/accessibility-gesture-event.h>
-#include <dali/integration-api/events/touch-integ.h>
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace Adaptor
-{
-
-/**
- * Stub for the AccessibilityAdaptor
- */
-class AccessibilityAdaptor : public BaseObject
-{
-public: // Creation & Destruction
-
- static Dali::AccessibilityAdaptor Get();
-
- AccessibilityAdaptor();
- ~AccessibilityAdaptor();
-
-public:
-
- // Functions to modify mock returns:
-
- void MockSetReadPosition( Vector2& position );
-
- void SetEnabled(bool enabled)
- {
- mIsEnabled = enabled;
- }
-
- void SendPanGesture( const AccessibilityGestureEvent& panEvent );
-
-public:
-
- bool IsEnabled() const;
- void SetActionHandler(Dali::AccessibilityActionHandler& handler);
- void SetGestureHandler(Dali::AccessibilityGestureHandler& handler);
-
- Vector2 GetReadPosition() const;
-
- bool HandleActionNextEvent(bool);
- bool HandleActionPreviousEvent(bool);
- bool HandleActionActivateEvent();
- bool HandleActionReadEvent(unsigned int x, unsigned int y, bool allowReadAgain);
- bool HandleActionReadNextEvent(bool);
- bool HandleActionReadPreviousEvent(bool);
- bool HandleActionUpEvent();
- bool HandleActionDownEvent();
- bool HandleActionClearFocusEvent();
- bool HandleActionScrollEvent(const TouchPoint& point, unsigned long timeStamp);
- bool HandleActionBackEvent();
- bool HandleActionEnableEvent();
- bool HandleActionDisableEvent();
- bool HandleActionScrollUpEvent();
- bool HandleActionScrollDownEvent();
- bool HandleActionPageLeftEvent();
- bool HandleActionPageRightEvent();
- bool HandleActionPageUpEvent();
- bool HandleActionPageDownEvent();
- bool HandleActionMoveToFirstEvent();
- bool HandleActionMoveToLastEvent();
- bool HandleActionReadFromTopEvent();
- bool HandleActionReadFromNextEvent();
- bool HandleActionZoomEvent();
- bool HandleActionReadPauseResumeEvent();
- bool HandleActionStartStopEvent();
-
-private:
-
- bool mIsEnabled;
- Dali::AccessibilityActionHandler* mActionHandler;
- Dali::AccessibilityGestureHandler* mGestureHandler;
- Vector2 mReadPosition;
-
- static Dali::AccessibilityAdaptor mToolkitAccessibilityAdaptor;
-};
-
-Dali::AccessibilityAdaptor AccessibilityAdaptor::mToolkitAccessibilityAdaptor;
-
-
-Dali::AccessibilityAdaptor AccessibilityAdaptor::Get()
-{
- if( !mToolkitAccessibilityAdaptor )
- {
- mToolkitAccessibilityAdaptor = Dali::AccessibilityAdaptor( new Dali::Internal::Adaptor::AccessibilityAdaptor() );
- }
- return mToolkitAccessibilityAdaptor;
-}
-
-AccessibilityAdaptor::AccessibilityAdaptor()
-: mIsEnabled(false),
- mActionHandler(NULL),
- mGestureHandler(NULL),
- mReadPosition( 0.0f, 0.0f )
-{
-}
-
-AccessibilityAdaptor::~AccessibilityAdaptor()
-{
-}
-
-Vector2 AccessibilityAdaptor::GetReadPosition() const
-{
- return mReadPosition;
-}
-
-void AccessibilityAdaptor::MockSetReadPosition( Vector2& position )
-{
- mReadPosition = position;
-}
-
-bool AccessibilityAdaptor::IsEnabled() const
-{
- return mIsEnabled;
-}
-
-void AccessibilityAdaptor::SendPanGesture( const AccessibilityGestureEvent& panEvent )
-{
- mGestureHandler->HandlePanGesture( panEvent );
-}
-
-void AccessibilityAdaptor::SetActionHandler(Dali::AccessibilityActionHandler& handler)
-{
- mActionHandler = &handler;
-}
-
-void AccessibilityAdaptor::SetGestureHandler(Dali::AccessibilityGestureHandler& handler)
-{
- mGestureHandler = &handler;
-}
-
-bool AccessibilityAdaptor::HandleActionNextEvent(bool allowEndFeedback)
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionNext( true );
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionPreviousEvent(bool allowEndFeedback)
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionPrevious( true );
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionActivateEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionActivate();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionReadEvent(unsigned int x, unsigned int y, bool allowReadAgain)
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionRead( allowReadAgain );
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionReadNextEvent(bool allowEndFeedback)
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionReadNext( true );
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionReadPreviousEvent(bool allowEndFeedback)
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionReadPrevious( true );
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionUpEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionUp();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionDownEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionDown();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionClearFocusEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->ClearAccessibilityFocus();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionScrollEvent(const TouchPoint& point, unsigned long timeStamp)
-{
- if( mActionHandler )
- {
- Dali::TouchEvent touch = Integration::NewTouchEvent(timeStamp, point);
- return mActionHandler->AccessibilityActionScroll( touch );
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionBackEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionBack();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionEnableEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->ChangeAccessibilityStatus();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionDisableEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->ChangeAccessibilityStatus();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionScrollUpEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionScrollUp();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionScrollDownEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionScrollDown();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionPageLeftEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionPageLeft();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionPageRightEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionPageRight();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionPageUpEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionPageUp();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionPageDownEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionPageDown();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionMoveToFirstEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionMoveToFirst();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionMoveToLastEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionMoveToLast();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionReadFromTopEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionReadFromTop();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionReadFromNextEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionReadFromNext();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionZoomEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionZoom();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionReadPauseResumeEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionReadPauseResume();
- }
- return false;
-}
-
-bool AccessibilityAdaptor::HandleActionStartStopEvent()
-{
- if( mActionHandler )
- {
- return mActionHandler->AccessibilityActionStartStop();
- }
- return false;
-}
-
-static Internal::Adaptor::AccessibilityAdaptor& GetImplementation(Dali::AccessibilityAdaptor& adaptor)
-{
- BaseObject& handle = adaptor.GetBaseObject();
- return static_cast<Internal::Adaptor::AccessibilityAdaptor&>(handle);
-}
-
-static const Internal::Adaptor::AccessibilityAdaptor& GetImplementation(const Dali::AccessibilityAdaptor& adaptor)
-{
- const BaseObject& handle = adaptor.GetBaseObject();
- return static_cast<const Internal::Adaptor::AccessibilityAdaptor&>(handle);
-}
-
-
-} // namespace Adaptor
-} // namespace Internal
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-AccessibilityAdaptor::AccessibilityAdaptor()
-{
-}
-
-AccessibilityAdaptor AccessibilityAdaptor::Get()
-{
- return Internal::Adaptor::AccessibilityAdaptor::Get();
-}
-
-AccessibilityAdaptor::~AccessibilityAdaptor()
-{
-}
-
-// Methods:
-
-Vector2 AccessibilityAdaptor::GetReadPosition() const
-{
- return Internal::Adaptor::GetImplementation(*this).GetReadPosition();
-}
-
-bool AccessibilityAdaptor::IsEnabled() const
-{
- return Internal::Adaptor::GetImplementation(*this).IsEnabled();
-}
-
-void AccessibilityAdaptor::SetActionHandler(AccessibilityActionHandler& handler)
-{
- Internal::Adaptor::GetImplementation(*this).SetActionHandler(handler);
-}
-
-void AccessibilityAdaptor::SetGestureHandler(AccessibilityGestureHandler& handler)
-{
- Internal::Adaptor::GetImplementation(*this).SetGestureHandler(handler);
-}
-
-bool AccessibilityAdaptor::HandleActionNextEvent(bool allowEndFeedback)
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionNextEvent(allowEndFeedback);
-}
-
-bool AccessibilityAdaptor::HandleActionPreviousEvent(bool allowEndFeedback)
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionPreviousEvent(allowEndFeedback);
-}
-
-bool AccessibilityAdaptor::HandleActionActivateEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionActivateEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionReadEvent(unsigned int x, unsigned int y, bool allowReadAgain)
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionReadEvent( x, y, allowReadAgain );
-}
-
-bool AccessibilityAdaptor::HandleActionReadNextEvent(bool allowEndFeedback)
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionReadNextEvent(allowEndFeedback);
-}
-
-bool AccessibilityAdaptor::HandleActionReadPreviousEvent(bool allowEndFeedback)
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionReadPreviousEvent(allowEndFeedback);
-}
-
-bool AccessibilityAdaptor::HandleActionUpEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionUpEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionDownEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionDownEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionClearFocusEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionClearFocusEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionScrollEvent(const TouchPoint& point, unsigned long timeStamp)
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionScrollEvent(point, timeStamp);
-}
-
-bool AccessibilityAdaptor::HandleActionBackEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionBackEvent();
-}
-
-void AccessibilityAdaptor::HandleActionEnableEvent()
-{
- Internal::Adaptor::GetImplementation(*this).HandleActionEnableEvent();
-}
-
-void AccessibilityAdaptor::HandleActionDisableEvent()
-{
- Internal::Adaptor::GetImplementation(*this).HandleActionDisableEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionScrollUpEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionScrollUpEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionScrollDownEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionScrollDownEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionPageLeftEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionPageLeftEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionPageRightEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionPageRightEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionPageUpEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionPageUpEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionPageDownEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionPageDownEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionMoveToFirstEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionMoveToFirstEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionMoveToLastEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionMoveToLastEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionReadFromTopEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionReadFromTopEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionReadFromNextEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionReadFromNextEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionZoomEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionZoomEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionReadPauseResumeEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionReadPauseResumeEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionStartStopEvent()
-{
- return Internal::Adaptor::GetImplementation(*this).HandleActionStartStopEvent();
-}
-
-AccessibilityAdaptor::AccessibilityAdaptor( Internal::Adaptor::AccessibilityAdaptor* adaptor )
-: BaseHandle( adaptor )
-{
-}
-
-} // namespace Dali
-
-
-namespace Test
-{
-namespace AccessibilityAdaptor
-{
-
-// Mock setup:
-
-void MockSetReadPosition( Dali::AccessibilityAdaptor adaptor, Dali::Vector2& position )
-{
- Dali::Internal::Adaptor::GetImplementation(adaptor).MockSetReadPosition( position );
-}
-
-void SetEnabled( Dali::AccessibilityAdaptor adaptor, bool enabled )
-{
- Dali::Internal::Adaptor::GetImplementation(adaptor).SetEnabled(enabled);
-}
-
-void SendPanGesture( Dali::AccessibilityAdaptor adaptor, const Dali::AccessibilityGestureEvent& panEvent )
-{
- Dali::Internal::Adaptor::GetImplementation(adaptor).SendPanGesture( panEvent );
-}
-
-} // namespace AccessibilityAdaptor
-} // namespace Test
+++ /dev/null
-#ifndef DALI_TEST_TOOLKIT_ACCESSIBILITY_ADAPTOR_H
-#define DALI_TEST_TOOLKIT_ACCESSIBILITY_ADAPTOR_H
-
-/*
- * Copyright (c) 2019 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
-#include <dali/devel-api/adaptor-framework/accessibility-gesture-event.h>
-
-namespace Test
-{
-namespace AccessibilityAdaptor
-{
-
-void MockSetReadPosition( Dali::AccessibilityAdaptor adaptor, Dali::Vector2& position );
-void SetEnabled( Dali::AccessibilityAdaptor adaptor, bool enabled);
-void SendPanGesture( Dali::AccessibilityAdaptor adaptor, const Dali::AccessibilityGestureEvent& panEvent );
-
-} // namespace AccessibilityAdaptor
-} // namespace Test
-
-#endif // DALI_TEST_TOOLKIT_ACCESSIBILITY_ADAPTOR_H
#include <dali/integration-api/debug.h>
#include <dali/integration-api/scene.h>
#include <test-application.h>
+#include <toolkit-test-application.h>
namespace Dali
{
-namespace
-{
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// LogFactoryStub
-//
-///////////////////////////////////////////////////////////////////////////////
-
-class LogFactory : public LogFactoryInterface
-{
-public:
- LogFactory() = default;
- virtual ~LogFactory() = default;
-
-private:
- void InstallLogFunction() const override
- {
- Dali::Integration::Log::InstallLogFunction( &TestApplication::LogMessage );
- }
-};
-LogFactory* gLogFactory = NULL; // For some reason, destroying this when the Adaptor is destroyed causes a crash in some test cases when running all of them.
-} //unnamed namespace
-
namespace Internal
{
namespace Adaptor
{
}
+class LogFactory : public LogFactoryInterface
+{
+public:
+ virtual void InstallLogFunction() const
+ {
+ Dali::Integration::Log::LogFunction logFunction(&ToolkitTestApplication::LogMessage);
+ Dali::Integration::Log::InstallLogFunction(logFunction);
+ }
+
+ LogFactory()
+ {
+ }
+ virtual ~LogFactory()
+ {
+ }
+};
+
+LogFactory* gLogFactory = NULL;
const LogFactoryInterface& Adaptor::GetLogFactory()
{
if( gLogFactory == NULL )
// INTERNAL INCLUDES
#include <dali-test-suite-utils.h>
#include <dali/devel-api/text-abstraction/font-client.h>
+#include <dali/devel-api/adaptor-framework/accessibility-impl.h>
#include <dali/integration-api/adaptor-framework/adaptor.h>
#include <toolkit-adaptor-impl.h>
#include <toolkit-lifecycle-controller.h>
// Core needs to be initialized next before we start the adaptor
InitializeCore();
+ Accessibility::Accessible::SetObjectRegistry(mCore->GetObjectRegistry());
// This will also emit the window created signals
AdaptorImpl::GetImpl( *mAdaptor ).Start( *mMainWindow );
// INTERNAL INCLUDES
#include <dali-test-suite-utils.h>
+#include <dali/devel-api/text-abstraction/font-client.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <toolkit-adaptor-impl.h>
+#include <dali/devel-api/adaptor-framework/accessibility.h>
+#include "test-application.h"
+
+//#undef assert
namespace Dali
{
+++ /dev/null
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <iostream>
-#include <stdlib.h>
-
-#include <dali-toolkit/dali-toolkit.h>
-#include <dali-toolkit/devel-api/accessibility-manager/accessibility-manager.h>
-
-#include <dali-toolkit-test-suite-utils.h>
-#include <toolkit-accessibility-adaptor.h>
-#include <dummy-control.h>
-
-using namespace Dali;
-using namespace Toolkit;
-
-
-void utc_dali_toolkit_accessibility_manager_startup(void)
-{
- test_return_value = TET_UNDEF;
-}
-
-void utc_dali_toolkit_accessibility_manager_cleanup(void)
-{
- test_return_value = TET_PASS;
-}
-
-
-namespace
-{
-
-// Functors to test whether focus changed signal is emitted when the focus is changed
-class FocusChangedCallback : public Dali::ConnectionTracker
-{
-public:
- FocusChangedCallback(bool& signalReceived)
- : mSignalVerified(signalReceived),
- mOriginalFocusedActor(),
- mCurrentFocusedActor()
- {
- }
-
- void Callback(Actor originalFocusedActor, Actor currentFocusedActor)
- {
- tet_infoline("Verifying FocusChangedCallback()");
-
- if(originalFocusedActor == mCurrentFocusedActor)
- {
- mSignalVerified = true;
- }
-
- mOriginalFocusedActor = originalFocusedActor;
- mCurrentFocusedActor = currentFocusedActor;
- }
-
- void Reset()
- {
- mSignalVerified = false;
- }
-
- bool& mSignalVerified;
- Actor mOriginalFocusedActor;
- Actor mCurrentFocusedActor;
-};
-
-// Functors to test whether focus overshot signal is emitted when there is no way to move focus further.
-class FocusOvershotCallback : public Dali::ConnectionTracker
-{
-public:
- FocusOvershotCallback(bool& signalReceived)
- : mSignalVerified(signalReceived),
- mCurrentFocusedActor(),
- mFocusOvershotDirection(Toolkit::AccessibilityManager::OVERSHOT_NEXT)
- {
- }
-
- void Callback(Actor currentFocusedActor, Toolkit::AccessibilityManager::FocusOvershotDirection direction)
- {
- tet_infoline("Verifying FocusOvershotCallback()");
-
- if(currentFocusedActor == mCurrentFocusedActor && direction == mFocusOvershotDirection)
- {
- mSignalVerified = true;
- }
- }
-
- void Reset()
- {
- mSignalVerified = false;
- }
-
- bool& mSignalVerified;
- Actor mCurrentFocusedActor;
- Toolkit::AccessibilityManager::FocusOvershotDirection mFocusOvershotDirection;
-};
-
-// Functor to test whether focused actor activated signal is emitted.
-class FocusedActorActivatedCallback : public Dali::ConnectionTracker
-{
-public:
- FocusedActorActivatedCallback()
- {
- }
-
- void Callback(Actor activatedActor)
- {
- tet_infoline("Verifying FocusedActorActivatedCallback()");
- }
-};
-
-} // namespace
-
-
-int UtcDaliAccessibilityManagerGet(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerGet");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- AccessibilityManager newManager = AccessibilityManager::Get();
- DALI_TEST_CHECK(newManager);
-
- // Check that accessibility manager is a singleton
- DALI_TEST_CHECK(manager == newManager);
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerSetAndGetAccessibilityAttribute(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerSetAndGetAccessibilityAttribute");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- Actor actor = Actor::New();
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(actor, AccessibilityManager::ACCESSIBILITY_LABEL) == "");
-
- manager.SetAccessibilityAttribute(actor, AccessibilityManager::ACCESSIBILITY_LABEL, "Description");
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(actor, AccessibilityManager::ACCESSIBILITY_LABEL) == "Description");
-
- manager.SetAccessibilityAttribute(actor, AccessibilityManager::ACCESSIBILITY_LABEL, "New description");
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(actor, AccessibilityManager::ACCESSIBILITY_LABEL) == "New description");
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerSetAndGetFocusOrder(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerSetAndGetFocusOrder");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- Actor first = Actor::New();
- Actor second = Actor::New();
- DALI_TEST_CHECK(manager.GetFocusOrder(first) == 0);
- DALI_TEST_CHECK(manager.GetFocusOrder(second) == 0);
-
- // Set the focus order and description for the first actor
- manager.SetFocusOrder(first, 1);
- manager.SetAccessibilityAttribute(first, AccessibilityManager::ACCESSIBILITY_LABEL, "first");
- DALI_TEST_CHECK(manager.GetFocusOrder(first) == 1);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(first, AccessibilityManager::ACCESSIBILITY_LABEL) == "first");
-
- // Set the focus order and description for the second actor
- manager.SetFocusOrder(second, 2);
- manager.SetAccessibilityAttribute(second, AccessibilityManager::ACCESSIBILITY_LABEL, "second");
- DALI_TEST_CHECK(manager.GetFocusOrder(second) == 2);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(second, AccessibilityManager::ACCESSIBILITY_LABEL) == "second");
-
- // check that the focus order of the first actor is changed
- manager.SetFocusOrder(first, 2);
- DALI_TEST_CHECK(manager.GetFocusOrder(first) == 2);
- // make sure the change of focus order doesn't affect the actor's description
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(first, AccessibilityManager::ACCESSIBILITY_LABEL) == "first");
-
- // check that the focus order of the second actor is increased to 3
- DALI_TEST_CHECK(manager.GetFocusOrder(second) == 3);
- // make sure the change of focus order doesn't affect the actor's description
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(second, AccessibilityManager::ACCESSIBILITY_LABEL) == "second");
-
- // check that the focus order of the second actor is changed to 1
- manager.SetFocusOrder(second, 1);
- DALI_TEST_CHECK(manager.GetFocusOrder(second) == 1);
- // make sure the change of focus order doesn't affect the actor's description
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(second, AccessibilityManager::ACCESSIBILITY_LABEL) == "second");
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- // Set the focus order and description for the third actor
- Actor third = Actor::New();
- manager.SetFocusOrder(third, 1);
- manager.SetAccessibilityAttribute(third, AccessibilityManager::ACCESSIBILITY_LABEL, "third");
- DALI_TEST_CHECK(manager.GetFocusOrder(third) == 1);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(third, AccessibilityManager::ACCESSIBILITY_LABEL) == "third");
-
- // check that the focus order of the second actor is increased to 2.
- DALI_TEST_CHECK(manager.GetFocusOrder(second) == 2);
- // make sure the change of focus order doesn't affect the actor's description
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(second, AccessibilityManager::ACCESSIBILITY_LABEL) == "second");
-
- // check that the focus order of the first actor is increased to 3.
- DALI_TEST_CHECK(manager.GetFocusOrder(first) == 3);
- // make sure the change of focus order doesn't affect the actor's description
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(first, AccessibilityManager::ACCESSIBILITY_LABEL) == "first");
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerGenerateNewFocusOrder(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerGenerateNewFocusOrder");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- DALI_TEST_CHECK(1 == manager.GenerateNewFocusOrder());
- DALI_TEST_CHECK(1 == manager.GenerateNewFocusOrder());
-
- Actor first = Actor::New();
- Actor second = Actor::New();
-
- // Set the focus order for the first actor
- manager.SetFocusOrder(first, 1);
- manager.SetAccessibilityAttribute(first, AccessibilityManager::ACCESSIBILITY_LABEL, "first");
- DALI_TEST_CHECK(manager.GetFocusOrder(first) == 1);
-
- //Test for new focus order
- DALI_TEST_CHECK(2 == manager.GenerateNewFocusOrder());
-
- // Set the focus order for the first actor
- manager.SetFocusOrder(second, 2);
- manager.SetAccessibilityAttribute(second, AccessibilityManager::ACCESSIBILITY_LABEL, "first");
- DALI_TEST_CHECK(manager.GetFocusOrder(second) == 2);
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerGetActorByFocusOrder(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerGetActorByFocusOrder");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- // Create the actors and set their focus orders
- Actor first = Actor::New();
- manager.SetFocusOrder(first, 1);
-
- Actor second = Actor::New();
- manager.SetFocusOrder(second, 2);
-
- Actor third = Actor::New();
- manager.SetFocusOrder(third, 3);
-
- // Check that we get an empty handle as no actor is added to the stage yet.
- DALI_TEST_CHECK(manager.GetActorByFocusOrder(1) == Actor());
- DALI_TEST_CHECK(manager.GetActorByFocusOrder(2) == Actor());
- DALI_TEST_CHECK(manager.GetActorByFocusOrder(3) == Actor());
-
- // Add the actors to the stage
- application.GetScene().Add(first);
- application.GetScene().Add(second);
- application.GetScene().Add(third);
-
- // Check that we get an empty handle because focus order 0 means undefined.
- DALI_TEST_CHECK(manager.GetActorByFocusOrder(0) == Actor());
-
- // Check that we get correct actors for the specified focus orders
- DALI_TEST_CHECK(manager.GetActorByFocusOrder(1) == first);
- DALI_TEST_CHECK(manager.GetActorByFocusOrder(2) == second);
- DALI_TEST_CHECK(manager.GetActorByFocusOrder(3) == third);
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- // Change the focus order of the third actor to 1
- manager.SetFocusOrder(third, 1);
-
- // Check that we still get correct actors after changing their focus orders
- DALI_TEST_CHECK(manager.GetActorByFocusOrder(1) == third);
- DALI_TEST_CHECK(manager.GetActorByFocusOrder(2) == first);
- DALI_TEST_CHECK(manager.GetActorByFocusOrder(3) == second);
-
- // Check that we get an empty handle because no actor has a focus order of 4
- DALI_TEST_CHECK(manager.GetActorByFocusOrder(4) == Actor());
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerSetAndGetCurrentFocusActor(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerSetAndGetCurrentFocusActor");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- // Create the first actor and add it to the stage
- Actor first = Actor::New();
- manager.SetFocusOrder(first, 1);
- application.GetScene().Add(first);
-
- // Create the second actor and add it to the stage
- Actor second = Actor::New();
- manager.SetFocusOrder(second, 2);
- application.GetScene().Add(second);
-
- // Create the third actor but don't add it to the stage
- Actor third = Actor::New();
- manager.SetFocusOrder(third, 3);
-
- // Check that no actor is being focused yet.
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
-
- // Check that it will fail to set focus on an invalid actor
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(Actor()) == false);
-
- // Check that the focus is set on the first actor
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
-
- // Check that the focus is set on the second actor
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
-
- // Check that it will fail to set focus on the third actor as it's not in the stage
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(third) == false);
-
- // Add the third actor to the stage
- application.GetScene().Add(third);
-
- // make the third actor invisible
- third.SetProperty( Actor::Property::VISIBLE,false);
- // flush the queue and render once
- application.SendNotification();
- application.Render();
-
- // Check that it will fail to set focus on the third actor as it's invisible
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(third) == false);
-
- // Make the third actor visible
- third.SetProperty( Actor::Property::VISIBLE,true);
- // flush the queue and render once
- application.SendNotification();
- application.Render();
-
- // Make the third actor not focusable
- Property::Index propertyActorFocusable = third.GetPropertyIndex("focusable");
- third.SetProperty(propertyActorFocusable, false);
- // flush the queue and render once
- application.SendNotification();
- application.Render();
-
- // Check that it will fail to set focus on the third actor as it's not focusable
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(third) == false);
-
- // Make the third actor focusable
- third.SetProperty(propertyActorFocusable, true);
- // flush the queue and render once
- application.SendNotification();
- application.Render();
-
- // Check that the focus is successfully moved to the third actor
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(third) == true);
-
- // Make the current focused actor to be not focusable by setting its focus order to be 0
- manager.SetFocusOrder(third, 0);
-
- // Check that the focus is automatically cleared
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
-
- // Set the focus order of the third actor again
- manager.SetFocusOrder(third, 3);
-
- // Check that the third actor can be focused successfully now
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(third) == true);
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerGetCurrentFocusGroup(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerGetCurrentFocusGroup");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- // Create an actor with two child actors and add it to the stage
- Actor parent = Actor::New();
- Actor firstChild = Actor::New();
- Actor secondChild = Actor::New();
- parent.Add(firstChild);
- parent.Add(secondChild);
- application.GetScene().Add(parent);
-
- // Create three actors and add them as the children of the first child actor
- Actor firstGrandChild = Actor::New();
- Actor secondGrandChild = Actor::New();
- Actor thirdGrandChild = Actor::New();
- firstChild.Add(firstGrandChild);
- firstChild.Add(secondGrandChild);
- firstChild.Add(thirdGrandChild);
-
- // Set focus order to the actors
- manager.SetFocusOrder(parent, 1);
- manager.SetFocusOrder(firstChild, 2);
- manager.SetFocusOrder(firstGrandChild, 3);
- manager.SetFocusOrder(secondGrandChild, 4);
- manager.SetFocusOrder(thirdGrandChild, 5);
- manager.SetFocusOrder(secondChild, 6);
-
- // Set the parent and the first child actor as focus groups
- manager.SetFocusGroup(parent, true);
- DALI_TEST_CHECK(manager.IsFocusGroup(parent) == true);
-
- // Set focus to the first grand child actor
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(firstGrandChild) == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == firstGrandChild);
-
- // The current focus group should be the parent, As it is the immediate parent which is also a focus group.
- DALI_TEST_CHECK(manager.GetCurrentFocusGroup() == parent);
-
- manager.SetFocusGroup(firstChild, true);
- DALI_TEST_CHECK(manager.IsFocusGroup(firstChild) == true);
-
- // The current focus group should be the firstChild, As it is the immediate parent which is also a focus group.
- DALI_TEST_CHECK(manager.GetCurrentFocusGroup() == firstChild);
-
- manager.SetFocusGroup(firstGrandChild, true);
- DALI_TEST_CHECK(manager.IsFocusGroup(firstGrandChild) == true);
-
- // The current focus group should be itself, As it is also a focus group.
- DALI_TEST_CHECK(manager.GetCurrentFocusGroup() == firstGrandChild);
-
- // Set focus to the second grand child actor
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(secondGrandChild) == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == secondGrandChild);
-
- // The current focus group should be the firstChild, As it is the immediate parent which is also a
- // focus group for the current focus actor.
- DALI_TEST_CHECK(manager.GetCurrentFocusGroup() == firstChild);
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerGetCurrentFocusOrder(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerGetCurrentFocusOrder");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- Actor first = Actor::New();
- application.GetScene().Add(first);
-
- Actor second = Actor::New();
- application.GetScene().Add(second);
-
- Actor third = Actor::New();
- application.GetScene().Add(third);
-
- // Set the focus order and description for the first actor
- manager.SetFocusOrder(first, 1);
- manager.SetAccessibilityAttribute(first, AccessibilityManager::ACCESSIBILITY_LABEL, "first");
- DALI_TEST_CHECK(manager.GetFocusOrder(first) == 1);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(first, AccessibilityManager::ACCESSIBILITY_LABEL) == "first");
-
- // Set the focus order and description for the second actor
- manager.SetFocusOrder(second, 2);
- manager.SetAccessibilityAttribute(second, AccessibilityManager::ACCESSIBILITY_LABEL, "second");
- DALI_TEST_CHECK(manager.GetFocusOrder(second) == 2);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(second, AccessibilityManager::ACCESSIBILITY_LABEL) == "second");
-
- // Set the focus order and description for the second actor
- manager.SetFocusOrder(third, 3);
- manager.SetAccessibilityAttribute(third, AccessibilityManager::ACCESSIBILITY_LABEL, "third");
- DALI_TEST_CHECK(manager.GetFocusOrder(third) == 3);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(third, AccessibilityManager::ACCESSIBILITY_LABEL) == "third");
-
- // Check that no actor is being focused yet.
- DALI_TEST_CHECK(manager.GetCurrentFocusOrder() == 0);
-
- // Set the focus on the first actor and test
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusOrder() == 1);
-
- // Move the focus forward to the second actor and test
- manager.MoveFocusForward();
- DALI_TEST_CHECK(manager.GetCurrentFocusOrder() == 2);
-
- // Move the focus forward to the third actor and test
- manager.MoveFocusForward();
- DALI_TEST_CHECK(manager.GetCurrentFocusOrder() == 3);
-
- // Clear focus and test
- manager.ClearFocus();
- DALI_TEST_CHECK(manager.GetCurrentFocusOrder() == 0);
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerMoveFocusForward(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerMoveFocusForward");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
- accAdaptor.HandleActionNextEvent(true);
-
- Actor first = Actor::New();
- application.GetScene().Add(first);
-
- Actor second = Actor::New();
- application.GetScene().Add(second);
-
- Actor third = Actor::New();
- application.GetScene().Add(third);
-
- // Set the focus order and description for the first actor
- manager.SetFocusOrder(first, 1);
- manager.SetAccessibilityAttribute(first, AccessibilityManager::ACCESSIBILITY_LABEL, "first");
- DALI_TEST_CHECK(manager.GetFocusOrder(first) == 1);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(first, AccessibilityManager::ACCESSIBILITY_LABEL) == "first");
-
- // Set the focus order and description for the second actor
- manager.SetFocusOrder(second, 2);
- manager.SetAccessibilityAttribute(second, AccessibilityManager::ACCESSIBILITY_LABEL, "second");
- DALI_TEST_CHECK(manager.GetFocusOrder(second) == 2);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(second, AccessibilityManager::ACCESSIBILITY_LABEL) == "second");
-
- // Set the focus order and description for the second actor
- manager.SetFocusOrder(third, 3);
- manager.SetAccessibilityAttribute(third, AccessibilityManager::ACCESSIBILITY_LABEL, "third");
- DALI_TEST_CHECK(manager.GetFocusOrder(third) == 3);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(third, AccessibilityManager::ACCESSIBILITY_LABEL) == "third");
-
- // Check that no actor is being focused yet.
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
-
- // Set the focus on the first actor
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(manager.GetCurrentFocusActor(), AccessibilityManager::ACCESSIBILITY_LABEL) == "first");
-
- // Test the non-wrapped move first
- manager.SetWrapMode(false);
- DALI_TEST_CHECK(manager.GetWrapMode() == false);
-
- // Move the focus forward to the second actor
- manager.MoveFocusForward();
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(manager.GetCurrentFocusActor(), AccessibilityManager::ACCESSIBILITY_LABEL) == "second");
-
- // Move the focus forward to the third actor
- manager.MoveFocusForward();
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == third);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(manager.GetCurrentFocusActor(), AccessibilityManager::ACCESSIBILITY_LABEL) == "third");
-
- // Check that it will fail to move the focus forward again as the third actor is the last
- // focusable actor in the focus chain
- manager.MoveFocusForward();
- // The focus should still be set on the third actor
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == third);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(manager.GetCurrentFocusActor(), AccessibilityManager::ACCESSIBILITY_LABEL) == "third");
-
- // Now test the wrapped move
- manager.SetWrapMode(true);
- DALI_TEST_CHECK(manager.GetWrapMode() == true);
-
- // Move the focus forward recursively and this time the first actor should be focused
- manager.MoveFocusForward();
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(manager.GetCurrentFocusActor(), AccessibilityManager::ACCESSIBILITY_LABEL) == "first");
-
- // Make the second actor not focusable
- Property::Index propertyActorFocusable = second.GetPropertyIndex("focusable");
- second.SetProperty(propertyActorFocusable, false);
- // flush the queue and render once
- application.SendNotification();
- application.Render();
-
- // Move the focus forward and check that the second actor should be skipped and
- // the third actor should be focused now.
- manager.MoveFocusForward();
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == third);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(manager.GetCurrentFocusActor(), AccessibilityManager::ACCESSIBILITY_LABEL) == "third");
-
- // Make the first actor invisible
- first.SetProperty( Actor::Property::VISIBLE,false);
- // flush the queue and render once
- application.SendNotification();
- application.Render();
-
- // Move the focus forward and check that the first actor should be skipped as it's
- // invisible and the second actor should also be skipped as it's not focusable,
- // so the focus will still be on the third actor
- manager.MoveFocusForward();
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == third);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(manager.GetCurrentFocusActor(), AccessibilityManager::ACCESSIBILITY_LABEL) == "third");
-
- // Make the third actor invisible so that no actor can be focused.
- third.SetProperty( Actor::Property::VISIBLE,false);
- // flush the queue and render once
- application.SendNotification();
- application.Render();
-
- // Check that the focus move is failed as all the three actors can not be focused
- manager.MoveFocusForward();
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == third);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(manager.GetCurrentFocusActor(), AccessibilityManager::ACCESSIBILITY_LABEL) == "third");
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerMoveFocusBackward(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerMoveFocusBackward");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- Actor first = Actor::New();
- application.GetScene().Add(first);
-
- Actor second = Actor::New();
- application.GetScene().Add(second);
-
- Actor third = Actor::New();
- application.GetScene().Add(third);
-
- // Set the focus order and description for the first actor
- manager.SetFocusOrder(first, 1);
- manager.SetAccessibilityAttribute(first, AccessibilityManager::ACCESSIBILITY_LABEL, "first");
- DALI_TEST_CHECK(manager.GetFocusOrder(first) == 1);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(first, AccessibilityManager::ACCESSIBILITY_LABEL) == "first");
-
- // Set the focus order and description for the second actor
- manager.SetFocusOrder(second, 2);
- manager.SetAccessibilityAttribute(second, AccessibilityManager::ACCESSIBILITY_LABEL, "second");
- DALI_TEST_CHECK(manager.GetFocusOrder(second) == 2);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(second, AccessibilityManager::ACCESSIBILITY_LABEL) == "second");
-
- // Set the focus order and description for the second actor
- manager.SetFocusOrder(third, 3);
- manager.SetAccessibilityAttribute(third, AccessibilityManager::ACCESSIBILITY_LABEL, "third");
- DALI_TEST_CHECK(manager.GetFocusOrder(third) == 3);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(third, AccessibilityManager::ACCESSIBILITY_LABEL) == "third");
-
- // Check that no actor is being focused yet.
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
-
- // Set the focus on the third actor
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(third) == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == third);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(manager.GetCurrentFocusActor(), AccessibilityManager::ACCESSIBILITY_LABEL) == "third");
-
- // Test the non-wrapped move first
- manager.SetWrapMode(false);
- DALI_TEST_CHECK(manager.GetWrapMode() == false);
-
- // Move the focus backward to the second actor
- manager.MoveFocusBackward();
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(manager.GetCurrentFocusActor(), AccessibilityManager::ACCESSIBILITY_LABEL) == "second");
-
- // Move the focus backward to the first actor
- manager.MoveFocusBackward();
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(manager.GetCurrentFocusActor(), AccessibilityManager::ACCESSIBILITY_LABEL) == "first");
-
- // Check that it will fail to move the focus backward again as the first actor is the first
- // focusable actor in the focus chain
- manager.MoveFocusBackward();
- // The focus should still be set on the first actor
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(manager.GetCurrentFocusActor(), AccessibilityManager::ACCESSIBILITY_LABEL) == "first");
-
- // Now test the wrapped move
- manager.SetWrapMode(true);
- DALI_TEST_CHECK(manager.GetWrapMode() == true);
-
- // Move the focus backward recursively and this time the third actor should be focused
- manager.MoveFocusBackward();
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == third);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(manager.GetCurrentFocusActor(), AccessibilityManager::ACCESSIBILITY_LABEL) == "third");
-
- // Make the second actor not focusable
- Property::Index propertyActorFocusable = second.GetPropertyIndex("focusable");
- second.SetProperty(propertyActorFocusable, false);
- // flush the queue and render once
- application.SendNotification();
- application.Render();
-
- // Move the focus backward and check that the second actor should be skipped and
- // the first actor should be focused now.
- manager.MoveFocusBackward();
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(manager.GetCurrentFocusActor(), AccessibilityManager::ACCESSIBILITY_LABEL) == "first");
-
- // Make the third actor invisible
- third.SetProperty( Actor::Property::VISIBLE,false);
- // flush the queue and render once
- application.SendNotification();
- application.Render();
-
- // Move the focus backward and check that the third actor should be skipped as it's
- // invisible and the second actor should also be skipped as it's not focusable,
- // so the focus will still be on the first actor
- manager.MoveFocusBackward();
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(manager.GetCurrentFocusActor(), AccessibilityManager::ACCESSIBILITY_LABEL) == "first");
-
- // Make the first actor invisible so that no actor can be focused.
- first.SetProperty( Actor::Property::VISIBLE,false);
- // flush the queue and render once
- application.SendNotification();
- application.Render();
-
- // Check that the focus move is failed as all the three actors can not be focused
- manager.MoveFocusBackward();
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
- DALI_TEST_CHECK(manager.GetAccessibilityAttribute(manager.GetCurrentFocusActor(), AccessibilityManager::ACCESSIBILITY_LABEL) == "first");
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerClearFocus(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerClearFocus");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- // Create the first actor and add it to the stage
- Actor first = Actor::New();
- manager.SetFocusOrder(first, 1);
- application.GetScene().Add(first);
-
- // Create the second actor and add it to the stage
- Actor second = Actor::New();
- manager.SetFocusOrder(second, 2);
- application.GetScene().Add(second);
-
- // Check that no actor is being focused yet.
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
-
- // Check that the focus is set on the first actor
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
-
- // Check that the focus is set on the second actor
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
-
- // Clear the focus
- manager.ClearFocus();
-
- // Check that no actor is being focused now.
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerReset(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerReset");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- // Create the first actor and add it to the stage
- Actor first = Actor::New();
- manager.SetFocusOrder(first, 1);
- application.GetScene().Add(first);
-
- // Create the second actor and add it to the stage
- Actor second = Actor::New();
- manager.SetFocusOrder(second, 2);
- application.GetScene().Add(second);
-
- // Check that no actor is being focused yet.
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
-
- // Check that the focus is set on the first actor
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
-
- // Check that the focus is set on the second actor
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
-
- // Clear the focus
- manager.Reset();
-
- // Check that no actor is being focused now and the focus order of actors have been cleared
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
- DALI_TEST_CHECK(manager.GetFocusOrder(first) == 0);
- DALI_TEST_CHECK(manager.GetFocusOrder(first) == 0);
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerFocusGroup(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerFocusGroup");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- // Create an actor with two child actors and add it to the stage
- Actor parent = Actor::New();
- Actor firstChild = Actor::New();
- Actor secondChild = Actor::New();
- parent.Add(firstChild);
- parent.Add(secondChild);
- application.GetScene().Add(parent);
-
- // Create three actors and add them as the children of the first child actor
- Actor firstGrandChild = Actor::New();
- Actor secondGrandChild = Actor::New();
- Actor thirdGrandChild = Actor::New();
- firstChild.Add(firstGrandChild);
- firstChild.Add(secondGrandChild);
- firstChild.Add(thirdGrandChild);
-
- // Set focus order to the actors
- manager.SetFocusOrder(parent, 1);
- manager.SetFocusOrder(firstChild, 2);
- manager.SetFocusOrder(firstGrandChild, 3);
- manager.SetFocusOrder(secondGrandChild, 4);
- manager.SetFocusOrder(thirdGrandChild, 5);
- manager.SetFocusOrder(secondChild, 6);
-
- // Set the parent and the first child actor as focus groups
- manager.SetFocusGroup(parent, true);
- DALI_TEST_CHECK(manager.IsFocusGroup(parent) == true);
-
- // The focus group of the parent should be itself, as it is set to be a focus group.
- DALI_TEST_CHECK(manager.GetFocusGroup(parent) == parent);
-
- // The focus group of the firstChild should be its parent, as it is the immediate parent which is also a group.
- DALI_TEST_CHECK(manager.GetFocusGroup(firstChild) == parent);
-
- manager.SetFocusGroup(firstChild, true);
- DALI_TEST_CHECK(manager.IsFocusGroup(firstChild) == true);
-
- // The focus group of the firstChild should be itself, as it is set to be a focus group now.
- DALI_TEST_CHECK(manager.GetFocusGroup(firstChild) == firstChild);
-
- // Enable wrap mode for focus movement.
- manager.SetWrapMode(true);
- DALI_TEST_CHECK(manager.GetWrapMode() == true);
-
- // Check that no actor is being focused yet.
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
-
- // Check that the focus is set on the parent actor.
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(parent) == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == parent);
-
- // Check that group mode is disabled.
- DALI_TEST_CHECK(manager.GetGroupMode() == false);
-
- // Check that the focus movement is wrapped as normal.
- DALI_TEST_CHECK(manager.MoveFocusForward() == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == firstChild);
- DALI_TEST_CHECK(manager.MoveFocusForward() == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == firstGrandChild);
- DALI_TEST_CHECK(manager.MoveFocusForward() == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == secondGrandChild);
- DALI_TEST_CHECK(manager.MoveFocusForward() == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == thirdGrandChild);
- DALI_TEST_CHECK(manager.MoveFocusForward() == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == secondChild);
- DALI_TEST_CHECK(manager.MoveFocusForward() == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == parent);
- DALI_TEST_CHECK(manager.MoveFocusForward() == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == firstChild);
- DALI_TEST_CHECK(manager.MoveFocusForward() == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == firstGrandChild);
-
- // Enable the group mode.
- manager.SetGroupMode(true);
- DALI_TEST_CHECK(manager.GetGroupMode() == true);
-
- // Check that the focus movement is now limited to the current focus group.
- DALI_TEST_CHECK(manager.MoveFocusForward() == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == secondGrandChild);
- DALI_TEST_CHECK(manager.MoveFocusForward() == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == thirdGrandChild);
- DALI_TEST_CHECK(manager.MoveFocusForward() == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == firstChild);
- DALI_TEST_CHECK(manager.MoveFocusForward() == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == firstGrandChild);
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerSetAndGetFocusIndicator(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerSetAndGetFocusIndicator");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- Actor defaultFocusIndicatorActor = manager.GetFocusIndicatorActor();
- DALI_TEST_CHECK(defaultFocusIndicatorActor);
-
- Actor newFocusIndicatorActor = Actor::New();
- manager.SetFocusIndicatorActor(newFocusIndicatorActor);
- DALI_TEST_CHECK(manager.GetFocusIndicatorActor() == newFocusIndicatorActor);
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerSetAndGetFocusIndicatorWithFocusedActor(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerSetAndGetFocusIndicatorWithFocusedActor");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- Actor defaultFocusIndicatorActor = manager.GetFocusIndicatorActor();
- DALI_TEST_CHECK(defaultFocusIndicatorActor);
-
- Actor focusedActor = Actor::New();
- application.GetScene().Add( focusedActor );
-
- application.SendNotification();
- application.Render();
-
- DALI_TEST_EQUALS( focusedActor.GetChildCount(), 0u, TEST_LOCATION );
-
- manager.SetFocusOrder( focusedActor, 1 );
- manager.SetCurrentFocusActor( focusedActor );
-
- DALI_TEST_EQUALS( focusedActor.GetChildCount(), 1u, TEST_LOCATION );
- DALI_TEST_CHECK( focusedActor.GetChildAt(0) == defaultFocusIndicatorActor );
-
- Actor newFocusIndicatorActor = Actor::New();
- manager.SetFocusIndicatorActor( newFocusIndicatorActor );
- DALI_TEST_CHECK(manager.GetFocusIndicatorActor() == newFocusIndicatorActor);
- DALI_TEST_EQUALS( focusedActor.GetChildCount(), 1u, TEST_LOCATION );
- DALI_TEST_CHECK( focusedActor.GetChildAt(0) == newFocusIndicatorActor );
-
- // Disable Accessibility
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, false );
- accAdaptor.HandleActionEnableEvent();
-
- DALI_TEST_EQUALS( focusedActor.GetChildCount(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerSignalFocusChanged(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerSignalFocusChanged");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- bool signalVerified = false;
- FocusChangedCallback callback(signalVerified);
- manager.FocusChangedSignal().Connect( &callback, &FocusChangedCallback::Callback );
-
- // Create the first actor and add it to the stage
- Actor first = Actor::New();
- manager.SetFocusOrder(first, 1);
- application.GetScene().Add(first);
-
- // Create the second actor and add it to the stage
- Actor second = Actor::New();
- manager.SetFocusOrder(second, 2);
- application.GetScene().Add(second);
-
- // Check that no actor is being focused yet.
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
-
- // Check that the focus is set on the first actor
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
- DALI_TEST_CHECK(callback.mSignalVerified);
- callback.Reset();
-
- // Check that the focus is set on the second actor
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
- DALI_TEST_CHECK(callback.mSignalVerified);
- callback.Reset();
-
- // Clear the focus
- manager.ClearFocus();
-
- // Check that no actor is being focused now.
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
- DALI_TEST_CHECK(callback.mSignalVerified);
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerSignalFocusOvershot(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerSignalFocusOvershot");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- bool signalVerified = false;
- FocusOvershotCallback callback(signalVerified);
- manager.FocusOvershotSignal().Connect(&callback, &FocusOvershotCallback::Callback);
-
- // Create the first actor and add it to the stage
- Actor first = Actor::New();
- manager.SetFocusOrder(first, 1);
- application.GetScene().Add(first);
-
- // Create the second actor and add it to the stage
- Actor second = Actor::New();
- manager.SetFocusOrder(second, 2);
- application.GetScene().Add(second);
-
- // Check that the wrap mode is disabled
- DALI_TEST_CHECK(manager.GetWrapMode() == false);
-
- // Check that the focus is set on the first actor
- DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
-
- // Check that the focus is moved to the second actor successfully.
- DALI_TEST_CHECK(manager.MoveFocusForward() == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
-
- // Check that the forward focus movement is overshot.
- callback.mCurrentFocusedActor = second;
- callback.mFocusOvershotDirection = Toolkit::AccessibilityManager::OVERSHOT_NEXT;
- DALI_TEST_CHECK(manager.MoveFocusForward() == false);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
- DALI_TEST_CHECK(signalVerified);
- callback.Reset();
-
- // Enable the wrap mode
- manager.SetWrapMode(true);
- DALI_TEST_CHECK(manager.GetWrapMode() == true);
-
- // Check that the forward focus movement is wrapped and no overshot happens.
- DALI_TEST_CHECK(manager.MoveFocusForward() == true);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
- DALI_TEST_CHECK(signalVerified == false);
-
- // Disable the wrap mode
- manager.SetWrapMode(false);
- DALI_TEST_CHECK(manager.GetWrapMode() == false);
-
- // Check that the backward focus movement is overshot.
- callback.mCurrentFocusedActor = first;
- callback.mFocusOvershotDirection = Toolkit::AccessibilityManager::OVERSHOT_PREVIOUS;
- DALI_TEST_CHECK(manager.MoveFocusBackward() == false);
- DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
- DALI_TEST_CHECK(signalVerified);
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerSignalFocusedActorActivated(void)
-{
- ToolkitTestApplication application;
-
- tet_infoline(" UtcDaliAccessibilityManagerSignalFocusedActorActivated");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK(manager);
-
- FocusedActorActivatedCallback callback;
- manager.FocusedActorActivatedSignal().Connect(&callback, &FocusedActorActivatedCallback::Callback);
- DALI_TEST_CHECK(true);
-
- END_TEST;
-}
-
-// Note: No negative test for GetReadPosition as it will always return something.
-int UtcDaliAccessibilityManagerGetReadPositionP(void)
-{
- ToolkitTestApplication application;
- tet_infoline(" UtcDaliAccessibilityManagerGetReadPositionP");
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- Vector2 readPosition( manager.GetReadPosition() );
- DALI_TEST_EQUALS( readPosition.x, 0.0f, Math::MACHINE_EPSILON_0, TEST_LOCATION );
- DALI_TEST_EQUALS( readPosition.y, 0.0f, Math::MACHINE_EPSILON_0, TEST_LOCATION );
-
- END_TEST;
-}
-
-// Functor to test if an accessibility signal has been called.
-class AccessibilityManagerSignalHandler : public Dali::ConnectionTracker
-{
-public:
- AccessibilityManagerSignalHandler() :
- mCalls( 0 )
- {
- }
-
- bool Callback( AccessibilityManager& accessibilityManager )
- {
- mCalls++;
- tet_infoline( "Signal called" );
- return true;
- }
-
- unsigned int GetCalls() const
- {
- return mCalls;
- }
-
-private:
- unsigned int mCalls; ///< Keeps track of how many times the signal has been called.
-};
-
-int UtcDaliAccessibilityManagerStatusChangedSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerStatusChangedSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.StatusChangedSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- // Cause a state change.
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionEnableEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerStatusChangedSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerStatusChangedSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.StatusChangedSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionNextSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionNextSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionNextSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionNextEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionNextSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionNextSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionNextSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionPreviousSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionPreviousSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionPreviousSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionPreviousEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionPreviousSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionPreviousSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionPreviousSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionActivateSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionActivateSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- Dali::Toolkit::PushButton button = Dali::Toolkit::PushButton::New();
- button.SetProperty( Actor::Property::SIZE, Vector2(480, 800) );
- application.GetScene().Add(button);
- manager.SetFocusOrder( button, 1 );
- manager.SetCurrentFocusActor( button );
-
- manager.ActionActivateSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionActivateEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionActivateSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionActivateSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionActivateSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionReadSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionReadSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionReadSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionReadEvent( 100.0f, 200.0f, true );
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionReadSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionReadSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionReadSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionOverSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionOverSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionOverSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- // Note that the ActionOverSignal is provoked by a read even when "allow read again" is set to false.
- accessibilityAdaptor.HandleActionReadEvent( 100.0f, 200.0f, false );
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionOverSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionOverSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionOverSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionReadNextSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionReadNextSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionReadNextSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionReadNextEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionReadNextSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionReadNextSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionReadNextSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionReadPreviousSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionReadPreviousSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionReadPreviousSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionReadPreviousEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionReadPreviousSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionReadPreviousSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionReadPreviousSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionUpSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionUpSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accessibilityAdaptor, true );
- accessibilityAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionUpSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- DummyControl dummyControl = DummyControl::New(true);
- dummyControl.SetProperty( Actor::Property::SIZE, Vector2(480, 800) );
- manager.SetFocusOrder( dummyControl, 1 );
- application.GetScene().Add( dummyControl );
- manager.SetCurrentFocusActor( dummyControl );
-
- accessibilityAdaptor.HandleActionUpEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionUpSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionUpSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionUpSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionDownSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionDownSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accessibilityAdaptor, true );
- accessibilityAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionDownSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::Toolkit::PushButton button = Dali::Toolkit::PushButton::New();
- button.SetProperty( Actor::Property::SIZE, Vector2(480, 800) );
- application.GetScene().Add(button);
- manager.SetFocusOrder( button, 1 );
- manager.SetCurrentFocusActor( button );
-
- accessibilityAdaptor.HandleActionDownEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionDownSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionDownSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionDownSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionClearFocusSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionClearFocusSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionClearFocusSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionClearFocusEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionClearFocusSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionClearFocusSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionClearFocusSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionBackSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionBackSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionBackSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionBackEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionBackSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionBackSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionBackSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionScrollUpSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionScrollUpSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionScrollUpSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionScrollUpEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionScrollUpSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionScrollUpSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionScrollUpSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionScrollDownSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionScrollDownSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionScrollDownSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionScrollDownEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionScrollDownSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionScrollDownSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionScrollDownSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionPageLeftSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionPageLeftSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionPageLeftSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionPageLeftEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionPageLeftSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionPageLeftSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionPageLeftSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionPageRightSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionPageRightSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionPageRightSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionPageRightEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionPageRightSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionPageRightSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionPageRightSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionPageUpSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionPageUpSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionPageUpSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionPageUpEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionPageUpSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionPageUpSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionPageUpSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionPageDownSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionPageDownSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionPageDownSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionPageDownEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionPageDownSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionPageDownSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionPageDownSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionMoveToFirstSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionMoveToFirstSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionMoveToFirstSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionMoveToFirstEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-
-int UtcDaliAccessibilityManagerActionMoveToFirstSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionMoveToFirstSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionMoveToFirstSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionMoveToLastSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionMoveToLastSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionMoveToLastSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionMoveToLastEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionMoveToLastSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionMoveToLastSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionMoveToLastSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionReadFromTopSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionReadFromTopSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionReadFromTopSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionReadFromTopEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionReadFromTopSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionReadFromTopSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionReadFromTopSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionReadFromNextSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionReadFromNextSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionReadFromNextSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionReadFromNextEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionReadFromNextSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionReadFromNextSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionReadFromNextSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionZoomSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionZoomSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- Dali::Toolkit::PushButton button = Dali::Toolkit::PushButton::New();
- button.SetProperty( Actor::Property::SIZE, Vector2(480, 800) );
- application.GetScene().Add(button);
- manager.SetFocusOrder( button, 1 );
- manager.SetCurrentFocusActor( button );
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- manager.ActionZoomSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionZoomEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionZoomSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionZoomSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionZoomSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionReadPauseResumeSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionReadPauseResumeSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
- Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
- accAdaptor.HandleActionEnableEvent();
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionReadPauseResumeSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionReadPauseResumeEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionReadPauseResumeSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionReadPauseResumeSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionReadPauseResumeSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionStartStopSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionStartStopSignalP" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionStartStopSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- accessibilityAdaptor.HandleActionStartStopEvent();
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionStartStopSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionStartStopSignalN" );
-
- AccessibilityManagerSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionStartStopSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-// Functor to test if a accessibility scroll signal has been called.
-class AccessibilityManagerScrollSignalHandler : public Dali::ConnectionTracker
-{
-public:
- AccessibilityManagerScrollSignalHandler() :
- mCalls( 0 )
- {
- }
-
- bool Callback( AccessibilityManager& accessibilityManager, const Dali::TouchEvent& touchEvent )
- {
- mCalls++;
- Dali::TouchEvent handle(touchEvent); // Ensure it's ref-counted
- mTouchEvent = handle;
- tet_infoline( "Signal called" );
- return true;
- }
-
- unsigned int GetCalls() const
- {
- return mCalls;
- }
-
- const Dali::TouchEvent& GetTouchEvent() const
- {
- return mTouchEvent;
- }
-
-private:
- unsigned int mCalls; ///< Keeps track of how many times the signal has been called.
- Dali::TouchEvent mTouchEvent ; ///< Stores the last touch event received.
-};
-
-int UtcDaliAccessibilityManagerActionScrollSignalP(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionScrollSignalP" );
-
- AccessibilityManagerScrollSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionScrollSignal().Connect( &callback, &AccessibilityManagerScrollSignalHandler::Callback );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
-
- TouchPoint point( 0, PointState::STARTED, 100.0f, 200.0f );
- accessibilityAdaptor.HandleActionScrollEvent( point, 0u );
-
- DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
- const TouchEvent& signalTouchEvent = callback.GetTouchEvent();
- DALI_TEST_EQUALS( signalTouchEvent.GetPointCount(), 1u, TEST_LOCATION );
-
-
- DALI_TEST_EQUALS( signalTouchEvent.GetState(0), PointState::STARTED, TEST_LOCATION );
- DALI_TEST_EQUALS( signalTouchEvent.GetScreenPosition(0).x, 100.0f, TEST_LOCATION );
- DALI_TEST_EQUALS( signalTouchEvent.GetScreenPosition(0).y, 200.0f, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerActionScrollSignalN(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerActionScrollSignalN" );
-
- AccessibilityManagerScrollSignalHandler callback;
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- manager.ActionScrollSignal().Connect( &callback, &AccessibilityManagerScrollSignalHandler::Callback );
-
- DALI_TEST_EQUALS( callback.GetCalls(), 0u, TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliAccessibilityManagerHandlePanGesture(void)
-{
- // Pan gesture sent from adaptor to manager via AccessibilityGestureHandler
- // Adaptor.SetGestureHandler is called in Initialize (check it's the toolkit version)
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliAccessibilityManagerHandlePanGesture" );
-
- AccessibilityManager manager = AccessibilityManager::Get();
- DALI_TEST_CHECK( manager );
-
- Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
- DummyControl dummyControl = DummyControl::New(true);
- dummyControl.SetProperty( Actor::Property::SIZE, Vector2(480, 800) );
- application.GetScene().Add( dummyControl );
-
- AccessibilityGestureEvent panGestureEvent(AccessibilityGestureEvent::STARTED);
- panGestureEvent.previousPosition = Vector2(0.f, 0.f);
- panGestureEvent.currentPosition = Vector2(100.f, 0.f);
- panGestureEvent.timeDelta = 16;
- panGestureEvent.numberOfTouches = 1;
-
- Test::AccessibilityAdaptor::SendPanGesture( accessibilityAdaptor, panGestureEvent );
-
- panGestureEvent.state = AccessibilityGestureEvent::CONTINUING;
- panGestureEvent.previousPosition = Vector2(100.f, 0.f);
- panGestureEvent.currentPosition = Vector2(200.f, 0.f);
- Test::AccessibilityAdaptor::SendPanGesture( accessibilityAdaptor, panGestureEvent );
-
- panGestureEvent.state = AccessibilityGestureEvent::FINISHED;
- panGestureEvent.previousPosition = Vector2(200.f, 0.f);
- panGestureEvent.currentPosition = Vector2(300.f, 0.f);
- Test::AccessibilityAdaptor::SendPanGesture( accessibilityAdaptor, panGestureEvent );
-
-
- END_TEST;
-}
-
-// Methods missing coverage:
-// IsActorFocusableFunction
-// DoActivate
-// SetFocusable
-// TtsStateChanged
int UtcDaliButtonConstructorP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
Button button;
int UtcDaliButtonCopyConstructorP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
// Initialize an object, ref count == 1
Button button = PushButton::New();
int UtcDaliButtonAssignmentOperatorP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
Button button = PushButton::New();
int UtcDaliButtonDownCastP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
Button button = PushButton::New();
int UtcDaliButtonDownCastN(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
BaseHandle unInitializedObject;
int UtcDaliControlWrapperDestructor(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
ControlWrapper control = ControlWrapper::New( customControlTypeName, *( new Toolkit::Internal::ControlWrapper( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT ) ) );
int UtcDaliControlWrapperRelayoutRequest(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
DALI_TEST_EQUALS( gOnRelayout, false, TEST_LOCATION );
int UtcDaliControlWrapperImplGetHeightForWidthBase(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
int UtcDaliControlWrapperGetWidthForHeightBase(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
int UtcDaliControlWrapperCalculateChildSizeBase(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
int UtcDaliControlWrapperRelayoutDependentOnChildrenBase(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
int UtcDaliControlWrapperTransitionDataMap1N(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
Property::Map map;
map["target"] = "Actor1";
int UtcDaliPushButtonConstructorP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
PushButton button;
int UtcDaliPushButtonCopyConstructorP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
// Initialize an object, ref count == 1
PushButton button = PushButton::New();
int UtcDaliPushButtonAssignmentOperatorP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
PushButton button = PushButton::New();
int UtcDaliPushButtonNewP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
PushButton button = PushButton::New();
int UtcDaliPushButtonDownCastP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
PushButton button = PushButton::New();
int UtcDaliPushButtonDownCastN(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
BaseHandle unInitializedObject;
int UtcDaliRadioButtonConstructorP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
RadioButton button;
int UtcDaliRadioButtonCopyConstructorP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
// Initialize an object, ref count == 1
RadioButton button = RadioButton::New();
int UtcDaliRadioButtonAssignmentOperatorP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
RadioButton button = RadioButton::New();
int UtcDaliScene3dViewConstructorP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
Scene3dView scene3dView;
int UtcDaliScene3dViewCopyConstructorP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
// Initialize an object, ref count == 1
Scene3dView scene3dView = Scene3dView::New( TEST_GLTF_FILE_NAME[0] );
int UtcDaliScene3dViewCopyConstructor2P(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
// Initialize an object, ref count == 1
Toolkit::Scene3dView scene3dView = Toolkit::Scene3dView::New( TEST_GLTF_FILE_NAME[0], TEST_DIFFUSE_TEXTURE, TEST_SPECULAR_TEXTURE, Vector4::ONE );
int UtcDaliScene3dViewAssignmentOperatorP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
Scene3dView scene3dView = Scene3dView::New( TEST_GLTF_FILE_NAME[0] );
int UtcDaliTableViewCtorCopyP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
TableView actor1 = TableView::New(10,10);
TableView actor2( actor1 );
//text is "c"
DALI_TEST_EQUALS( "c", editor.GetProperty<std::string>( TextEditor::Property::TEXT ), TEST_LOCATION );
+ // select all text
+ DevelTextEditor::SelectWholeText(editor);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Copy the selected text using logical keys
+ application.ProcessEvent( GenerateKey( "", "", "", Dali::DevelKey::DALI_KEY_CONTROL_LEFT, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+ application.ProcessEvent( GenerateKey( "ؤ", "c", "ؤ", KEY_C_CODE, KEY_CONTROL_MODIFIER, 0, Integration::KeyEvent::DOWN, "c", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // select none
+ DevelTextEditor::SelectNone(editor);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Paste the selected using logical keys
+ application.ProcessEvent( GenerateKey( "", "", "", Dali::DevelKey::DALI_KEY_CONTROL_LEFT, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+ application.ProcessEvent( GenerateKey( "ر", "v", "ر", KEY_V_CODE, KEY_CONTROL_MODIFIER, 0, Integration::KeyEvent::DOWN, "v", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+ //text is "cc"
+ DALI_TEST_EQUALS( "cc", editor.GetProperty<std::string>( TextEditor::Property::TEXT ), TEST_LOCATION );
+
+ // select all using logical keys
+ application.ProcessEvent( GenerateKey( "", "", "", Dali::DevelKey::DALI_KEY_CONTROL_LEFT, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+ application.ProcessEvent( GenerateKey( "Ø´", "a", "Ø´", KEY_A_CODE, KEY_CONTROL_MODIFIER, 0, Integration::KeyEvent::DOWN, "a", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // cut text using logical keys
+ application.ProcessEvent( GenerateKey( "", "", "", Dali::DevelKey::DALI_KEY_CONTROL_LEFT, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+ application.ProcessEvent( GenerateKey( "Ø¡", "x", "Ø¡", KEY_X_CODE, KEY_CONTROL_MODIFIER, 0, Integration::KeyEvent::DOWN, "x", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ //text is ""
+ DALI_TEST_EQUALS( "", editor.GetProperty<std::string>( TextEditor::Property::TEXT ), TEST_LOCATION );
+
END_TEST;
}
END_TEST;
}
+
+int UtcDaliTextEditorScrolling(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextEditorScrolling ");
+
+ TextEditor textEditor = TextEditor::New();
+ DALI_TEST_CHECK( textEditor );
+
+ application.GetScene().Add( textEditor );
+
+ // Avoid a crash when core load gl resources.
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+ application.SendNotification();
+ application.Render();
+
+ textEditor.SetProperty(TextEditor::Property::TEXT, "Tex1\nTex2\nTex3\nTex4\nTex5\nTex6\nTex7\nTex8");
+ textEditor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER);
+ textEditor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
+ textEditor.SetProperty(Actor::Property::SIZE, Vector2(60.0f, 160.0f));
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( textEditor.GetProperty( DevelTextEditor::Property::VERTICAL_SCROLL_POSITION ).Get<float>(), 0.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( textEditor.GetProperty( DevelTextEditor::Property::HORIZONTAL_SCROLL_POSITION ).Get<float>(), 0.0f, TEST_LOCATION );
+
+
+ DevelTextEditor::ScrollBy(textEditor, Vector2(1.0f, 1.0f));
+
+ DALI_TEST_EQUALS( textEditor.GetProperty( DevelTextEditor::Property::VERTICAL_SCROLL_POSITION ).Get<float>(), 1.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( textEditor.GetProperty( DevelTextEditor::Property::HORIZONTAL_SCROLL_POSITION ).Get<float>(), 0.0f, TEST_LOCATION );
+
+ DevelTextEditor::ScrollBy(textEditor, Vector2(0.0f, 1000.0f));
+
+ DALI_TEST_NOT_EQUALS( textEditor.GetProperty( DevelTextEditor::Property::VERTICAL_SCROLL_POSITION ).Get<float>(), 1.0f, 0.1f, TEST_LOCATION );
+ DALI_TEST_EQUALS( textEditor.GetProperty( DevelTextEditor::Property::HORIZONTAL_SCROLL_POSITION ).Get<float>(), 0.0f, TEST_LOCATION );
+
+ textEditor.SetProperty(DevelTextEditor::Property::VERTICAL_SCROLL_POSITION , 0.0f);
+ textEditor.SetProperty(DevelTextEditor::Property::HORIZONTAL_SCROLL_POSITION , 0.0f);
+
+ DALI_TEST_EQUALS( textEditor.GetProperty( DevelTextEditor::Property::VERTICAL_SCROLL_POSITION ).Get<float>(), 0.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( textEditor.GetProperty( DevelTextEditor::Property::HORIZONTAL_SCROLL_POSITION ).Get<float>(), 0.0f, TEST_LOCATION );
+
+ END_TEST;
+}
int UtcDaliToggleButtonConstructorP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
tet_infoline(" UtcDaliToggleButtonConstructorP");
ToggleButton button;
int UtcDaliToggleButtonCopyConstructorP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
tet_infoline(" UtcDaliToggleButtonCopyConstructorP");
// Initialize an object, ref count == 1
int UtcDaliToggleButtonAssignmentOperatorP(void)
{
- TestApplication application;
+ ToolkitTestApplication application;
tet_infoline(" UtcDaliToggleButtonAssignmentOperatorP");
ToggleButton button = ToggleButton::New();
ALIASES += SINCE_1_3="@since 1.3"
ALIASES += SINCE_1_4="@since 1.4"
ALIASES += SINCE_1_9="@since 1.9"
+ALIASES += SINCE_2_0="@since 2.0"
# Extra tags for Tizen 3.0
ALIASES += SINCE_1_2_2="@since 1.2.2"
ALIASES += DEPRECATED_1_3_39="@deprecated Deprecated since 1.3.39"
ALIASES += DEPRECATED_1_3_51="@deprecated Deprecated since 1.3.51"
ALIASES += DEPRECATED_1_4="@deprecated Deprecated since 1.4"
+ALIASES += DEPRECATED_2_0="@deprecated Deprecated since 2.0"
ALIASES += PLATFORM=""
ALIASES += PRIVLEVEL_PLATFORM=""
#ALIASES += SINCE_1_3="\par Since:\n 5.0, DALi version 1.3"
#ALIASES += SINCE_1_4="\par Since:\n 5.5, DALi version 1.4"
#ALIASES += SINCE_1_9="\par Since:\n 6.0, DALi version 1.9"
+#ALIASES += SINCE_2_0="\par Since:\n 6.0, DALi version 2.0"
## Extra tags for Tizen 3.0
#ALIASES += SINCE_1_2_2="\par Since:\n 3.0, DALi version 1.2.2"
ALIASES += SINCE_1_3="@since 1.3"
ALIASES += SINCE_1_4="@since 1.4"
ALIASES += SINCE_1_9="@since 1.9"
+ALIASES += SINCE_2_0="@since 2.0"
# Extra tags for Tizen 3.0
ALIASES += SINCE_1_2_2="@since 1.2.2"
ALIASES += DEPRECATED_1_3_39="@deprecated Deprecated since 1.3.39"
ALIASES += DEPRECATED_1_3_51="@deprecated Deprecated since 1.3.51"
ALIASES += DEPRECATED_1_4="@deprecated Deprecated since 1.4"
+ALIASES += DEPRECATED_2_0="@deprecated Deprecated since 2.0"
ALIASES += PLATFORM=""
ALIASES += PRIVLEVEL_PLATFORM=""
#ALIASES += SINCE_1_3="\par Since:\n 5.0, DALi version 1.3"
#ALIASES += SINCE_1_4="\par Since:\n 5.5, DALi version 1.4"
#ALIASES += SINCE_1_9="\par Since:\n 6.0, DALi version 1.9"
+#ALIASES += SINCE_2_0="\par Since:\n 6.0, DALi version 2.0"
## Extra tags for Tizen 3.0
#ALIASES += SINCE_1_2_2="\par Since:\n 3.0, DALi version 1.2.2"
#ALIASES += DEPRECATED_1_3_39="@deprecated Deprecated since 5.5, DALi version 1.3.39"
#ALIASES += DEPRECATED_1_3_51="@deprecated Deprecated since 5.5, DALi version 1.3.51"
#ALIASES += DEPRECATED_1_4="@deprecated Deprecated since 5.5, DALi version 1.4"
+#ALIASES += DEPRECATED_2_0="@deprecated Deprecated since 5.5, DALi version 2.0"
#ALIASES += PLATFORM="@platform"
#ALIASES += PRIVLEVEL_PLATFORM="\par Privilege Level:\n platform"
// If not, create the accessibility manager and register it as a singleton
Internal::AccessibilityManager* internalManager = new Internal::AccessibilityManager();
manager = AccessibilityManager(internalManager);
- internalManager->Initialise();
singletonService.Register(typeid(manager), manager);
}
}
#include "control-devel.h"
// EXTERNAL INCLUDES
+#include <dali/public-api/actors/actor.h>
#include <dali/public-api/animation/animation.h>
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/visual-factory/transition-data.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/public-api/controls/control.h>
#include <dali-toolkit/public-api/controls/control-impl.h>
namespace Dali
return controlDataImpl.VisualEventSignal();
}
+static Toolkit::Internal::Control::Impl *GetControlImplementationIfAny( Dali::Actor actor)
+{
+ Dali::Toolkit::Control c = Toolkit::Control::DownCast( actor );
+ if ( c )
+ {
+ auto &impl1 = Toolkit::Internal::GetImplementation( c );
+ auto &impl2 = Toolkit::Internal::Control::Impl::Get( impl1 );
+ return &impl2;
+ }
+ return nullptr;
+}
+
+Toolkit::DevelControl::AccessibilityActivateSignalType &AccessibilityActivateSignal( Toolkit::Control control )
+{
+ auto ac = GetControlImplementationIfAny ( control );
+ return ac->mAccessibilityActivateSignal;
+}
+
+Toolkit::DevelControl::AccessibilityReadingSkippedSignalType &AccessibilityReadingSkippedSignal( Toolkit::Control control )
+{
+ auto ac = GetControlImplementationIfAny ( control );
+ return ac->mAccessibilityReadingSkippedSignal;
+}
+
+Toolkit::DevelControl::AccessibilityReadingPausedSignalType &AccessibilityReadingPausedSignal( Toolkit::Control control )
+{
+ auto ac = GetControlImplementationIfAny ( control );
+ return ac->mAccessibilityReadingPausedSignal;
+}
+
+Toolkit::DevelControl::AccessibilityReadingResumedSignalType &AccessibilityReadingResumedSignal( Toolkit::Control control )
+{
+ auto ac = GetControlImplementationIfAny ( control );
+ return ac->mAccessibilityReadingResumedSignal;
+}
+
+Toolkit::DevelControl::AccessibilityReadingCancelledSignalType &AccessibilityReadingCancelledSignal( Toolkit::Control control )
+{
+ auto ac = GetControlImplementationIfAny ( control );
+ return ac->mAccessibilityReadingCancelledSignal;
+}
+
+Toolkit::DevelControl::AccessibilityReadingStoppedSignalType &AccessibilityReadingStoppedSignal( Toolkit::Control control )
+{
+ auto ac = GetControlImplementationIfAny ( control );
+ return ac->mAccessibilityReadingStoppedSignal;
+}
+
+Toolkit::DevelControl::AccessibilityGetNameSignalType &AccessibilityGetNameSignal( Toolkit::Control control )
+{
+ auto ac = GetControlImplementationIfAny ( control );
+ return ac->mAccessibilityGetNameSignal;
+}
+
+Toolkit::DevelControl::AccessibilityGetDescriptionSignalType &AccessibilityGetDescriptionSignal( Toolkit::Control control )
+{
+ auto ac = GetControlImplementationIfAny ( control );
+ return ac->mAccessibilityGetDescriptionSignal;
+}
+
+Toolkit::DevelControl::AccessibilityDoGestureSignalType &AccessibilityDoGestureSignal( Toolkit::Control control )
+{
+ auto ac = GetControlImplementationIfAny ( control );
+ return ac->mAccessibilityDoGestureSignal;
+}
+
+void AppendAccessibilityRelation( Dali::Actor control, Actor destination, Dali::Accessibility::RelationType relation)
+{
+ if ( auto ac = GetControlImplementationIfAny ( control ) )
+ {
+ auto index = static_cast<Dali::Property::Array::SizeType>(relation);
+ if (index >= ac->mAccessibilityRelations.size())
+ {
+ DALI_LOG_ERROR( "Relation index exceeds vector size." );
+ return;
+ }
+
+ auto obj = ac->GetAccessibilityObject(destination);
+ if (obj)
+ ac->mAccessibilityRelations[index].push_back(obj->GetAddress());
+ }
+}
+
+void RemoveAccessibilityRelation( Dali::Actor control, Actor destination, Dali::Accessibility::RelationType relation)
+{
+ if ( auto ac = GetControlImplementationIfAny ( control ) )
+ {
+ auto index = static_cast<Dali::Property::Array::SizeType>(relation);
+ if (index >= ac->mAccessibilityRelations.size())
+ {
+ DALI_LOG_ERROR( "Relation index exceeds vector size." );
+ return;
+ }
+
+ auto obj = ac->GetAccessibilityObject(destination);
+ if (!obj)
+ return;
+
+ auto address = obj->GetAddress();
+
+ auto &targets = ac->mAccessibilityRelations[index];
+ for (auto i = 0u; i < targets.size(); ++i) {
+ if (targets[i].ToString() == address.ToString())
+ {
+ targets[i] = targets.back();
+ targets.erase(targets.end() - 1);
+ }
+ }
+ }
+}
+
+std::vector<std::vector<Accessibility::Address>> GetAccessibilityRelations( Dali::Actor control )
+{
+ if ( auto ac = GetControlImplementationIfAny ( control ) )
+ {
+ return ac->mAccessibilityRelations;
+ }
+ return {};
+}
+
+void ClearAccessibilityRelations( Dali::Actor control )
+{
+ if ( auto ac = GetControlImplementationIfAny ( control ) )
+ {
+ for (auto &it : ac->mAccessibilityRelations)
+ it.clear();
+ }
+}
+
+void SetAccessibilityConstructor( Dali::Actor control,
+ std::function< std::unique_ptr< Dali::Accessibility::Accessible >( Dali::Actor ) > constructor )
+{
+ if ( auto ac = GetControlImplementationIfAny ( control ) )
+ {
+ ac->accessibilityConstructor = constructor;
+ }
+}
+
+void AppendAccessibilityAttribute( Dali::Actor control, const std::string& key,
+ const std::string value )
+{
+ if ( auto ac = GetControlImplementationIfAny ( control ) )
+ {
+ ac->AppendAccessibilityAttribute( key, value );
+ }
+}
+
+void RemoveAccessibilityAttribute( Dali::Actor control, const std::string& key )
+{
+ if ( auto ac = GetControlImplementationIfAny ( control ) )
+ {
+ ac->RemoveAccessibilityAttribute( key );
+ }
+}
+
+void ClearAccessibilityAttributes( Dali::Actor control )
+{
+ if ( auto ac = GetControlImplementationIfAny ( control ) )
+ {
+ ac->ClearAccessibilityAttributes();
+ }
+}
+
+void SetAccessibilityReadingInfoType( Dali::Actor control, const Dali::Accessibility::ReadingInfoTypes types )
+{
+ if ( auto ac = GetControlImplementationIfAny ( control ) )
+ {
+ ac->SetAccessibilityReadingInfoType( types );
+ }
+}
+
+Dali::Accessibility::ReadingInfoTypes GetAccessibilityReadingInfoType(Dali::Actor control )
+{
+ if ( auto ac = GetControlImplementationIfAny ( control ) )
+ {
+ return ac->GetAccessibilityReadingInfoType();
+ }
+ return {};
+}
+
+bool ClearAccessibilityHighlight( Dali::Actor control )
+{
+ if ( auto ac = GetControlImplementationIfAny ( control ) )
+ {
+ auto ptr = dynamic_cast<Dali::Accessibility::Component*>( ac->GetAccessibilityObject() );
+ if( ptr )
+ return ptr->ClearHighlight();
+ }
+ return false;
+}
+
+bool GrabAccessibilityHighlight( Dali::Actor control )
+{
+ if ( auto ac = GetControlImplementationIfAny ( control ) )
+ {
+ auto ptr = dynamic_cast<Dali::Accessibility::Component*>( ac->GetAccessibilityObject() );
+ if( ptr )
+ return ptr->GrabHighlight();
+ }
+ return false;
+}
+
+Dali::Accessibility::States GetAccessibilityStates( Dali::Actor control )
+{
+ if ( auto ac = GetControlImplementationIfAny ( control ) )
+ {
+ auto ptr = dynamic_cast<Dali::Accessibility::Component*>( ac->GetAccessibilityObject() );
+ if(ptr)
+ return ptr->GetStates();
+ }
+ return {};
+}
+
+void NotifyAccessibilityStateChange( Dali::Actor control, Dali::Accessibility::States states, bool doRecursive )
+{
+ if ( auto ac = GetControlImplementationIfAny ( control ) )
+ {
+ ac->GetAccessibilityObject()->NotifyAccessibilityStateChange( std::move(states), doRecursive );
+ }
+}
+
+Dali::Accessibility::Accessible *GetBoundAccessibilityObject( Dali::Actor control )
+{
+ return Dali::Accessibility::Accessible::Get( control );
+}
+
} // namespace DevelControl
} // namespace Toolkit
*
*/
// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/accessibility-impl.h>
#include <dali/devel-api/adaptor-framework/input-method-context.h>
// INTERNAL INCLUDES
namespace DevelControl
{
+/// @brief AccessibilityActivate signal type.
+typedef Signal< void ( ) > AccessibilityActivateSignalType;
+
+/// @brief AccessibilityReadingSkipped signal type.
+typedef Signal< void ( ) > AccessibilityReadingSkippedSignalType;
+
+/// @brief AccessibilityReadingPaused signal type.
+typedef Signal< void ( ) > AccessibilityReadingPausedSignalType;
+
+/// @brief AccessibilityReadingResumed signal type.
+typedef Signal< void ( ) > AccessibilityReadingResumedSignalType;
+
+/// @brief AccessibilityReadingCancelled signal type.
+typedef Signal< void ( ) > AccessibilityReadingCancelledSignalType;
+
+/// @brief AccessibilityReadingStopped signal type.
+typedef Signal< void ( ) > AccessibilityReadingStoppedSignalType;
+
+/// @brief AccessibilityGetName signal type.
+typedef Signal< void ( std::string& ) > AccessibilityGetNameSignalType;
+
+/// @brief AccessibilityGetDescription signal type.
+typedef Signal< void ( std::string& ) > AccessibilityGetDescriptionSignalType;
+
+/// @brief AccessibilityDoGesture signal type.
+typedef Signal< void ( std::pair<Dali::Accessibility::GestureInfo, bool>& ) > AccessibilityDoGestureSignalType;
+
enum State
{
NORMAL,
* @brief The shadow of the control.
* @details Name "shadow", type Property::MAP.
*/
- SHADOW = PADDING + 8
+ SHADOW = PADDING + 8,
+
+ /**
+ * @brief The name of object visible in accessibility tree.
+ * @details Name "accessibilityName", type Property::STRING.
+ */
+ ACCESSIBILITY_NAME,
+
+ /**
+ * @brief The description of object visible in accessibility tree.
+ * @details Name "accessibilityDescription", type Property::STRING.
+ */
+ ACCESSIBILITY_DESCRIPTION,
+
+ /**
+ * @brief Current translation domain for accessibility clients.
+ * @details Name "accessibilityTranslationDomain", type Property::STRING.
+ */
+ ACCESSIBILITY_TRANSLATION_DOMAIN,
+
+ /**
+ * @brief Role being performed in accessibility hierarchy.
+ * @details Name "accessibilityRole", type Property::INTEGER.
+ * @note Property is stored as INTEGER, however its interpretaton
+ * depend on enumeration Dali::Accessibility::Role and should be read and written
+ * with usage of enumerated values.
+ * @see Dali::Accessibility::Role
+ */
+ ACCESSIBILITY_ROLE,
+ /**
+ * @brief Mark of able to highlight object.
+ * @details Name "accessibilityHighlightable", type Property::BOOLEAN.
+ */
+ ACCESSIBILITY_HIGHLIGHTABLE,
+ /**
+ * @brief Set of accessibility attributes describing object in accessibility hierarchy
+ * @details Name "accessibilityAttributes", type Property::MAP
+ */
+ ACCESSIBILITY_ATTRIBUTES,
+
+ /**
+ * @brief Boolean flag describing object as animated
+ * @details Name "accessibilityAnimated", type Property::BOOLEAN
+ * @note Flag set to true will prevent BoundChanged accessibility signal from emiting
+ */
+ ACCESSIBILITY_ANIMATED
};
} // namespace Property
*/
DALI_TOOLKIT_API VisualEventSignalType& VisualEventSignal(Control control);
+/**
+ * @brief The signal is emmited as a succession of "activate" signal send by accessibility client.
+ * @return The signal to connect to
+ */
+DALI_TOOLKIT_API AccessibilityActivateSignalType &AccessibilityActivateSignal( Toolkit::Control control );
+
+/**
+ * @brief The signal is emmited when text send via Dali::Accessibility::Bridge::Say
+ * was placed in TTS queue but other text with higher priority prevented it from being read.
+ *
+ * @return The signal to connect to
+ */
+DALI_TOOLKIT_API AccessibilityReadingSkippedSignalType &AccessibilityReadingSkippedSignal( Toolkit::Control control );
+
+/**
+ * @brief
+ *
+ * @return The signal to connect to
+ */
+DALI_TOOLKIT_API AccessibilityReadingPausedSignalType &AccessibilityReadingPausedSignal( Toolkit::Control control );
+
+/**
+ * @brief
+ *
+ * @return The signal to connect to
+ */
+DALI_TOOLKIT_API AccessibilityReadingResumedSignalType &AccessibilityReadingResumedSignal( Toolkit::Control control );
+
+/**
+ * @brief The signal is emmited when text send via Dali::Accessibility::Bridge::Say
+ * was placed in TTS queue and reading was started but other text with higher priority cancelled it.
+ *
+ * @return The signal to connect to
+ */
+DALI_TOOLKIT_API AccessibilityReadingCancelledSignalType &AccessibilityReadingCancelledSignal( Toolkit::Control control );
+
+/**
+ * @brief The signal is emmited when text send via Dali::Accessibility::Bridge::Say
+ * was fully read by TTS module.
+ *
+ * @return The signal to connect to
+ */
+DALI_TOOLKIT_API AccessibilityReadingStoppedSignalType &AccessibilityReadingStoppedSignal( Toolkit::Control control );
+
+/**
+ * @brief The signal is emmited when accessibility client asks for object's name.
+ *
+ * Connected callback should assign name to std::string call parameter.
+ * Accessibility name can be stored in two ways:
+ * this signal,
+ * ACCESSIBILITY_NAME property,
+ * Priority is as above. If none is used, default implementation is provided.
+ * @return [description]
+ */
+DALI_TOOLKIT_API AccessibilityGetNameSignalType &AccessibilityGetNameSignal( Toolkit::Control control );
+
+/**
+ * @brief The signal is emmited when accessibility client asks for object's description.
+ *
+ * Connected callback should assign description to std::string call parameter.
+ * Accessibility description can be stored in two ways:
+ * this signal,
+ * ACCESSIBILITY_DESCRIPTION property,
+ * Priority is as above. If none is used, default implementation is provided.
+ * @return signal handler
+ */
+DALI_TOOLKIT_API AccessibilityGetDescriptionSignalType &AccessibilityGetDescriptionSignal( Toolkit::Control control );
+
+/**
+ * @brief The signal is emitted when accessibility client call "DoGesture" method via IPC mechanism.
+ *
+ * This signal allows developers to serve incoming gesture in specific way.
+ * @return signal handler
+ */
+DALI_TOOLKIT_API AccessibilityDoGestureSignalType &AccessibilityDoGestureSignal( Toolkit::Control control );
+
+/**
+ * @brief The method allows connection with other actor with usage of concrete accessibility relation type.
+ *
+ * @param control object to append attribute to
+ * @param destination Actor object
+ * @param relation enumerated value describing relation
+ */
+DALI_TOOLKIT_API void AppendAccessibilityRelation( Dali::Actor control, Actor destination, Dali::Accessibility::RelationType relation );
+
+/**
+ * @brief The method allows removing relation
+ *
+ * @param control object to append attribute to
+ * @param destination Actor object
+ * @param relation enumerated value describing relation
+ */
+DALI_TOOLKIT_API void RemoveAccessibilityRelation( Dali::Actor control, Actor destination, Dali::Accessibility::RelationType relation );
+
+/**
+ * @brief The method returns collection accessibility addresses representing objects connected with current object
+ *
+ * @param control object to append attribute to
+ * @return std::vector, where index is casted value of Accessibility::RelationType and value is std::vector of type Accessibility::Address
+ */
+DALI_TOOLKIT_API std::vector<std::vector<Accessibility::Address>> GetAccessibilityRelations( Dali::Actor control );
+
+/**
+ * @brief The method removes all previously appended relations
+ *
+ * @param control object to append attribute to
+ */
+DALI_TOOLKIT_API void ClearAccessibilityRelations( Dali::Actor control );
+
+/**
+ * @brief The method allows to add or modify value matched with given key.
+ * Modification take place if key was previously set.
+ *
+ * @param control object to append attribute to
+ * @param key std::string value
+ * @param value std::string value
+ */
+DALI_TOOLKIT_API void AppendAccessibilityAttribute( Dali::Actor control, const std::string& key, const std::string value );
+
+/**
+ * @brief The method erases key with its value from accessibility attributes
+ * @param control object to append attribute to
+ * @param key std::string value
+ */
+DALI_TOOLKIT_API void RemoveAccessibilityAttribute( Dali::Actor control, const std::string& key );
+
+/**
+ * @brief The method clears accessibility attributes
+ *
+ * @param control object to append attribute to
+ */
+DALI_TOOLKIT_API void ClearAccessibilityAttributes( Dali::Actor control );
+
+/**
+ * @brief The method inserts reading information of an accessible object into attributes
+ *
+ * @param control object to append attribute to
+ * @param types Reading information types
+ */
+DALI_TOOLKIT_API void SetAccessibilityReadingInfoType( Dali::Actor control, const Dali::Accessibility::ReadingInfoTypes types );
+
+/**
+ * @brief The method returns reading information of an accessible object
+ *
+ * @param control object to append attribute to
+ * @return Reading information types
+ */
+DALI_TOOLKIT_API Dali::Accessibility::ReadingInfoTypes GetAccessibilityReadingInfoType( Dali::Actor control );
+
+/**
+ * @brief The method erases highlight.
+ *
+ * @param control object to append attribute to
+ * @return bool value, false when it is not possible or something went wrong, at the other way true.
+ */
+DALI_TOOLKIT_API bool ClearAccessibilityHighlight( Dali::Actor control );
+
+/**
+ * @brief The method grabs highlight.
+ *
+ * @param control object to append attribute to
+ * @return bool value, false when it is not possible or something went wrong, at the other way true.
+ */
+DALI_TOOLKIT_API bool GrabAccessibilityHighlight( Dali::Actor control );
+
+/**
+ * @brief The metod presents bitset of control's states.
+ *
+ * @param control object to append attribute to
+ * @return Dali::Accessibility::States is vector of enumerated State.
+ */
+DALI_TOOLKIT_API Dali::Accessibility::States GetAccessibilityStates( Dali::Actor control );
+
+/**
+ * @brief The method force sending notifications about current states to accessibility clients
+ *
+ * @param control object to append attribute to
+ * @param states mask with states expected to broadcast
+ * @param doRecursive flag pointing if notifications of children's state would be sent
+ */
+DALI_TOOLKIT_API void NotifyAccessibilityStateChange( Dali::Actor control, Dali::Accessibility::States states, bool doRecursive );
+
+/**
+ * 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 AccessibleImpl( 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);
+
+/**
+ * Returns accessibility object bound to actor, if any
+ *
+ * This method won't bound new accessibility object. Use Dali::Accessibility::Accessible::Get in that case.
+ */
+DALI_TOOLKIT_API Dali::Accessibility::Accessible *GetBoundAccessibilityObject( Dali::Actor control );
+
} // namespace DevelControl
} // namespace Toolkit
GetImpl(textEditor).SelectNone();
}
+void ScrollBy(TextEditor textEditor, Vector2 scroll)
+{
+ GetImpl(textEditor).ScrollBy(scroll);
+}
+
} // namespace DevelTextEditor
} // namespace Toolkit
SELECTED_TEXT_END,
/**
+ * @brief The horizontal scroll position in pixels.
+ * @details Name "horizontalScrollPosition", type Property::FLOAT.
+ */
+ HORIZONTAL_SCROLL_POSITION,
+
+ /**
+ * @brief The vertical scroll position in pixels.
+ * @details Name "verticalScrollPosition", type Property::FLOAT.
+ */
+ VERTICAL_SCROLL_POSITION,
+
+ /**
* @brief The Editable state of control.
* @details Name "enableEditing", type Property::BOOLEAN.
*/
*/
DALI_TOOLKIT_API void SelectNone(TextEditor textEditor);
+/**
+ * @brief Scroll the TextEditor by specific amount.
+ *
+ * @param[in] textEditor The instance of TextEditor.
+ * @param[in] scroll amount (in pixels) of scrolling in horizontal & vectical directions.
+ */
+DALI_TOOLKIT_API void ScrollBy(TextEditor textEditor, Vector2 scroll);
+
} // namespace DevelTextEditor
} // namespace Toolkit
#include "accessibility-manager-impl.h"
// EXTERNAL INCLUDES
-#include <cstring> // for strcmp
-#include <dali/public-api/actors/layer.h>
-#include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
-#include <dali/devel-api/adaptor-framework/sound-player.h>
-#include <dali/public-api/animation/constraints.h>
-#include <dali/devel-api/events/hit-test-algorithm.h>
-#include <dali/devel-api/events/pan-gesture-devel.h>
-#include <dali/integration-api/debug.h>
+#include <dali/devel-api/adaptor-framework/accessibility.h>
+#include <dali/devel-api/adaptor-framework/accessibility-impl.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/devel-api/asset-manager/asset-manager.h>
#include <dali-toolkit/public-api/controls/control.h>
#include <dali-toolkit/public-api/controls/control-impl.h>
-#include <dali-toolkit/public-api/controls/image-view/image-view.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
namespace Dali
{
namespace Internal
{
-namespace // unnamed namespace
-{
-
-// Signals
-
-const char* const SIGNAL_FOCUS_CHANGED = "focusChanged";
-const char* const SIGNAL_FOCUS_OVERSHOT = "focusOvershot";
-const char* const SIGNAL_FOCUSED_ACTOR_ACTIVATED = "focusedActorActivated";
-
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_FOCUS_MANAGER");
-#endif
-
-const char* const ACTOR_FOCUSABLE("focusable");
-const char* const IS_FOCUS_GROUP("isFocusGroup");
-
-const char* FOCUS_BORDER_IMAGE_FILE_NAME = "B16-8_TTS_focus.9.png";
-
-const char* FOCUS_SOUND_FILE_NAME = "Focus.ogg";
-const char* FOCUS_CHAIN_END_SOUND_FILE_NAME = "End_of_List.ogg";
-
-/**
- * The function to be used in the hit-test algorithm to check whether the actor is hittable.
- */
-bool IsActorFocusableFunction(Actor actor, Dali::HitTestAlgorithm::TraverseType type)
-{
- bool hittable = false;
-
- switch (type)
- {
- case Dali::HitTestAlgorithm::CHECK_ACTOR:
- {
- // Check whether the actor is visible and not fully transparent.
- if( actor.GetCurrentProperty< bool >( Actor::Property::VISIBLE )
- && actor.GetCurrentProperty< Vector4 >( Actor::Property::WORLD_COLOR ).a > 0.01f) // not FULLY_TRANSPARENT
- {
- // Check whether the actor is focusable
- Property::Index propertyActorFocusable = actor.GetPropertyIndex(ACTOR_FOCUSABLE);
- if(propertyActorFocusable != Property::INVALID_INDEX)
- {
- hittable = actor.GetProperty<bool>(propertyActorFocusable);
- }
- }
- break;
- }
- case Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE:
- {
- if( actor.GetCurrentProperty< bool >( Actor::Property::VISIBLE ) ) // Actor is visible, if not visible then none of its children are visible.
- {
- hittable = true;
- }
- break;
- }
- default:
- {
- break;
- }
- }
-
- return hittable;
-};
-
-}
-
AccessibilityManager::AccessibilityManager()
-: mCurrentFocusActor(FocusIDPair(0, 0)),
- mCurrentGesturedActor(),
- mFocusIndicatorActor(),
- mPreviousPosition( 0.0f, 0.0f ),
- mRecursiveFocusMoveCounter(0),
- mFocusSoundFilePath(),
- mFocusChainEndSoundFilePath(),
- mIsWrapped(false),
- mIsFocusWithinGroup(false),
- mIsEndcapFeedbackEnabled(false),
- mIsEndcapFeedbackPlayed(false),
- mIsAccessibilityTtsEnabled(false),
- mTtsCreated(false),
- mIsFocusIndicatorEnabled(false),
- mContinuousPlayMode(false),
- mIsFocusSoundFilePathSet(false),
- mIsFocusChainEndSoundFilePathSet(false)
{
+ mFocusOrder.push_back( {} ); // zero has a special meaning
}
AccessibilityManager::~AccessibilityManager()
{
}
-void AccessibilityManager::Initialise()
-{
- AccessibilityAdaptor adaptor = AccessibilityAdaptor::Get();
- adaptor.SetActionHandler(*this);
- adaptor.SetGestureHandler(*this);
-
- ChangeAccessibilityStatus();
-}
-
-AccessibilityManager::ActorAdditionalInfo AccessibilityManager::GetActorAdditionalInfo(const unsigned int actorID) const
-{
- ActorAdditionalInfo data;
- IDAdditionalInfoConstIter iter = mIDAdditionalInfoContainer.find(actorID);
- if(iter != mIDAdditionalInfoContainer.end())
- {
- data = (*iter).second;
- }
-
- return data;
-}
-
-void AccessibilityManager::SynchronizeActorAdditionalInfo(const unsigned int actorID, const unsigned int order)
-{
- ActorAdditionalInfo actorInfo = GetActorAdditionalInfo(actorID);
- actorInfo.mFocusOrder = order;
- mIDAdditionalInfoContainer.erase(actorID);
- mIDAdditionalInfoContainer.insert(IDAdditionalInfoPair(actorID, actorInfo));
-}
-
void AccessibilityManager::SetAccessibilityAttribute(Actor actor, Toolkit::AccessibilityManager::AccessibilityAttribute type, const std::string& text)
{
- if(actor)
+ switch ( type )
{
- unsigned int actorID = actor.GetProperty< int >( Actor::Property::ID );
+ case Toolkit::AccessibilityManager::ACCESSIBILITY_LABEL:
+ actor.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_NAME, text );
+ break;
- ActorAdditionalInfo info = GetActorAdditionalInfo(actorID);
- info.mAccessibilityAttributes[type] = text;
+ case Toolkit::AccessibilityManager::ACCESSIBILITY_HINT:
+ actor.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION, text );
+ break;
- mIDAdditionalInfoContainer.erase(actorID);
- mIDAdditionalInfoContainer.insert(IDAdditionalInfoPair(actorID, info));
+ case Toolkit::AccessibilityManager::ACCESSIBILITY_TRAIT:
+ case Toolkit::AccessibilityManager::ACCESSIBILITY_VALUE:
+ default:
+ break;
}
}
std::string AccessibilityManager::GetAccessibilityAttribute(Actor actor, Toolkit::AccessibilityManager::AccessibilityAttribute type) const
{
- std::string text;
-
- if(actor)
+ switch ( type )
{
- ActorAdditionalInfo data = GetActorAdditionalInfo(actor.GetProperty< int >( Actor::Property::ID ));
- text = data.mAccessibilityAttributes[type];
- }
+ case Toolkit::AccessibilityManager::ACCESSIBILITY_LABEL:
+ return actor.GetProperty< std::string >( Toolkit::DevelControl::Property::ACCESSIBILITY_NAME );
+
+ case Toolkit::AccessibilityManager::ACCESSIBILITY_HINT:
+ return actor.GetProperty< std::string >( Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION );
- return text;
+ case Toolkit::AccessibilityManager::ACCESSIBILITY_TRAIT:
+ case Toolkit::AccessibilityManager::ACCESSIBILITY_VALUE:
+ default:
+ return "";
+ }
}
void AccessibilityManager::SetFocusOrder(Actor actor, const unsigned int order)
{
- // Do nothing if the focus order of the actor is not changed.
- if(actor && GetFocusOrder(actor) != order)
- {
- // Firstly delete the actor from the focus chain if it's already there with a different focus order.
- mFocusIDContainer.erase(GetFocusOrder(actor));
-
- // Create/retrieve actor focusable property
- Property::Index propertyActorFocusable = actor.RegisterProperty( ACTOR_FOCUSABLE, true, Property::READ_WRITE );
-
- if(order == 0)
- {
- // The actor is not focusable without a defined focus order.
- actor.SetProperty(propertyActorFocusable, false);
-
- // If the actor is currently being focused, it should clear the focus
- if(actor == GetCurrentFocusActor())
- {
- ClearFocus();
- }
- }
- else // Insert the actor to the focus chain
- {
- // Check whether there is another actor in the focus chain with the same focus order already.
- FocusIDIter focusIDIter = mFocusIDContainer.find(order);
- if(focusIDIter != mFocusIDContainer.end())
- {
- // We need to increase the focus order of that actor and all the actors followed it
- // in the focus chain.
- FocusIDIter lastIter = mFocusIDContainer.end();
- --lastIter;//We want forward iterator to the last element here
- mFocusIDContainer.insert(FocusIDPair((*lastIter).first + 1, (*lastIter).second));
-
- // Update the actor's focus order in its additional data
- SynchronizeActorAdditionalInfo((*lastIter).second, (*lastIter).first + 1);
-
- for(FocusIDIter iter = lastIter; iter != focusIDIter; iter--)
- {
- FocusIDIter previousIter = iter;
- --previousIter;//We want forward iterator to the previous element here
- unsigned int actorID = (*previousIter).second;
- (*iter).second = actorID;
+ if (order == 0)
+ return;
- // Update the actor's focus order in its additional data
- SynchronizeActorAdditionalInfo(actorID, (*iter).first);
- }
+ if (order >= mFocusOrder.size())
+ mFocusOrder.resize(order + 1);
- mFocusIDContainer.erase(order);
- }
+ auto it = mFocusOrder.begin() + order;
+ mFocusOrder.insert(it, actor);
- // The actor is focusable
- actor.SetProperty(propertyActorFocusable, true);
-
- // Now we insert the actor into the focus chain with the specified focus order
- mFocusIDContainer.insert(FocusIDPair(order, actor.GetProperty< int >( Actor::Property::ID )));
- }
+ if (order > 0)
+ {
+ Actor prev = mFocusOrder[order - 1];
+ DevelControl::AppendAccessibilityRelation( prev, actor, Accessibility::RelationType::FLOWS_TO );
+ DevelControl::AppendAccessibilityRelation( actor, prev, Accessibility::RelationType::FLOWS_FROM );
+ }
- // Update the actor's focus order in its additional data
- SynchronizeActorAdditionalInfo(actor.GetProperty< int >( Actor::Property::ID ), order);
+ if (order + 1 < mFocusOrder.size())
+ {
+ Actor next = mFocusOrder[order + 1];
+ DevelControl::AppendAccessibilityRelation( actor, next, Accessibility::RelationType::FLOWS_TO );
+ DevelControl::AppendAccessibilityRelation( next, actor, Accessibility::RelationType::FLOWS_FROM );
}
}
unsigned int AccessibilityManager::GetFocusOrder(Actor actor) const
{
- unsigned int focusOrder = 0;
-
- if(actor)
+ for (auto it = mFocusOrder.begin(); it != mFocusOrder.end(); ++it)
{
- ActorAdditionalInfo data = GetActorAdditionalInfo(actor.GetProperty< int >( Actor::Property::ID ));
- focusOrder = data.mFocusOrder;
+ if (actor == *it)
+ return it - mFocusOrder.begin();
}
- return focusOrder;
+ return 0;
}
unsigned int AccessibilityManager::GenerateNewFocusOrder() const
{
- unsigned int order = 1;
- FocusIDContainer::const_reverse_iterator iter = mFocusIDContainer.rbegin();
-
- if(iter != mFocusIDContainer.rend())
- {
- order = (*iter).first + 1;
- }
-
- return order;
+ return static_cast<unsigned>(mFocusOrder.size());
}
Actor AccessibilityManager::GetActorByFocusOrder(const unsigned int order)
{
- Actor actor = Actor();
+ Actor actor;
- FocusIDIter focusIDIter = mFocusIDContainer.find(order);
- if(focusIDIter != mFocusIDContainer.end())
- {
- Actor rootActor = Stage::GetCurrent().GetRootLayer();
- actor = rootActor.FindChildById(mFocusIDContainer[order]);
- }
+ if (order > 0 && order < mFocusOrder.size())
+ actor = mFocusOrder[order];
return actor;
}
bool AccessibilityManager::SetCurrentFocusActor(Actor actor)
{
- if(actor)
- {
- return DoSetCurrentFocusActor(actor.GetProperty< int >( Actor::Property::ID ));
- }
-
- return false;
-}
-
-bool AccessibilityManager::DoSetCurrentFocusActor(const unsigned int actorID)
-{
- Actor rootActor = Stage::GetCurrent().GetRootLayer();
-
- // If the group mode is enabled, check which focus group the current focused actor belongs to
- Actor focusGroup;
- if(mIsFocusWithinGroup)
- {
- focusGroup = GetFocusGroup(GetCurrentFocusActor());
- }
+ Dali::Accessibility::Accessible::SetCurrentlyHighlightedActor(actor);
- if(!focusGroup)
- {
- focusGroup = rootActor;
- }
-
- Actor actor = focusGroup.FindChildById(actorID);
-
- // Check whether the actor is in the stage
- if(actor)
- {
- // Check whether the actor is focusable
- bool actorFocusable = false;
- Property::Index propertyActorFocusable = actor.GetPropertyIndex(ACTOR_FOCUSABLE);
- if(propertyActorFocusable != Property::INVALID_INDEX)
- {
- actorFocusable = actor.GetProperty<bool>(propertyActorFocusable);
- }
-
- // Go through the actor's hierarchy to check whether the actor is visible
- bool actorVisible = actor.GetCurrentProperty< bool >( Actor::Property::VISIBLE );
- Actor parent = actor.GetParent();
- while (actorVisible && parent && parent != rootActor)
- {
- actorVisible = parent.GetCurrentProperty< bool >( Actor::Property::VISIBLE );
- parent = parent.GetParent();
- }
-
- // Check whether the actor is fully transparent
- bool actorOpaque = actor.GetCurrentProperty< Vector4 >( Actor::Property::WORLD_COLOR ).a > 0.01f;
-
- // Set the focus only when the actor is focusable and visible and not fully transparent
- if(actorVisible && actorFocusable && actorOpaque)
- {
- // Draw the focus indicator upon the focused actor
- if( mIsFocusIndicatorEnabled )
- {
- actor.Add( GetFocusIndicatorActor() );
- }
-
- // Send notification for the change of focus actor
- mFocusChangedSignal.Emit( GetCurrentFocusActor(), actor );
-
- // Save the current focused actor
- mCurrentFocusActor = FocusIDPair(GetFocusOrder(actor), actorID);
-
- if(mIsAccessibilityTtsEnabled)
- {
- Dali::SoundPlayer soundPlayer = Dali::SoundPlayer::Get();
- if(soundPlayer)
- {
- if (!mIsFocusSoundFilePathSet)
- {
- const std::string soundDirPath = AssetManager::GetDaliSoundPath();
- mFocusSoundFilePath = soundDirPath + FOCUS_SOUND_FILE_NAME;
- mIsFocusSoundFilePathSet = true;
- }
- soundPlayer.PlaySound(mFocusSoundFilePath);
- }
-
- // Play the accessibility attributes with the TTS player.
- Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER);
-
- // Combine attribute texts to one text
- std::string informationText;
- for(int i = 0; i < Toolkit::AccessibilityManager::ACCESSIBILITY_ATTRIBUTE_NUM; i++)
- {
- if(!GetActorAdditionalInfo(actorID).mAccessibilityAttributes[i].empty())
- {
- if( i > 0 )
- {
- informationText += ", "; // for space time between each information
- }
- informationText += GetActorAdditionalInfo(actorID).mAccessibilityAttributes[i];
- }
- }
- player.Play(informationText);
- }
-
- return true;
- }
- }
-
- DALI_LOG_WARNING("[%s:%d] FAILED\n", __FUNCTION__, __LINE__);
- return false;
+ return true;
}
Actor AccessibilityManager::GetCurrentFocusActor()
{
- Actor rootActor = Stage::GetCurrent().GetRootLayer();
- return rootActor.FindChildById(mCurrentFocusActor.second);
+ return Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor();
}
Actor AccessibilityManager::GetCurrentFocusGroup()
unsigned int AccessibilityManager::GetCurrentFocusOrder()
{
- return mCurrentFocusActor.first;
+ auto actor = GetCurrentFocusActor();
+ unsigned order = 0;
+
+ if (actor)
+ order = GetFocusOrder( actor );
+
+ return order;
}
bool AccessibilityManager::MoveFocusForward()
{
- bool ret = false;
- mRecursiveFocusMoveCounter = 0;
+ unsigned current = GetCurrentFocusOrder();
- FocusIDIter focusIDIter = mFocusIDContainer.find(mCurrentFocusActor.first);
- if(focusIDIter != mFocusIDContainer.end())
- {
- DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
- ret = DoMoveFocus(focusIDIter, true, mIsWrapped);
- }
- else
- {
- // TODO: if there is not focused actor, move first actor
- if(!mFocusIDContainer.empty())
- {
- //if there is not focused actor, move 1st actor
- focusIDIter = mFocusIDContainer.begin(); // TODO: I'm not sure it was sorted.
- DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
- ret = DoSetCurrentFocusActor((*focusIDIter).second);
- }
- }
+ if (current + 1 < mFocusOrder.size())
+ return SetCurrentFocusActor(mFocusOrder[current + 1]);
- DALI_LOG_INFO( gLogFilter, Debug::General, "[%s] %s\n", __FUNCTION__, ret?"SUCCEED!!!":"FAILED!!!");
-
- return ret;
+ return false;
}
bool AccessibilityManager::MoveFocusBackward()
{
- bool ret = false;
- mRecursiveFocusMoveCounter = 0;
-
- FocusIDIter focusIDIter = mFocusIDContainer.find(mCurrentFocusActor.first);
- if(focusIDIter != mFocusIDContainer.end())
- {
- DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
- ret = DoMoveFocus(focusIDIter, false, mIsWrapped);
- }
- else
- {
- // TODO: if there is not focused actor, move last actor
- if(!mFocusIDContainer.empty())
- {
- //if there is not focused actor, move last actor
- focusIDIter = mFocusIDContainer.end();
- --focusIDIter;//We want forward iterator to the last element here
- DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
- ret = DoSetCurrentFocusActor((*focusIDIter).second);
- }
- }
+ unsigned current = GetCurrentFocusOrder();
- DALI_LOG_INFO( gLogFilter, Debug::General, "[%s] %s\n", __FUNCTION__, ret?"SUCCEED!!!":"FAILED!!!");
+ if (current > 1) // zero has a special meaning
+ return SetCurrentFocusActor(mFocusOrder[current - 1]);
- return ret;
+ return false;
}
-void AccessibilityManager::DoActivate(Actor actor)
+void AccessibilityManager::ClearFocus()
{
- if(actor)
- {
- Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
- if(control)
- {
- // Notify the control that it is activated
- GetImplementation( control ).AccessibilityActivate();
- }
-
- // Send notification for the activation of focused actor
- mFocusedActorActivatedSignal.Emit(actor);
- }
+ auto actor = GetCurrentFocusActor();
+ Toolkit::DevelControl::ClearAccessibilityHighlight( actor );
}
-void AccessibilityManager::ClearFocus()
+void AccessibilityManager::Reset()
{
- Actor actor = GetCurrentFocusActor();
- if( actor && mFocusIndicatorActor )
- {
- actor.Remove( mFocusIndicatorActor );
- }
-
- mCurrentFocusActor = FocusIDPair(0, 0);
-
- // Send notification for the change of focus actor
- mFocusChangedSignal.Emit(actor, Actor());
+ ClearFocus();
- if(mIsAccessibilityTtsEnabled)
+ for (std::size_t i = 2; i < mFocusOrder.size(); ++i)
{
- // Stop the TTS playing if any
- Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER);
- player.Stop();
+ Actor prev = mFocusOrder[i - 1];
+ Actor next = mFocusOrder[i];
+
+ DevelControl::RemoveAccessibilityRelation( prev, next, Accessibility::RelationType::FLOWS_TO );
+ DevelControl::RemoveAccessibilityRelation( next, prev, Accessibility::RelationType::FLOWS_FROM );
}
-}
-void AccessibilityManager::Reset()
-{
- ClearFocus();
- mFocusIDContainer.clear();
- mIDAdditionalInfoContainer.clear();
+ mFocusOrder.clear();
+ mFocusOrder.push_back( {} );
}
void AccessibilityManager::SetFocusGroup(Actor actor, bool isFocusGroup)
{
- if(actor)
- {
- // Create/Set focus group property.
- actor.RegisterProperty( IS_FOCUS_GROUP, isFocusGroup, Property::READ_WRITE );
- }
}
bool AccessibilityManager::IsFocusGroup(Actor actor) const
{
- // Check whether the actor is a focus group
- bool isFocusGroup = false;
-
- if(actor)
- {
- Property::Index propertyIsFocusGroup = actor.GetPropertyIndex(IS_FOCUS_GROUP);
- if(propertyIsFocusGroup != Property::INVALID_INDEX)
- {
- isFocusGroup = actor.GetProperty<bool>(propertyIsFocusGroup);
- }
- }
-
- return isFocusGroup;
+ return false;
}
Actor AccessibilityManager::GetFocusGroup(Actor actor)
{
- // Go through the actor's hierarchy to check which focus group the actor belongs to
- while (actor && !IsFocusGroup(actor))
- {
- actor = actor.GetParent();
- }
-
- return actor;
+ return {};
}
Vector2 AccessibilityManager::GetReadPosition() const
{
- AccessibilityAdaptor adaptor = AccessibilityAdaptor::Get();
- return adaptor.GetReadPosition();
+ return {};
}
void AccessibilityManager::SetGroupMode(bool enabled)
{
- mIsFocusWithinGroup = enabled;
}
bool AccessibilityManager::GetGroupMode() const
{
- return mIsFocusWithinGroup;
+ return false;
}
void AccessibilityManager::SetWrapMode(bool wrapped)
{
- mIsWrapped = wrapped;
}
bool AccessibilityManager::GetWrapMode() const
{
- return mIsWrapped;
+ return true;
}
void AccessibilityManager::SetFocusIndicatorActor(Actor indicator)
{
- if( mFocusIndicatorActor != indicator )
- {
- Actor currentFocusActor = GetCurrentFocusActor();
- if( currentFocusActor )
- {
- // The new focus indicator should be added to the current focused actor immediately
- if( mFocusIndicatorActor )
- {
- currentFocusActor.Remove( mFocusIndicatorActor );
- }
-
- if( indicator )
- {
- currentFocusActor.Add( indicator );
- }
- }
-
- mFocusIndicatorActor = indicator;
- }
+ Dali::Accessibility::Accessible::SetHighlightActor( indicator );
}
Actor AccessibilityManager::GetFocusIndicatorActor()
{
- if( ! mFocusIndicatorActor )
- {
- // Create the default if it hasn't been set and one that's shared by all the keyboard focusable actors
- const std::string imageDirPath = AssetManager::GetDaliImagePath();
- const std::string focusBorderImagePath = imageDirPath + FOCUS_BORDER_IMAGE_FILE_NAME;
-
- mFocusIndicatorActor = Toolkit::ImageView::New(focusBorderImagePath);
- mFocusIndicatorActor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
- mFocusIndicatorActor.SetProperty( Actor::Property::POSITION_Z, 1.0f );
-
- // Apply size constraint to the focus indicator
- mFocusIndicatorActor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
- }
-
- return mFocusIndicatorActor;
-}
-
-bool AccessibilityManager::DoMoveFocus(FocusIDIter focusIDIter, bool forward, bool wrapped)
-{
- DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] %d focusable actors\n", __FUNCTION__, __LINE__, mFocusIDContainer.size());
- DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
-
- if( (forward && ++focusIDIter == mFocusIDContainer.end())
- || (!forward && focusIDIter-- == mFocusIDContainer.begin()) )
- {
- if(mIsEndcapFeedbackEnabled)
- {
- if(mIsEndcapFeedbackPlayed == false)
- {
- // play sound & skip moving once
- Dali::SoundPlayer soundPlayer = Dali::SoundPlayer::Get();
- if(soundPlayer)
- {
- if (!mIsFocusChainEndSoundFilePathSet)
- {
- const std::string soundDirPath = AssetManager::GetDaliSoundPath();
- mFocusChainEndSoundFilePath = soundDirPath + FOCUS_CHAIN_END_SOUND_FILE_NAME;
- mIsFocusChainEndSoundFilePathSet = true;
- }
- soundPlayer.PlaySound(mFocusChainEndSoundFilePath);
- }
-
- mIsEndcapFeedbackPlayed = true;
- return true;
- }
- mIsEndcapFeedbackPlayed = false;
- }
-
- if(wrapped)
- {
- if(forward)
- {
- focusIDIter = mFocusIDContainer.begin();
- }
- else
- {
- focusIDIter = mFocusIDContainer.end();
- --focusIDIter;//We want forward iterator to the last element here
- }
- }
- else
- {
- DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] Overshot\n", __FUNCTION__, __LINE__);
- // Send notification for handling overshooted situation
- mFocusOvershotSignal.Emit(GetCurrentFocusActor(), forward ? Toolkit::AccessibilityManager::OVERSHOT_NEXT : Toolkit::AccessibilityManager::OVERSHOT_PREVIOUS);
-
- return false; // Try to move the focus out of the scope
- }
- }
-
- // Invalid focus.
- if( focusIDIter == mFocusIDContainer.end() )
- {
- return false;
- }
-
- // Note: This function performs the focus change.
- if( !DoSetCurrentFocusActor( (*focusIDIter).second ) )
- {
- mRecursiveFocusMoveCounter++;
- if(mRecursiveFocusMoveCounter > mFocusIDContainer.size())
- {
- // We've attempted to focus all the actors in the whole focus chain and no actor
- // can be focused successfully.
- DALI_LOG_WARNING("[%s] There is no more focusable actor in %d focus chains\n", __FUNCTION__, mRecursiveFocusMoveCounter);
-
- return false;
- }
- else
- {
- return DoMoveFocus(focusIDIter, forward, wrapped);
- }
- }
-
- return true;
-}
-
-void AccessibilityManager::SetFocusable(Actor actor, bool focusable)
-{
- if(actor)
- {
- // Create/Set actor focusable property.
- actor.RegisterProperty( ACTOR_FOCUSABLE, focusable, Property::READ_WRITE );
- }
-}
-
-bool AccessibilityManager::ChangeAccessibilityStatus()
-{
- AccessibilityAdaptor adaptor = AccessibilityAdaptor::Get();
- mIsAccessibilityTtsEnabled = adaptor.IsEnabled();
- Dali::Toolkit::AccessibilityManager handle( this );
-
- if(mIsAccessibilityTtsEnabled)
- {
- // Show indicator when tts turned on if there is focused actor.
- Actor actor = GetCurrentFocusActor();
- if(actor)
- {
- actor.Add( GetFocusIndicatorActor() );
- }
- mIsFocusIndicatorEnabled = true;
-
- // Connect a signal to the TTS player to implement continuous reading mode.
- Dali::TtsPlayer player = Dali::TtsPlayer::Get( Dali::TtsPlayer::SCREEN_READER );
- player.StateChangedSignal().Connect( this, &AccessibilityManager::TtsStateChanged );
- mTtsCreated = true;
- }
- else
- {
- // Hide indicator when tts turned off
- Actor actor = GetCurrentFocusActor();
- if( actor && mFocusIndicatorActor )
- {
- actor.Remove( mFocusIndicatorActor );
- }
- mIsFocusIndicatorEnabled = false;
-
- if( mTtsCreated )
- {
- // Disconnect the TTS state change signal.
- Dali::TtsPlayer player = Dali::TtsPlayer::Get( Dali::TtsPlayer::SCREEN_READER );
- player.StateChangedSignal().Disconnect( this, &AccessibilityManager::TtsStateChanged );
- mTtsCreated = true;
- }
- }
-
- mStatusChangedSignal.Emit( handle );
-
- return true;
-}
-
-bool AccessibilityManager::AccessibilityActionNext(bool allowEndFeedback)
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionNextSignal.Empty() )
- {
- mActionNextSignal.Emit( handle );
- }
-
- if(mIsAccessibilityTtsEnabled)
- {
- mIsEndcapFeedbackEnabled = allowEndFeedback;
- return MoveFocusForward();
- }
- else
- {
- return false;
- }
-}
-
-bool AccessibilityManager::AccessibilityActionPrevious(bool allowEndFeedback)
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionPreviousSignal.Empty() )
- {
- mActionPreviousSignal.Emit( handle );
- }
-
- if(mIsAccessibilityTtsEnabled)
- {
- mIsEndcapFeedbackEnabled = allowEndFeedback;
- return MoveFocusBackward();
- }
- else
- {
- return false;
- }
-}
-
-bool AccessibilityManager::AccessibilityActionActivate()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionActivateSignal.Empty() )
- {
- mActionActivateSignal.Emit( handle );
- }
-
- bool ret = false;
-
- Actor actor = GetCurrentFocusActor();
- if(actor)
- {
- DoActivate(actor);
- ret = true;
- }
-
- return ret;
-}
-
-bool AccessibilityManager::AccessibilityActionRead(bool allowReadAgain)
-{
- Dali::Toolkit::AccessibilityManager handle( this );
-
- if( allowReadAgain )
- {
- if ( !mActionReadSignal.Empty() )
- {
- mActionReadSignal.Emit( handle );
- }
- }
- else
- {
- if ( !mActionOverSignal.Empty() )
- {
- mActionOverSignal.Emit( handle );
- }
- }
-
- bool ret = false;
-
- if(mIsAccessibilityTtsEnabled)
- {
- // Find the focusable actor at the read position
- AccessibilityAdaptor adaptor = AccessibilityAdaptor::Get();
- Dali::HitTestAlgorithm::Results results;
- Dali::HitTestAlgorithm::HitTest( Stage::GetCurrent(), adaptor.GetReadPosition(), results, IsActorFocusableFunction );
-
- FocusIDIter focusIDIter = mFocusIDContainer.find(GetFocusOrder(results.actor));
- if(focusIDIter != mFocusIDContainer.end())
- {
- if( allowReadAgain || (results.actor != GetCurrentFocusActor()) )
- {
- // Move the focus to the actor
- ret = SetCurrentFocusActor(results.actor);
- DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] SetCurrentFocusActor returns %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
- }
- }
- }
-
- return ret;
-}
-
-bool AccessibilityManager::AccessibilityActionReadNext(bool allowEndFeedback)
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionReadNextSignal.Empty() )
- {
- mActionReadNextSignal.Emit( handle );
- }
-
- if(mIsAccessibilityTtsEnabled)
- {
- return MoveFocusForward();
- }
- else
- {
- return false;
- }
-}
-
-bool AccessibilityManager::AccessibilityActionReadPrevious(bool allowEndFeedback)
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionReadPreviousSignal.Empty() )
- {
- mActionReadPreviousSignal.Emit( handle );
- }
-
- if(mIsAccessibilityTtsEnabled)
- {
- return MoveFocusBackward();
- }
- else
- {
- return false;
- }
-}
-
-bool AccessibilityManager::AccessibilityActionUp()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionUpSignal.Empty() )
- {
- mActionUpSignal.Emit( handle );
- }
-
- bool ret = false;
-
- if(mIsAccessibilityTtsEnabled)
- {
- Actor actor = GetCurrentFocusActor();
- if(actor)
- {
- Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
- if(control)
- {
- // Notify the control that it is activated
- ret = GetImplementation( control ).OnAccessibilityValueChange(true);
- }
- }
- }
-
- return ret;
-}
-
-bool AccessibilityManager::AccessibilityActionDown()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionDownSignal.Empty() )
- {
- mActionDownSignal.Emit( handle );
- }
-
- bool ret = false;
-
- if(mIsAccessibilityTtsEnabled)
- {
- Actor actor = GetCurrentFocusActor();
- if(actor)
- {
- Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
- if(control)
- {
- // Notify the control that it is activated
- ret = GetImplementation( control ).OnAccessibilityValueChange(false);
- }
- }
- }
-
- return ret;
-}
-
-bool AccessibilityManager::ClearAccessibilityFocus()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionClearFocusSignal.Empty() )
- {
- mActionClearFocusSignal.Emit( handle );
- }
-
- if(mIsAccessibilityTtsEnabled)
- {
- ClearFocus();
- return true;
- }
- else
- {
- return false;
- }
-}
-
-bool AccessibilityManager::AccessibilityActionScroll( Dali::TouchEvent& touch )
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionScrollSignal.Empty() )
- {
- mActionScrollSignal.Emit( handle, touch );
- }
-
- return true;
-}
-
-bool AccessibilityManager::AccessibilityActionBack()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionBackSignal.Empty() )
- {
- mActionBackSignal.Emit( handle );
- }
-
- // TODO: Back to previous view
-
- return mIsAccessibilityTtsEnabled;
-}
-
-bool AccessibilityManager::AccessibilityActionScrollUp()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionScrollUpSignal.Empty() )
- {
- mActionScrollUpSignal.Emit( handle );
- }
-
- bool ret = false;
-
- if(mIsAccessibilityTtsEnabled)
- {
- Actor actor = GetCurrentFocusActor();
- if(actor)
- {
- Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
- if(control)
- {
- // TODO: Notify the control to scroll up. Should control handle this?
-// ret = GetImplementation( control ).OnAccessibilityScroll(Direction::UP);
- }
- }
- }
-
- return ret;
-}
-
-bool AccessibilityManager::AccessibilityActionScrollDown()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionScrollDownSignal.Empty() )
- {
- mActionScrollDownSignal.Emit( handle );
- }
-
- bool ret = false;
-
- if(mIsAccessibilityTtsEnabled)
- {
- Actor actor = GetCurrentFocusActor();
- if(actor)
- {
- Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
- if(control)
- {
- // TODO: Notify the control to scroll down. Should control handle this?
-// ret = GetImplementation( control ).OnAccessibilityScrollDown(Direction::DOWN);
- }
- }
- }
-
- return ret;
-}
-
-bool AccessibilityManager::AccessibilityActionPageLeft()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionPageLeftSignal.Empty() )
- {
- mActionPageLeftSignal.Emit( handle );
- }
-
- bool ret = false;
-
- if(mIsAccessibilityTtsEnabled)
- {
- Actor actor = GetCurrentFocusActor();
- if(actor)
- {
- Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
- if(control)
- {
- // TODO: Notify the control to scroll left to the previous page. Should control handle this?
-// ret = GetImplementation( control ).OnAccessibilityScrollToPage(Direction::LEFT);
- }
- }
- }
-
- return ret;
-}
-
-bool AccessibilityManager::AccessibilityActionPageRight()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionPageRightSignal.Empty() )
- {
- mActionPageRightSignal.Emit( handle );
- }
-
- bool ret = false;
-
- if(mIsAccessibilityTtsEnabled)
- {
- Actor actor = GetCurrentFocusActor();
- if(actor)
- {
- Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
- if(control)
- {
- // TODO: Notify the control to scroll right to the next page. Should control handle this?
-// ret = GetImplementation( control ).OnAccessibilityScrollToPage(Direction::RIGHT);
- }
- }
- }
-
- return ret;
-}
-
-bool AccessibilityManager::AccessibilityActionPageUp()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionPageUpSignal.Empty() )
- {
- mActionPageUpSignal.Emit( handle );
- }
-
- bool ret = false;
-
- if(mIsAccessibilityTtsEnabled)
- {
- Actor actor = GetCurrentFocusActor();
- if(actor)
- {
- Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
- if(control)
- {
- // TODO: Notify the control to scroll up to the previous page. Should control handle this?
-// ret = GetImplementation( control ).OnAccessibilityScrollToPage(Direction::UP);
- }
- }
- }
-
- return ret;
-}
-
-bool AccessibilityManager::AccessibilityActionPageDown()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionPageDownSignal.Empty() )
- {
- mActionPageDownSignal.Emit( handle );
- }
-
- bool ret = false;
-
- if(mIsAccessibilityTtsEnabled)
- {
- Actor actor = GetCurrentFocusActor();
- if(actor)
- {
- Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
- if(control)
- {
- // TODO: Notify the control to scroll down to the next page. Should control handle this?
-// ret = GetImplementation( control ).OnAccessibilityScrollToPage(Direction::DOWN);
- }
- }
- }
-
- return ret;
-}
-
-bool AccessibilityManager::AccessibilityActionMoveToFirst()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionMoveToFirstSignal.Empty() )
- {
- mActionMoveToFirstSignal.Emit( handle );
- }
-
- // TODO: Move to the first item on screen
-
- return mIsAccessibilityTtsEnabled;
-}
-
-bool AccessibilityManager::AccessibilityActionMoveToLast()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionMoveToLastSignal.Empty() )
- {
- mActionMoveToLastSignal.Emit( handle );
- }
-
- // TODO: Move to the last item on screen
-
- return mIsAccessibilityTtsEnabled;
-}
-
-bool AccessibilityManager::AccessibilityActionReadFromTop()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionReadFromTopSignal.Empty() )
- {
- mActionReadFromTopSignal.Emit( handle );
- }
-
- // TODO: Move to the top item on screen and read from the item continuously
-
- return mIsAccessibilityTtsEnabled;
-}
-
-bool AccessibilityManager::AccessibilityActionReadFromNext()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
-
- if( !mActionReadFromNextSignal.Empty() )
- {
- mActionReadFromNextSignal.Emit( handle );
- }
-
- if( mIsAccessibilityTtsEnabled )
- {
- // Mark that we are in continuous play mode, so TTS signals can move focus.
- mContinuousPlayMode = true;
-
- // Attempt to move to the next item and read from the item continuously.
- MoveFocusForward();
- }
-
- return mIsAccessibilityTtsEnabled;
-}
-
-void AccessibilityManager::TtsStateChanged( const Dali::TtsPlayer::State previousState, const Dali::TtsPlayer::State currentState )
-{
- if( mContinuousPlayMode )
- {
- // If we were playing and now we have stopped, attempt to play the next item.
- if( ( previousState == Dali::TtsPlayer::PLAYING ) && ( currentState == Dali::TtsPlayer::READY ) )
- {
- // Attempt to move the focus forward and play.
- // If we can't cancel continuous play mode.
- if( !MoveFocusForward() )
- {
- // We are done, exit continuous play mode.
- mContinuousPlayMode = false;
- }
- }
- else
- {
- // Unexpected play state change, exit continuous play mode.
- mContinuousPlayMode = false;
- }
- }
-}
-
-bool AccessibilityManager::AccessibilityActionZoom()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionZoomSignal.Empty() )
- {
- mActionZoomSignal.Emit( handle );
- }
-
- bool ret = false;
-
- if(mIsAccessibilityTtsEnabled)
- {
- Actor actor = GetCurrentFocusActor();
- if(actor)
- {
- Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
- if(control)
- {
- // Notify the control to zoom
- ret = GetImplementation( control ).OnAccessibilityZoom();
- }
- }
- }
-
- return ret;
-}
-
-bool AccessibilityManager::AccessibilityActionReadPauseResume()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionReadPauseResumeSignal.Empty() )
- {
- mActionReadPauseResumeSignal.Emit( handle );
- }
-
- bool ret = false;
-
- if(mIsAccessibilityTtsEnabled)
- {
- // Pause or resume the TTS player
- Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER);
- Dali::TtsPlayer::State state = player.GetState();
- if(state == Dali::TtsPlayer::PLAYING)
- {
- player.Pause();
- ret = true;
- }
- else if(state == Dali::TtsPlayer::PAUSED)
- {
- player.Resume();
- ret = true;
- }
- }
-
- return ret;
-}
-
-bool AccessibilityManager::AccessibilityActionStartStop()
-{
- Dali::Toolkit::AccessibilityManager handle( this );
- if( !mActionStartStopSignal.Empty() )
- {
- mActionStartStopSignal.Emit( handle );
- }
-
- // TODO: Start/stop the current action
-
- return mIsAccessibilityTtsEnabled;
-}
-
-bool AccessibilityManager::HandlePanGesture(const AccessibilityGestureEvent& panEvent)
-{
- bool handled = false;
-
- if( panEvent.state == AccessibilityGestureEvent::STARTED )
- {
- // Find the focusable actor at the event position
- Dali::HitTestAlgorithm::Results results;
- AccessibilityAdaptor adaptor = AccessibilityAdaptor::Get();
-
- Dali::HitTestAlgorithm::HitTest( Stage::GetCurrent(), panEvent.currentPosition, results, IsActorFocusableFunction );
- mCurrentGesturedActor = results.actor;
-
- if(!mCurrentGesturedActor)
- {
- DALI_LOG_ERROR("Gesture detected, but no hit actor\n");
- }
- }
-
- // GestureState::FINISHED (Up) events are delivered with previous (Motion) event position
- // Use the real previous position; otherwise we may incorrectly get a ZERO velocity
- if ( AccessibilityGestureEvent::FINISHED != panEvent.state )
- {
- // Store the previous position for next GestureState::FINISHED iteration.
- mPreviousPosition = panEvent.previousPosition;
- }
-
- Actor rootActor = Stage::GetCurrent().GetRootLayer();
-
- Dali::PanGesture pan = DevelPanGesture::New( static_cast<Dali::GestureState>(panEvent.state) );
- DevelPanGesture::SetTime( pan, panEvent.time );
- DevelPanGesture::SetNumberOfTouches( pan, panEvent.numberOfTouches );
- DevelPanGesture::SetScreenPosition( pan, panEvent.currentPosition );
- DevelPanGesture::SetScreenDisplacement( pan, mPreviousPosition - panEvent.currentPosition );
- DevelPanGesture::SetScreenVelocity( pan, Vector2( pan.GetScreenDisplacement().x / panEvent.timeDelta, pan.GetScreenDisplacement().y / panEvent.timeDelta ) );
-
- // Only handle the pan gesture when the current focused actor is scrollable or within a scrollable actor
- while(mCurrentGesturedActor && mCurrentGesturedActor != rootActor && !handled)
- {
- Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(mCurrentGesturedActor);
- if(control)
- {
- Vector2 localCurrent;
- control.ScreenToLocal( localCurrent.x, localCurrent.y, panEvent.currentPosition.x, panEvent.currentPosition.y );
- DevelPanGesture::SetPosition( pan, localCurrent );
-
- Vector2 localPrevious;
- control.ScreenToLocal( localPrevious.x, localPrevious.y, mPreviousPosition.x, mPreviousPosition.y );
-
- DevelPanGesture::SetDisplacement( pan, localCurrent - localPrevious );
- DevelPanGesture::SetVelocity( pan, Vector2( pan.GetDisplacement().x / panEvent.timeDelta, pan.GetDisplacement().y / panEvent.timeDelta ));
-
- handled = GetImplementation( control ).OnAccessibilityPan(pan);
- }
-
- // If the gesture is not handled by the control, check its parent
- if(!handled)
- {
- mCurrentGesturedActor = mCurrentGesturedActor.GetParent();
-
- if(!mCurrentGesturedActor)
- {
- DALI_LOG_ERROR("no more gestured actor\n");
- }
- }
- else
- {
- // If handled, then update the pan gesture properties
- PanGestureDetector::SetPanGestureProperties( pan );
- }
- }
-
- return handled;
+ return Dali::Accessibility::Accessible::GetHighlightActor();
}
Toolkit::AccessibilityManager::FocusChangedSignalType& AccessibilityManager::FocusChangedSignal()
// EXTERNAL INCLUDES
#include <string>
-#include <dali/devel-api/common/map-wrapper.h>
-#include <dali/devel-api/adaptor-framework/accessibility-action-handler.h>
-#include <dali/devel-api/adaptor-framework/accessibility-gesture-handler.h>
-#include <dali/devel-api/adaptor-framework/accessibility-gesture-event.h>
+#include <vector>
#include <dali/public-api/object/base-object.h>
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/accessibility-manager/accessibility-manager.h>
-#include <dali/public-api/adaptor-framework/tts-player.h>
namespace Dali
{
/**
* @copydoc Toolkit::AccessibilityManager
*/
-class AccessibilityManager : public Dali::BaseObject, Dali::AccessibilityActionHandler, Dali::AccessibilityGestureHandler, public Dali::ConnectionTracker
+class AccessibilityManager : public Dali::BaseObject, public Dali::ConnectionTracker
{
public:
typedef Dali::Toolkit::AccessibilityManager::AccessibilityActionSignalType AccessibilityActionSignalType;
typedef Dali::Toolkit::AccessibilityManager::AccessibilityActionScrollSignalType AccessibilityActionScrollSignalType;
- struct ActorAdditionalInfo
- {
- ActorAdditionalInfo()
- : mFocusOrder(0)
- {
- }
-
- unsigned int mFocusOrder; ///< The focus order of the actor. It is undefined by default.
-
- std::string mAccessibilityAttributes[Toolkit::AccessibilityManager::ACCESSIBILITY_ATTRIBUTE_NUM]; ///< The array of attribute texts
- };
-
- typedef std::pair<unsigned int, unsigned int> FocusIDPair;
- typedef std::map<unsigned int, unsigned int> FocusIDContainer;
- typedef FocusIDContainer::iterator FocusIDIter;
- typedef FocusIDContainer::const_iterator FocusIDConstIter;
-
- typedef std::pair<unsigned int, ActorAdditionalInfo> IDAdditionalInfoPair;
- typedef std::map<unsigned int, ActorAdditionalInfo> IDAdditionalInfoContainer;
- typedef IDAdditionalInfoContainer::iterator IDAdditionalInfoIter;
- typedef IDAdditionalInfoContainer::const_iterator IDAdditionalInfoConstIter;
-
/**
* Construct a new AccessibilityManager.
*/
AccessibilityManager();
/**
- * Initialise the AccessibilityManager
- */
- void Initialise();
-
- /**
* @copydoc Toolkit::AccessibilityManager::SetAccessibilityAttribute
*/
void SetAccessibilityAttribute(Actor actor, Toolkit::AccessibilityManager::AccessibilityAttribute type, const std::string& text);
bool GetGroupMode() const;
/**
+ * @copydoc Toolkit::AccessibilityManager::GetFocusGroup
+ */
+ Actor GetFocusGroup(Actor actor);
+
+ /**
+ * @copydoc Toolkit::AccessibilityManager::GetReadPosition
+ */
+ Vector2 GetReadPosition() const;
+
+ /**
* @copydoc Toolkit::AccessibilityManager::SetWrapMode
*/
void SetWrapMode(bool wrapped);
*/
Actor GetFocusIndicatorActor();
- /**
- * @copydoc Toolkit::AccessibilityManager::GetFocusGroup
- */
- Actor GetFocusGroup(Actor actor);
-
- /**
- * @copydoc Toolkit::AccessibilityManager::GetReadPosition
- */
- Vector2 GetReadPosition() const;
-
public:
/**
private:
- /**
- * Get the additional information (e.g. focus order and description) of the given actor.
- * @param actorID The ID of the actor to be queried
- * @return The additional information of the actor
- */
- ActorAdditionalInfo GetActorAdditionalInfo(const unsigned int actorID) const;
-
- /**
- * Synchronize the actor's additional information to reflect its latest focus order
- * @param actorID The ID of the actor
- * @param order The focus order of the actor
- * @return The additional information of the actor
- */
- void SynchronizeActorAdditionalInfo(const unsigned int actorID, const unsigned int order);
-
- /**
- * Move the focus to the specified actor and send notification for the focus change.
- * @param actorID The ID of the actor to be queried
- * @return Whether the focus is successful or not
- */
- bool DoSetCurrentFocusActor(const unsigned int actorID);
-
- /**
- * Move the focus to the next actor in the focus chain towards the specified direction.
- * @param focusIDIter The iterator pointing to the current focused actor
- * @param forward Whether the focus movement is forward or not. The focus movement will be backward if this is false.
- * @param wrapped Whether the focus shoule be moved wrapped around or not
- * @return Whether the focus is successful or not
- */
- bool DoMoveFocus(FocusIDIter focusIDIter, bool forward, bool wrapped);
-
- /**
- * Activate the actor. If the actor is control, call OnAccessibilityActivated virtual function.
- * This function will emit FocusedActorActivatedSignal.
- * @param actor The actor to activate
- */
- void DoActivate(Actor actor);
-
- /**
- * Set whether the actor is focusable or not. A focusable property will be registered for
- * the actor if not yet.
- * @param actor The actor to be focused
- * @param focusable Whether the actor is focusable or not
- */
- void SetFocusable(Actor actor, bool focusable);
-
- /**
- * Handle the accessibility pan gesture.
- * @param[in] panEvent The pan event to be handled.
- * @return whether the gesture is handled successfully or not.
- */
- bool HandlePanGesture(const AccessibilityGestureEvent& panEvent) override;
-
- /**
- * Change the accessibility status when Accessibility feature(screen-reader) turned on or off.
- * @return whether the status is changed or not.
- */
- bool ChangeAccessibilityStatus() override;
-
- /**
- * Clear the accessibility focus from the current focused actor.
- * @return whether the focus is cleared or not.
- */
- bool ClearAccessibilityFocus() override;
-
- /**
- * Perform the accessibility action associated with a scroll event.
- * @param touch The touch point (and time) of the event.
- * @return whether the focus is cleared or not.
- */
- bool AccessibilityActionScroll( Dali::TouchEvent& touch ) override;
-
- /**
- * Perform the accessibility action to move focus to the previous focusable actor (by one finger flick up).
- * @param allowEndFeedback true if end of list feedback should be played when the focus is alread reached to the end
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionPrevious(bool allowEndFeedback) override;
-
- /**
- * Perform the accessibility action to move focus to the next focusable actor (by one finger flick down).
- * @param allowEndFeedback true if end of list feedback should be played when the focus is alread reached to the end
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionNext(bool allowEndFeedback) override;
-
- /**
- * Perform the accessibility action to move focus to the previous focusable actor (by one finger flick left).
- * @param allowEndFeedback true if end of list feedback should be played when the focus is alread reached to the end
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionReadPrevious(bool allowEndFeedback) override;
-
- /**
- * Perform the accessibility action to move focus to the next focusable actor (by one finger flick right).
- * @param allowEndFeedback true if end of list feedback should be played when the focus is alread reached to the end
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionReadNext(bool allowEndFeedback) override;
-
- /**
- * Perform the accessibility action to focus and read the actor (by one finger tap or move).
- * @param allowReadAgain true if the action read again the same object (i.e. read action)
- * false if the action just read when the focus object is changed (i.e. over action)
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionRead(bool allowReadAgain) override;
-
- /**
- * Perform the accessibility action to activate the current focused actor (by one finger double tap).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionActivate() override;
-
- /**
- * Perform the accessibility action to change the value when the current focused actor is a slider
- * (by double finger down and move up and right).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionUp() override;
-
- /**
- * Perform the accessibility action to change the value when the current focused actor is a slider
- * (by double finger down and move down and left).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionDown() override;
-
- /**
- * Perform the accessibility action to navigate back (by two fingers circle draw).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionBack() override;
-
- /**
- * Perform the accessibility action to scroll up the list and focus on the first item on the list
- * after the scrolling and read the item (by two finger swipe up).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionScrollUp() override;
-
- /**
- * Perform the accessibility action to scroll down the list and focus on the first item on the list
- * after the scrolling and read the item (by two finger swipe down).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionScrollDown() override;
-
- /**
- * Perform the accessibility action to scroll left to the previous page (by two finger swipe left).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionPageLeft() override;
-
- /**
- * Perform the accessibility action to scroll right to the next page (by two finger swipe right).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionPageRight() override;
-
- /**
- * Perform the accessibility action to scroll up to the previous page (by one finger swipe left and right).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionPageUp() override;
-
- /**
- * Perform the accessibility action to scroll down to the next page (by one finger swipe right and left).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionPageDown() override;
-
- /**
- * Perform the accessibility action to move the focus to the first item on the screen
- * (by one finger swipe up and down).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionMoveToFirst() override;
-
- /**
- * Perform the accessibility action to move the focus to the last item on the screen
- * (by one finger swipe down and up).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionMoveToLast() override;
-
- /**
- * Perform the accessibility action to move the focus to the first item on the top
- * and read from the top item continuously (by three fingers single tap).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionReadFromTop() override;
-
- /**
- * Perform the accessibility action to move the focus to and read from the next item
- * continuously (by three fingers double tap).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionReadFromNext() override;
-
- /**
- * Perform the accessibility action to move the focus to do the zooming (by one finger triple tap).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionZoom() override;
-
- /**
- * Perform the accessibility action to pause/resume the current read out (by two fingers single tap).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionReadPauseResume() override;
-
- /**
- * Perform the accessibility action to start/stop the current action (by two fingers double tap).
- * @return whether the accessibility action is performed or not.
- */
- bool AccessibilityActionStartStop() override;
-
- /**
- * This function is connected to the TtsPlayer StateChangeSignal.
- * It is called when the TTS players state changes.
- * @param previousState The previous state of the TTS player (for comparison)
- * @param currentState The current state of the TTS player
- */
- void TtsStateChanged( const Dali::TtsPlayer::State previousState, const Dali::TtsPlayer::State currentState );
-
-private:
-
// Undefined
AccessibilityManager(const AccessibilityManager&);
private:
+ std::vector<Actor> mFocusOrder;
+
Toolkit::AccessibilityManager::FocusChangedSignalType mFocusChangedSignal; ///< The signal to notify the focus change
Toolkit::AccessibilityManager::FocusOvershotSignalType mFocusOvershotSignal; ///< The signal to notify the focus overshooted
Toolkit::AccessibilityManager::FocusedActorActivatedSignalType mFocusedActorActivatedSignal; ///< The signal to notify the activation of focused actor
AccessibilityActionSignalType mActionReadFromTopSignal;
AccessibilityActionSignalType mActionReadFromNextSignal;
AccessibilityActionSignalType mActionZoomSignal;
+ AccessibilityActionSignalType mActionReadIndicatorInformationSignal;
AccessibilityActionSignalType mActionReadPauseResumeSignal;
AccessibilityActionSignalType mActionStartStopSignal;
AccessibilityActionScrollSignalType mActionScrollSignal;
-
- FocusIDContainer mFocusIDContainer; ///< The container to look up actor ID by focus order
- IDAdditionalInfoContainer mIDAdditionalInfoContainer; ///< The container to look up additional information by actor ID
- FocusIDPair mCurrentFocusActor; ///< The focus order and actor ID of current focused actor
- Actor mCurrentGesturedActor; ///< The actor that will handle the gesture
- Actor mFocusIndicatorActor; ///< The focus indicator actor shared by all the focusable actors for highlight
- Vector2 mPreviousPosition; ///< The previous pan position; useful for calculating velocity for GestureState::FINISHED events
- unsigned int mRecursiveFocusMoveCounter; ///< The counter to count the number of recursive focus movement attempted before the focus movement is successful.
- std::string mFocusSoundFilePath; ///< The path of the focus sound file
- std::string mFocusChainEndSoundFilePath; ///< The path of the focus chain end sound file
-
- bool mIsWrapped:1; ///< Whether the focus movement is wrapped around or not
- bool mIsFocusWithinGroup:1; ///< Whether the focus movement is limited to the current focus group or not
- bool mIsEndcapFeedbackEnabled:1; ///< Whether the endcap feedback need to be played when the focus leaves the end or vice versa
- bool mIsEndcapFeedbackPlayed:1; ///< Whether the endcap feedback was played or not
- bool mIsAccessibilityTtsEnabled:1; ///< Whether accessibility feature(screen-reader) turned on/off
- bool mTtsCreated:1; ///< Whether the TTS Player has been accessed
- bool mIsFocusIndicatorEnabled:1; ///< Whether indicator should be shown / hidden. It could be enabled when TTS enabled or 'Tab' key operated.
- bool mContinuousPlayMode:1; ///< Keeps track of whether or not we are in continuous play mode
- bool mIsFocusSoundFilePathSet:1; ///< Whether the path of the focus sound file has been set
- bool mIsFocusChainEndSoundFilePathSet:1; ///< Whether the path of the focus chain end sound file has been set
-
};
} // namespace Internal
#include <dali/public-api/object/type-registry-helper.h>
#include <dali/public-api/size-negotiation/relayout-container.h>
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+
namespace Dali
{
return mPadding;
}
+void Alignment::OnInitialize()
+{
+ DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::FILLER ) );
+ } );
+}
+
void Alignment::OnRelayout( const Vector2& size, RelayoutContainer& container )
{
// lay out the actors
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/devel-api/controls/alignment/alignment.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
private: // From Control
/**
+ * @copydoc Control::OnInitialize()
+ */
+ virtual void OnInitialize() override;
+
+ /**
* @copydoc Control::OnRelayout()
*/
void OnRelayout( const Vector2& size, RelayoutContainer& container ) override;
#include <dali-toolkit/devel-api/controls/bloom-view/bloom-view.h>
#include <dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.h>
#include <dali-toolkit/internal/controls/control/control-renderers.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
// bind properties for / set shader constants to defaults
SetupProperties();
+
+ DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::ANIMATION ) );
+ } );
}
void BloomView::OnSizeSet(const Vector3& targetSize)
mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
self.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE, true );
+ self.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true );
self.TouchedSignal().Connect( this, &Button::OnTouch );
}
return mForegroundPadding;
}
+std::string Button::AccessibleImpl::GetNameRaw()
+{
+ std::string labelText;
+ auto slf = Toolkit::Button::DownCast( self );
+ Property::Map labelMap = slf.GetProperty<Property::Map>( Toolkit::Button::Property::LABEL );
+
+ Property::Value* textPropertyPtr = labelMap.Find( Toolkit::TextVisual::Property::TEXT );
+ if ( textPropertyPtr )
+ {
+ textPropertyPtr->Get( labelText );
+ }
+
+ return labelText;
+}
+
+
+Property::Index Button::AccessibleImpl::GetNamePropertyIndex()
+{
+ Property::Index label = Toolkit::Button::Property::LABEL;
+ Property::Map labelMap = self.GetProperty<Property::Map>(label);
+
+ if (MapContainsTextString(labelMap))
+ return label;
+ else
+ return Property::INVALID_INDEX;
+}
+
+Dali::Accessibility::States Button::AccessibleImpl::CalculateStates()
+{
+ auto tmp = Control::Impl::AccessibleImpl::CalculateStates();
+ tmp[Dali::Accessibility::State::SELECTABLE] = true;
+ auto slf = Toolkit::Button::DownCast( self );
+ tmp[Dali::Accessibility::State::ENABLED] = !slf.GetProperty<bool>( Toolkit::Button::Property::DISABLED );
+ tmp[Dali::Accessibility::State::CHECKED] = slf.GetProperty<bool>( Toolkit::Button::Property::SELECTED );
+ return tmp;
+}
+
} // namespace Internal
} // namespace Toolkit
#include <dali-toolkit/devel-api/visual-factory/visual-base.h>
#include <dali-toolkit/devel-api/controls/buttons/button-devel.h>
#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
// Actions
bool mClickActionPerforming; ///< Used to manage signal emissions during action
+
+protected:
+ struct AccessibleImpl : public Control::Impl::AccessibleImpl
+ {
+ using Control::Impl::AccessibleImpl::AccessibleImpl;
+
+ Dali::Accessibility::States CalculateStates() override;
+ std::string GetNameRaw() override;
+ Property::Index GetNamePropertyIndex() override;
+ };
};
} // namespace Internal
void CheckBoxButton::OnInitialize()
{
Button::OnInitialize();
+
+ DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new AccessibleImpl( actor, Dali::Accessibility::Role::CHECK_BOX ) );
+ } );
+}
+
+Dali::Accessibility::States CheckBoxButton::AccessibleImpl::CalculateStates()
+{
+ auto tmp = Button::AccessibleImpl::CalculateStates();
+ auto slf = Toolkit::Button::DownCast( self );
+ if( slf.GetProperty<bool>( Toolkit::Button::Property::SELECTED ) )
+ tmp[Dali::Accessibility::State::CHECKED] = true;
+ return tmp;
}
+void CheckBoxButton::OnStateChange( State newState )
+{
+ // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
+ if (Dali::Accessibility::IsUp() && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+ {
+ Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(
+ Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0
+ );
+ }
+}
} // namespace Internal
// Undefined
CheckBoxButton& operator=( const CheckBoxButton& );
-
+protected:
+ struct AccessibleImpl : public Button::AccessibleImpl
+ {
+ using Button::AccessibleImpl::AccessibleImpl;
+
+ Dali::Accessibility::States CalculateStates() override;
+ };
+ void OnStateChange( State newState ) override;
};
} // namespace Internal
// Push button requires the Leave event.
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 ) );
+ } );
}
void PushButton::SetIconAlignment( const PushButton::IconAlignment iconAlignment )
return value;
}
+Dali::Accessibility::States PushButton::AccessibleImpl::CalculateStates()
+{
+ auto tmp = Button::AccessibleImpl::CalculateStates();
+ auto slf = Toolkit::Button::DownCast( self );
+ tmp[Dali::Accessibility::State::PRESSED] = slf.GetProperty<bool>( Toolkit::Button::Property::SELECTED );
+ return tmp;
+}
+
+void PushButton::OnStateChange( State newState )
+{
+ // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
+ if (Dali::Accessibility::IsUp() && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+ {
+ Dali::Accessibility::Accessible::Get(Self())->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
+ );
+ }
+ }
+}
+
} // namespace Internal
} // namespace Toolkit
private:
IconAlignment mIconAlignment; ///< The alignment of the icon against the label.
+
+protected:
+ struct AccessibleImpl : public Button::AccessibleImpl
+ {
+ using Button::AccessibleImpl::AccessibleImpl;
+
+ Dali::Accessibility::States CalculateStates() override;
+ };
+ void OnStateChange( State newState ) override;
};
} // namespace Internal
void RadioButton::OnInitialize()
{
Button::OnInitialize();
+
+ DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new AccessibleImpl( actor, Dali::Accessibility::Role::RADIO_BUTTON ) );
+ } );
}
bool RadioButton::OnToggleReleased()
}
}
}
+ // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
+ if (Dali::Accessibility::IsUp() && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+ {
+ Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(
+ Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0
+ );
+ }
+}
+
+Dali::Accessibility::States RadioButton::AccessibleImpl::CalculateStates()
+{
+ auto tmp = Button::AccessibleImpl::CalculateStates();
+ auto slf = Toolkit::Button::DownCast( self );
+ if( slf.GetProperty<bool>( Toolkit::Button::Property::SELECTED ) )
+ tmp[Dali::Accessibility::State::CHECKED] = true;
+ tmp[Dali::Accessibility::State::SELECTABLE] = true;
+ return tmp;
}
} // namespace Internal
// Undefined
RadioButton& operator=( const RadioButton& origin );
+
+protected:
+ struct AccessibleImpl : public Button::AccessibleImpl
+ {
+ using Button::AccessibleImpl::AccessibleImpl;
+
+ Dali::Accessibility::States CalculateStates() override;
+ };
};
} // namespace Internal
// Toggle button requires the Leave event.
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 ) );
+ } );
}
void ToggleButton::SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value )
RelayoutRequest();
}
+Dali::Accessibility::States ToggleButton::AccessibleImpl::CalculateStates()
+{
+ auto states = Button::AccessibleImpl::CalculateStates();
+ auto button = Toolkit::ToggleButton::DownCast( self );
+ if( button.GetProperty<int>( Toolkit::ToggleButton::Property::CURRENT_STATE_INDEX ) )
+ states[Dali::Accessibility::State::CHECKED] = true;
+ return states;
+}
+
+std::string ToggleButton::AccessibleImpl::GetDescriptionRaw()
+{
+ auto button = Toolkit::ToggleButton::DownCast( self );
+ auto index = button.GetProperty<int>( Toolkit::ToggleButton::Property::CURRENT_STATE_INDEX );
+ auto tooltips = button.GetProperty<Property::Array>( Toolkit::ToggleButton::Property::TOOLTIPS );
+
+ return tooltips[index].Get<std::string>();
+}
+
+Property::Index ToggleButton::AccessibleImpl::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() && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+ {
+ Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(
+ Dali::Accessibility::State::CHECKED, mCurrentToggleIndex ? 1 : 0, 0
+ );
+
+ if(Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
+ {
+ Dali::Accessibility::Accessible::Get(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::DESCRIPTION);
+ }
+ }
+}
+
} // namespace Internal
} // namespace Toolkit
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
+ {
+ using Button::AccessibleImpl::AccessibleImpl;
+
+ Dali::Accessibility::States CalculateStates() override;
+ std::string GetDescriptionRaw() override;
+ Property::Index GetDescriptionPropertyIndex() override;
+ };
+ void OnStateChange( State newState ) override;
};
} // namespace Internal
#include <dali/integration-api/debug.h>
#include <dali/public-api/object/type-registry-helper.h>
#include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali/devel-api/common/stage.h>
+#include <dali-toolkit/public-api/controls/control.h>
+#include <dali/public-api/object/object-registry.h>
+#include <dali/devel-api/adaptor-framework/accessibility.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali/devel-api/actors/actor-devel.h>
#include <cstring>
#include <limits>
#include <dali-toolkit/devel-api/controls/control-wrapper-impl.h>
#include <dali-toolkit/internal/styling/style-manager-impl.h>
#include <dali-toolkit/internal/visuals/visual-string-constants.h>
+#include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
+#include <dali-toolkit/public-api/controls/image-view/image-view.h>
+
+namespace
+{
+ const std::string READING_INFO_TYPE_NAME = "name";
+ const std::string READING_INFO_TYPE_ROLE = "role";
+ const std::string READING_INFO_TYPE_DESCRIPTION = "description";
+ const std::string READING_INFO_TYPE_STATE = "state";
+ const std::string READING_INFO_TYPE_ATTRIBUTE_NAME = "reading_info_type";
+ const std::string READING_INFO_TYPE_SEPARATOR = "|";
+}
namespace Dali
{
* @param[in] attributes The attributes with which to perfrom this action.
* @return true if action has been accepted by this control
*/
-const char* ACTION_ACCESSIBILITY_ACTIVATED = "accessibilityActivated";
+const char* ACTION_ACCESSIBILITY_ACTIVATED = "accessibilityActivated";
+const char* ACTION_ACCESSIBILITY_READING_CANCELLED = "ReadingCancelled";
+const char* ACTION_ACCESSIBILITY_READING_PAUSED = "ReadingPaused";
+const char* ACTION_ACCESSIBILITY_READING_RESUMED = "ReadingResumed";
+const char* ACTION_ACCESSIBILITY_READING_SKIPPED = "ReadingSkipped";
+const char* ACTION_ACCESSIBILITY_READING_STOPPED = "ReadingStopped";
+
static bool DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
{
- bool ret = false;
+ bool ret = true;
+
+ Dali::BaseHandle handle( object );
+
+ Toolkit::Control control = Toolkit::Control::DownCast( handle );
- if( object && ( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_ACTIVATED ) ) )
+ DALI_ASSERT_ALWAYS( control );
+
+ if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_ACTIVATED ) ||
+ actionName == "activate" )
{
- Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
- if( control )
- {
- // if cast succeeds there is an implementation so no need to check
- ret = Internal::GetImplementation( control ).OnAccessibilityActivated();
- }
+ // if cast succeeds there is an implementation so no need to check
+ if( !DevelControl::AccessibilityActivateSignal( control ).Empty() )
+ DevelControl::AccessibilityActivateSignal( control ).Emit();
+ else ret = Internal::GetImplementation( control ).OnAccessibilityActivated();
+ }
+ else if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_READING_SKIPPED ) )
+ {
+ // if cast succeeds there is an implementation so no need to check
+ if( !DevelControl::AccessibilityReadingSkippedSignal( control ).Empty() )
+ DevelControl::AccessibilityReadingSkippedSignal( control ).Emit();
+ }
+ else if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_READING_PAUSED ) )
+ {
+ // if cast succeeds there is an implementation so no need to check
+ if( !DevelControl::AccessibilityReadingPausedSignal( control ).Empty() )
+ DevelControl::AccessibilityReadingPausedSignal( control ).Emit();
+ }
+ else if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_READING_RESUMED ) )
+ {
+ // if cast succeeds there is an implementation so no need to check
+ if( !DevelControl::AccessibilityReadingResumedSignal( control ).Empty() )
+ DevelControl::AccessibilityReadingResumedSignal( control ).Emit();
+ }
+ else if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_READING_CANCELLED ) )
+ {
+ // if cast succeeds there is an implementation so no need to check
+ if( !DevelControl::AccessibilityReadingCancelledSignal( control ).Empty() )
+ DevelControl::AccessibilityReadingCancelledSignal( control ).Emit();
+ }
+ else if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_READING_STOPPED ) )
+ {
+ // if cast succeeds there is an implementation so no need to check
+ if(!DevelControl::AccessibilityReadingStoppedSignal( control ).Empty())
+ DevelControl::AccessibilityReadingStoppedSignal( control ).Emit();
+ } else
+ {
+ ret = false;
}
-
return ret;
}
const char* SIGNAL_PANNED = "panned";
const char* SIGNAL_PINCHED = "pinched";
const char* SIGNAL_LONG_PRESSED = "longPressed";
+const char* SIGNAL_GET_NAME = "getName";
+const char* SIGNAL_GET_DESCRIPTION = "getDescription";
+const char* SIGNAL_DO_GESTURE = "doGesture";
static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
{
Dali::BaseHandle handle( object );
controlImpl.EnableGestureDetection( GestureType::LONG_PRESS );
controlImpl.GetLongPressGestureDetector().DetectedSignal().Connect( tracker, functor );
}
+ else if( 0 == strcmp( signalName.c_str(), SIGNAL_GET_NAME ) )
+ {
+ DevelControl::AccessibilityGetNameSignal( control ).Connect( tracker, functor );
+ }
+ else if( 0 == strcmp( signalName.c_str(), SIGNAL_GET_DESCRIPTION ) )
+ {
+ DevelControl::AccessibilityGetDescriptionSignal( control ).Connect( tracker, functor );
+ }
+ else if( 0 == strcmp( signalName.c_str(), SIGNAL_DO_GESTURE ) )
+ {
+ DevelControl::AccessibilityDoGestureSignal( control ).Connect( tracker, functor );
+ }
+
}
return connected;
}
SignalConnectorType registerSignal5( typeRegistration, SIGNAL_PANNED, &DoConnectSignal );
SignalConnectorType registerSignal6( typeRegistration, SIGNAL_PINCHED, &DoConnectSignal );
SignalConnectorType registerSignal7( typeRegistration, SIGNAL_LONG_PRESSED, &DoConnectSignal );
-
-TypeAction registerAction( typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, &DoAction );
+SignalConnectorType registerSignal8( typeRegistration, SIGNAL_GET_NAME, &DoConnectSignal );
+SignalConnectorType registerSignal9( typeRegistration, SIGNAL_GET_DESCRIPTION, &DoConnectSignal );
+SignalConnectorType registerSignal10( typeRegistration, SIGNAL_DO_GESTURE, &DoConnectSignal );
+
+TypeAction registerAction1( typeRegistration, "activate", &DoAction );
+TypeAction registerAction2( typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, &DoAction );
+TypeAction registerAction3( typeRegistration, ACTION_ACCESSIBILITY_READING_SKIPPED, &DoAction );
+TypeAction registerAction4( typeRegistration, ACTION_ACCESSIBILITY_READING_CANCELLED, &DoAction );
+TypeAction registerAction5( typeRegistration, ACTION_ACCESSIBILITY_READING_STOPPED, &DoAction );
+TypeAction registerAction6( typeRegistration, ACTION_ACCESSIBILITY_READING_PAUSED, &DoAction );
+TypeAction registerAction7( typeRegistration, ACTION_ACCESSIBILITY_READING_RESUMED, &DoAction );
DALI_TYPE_REGISTRATION_END()
const PropertyRegistration Control::Impl::PROPERTY_13( typeRegistration, "upFocusableActorId", Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
const PropertyRegistration Control::Impl::PROPERTY_14( typeRegistration, "downFocusableActorId", Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
const PropertyRegistration Control::Impl::PROPERTY_15( typeRegistration, "shadow", Toolkit::DevelControl::Property::SHADOW, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
-
+const PropertyRegistration Control::Impl::PROPERTY_16( typeRegistration, "accessibilityAttributes", Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+const PropertyRegistration Control::Impl::PROPERTY_17( typeRegistration, "accessibilityName", Toolkit::DevelControl::Property::ACCESSIBILITY_NAME, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+const PropertyRegistration Control::Impl::PROPERTY_18( typeRegistration, "accessibilityDescription", Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+const PropertyRegistration Control::Impl::PROPERTY_19( typeRegistration, "accessibilityTranslationDomain", Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+const PropertyRegistration Control::Impl::PROPERTY_20( typeRegistration, "accessibilityRole", Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+const PropertyRegistration Control::Impl::PROPERTY_21( typeRegistration, "accessibilityHighlightable", Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+const PropertyRegistration Control::Impl::PROPERTY_22( typeRegistration, "accessibilityAnimated", Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
Control::Impl::Impl( Control& controlImpl )
: mControlImpl( controlImpl ),
mKeyInputFocusLostSignal(),
mResourceReadySignal(),
mVisualEventSignal(),
+ mAccessibilityGetNameSignal(),
+ mAccessibilityGetDescriptionSignal(),
+ mAccessibilityDoGestureSignal(),
mPinchGestureDetector(),
mPanGestureDetector(),
mTapGestureDetector(),
mIsEmittingResourceReadySignal(false),
mNeedToEmitResourceReady(false)
{
+ Dali::Accessibility::Accessible::RegisterControlAccessibilityGetter(
+ []( Dali::Actor actor ) -> Dali::Accessibility::Accessible* {
+ return Control::Impl::GetAccessibilityObject( actor );
+ } );
+
+ accessibilityConstructor = []( Dali::Actor actor ) -> std::unique_ptr< Dali::Accessibility::Accessible > {
+ return std::unique_ptr< Dali::Accessibility::Accessible >( new AccessibleImpl( actor,
+ Dali::Accessibility::Role::UNKNOWN ) );
+ };
+
+ size_t len = static_cast<size_t>(Dali::Accessibility::RelationType::MAX_COUNT);
+ mAccessibilityRelations.reserve(len);
+ for (auto i = 0u; i < len; ++i)
+ {
+ mAccessibilityRelations.push_back({});
+ }
}
Control::Impl::~Impl()
{
+ AccessibilityDeregister();
// All gesture detectors will be destroyed so no need to disconnect.
delete mStartingPinchScale;
}
}
+void Control::Impl::AppendAccessibilityAttribute( const std::string& key,
+ const std::string value )
+{
+ Property::Value* val = mAccessibilityAttributes.Find( key );
+ if( val )
+ {
+ mAccessibilityAttributes[key] = Property::Value( value );
+ }
+ else
+ {
+ mAccessibilityAttributes.Insert( key, value );
+ }
+}
+
void Control::Impl::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
{
Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
}
break;
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME:
+ {
+ std::string name;
+ if( value.Get( name ) )
+ {
+ controlImpl.mImpl->mAccessibilityName = name;
+ controlImpl.mImpl->mAccessibilityNameSet = true;
+ }
+ else
+ {
+ controlImpl.mImpl->mAccessibilityNameSet = false;
+ }
+ }
+ break;
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
+ {
+ std::string txt;
+ if( value.Get( txt ) )
+ {
+ controlImpl.mImpl->mAccessibilityDescription = txt;
+ controlImpl.mImpl->mAccessibilityDescriptionSet = true;
+ }
+ else
+ {
+ controlImpl.mImpl->mAccessibilityDescriptionSet = false;
+ }
+ }
+ break;
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
+ {
+ std::string txt;
+ if( value.Get( txt ) )
+ {
+ controlImpl.mImpl->mAccessibilityTranslationDomain = txt;
+ controlImpl.mImpl->mAccessibilityTranslationDomainSet = true;
+ }
+ else
+ {
+ controlImpl.mImpl->mAccessibilityTranslationDomainSet = false;
+ }
+ }
+ break;
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
+ {
+ bool highlightable;
+ if( value.Get( highlightable ) )
+ {
+ controlImpl.mImpl->mAccessibilityHighlightable = highlightable;
+ controlImpl.mImpl->mAccessibilityHighlightableSet = true;
+ }
+ else
+ {
+ controlImpl.mImpl->mAccessibilityHighlightableSet = false;
+ }
+ }
+ break;
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
+ {
+ Dali::Accessibility::Role val;
+ if( value.Get( val ) )
+ {
+ controlImpl.mImpl->mAccessibilityRole = val;
+ }
+ }
+ break;
+
case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID:
{
int focusId;
break;
}
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
+ {
+ value.Get( controlImpl.mImpl->mAccessibilityAttributes );
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED:
+ {
+ value.Get( controlImpl.mImpl->mAccessibilityAnimated );
+ break;
+ }
}
}
}
break;
}
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME:
+ {
+ if (controlImpl.mImpl->mAccessibilityNameSet)
+ {
+ value = controlImpl.mImpl->mAccessibilityName;
+ }
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
+ {
+ if (controlImpl.mImpl->mAccessibilityDescriptionSet)
+ {
+ value = controlImpl.mImpl->mAccessibilityDescription;
+ }
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
+ {
+ if (controlImpl.mImpl->mAccessibilityTranslationDomainSet)
+ {
+ value = controlImpl.mImpl->mAccessibilityTranslationDomain;
+ }
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
+ {
+ if (controlImpl.mImpl->mAccessibilityHighlightableSet)
+ {
+ value = controlImpl.mImpl->mAccessibilityHighlightable;
+ }
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
+ {
+ value = Property::Value(controlImpl.mImpl->mAccessibilityRole);
+ break;
+ }
+
case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID:
{
value = controlImpl.mImpl->mUpFocusableActorId;
value = map;
break;
}
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
+ {
+ value = controlImpl.mImpl->mAccessibilityAttributes;
+ break;
+ }
+
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED:
+ {
+ value = controlImpl.mImpl->mAccessibilityAnimated;
+ break;
+ }
}
}
return value;
}
+void Control::Impl::RemoveAccessibilityAttribute( const std::string& key )
+{
+ Property::Value* val = mAccessibilityAttributes.Find( key );
+ if( val )
+ mAccessibilityAttributes[key] = Property::Value();
+}
+
+void Control::Impl::ClearAccessibilityAttributes()
+{
+ mAccessibilityAttributes.Clear();
+}
+
+void Control::Impl::SetAccessibilityReadingInfoType( const Dali::Accessibility::ReadingInfoTypes types )
+{
+ std::string value;
+ if ( types[ Dali::Accessibility::ReadingInfoType::NAME ] )
+ {
+ value += READING_INFO_TYPE_NAME;
+ }
+ if ( types[ Dali::Accessibility::ReadingInfoType::ROLE ] )
+ {
+ if( !value.empty() )
+ {
+ value += READING_INFO_TYPE_SEPARATOR;
+ }
+ value += READING_INFO_TYPE_ROLE;
+ }
+ if ( types[ Dali::Accessibility::ReadingInfoType::DESCRIPTION ] )
+ {
+ if( !value.empty() )
+ {
+ value += READING_INFO_TYPE_SEPARATOR;
+ }
+ value += READING_INFO_TYPE_DESCRIPTION;
+ }
+ if ( types[ Dali::Accessibility::ReadingInfoType::STATE ] )
+ {
+ if( !value.empty() )
+ {
+ value += READING_INFO_TYPE_SEPARATOR;
+ }
+ value += READING_INFO_TYPE_STATE;
+ }
+ AppendAccessibilityAttribute( READING_INFO_TYPE_ATTRIBUTE_NAME, value );
+}
+
+Dali::Accessibility::ReadingInfoTypes Control::Impl::GetAccessibilityReadingInfoType() const
+{
+ std::string value;
+ auto place = mAccessibilityAttributes.Find( READING_INFO_TYPE_ATTRIBUTE_NAME );
+ if( place )
+ {
+ place->Get( value );
+ }
+
+ if ( value.empty() )
+ {
+ return {};
+ }
+
+ Dali::Accessibility::ReadingInfoTypes types;
+
+ if ( value.find( READING_INFO_TYPE_NAME ) != std::string::npos )
+ {
+ types[ Dali::Accessibility::ReadingInfoType::NAME ] = true;
+ }
+ if ( value.find( READING_INFO_TYPE_ROLE ) != std::string::npos )
+ {
+ types[ Dali::Accessibility::ReadingInfoType::ROLE ] = true;
+ }
+ if ( value.find( READING_INFO_TYPE_DESCRIPTION ) != std::string::npos )
+ {
+ types[ Dali::Accessibility::ReadingInfoType::DESCRIPTION ] = true;
+ }
+ if ( value.find( READING_INFO_TYPE_STATE ) != std::string::npos )
+ {
+ types[ Dali::Accessibility::ReadingInfoType::STATE ] = true;
+ }
+
+ return types;
+}
void Control::Impl::CopyInstancedProperties( RegisteredVisualContainer& visuals, Dictionary<Property::Map>& instancedProperties )
{
mIdleCallback = nullptr;
}
+Dali::Accessibility::Accessible *Control::Impl::GetAccessibilityObject()
+{
+ if( !accessibilityObject )
+ accessibilityObject = accessibilityConstructor( mControlImpl.Self() );
+ return accessibilityObject.get();
+}
+
+Dali::Accessibility::Accessible *Control::Impl::GetAccessibilityObject(Dali::Actor actor)
+{
+ if( actor )
+ {
+ auto q = Dali::Toolkit::Control::DownCast( actor );
+ if( q )
+ {
+ auto q2 = static_cast< Internal::Control* >( &q.GetImplementation() );
+ return q2->mImpl->GetAccessibilityObject();
+ }
+ }
+ return nullptr;
+}
+
+Control::Impl::AccessibleImpl::AccessibleImpl(Dali::Actor self, Dali::Accessibility::Role role, bool modal)
+ : self(self), modal(modal)
+{
+ auto control = Dali::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)
+ {
+ if (this->self != Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
+ {
+ return;
+ }
+
+ if (index == DevelControl::Property::ACCESSIBILITY_NAME
+ || (index == GetNamePropertyIndex() && !controlImpl.mAccessibilityNameSet))
+ {
+ if (controlImpl.mAccessibilityGetNameSignal.Empty())
+ {
+ Emit(Dali::Accessibility::ObjectPropertyChangeEvent::NAME);
+ }
+ }
+
+ if (index == DevelControl::Property::ACCESSIBILITY_DESCRIPTION
+ || (index == GetDescriptionPropertyIndex() && !controlImpl.mAccessibilityDescriptionSet))
+ {
+ if (controlImpl.mAccessibilityGetDescriptionSignal.Empty())
+ {
+ Emit(Dali::Accessibility::ObjectPropertyChangeEvent::DESCRIPTION);
+ }
+ }
+ });
+}
+
+std::string Control::Impl::AccessibleImpl::GetName()
+{
+ auto control = Dali::Toolkit::Control::DownCast(self);
+
+ Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
+ Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
+
+ if (!controlImpl.mAccessibilityGetNameSignal.Empty()) {
+ std::string ret;
+ controlImpl.mAccessibilityGetNameSignal.Emit(ret);
+ return ret;
+ }
+
+ if (controlImpl.mAccessibilityNameSet)
+ return controlImpl.mAccessibilityName;
+
+ if (auto raw = GetNameRaw(); !raw.empty())
+ return raw;
+
+ return self.GetProperty< std::string >( Actor::Property::NAME );
+}
+
+std::string Control::Impl::AccessibleImpl::GetNameRaw()
+{
+ return {};
+}
+
+std::string Control::Impl::AccessibleImpl::GetDescription()
+{
+ auto control = Dali::Toolkit::Control::DownCast(self);
+
+ Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
+ Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
+
+ if (!controlImpl.mAccessibilityGetDescriptionSignal.Empty()) {
+ std::string ret;
+ controlImpl.mAccessibilityGetDescriptionSignal.Emit(ret);
+ return ret;
+ }
+
+ if (controlImpl.mAccessibilityDescriptionSet)
+ return controlImpl.mAccessibilityDescription;
+
+ return GetDescriptionRaw();
+}
+
+std::string Control::Impl::AccessibleImpl::GetDescriptionRaw()
+{
+ return "";
+}
+
+Dali::Accessibility::Accessible* Control::Impl::AccessibleImpl::GetParent()
+{
+ return Dali::Accessibility::Accessible::Get( self.GetParent() );
+}
+
+size_t Control::Impl::AccessibleImpl::GetChildCount()
+{
+ return self.GetChildCount();
+}
+
+Dali::Accessibility::Accessible* Control::Impl::AccessibleImpl::GetChildAtIndex( size_t index )
+{
+ return Dali::Accessibility::Accessible::Get( self.GetChildAt( static_cast< unsigned int >( index ) ) );
+}
+
+size_t Control::Impl::AccessibleImpl::GetIndexInParent()
+{
+ auto s = self;
+ auto parent = s.GetParent();
+ DALI_ASSERT_ALWAYS( parent && "can't call GetIndexInParent on object without parent" );
+ auto count = parent.GetChildCount();
+ for( auto i = 0u; i < count; ++i )
+ {
+ auto c = parent.GetChildAt( i );
+ if( c == s )
+ return i;
+ }
+ DALI_ASSERT_ALWAYS( false && "object isn't child of it's parent" );
+ return static_cast<size_t>(-1);
+}
+
+Dali::Accessibility::Role Control::Impl::AccessibleImpl::GetRole()
+{
+ return self.GetProperty<Dali::Accessibility::Role>( Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE );
+}
+
+Dali::Accessibility::States Control::Impl::AccessibleImpl::CalculateStates()
+{
+ Dali::Accessibility::States s;
+ s[Dali::Accessibility::State::FOCUSABLE] = self.GetProperty< bool >( Actor::Property::KEYBOARD_FOCUSABLE );
+ s[Dali::Accessibility::State::FOCUSED] = Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor() == self;
+ if(self.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE ).GetType() == Property::NONE )
+ s[Dali::Accessibility::State::HIGHLIGHTABLE] = false;
+ else
+ s[Dali::Accessibility::State::HIGHLIGHTABLE] = self.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE ).Get< bool >();
+ s[Dali::Accessibility::State::HIGHLIGHTED] = GetCurrentlyHighlightedActor() == self;
+ s[Dali::Accessibility::State::ENABLED] = true;
+ s[Dali::Accessibility::State::SENSITIVE] = true;
+ s[Dali::Accessibility::State::ANIMATED] = self.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED ).Get< bool >();
+ s[Dali::Accessibility::State::VISIBLE] = true;
+ if( modal )
+ {
+ s[Dali::Accessibility::State::MODAL] = true;
+ }
+ s[Dali::Accessibility::State::SHOWING] = !self.GetProperty( Dali::DevelActor::Property::CULLED ).Get< bool >()
+ && self.GetCurrentProperty< bool >( Actor::Property::VISIBLE );
+
+ s[Dali::Accessibility::State::DEFUNCT] = !self.GetProperty( Dali::DevelActor::Property::CONNECTED_TO_SCENE ).Get< bool >();
+ return s;
+}
+
+Dali::Accessibility::States Control::Impl::AccessibleImpl::GetStates()
+{
+ return CalculateStates();
+}
+
+Dali::Accessibility::Attributes Control::Impl::AccessibleImpl::GetAttributes()
+{
+ std::unordered_map< std::string, std::string > attribute_map;
+ auto q = Dali::Toolkit::Control::DownCast( self );
+ auto w =
+ q.GetProperty( Dali::Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES );
+ auto z = w.GetMap();
+
+ if( z )
+ {
+ auto map_size = z->Count();
+
+ for( unsigned int i = 0; i < map_size; i++ )
+ {
+ auto map_key = z->GetKeyAt( i );
+ if( map_key.type == Property::Key::STRING )
+ {
+ std::string map_value;
+ if( z->GetValue( i ).Get( map_value ) )
+ {
+ attribute_map.emplace( std::move( map_key.stringKey ),
+ std::move( map_value ) );
+ }
+ }
+ }
+ }
+
+ return attribute_map;
+}
+
+Dali::Accessibility::ComponentLayer Control::Impl::AccessibleImpl::GetLayer()
+{
+ return Dali::Accessibility::ComponentLayer::WINDOW;
+}
+
+Dali::Rect<> Control::Impl::AccessibleImpl::GetExtents( Dali::Accessibility::CoordType ctype )
+{
+ Vector2 screenPosition =
+ self.GetProperty( Dali::DevelActor::Property::SCREEN_POSITION )
+ .Get< Vector2 >();
+ auto size = self.GetCurrentProperty< Vector3 >( Actor::Property::SIZE ) * self.GetCurrentProperty< Vector3 >( Actor::Property::WORLD_SCALE );
+ bool positionUsesAnchorPoint =
+ self.GetProperty( Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT )
+ .Get< bool >();
+ Vector3 anchorPointOffSet =
+ size * ( positionUsesAnchorPoint ? self.GetCurrentProperty< Vector3 >( Actor::Property::ANCHOR_POINT )
+ : AnchorPoint::TOP_LEFT );
+ Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x,
+ screenPosition.y - anchorPointOffSet.y );
+
+ return { position.x, position.y, size.x, size.y };
+}
+
+int16_t Control::Impl::AccessibleImpl::GetMdiZOrder() { return 0; }
+double Control::Impl::AccessibleImpl::GetAlpha() { return 0; }
+
+bool Control::Impl::AccessibleImpl::GrabFocus()
+{
+ return Toolkit::KeyboardFocusManager::Get().SetCurrentFocusActor( self );
+}
+
+const char* const FOCUS_BORDER_IMAGE_PATH = DALI_IMAGE_DIR "keyboard_focus.9.png";
+
+static Dali::Actor CreateHighlightIndicatorActor()
+{
+ // Create the default if it hasn't been set and one that's shared by all the
+ // keyboard focusable actors const char* const FOCUS_BORDER_IMAGE_PATH =
+ // DALI_IMAGE_DIR "keyboard_focus.9.png";
+ auto actor = Toolkit::ImageView::New( FOCUS_BORDER_IMAGE_PATH );
+ actor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
+ DevelControl::AppendAccessibilityAttribute( actor, "highlight", "" );
+ actor.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED, true);
+ actor.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, false );
+
+ return actor;
+}
+
+bool Control::Impl::AccessibleImpl::GrabHighlight()
+{
+ auto old = GetCurrentlyHighlightedActor();
+
+ if( !Dali::Accessibility::IsUp() )
+ return false;
+ if( self == old )
+ return true;
+ if( old )
+ {
+ auto c = dynamic_cast< Dali::Accessibility::Component* >( GetAccessibilityObject( old ) );
+ if( c )
+ c->ClearHighlight();
+ }
+ auto highlight = GetHighlightActor();
+ if ( !highlight )
+ {
+ highlight = CreateHighlightIndicatorActor();
+ SetHighlightActor( highlight );
+ }
+ highlight.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
+ highlight.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
+ highlight.SetProperty( Actor::Property::POSITION_Z, 1.0f );
+ highlight.SetProperty( Actor::Property::POSITION, Vector2( 0.0f, 0.0f ));
+
+ EnsureSelfVisible();
+ self.Add( highlight );
+ SetCurrentlyHighlightedActor( self );
+ EmitHighlighted( true );
+
+ return true;
+}
+
+
+
+bool Control::Impl::AccessibleImpl::ClearHighlight()
+{
+ if( !Dali::Accessibility::IsUp() )
+ return false;
+ if( GetCurrentlyHighlightedActor() == self )
+ {
+ self.Remove( GetHighlightActor() );
+ SetCurrentlyHighlightedActor( {} );
+ EmitHighlighted( false );
+ return true;
+ }
+ return false;
+}
+
+std::string Control::Impl::AccessibleImpl::GetActionName( size_t index )
+{
+ if ( index >= GetActionCount() ) return "";
+ Dali::TypeInfo type;
+ self.GetTypeInfo( type );
+ DALI_ASSERT_ALWAYS( type && "no TypeInfo object" );
+ return type.GetActionName( index );
+}
+std::string Control::Impl::AccessibleImpl::GetLocalizedActionName( size_t index )
+{
+ // TODO: add localization
+ return GetActionName( index );
+}
+std::string Control::Impl::AccessibleImpl::GetActionDescription( size_t index )
+{
+ return "";
+}
+size_t Control::Impl::AccessibleImpl::GetActionCount()
+{
+ Dali::TypeInfo type;
+ self.GetTypeInfo( type );
+ DALI_ASSERT_ALWAYS( type && "no TypeInfo object" );
+ return type.GetActionCount();
+}
+std::string Control::Impl::AccessibleImpl::GetActionKeyBinding( size_t index )
+{
+ return "";
+}
+bool Control::Impl::AccessibleImpl::DoAction( size_t index )
+{
+ std::string actionName = GetActionName( index );
+ return self.DoAction( actionName, {} );
+}
+bool Control::Impl::AccessibleImpl::DoAction(const std::string& name)
+{
+ return self.DoAction( name, {} );
+}
+
+bool Control::Impl::AccessibleImpl::DoGesture(const Dali::Accessibility::GestureInfo &gestureInfo)
+{
+ auto control = Dali::Toolkit::Control::DownCast(self);
+
+ Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
+ Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
+
+ if (!controlImpl.mAccessibilityDoGestureSignal.Empty()) {
+ auto ret = std::make_pair(gestureInfo, false);
+ controlImpl.mAccessibilityDoGestureSignal.Emit(ret);
+ return ret.second;
+ }
+
+ return false;
+}
+
+std::vector<Dali::Accessibility::Relation> Control::Impl::AccessibleImpl::GetRelationSet()
+{
+ auto control = Dali::Toolkit::Control::DownCast(self);
+
+ Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
+ Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
+
+ std::vector<Dali::Accessibility::Relation> ret;
+
+ auto &v = controlImpl.mAccessibilityRelations;
+ for (auto i = 0u; i < v.size(); ++i)
+ {
+ if ( v[i].empty() )
+ continue;
+
+ ret.emplace_back( Accessibility::Relation{ static_cast<Accessibility::RelationType>(i), v[i] } );
+ }
+
+ return ret;
+}
+
+void Control::Impl::AccessibleImpl::EnsureChildVisible(Actor child)
+{
+}
+
+void Control::Impl::AccessibleImpl::EnsureSelfVisible()
+{
+ auto parent = dynamic_cast<Control::Impl::AccessibleImpl*>(GetParent());
+ if (parent)
+ {
+ parent->EnsureChildVisible(self);
+ }
+}
+
+Property::Index Control::Impl::AccessibleImpl::GetNamePropertyIndex()
+{
+ return Actor::Property::NAME;
+}
+
+Property::Index Control::Impl::AccessibleImpl::GetDescriptionPropertyIndex()
+{
+ return Property::INVALID_INDEX;
+}
+
+void Control::Impl::PositionOrSizeChangedCallback( PropertyNotification &p )
+{
+ auto self = Dali::Actor::DownCast(p.GetTarget());
+ if (Dali::Accessibility::IsUp() && !self.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED ).Get< bool >())
+ {
+ auto extents = DevelActor::CalculateScreenExtents( self );
+ Dali::Accessibility::Accessible::Get( self )->EmitBoundsChanged( extents );
+ }
+}
+
+void Control::Impl::CulledChangedCallback( PropertyNotification &p)
+{
+ if (Dali::Accessibility::IsUp())
+ {
+ auto self = Dali::Actor::DownCast(p.GetTarget());
+ Dali::Accessibility::Accessible::Get(self)->EmitShowing( !self.GetProperty( DevelActor::Property::CULLED ).Get<bool>() );
+ }
+}
+
+void Control::Impl::AccessibilityRegister()
+{
+ if (!accessibilityNotificationSet)
+ {
+ accessibilityNotificationPosition = mControlImpl.Self().AddPropertyNotification( Actor::Property::POSITION, StepCondition( 0.01f ) );
+ accessibilityNotificationPosition.SetNotifyMode( PropertyNotification::NOTIFY_ON_CHANGED );
+ accessibilityNotificationPosition.NotifySignal().Connect( &Control::Impl::PositionOrSizeChangedCallback );
+
+ accessibilityNotificationSize = mControlImpl.Self().AddPropertyNotification( Actor::Property::SIZE, StepCondition( 0.01f ) );
+ accessibilityNotificationSize.SetNotifyMode( PropertyNotification::NOTIFY_ON_CHANGED );
+ accessibilityNotificationSize.NotifySignal().Connect( &Control::Impl::PositionOrSizeChangedCallback );
+
+ accessibilityNotificationCulled = mControlImpl.Self().AddPropertyNotification( DevelActor::Property::CULLED, LessThanCondition( 0.5f ) );
+ accessibilityNotificationCulled.SetNotifyMode( PropertyNotification::NOTIFY_ON_CHANGED );
+ accessibilityNotificationCulled.NotifySignal().Connect( &Control::Impl::CulledChangedCallback );
+
+ accessibilityNotificationSet = true;
+ }
+}
+
+void Control::Impl::AccessibilityDeregister()
+{
+ if (accessibilityNotificationSet)
+ {
+ accessibilityNotificationPosition = {};
+ accessibilityNotificationSize = {};
+ accessibilityNotificationCulled = {};
+ accessibilityNotificationSet = false;
+ }
+}
+
} // namespace Internal
} // namespace Toolkit
// EXTERNAL INCLUDES
#include <dali/public-api/object/type-registry.h>
+#include <dali/public-api/object/property-notification.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali/devel-api/adaptor-framework/accessibility.h>
#include <string>
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali/devel-api/common/owner-container.h>
#include <dali-toolkit/devel-api/visual-factory/visual-base.h>
-#include <dali-toolkit/internal/controls/tooltip/tooltip.h>
-#include <dali-toolkit/internal/builder/style.h>
#include <dali-toolkit/internal/builder/dictionary.h>
+#include <dali-toolkit/internal/builder/style.h>
+#include <dali-toolkit/internal/controls/tooltip/tooltip.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/public-api/visuals/visual-properties.h>
+#include <dali/devel-api/common/owner-container.h>
+#include <dali/integration-api/debug.h>
+#include <memory>
namespace Dali
{
bool FilterKeyEvent( const KeyEvent& event );
/**
+ * @brief Adds accessibility attribute
+ * @param[in] key Attribute name to set
+ * @param[in] value Attribute value to set
+ *
+ * Attribute is added if not existed previously or updated
+ * if existed.
+ */
+ void AppendAccessibilityAttribute( const std::string& key,
+ const std::string value );
+
+ /**
+ * @brief Removes accessibility attribute
+ * @param[in] key Attribute name to remove
+ *
+ * Function does nothing if attribute doesn't exist.
+ */
+ void RemoveAccessibilityAttribute( const std::string& key );
+
+ /**
+ * @brief Removes all accessibility attributes
+ */
+ void ClearAccessibilityAttributes();
+
+ /**
+ * @brief Sets reading info type attributes
+ * @param[in] types info type attributes to set
+ *
+ * This function sets, which part of object will be read out
+ * by screen-reader.
+ */
+ void SetAccessibilityReadingInfoType( const Dali::Accessibility::ReadingInfoTypes types );
+
+ /**
+ * @brief Gets currently active reading info type attributes
+ */
+ Dali::Accessibility::ReadingInfoTypes GetAccessibilityReadingInfoType() const;
+
+ /**
* @copydoc DevelControl::VisualEventSignal()
*/
DevelControl::VisualEventSignalType& VisualEventSignal();
Control& mControlImpl;
DevelControl::State mState;
std::string mSubStateName;
+ Property::Map mAccessibilityAttributes;
int mLeftFocusableActorId; ///< Actor ID of Left focusable control.
int mRightFocusableActorId; ///< Actor ID of Right focusable control.
Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusLostSignal;
Toolkit::Control::ResourceReadySignalType mResourceReadySignal;
DevelControl::VisualEventSignalType mVisualEventSignal;
+ Toolkit::DevelControl::AccessibilityActivateSignalType mAccessibilityActivateSignal;
+ Toolkit::DevelControl::AccessibilityReadingSkippedSignalType mAccessibilityReadingSkippedSignal;
+ Toolkit::DevelControl::AccessibilityReadingPausedSignalType mAccessibilityReadingPausedSignal;
+ Toolkit::DevelControl::AccessibilityReadingResumedSignalType mAccessibilityReadingResumedSignal;
+ Toolkit::DevelControl::AccessibilityReadingCancelledSignalType mAccessibilityReadingCancelledSignal;
+ Toolkit::DevelControl::AccessibilityReadingStoppedSignalType mAccessibilityReadingStoppedSignal;
+
+ Toolkit::DevelControl::AccessibilityGetNameSignalType mAccessibilityGetNameSignal;
+ Toolkit::DevelControl::AccessibilityGetDescriptionSignalType mAccessibilityGetDescriptionSignal;
+ Toolkit::DevelControl::AccessibilityDoGestureSignalType mAccessibilityDoGestureSignal;
+
+ std::string mAccessibilityName;
+ bool mAccessibilityNameSet = false;
+
+ std::string mAccessibilityDescription;
+ bool mAccessibilityDescriptionSet = false;
+
+ std::string mAccessibilityTranslationDomain;
+ bool mAccessibilityTranslationDomainSet = false;
+
+ bool mAccessibilityHighlightable = false;
+ bool mAccessibilityHighlightableSet = false;
+
+ Dali::Accessibility::Role mAccessibilityRole = Dali::Accessibility::Role::UNKNOWN;
+
+ std::vector<std::vector<Accessibility::Address>> mAccessibilityRelations;
+ bool mAccessibilityAnimated = false;
// Gesture Detection
PinchGestureDetector mPinchGestureDetector;
static const PropertyRegistration PROPERTY_13;
static const PropertyRegistration PROPERTY_14;
static const PropertyRegistration PROPERTY_15;
+ static const PropertyRegistration PROPERTY_16;
+ static const PropertyRegistration PROPERTY_17;
+ static const PropertyRegistration PROPERTY_18;
+ static const PropertyRegistration PROPERTY_19;
+ static const PropertyRegistration PROPERTY_20;
+ static const PropertyRegistration PROPERTY_21;
+ static const PropertyRegistration PROPERTY_22;
+
+ /**
+ * The method acquires Accessible handle from Actor object
+ * @param actor Actor object
+ * @return handle to Accessible object
+ */
+ static Dali::Accessibility::Accessible *GetAccessibilityObject(Dali::Actor actor);
+ Dali::Accessibility::Accessible *GetAccessibilityObject();
+
+ void AccessibilityRegister();
+ void AccessibilityDeregister();
+
+ struct AccessibleImpl : public virtual Dali::Accessibility::Accessible,
+ public virtual Dali::Accessibility::Component,
+ public virtual Dali::Accessibility::Collection,
+ public virtual Dali::Accessibility::Action
+ {
+ Dali::Actor self;
+ bool modal = false, root = false;
+
+ AccessibleImpl(Dali::Actor self, Dali::Accessibility::Role role, bool modal = false);
+
+ std::string GetName() override;
+ virtual std::string GetNameRaw();
+ std::string GetDescription() override;
+ virtual std::string GetDescriptionRaw();
+ Dali::Accessibility::Accessible* GetParent() override;
+ size_t GetChildCount() override;
+ Dali::Accessibility::Accessible* GetChildAtIndex( size_t index ) override;
+ size_t GetIndexInParent() override;
+ Dali::Accessibility::Role GetRole() override;
+ Dali::Accessibility::States GetStates() override;
+ Dali::Accessibility::Attributes GetAttributes() override;
+ Dali::Rect<> GetExtents( Dali::Accessibility::CoordType ctype ) override;
+ Dali::Accessibility::ComponentLayer GetLayer() override;
+ int16_t GetMdiZOrder() override;
+ bool GrabFocus() override;
+ double GetAlpha() override;
+ bool GrabHighlight() override;
+ bool ClearHighlight() override;
+
+ std::string GetActionName( size_t index ) override;
+ std::string GetLocalizedActionName( size_t index ) override;
+ std::string GetActionDescription( size_t index ) override;
+ size_t GetActionCount() override;
+ std::string GetActionKeyBinding(size_t index) override;
+ bool DoAction(size_t index) override;
+ bool DoAction(const std::string& name) override;
+ bool DoGesture(const Dali::Accessibility::GestureInfo &gestureInfo) override;
+ std::vector<Dali::Accessibility::Relation> GetRelationSet() override;
+
+ virtual Dali::Accessibility::States CalculateStates();
+ virtual void EnsureChildVisible(Actor child);
+ virtual void EnsureSelfVisible();
+ virtual Property::Index GetNamePropertyIndex();
+ virtual Property::Index GetDescriptionPropertyIndex();
+ };
+
+ std::function< std::unique_ptr< Dali::Accessibility::Accessible >( Actor ) > accessibilityConstructor;
+ std::unique_ptr< Dali::Accessibility::Accessible > accessibilityObject;
+ Dali::PropertyNotification accessibilityNotificationPosition, accessibilityNotificationSize, accessibilityNotificationCulled;
+ bool accessibilityNotificationSet = false;
+ static void PositionOrSizeChangedCallback( PropertyNotification& );
+ static void CulledChangedCallback( PropertyNotification& );
};
#include <dali-toolkit/internal/filters/emboss-filter.h>
#include <dali-toolkit/internal/filters/spread-filter.h>
#include <dali-toolkit/internal/controls/control/control-renderers.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
CustomActor self = Self();
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 Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::FILLER ) );
+ } );
}
void EffectsView::OnSizeSet(const Vector3& targetSize)
#include <dali/public-api/size-negotiation/relayout-container.h>
#include <dali/integration-api/debug.h>
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+
using namespace Dali;
namespace
// Make self as keyboard focusable and focus group
self.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE, true );
SetAsKeyboardFocusGroup( true );
+
+ DevelControl::SetAccessibilityConstructor( self, []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::FILLER ) );
+ } );
}
} // namespace Internal
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/visuals/visual-properties.h>
#include <dali-toolkit/internal/controls/control/control-renderers.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
// TODO:
// pixel format / size - set from JSON
mInternalRoot.Add( mHorizBlurActor );
mInternalRoot.Add( mVertBlurActor );
mInternalRoot.Add( mRenderDownsampledCamera );
+
+ DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::FILLER ) );
+ } );
}
#include <dali-toolkit/internal/visuals/visual-string-constants.h>
#include <dali-toolkit/internal/visuals/visual-base-impl.h>
#include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
// ImageView can relayout in the OnImageReady, alternative to a signal would be to have a upcall from the Control to ImageView
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 Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::IMAGE ) );
+ } );
+
+ //Enable highightability
+ Self().SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true );
+
}
void ImageView::SetImage( const Property::Map& map )
#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
#include <dali-toolkit/internal/visuals/visual-factory-impl.h>
#include <dali-toolkit/public-api/visuals/visual-properties.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
constraint.AddSource( Source( self, Actor::Property::SIZE ) );
constraint.AddSource( Source( self, Actor::Property::WORLD_SCALE ) );
constraint.Apply();
+
+ DevelControl::SetAccessibilityConstructor( self, []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::FILLER ) );
+ } );
}
Magnifier::~Magnifier()
// INTERNAL INCLUDES
#include <dali-toolkit/internal/controls/model3d-view/obj-loader.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
Shader shader = Shader::New( SIMPLE_VERTEX_SHADER, SIMPLE_FRAGMENT_SHADER );
mRenderer = Renderer::New( mesh, shader );
+ DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::IMAGE ) );
+ } );
}
void Model3dView::LoadGeometry()
#include <dali/public-api/object/type-registry-helper.h>
// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
return navigationView;
}
+void NavigationView::OnInitialize()
+{
+ DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::FILLER ) );
+ } );
+}
+
void NavigationView::OnSceneConnection( int depth )
{
Self().SetProperty( Actor::Property::SENSITIVE,true);
private: // override functions from Control
/**
+ * @copydoc Constrol::OnInitialize
+ */
+ virtual void OnInitialize() override;
+
+ /**
* @copydoc Control::OnSceneConnection( int depth )
*/
void OnSceneConnection( int depth ) override;
#include <dali-toolkit/internal/controls/page-turn-view/page-turn-book-spine-effect.h>
#include <dali-toolkit/internal/visuals/visual-factory-cache.h>
#include <dali-toolkit/internal/visuals/visual-string-constants.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
using namespace Dali;
// 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 Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::PAGE_TAB_LIST ) );
+ } );
}
Shader PageTurnView::CreateShader( const Property::Map& shaderMap )
#include <dali/public-api/object/type-registry-helper.h>
#include <cstring>
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+
namespace Dali
{
#include <dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h>
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/public-api/controls/image-view/image-view.h>
-#include <dali-toolkit/devel-api/accessibility-manager/accessibility-manager.h>
#include <dali-toolkit/public-api/visuals/color-visual-properties.h>
#include <dali-toolkit/public-api/visuals/visual-properties.h>
#include <dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/dali-toolkit.h>
using namespace Dali;
SetAsKeyboardFocusGroup( true );
SetupTouch();
+
+ DevelControl::AppendAccessibilityAttribute(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));
+ });
}
Popup::~Popup()
bool Popup::OnAutoHideTimeReached()
{
- // Display timer has expired, auto hide the popup exactly as if the user had clicked outside.
- SetDisplayState( Toolkit::Popup::HIDDEN );
+ if (!Dali::Accessibility::IsUp() || true) // TODO: remove 'true' in sync with EFL (UX change)
+ {
+ // Display timer has expired, auto hide the popup exactly as if the user had clicked outside.
+ SetDisplayState( Toolkit::Popup::HIDDEN );
+ }
if( mAutoHideTimer )
{
return;
}
+ auto *accessible = Dali::Accessibility::Accessible::Get(Self());
+ if (display)
+ {
+ Dali::Accessibility::Bridge::GetCurrentBridge()->AddPopup(accessible);
+ accessible->EmitStateChanged(Dali::Accessibility::State::SHOWING, 1, 0);
+ }
+ else
+ {
+ accessible->EmitStateChanged(Dali::Accessibility::State::SHOWING, 0, 0);
+ Dali::Accessibility::Bridge::GetCurrentBridge()->RemovePopup(accessible);
+ }
+
// Convert the bool state to the actual display state to use.
mDisplayState = display ? Toolkit::Popup::SHOWING : Toolkit::Popup::HIDING;
}
}
+std::string Popup::AccessibleImpl::GetNameRaw()
+{
+ auto popup = Toolkit::Popup::DownCast( self );
+ std::string title;
+ Actor popupTitle = popup.GetTitle();
+ if (popupTitle)
+ {
+ std::string titleText = popupTitle.GetProperty<std::string>(Toolkit::TextLabel::Property::TEXT);
+ title = titleText;
+ }
+ else
+ {
+ Actor popupContent = popup.GetContent();
+ if (popupContent)
+ {
+ std::string contentText = popupContent.GetProperty<std::string>(Toolkit::TextLabel::Property::TEXT);
+ title = contentText;
+ }
+ }
+ return title;
+}
+
+Dali::Accessibility::States Popup::AccessibleImpl::CalculateStates()
+{
+ auto states = Control::Impl::AccessibleImpl::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");
+
+ return states;
+}
+
} // namespace Internal
} // namespace Toolkit
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/devel-api/controls/table-view/table-view.h>
#include <dali-toolkit/devel-api/controls/popup/popup.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
static Property::Value GetProperty( BaseObject* object, Property::Index propertyIndex );
protected:
+ struct AccessibleImpl : public Control::Impl::AccessibleImpl
+ {
+ using Control::Impl::AccessibleImpl::AccessibleImpl;
+
+ std::string GetNameRaw() override;
+ Dali::Accessibility::States CalculateStates() override;
+ };
/**
* Construct a new Popup.
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 );
}
void ProgressBar::OnRelayout( const Vector2& size, RelayoutContainer& container )
Toolkit::ProgressBar self = Toolkit::ProgressBar::DownCast( Self() );
mValueChangedSignal.Emit( self, mProgressValue, mSecondaryProgressValue );
+ if (Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
+ {
+ Control::Impl::GetAccessibilityObject(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
+ }
RelayoutRequest();
}
}
}
}
+double ProgressBar::AccessibleImpl::GetMinimum() { return DEFAULT_LOWER_BOUND; }
+
+double ProgressBar::AccessibleImpl::GetCurrent()
+{
+ auto p = Toolkit::ProgressBar::DownCast( self );
+ return p.GetProperty( Toolkit::ProgressBar::Property::PROGRESS_VALUE )
+ .Get< float >();
+}
+
+double ProgressBar::AccessibleImpl::GetMaximum() { return DEFAULT_UPPER_BOUND; }
+
+bool ProgressBar::AccessibleImpl::SetCurrent( double current )
+{
+ if( current < GetMinimum() || current > GetMaximum() )
+ return false;
+ auto p = Toolkit::ProgressBar::DownCast( self );
+ p.SetProperty( Toolkit::ProgressBar::Property::PROGRESS_VALUE,
+ static_cast< float >( current ) );
+ return true;
+}
+
+double ProgressBar::AccessibleImpl::GetMinimumIncrement() { return 0.0; }
+
} // namespace Internal
} // namespace Toolkit
#include <dali-toolkit/public-api/controls/progress-bar/progress-bar.h>
#include <dali-toolkit/devel-api/controls/progress-bar/progress-bar-devel.h>
#include <dali-toolkit/devel-api/visual-factory/transition-data.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
Property::Map mTrackVisualMap; ///< To backup visual properties when switching determinate/indeterminate.
Property::Map mProgressVisualMap; ///< To backup visual properties when switching determinate/indeterminate.
Property::Map mSecondaryProgressVisualMap; ///< To backup visual properties when switching determinate/indeterminate.
+
+protected:
+ struct AccessibleImpl : public Control::Impl::AccessibleImpl,
+ public virtual Dali::Accessibility::Value
+ {
+ using Control::Impl::AccessibleImpl::AccessibleImpl;
+ double GetMinimum() override;
+ double GetCurrent() override;
+ double GetMaximum() override;
+ bool SetCurrent( double ) override;
+ double GetMinimumIncrement() override;
+ };
};
} // namespace Internal
{
CreateDefaultIndicatorActor();
Self().SetProperty( Actor::Property::DRAW_MODE,DrawMode::OVERLAY_2D);
+
+ DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new AccessibleImpl( actor, Dali::Accessibility::Role::SCROLL_BAR ) );
+ } );
}
void ScrollBar::SetScrollPropertySource( Handle handle, Property::Index propertyScrollPosition, Property::Index propertyMinScrollPosition, Property::Index propertyMaxScrollPosition, Property::Index propertyScrollContentSize )
if(scrollableHandle)
{
mScrollPositionIntervalReachedSignal.Emit( scrollableHandle.GetCurrentProperty< float >( mPropertyScrollPosition ) );
+ if (Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
+ {
+ Control::Impl::GetAccessibilityObject(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
+ }
}
}
return handle;
}
+double ScrollBar::AccessibleImpl::GetMinimum()
+{
+ auto p = Toolkit::ScrollBar::DownCast( self );
+ Handle scrollableHandle = GetImpl( p ).mScrollableObject.GetHandle();
+ return scrollableHandle ? scrollableHandle.GetCurrentProperty< float >( GetImpl( p ).mPropertyMinScrollPosition ) : 0.0f;
+}
+
+double ScrollBar::AccessibleImpl::GetCurrent()
+{
+ auto p = Toolkit::ScrollBar::DownCast( self );
+ Handle scrollableHandle = GetImpl( p ).mScrollableObject.GetHandle();
+ return scrollableHandle ? scrollableHandle.GetCurrentProperty< float >( GetImpl( p ).mPropertyScrollPosition ) : 0.0f;
+}
+
+double ScrollBar::AccessibleImpl::GetMaximum()
+{
+ auto p = Toolkit::ScrollBar::DownCast( self );
+ Handle scrollableHandle = GetImpl( p ).mScrollableObject.GetHandle();
+ return scrollableHandle ? scrollableHandle.GetCurrentProperty< float >( GetImpl( p ).mPropertyMaxScrollPosition ) : 1.0f;
+}
+
+bool ScrollBar::AccessibleImpl::SetCurrent( double current )
+{
+ if( current < GetMinimum() || current > GetMaximum() )
+ return false;
+
+ auto value_before = GetCurrent();
+
+ auto p = Toolkit::ScrollBar::DownCast( self );
+ Handle scrollableHandle = GetImpl( p ).mScrollableObject.GetHandle();
+ if( !scrollableHandle )
+ return false;
+ scrollableHandle.SetProperty( GetImpl( p ).mPropertyScrollPosition, static_cast< float >( current ) );
+
+ auto value_after = GetCurrent();
+
+ if( ( current != value_before ) && ( value_before == value_after ) )
+ return false;
+
+ return true;
+}
+
+double ScrollBar::AccessibleImpl::GetMinimumIncrement() { return 1.0; }
+
} // namespace Internal
} // namespace Toolkit
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/devel-api/controls/scroll-bar/scroll-bar.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
WeakHandle<Handle> mScrollableObject; ///< Object to be scrolled
- Property::Index mPropertyScrollPosition; ///< Index of scroll position property owned by the object to be scrolled
- Property::Index mPropertyMinScrollPosition; ///< Index of minimum scroll position property owned by the object to be scrolled
- Property::Index mPropertyMaxScrollPosition; ///< Index of maximum scroll position property owned by the object to be scrolled
+ Property::Index mPropertyScrollPosition = 0; ///< Index of scroll position property owned by the object to be scrolled
+ Property::Index mPropertyMinScrollPosition = 0; ///< Index of minimum scroll position property owned by the object to be scrolled
+ Property::Index mPropertyMaxScrollPosition = 1; ///< Index of maximum scroll position property owned by the object to be scrolled
Property::Index mPropertyScrollContentSize; ///< Index of scroll content size property owned by the object to be scrolled
float mIndicatorShowDuration; ///< The duration of scroll indicator show animation
bool mIsPanning : 1; ///< Whether the scroll bar is being panned.
bool mIndicatorFirstShow : 1; ///< True if the indicator has never been shown
+
+protected:
+ struct AccessibleImpl : public Control::Impl::AccessibleImpl,
+ public virtual Dali::Accessibility::Value
+ {
+ using Control::Impl::AccessibleImpl::AccessibleImpl;
+ double GetMinimum() override;
+ double GetCurrent() override;
+ double GetMaximum() override;
+ bool SetCurrent( double ) override;
+ double GetMinimumIncrement() override;
+ };
};
} // namespace Internal
#include <cstring> // for strcmp
#include <algorithm>
#include <dali/public-api/actors/layer.h>
-
+#include <dali/devel-api/actors/actor-devel.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/constraints.h>
#include <dali/devel-api/common/stage.h>
void ItemView::OnInitialize()
{
+ Scrollable::OnInitialize();
+
Actor self = Self();
Vector2 stageSize = Stage::GetCurrent().GetSize();
// 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));
+ });
}
ItemView::~ItemView()
}
}
+void ItemView::AccessibleImpl::EnsureChildVisible(Actor child)
+{
+ EnsureSelfVisible();
+ auto itemView = Dali::Toolkit::ItemView::DownCast(self);
+ Toolkit::GetImpl(itemView).OnKeyboardFocusChangeCommitted(child);
+}
+
Animation ItemView::DoAnchoring()
{
Animation anchoringAnimation;
void OnKeyboardFocusChangeCommitted(Actor commitedFocusableActor) override;
protected:
+ struct AccessibleImpl : public Scrollable::AccessibleImpl
+ {
+ using Scrollable::AccessibleImpl::AccessibleImpl;
+
+ void EnsureChildVisible(Actor child) override;
+ };
/**
* Construct a new ItemView.
// ScrollBase
///////////////////////////////////////////////////////////////////////////////////////////////////
-ScrollBase::ScrollBase()
-: Scrollable(),
- mParent(NULL),
- mDelay(0.0f)
-{
-}
-
ScrollBase::ScrollBase( ControlBehaviour behaviourFlags )
: Scrollable( behaviourFlags ),
mParent(NULL),
protected:
/**
- * Construct a new ScrollBase.
+ * Removed default costructor.
*/
- ScrollBase();
+ ScrollBase() = delete;
/**
* @brief Construct a new ScrollBase.
// EXTERNAL INCLUDES
#include <cstring> // for strcmp
+#include <dali/devel-api/actors/actor-devel.h>
#include <dali/public-api/animation/constraints.h>
#include <dali/devel-api/common/stage.h>
#include <dali/public-api/events/wheel-event.h>
// 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 ) );
+ } );
}
void ScrollView::OnSceneConnection( int depth )
return mSnapStartedSignal;
}
+void ScrollView::AccessibleImpl::EnsureChildVisible(Actor child)
+{
+ auto scrollView = Dali::Toolkit::ScrollView::DownCast(self);
+ scrollView.ScrollTo(child);
+}
+
void ScrollView::FindAndUnbindActor(Actor child)
{
UnbindActor(child);
void SetInternalConstraints();
protected:
+ struct AccessibleImpl : public Scrollable::AccessibleImpl
+ {
+ using Scrollable::AccessibleImpl::AccessibleImpl;
+
+ void EnsureChildVisible(Actor child) override;
+ };
/**
* Construct a new ScrollView.
// INTERNAL INCLUDES
#include <dali-toolkit/internal/controls/scrollable/scrollable-impl.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
using namespace Dali;
// Scrollable
///////////////////////////////////////////////////////////////////////////////////////////////////
-// Scrollable controls are not layout containers so they dont need size negotiation..
-// we dont want size negotiation while scrolling if we can avoid it
-Scrollable::Scrollable()
-: Control( ControlBehaviour( DISABLE_SIZE_NEGOTIATION ) ),
- mOvershootEffectColor( DEFAULT_OVERSHOOT_COLOUR ),
- mOvershootAnimationSpeed ( DEFAULT_OVERSHOOT_ANIMATION_SPEED ),
- mOvershootSize( OVERSHOOT_DEFAULT_SIZE ),
- mScrollToAlphaFunction( AlphaFunction::EASE_OUT ),
- mScrollStartedSignal(),
- mScrollUpdatedSignal(),
- mScrollCompletedSignal(),
- mOvershootEnabled(true)
-{
-}
-
Scrollable::Scrollable( ControlBehaviour behaviourFlags )
: Control( ControlBehaviour( behaviourFlags ) ),
mOvershootEffectColor( DEFAULT_OVERSHOOT_COLOUR ),
{
}
+bool Scrollable::AccessibleImpl::IsScrollable()
+{
+ 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 ) );
+ } );
+}
+
bool Scrollable::IsOvershootEnabled() const
{
return mOvershootEnabled;
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/public-api/controls/scrollable/scrollable.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
*/
virtual void SetOvershootSize( const Vector2& size ) = 0;
+protected: // From Control
+ struct AccessibleImpl : public Control::Impl::AccessibleImpl
+ {
+ using Control::Impl::AccessibleImpl::AccessibleImpl;
+
+ bool IsScrollable() override;
+ };
+
+ /**
+ * @copydoc Control::OnInitialize
+ */
+ virtual void OnInitialize() override;
+
private:
/**
protected:
/**
- * Construct a new Scrollable.
+ * Removed default constructor.
*/
- Scrollable();
+ Scrollable() = delete;
/**
* @brief Construct a new Scrollable.
#include <dali-toolkit/internal/controls/control/control-renderers.h>
#include <dali-toolkit/internal/controls/shadow-view/shadow-view-impl.h>
#include <dali-toolkit/internal/filters/blur-two-pass-filter.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
// TODO:
// pixel format / size - set from JSON
Constraint blurStrengthConstraint = Constraint::New<float>( mBlurFilter.GetHandleForAnimateBlurStrength(), mBlurFilter.GetBlurStrengthPropertyIndex(), EqualToConstraint() );
blurStrengthConstraint.AddSource( Source( self, mBlurStrengthPropertyIndex) );
blurStrengthConstraint.Apply();
+
+ DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new Control::Impl::AccessibleImpl( actor, 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 ) );
+ } );
}
void Slider::OnRelayout( const Vector2& size, RelayoutContainer& container )
textLabel.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
textLabel.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
textLabel.SetProperty( Actor::Property::PADDING, Padding( POPUP_TEXT_PADDING, POPUP_TEXT_PADDING, 0.0f, 0.0f ) );
+ textLabel.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, false );
return textLabel;
}
mHandleValueTextLabel.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
mHandleValueTextLabel.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
mHandleValueTextLabel.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
+ mHandleValueTextLabel.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, false );
mHandle.Add( mHandleValueTextLabel );
}
}
{
const float MARK_TOLERANCE = GetMarkTolerance();
- float mark;
- for( MarkList::SizeType i = 0; i < mMarks.Count(); ++i)
- {
- const Property::Value& propertyValue = mMarks[i];
- propertyValue.Get( mark );
- mark = MapValuePercentage( mark );
-
- // If close to a mark, return the mark
- if( fabsf( mark - value ) < MARK_TOLERANCE )
- {
- return mark;
- }
- }
+ float mark = SnapToMark(value);
+ if (fabsf(mark - value) < MARK_TOLERANCE)
+ return mark;
return value;
}
{
mValue = value;
DisplayValue( mValue, true );
+ if (Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
+ {
+ Control::Impl::GetAccessibilityObject(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
+ }
}
float Slider::GetValue() const
return value;
}
+double Slider::AccessibleImpl::GetMinimum()
+{
+ auto p = Toolkit::Slider::DownCast( self );
+ return p.GetProperty( Toolkit::Slider::Property::LOWER_BOUND ).Get< float >();
+}
+
+double Slider::AccessibleImpl::GetCurrent()
+{
+ auto p = Toolkit::Slider::DownCast( self );
+ return p.GetProperty( Toolkit::Slider::Property::VALUE ).Get< float >();
+}
+
+double Slider::AccessibleImpl::GetMaximum()
+{
+ auto p = Toolkit::Slider::DownCast( self );
+ return p.GetProperty( Toolkit::Slider::Property::UPPER_BOUND ).Get< float >();
+}
+
+bool Slider::AccessibleImpl::SetCurrent( double current )
+{
+ if (current < GetMinimum() || current > GetMaximum())
+ return false;
+
+ auto p = Toolkit::Slider::DownCast( self );
+ auto &impl = Toolkit::GetImpl(p);
+
+ const float prev = p.GetProperty<float>(Toolkit::Slider::Property::VALUE);
+ float next = static_cast<float>(current);
+
+ if (fabsf(next - prev) < Math::MACHINE_EPSILON_0)
+ {
+ // do nothing
+ }
+ else if (p.GetProperty<bool>(Toolkit::Slider::Property::SNAP_TO_MARKS))
+ {
+ auto marks = p.GetProperty<Property::Array>(Toolkit::Slider::Property::MARKS);
+
+ int prevIdx;
+ if (impl.MarkReached(impl.MapValuePercentage(prev), prevIdx))
+ {
+ int nextIdx = prevIdx;
+ nextIdx += (next > prev) ? 1 : -1;
+
+ if (nextIdx < 0 || nextIdx >= static_cast<int>(marks.Count()))
+ return false;
+
+ next = marks[nextIdx].Get<float>();
+ }
+ else
+ {
+ next = impl.MapBounds(impl.SnapToMark(impl.MapValuePercentage(next)), impl.GetLowerBound(), impl.GetUpperBound());
+ }
+ }
+ else
+ {
+ next = impl.MapBounds(impl.MarkFilter(impl.MapValuePercentage(next)), impl.GetLowerBound(), impl.GetUpperBound());
+ }
+
+ impl.SetValue(next);
+ impl.DisplayPopup(next);
+
+ return true;
+}
+
+double Slider::AccessibleImpl::GetMinimumIncrement()
+{
+ auto p = Toolkit::Slider::DownCast( self );
+
+ bool hasMarks = !p.GetProperty<Property::Array>(Toolkit::Slider::Property::MARKS).Empty();
+ float tolerance = p.GetProperty<float>(Toolkit::Slider::Property::MARK_TOLERANCE);
+
+ if (!hasMarks || fabsf(tolerance) < 0.01)
+ return 0.0; // let screen-reader choose the increment
+
+ return Math::MACHINE_EPSILON_10000 + tolerance * (GetMaximum() - GetMinimum());
+}
+
} // namespace Internal
} // namespace Toolkit
#include <dali-toolkit/public-api/controls/slider/slider.h>
#include <dali-toolkit/public-api/controls/text-controls/text-label.h>
#include <dali-toolkit/public-api/controls/image-view/image-view.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
Vector2 mTrackRegion; ///< Size of track region
Vector2 mHandleSize; ///< Size of the handle
- float mLowerBound; ///< Lower bound on value
- float mUpperBound; ///< Upper bound on value
- float mValue; ///< Current value of slider
+ float mLowerBound = 0.0f; ///< Lower bound on value
+ float mUpperBound = 1.0f; ///< Upper bound on value
+ float mValue = 0.0f; ///< Current value of slider
- float mMarkTolerance; ///< Tolerance in percentage of slider width for which to snap to marks
+ float mMarkTolerance = 0.05f; ///< Tolerance in percentage of slider width for which to snap to marks
int mValuePrecision; ///< The precision to use for outputting the value
bool mShowPopup : 1, ///< Show the popup or not
mShowValue : 1, ///< Whether to display the value number or not on the handle
mSnapToMarks : 1; ///< Turn on or off snapping to marks
+
+protected:
+ struct AccessibleImpl : public Control::Impl::AccessibleImpl,
+ public virtual Dali::Accessibility::Value
+ {
+ using Control::Impl::AccessibleImpl::AccessibleImpl;
+ double GetMinimum() override;
+ double GetCurrent() override;
+ double GetMaximum() override;
+ bool SetCurrent( double ) override;
+ double GetMinimumIncrement() override;
+ };
};
} // namespace Internal
#include <dali-toolkit/internal/controls/control/control-renderers.h>
#include <dali-toolkit/internal/visuals/visual-base-impl.h>
#include <dali-toolkit/internal/visuals/visual-factory-impl.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace //Unnamed namespace
{
Actor self( Self() );
mBlurStrengthPropertyIndex = self.RegisterProperty( "blurStrength", 0.f );
+
+ DevelControl::SetAccessibilityConstructor( self, []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::FILLER ) );
+ } );
}
void SuperBlurView::SetTexture( Texture texture )
#include <dali/public-api/size-negotiation/relayout-container.h>
#include <dali/integration-api/debug.h>
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+
using namespace Dali;
namespace
Actor self = Self();
self.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE,true);
SetAsKeyboardFocusGroup(true);
+
+ DevelControl::SetAccessibilityConstructor( self, []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::TABLE ) );
+ } );
}
void TableView::ResizeContainers( unsigned int rows, unsigned int columns )
#include <dali-toolkit/devel-api/text/rendering-backend.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
#include <dali-toolkit/public-api/visuals/visual-properties.h>
#include <dali-toolkit/internal/text/text-enumerations-impl.h>
#include <dali-toolkit/internal/text/rendering/text-backend.h>
DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "maxLength", INTEGER, MAX_LENGTH )
DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectedTextStart", INTEGER, SELECTED_TEXT_START )
DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectedTextEnd", INTEGER, SELECTED_TEXT_END )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "horizontalScrollPosition", FLOAT, HORIZONTAL_SCROLL_POSITION )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "verticalScrollPosition", INTEGER, VERTICAL_SCROLL_POSITION )
DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "enableEditing", BOOLEAN, ENABLE_EDITING )
DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY( Toolkit, TextEditor, "selectedText", STRING, SELECTED_TEXT )
impl.SetEditable( editable );
break;
}
+ case Toolkit::DevelTextEditor::Property::HORIZONTAL_SCROLL_POSITION:
+ {
+ float horizontalScroll = value.Get< float >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p HORIZONTAL_SCROLL_POSITION %d\n", impl.mController.Get(), horizontalScroll );
+ if (horizontalScroll >= 0.0f)
+ {
+ impl.ScrollBy( Vector2(horizontalScroll - impl.GetHorizontalScrollPosition(), 0 ));
+ }
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::VERTICAL_SCROLL_POSITION:
+ {
+ float verticalScroll = value.Get< float >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p VERTICAL_SCROLL_POSITION %d\n", impl.mController.Get(), verticalScroll );
+ if (verticalScroll >= 0.0f)
+ {
+ impl.ScrollBy( Vector2(0, verticalScroll - impl.GetVerticalScrollPosition() ));
+ }
+ break;
+ }
} // switch
} // texteditor
}
value = impl.IsEditable();
break;
}
+ case Toolkit::DevelTextEditor::Property::HORIZONTAL_SCROLL_POSITION:
+ {
+ value = impl.GetHorizontalScrollPosition();
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::VERTICAL_SCROLL_POSITION:
+ {
+ value = impl.GetVerticalScrollPosition();
+ break;
+ }
} //switch
}
}
}
+void TextEditor::ScrollBy(Vector2 scroll)
+{
+ if( mController && mController->IsShowingRealText() )
+ {
+ mController->ScrollBy(scroll);
+ }
+}
+
+float TextEditor::GetHorizontalScrollPosition()
+{
+ if( mController && mController->IsShowingRealText() )
+ {
+ return mController->GetHorizontalScrollPosition();
+ }
+ return 0;
+}
+
+float TextEditor::GetVerticalScrollPosition()
+{
+ if( mController && mController->IsShowingRealText() )
+ {
+ return mController->GetVerticalScrollPosition();
+ }
+ return 0;
+}
+
string TextEditor::GetSelectedText() const
{
string selectedText = "";
return mMaxLengthReachedSignal;
}
+Text::ControllerPtr TextEditor::getController()
+{
+ return mController;
+}
+
bool TextEditor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
{
Dali::BaseHandle handle( object );
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.
mStencil.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
self.Add( mStencil );
+
+ DevelControl::SetAccessibilityConstructor( self, []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new AccessibleImpl( actor, Dali::Accessibility::Role::ENTRY ) );
+ } );
}
void TextEditor::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
EmitKeyInputFocusSignal( false ); // Calls back into the Control hence done last.
}
+bool TextEditor::OnAccessibilityActivated()
+{
+ SetKeyInputFocus();
+ return true;
+}
+
void TextEditor::OnTap( const TapGesture& gesture )
{
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnTap %p\n", mController.Get() );
RelayoutRequest();
}
+void TextEditor::TextInserted( unsigned int position, unsigned int length, const std::string &content )
+{
+ if( Accessibility::IsUp() )
+ {
+ Control::Impl::GetAccessibilityObject( Self() )->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 );
+ }
+}
+
+void TextEditor::CaretMoved( unsigned int position )
+{
+ if( Accessibility::IsUp() )
+ {
+ Control::Impl::GetAccessibilityObject( Self() )->EmitTextCaretMoved( position );
+ }
+}
+
void TextEditor::TextChanged()
{
Dali::Toolkit::TextEditor handle( GetOwner() );
}
}
+std::string TextEditor::AccessibleImpl::GetName()
+{
+ auto slf = Toolkit::TextEditor::DownCast( self );
+ return slf.GetProperty( Toolkit::TextEditor::Property::TEXT )
+ .Get< std::string >();
+}
+
+std::string TextEditor::AccessibleImpl::GetText( size_t startOffset,
+ size_t endOffset )
+{
+ if( endOffset <= startOffset )
+ return {};
+
+ auto slf = Toolkit::TextEditor::DownCast( self );
+ auto txt =
+ slf.GetProperty( Toolkit::TextEditor::Property::TEXT ).Get< std::string >();
+
+ if( startOffset > txt.size() || endOffset > txt.size() )
+ return {};
+
+ return txt.substr( startOffset, endOffset - startOffset );
+}
+
+size_t TextEditor::AccessibleImpl::GetCharacterCount()
+{
+ auto slf = Toolkit::TextEditor::DownCast( self );
+ auto txt =
+ slf.GetProperty( Toolkit::TextEditor::Property::TEXT ).Get< std::string >();
+
+ return txt.size();
+}
+
+size_t TextEditor::AccessibleImpl::GetCaretOffset()
+{
+ auto slf = Toolkit::TextEditor::DownCast( self );
+ return Dali::Toolkit::GetImpl( slf ).getController()->GetCursorPosition();
+}
+
+bool TextEditor::AccessibleImpl::SetCaretOffset(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.getController()->ResetCursorPosition( offset );
+ slfImpl.RequestTextRelayout();
+ return true;
+}
+
+Dali::Accessibility::Range TextEditor::AccessibleImpl::GetTextAtOffset(
+ size_t offset, Dali::Accessibility::TextBoundary boundary )
+{
+ auto slf = Toolkit::TextEditor::DownCast( self );
+ auto txt = slf.GetProperty( Toolkit::TextEditor::Property::TEXT ).Get< std::string >();
+ auto txt_size = txt.size();
+
+ auto range = Dali::Accessibility::Range{};
+
+ switch(boundary)
+ {
+ case Dali::Accessibility::TextBoundary::CHARACTER:
+ {
+ if (offset < txt_size)
+ {
+ range.content = txt[offset];
+ range.startOffset = offset;
+ range.endOffset = offset + 1;
+ }
+ }
+ break;
+ case Dali::Accessibility::TextBoundary::WORD:
+ case Dali::Accessibility::TextBoundary::LINE:
+ {
+ auto txt_c_string = txt.c_str();
+ auto breaks = std::vector< char >( txt_size, 0 );
+ if(boundary == Dali::Accessibility::TextBoundary::WORD)
+ Accessibility::Accessible::FindWordSeparationsUtf8((const utf8_t *) txt_c_string, txt_size, "", breaks.data());
+ else
+ Accessibility::Accessible::FindLineSeparationsUtf8((const utf8_t *) txt_c_string, txt_size, "", breaks.data());
+ auto index = 0u;
+ auto counter = 0u;
+ while( index < txt_size && 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 = txt.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 efl */
+ }
+ break;
+ case Dali::Accessibility::TextBoundary::PARAGRAPH:
+ {
+ /* Paragraph is not supported by libunibreak library */
+ }
+ break;
+ default:
+ break;
+ }
+
+ return range;
+}
+
+Dali::Accessibility::Range
+TextEditor::AccessibleImpl::GetSelection( size_t selectionNum )
+{
+ // Since DALi supports only one selection indexes higher than 0 are ignored
+ if( selectionNum > 0 )
+ return {};
+
+ auto slf = Toolkit::TextEditor::DownCast( self );
+ auto ctrl = Dali::Toolkit::GetImpl( slf ).getController();
+ std::string ret;
+ ctrl->RetrieveSelection( ret );
+ auto r = ctrl->GetSelectionIndexes();
+
+ return { static_cast<size_t>(r.first), static_cast<size_t>(r.second), ret };
+}
+
+bool TextEditor::AccessibleImpl::RemoveSelection( size_t selectionNum )
+{
+ // Since DALi supports only one selection indexes higher than 0 are ignored
+ if( selectionNum > 0 )
+ return false;
+
+ auto slf = Toolkit::TextEditor::DownCast( self );
+ Dali::Toolkit::GetImpl( slf ).getController()->SetSelection( 0, 0 );
+ return true;
+}
+
+bool TextEditor::AccessibleImpl::SetSelection( size_t selectionNum,
+ size_t startOffset,
+ size_t endOffset )
+{
+ // Since DALi supports only one selection indexes higher than 0 are ignored
+ if( selectionNum > 0 )
+ return false;
+
+ auto slf = Toolkit::TextEditor::DownCast( self );
+ Dali::Toolkit::GetImpl( slf ).getController()->SetSelection( startOffset,
+ endOffset );
+ return true;
+}
+
+bool TextEditor::AccessibleImpl::CopyText( size_t startPosition,
+ size_t endPosition )
+{
+ if( endPosition <= startPosition )
+ return false;
+
+ auto slf = Toolkit::TextEditor::DownCast( self );
+ auto txt = slf.GetProperty( Toolkit::TextEditor::Property::TEXT ).Get<std::string>();
+ Dali::Toolkit::GetImpl( slf ).getController()->CopyStringToClipboard( txt.substr(startPosition, endPosition - startPosition) );
+
+ return true;
+}
+
+bool TextEditor::AccessibleImpl::CutText( size_t startPosition,
+ size_t endPosition )
+{
+ if( endPosition <= startPosition )
+ return false;
+
+ auto slf = Toolkit::TextEditor::DownCast( self );
+ auto txt = slf.GetProperty( Toolkit::TextEditor::Property::TEXT ).Get<std::string>();
+ Dali::Toolkit::GetImpl( slf ).getController()->CopyStringToClipboard( txt.substr(startPosition, endPosition - startPosition) );
+
+ slf.SetProperty( Toolkit::TextEditor::Property::TEXT,
+ txt.substr( 0, startPosition ) + txt.substr( endPosition - startPosition, txt.size()));
+
+ return true;
+}
+
+Dali::Accessibility::States TextEditor::AccessibleImpl::CalculateStates()
+{
+ using namespace Dali::Accessibility;
+
+ auto states = Control::Impl::AccessibleImpl::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;
+}
+
} // namespace Internal
} // namespace Toolkit
// EXTERNAL INCLUDES
#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
#include <dali/devel-api/adaptor-framework/input-method-context.h>
+#include <dali/devel-api/adaptor-framework/accessibility.h>
#include <dali/public-api/animation/animation.h>
// INTERNAL INCLUDES
#include <dali-toolkit/internal/text/text-controller.h>
#include <dali-toolkit/internal/text/text-vertical-scroller.h>
#include <dali-toolkit/internal/text/rendering/text-renderer.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
void OnKeyInputFocusLost() override;
/**
+ * @copydoc Control::OnAccessibilityActivated()
+ */
+ bool OnAccessibilityActivated() override;
+
+ /**
* @copydoc Control::OnTap()
*/
void OnTap( const TapGesture& tap ) override;
/**
* @copydoc Text::EditableControlInterface::TextChanged()
*/
+ void TextInserted( unsigned int position, unsigned int length, const std::string &content ) override;
+
+ /**
+ * @copydoc Text::EditableControlInterface::TextDeleted()
+ */
+ void TextDeleted( unsigned int position, unsigned int length, const std::string &content ) override;
+
+ /**
+ * @copydoc Text::EditableControlInterface::CaretMoved()
+ */
+ void CaretMoved( unsigned int position ) override;
+
+ /**
+ * @copydoc Text::EditableControlInterface::TextChanged()
+ */
void TextChanged() override;
/**
void SelectNone() override;
/**
+ * @copydoc Dali::Toolkit::DevelTextEditor::ScrollBy()
+ */
+ void ScrollBy(Vector2 Scroll);
+
+ /**
+ * @brief Get Horizontal scroll position of TextEditor.
+ *
+ * @return Horizontal scroll position (in pixels) of TextEditor.
+ */
+ float GetHorizontalScrollPosition();
+
+ /**
+ * @brief Get Vertical scroll position of TextEditor.
+ *
+ * @return Vertical scroll position (in pixels) of TextEditor.
+ */
+ float GetVerticalScrollPosition();
+
+ /**
* @copydoc Text::SelectableControlInterface::GetSelectedText()
*/
string GetSelectedText() const override;
* @copydoc Text::EditableControlInterface::SetEditable()
*/
void SetEditable( bool editable ) override;
+ Text::ControllerPtr getController();
private: // Implementation
bool mScrollAnimationEnabled:1;
bool mScrollBarEnabled:1;
bool mScrollStarted:1;
+
+ struct AccessibleImpl : public Control::Impl::AccessibleImpl,
+ public virtual Dali::Accessibility::Text,
+ public virtual Dali::Accessibility::EditableText
+ {
+ using Control::Impl::AccessibleImpl::AccessibleImpl;
+
+ std::string GetName() override;
+ std::string GetText( size_t startOffset, size_t endOffset ) override;
+ size_t GetCharacterCount() override;
+ size_t GetCaretOffset() override;
+ bool SetCaretOffset(size_t offset) override;
+ Dali::Accessibility::Range
+ GetTextAtOffset( size_t offset,
+ Dali::Accessibility::TextBoundary boundary ) override;
+ Dali::Accessibility::Range GetSelection( size_t selectionNum ) override;
+ bool RemoveSelection( size_t selectionNum ) override;
+ bool SetSelection( size_t selectionNum, size_t startOffset,
+ size_t endOffset ) override;
+ bool CopyText( size_t startPosition, size_t endPosition ) override;
+ bool CutText( size_t startPosition, size_t endPosition ) override;
+ Dali::Accessibility::States CalculateStates() override;
+ };
};
} // namespace Internal
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 ) );
+ } );
}
void TextField::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
}
}
+Text::ControllerPtr TextField::getController() { return mController; }
+
void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
{
Actor renderableActor;
EmitKeyInputFocusSignal( false ); // Calls back into the Control hence done last.
}
+bool TextField::OnAccessibilityActivated()
+{
+ SetKeyInputFocus();
+ return true;
+}
+
void TextField::OnTap( const TapGesture& gesture )
{
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnTap %p\n", mController.Get() );
}
}
+void TextField::TextInserted( unsigned int position, unsigned int length, const std::string &content )
+{
+ if( Accessibility::IsUp() )
+ {
+ Control::Impl::GetAccessibilityObject( Self() )->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 );
+ }
+}
+
+void TextField::CaretMoved( unsigned int position )
+{
+ if( Accessibility::IsUp() )
+ {
+ Control::Impl::GetAccessibilityObject( Self() )->EmitTextCaretMoved( position );
+ }
+}
+
void TextField::TextChanged()
{
Dali::Toolkit::TextField handle( GetOwner() );
}
}
+std::string TextField::AccessibleImpl::GetName()
+{
+ auto slf = Toolkit::TextField::DownCast( self );
+ return slf.GetProperty( Toolkit::TextField::Property::TEXT ).Get< std::string >();
+}
+
+std::string TextField::AccessibleImpl::GetText( size_t startOffset,
+ size_t endOffset )
+{
+ if( endOffset <= startOffset )
+ return {};
+
+ auto slf = Toolkit::TextField::DownCast( self );
+ auto txt =
+ slf.GetProperty( Toolkit::TextField::Property::TEXT ).Get< std::string >();
+
+ if( startOffset > txt.size() || endOffset > txt.size() )
+ return {};
+
+ return txt.substr( startOffset, endOffset - startOffset );
+}
+
+size_t TextField::AccessibleImpl::GetCharacterCount()
+{
+ auto slf = Toolkit::TextField::DownCast( self );
+ auto txt =
+ slf.GetProperty( Toolkit::TextField::Property::TEXT ).Get< std::string >();
+
+ return txt.size();
+}
+
+size_t TextField::AccessibleImpl::GetCaretOffset()
+{
+ auto slf = Toolkit::TextField::DownCast( self );
+ return Dali::Toolkit::GetImpl( slf ).getController()->GetCursorPosition();
+}
+
+bool TextField::AccessibleImpl::SetCaretOffset(size_t offset)
+{
+ auto slf = Toolkit::TextField::DownCast( self );
+ auto txt = slf.GetProperty( Toolkit::TextField::Property::TEXT ).Get< std::string >();
+ if (offset > txt.size())
+ return false;
+
+ auto& slfImpl = Dali::Toolkit::GetImpl( slf );
+ slfImpl.getController()->ResetCursorPosition( offset );
+ slfImpl.RequestTextRelayout();
+ return true;
+}
+
+Dali::Accessibility::Range TextField::AccessibleImpl::GetTextAtOffset(
+ size_t offset, Dali::Accessibility::TextBoundary boundary )
+{
+ auto slf = Toolkit::TextField::DownCast( self );
+ auto txt = slf.GetProperty( Toolkit::TextField::Property::TEXT ).Get< std::string >();
+ auto txt_size = txt.size();
+
+ auto range = Dali::Accessibility::Range{};
+
+ switch(boundary)
+ {
+ case Dali::Accessibility::TextBoundary::CHARACTER:
+ {
+ if (offset < txt_size)
+ {
+ range.content = txt[offset];
+ range.startOffset = offset;
+ range.endOffset = offset + 1;
+ }
+ }
+ break;
+ case Dali::Accessibility::TextBoundary::WORD:
+ case Dali::Accessibility::TextBoundary::LINE:
+ {
+ auto txt_c_string = txt.c_str();
+ auto breaks = std::vector< char >( txt_size, 0 );
+ if(boundary == Dali::Accessibility::TextBoundary::WORD)
+ Accessibility::Accessible::FindWordSeparationsUtf8((const utf8_t *) txt_c_string, txt_size, "", breaks.data());
+ else
+ Accessibility::Accessible::FindLineSeparationsUtf8((const utf8_t *) txt_c_string, txt_size, "", breaks.data());
+ auto index = 0u;
+ auto counter = 0u;
+ while( index < txt_size && 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 = txt.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 efl */
+ }
+ break;
+ case Dali::Accessibility::TextBoundary::PARAGRAPH:
+ {
+ /* Paragraph is not supported by libunibreak library */
+ }
+ break;
+ default:
+ break;
+ }
+
+ return range;
+}
+
+Dali::Accessibility::Range
+TextField::AccessibleImpl::GetSelection( size_t selectionNum )
+{
+ // Since DALi supports only one selection indexes higher than 0 are ignored
+ if( selectionNum > 0 )
+ return {};
+
+ auto slf = Toolkit::TextField::DownCast( self );
+ auto ctrl = Dali::Toolkit::GetImpl( slf ).getController();
+ std::string ret;
+ ctrl->RetrieveSelection( ret );
+ auto r = ctrl->GetSelectionIndexes();
+
+ return { static_cast<size_t>(r.first), static_cast<size_t>(r.second), ret };
+}
+
+bool TextField::AccessibleImpl::RemoveSelection( size_t selectionNum )
+{
+ // Since DALi supports only one selection indexes higher than 0 are ignored
+ if( selectionNum > 0 )
+ return false;
+
+ auto slf = Toolkit::TextField::DownCast( self );
+ Dali::Toolkit::GetImpl( slf ).getController()->SetSelection( 0, 0 );
+ return true;
+}
+
+bool TextField::AccessibleImpl::SetSelection( size_t selectionNum,
+ size_t startOffset,
+ size_t endOffset )
+{
+ // Since DALi supports only one selection indexes higher than 0 are ignored
+ if( selectionNum > 0 )
+ return false;
+
+ auto slf = Toolkit::TextField::DownCast( self );
+ Dali::Toolkit::GetImpl( slf ).getController()->SetSelection( startOffset,
+ endOffset );
+ return true;
+}
+
+bool TextField::AccessibleImpl::CopyText( size_t startPosition,
+ size_t endPosition )
+{
+ if( endPosition <= startPosition )
+ return false;
+
+ auto slf = Toolkit::TextField::DownCast( self );
+ auto txt = slf.GetProperty( Toolkit::TextField::Property::TEXT ).Get<std::string>();
+ Dali::Toolkit::GetImpl( slf ).getController()->CopyStringToClipboard( txt.substr(startPosition, endPosition - startPosition) );
+
+ return true;
+}
+
+bool TextField::AccessibleImpl::CutText( size_t startPosition,
+ size_t endPosition )
+{
+ if( endPosition <= startPosition )
+ return false;
+
+ auto slf = Toolkit::TextField::DownCast( self );
+ auto txt = slf.GetProperty( Toolkit::TextField::Property::TEXT ).Get<std::string>();
+ Dali::Toolkit::GetImpl( slf ).getController()->CopyStringToClipboard( txt.substr(startPosition, endPosition - startPosition) );
+
+ slf.SetProperty( Toolkit::TextField::Property::TEXT,
+ txt.substr( 0, startPosition ) + txt.substr( endPosition - startPosition, txt.size()));
+
+ return true;
+}
+
+Dali::Accessibility::States TextField::AccessibleImpl::CalculateStates()
+{
+ using namespace Dali::Accessibility;
+
+ auto states = Control::Impl::AccessibleImpl::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;
+}
+
} // namespace Internal
} // namespace Toolkit
#include <dali-toolkit/internal/text/text-selectable-control-interface.h>
#include <dali-toolkit/internal/text/text-controller.h>
#include <dali-toolkit/internal/text/rendering/text-renderer.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
*/
Toolkit::TextField::InputStyleChangedSignalType& InputStyleChangedSignal();
+ Text::ControllerPtr getController();
+
private: // From Control
/**
void OnKeyInputFocusLost() override;
/**
+ * @copydoc Control::OnAccessibilityActivated()
+ */
+ bool OnAccessibilityActivated() override;
+
+ /**
* @copydoc Control::OnTap()
*/
void OnTap( const TapGesture& tap ) override;
/**
* @copydoc Text::EditableControlInterface::TextChanged()
*/
+ void TextInserted( unsigned int position, unsigned int length, const std::string &content ) override;
+
+ /**
+ * @copydoc Text::EditableControlInterface::TextDeleted()
+ */
+ void TextDeleted( unsigned int position, unsigned int length, const std::string &content ) override;
+
+ /**
+ * @copydoc Text::EditableControlInterface::CaretMoved()
+ */
+ void CaretMoved( unsigned int position ) override;
+
+ /**
+ * @copydoc Text::EditableControlInterface::TextChanged()
+ */
void TextChanged() override;
/**
int mRenderingBackend;
int mExceedPolicy;
bool mHasBeenStaged:1;
+
+protected:
+ struct AccessibleImpl : public Control::Impl::AccessibleImpl,
+ public virtual Dali::Accessibility::Text,
+ public virtual Dali::Accessibility::EditableText
+ {
+ using Control::Impl::AccessibleImpl::AccessibleImpl;
+
+ std::string GetName() override;
+ std::string GetText( size_t startOffset, size_t endOffset ) override;
+ size_t GetCharacterCount() override;
+ size_t GetCaretOffset() override;
+ bool SetCaretOffset(size_t offset) override;
+ Dali::Accessibility::Range
+ GetTextAtOffset( size_t offset,
+ Dali::Accessibility::TextBoundary boundary ) override;
+ Dali::Accessibility::Range GetSelection( size_t selectionNum ) override;
+ bool RemoveSelection( size_t selectionNum ) override;
+ bool SetSelection( size_t selectionNum, size_t startOffset,
+ size_t endOffset ) override;
+ bool CopyText( size_t startPosition, size_t endPosition ) override;
+ bool CutText( size_t startPosition, size_t endPosition ) override;
+ Dali::Accessibility::States CalculateStates() override;
+ };
};
} // namespace Internal
}
}
+Text::ControllerPtr TextLabel::getController() { return mController; }
+
Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index index )
{
Property::Value value;
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 ) );
+ } );
}
void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
{
}
+std::string TextLabel::AccessibleImpl::GetNameRaw()
+{
+ auto slf = Toolkit::TextLabel::DownCast( self );
+ return slf.GetProperty( Toolkit::TextLabel::Property::TEXT ).Get< std::string >();
+}
+
+Property::Index TextLabel::AccessibleImpl::GetNamePropertyIndex()
+{
+ return Toolkit::TextLabel::Property::TEXT;
+}
+
+std::string TextLabel::AccessibleImpl::GetText( size_t startOffset,
+ size_t endOffset )
+{
+ if( endOffset <= startOffset )
+ return {};
+
+ auto slf = Toolkit::TextLabel::DownCast( self );
+ auto txt =
+ slf.GetProperty( Toolkit::TextLabel::Property::TEXT ).Get< std::string >();
+
+ if( startOffset > txt.size() || endOffset > txt.size() )
+ return {};
+
+ return txt.substr( startOffset, endOffset - startOffset );
+}
+
+size_t TextLabel::AccessibleImpl::GetCharacterCount()
+{
+ auto slf = Toolkit::TextLabel::DownCast( self );
+ auto txt =
+ slf.GetProperty( Toolkit::TextLabel::Property::TEXT ).Get< std::string >();
+
+ return txt.size();
+}
+
+size_t TextLabel::AccessibleImpl::GetCaretOffset()
+{
+ return {};
+}
+
+bool TextLabel::AccessibleImpl::SetCaretOffset(size_t offset)
+{
+ return {};
+}
+
+Dali::Accessibility::Range TextLabel::AccessibleImpl::GetTextAtOffset(
+ size_t offset, Dali::Accessibility::TextBoundary boundary )
+{
+ auto slf = Toolkit::TextLabel::DownCast( self );
+ auto txt = slf.GetProperty( Toolkit::TextLabel::Property::TEXT ).Get< std::string >();
+ auto txt_size = txt.size();
+
+ auto range = Dali::Accessibility::Range{};
+
+ switch(boundary)
+ {
+ case Dali::Accessibility::TextBoundary::CHARACTER:
+ {
+ if (offset < txt_size)
+ {
+ range.content = txt[offset];
+ range.startOffset = offset;
+ range.endOffset = offset + 1;
+ }
+ }
+ break;
+ case Dali::Accessibility::TextBoundary::WORD:
+ case Dali::Accessibility::TextBoundary::LINE:
+ {
+ auto txt_c_string = txt.c_str();
+ auto breaks = std::vector< char >( txt_size, 0 );
+ if(boundary == Dali::Accessibility::TextBoundary::WORD)
+ Accessibility::Accessible::FindWordSeparationsUtf8((const utf8_t *) txt_c_string, txt_size, "", breaks.data());
+ else
+ Accessibility::Accessible::FindLineSeparationsUtf8((const utf8_t *) txt_c_string, txt_size, "", breaks.data());
+ auto index = 0u;
+ auto counter = 0u;
+ while( index < txt_size && 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 = txt.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 efl */
+ }
+ break;
+ case Dali::Accessibility::TextBoundary::PARAGRAPH:
+ {
+ /* Paragraph is not supported by libunibreak library */
+ }
+ break;
+ default:
+ break;
+ }
+
+ return range;
+}
+
+Dali::Accessibility::Range
+TextLabel::AccessibleImpl::GetSelection( size_t selectionNum )
+{
+ // Since DALi supports only one selection indexes higher than 0 are ignored
+ if( selectionNum > 0 )
+ return {};
+
+ auto slf = Toolkit::TextLabel::DownCast( self );
+ auto ctrl = Dali::Toolkit::GetImpl( slf ).getController();
+ std::string ret;
+ ctrl->RetrieveSelection( ret );
+ auto r = ctrl->GetSelectionIndexes();
+
+ return { static_cast<size_t>(r.first), static_cast<size_t>(r.second), ret };
+}
+
+bool TextLabel::AccessibleImpl::RemoveSelection( size_t selectionNum )
+{
+ // Since DALi supports only one selection indexes higher than 0 are ignored
+ if( selectionNum > 0 )
+ return false;
+
+ auto slf = Toolkit::TextLabel::DownCast( self );
+ Dali::Toolkit::GetImpl( slf ).getController()->SetSelection( 0, 0 );
+ return true;
+}
+
+bool TextLabel::AccessibleImpl::SetSelection( size_t selectionNum,
+ size_t startOffset,
+ size_t endOffset )
+{
+ // Since DALi supports only one selection indexes higher than 0 are ignored
+ if( selectionNum > 0 )
+ return false;
+
+ auto slf = Toolkit::TextLabel::DownCast( self );
+ Dali::Toolkit::GetImpl( slf ).getController()->SetSelection( startOffset,
+ endOffset );
+ return true;
+}
+
} // namespace Internal
} // namespace Toolkit
#include <dali-toolkit/internal/text/rendering/text-renderer.h>
#include <dali-toolkit/internal/text/text-scroller.h>
#include <dali-toolkit/internal/visuals/text/text-visual.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
*/
static Property::Value GetProperty( BaseObject* object, Property::Index index );
+ Text::ControllerPtr getController();
+
private: // From Control
/**
int mRenderingBackend;
bool mTextUpdateNeeded:1;
+
+protected:
+ struct AccessibleImpl : public Control::Impl::AccessibleImpl,
+ public virtual Dali::Accessibility::Text
+ {
+ using Control::Impl::AccessibleImpl::AccessibleImpl;
+
+ std::string GetText( size_t startOffset, size_t endOffset ) override;
+ size_t GetCharacterCount() override;
+ size_t GetCaretOffset() override;
+ bool SetCaretOffset(size_t offset) override;
+ Dali::Accessibility::Range
+ GetTextAtOffset( size_t offset,
+ Dali::Accessibility::TextBoundary boundary ) override;
+ Dali::Accessibility::Range GetSelection( size_t selectionNum ) override;
+ bool RemoveSelection( size_t selectionNum ) override;
+ bool SetSelection( size_t selectionNum, size_t startOffset,
+ size_t endOffset ) override;
+ std::string GetNameRaw() override;
+ Property::Index GetNamePropertyIndex() override;
+ };
};
} // namespace Internal
#include <dali-toolkit/public-api/visuals/visual-properties.h>
#include <dali-toolkit/internal/helpers/color-conversion.h>
#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
Actor self = Self();
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 Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::DIALOG, true ) );
+ } );
+
+ //Enable highightability
+ self.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true );
}
void TextSelectionPopup::HideAnimationFinished( Animation& animation )
#include <dali-toolkit/public-api/controls/image-view/image-view.h>
#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/internal/helpers/color-conversion.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
void TextSelectionToolbar::OnInitialize()
{
SetUp();
+
+ DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::TOOL_BAR ));
+ } );
}
void TextSelectionToolbar::OnRelayout( const Vector2& size, RelayoutContainer& container )
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/controls/alignment/alignment.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
mLayout.AddChild( rightSpace, Toolkit::TableView::CellPosition( 0, 1 ) );
mLayout.SetRelativeWidth( 0, mLeftRelativeSpace );
mLayout.SetRelativeWidth( 1, mRightRelativeSpace );
+
+ DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::TOOL_BAR ));
+ } );
}
void ToolBar::OnChildAdd(Actor& child)
if( value.Get( text ) )
{
mContentTextVisual[ Toolkit::TextVisual::Property::TEXT ] = text;
- mContentTextVisual[ Toolkit::Visual::Property::TYPE ] = Visual::TEXT;
+ mContentTextVisual[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::TEXT;
mContentArray.Clear();
connectSignals = true;
}
#include <dali-toolkit/public-api/controls/video-view/video-view.h>
#include <dali-toolkit/internal/visuals/visual-factory-cache.h>
#include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
void VideoView::OnInitialize()
{
mVideoPlayer.FinishedSignal().Connect( this, &VideoView::EmitSignalFinish );
+
+ DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::VIDEO ));
+ } );
}
void VideoView::SetUrl( const std::string& url )
// EXTERNAL INCLUDES
#include <cstring> // for strcmp
#include <dali/public-api/actors/layer.h>
-#include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
#include <dali/devel-api/common/singleton-service.h>
#include <dali/devel-api/adaptor-framework/lifecycle-controller.h>
#include <dali/public-api/animation/constraints.h>
#include <dali-toolkit/public-api/controls/control.h>
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/public-api/controls/image-view/image-view.h>
-#include <dali-toolkit/devel-api/accessibility-manager/accessibility-manager.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/public-api/styling/style-manager.h>
#include <dali-toolkit/devel-api/styling/style-manager-devel.h>
+#include <dali/devel-api/adaptor-framework/accessibility.h>
namespace Dali
{
void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
{
- AccessibilityAdaptor accessibilityAdaptor = AccessibilityAdaptor::Get();
- bool isAccessibilityEnabled = accessibilityAdaptor.IsEnabled();
-
- Toolkit::AccessibilityManager accessibilityManager = Toolkit::AccessibilityManager::Get();
-
std::string keyName = event.GetKeyName();
if( mIsFocusIndicatorShown == UNKNOWN )
{
if (keyName == "Left")
{
- if(!isAccessibilityEnabled)
+ if(!mIsFocusIndicatorShown)
{
if(mIsFocusIndicatorShown == HIDE)
{
}
else
{
- // Move the accessibility focus backward
- accessibilityManager.MoveFocusBackward();
+ // Move the focus towards left
+ MoveFocus(Toolkit::Control::KeyboardFocus::LEFT);
}
+
+ isFocusStartableKey = true;
}
else if (keyName == "Right")
{
- if(!isAccessibilityEnabled)
+ if(!mIsFocusIndicatorShown)
{
if( mIsFocusIndicatorShown == HIDE )
{
}
else
{
- // Move the accessibility focus forward
- accessibilityManager.MoveFocusForward();
+ // Move the focus towards right
+ MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT);
}
isFocusStartableKey = true;
}
- else if (keyName == "Up" && !isAccessibilityEnabled)
+ else if (keyName == "Up")
{
if( mIsFocusIndicatorShown == HIDE )
{
isFocusStartableKey = true;
}
- else if (keyName == "Down" && !isAccessibilityEnabled)
+ else if (keyName == "Down")
{
if( mIsFocusIndicatorShown == HIDE )
{
isFocusStartableKey = true;
}
- else if (keyName == "Prior" && !isAccessibilityEnabled)
+ else if (keyName == "Prior")
{
if( mIsFocusIndicatorShown == HIDE )
{
isFocusStartableKey = true;
}
- else if (keyName == "Next" && !isAccessibilityEnabled)
+ else if (keyName == "Next")
{
if( mIsFocusIndicatorShown == HIDE )
{
isFocusStartableKey = true;
}
- else if (keyName == "Tab" && !isAccessibilityEnabled)
+ else if (keyName == "Tab")
{
if( mIsFocusIndicatorShown == HIDE )
{
isFocusStartableKey = true;
}
- else if (keyName == "space" && !isAccessibilityEnabled)
+ else if (keyName == "space")
{
if( mIsFocusIndicatorShown == HIDE )
{
isFocusStartableKey = true;
}
- else if (keyName == "" && !isAccessibilityEnabled)
+ else if (keyName == "")
{
// Check the fake key event for evas-plugin case
if( mIsFocusIndicatorShown == HIDE )
isFocusStartableKey = true;
}
- else if (keyName == "Backspace" && !isAccessibilityEnabled)
+ else if (keyName == "Backspace")
{
// Emit signal to go back to the previous view???
}
- else if (keyName == "Escape" && !isAccessibilityEnabled)
+ else if (keyName == "Escape")
{
}
}
{
if (keyName == "Return")
{
- if((mIsFocusIndicatorShown == HIDE) && !isAccessibilityEnabled)
+ if( mIsFocusIndicatorShown == HIDE )
{
// Show focus indicator
mIsFocusIndicatorShown = SHOW;
else
{
// The focused actor has enter pressed on it
- Actor actor;
- if( !isAccessibilityEnabled )
- {
- actor = GetCurrentFocusActor();
- }
- else
- {
- actor = accessibilityManager.GetCurrentFocusActor();
- }
-
+ Actor actor = GetCurrentFocusActor();
if( actor )
{
DoKeyboardEnter( actor );
}
}
- if(isFocusStartableKey && ( mIsFocusIndicatorShown == SHOW ) && !isAccessibilityEnabled)
+ if( isFocusStartableKey && mIsFocusIndicatorShown == SHOW )
{
Actor actor = GetCurrentFocusActor();
if( actor )
// Let's try to move the initial focus
MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT);
}
+
}
}
int keyCode = keyEvent.GetKeyCode();
const std::string& keyString = keyEvent.GetKeyString();
const std::string keyName = keyEvent.GetKeyName();
+ // Key will produce same logical-key value when ctrl
+ // is down, regardless of language layout
+ const std::string logicalKey = keyEvent.GetLogicalKey();
const bool isNullKey = ( 0 == keyCode ) && ( keyString.empty() );
else if ( keyEvent.IsCtrlModifier() && !keyEvent.IsShiftModifier())
{
bool consumed = false;
- if (keyName == KEY_C_NAME || keyName == KEY_INSERT_NAME)
+ if (keyName == KEY_C_NAME || keyName == KEY_INSERT_NAME || logicalKey == KEY_C_NAME || logicalKey == KEY_INSERT_NAME)
{
// Ctrl-C or Ctrl+Insert to copy the selected text
controller.TextPopupButtonTouched( Toolkit::TextSelectionPopup::COPY );
consumed = true;
}
- else if (keyName == KEY_V_NAME)
+ else if (keyName == KEY_V_NAME || logicalKey == KEY_V_NAME)
{
// Ctrl-V to paste the copied text
controller.TextPopupButtonTouched( Toolkit::TextSelectionPopup::PASTE );
consumed = true;
}
- else if (keyName == KEY_X_NAME)
+ else if (keyName == KEY_X_NAME || logicalKey == KEY_X_NAME)
{
// Ctrl-X to cut the selected text
controller.TextPopupButtonTouched( Toolkit::TextSelectionPopup::CUT );
consumed = true;
}
- else if (keyName == KEY_A_NAME)
+ else if (keyName == KEY_A_NAME || logicalKey == KEY_A_NAME)
{
// Ctrl-A to select All the text
controller.TextPopupButtonTouched( Toolkit::TextSelectionPopup::SELECT_ALL );
#include <dali-toolkit/internal/text/text-control-interface.h>
#include <dali-toolkit/internal/text/text-controller-impl-event-handler.h>
#include <dali-toolkit/internal/text/text-run-container.h>
+#include <dali-toolkit/internal/text/text-editable-control-interface.h>
using namespace Dali;
GetCursorPosition( mEventData->mPrimaryCursorPosition,
cursorInfo );
+ if( NULL != mEditableControlInterface )
+ {
+ mEditableControlInterface->CaretMoved( mEventData->mPrimaryCursorPosition );
+ }
+
if( mEventData->mUpdateCursorHookPosition )
{
// Update the cursor hook position. Used to move the cursor with the keys 'up' and 'down'.
}
}
+void Controller::Impl::SetSelection( int start, int end )
+{
+ mEventData->mLeftSelectionPosition = start;
+ mEventData->mRightSelectionPosition = end;
+ mEventData->mUpdateCursorPosition = true;
+}
+
+std::pair< int, int > Controller::Impl::GetSelectionIndexes() const
+{
+ return { mEventData->mLeftSelectionPosition, mEventData->mRightSelectionPosition };
+}
+
void Controller::Impl::ShowClipboard()
{
if( mClipboard )
mClipboardHideEnabled = enable;
}
-bool Controller::Impl::CopyStringToClipboard( std::string& source )
+bool Controller::Impl::CopyStringToClipboard( const std::string& source )
{
//Send string to clipboard
return ( mClipboard && mClipboard.SetItem( source ) );
*/
void RetrieveSelection( std::string& selectedText, bool deleteAfterRetrieval );
+ void SetSelection( int start, int end );
+
+ std::pair< int, int > GetSelectionIndexes() const;
+
void ShowClipboard();
void HideClipboard();
void SetClipboardHideEnable(bool enable);
- bool CopyStringToClipboard( std::string& source );
+ bool CopyStringToClipboard( const std::string& source );
void SendSelectionToClipboard( bool deleteAfterSending );
}
}
+void Controller::RetrieveSelection( std::string& selectedText ) const
+{
+ mImpl->RetrieveSelection( selectedText, false );
+}
+
+void Controller::SetSelection( int start, int end )
+{
+ mImpl->SetSelection( start, end );
+}
+
+std::pair< int, int > Controller::GetSelectionIndexes() const
+{
+ return mImpl->GetSelectionIndexes();
+}
+
+void Controller::CopyStringToClipboard( const std::string& source )
+{
+ mImpl->CopyStringToClipboard( source );
+}
+
+void Controller::SendSelectionToClipboard( bool deleteAfterSending )
+{
+ mImpl->SendSelectionToClipboard( deleteAfterSending );
+}
+
// public : Default style & Input style
void Controller::SetDefaultFontFamily( const std::string& defaultFontFamily )
}
}
+void Controller::ScrollBy( Vector2 scroll )
+{
+ if( mImpl->mEventData && (fabs(scroll.x) > Math::MACHINE_EPSILON_0 || fabs(scroll.y) > Math::MACHINE_EPSILON_0))
+ {
+ const Vector2& layoutSize = mImpl->mModel->mVisualModel->GetLayoutSize();
+ const Vector2 currentScroll = mImpl->mModel->mScrollPosition;
+
+ scroll.x = -scroll.x;
+ scroll.y = -scroll.y;
+
+ if( fabs(scroll.x) > Math::MACHINE_EPSILON_0 )
+ {
+ mImpl->mModel->mScrollPosition.x += scroll.x;
+ mImpl->ClampHorizontalScroll( layoutSize );
+ }
+
+ if( fabs(scroll.y) > Math::MACHINE_EPSILON_0 )
+ {
+ mImpl->mModel->mScrollPosition.y += scroll.y;
+ mImpl->ClampVerticalScroll( layoutSize );
+ }
+
+ if (mImpl->mModel->mScrollPosition != currentScroll)
+ {
+ mImpl->mEventData->mDecorator->UpdatePositions( mImpl->mModel->mScrollPosition - currentScroll );
+ mImpl->RequestRelayout();
+ }
+ }
+}
+
+float Controller::GetHorizontalScrollPosition()
+{
+ if( mImpl->mEventData )
+ {
+ //scroll values are negative internally so we convert them to positive numbers
+ return -mImpl->mModel->mScrollPosition.x;
+ }
+ return 0;
+}
+
+float Controller::GetVerticalScrollPosition()
+{
+ if( mImpl->mEventData )
+ {
+ //scroll values are negative internally so we convert them to positive numbers
+ return -mImpl->mModel->mScrollPosition.y;
+ }
+ return 0;
+}
+
void Controller::DecorationEvent( HandleType handleType, HandleState state, float x, float y )
{
EventHandler::DecorationEvent(*this, handleType, state, x, y);
// Insert at current cursor position.
Vector<Character>& modifyText = mImpl->mModel->mLogicalModel->mText;
+ auto pos = modifyText.End();
if( cursorIndex < numberOfCharactersInModel )
{
- modifyText.Insert( modifyText.Begin() + cursorIndex, utf32Characters.Begin(), utf32Characters.Begin() + maxSizeOfNewText );
+ pos = modifyText.Begin() + cursorIndex;
}
- else
+ unsigned int realPos = pos - modifyText.Begin();
+ modifyText.Insert( pos, utf32Characters.Begin(), utf32Characters.Begin() + maxSizeOfNewText );
+
+ if( NULL != mImpl->mEditableControlInterface )
{
- modifyText.Insert( modifyText.End(), utf32Characters.Begin(), utf32Characters.Begin() + maxSizeOfNewText );
+ mImpl->mEditableControlInterface->TextInserted( realPos, maxSizeOfNewText, text );
}
// Mark the first paragraph to be updated.
Vector<Character>::Iterator first = currentText.Begin() + cursorIndex;
Vector<Character>::Iterator last = first + numberOfCharacters;
+ if( NULL != mImpl->mEditableControlInterface )
+ {
+ std::string utf8;
+ Utf32ToUtf8( first, numberOfCharacters, utf8 );
+ mImpl->mEditableControlInterface->TextDeleted( cursorIndex, numberOfCharacters, utf8 );
+ }
+
currentText.Erase( first, last );
// Cursor position retreat
}
}
+CharacterIndex Controller::GetCursorPosition()
+{
+ if( !mImpl->mEventData )
+ return 0;
+
+ return mImpl->mEventData->mPrimaryCursorPosition;
+}
+
void Controller::ResetScrollPosition()
{
if( NULL != mImpl->mEventData )
*/
void UpdateAfterFontChange( const std::string& newDefaultFont );
+ /**
+ * @brief The method acquires currently selected text
+ * @param selectedText variable to place selected text in
+ */
+ void RetrieveSelection( std::string& selectedText ) const;
+
+ /**
+ * @brief The method sets selection in given range
+ * @param start index of first character
+ * @param end index of first character after selection
+ */
+ void SetSelection( int start, int end );
+
+ /**
+ * @brief This method retrieve indexes of current selection
+ *
+ * @return a pair, where first element is left index of selection and second is the right one
+ */
+ std::pair< int, int > GetSelectionIndexes() const;
+
+ /**
+ * Place string in system clipboard
+ * @param source std::string
+ */
+ void CopyStringToClipboard( const std::string& source );
+
+ /**
+ * Place currently selected text in system clipboard
+ * @param deleteAfterSending flag pointing if text should be deleted after sending to clipboard
+ */
+ void SendSelectionToClipboard( bool deleteAfterSending );
+
public: // Default style & Input style
/**
virtual void SetEditable( bool editable );
/**
+ * @copydoc Dali::Toolkit::Internal::TextEditor::ScrollBy()
+ */
+ virtual void ScrollBy( Vector2 scroll );
+
+ /**
+ * @copydoc Dali::Toolkit::Internal::TextEditor::GetHorizontalScrollPosition()
+ */
+ float GetHorizontalScrollPosition();
+
+ /**
+ * @copydoc Dali::Toolkit::Internal::TextEditor::GetVerticalScrollPosition()
+ */
+ float GetVerticalScrollPosition();
+
+ /**
* @brief Event received from input method context
*
* @param[in] inputMethodContext The input method context.
*/
Actor CreateBackgroundActor();
+ /**
+ * @brief Used to reset the cursor position after setting a new text.
+ *
+ * @param[in] cursorIndex Where to place the cursor.
+ */
+ void ResetCursorPosition( CharacterIndex cursorIndex );
+
+ /**
+ * @brief The method acquires current position of cursor
+ * @return unsigned value with cursor position
+ */
+ CharacterIndex GetCursorPosition();
+
protected: // Inherit from Text::Decorator::ControllerInterface.
/**
void ClearStyleData();
/**
- * @brief Used to reset the cursor position after setting a new text.
- *
- * @param[in] cursorIndex Where to place the cursor.
- */
- void ResetCursorPosition( CharacterIndex cursorIndex );
-
- /**
* @brief Used to reset the scroll position after setting a new text.
*/
void ResetScrollPosition();
{}
/**
+ * @brief Called to signal that text has been inserted.
+ */
+ virtual void TextInserted( unsigned int position, unsigned int length, const std::string &content ) = 0;
+
+ /**
+ * @brief Called to signal that text has been deleted.
+ */
+ virtual void TextDeleted( unsigned int position, unsigned int length, const std::string &content ) = 0;
+
+ /**
+ * @brief Called to signal that caret (cursor position) has been moved.
+ */
+ virtual void CaretMoved( unsigned int position ) = 0;
+
+ /**
* @brief Called to signal that text has been inserted or deleted.
*/
virtual void TextChanged() = 0;
mPlacementActor(),
mPlayState( DevelImageVisual::PlayState::STOPPED ),
mEventCallback( nullptr ),
- mRendererAdded( false )
+ mRendererAdded( false ),
+ mCoreShutdown(false)
{
// the rasterized image is with pre-multiplied alpha format
mImpl->mFlags |= Impl::IS_PREMULTIPLIED_ALPHA;
mVectorAnimationTask->UploadCompletedSignal().Connect( this, &AnimatedVectorImageVisual::OnUploadCompleted );
mVectorAnimationTask->SetAnimationFinishedCallback( new EventThreadCallback( MakeCallback( this, &AnimatedVectorImageVisual::OnAnimationFinished ) ) );
+
+ auto& vectorAnimationManager = mFactoryCache.GetVectorAnimationManager();
+ vectorAnimationManager.AddObserver(*this);
}
AnimatedVectorImageVisual::~AnimatedVectorImageVisual()
{
- if( mEventCallback )
+ if( ! mCoreShutdown )
{
- mFactoryCache.GetVectorAnimationManager().UnregisterEventCallback( mEventCallback );
+ auto& vectorAnimationManager = mFactoryCache.GetVectorAnimationManager();
+ vectorAnimationManager.RemoveObserver(*this);
+
+ if( mEventCallback )
+ {
+ mFactoryCache.GetVectorAnimationManager().UnregisterEventCallback( mEventCallback );
+ }
+
+ // Finalize animation task and disconnect the signal in the main thread
+ mVectorAnimationTask->UploadCompletedSignal().Disconnect( this, &AnimatedVectorImageVisual::OnUploadCompleted );
+ mVectorAnimationTask->Finalize();
}
+}
- // Finalize animation task and disconnect the signal in the main thread
- mVectorAnimationTask->UploadCompletedSignal().Disconnect( this, &AnimatedVectorImageVisual::OnUploadCompleted );
- mVectorAnimationTask->Finalize();
+void AnimatedVectorImageVisual::VectorAnimationManagerDestroyed()
+{
+ // Core is shutting down. Don't talk to the plugin any more.
+ mCoreShutdown = true;
}
void AnimatedVectorImageVisual::GetNaturalSize( Vector2& naturalSize )
void AnimatedVectorImageVisual::TriggerVectorRasterization()
{
- if( !mEventCallback )
+ if( !mEventCallback && !mCoreShutdown )
{
mEventCallback = MakeCallback( this, &AnimatedVectorImageVisual::OnProcessEvents );
- mFactoryCache.GetVectorAnimationManager().RegisterEventCallback( mEventCallback );
+ auto& vectorAnimationManager = mFactoryCache.GetVectorAnimationManager();
+ vectorAnimationManager.RegisterEventCallback( mEventCallback );
Stage::GetCurrent().KeepRendering( 0.0f ); // Trigger event processing
}
}
#include <dali-toolkit/internal/visuals/visual-url.h>
#include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h>
#include <dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h>
+#include <dali-toolkit/internal/visuals/animated-vector-image/vector-animation-manager.h>
namespace Dali
{
* | url | STRING |
*
*/
-class AnimatedVectorImageVisual: public Visual::Base, public ConnectionTracker
+class AnimatedVectorImageVisual: public Visual::Base, public ConnectionTracker, public VectorAnimationManager::LifecycleObserver
{
public:
*/
void DoCreateInstancePropertyMap( Property::Map& map ) const override;
+protected: // From VectorAnimationManager::LifecycleObserver:
+ /**
+ * @copydoc VectorAnimationManager::LifecycleObserver::VectorAnimationManagerDestroyed()
+ */
+ void VectorAnimationManagerDestroyed() override;
+
protected:
/**
DevelImageVisual::PlayState::Type mPlayState;
CallbackBase* mEventCallback; // Not owned
bool mRendererAdded;
+ bool mCoreShutdown;
};
} // namespace Internal
VectorAnimationManager::VectorAnimationManager()
: mEventCallbacks(),
+ mLifecycleObservers(),
mVectorAnimationThread( nullptr ),
mProcessorRegistered( false )
{
{
Adaptor::Get().UnregisterProcessor( *this );
}
+
+ for( auto observer : mLifecycleObservers )
+ {
+ observer->VectorAnimationManagerDestroyed();
+ }
+}
+
+void VectorAnimationManager::AddObserver( VectorAnimationManager::LifecycleObserver& observer )
+{
+ DALI_ASSERT_DEBUG( mLifecycleObservers.end() == std::find( mLifecycleObservers.begin(), mLifecycleObservers.end(), &observer));
+ mLifecycleObservers.push_back( &observer );
+}
+
+void VectorAnimationManager::RemoveObserver( VectorAnimationManager::LifecycleObserver& observer)
+{
+ auto iterator=std::find(mLifecycleObservers.begin(), mLifecycleObservers.end(), &observer);
+ if( iterator != mLifecycleObservers.end() )
+ {
+ mLifecycleObservers.erase(iterator);
+ }
}
VectorAnimationThread& VectorAnimationManager::GetVectorAnimationThread()
class VectorAnimationManager: public Integration::Processor
{
public:
+ struct LifecycleObserver
+ {
+ virtual void VectorAnimationManagerDestroyed() = 0;
+ };
/**
* @brief Constructor.
~VectorAnimationManager() override;
/**
+ * Add a lifecycle observer
+ * @param[in] observer The object watching this one
+ */
+ void AddObserver( LifecycleObserver& observer );
+
+ /**
+ * Remove a lifecycle observer
+ * @param[in] observer The object watching this one
+ */
+ void RemoveObserver( LifecycleObserver& observer );
+
+ /**
* Get the vector animation thread.
* @return A raw pointer pointing to the vector animation thread.
*/
private:
std::vector< CallbackBase* > mEventCallbacks;
+ std::vector<LifecycleObserver*> mLifecycleObservers;
std::unique_ptr< VectorAnimationThread > mVectorAnimationThread;
bool mProcessorRegistered;
};
#include <limits>
#include <stack>
#include <typeinfo>
+#include <dali/public-api/object/type-info.h>
+#include <dali/devel-api/common/stage.h>
+#include <dali/devel-api/actors/actor-devel.h>
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/public-api/styling/style-manager.h>
#include <dali-toolkit/public-api/visuals/color-visual-properties.h>
#include <dali-toolkit/public-api/visuals/visual-properties.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/public-api/controls/image-view/image-view.h>
+#include <dali-toolkit/dali-toolkit.h>
namespace Dali
{
if((type & GestureType::PAN) && !mImpl->mPanGestureDetector)
{
mImpl->mPanGestureDetector = PanGestureDetector::New();
+ mImpl->mPanGestureDetector.SetMaximumTouchesRequired(2);
mImpl->mPanGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PanDetected);
mImpl->mPanGestureDetector.Attach(Self());
}
bool Control::OnAccessibilityActivated()
{
- return false; // Accessibility activation is not handled by default
+ if( Toolkit::KeyboardFocusManager::Get().SetCurrentFocusActor( Self() ) )
+ {
+ return OnKeyboardEnter();
+ }
+ return false;
}
bool Control::OnKeyboardEnter()
{
SetKeyboardNavigationSupport(true);
}
+
+ Dali::TypeInfo type;
+ Self().GetTypeInfo( type );
+ if (type)
+ {
+ auto typeName = type.GetName();
+ DevelControl::AppendAccessibilityAttribute( Self(), "t", typeName );
+ }
+
+ if (Accessibility::IsUp())
+ mImpl->AccessibilityRegister();
}
void Control::OnInitialize()
{
Dali::Toolkit::Control handle(GetOwner());
+ if( Accessibility::IsUp() )
+ {
+ auto self = mImpl->GetAccessibilityObject( Self() );
+ self->EmitFocused( focusGained );
+ auto parent = self->GetParent();
+ if( parent && !self->GetStates()[Dali::Accessibility::State::MANAGES_DESCENDANTS] )
+ {
+ parent->EmitActiveDescendantChanged( parent, self );
+ }
+ }
+
if(focusGained)
{
// signals are allocated dynamically when someone connects
// Request to be laid out when the control is connected to the Scene.
// Signal that a Relayout may be needed
+ if( Accessibility::IsUp() )
+ {
+ mImpl->AccessibilityRegister();
+ }
}
void Control::OnSceneDisconnection()
{
+ if( Accessibility::IsUp() )
+ {
+ mImpl->AccessibilityDeregister();
+ }
mImpl->OnSceneDisconnection();
}
{
// If the clipping mode has been set, we may need to create a renderer.
// Only do this if we are already on-stage as the OnSceneConnection will handle the off-stage clipping controls.
- if((index == Actor::Property::CLIPPING_MODE) && Self().GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
+ switch( index )
{
- // Note: This method will handle whether creation of the renderer is required.
- CreateClippingRenderer(*this);
+ case Actor::Property::CLIPPING_MODE:
+ {
+ if( Self().GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ))
+ {
+ // Note: This method will handle whether creation of the renderer is required.
+ CreateClippingRenderer( *this );
+ }
+ break;
+ }
+ case Actor::Property::VISIBLE:
+ {
+ if( Dali::Accessibility::IsUp() )
+ {
+ Dali::Accessibility::Accessible::Get(Self())->EmitVisible( Self().GetProperty( Actor::Property::VISIBLE ).Get<bool>() );
+ }
+ break;
+ }
+ case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
+ {
+ if( Dali::Accessibility::IsUp() )
+ {
+ Dali::Accessibility::Accessible::Get(Self())->Emit( Dali::Accessibility::ObjectPropertyChangeEvent::ROLE );
+ }
+ break;
+ }
}
}
* @note A RelayoutRequest is queued by Control before this signal is emitted
*/
ResourceReadySignalType& ResourceReadySignal();
-
public: // Intended for control developers
/**
* @brief Creates an initialized Control.
{
const unsigned int TOOLKIT_MAJOR_VERSION = 1;
const unsigned int TOOLKIT_MINOR_VERSION = 9;
-const unsigned int TOOLKIT_MICRO_VERSION = 35;
+const unsigned int TOOLKIT_MICRO_VERSION = 36;
const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-toolkit
Summary: Dali 3D engine Toolkit
-Version: 1.9.35
+Version: 1.9.36
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT