#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;
-
- static bool MoveOutedCalled = false;
-
- 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);
- };
- wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "MoveOuted", MethodType::Method}] =
- [wr](const MessagePtr &m) -> MessagePtr {
- MoveOutedCalled = true;
- 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, Dali::Accessibility::CoordinateType coordinateType)
- {
- 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::make_tuple(static_cast<uint32_t>(coordinateType)));
- 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 TestResetMoveOutedCalled ()
- {
- MoveOutedCalled = false;
- }
-
- bool TestGetMoveOutedCalled ()
- {
- return MoveOutedCalled;
- }
-
- 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;
- }
+namespace Dali
+{
+namespace Accessibility
+{
+ using MethodType = TestDBusWrapper::MethodType;
+ using MessagePtr = DBusWrapper::MessagePtr;
+
+ static bool gMoveOutedCalled = false;
+
+ 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(), true );
+ bridge->AddTopLevelWindow( accessible );
+ 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);
+ };
+ wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "MoveOuted", MethodType::Method}] =
+ [wr](const MessagePtr &m) -> MessagePtr {
+ gMoveOutedCalled = true;
+ 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, Dali::Accessibility::CoordinateType coordinateType)
+ {
+ 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::make_tuple(static_cast<uint32_t>(coordinateType)));
+ 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 TestResetMoveOutedCalled ()
+ {
+ gMoveOutedCalled = false;
+ }
+
+ bool TestGetMoveOutedCalled ()
+ {
+ return gMoveOutedCalled;
+ }
+
+ 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;
+ }
+
+} // namespace Accessibility
+} // namespace Dali
#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, Dali::Accessibility::CoordinateType coordinateType );
- 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 );
- void TestResetMoveOutedCalled ();
- bool TestGetMoveOutedCalled ();
- }
-}
+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, Dali::Accessibility::CoordinateType coordinateType );
+ 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 );
+ void TestResetMoveOutedCalled ();
+ bool TestGetMoveOutedCalled ();
+} // namespace Accessibility
+} // namespace Dali
#endif //__DALI_TOOLKIT_ACCESSIBILITY_TEST_UTILS__
DALI_TEST_EQUALS(accessible->IsScrollable(), false, TEST_LOCATION);
DALI_TEST_EQUALS(accessible->ScrollToChild({}), false, TEST_LOCATION);
+ DALI_TEST_EQUALS(accessible->GetInternalActor(), Dali::Actor{}, TEST_LOCATION);
Dali::Accessibility::TestEnableSC( false );
END_TEST;
#include <dali-toolkit/public-api/transition/transition-set.h>
#include <dali-toolkit/public-api/transition/transition-base.h>
#include <dali-toolkit/public-api/transition/transition.h>
+#include <dali-toolkit/public-api/transition/fade-transition.h>
+#include <dali-toolkit/public-api/transition/slide-transition.h>
using namespace Dali;
using namespace Dali::Toolkit;
END_TEST;
}
+
+
+int UtcDaliMultipleTransitionAppearing(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliMultipleTransitionAppearing");
+
+ Control control = Control::New();
+ control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ control.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ control.SetProperty(Actor::Property::POSITION, Vector3(100, 200, 0));
+ control.SetProperty(Actor::Property::SIZE, Vector3(150, 150, 0));
+ Property::Map controlProperty;
+ controlProperty.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR);
+ controlProperty.Insert(Toolkit::ColorVisual::Property::MIX_COLOR, Vector4(1.0f, 0.0f, 0.0f, 1.0f));
+ control.SetProperty(Toolkit::Control::Property::BACKGROUND, controlProperty);
+
+ application.GetScene().Add(control);
+
+ application.SendNotification();
+ application.Render(20);
+
+ DALI_TEST_EQUALS(1.0f, control.GetCurrentProperty<float>(Actor::Property::OPACITY), TEST_LOCATION);
+
+ TransitionSet transitionSet = TransitionSet::New();
+ FadeTransition fade = FadeTransition::New(control, 0.5, TimePeriod(1.0f, 1.0f));
+ fade.SetAppearingTransition(true); // set fade in
+ transitionSet.AddTransition(fade);
+ SlideTransition slide = SlideTransition::New(control, Dali::Toolkit::SlideTransitionDirection::BOTTOM, TimePeriod(0.5f, 1.0f));
+ slide.SetAppearingTransition(true); // set slide
+ transitionSet.AddTransition(slide);
+ transitionSet.Play();
+
+ bool signalReceived(false);
+ TransitionFinishCheck finishCheck(signalReceived);
+ transitionSet.FinishedSignal().Connect(&application, finishCheck);
+
+ application.SendNotification();
+ application.Render(300);
+
+ float currentOpacity = control.GetCurrentProperty<float>(Actor::Property::OPACITY);
+ DALI_TEST_CHECK(currentOpacity == 0.0f);
+
+ application.SendNotification();
+ application.Render(400);
+
+ currentOpacity = control.GetCurrentProperty<float>(Actor::Property::OPACITY);
+ DALI_TEST_CHECK(currentOpacity == 0.5f);
+
+ application.SendNotification();
+ application.Render(500);
+
+ currentOpacity = control.GetCurrentProperty<float>(Actor::Property::OPACITY);
+ DALI_TEST_CHECK(currentOpacity > 0.5f && currentOpacity < 1.0f);
+
+ application.SendNotification();
+ application.Render(500);
+
+ currentOpacity = control.GetCurrentProperty<float>(Actor::Property::OPACITY);
+ DALI_TEST_CHECK(currentOpacity > 0.5f && currentOpacity < 1.0f);
+
+ // We didn't expect the animation to finish yet
+ application.SendNotification();
+ finishCheck.CheckSignalNotReceived();
+
+ application.SendNotification();
+ application.Render(500);
+
+ // We did expect the animation to finish
+ application.SendNotification();
+ finishCheck.CheckSignalReceived();
+
+ application.SendNotification();
+ application.Render(20);
+
+ DALI_TEST_EQUALS(1.0f, control.GetCurrentProperty<float>(Actor::Property::OPACITY), TEST_LOCATION);
+
+ END_TEST;
+}
return ret;
}
+Dali::Actor AccessibleImpl::GetInternalActor()
+{
+ return Dali::Actor{};
+}
+
bool AccessibleImpl::ScrollToChild(Actor child)
{
return false;
std::vector<Dali::Accessibility::Relation> GetRelationSet() override;
/**
+ * @copydoc Dali::Accessibility::Accessible::GetInternalActor()
+ */
+ Dali::Actor GetInternalActor() override;
+
+ /**
* @copydoc Dali::Accessibility::Accessible::GetStates()
*/
virtual Dali::Accessibility::States CalculateStates();
#include <dali/integration-api/adaptor-framework/adaptor.h>
#include <dali/public-api/object/type-registry-helper.h>
#include <dali/public-api/object/type-registry.h>
+#include <dali/devel-api/rendering/texture-devel.h>
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/controls/control-devel.h>
{
if(!mTextureSet)
{
+ std::string fragmentShader = SHADER_CANVAS_VIEW_FRAG.data();
+ DevelTexture::ApplyNativeFragmentShader(rasterizedTexture, fragmentShader);
+
mTextureSet = TextureSet::New();
Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
- Shader shader = Shader::New(SHADER_CANVAS_VIEW_VERT, SHADER_CANVAS_VIEW_FRAG);
+ Shader shader = Shader::New(SHADER_CANVAS_VIEW_VERT, fragmentShader);
Renderer renderer = Renderer::New(geometry, shader);
+
renderer.SetTextures(mTextureSet);
renderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true);
Self().AddRenderer(renderer);
mNeedToEmitResourceReady(false),
mDispatchKeyEvents(true)
{
- Dali::Accessibility::Accessible::RegisterControlAccessibilityGetter(
+ Dali::Accessibility::Accessible::RegisterExternalAccessibleGetter(
[](Dali::Actor actor) -> Dali::Accessibility::Accessible* {
return Control::Impl::GetAccessibilityObject(actor);
});
${toolkit_src_dir}/text/text-controller-event-handler.cpp
${toolkit_src_dir}/text/text-controller-impl.cpp
${toolkit_src_dir}/text/text-controller-impl-event-handler.cpp
+ ${toolkit_src_dir}/text/text-controller-impl-model-updater.cpp
${toolkit_src_dir}/text/text-controller-input-font-handler.cpp
${toolkit_src_dir}/text/text-controller-placeholder-handler.cpp
${toolkit_src_dir}/text/text-controller-relayouter.cpp
--- /dev/null
+/*
+ * Copyright (c) 2021 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 <dali-toolkit/internal/text/text-controller-impl-model-updater.h>
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/bidirectional-support.h>
+#include <dali-toolkit/internal/text/character-set-conversion.h>
+#include <dali-toolkit/internal/text/color-segmentation.h>
+#include <dali-toolkit/internal/text/hyphenator.h>
+#include <dali-toolkit/internal/text/multi-language-support.h>
+#include <dali-toolkit/internal/text/segmentation.h>
+#include <dali-toolkit/internal/text/shaper.h>
+#include <dali-toolkit/internal/text/text-editable-control-interface.h>
+
+namespace Dali::Toolkit::Text
+{
+
+namespace
+{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
+#endif
+
+// The relative luminance of a color is defined as (L = 0.2126 * R + 0.7152 * G + 0.0722 * B)
+// based on W3C Recommendations (https://www.w3.org/TR/WCAG20/)
+constexpr float BRIGHTNESS_THRESHOLD = 0.179f;
+constexpr float CONSTANT_R = 0.2126f;
+constexpr float CONSTANT_G = 0.7152f;
+constexpr float CONSTANT_B = 0.0722f;
+constexpr Dali::Vector4 BLACK(0.f, 0.f, 0.f, 1.f);
+constexpr Dali::Vector4 WHITE(1.f, 1.f, 1.f, 1.f);
+constexpr Dali::Vector4 LIGHT_BLUE(0.75f, 0.96f, 1.f, 1.f);
+constexpr Dali::Vector4 BACKGROUND_SUB4(0.58f, 0.87f, 0.96f, 1.f);
+constexpr Dali::Vector4 BACKGROUND_SUB5(0.83f, 0.94f, 0.98f, 1.f);
+constexpr Dali::Vector4 BACKGROUND_SUB6(1.f, 0.5f, 0.5f, 1.f);
+constexpr Dali::Vector4 BACKGROUND_SUB7(1.f, 0.8f, 0.8f, 1.f);
+} // namespace
+
+bool ControllerImplModelUpdater::Update(Controller::Impl& impl, OperationsMask operationsRequired)
+{
+ DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::UpdateModel\n");
+
+ // Calculate the operations to be done.
+ const OperationsMask operations = static_cast<OperationsMask>(impl.mOperationsPending & operationsRequired);
+
+ if(Controller::NO_OPERATION == operations)
+ {
+ // Nothing to do if no operations are pending and required.
+ return false;
+ }
+
+ Vector<Character>& srcCharacters = impl.mModel->mLogicalModel->mText;
+ Vector<Character> displayCharacters;
+ bool useHiddenText = false;
+ if(impl.mHiddenInput && impl.mEventData != nullptr && !impl.mEventData->mIsShowingPlaceholderText)
+ {
+ impl.mHiddenInput->Substitute(srcCharacters, displayCharacters);
+ useHiddenText = true;
+ }
+
+ Vector<Character>& utf32Characters = useHiddenText ? displayCharacters : srcCharacters;
+ const Length numberOfCharacters = utf32Characters.Count();
+
+ // Index to the first character of the first paragraph to be updated.
+ CharacterIndex startIndex = 0u;
+ // Number of characters of the paragraphs to be removed.
+ Length paragraphCharacters = 0u;
+
+ impl.CalculateTextUpdateIndices(paragraphCharacters);
+
+ // Check whether the indices for updating the text is valid
+ if(numberOfCharacters > 0u &&
+ (impl.mTextUpdateInfo.mParagraphCharacterIndex > numberOfCharacters ||
+ impl.mTextUpdateInfo.mRequestedNumberOfCharacters > numberOfCharacters))
+ {
+ std::string currentText;
+ Utf32ToUtf8(impl.mModel->mLogicalModel->mText.Begin(), numberOfCharacters, currentText);
+
+ DALI_LOG_ERROR("Controller::Impl::UpdateModel: mTextUpdateInfo has invalid indices\n");
+ DALI_LOG_ERROR("Number of characters: %d, current text is: %s\n", numberOfCharacters, currentText.c_str());
+
+ // Dump mTextUpdateInfo
+ DALI_LOG_ERROR("Dump mTextUpdateInfo:\n");
+ DALI_LOG_ERROR(" mTextUpdateInfo.mCharacterIndex = %u\n", impl.mTextUpdateInfo.mCharacterIndex);
+ DALI_LOG_ERROR(" mTextUpdateInfo.mNumberOfCharactersToRemove = %u\n", impl.mTextUpdateInfo.mNumberOfCharactersToRemove);
+ DALI_LOG_ERROR(" mTextUpdateInfo.mNumberOfCharactersToAdd = %u\n", impl.mTextUpdateInfo.mNumberOfCharactersToAdd);
+ DALI_LOG_ERROR(" mTextUpdateInfo.mPreviousNumberOfCharacters = %u\n", impl.mTextUpdateInfo.mPreviousNumberOfCharacters);
+ DALI_LOG_ERROR(" mTextUpdateInfo.mParagraphCharacterIndex = %u\n", impl.mTextUpdateInfo.mParagraphCharacterIndex);
+ DALI_LOG_ERROR(" mTextUpdateInfo.mRequestedNumberOfCharacters = %u\n", impl.mTextUpdateInfo.mRequestedNumberOfCharacters);
+ DALI_LOG_ERROR(" mTextUpdateInfo.mStartGlyphIndex = %u\n", impl.mTextUpdateInfo.mStartGlyphIndex);
+ DALI_LOG_ERROR(" mTextUpdateInfo.mStartLineIndex = %u\n", impl.mTextUpdateInfo.mStartLineIndex);
+ DALI_LOG_ERROR(" mTextUpdateInfo.mEstimatedNumberOfLines = %u\n", impl.mTextUpdateInfo.mEstimatedNumberOfLines);
+ DALI_LOG_ERROR(" mTextUpdateInfo.mClearAll = %d\n", impl.mTextUpdateInfo.mClearAll);
+ DALI_LOG_ERROR(" mTextUpdateInfo.mFullRelayoutNeeded = %d\n", impl.mTextUpdateInfo.mFullRelayoutNeeded);
+ DALI_LOG_ERROR(" mTextUpdateInfo.mIsLastCharacterNewParagraph = %d\n", impl.mTextUpdateInfo.mIsLastCharacterNewParagraph);
+
+ return false;
+ }
+
+ startIndex = impl.mTextUpdateInfo.mParagraphCharacterIndex;
+
+ if(impl.mTextUpdateInfo.mClearAll ||
+ (0u != paragraphCharacters))
+ {
+ impl.ClearModelData(startIndex, startIndex + ((paragraphCharacters > 0u) ? paragraphCharacters - 1u : 0u), operations);
+ }
+
+ impl.mTextUpdateInfo.mClearAll = false;
+
+ // Whether the model is updated.
+ bool updated = false;
+
+ Vector<LineBreakInfo>& lineBreakInfo = impl.mModel->mLogicalModel->mLineBreakInfo;
+ const Length requestedNumberOfCharacters = impl.mTextUpdateInfo.mRequestedNumberOfCharacters;
+
+ if(Controller::NO_OPERATION != (Controller::GET_LINE_BREAKS & operations))
+ {
+ // Retrieves the line break info. The line break info is used to split the text in 'paragraphs' to
+ // calculate the bidirectional info for each 'paragraph'.
+ // It's also used to layout the text (where it should be a new line) or to shape the text (text in different lines
+ // is not shaped together).
+ lineBreakInfo.Resize(numberOfCharacters, TextAbstraction::LINE_NO_BREAK);
+
+ SetLineBreakInfo(utf32Characters,
+ startIndex,
+ requestedNumberOfCharacters,
+ lineBreakInfo);
+
+ if(impl.mModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) ||
+ impl.mModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::MIXED))
+ {
+ CharacterIndex end = startIndex + requestedNumberOfCharacters;
+ LineBreakInfo* lineBreakInfoBuffer = lineBreakInfo.Begin();
+
+ for(CharacterIndex index = startIndex; index < end; index++)
+ {
+ CharacterIndex wordEnd = index;
+ while((*(lineBreakInfoBuffer + wordEnd) != TextAbstraction::LINE_ALLOW_BREAK) && (*(lineBreakInfoBuffer + wordEnd) != TextAbstraction::LINE_MUST_BREAK))
+ {
+ wordEnd++;
+ }
+
+ if((wordEnd + 1) == end) // add last char
+ {
+ wordEnd++;
+ }
+
+ Vector<bool> hyphens = GetWordHyphens(utf32Characters.Begin() + index, wordEnd - index, nullptr);
+
+ for(CharacterIndex i = 0; i < (wordEnd - index); i++)
+ {
+ if(hyphens[i])
+ {
+ *(lineBreakInfoBuffer + index + i) = TextAbstraction::LINE_HYPHENATION_BREAK;
+ }
+ }
+
+ index = wordEnd;
+ }
+ }
+
+ // Create the paragraph info.
+ impl.mModel->mLogicalModel->CreateParagraphInfo(startIndex,
+ requestedNumberOfCharacters);
+ updated = true;
+ }
+
+ const bool getScripts = Controller::NO_OPERATION != (Controller::GET_SCRIPTS & operations);
+ const bool validateFonts = Controller::NO_OPERATION != (Controller::VALIDATE_FONTS & operations);
+
+ Vector<ScriptRun>& scripts = impl.mModel->mLogicalModel->mScriptRuns;
+ Vector<FontRun>& validFonts = impl.mModel->mLogicalModel->mFontRuns;
+
+ if(getScripts || validateFonts)
+ {
+ // Validates the fonts assigned by the application or assigns default ones.
+ // It makes sure all the characters are going to be rendered by the correct font.
+ MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
+
+ if(getScripts)
+ {
+ // Retrieves the scripts used in the text.
+ multilanguageSupport.SetScripts(utf32Characters,
+ startIndex,
+ requestedNumberOfCharacters,
+ scripts);
+ }
+
+ if(validateFonts)
+ {
+ // Validate the fonts set through the mark-up string.
+ Vector<FontDescriptionRun>& fontDescriptionRuns = impl.mModel->mLogicalModel->mFontDescriptionRuns;
+
+ // Get the default font's description.
+ TextAbstraction::FontDescription defaultFontDescription;
+ TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE * impl.mFontSizeScale;
+
+ //Get the number of points per one unit of point-size
+ uint32_t numberOfPointsPerOneUnitOfPointSize = impl.mFontClient.GetNumberOfPointsPerOneUnitOfPointSize();
+
+ if(impl.IsShowingPlaceholderText() && impl.mEventData && (nullptr != impl.mEventData->mPlaceholderFont))
+ {
+ // If the placeholder font is set specifically, only placeholder font is changed.
+ defaultFontDescription = impl.mEventData->mPlaceholderFont->mFontDescription;
+ if(impl.mEventData->mPlaceholderFont->sizeDefined)
+ {
+ defaultPointSize = impl.mEventData->mPlaceholderFont->mDefaultPointSize * impl.mFontSizeScale * numberOfPointsPerOneUnitOfPointSize;
+ }
+ }
+ else if(nullptr != impl.mFontDefaults)
+ {
+ // Set the normal font and the placeholder font.
+ defaultFontDescription = impl.mFontDefaults->mFontDescription;
+
+ if(impl.mTextFitEnabled)
+ {
+ defaultPointSize = impl.mFontDefaults->mFitPointSize * numberOfPointsPerOneUnitOfPointSize;
+ }
+ else
+ {
+ defaultPointSize = impl.mFontDefaults->mDefaultPointSize * impl.mFontSizeScale * numberOfPointsPerOneUnitOfPointSize;
+ }
+ }
+
+ // Validates the fonts. If there is a character with no assigned font it sets a default one.
+ // After this call, fonts are validated.
+ multilanguageSupport.ValidateFonts(utf32Characters,
+ scripts,
+ fontDescriptionRuns,
+ defaultFontDescription,
+ defaultPointSize,
+ startIndex,
+ requestedNumberOfCharacters,
+ validFonts);
+ }
+ updated = true;
+ }
+
+ Vector<Character> mirroredUtf32Characters;
+ bool textMirrored = false;
+ const Length numberOfParagraphs = impl.mModel->mLogicalModel->mParagraphInfo.Count();
+ if(Controller::NO_OPERATION != (Controller::BIDI_INFO & operations))
+ {
+ Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = impl.mModel->mLogicalModel->mBidirectionalParagraphInfo;
+ bidirectionalInfo.Reserve(numberOfParagraphs);
+
+ // Calculates the bidirectional info for the whole paragraph if it contains right to left scripts.
+ SetBidirectionalInfo(utf32Characters,
+ scripts,
+ lineBreakInfo,
+ startIndex,
+ requestedNumberOfCharacters,
+ bidirectionalInfo,
+ (impl.mModel->mMatchLayoutDirection != DevelText::MatchLayoutDirection::CONTENTS),
+ impl.mLayoutDirection);
+
+ if(0u != bidirectionalInfo.Count())
+ {
+ // Only set the character directions if there is right to left characters.
+ Vector<CharacterDirection>& directions = impl.mModel->mLogicalModel->mCharacterDirections;
+ GetCharactersDirection(bidirectionalInfo,
+ numberOfCharacters,
+ startIndex,
+ requestedNumberOfCharacters,
+ directions);
+
+ // This paragraph has right to left text. Some characters may need to be mirrored.
+ // TODO: consider if the mirrored string can be stored as well.
+
+ textMirrored = GetMirroredText(utf32Characters,
+ directions,
+ bidirectionalInfo,
+ startIndex,
+ requestedNumberOfCharacters,
+ mirroredUtf32Characters);
+ }
+ else
+ {
+ // There is no right to left characters. Clear the directions vector.
+ impl.mModel->mLogicalModel->mCharacterDirections.Clear();
+ }
+ updated = true;
+ }
+
+ Vector<GlyphInfo>& glyphs = impl.mModel->mVisualModel->mGlyphs;
+ Vector<CharacterIndex>& glyphsToCharactersMap = impl.mModel->mVisualModel->mGlyphsToCharacters;
+ Vector<Length>& charactersPerGlyph = impl.mModel->mVisualModel->mCharactersPerGlyph;
+ Vector<GlyphIndex> newParagraphGlyphs;
+ newParagraphGlyphs.Reserve(numberOfParagraphs);
+
+ const Length currentNumberOfGlyphs = glyphs.Count();
+ if(Controller::NO_OPERATION != (Controller::SHAPE_TEXT & operations))
+ {
+ const Vector<Character>& textToShape = textMirrored ? mirroredUtf32Characters : utf32Characters;
+ // Shapes the text.
+ ShapeText(textToShape,
+ lineBreakInfo,
+ scripts,
+ validFonts,
+ startIndex,
+ impl.mTextUpdateInfo.mStartGlyphIndex,
+ requestedNumberOfCharacters,
+ glyphs,
+ glyphsToCharactersMap,
+ charactersPerGlyph,
+ newParagraphGlyphs);
+
+ // Create the 'number of glyphs' per character and the glyph to character conversion tables.
+ impl.mModel->mVisualModel->CreateGlyphsPerCharacterTable(startIndex, impl.mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
+ impl.mModel->mVisualModel->CreateCharacterToGlyphTable(startIndex, impl.mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
+
+ updated = true;
+ }
+
+ const Length numberOfGlyphs = glyphs.Count() - currentNumberOfGlyphs;
+
+ if(Controller::NO_OPERATION != (Controller::GET_GLYPH_METRICS & operations))
+ {
+ GlyphInfo* glyphsBuffer = glyphs.Begin();
+ impl.mMetrics->GetGlyphMetrics(glyphsBuffer + impl.mTextUpdateInfo.mStartGlyphIndex, numberOfGlyphs);
+
+ // Update the width and advance of all new paragraph characters.
+ for(Vector<GlyphIndex>::ConstIterator it = newParagraphGlyphs.Begin(), endIt = newParagraphGlyphs.End(); it != endIt; ++it)
+ {
+ const GlyphIndex index = *it;
+ GlyphInfo& glyph = *(glyphsBuffer + index);
+
+ glyph.xBearing = 0.f;
+ glyph.width = 0.f;
+ glyph.advance = 0.f;
+ }
+ updated = true;
+ }
+
+ if((nullptr != impl.mEventData) &&
+ impl.mEventData->mPreEditFlag &&
+ (0u != impl.mModel->mVisualModel->mCharactersToGlyph.Count()))
+ {
+ Dali::InputMethodContext::PreEditAttributeDataContainer attrs;
+ impl.mEventData->mInputMethodContext.GetPreeditStyle(attrs);
+ Dali::InputMethodContext::PreeditStyle type = Dali::InputMethodContext::PreeditStyle::NONE;
+
+ // Check the type of preedit and run it.
+ for(Dali::InputMethodContext::PreEditAttributeDataContainer::Iterator it = attrs.Begin(), endIt = attrs.End(); it != endIt; it++)
+ {
+ Dali::InputMethodContext::PreeditAttributeData attrData = *it;
+ DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::UpdateModel PreeditStyle type : %d start %d end %d \n", attrData.preeditType, attrData.startIndex, attrData.endIndex);
+ type = attrData.preeditType;
+
+ // Check the number of commit characters for the start position.
+ unsigned int numberOfCommit = impl.mEventData->mPrimaryCursorPosition - impl.mEventData->mPreEditLength;
+ Length numberOfIndices = attrData.endIndex - attrData.startIndex;
+
+ switch(type)
+ {
+ case Dali::InputMethodContext::PreeditStyle::UNDERLINE:
+ {
+ // Add the underline for the pre-edit text.
+ GlyphRun underlineRun;
+ underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
+ underlineRun.numberOfGlyphs = numberOfIndices;
+ impl.mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
+
+ //Mark-up processor case
+ if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
+ {
+ impl.CopyUnderlinedFromLogicalToVisualModels(false);
+ }
+ break;
+ }
+ case Dali::InputMethodContext::PreeditStyle::REVERSE:
+ {
+ Vector4 textColor = impl.mModel->mVisualModel->GetTextColor();
+ ColorRun backgroundColorRun;
+ backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
+ backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
+ backgroundColorRun.color = textColor;
+ impl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
+
+ Vector4 backgroundColor = impl.mModel->mVisualModel->GetBackgroundColor();
+ if(backgroundColor.a == 0) // There is no text background color.
+ {
+ // Try use the control's background color.
+ if(nullptr != impl.mEditableControlInterface)
+ {
+ impl.mEditableControlInterface->GetControlBackgroundColor(backgroundColor);
+ if(backgroundColor.a == 0) // There is no control background color.
+ {
+ // Determines black or white color according to text color.
+ // Based on W3C Recommendations (https://www.w3.org/TR/WCAG20/)
+ float L = CONSTANT_R * textColor.r + CONSTANT_G * textColor.g + CONSTANT_B * textColor.b;
+ backgroundColor = L > BRIGHTNESS_THRESHOLD ? BLACK : WHITE;
+ }
+ }
+ }
+
+ Vector<ColorRun> colorRuns;
+ colorRuns.Resize(1u);
+ ColorRun& colorRun = *(colorRuns.Begin());
+ colorRun.color = backgroundColor;
+ colorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
+ colorRun.characterRun.numberOfCharacters = numberOfIndices;
+ impl.mModel->mLogicalModel->mColorRuns.PushBack(colorRun);
+
+ //Mark-up processor case
+ if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
+ {
+ impl.CopyUnderlinedFromLogicalToVisualModels(false);
+ }
+ break;
+ }
+ case Dali::InputMethodContext::PreeditStyle::HIGHLIGHT:
+ {
+ ColorRun backgroundColorRun;
+ backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
+ backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
+ backgroundColorRun.color = LIGHT_BLUE;
+ impl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
+
+ //Mark-up processor case
+ if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
+ {
+ impl.CopyUnderlinedFromLogicalToVisualModels(false);
+ }
+ break;
+ }
+ case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_1:
+ {
+ // CUSTOM_PLATFORM_STYLE_1 should be drawn with background and underline together.
+ ColorRun backgroundColorRun;
+ backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
+ backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
+ backgroundColorRun.color = BACKGROUND_SUB4;
+ impl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
+
+ GlyphRun underlineRun;
+ underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
+ underlineRun.numberOfGlyphs = numberOfIndices;
+ impl.mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
+
+ //Mark-up processor case
+ if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
+ {
+ impl.CopyUnderlinedFromLogicalToVisualModels(false);
+ }
+ break;
+ }
+ case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_2:
+ {
+ // CUSTOM_PLATFORM_STYLE_2 should be drawn with background and underline together.
+ ColorRun backgroundColorRun;
+ backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
+ backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
+ backgroundColorRun.color = BACKGROUND_SUB5;
+ impl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
+
+ GlyphRun underlineRun;
+ underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
+ underlineRun.numberOfGlyphs = numberOfIndices;
+ impl.mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
+
+ //Mark-up processor case
+ if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
+ {
+ impl.CopyUnderlinedFromLogicalToVisualModels(false);
+ }
+ break;
+ }
+ case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_3:
+ {
+ // CUSTOM_PLATFORM_STYLE_3 should be drawn with background and underline together.
+ ColorRun backgroundColorRun;
+ backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
+ backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
+ backgroundColorRun.color = BACKGROUND_SUB6;
+ impl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
+
+ GlyphRun underlineRun;
+ underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
+ underlineRun.numberOfGlyphs = numberOfIndices;
+ impl.mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
+
+ //Mark-up processor case
+ if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
+ {
+ impl.CopyUnderlinedFromLogicalToVisualModels(false);
+ }
+ break;
+ }
+ case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_4:
+ {
+ // CUSTOM_PLATFORM_STYLE_4 should be drawn with background and underline together.
+ ColorRun backgroundColorRun;
+ backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
+ backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
+ backgroundColorRun.color = BACKGROUND_SUB7;
+ impl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
+
+ GlyphRun underlineRun;
+ underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
+ underlineRun.numberOfGlyphs = numberOfIndices;
+ impl.mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
+
+ //Mark-up processor case
+ if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
+ {
+ impl.CopyUnderlinedFromLogicalToVisualModels(false);
+ }
+ break;
+ }
+ case Dali::InputMethodContext::PreeditStyle::NONE:
+ default:
+ {
+ break;
+ }
+ }
+ }
+ attrs.Clear();
+ updated = true;
+ }
+
+ if(Controller::NO_OPERATION != (Controller::COLOR & operations))
+ {
+ // Set the color runs in glyphs.
+ SetColorSegmentationInfo(impl.mModel->mLogicalModel->mColorRuns,
+ impl.mModel->mVisualModel->mCharactersToGlyph,
+ impl.mModel->mVisualModel->mGlyphsPerCharacter,
+ startIndex,
+ impl.mTextUpdateInfo.mStartGlyphIndex,
+ requestedNumberOfCharacters,
+ impl.mModel->mVisualModel->mColors,
+ impl.mModel->mVisualModel->mColorIndices);
+
+ // Set the background color runs in glyphs.
+ SetColorSegmentationInfo(impl.mModel->mLogicalModel->mBackgroundColorRuns,
+ impl.mModel->mVisualModel->mCharactersToGlyph,
+ impl.mModel->mVisualModel->mGlyphsPerCharacter,
+ startIndex,
+ impl.mTextUpdateInfo.mStartGlyphIndex,
+ requestedNumberOfCharacters,
+ impl.mModel->mVisualModel->mBackgroundColors,
+ impl.mModel->mVisualModel->mBackgroundColorIndices);
+
+ updated = true;
+ }
+
+ if((Controller::NO_OPERATION != (Controller::SHAPE_TEXT & operations)) &&
+ !((nullptr != impl.mEventData) &&
+ impl.mEventData->mPreEditFlag &&
+ (0u != impl.mModel->mVisualModel->mCharactersToGlyph.Count())))
+ {
+ //Mark-up processor case
+ if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
+ {
+ impl.CopyUnderlinedFromLogicalToVisualModels(true);
+ }
+
+ updated = true;
+ }
+
+ // The estimated number of lines. Used to avoid reallocations when layouting.
+ impl.mTextUpdateInfo.mEstimatedNumberOfLines = std::max(impl.mModel->mVisualModel->mLines.Count(), impl.mModel->mLogicalModel->mParagraphInfo.Count());
+
+ // Set the previous number of characters for the next time the text is updated.
+ impl.mTextUpdateInfo.mPreviousNumberOfCharacters = numberOfCharacters;
+
+ return updated;
+}
+
+} // namespace Dali::Toolkit::Text
--- /dev/null
+#ifndef DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_MODEL_UPDATER_H
+#define DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_MODEL_UPDATER_H
+
+/*
+ * Copyright (c) 2021 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/text-controller-impl.h>
+
+namespace Dali::Toolkit::Text
+{
+
+/**
+ * Contains methods for updating the models in the TextController
+ */
+struct ControllerImplModelUpdater
+{
+ using OperationsMask = Controller::OperationsMask;
+
+ /**
+ * @brief Updates the logical and visual models. Updates the style runs in the visual model when the text's styles changes.
+ *
+ * @param[in] impl A reference to the Controller::Impl class
+ * @param[in] operationsRequired The operations required
+ * @return true if mode has been modified.
+ */
+ static bool Update(Controller::Impl& impl, OperationsMask operationsRequired);
+};
+
+} // namespace Dali::Toolkit::Text
+
+#endif // DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_MODEL_UPDATER_H
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
-#include <dali-toolkit/internal/text/bidirectional-support.h>
#include <dali-toolkit/internal/text/character-set-conversion.h>
-#include <dali-toolkit/internal/text/color-segmentation.h>
#include <dali-toolkit/internal/text/cursor-helper-functions.h>
-#include <dali-toolkit/internal/text/hyphenator.h>
-#include <dali-toolkit/internal/text/multi-language-support.h>
-#include <dali-toolkit/internal/text/segmentation.h>
-#include <dali-toolkit/internal/text/shaper.h>
#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-controller-impl-model-updater.h>
#include <dali-toolkit/internal/text/text-editable-control-interface.h>
#include <dali-toolkit/internal/text/text-enumerations-impl.h>
#include <dali-toolkit/internal/text/text-run-container.h>
Vector<unsigned short> mIndices; ///< container of indices
};
-// The relative luminance of a color is defined as (L = 0.2126 * R + 0.7152 * G + 0.0722 * B)
-// based on W3C Recommendations (https://www.w3.org/TR/WCAG20/)
-const float BRIGHTNESS_THRESHOLD = 0.179f;
-const float CONSTANT_R = 0.2126f;
-const float CONSTANT_G = 0.7152f;
-const float CONSTANT_B = 0.0722f;
-const Dali::Vector4 BLACK(0.f, 0.f, 0.f, 1.f);
-const Dali::Vector4 WHITE(1.f, 1.f, 1.f, 1.f);
-const Dali::Vector4 LIGHT_BLUE(0.75f, 0.96f, 1.f, 1.f);
-const Dali::Vector4 BACKGROUND_SUB4(0.58f, 0.87f, 0.96f, 1.f);
-const Dali::Vector4 BACKGROUND_SUB5(0.83f, 0.94f, 0.98f, 1.f);
-const Dali::Vector4 BACKGROUND_SUB6(1.f, 0.5f, 0.5f, 1.f);
-const Dali::Vector4 BACKGROUND_SUB7(1.f, 0.8f, 0.8f, 1.f);
-
} // namespace
-namespace Dali
+namespace Dali::Toolkit::Text
{
-namespace Toolkit
+
+namespace
{
-namespace Text
+
+void SetDefaultInputStyle(InputStyle& inputStyle, const FontDefaults* const fontDefaults, const Vector4& textColor)
{
+ // Sets the default text's color.
+ inputStyle.textColor = textColor;
+ inputStyle.isDefaultColor = true;
+
+ inputStyle.familyName.clear();
+ inputStyle.weight = TextAbstraction::FontWeight::NORMAL;
+ inputStyle.width = TextAbstraction::FontWidth::NORMAL;
+ inputStyle.slant = TextAbstraction::FontSlant::NORMAL;
+ inputStyle.size = 0.f;
+
+ inputStyle.lineSpacing = 0.f;
+
+ inputStyle.underlineProperties.clear();
+ inputStyle.shadowProperties.clear();
+ inputStyle.embossProperties.clear();
+ inputStyle.outlineProperties.clear();
+
+ inputStyle.isFamilyDefined = false;
+ inputStyle.isWeightDefined = false;
+ inputStyle.isWidthDefined = false;
+ inputStyle.isSlantDefined = false;
+ inputStyle.isSizeDefined = false;
+
+ inputStyle.isLineSpacingDefined = false;
+
+ inputStyle.isUnderlineDefined = false;
+ inputStyle.isShadowDefined = false;
+ inputStyle.isEmbossDefined = false;
+ inputStyle.isOutlineDefined = false;
+
+ // Sets the default font's family name, weight, width, slant and size.
+ if(fontDefaults)
+ {
+ if(fontDefaults->familyDefined)
+ {
+ inputStyle.familyName = fontDefaults->mFontDescription.family;
+ inputStyle.isFamilyDefined = true;
+ }
+
+ if(fontDefaults->weightDefined)
+ {
+ inputStyle.weight = fontDefaults->mFontDescription.weight;
+ inputStyle.isWeightDefined = true;
+ }
+
+ if(fontDefaults->widthDefined)
+ {
+ inputStyle.width = fontDefaults->mFontDescription.width;
+ inputStyle.isWidthDefined = true;
+ }
+
+ if(fontDefaults->slantDefined)
+ {
+ inputStyle.slant = fontDefaults->mFontDescription.slant;
+ inputStyle.isSlantDefined = true;
+ }
+
+ if(fontDefaults->sizeDefined)
+ {
+ inputStyle.size = fontDefaults->mDefaultPointSize;
+ inputStyle.isSizeDefined = true;
+ }
+ }
+}
+} // unnamed Namespace
+
EventData::EventData(DecoratorPtr decorator, InputMethodContext& inputMethodContext)
: mDecorator(decorator),
mInputMethodContext(inputMethodContext),
bool Controller::Impl::UpdateModel(OperationsMask operationsRequired)
{
- DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::UpdateModel\n");
-
- // Calculate the operations to be done.
- const OperationsMask operations = static_cast<OperationsMask>(mOperationsPending & operationsRequired);
-
- if(NO_OPERATION == operations)
- {
- // Nothing to do if no operations are pending and required.
- return false;
- }
-
- Vector<Character>& srcCharacters = mModel->mLogicalModel->mText;
- Vector<Character> displayCharacters;
- bool useHiddenText = false;
- if(mHiddenInput && mEventData != nullptr && !mEventData->mIsShowingPlaceholderText)
- {
- mHiddenInput->Substitute(srcCharacters, displayCharacters);
- useHiddenText = true;
- }
-
- Vector<Character>& utf32Characters = useHiddenText ? displayCharacters : srcCharacters;
- const Length numberOfCharacters = utf32Characters.Count();
-
- // Index to the first character of the first paragraph to be updated.
- CharacterIndex startIndex = 0u;
- // Number of characters of the paragraphs to be removed.
- Length paragraphCharacters = 0u;
-
- CalculateTextUpdateIndices(paragraphCharacters);
-
- // Check whether the indices for updating the text is valid
- if(numberOfCharacters > 0u &&
- (mTextUpdateInfo.mParagraphCharacterIndex > numberOfCharacters ||
- mTextUpdateInfo.mRequestedNumberOfCharacters > numberOfCharacters))
- {
- std::string currentText;
- Utf32ToUtf8(mModel->mLogicalModel->mText.Begin(), numberOfCharacters, currentText);
-
- DALI_LOG_ERROR("Controller::Impl::UpdateModel: mTextUpdateInfo has invalid indices\n");
- DALI_LOG_ERROR("Number of characters: %d, current text is: %s\n", numberOfCharacters, currentText.c_str());
-
- // Dump mTextUpdateInfo
- DALI_LOG_ERROR("Dump mTextUpdateInfo:\n");
- DALI_LOG_ERROR(" mTextUpdateInfo.mCharacterIndex = %u\n", mTextUpdateInfo.mCharacterIndex);
- DALI_LOG_ERROR(" mTextUpdateInfo.mNumberOfCharactersToRemove = %u\n", mTextUpdateInfo.mNumberOfCharactersToRemove);
- DALI_LOG_ERROR(" mTextUpdateInfo.mNumberOfCharactersToAdd = %u\n", mTextUpdateInfo.mNumberOfCharactersToAdd);
- DALI_LOG_ERROR(" mTextUpdateInfo.mPreviousNumberOfCharacters = %u\n", mTextUpdateInfo.mPreviousNumberOfCharacters);
- DALI_LOG_ERROR(" mTextUpdateInfo.mParagraphCharacterIndex = %u\n", mTextUpdateInfo.mParagraphCharacterIndex);
- DALI_LOG_ERROR(" mTextUpdateInfo.mRequestedNumberOfCharacters = %u\n", mTextUpdateInfo.mRequestedNumberOfCharacters);
- DALI_LOG_ERROR(" mTextUpdateInfo.mStartGlyphIndex = %u\n", mTextUpdateInfo.mStartGlyphIndex);
- DALI_LOG_ERROR(" mTextUpdateInfo.mStartLineIndex = %u\n", mTextUpdateInfo.mStartLineIndex);
- DALI_LOG_ERROR(" mTextUpdateInfo.mEstimatedNumberOfLines = %u\n", mTextUpdateInfo.mEstimatedNumberOfLines);
- DALI_LOG_ERROR(" mTextUpdateInfo.mClearAll = %d\n", mTextUpdateInfo.mClearAll);
- DALI_LOG_ERROR(" mTextUpdateInfo.mFullRelayoutNeeded = %d\n", mTextUpdateInfo.mFullRelayoutNeeded);
- DALI_LOG_ERROR(" mTextUpdateInfo.mIsLastCharacterNewParagraph = %d\n", mTextUpdateInfo.mIsLastCharacterNewParagraph);
-
- return false;
- }
-
- startIndex = mTextUpdateInfo.mParagraphCharacterIndex;
-
- if(mTextUpdateInfo.mClearAll ||
- (0u != paragraphCharacters))
- {
- ClearModelData(startIndex, startIndex + ((paragraphCharacters > 0u) ? paragraphCharacters - 1u : 0u), operations);
- }
-
- mTextUpdateInfo.mClearAll = false;
-
- // Whether the model is updated.
- bool updated = false;
-
- Vector<LineBreakInfo>& lineBreakInfo = mModel->mLogicalModel->mLineBreakInfo;
- const Length requestedNumberOfCharacters = mTextUpdateInfo.mRequestedNumberOfCharacters;
-
- if(NO_OPERATION != (GET_LINE_BREAKS & operations))
- {
- // Retrieves the line break info. The line break info is used to split the text in 'paragraphs' to
- // calculate the bidirectional info for each 'paragraph'.
- // It's also used to layout the text (where it should be a new line) or to shape the text (text in different lines
- // is not shaped together).
- lineBreakInfo.Resize(numberOfCharacters, TextAbstraction::LINE_NO_BREAK);
-
- SetLineBreakInfo(utf32Characters,
- startIndex,
- requestedNumberOfCharacters,
- lineBreakInfo);
-
- if(mModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) ||
- mModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::MIXED))
- {
- CharacterIndex end = startIndex + requestedNumberOfCharacters;
- LineBreakInfo* lineBreakInfoBuffer = lineBreakInfo.Begin();
-
- for(CharacterIndex index = startIndex; index < end; index++)
- {
- CharacterIndex wordEnd = index;
- while((*(lineBreakInfoBuffer + wordEnd) != TextAbstraction::LINE_ALLOW_BREAK) && (*(lineBreakInfoBuffer + wordEnd) != TextAbstraction::LINE_MUST_BREAK))
- {
- wordEnd++;
- }
-
- if((wordEnd + 1) == end) // add last char
- {
- wordEnd++;
- }
-
- Vector<bool> hyphens = GetWordHyphens(utf32Characters.Begin() + index, wordEnd - index, nullptr);
-
- for(CharacterIndex i = 0; i < (wordEnd - index); i++)
- {
- if(hyphens[i])
- {
- *(lineBreakInfoBuffer + index + i) = TextAbstraction::LINE_HYPHENATION_BREAK;
- }
- }
-
- index = wordEnd;
- }
- }
-
- // Create the paragraph info.
- mModel->mLogicalModel->CreateParagraphInfo(startIndex,
- requestedNumberOfCharacters);
- updated = true;
- }
-
- const bool getScripts = NO_OPERATION != (GET_SCRIPTS & operations);
- const bool validateFonts = NO_OPERATION != (VALIDATE_FONTS & operations);
-
- Vector<ScriptRun>& scripts = mModel->mLogicalModel->mScriptRuns;
- Vector<FontRun>& validFonts = mModel->mLogicalModel->mFontRuns;
-
- if(getScripts || validateFonts)
- {
- // Validates the fonts assigned by the application or assigns default ones.
- // It makes sure all the characters are going to be rendered by the correct font.
- MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
-
- if(getScripts)
- {
- // Retrieves the scripts used in the text.
- multilanguageSupport.SetScripts(utf32Characters,
- startIndex,
- requestedNumberOfCharacters,
- scripts);
- }
-
- if(validateFonts)
- {
- // Validate the fonts set through the mark-up string.
- Vector<FontDescriptionRun>& fontDescriptionRuns = mModel->mLogicalModel->mFontDescriptionRuns;
-
- // Get the default font's description.
- TextAbstraction::FontDescription defaultFontDescription;
- TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE * mFontSizeScale;
-
- //Get the number of points per one unit of point-size
- uint32_t numberOfPointsPerOneUnitOfPointSize = mFontClient.GetNumberOfPointsPerOneUnitOfPointSize();
-
- if(IsShowingPlaceholderText() && mEventData && (nullptr != mEventData->mPlaceholderFont))
- {
- // If the placeholder font is set specifically, only placeholder font is changed.
- defaultFontDescription = mEventData->mPlaceholderFont->mFontDescription;
- if(mEventData->mPlaceholderFont->sizeDefined)
- {
- defaultPointSize = mEventData->mPlaceholderFont->mDefaultPointSize * mFontSizeScale * numberOfPointsPerOneUnitOfPointSize;
- }
- }
- else if(nullptr != mFontDefaults)
- {
- // Set the normal font and the placeholder font.
- defaultFontDescription = mFontDefaults->mFontDescription;
-
- if(mTextFitEnabled)
- {
- defaultPointSize = mFontDefaults->mFitPointSize * numberOfPointsPerOneUnitOfPointSize;
- }
- else
- {
- defaultPointSize = mFontDefaults->mDefaultPointSize * mFontSizeScale * numberOfPointsPerOneUnitOfPointSize;
- }
- }
-
- // Validates the fonts. If there is a character with no assigned font it sets a default one.
- // After this call, fonts are validated.
- multilanguageSupport.ValidateFonts(utf32Characters,
- scripts,
- fontDescriptionRuns,
- defaultFontDescription,
- defaultPointSize,
- startIndex,
- requestedNumberOfCharacters,
- validFonts);
- }
- updated = true;
- }
-
- Vector<Character> mirroredUtf32Characters;
- bool textMirrored = false;
- const Length numberOfParagraphs = mModel->mLogicalModel->mParagraphInfo.Count();
- if(NO_OPERATION != (BIDI_INFO & operations))
- {
- Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = mModel->mLogicalModel->mBidirectionalParagraphInfo;
- bidirectionalInfo.Reserve(numberOfParagraphs);
-
- // Calculates the bidirectional info for the whole paragraph if it contains right to left scripts.
- SetBidirectionalInfo(utf32Characters,
- scripts,
- lineBreakInfo,
- startIndex,
- requestedNumberOfCharacters,
- bidirectionalInfo,
- (mModel->mMatchLayoutDirection != DevelText::MatchLayoutDirection::CONTENTS),
- mLayoutDirection);
-
- if(0u != bidirectionalInfo.Count())
- {
- // Only set the character directions if there is right to left characters.
- Vector<CharacterDirection>& directions = mModel->mLogicalModel->mCharacterDirections;
- GetCharactersDirection(bidirectionalInfo,
- numberOfCharacters,
- startIndex,
- requestedNumberOfCharacters,
- directions);
-
- // This paragraph has right to left text. Some characters may need to be mirrored.
- // TODO: consider if the mirrored string can be stored as well.
-
- textMirrored = GetMirroredText(utf32Characters,
- directions,
- bidirectionalInfo,
- startIndex,
- requestedNumberOfCharacters,
- mirroredUtf32Characters);
- }
- else
- {
- // There is no right to left characters. Clear the directions vector.
- mModel->mLogicalModel->mCharacterDirections.Clear();
- }
- updated = true;
- }
-
- Vector<GlyphInfo>& glyphs = mModel->mVisualModel->mGlyphs;
- Vector<CharacterIndex>& glyphsToCharactersMap = mModel->mVisualModel->mGlyphsToCharacters;
- Vector<Length>& charactersPerGlyph = mModel->mVisualModel->mCharactersPerGlyph;
- Vector<GlyphIndex> newParagraphGlyphs;
- newParagraphGlyphs.Reserve(numberOfParagraphs);
-
- const Length currentNumberOfGlyphs = glyphs.Count();
- if(NO_OPERATION != (SHAPE_TEXT & operations))
- {
- const Vector<Character>& textToShape = textMirrored ? mirroredUtf32Characters : utf32Characters;
- // Shapes the text.
- ShapeText(textToShape,
- lineBreakInfo,
- scripts,
- validFonts,
- startIndex,
- mTextUpdateInfo.mStartGlyphIndex,
- requestedNumberOfCharacters,
- glyphs,
- glyphsToCharactersMap,
- charactersPerGlyph,
- newParagraphGlyphs);
-
- // Create the 'number of glyphs' per character and the glyph to character conversion tables.
- mModel->mVisualModel->CreateGlyphsPerCharacterTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
- mModel->mVisualModel->CreateCharacterToGlyphTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
-
- updated = true;
- }
-
- const Length numberOfGlyphs = glyphs.Count() - currentNumberOfGlyphs;
-
- if(NO_OPERATION != (GET_GLYPH_METRICS & operations))
- {
- GlyphInfo* glyphsBuffer = glyphs.Begin();
- mMetrics->GetGlyphMetrics(glyphsBuffer + mTextUpdateInfo.mStartGlyphIndex, numberOfGlyphs);
-
- // Update the width and advance of all new paragraph characters.
- for(Vector<GlyphIndex>::ConstIterator it = newParagraphGlyphs.Begin(), endIt = newParagraphGlyphs.End(); it != endIt; ++it)
- {
- const GlyphIndex index = *it;
- GlyphInfo& glyph = *(glyphsBuffer + index);
-
- glyph.xBearing = 0.f;
- glyph.width = 0.f;
- glyph.advance = 0.f;
- }
- updated = true;
- }
-
- if((nullptr != mEventData) &&
- mEventData->mPreEditFlag &&
- (0u != mModel->mVisualModel->mCharactersToGlyph.Count()))
- {
- Dali::InputMethodContext::PreEditAttributeDataContainer attrs;
- mEventData->mInputMethodContext.GetPreeditStyle(attrs);
- Dali::InputMethodContext::PreeditStyle type = Dali::InputMethodContext::PreeditStyle::NONE;
-
- // Check the type of preedit and run it.
- for(Dali::InputMethodContext::PreEditAttributeDataContainer::Iterator it = attrs.Begin(), endIt = attrs.End(); it != endIt; it++)
- {
- Dali::InputMethodContext::PreeditAttributeData attrData = *it;
- DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::UpdateModel PreeditStyle type : %d start %d end %d \n", attrData.preeditType, attrData.startIndex, attrData.endIndex);
- type = attrData.preeditType;
-
- // Check the number of commit characters for the start position.
- unsigned int numberOfCommit = mEventData->mPrimaryCursorPosition - mEventData->mPreEditLength;
- Length numberOfIndices = attrData.endIndex - attrData.startIndex;
-
- switch(type)
- {
- case Dali::InputMethodContext::PreeditStyle::UNDERLINE:
- {
- // Add the underline for the pre-edit text.
- GlyphRun underlineRun;
- underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
- underlineRun.numberOfGlyphs = numberOfIndices;
- mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
-
- //Mark-up processor case
- if(mModel->mVisualModel->IsMarkupProcessorEnabled())
- {
- CopyUnderlinedFromLogicalToVisualModels(false);
- }
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::REVERSE:
- {
- Vector4 textColor = mModel->mVisualModel->GetTextColor();
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = textColor;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
- Vector4 backgroundColor = mModel->mVisualModel->GetBackgroundColor();
- if(backgroundColor.a == 0) // There is no text background color.
- {
- // Try use the control's background color.
- if(nullptr != mEditableControlInterface)
- {
- mEditableControlInterface->GetControlBackgroundColor(backgroundColor);
- if(backgroundColor.a == 0) // There is no control background color.
- {
- // Determines black or white color according to text color.
- // Based on W3C Recommendations (https://www.w3.org/TR/WCAG20/)
- float L = CONSTANT_R * textColor.r + CONSTANT_G * textColor.g + CONSTANT_B * textColor.b;
- backgroundColor = L > BRIGHTNESS_THRESHOLD ? BLACK : WHITE;
- }
- }
- }
-
- Vector<ColorRun> colorRuns;
- colorRuns.Resize(1u);
- ColorRun& colorRun = *(colorRuns.Begin());
- colorRun.color = backgroundColor;
- colorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- colorRun.characterRun.numberOfCharacters = numberOfIndices;
- mModel->mLogicalModel->mColorRuns.PushBack(colorRun);
-
- //Mark-up processor case
- if(mModel->mVisualModel->IsMarkupProcessorEnabled())
- {
- CopyUnderlinedFromLogicalToVisualModels(false);
- }
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::HIGHLIGHT:
- {
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = LIGHT_BLUE;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
- //Mark-up processor case
- if(mModel->mVisualModel->IsMarkupProcessorEnabled())
- {
- CopyUnderlinedFromLogicalToVisualModels(false);
- }
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_1:
- {
- // CUSTOM_PLATFORM_STYLE_1 should be drawn with background and underline together.
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = BACKGROUND_SUB4;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
- GlyphRun underlineRun;
- underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
- underlineRun.numberOfGlyphs = numberOfIndices;
- mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
-
- //Mark-up processor case
- if(mModel->mVisualModel->IsMarkupProcessorEnabled())
- {
- CopyUnderlinedFromLogicalToVisualModels(false);
- }
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_2:
- {
- // CUSTOM_PLATFORM_STYLE_2 should be drawn with background and underline together.
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = BACKGROUND_SUB5;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
- GlyphRun underlineRun;
- underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
- underlineRun.numberOfGlyphs = numberOfIndices;
- mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
-
- //Mark-up processor case
- if(mModel->mVisualModel->IsMarkupProcessorEnabled())
- {
- CopyUnderlinedFromLogicalToVisualModels(false);
- }
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_3:
- {
- // CUSTOM_PLATFORM_STYLE_3 should be drawn with background and underline together.
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = BACKGROUND_SUB6;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
- GlyphRun underlineRun;
- underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
- underlineRun.numberOfGlyphs = numberOfIndices;
- mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
-
- //Mark-up processor case
- if(mModel->mVisualModel->IsMarkupProcessorEnabled())
- {
- CopyUnderlinedFromLogicalToVisualModels(false);
- }
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_4:
- {
- // CUSTOM_PLATFORM_STYLE_4 should be drawn with background and underline together.
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = BACKGROUND_SUB7;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
- GlyphRun underlineRun;
- underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
- underlineRun.numberOfGlyphs = numberOfIndices;
- mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
-
- //Mark-up processor case
- if(mModel->mVisualModel->IsMarkupProcessorEnabled())
- {
- CopyUnderlinedFromLogicalToVisualModels(false);
- }
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::NONE:
- default:
- {
- break;
- }
- }
- }
- attrs.Clear();
- updated = true;
- }
-
- if(NO_OPERATION != (COLOR & operations))
- {
- // Set the color runs in glyphs.
- SetColorSegmentationInfo(mModel->mLogicalModel->mColorRuns,
- mModel->mVisualModel->mCharactersToGlyph,
- mModel->mVisualModel->mGlyphsPerCharacter,
- startIndex,
- mTextUpdateInfo.mStartGlyphIndex,
- requestedNumberOfCharacters,
- mModel->mVisualModel->mColors,
- mModel->mVisualModel->mColorIndices);
-
- // Set the background color runs in glyphs.
- SetColorSegmentationInfo(mModel->mLogicalModel->mBackgroundColorRuns,
- mModel->mVisualModel->mCharactersToGlyph,
- mModel->mVisualModel->mGlyphsPerCharacter,
- startIndex,
- mTextUpdateInfo.mStartGlyphIndex,
- requestedNumberOfCharacters,
- mModel->mVisualModel->mBackgroundColors,
- mModel->mVisualModel->mBackgroundColorIndices);
-
- updated = true;
- }
-
- if((NO_OPERATION != (SHAPE_TEXT & operations)) &&
- !((nullptr != mEventData) &&
- mEventData->mPreEditFlag &&
- (0u != mModel->mVisualModel->mCharactersToGlyph.Count())))
- {
- //Mark-up processor case
- if(mModel->mVisualModel->IsMarkupProcessorEnabled())
- {
- CopyUnderlinedFromLogicalToVisualModels(true);
- }
-
- updated = true;
- }
-
- // The estimated number of lines. Used to avoid reallocations when layouting.
- mTextUpdateInfo.mEstimatedNumberOfLines = std::max(mModel->mVisualModel->mLines.Count(), mModel->mLogicalModel->mParagraphInfo.Count());
-
- // Set the previous number of characters for the next time the text is updated.
- mTextUpdateInfo.mPreviousNumberOfCharacters = numberOfCharacters;
-
- return updated;
+ return ControllerImplModelUpdater::Update(*this, operationsRequired);
}
void Controller::Impl::RetrieveDefaultInputStyle(InputStyle& inputStyle)
{
- // Sets the default text's color.
- inputStyle.textColor = mTextColor;
- inputStyle.isDefaultColor = true;
-
- inputStyle.familyName.clear();
- inputStyle.weight = TextAbstraction::FontWeight::NORMAL;
- inputStyle.width = TextAbstraction::FontWidth::NORMAL;
- inputStyle.slant = TextAbstraction::FontSlant::NORMAL;
- inputStyle.size = 0.f;
-
- inputStyle.lineSpacing = 0.f;
-
- inputStyle.underlineProperties.clear();
- inputStyle.shadowProperties.clear();
- inputStyle.embossProperties.clear();
- inputStyle.outlineProperties.clear();
-
- inputStyle.isFamilyDefined = false;
- inputStyle.isWeightDefined = false;
- inputStyle.isWidthDefined = false;
- inputStyle.isSlantDefined = false;
- inputStyle.isSizeDefined = false;
-
- inputStyle.isLineSpacingDefined = false;
-
- inputStyle.isUnderlineDefined = false;
- inputStyle.isShadowDefined = false;
- inputStyle.isEmbossDefined = false;
- inputStyle.isOutlineDefined = false;
-
- // Sets the default font's family name, weight, width, slant and size.
- if(mFontDefaults)
- {
- if(mFontDefaults->familyDefined)
- {
- inputStyle.familyName = mFontDefaults->mFontDescription.family;
- inputStyle.isFamilyDefined = true;
- }
-
- if(mFontDefaults->weightDefined)
- {
- inputStyle.weight = mFontDefaults->mFontDescription.weight;
- inputStyle.isWeightDefined = true;
- }
-
- if(mFontDefaults->widthDefined)
- {
- inputStyle.width = mFontDefaults->mFontDescription.width;
- inputStyle.isWidthDefined = true;
- }
-
- if(mFontDefaults->slantDefined)
- {
- inputStyle.slant = mFontDefaults->mFontDescription.slant;
- inputStyle.isSlantDefined = true;
- }
-
- if(mFontDefaults->sizeDefined)
- {
- inputStyle.size = mFontDefaults->mDefaultPointSize;
- inputStyle.isSizeDefined = true;
- }
- }
+ SetDefaultInputStyle(inputStyle, mFontDefaults, mTextColor);
}
float Controller::Impl::GetDefaultFontLineHeight()
const Vector2 textSize = mView.GetLayoutSize();
- const float offsetX = textSize.width * 0.5f;
+ const float offsetX = alignmentOffset + textSize.width * 0.5f;
const float offsetY = textSize.height * 0.5f;
const Vector4* const backgroundColorsBuffer = mView.GetBackgroundColors();
}
}
-} // namespace Text
-
-} // namespace Toolkit
-
-} // namespace Dali
+} // namespace Dali::Toolkit::Text
struct CursorInfo;
struct FontDefaults;
struct ControllerImplEventHandler;
+struct ControllerImplModelUpdater;
struct SelectionHandleController;
class SelectableControlInterface;
private:
friend ControllerImplEventHandler;
+ friend ControllerImplModelUpdater;
friend SelectionHandleController;
};
return;
}
- // If this transition is not a transition from a Control to another Control
- // and a transition effect to appear with delay,
- // the mTarget should not be shown until delay seconds.
- if(!IsPairTransition() && mIsAppearingTransition && mAnimation && mTimePeriod.delaySeconds > Dali::Math::MACHINE_EPSILON_10)
- {
- Dali::KeyFrames initialKeyframes = Dali::KeyFrames::New();
- initialKeyframes.Add(0.0f, OPACITY_TRANSPARENT);
- initialKeyframes.Add(1.0f, OPACITY_TRANSPARENT);
- mAnimation.AnimateBetween(Property(mTarget, Dali::Actor::Property::OPACITY), initialKeyframes, TimePeriod(mTimePeriod.delaySeconds));
- }
-
for(uint32_t i = 0; i < mStartPropertyMap.Count(); ++i)
{
Property::Value* finishValue = mFinishPropertyMap.Find(mStartPropertyMap.GetKeyAt(i).indexKey);
if(finishValue)
{
+ // If this transition is appearing transition, this property keeps start value during delay.
+ // If multiple transitions are applied to this Control and others run before this transition,
+ // this property should keep start value until this transition starts.
+ if(!IsPairTransition() && IsAppearingTransition() && mTimePeriod.delaySeconds > Dali::Math::MACHINE_EPSILON_10)
+ {
+ mTarget.SetProperty(mStartPropertyMap.GetKeyAt(i).indexKey, mStartPropertyMap.GetValue(i));
+ }
AnimateBetween(mTarget, mStartPropertyMap.GetKeyAt(i).indexKey, mStartPropertyMap.GetValue(i), *finishValue);
}
}
mIsAppearingTransition = appearingTransition;
}
+ /**
+ * @brief Returns whether this transition is appearing transition or not
+ */
+ bool IsAppearingTransition() const
+ {
+ return mIsAppearingTransition;
+ }
+
+ /**
+ * @brief Returns whether this transition is a transition from a Control to another Control or effect to appearing or disappearing.
+ */
+ bool IsPairTransition() const
+ {
+ return mIsPairTransition;
+ }
+
+ /**
+ * @brief Returns target which will be transition.
+ */
+ const Dali::Toolkit::Control GetTarget() const
+ {
+ return mTarget;
+ }
+
protected:
/**
}
/**
- * @brief Returns whether this transition is appearing transition or not
- */
- bool IsAppearingTransition() const
- {
- return mIsAppearingTransition;
- }
-
- /**
* @brief Set whether this transition is a transition from a Control to another Control or effect to appearing or disappearing.
* @param[in] pairTransition True if this transition is appearing transition.
*/
mIsPairTransition = pairTransition;
}
- /**
- * @brief Returns whether this transition is a transition from a Control to another Control or effect to appearing or disappearing.
- */
- bool IsPairTransition() const
- {
- return mIsPairTransition;
- }
-
protected:
/**
* Construct a new TransitionBase.
// Signals
static constexpr std::string_view SIGNAL_FINISHED = "finished";
+static constexpr float OPACITY_TRANSPARENT = 0.0f;
+
+float CustomAlphaFunction(float progress)
+{
+ return (progress >= 1.0f) ? 1.0f : 0.0f;
+}
+
BaseHandle Create()
{
return Dali::Toolkit::TransitionSet::New();
void TransitionSet::TransitionStart()
{
+ std::vector<std::pair<Dali::Actor, float>> minimumDelays;
for(auto&& transition : mTransitions)
{
transition->Play();
+
+ // If target Control has appearing transition, the target will not be rendered during delay.
+ // And if the Control has multiple transitions, the target will not be rendered during minimum delay of the transitions.
+ // Here we can find minimum delay of each target.
+ if(!transition->IsPairTransition() && transition->IsAppearingTransition())
+ {
+ bool found = false;
+ for(uint32_t index = 0; index < minimumDelays.size(); ++index)
+ {
+ if(minimumDelays[index].first == transition->GetTarget())
+ {
+ minimumDelays[index].second = std::min(minimumDelays[index].second, transition->GetTimePeriod().delaySeconds);
+ found = true;
+ break;
+ }
+ }
+ if(!found)
+ {
+ minimumDelays.push_back(std::pair<Dali::Actor, float>(transition->GetTarget(), transition->GetTimePeriod().delaySeconds));
+ }
+ }
+ }
+
+ // If the target has delay that is larger than 0, hide the target during minimum delay.
+ // The custom alpha function make the target hide just during delay.
+ for(auto&& delay : minimumDelays)
+ {
+ if(delay.second > Dali::Math::MACHINE_EPSILON_10)
+ {
+ Dali::KeyFrames initialKeyframes = Dali::KeyFrames::New();
+ initialKeyframes.Add(0.0f, OPACITY_TRANSPARENT);
+ initialKeyframes.Add(1.0f, delay.first.GetProperty<float>(Dali::Actor::Property::OPACITY));
+
+ AlphaFunction alpha(&CustomAlphaFunction);
+ mAnimation.AnimateBetween(Property(delay.first, Dali::Actor::Property::OPACITY), initialKeyframes, alpha, TimePeriod(delay.second));
+ }
}
mAnimation.FinishedSignal().Connect(this, &TransitionSet::TransitionFinished);
mController(Text::Controller::New()),
mTypesetter(Text::Typesetter::New(mController->GetTextModel())),
mAnimatableTextColorPropertyIndex(Property::INVALID_INDEX),
+ mTextColorAnimatableIndex(Property::INVALID_INDEX),
mRendererUpdateNeeded(false)
{
}
// Enable the pre-multiplied alpha to improve the text quality
EnablePreMultipliedAlpha(true);
- if(mAnimatableTextColorPropertyIndex != Property::INVALID_INDEX)
+ const Vector4& defaultColor = mController->GetTextModel()->GetDefaultColor();
+ if(mTextColorAnimatableIndex == Property::INVALID_INDEX)
+ {
+ mTextColorAnimatableIndex = mImpl->mRenderer.RegisterProperty("uTextColorAnimatable", defaultColor);
+ }
+ else
{
- const Vector4& defaultColor = mController->GetTextModel()->GetDefaultColor();
- Dali::Property::Index shaderTextColorIndex = mImpl->mRenderer.RegisterProperty("uTextColorAnimatable", defaultColor);
+ mImpl->mRenderer.SetProperty(mTextColorAnimatableIndex, defaultColor);
+ }
+ if(mAnimatableTextColorPropertyIndex != Property::INVALID_INDEX)
+ {
// Create constraint for the animatable text's color Property with uTextColorAnimatable in the renderer.
- if(shaderTextColorIndex != Property::INVALID_INDEX)
+ if(mTextColorAnimatableIndex != Property::INVALID_INDEX)
{
if(!mColorConstraint)
{
- mColorConstraint = Constraint::New<Vector4>(mImpl->mRenderer, shaderTextColorIndex, TextColorConstraint);
+ mColorConstraint = Constraint::New<Vector4>(mImpl->mRenderer, mTextColorAnimatableIndex, TextColorConstraint);
mColorConstraint.AddSource(Source(actor, mAnimatableTextColorPropertyIndex));
}
mColorConstraint.Apply();
+ }
- // Make zero if the alpha value of text color is zero to skip rendering text
- if(!mOpacityConstraint)
- {
- mOpacityConstraint = Constraint::New<float>(mImpl->mRenderer, Dali::DevelRenderer::Property::OPACITY, OpacityConstraint);
- mOpacityConstraint.AddSource(Source(actor, mAnimatableTextColorPropertyIndex));
- }
- mOpacityConstraint.Apply();
+ // Make zero if the alpha value of text color is zero to skip rendering text
+ if(!mOpacityConstraint)
+ {
+ mOpacityConstraint = Constraint::New<float>(mImpl->mRenderer, Dali::DevelRenderer::Property::OPACITY, OpacityConstraint);
+ mOpacityConstraint.AddSource(Source(actor, mAnimatableTextColorPropertyIndex));
}
+ mOpacityConstraint.Apply();
}
// Renderer needs textures and to be added to control
Constraint mColorConstraint{}; ///< Color constraint
Constraint mOpacityConstraint{}; ///< Opacity constraint
Property::Index mAnimatableTextColorPropertyIndex; ///< The index of animatable text color property registered by the control.
+ Property::Index mTextColorAnimatableIndex; ///< The index of uTextColorAnimatable property.
bool mRendererUpdateNeeded : 1; ///< The flag to indicate whether the renderer needs to be updated.
RendererContainer mRendererList;
};
{
const unsigned int TOOLKIT_MAJOR_VERSION = 2;
const unsigned int TOOLKIT_MINOR_VERSION = 0;
-const unsigned int TOOLKIT_MICRO_VERSION = 51;
+const unsigned int TOOLKIT_MICRO_VERSION = 52;
const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * This file is part of Dali Toolkit
+ *
+ * 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.
+ */
+
+
+//******************************************************************************
+//
+// Default Reference style theme for a 1920x1080 resolution, The values determined by UX design specification.
+// This file can be copied to a new folder within the styles/ directory and amended with new default values.
+// Can be overriden if StyleManager applies another style sheet.
+//
+//******************************************************************************
+
+{
+ "config":
+ {
+ "brokenImageUrl":"{DALI_IMAGE_DIR}broken.png",
+ "alwaysShowFocus":true,
+ "clearFocusOnEscape":false
+ },
+ "styles":
+ {
+ "Tooltip":
+ {
+ "tooltip":
+ {
+ "content":
+ {
+ "pointSize":24
+ },
+ "waitTime":0.5,
+ "background":
+ {
+ "visual":"{DALI_IMAGE_DIR}tooltip.9.png",
+ "border":[1,5,5,1]
+ },
+ "tail":
+ {
+ "visibility":false,
+ "aboveVisual":"{DALI_IMAGE_DIR}tooltip-tail-above.png",
+ "belowVisual":"{DALI_IMAGE_DIR}tooltip-tail-below.png"
+ },
+ "position":"BELOW",
+ "hoverPointOffset":[10,10],
+ "movementThreshold":5,
+ "disappearOnMovement":false
+ }
+ },
+ "TextLabel":
+ {
+ "pointSize":24,
+ "enableAutoScroll":false,
+ "autoScrollLoopCount":2,
+ "autoScrollGap":50,
+ "autoScrollSpeed":80,
+ "ignoreSpacesAfterText":false
+ },
+
+ "TextLabelFontSize0":
+ {
+ "pointSize":24
+ },
+ "TextLabelFontSize1":
+ {
+ "pointSize":28
+ },
+ "TextLabelFontSize2":
+ {
+ "pointSize":32
+ },
+ "TextLabelFontSize3":
+ {
+ "pointSize":36
+ },
+ "TextLabelFontSize4":
+ {
+ "pointSize":40
+ },
+
+ "TextField":
+ {
+ "pointSize":28,
+ "primaryCursorColor":[0.0,0.72,0.9,1.0],
+ "secondaryCursorColor":[0.0,0.72,0.9,1.0],
+ "cursorWidth":6,
+ "selectionHighlightColor":[0.75,0.96,1.0,1.0],
+ "grabHandleImage" : "{DALI_STYLE_IMAGE_DIR}cursor_handler_drop_center.png",
+ "selectionHandleImageLeft" : {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_left.png" },
+ "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" },
+ "enableSelection":false
+ },
+
+ "TextFieldFontSize0":
+ {
+ "pointSize":24
+ },
+ "TextFieldFontSize1":
+ {
+ "pointSize":28
+ },
+ "TextFieldFontSize2":
+ {
+ "pointSize":32
+ },
+ "TextFieldFontSize3":
+ {
+ "pointSize":36
+ },
+ "TextFieldFontSize4":
+ {
+ "pointSize":40
+ },
+ "TextSelectionPopup":
+ {
+ "popupMaxSize":[1700,100],
+ "optionDividerSize":[2,0],
+ "popupDividerColor":[0.23,0.72,0.8,0.11],
+ "popupIconColor":[1.0,1.0,1.0,1.0],
+ "popupPressedColor":[0.24,0.72,0.8,0.11],
+ "background": {
+ "rendererType": "image",
+ "url": "{DALI_IMAGE_DIR}selection-popup-background.9.png"
+ },
+ "backgroundBorder": {
+ "visualType": "IMAGE",
+ "url": "{DALI_IMAGE_DIR}selection-popup-border.9.png",
+ "mixColor":[0.24,0.72,0.8,1.0]
+ },
+ "popupFadeInDuration":0.25,
+ "popupFadeOutDuration":0.25
+ },
+ "TextSelectionPopupButton":
+ {
+ "label":
+ {
+ "visualType":"TEXT",
+ "pointSize":24
+ },
+ "unselectedBackgroundVisual":
+ {
+ "visualType": "IMAGE",
+ "url": ""
+ },
+ "selectedBackgroundVisual":
+ {
+ "visualType": "IMAGE",
+ "url": ""
+ }
+ },
+ "TextSelectionToolbar":
+ {
+ "enableOvershoot":true,
+ "enableScrollBar":true,
+ "scrollView":
+ {
+ "overshootAnimationSpeed":360.0,
+ "overshootSize":[1920.0,130.0]
+ }
+ },
+ "TextSelectionScrollBar":
+ {
+ "indicatorShowDuration":0.25,
+ "indicatorHideDuration":0.25,
+ "indicatorTransientDuration":1.0
+ },
+ "TextSelectionScrollIndicator":
+ {
+ "image":
+ {
+ "visualType":"IMAGE",
+ "url":"{DALI_IMAGE_DIR}text_selection_scroll_indicator.9.png"
+ },
+ "color":[0.0,0.72,0.9,0.7]
+ },
+ "ScrollView":
+ {
+ "overshootEffectColor":"B018",
+ "overshootAnimationSpeed":960.0,
+ "overshootSize":[1920.0,130.0]
+ },
+ "ItemView":
+ {
+ "overshootEffectColor":"B018",
+ "overshootAnimationSpeed":960.0,
+ "overshootSize":[1920.0,130.0]
+ },
+ "ScrollBar":
+ {
+ "indicatorShowDuration":0.25,
+ "indicatorHideDuration":0.25,
+ "color":[0.0,0.72,0.9,0.7]
+ },
+ "TextEditor":
+ {
+ "pointSize":24,
+ "primaryCursorColor":[0.0,0.72,0.9,1.0],
+ "secondaryCursorColor":[0.0,0.72,0.9,1.0],
+ "cursorWidth":6,
+ "selectionHighlightColor":[0.75,0.96,1.0,1.0],
+ "grabHandleImage" : "{DALI_STYLE_IMAGE_DIR}cursor_handler_drop_center.png",
+ "selectionHandleImageLeft" : {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_left.png" },
+ "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" },
+ "enableScrollBar":true,
+ "scrollBarShowDuration":0.8,
+ "scrollBarFadeDuration":0.5,
+ "enableSelection":false
+ },
+ "ProgressBar":
+ {
+ "trackVisual":{
+ "visualType":"IMAGE",
+ "url":"{DALI_IMAGE_DIR}progress-bar-skin-track.9.png"
+ },
+ "progressVisual":{
+ "visualType":"IMAGE",
+ "url":"{DALI_IMAGE_DIR}progress-bar-skin-progress.9.png"
+ },
+ "secondaryProgressVisual":{
+ "visualType":"IMAGE",
+ "url":"{DALI_IMAGE_DIR}progress-bar-skin-secondary-progress.9.png"
+ },
+ "indeterminateVisual":{
+ "visualType":"IMAGE",
+ "pixelArea":[0.0, 0.0, 10.0, 1.0],
+ "wrapModeU":"REPEAT",
+ "url":"{DALI_IMAGE_DIR}progress-bar-skin-indeterminate.png"
+ },
+ "indeterminateVisualAnimation":
+ [
+ {
+ "target":"indeterminateVisual",
+ "property":"pixelArea",
+ "initialValue":[0.0, 0.0, 10.0, 1.0],
+ "targetValue":[-1.0, 0.0, 10.0, 1.0],
+ "animator":
+ {
+ "alphaFunction":"DEFAULT",
+ "timePeriod":
+ {
+ "duration":0.8,
+ "delay":0
+ }
+ }
+ }
+ ],
+ "labelVisual":{
+ "visualType": "TEXT",
+ "textColor": [ 1.0, 1.0, 1.0, 1.0 ],
+ "pointSize" : 12.0, // Point size must always be provided to Text Visual
+ "horizontalAlignment": "CENTER",
+ "verticalAlignment": "CENTER"
+ },
+ "progressValue": 0.0,
+ "secondaryProgressValue":0.0,
+ "indeterminate": false
+ },
+ "CircularProgressBar":
+ {
+ "size":[64,64],
+ "trackVisual":{
+ "visualType":"ARC",
+ "mixColor":[0.0,0.165,0.302,1.0],
+ "thickness":4.0,
+ "startAngle":0.0,
+ "cap":"ROUND"
+ },
+ "progressVisual":{
+ "visualType":"ARC",
+ "mixColor":[0.0,0.549,1.0,1.0],
+ "thickness":4.0,
+ "startAngle":0.0,
+ "cap":"ROUND"
+ },
+ "secondaryProgressVisual":{
+ "visualType":"ARC",
+ "mixColor":[0.0,0.549,1.0,0.3],
+ "thickness":4.0,
+ "startAngle":0.0,
+ "cap":"ROUND"
+ },
+ "indeterminateVisual":{
+ "visualType":"ARC",
+ "mixColor":[0.02,0.71,0.525,1.0],
+ "thickness":4.0,
+ "startAngle":267.0,
+ "sweepAngle":75.0,
+ "cap":"ROUND"
+ },
+ "indeterminateVisualAnimation":
+ [
+ {
+ "target":"trackVisual",
+ "property":"opacity",
+ "targetValue": 0,
+ "animator":
+ {
+ "alphaFunction":"DEFAULT",
+ "timePeriod":
+ {
+ "duration":0,
+ "delay":0
+ }
+ }
+ },
+ {
+ "target":"secondaryProgressVisual",
+ "property":"opacity",
+ "targetValue": 0,
+ "animator":
+ {
+ "alphaFunction":"DEFAULT",
+ "timePeriod":
+ {
+ "duration":0,
+ "delay":0
+ }
+ }
+ },
+ {
+ "target":"progressVisual",
+ "property":"sweepAngle",
+ "initialValue": 75,
+ "targetValue": 180,
+ "animator":
+ {
+ "alphaFunction":[0.439, 0.0, 0.718, 0.428],
+ "timePeriod":
+ {
+ "duration":1.0,
+ "delay":0.0
+ }
+ }
+ },
+ {
+ "target":"progressVisual",
+ "property":"sweepAngle",
+ "targetValue": 75,
+ "animator":
+ {
+ "alphaFunction":[0.224, 0.571, 0.53, 1.0],
+ "timePeriod":
+ {
+ "duration":1.0,
+ "delay":2.0
+ }
+ }
+ },
+ {
+ "target":"progressVisual",
+ "property":"startAngle",
+ "initialValue": 87,
+ "targetValue": 1887,
+ "animator":
+ {
+ "alphaFunction":[0.33, 0.0, 0.3, 1.0],
+ "timePeriod":
+ {
+ "duration":3.0,
+ "delay":0.0
+ }
+ }
+ },
+ {
+ "target":"indeterminateVisual",
+ "property":"sweepAngle",
+ "initialValue": 75,
+ "targetValue": 180,
+ "animator":
+ {
+ "alphaFunction":[0.439, 0.0, 0.718, 0.428],
+ "timePeriod":
+ {
+ "duration":1.0,
+ "delay":0.0
+ }
+ }
+ },
+ {
+ "target":"indeterminateVisual",
+ "property":"sweepAngle",
+ "targetValue": 75,
+ "animator":
+ {
+ "alphaFunction":[0.224, 0.571, 0.53, 1.0],
+ "timePeriod":
+ {
+ "duration":1.0,
+ "delay":2.0
+ }
+ }
+ },
+ {
+ "target":"indeterminateVisual",
+ "property":"startAngle",
+ "initialValue": 267,
+ "targetValue": 2067,
+ "animator":
+ {
+ "alphaFunction":[0.33, 0.0, 0.3, 1.0],
+ "timePeriod":
+ {
+ "duration":3.0,
+ "delay":0.0
+ }
+ }
+ }
+ ],
+ "labelVisual":{
+ "visualType": "TEXT",
+ "textColor": [ 1.0, 1.0, 1.0, 1.0 ],
+ "pointSize" : 32.0, // Point size must always be provided to Text Visual
+ "horizontalAlignment": "CENTER",
+ "verticalAlignment": "CENTER"
+ },
+ "progressValue": 0.2,
+ "secondaryProgressValue":0.4,
+ "indeterminate": false
+ },
+ "Button":
+ {
+ "styles":["Tooltip"],
+ "initialAutoRepeatingDelay":2.0,
+ "nextAutoRepeatingDelay":0.9
+ // Note: Visuals added to Button will be used in all derived buttons unless overridden.
+ },
+ "PushButton":
+ {
+ "styles":["Button"],
+ "autoRepeating":false,
+ "togglable":false,
+ "labelPadding":[ 12.0, 12.0, 12.0, 12.0 ],
+ "label":
+ {
+ "visualType": "TEXT",
+ "horizontalAlignment": "CENTER",
+ "pointSize" : 24.0, // Point size must always be provided to Text Visual
+ "verticalAlignment": "CENTER"
+ },
+ "unselectedBackgroundVisual":
+ {
+ "visualType": "IMAGE",
+ "url": "{DALI_IMAGE_DIR}button-up.9.png"
+ },
+ "selectedBackgroundVisual":
+ {
+ "visualType": "IMAGE",
+ "url": "{DALI_IMAGE_DIR}button-down.9.png"
+ },
+ "disabledSelectedBackgroundVisual":
+ {
+ "visualType": "IMAGE",
+ "url": "{DALI_IMAGE_DIR}button-down-disabled.9.png"
+ },
+ "disabledUnselectedBackgroundVisual":
+ {
+ "visualType": "IMAGE",
+ "url": "{DALI_IMAGE_DIR}button-disabled.9.png"
+ }
+ },
+ "ToggleButton":
+ {
+ "styles":["Button"]
+ },
+ "CheckBoxButton":
+ {
+ "styles":["Button"],
+ "labelPadding":[ 12.0, 12.0, 0.0, 0.0 ],
+ "label":
+ {
+ "visualType": "TEXT",
+ "pointSize" : 24.0, // Point size must always be provided to Text Visual
+ "verticalAlignment": "CENTER"
+ },
+ "unselectedVisual":
+ {
+ "visualType": "IMAGE",
+ "url": "{DALI_IMAGE_DIR}checkbox-unselected.png"
+ },
+ "selectedVisual":
+ {
+ "visualType": "IMAGE",
+ "url": "{DALI_IMAGE_DIR}checkbox-selected.png"
+ },
+ "disabledUnselectedVisual":
+ {
+ "visualType": "IMAGE",
+ "url": "{DALI_IMAGE_DIR}checkbox-unselected-disabled.png"
+ },
+ "disabledSelectedVisual":
+ {
+ "visualType": "IMAGE",
+ "url": "{DALI_IMAGE_DIR}checkbox-selected-disabled.png"
+ }
+ },
+ "RadioButton":
+ {
+ "styles":["Button"],
+ "labelPadding":[ 12.0, 12.0, 0.0, 0.0 ],
+ "label":
+ {
+ "visualType": "TEXT",
+ "pointSize" : 24.0, // Point size must always be provided to Text Visual
+ "verticalAlignment": "CENTER"
+ },
+ "unselectedVisual":
+ {
+ "visualType": "IMAGE",
+ "url": "{DALI_IMAGE_DIR}radio-button-unselected.png"
+ },
+ "selectedVisual":
+ {
+ "visualType": "IMAGE",
+ "url": "{DALI_IMAGE_DIR}radio-button-selected.png"
+ },
+ "disabledUnselectedVisual":
+ {
+ "visualType": "IMAGE",
+ "url": "{DALI_IMAGE_DIR}radio-button-unselected-disabled.png"
+ },
+ "disabledSelectedVisual":
+ {
+ "visualType": "IMAGE",
+ "url": "{DALI_IMAGE_DIR}radio-button-selected-disabled.png"
+ }
+ }
+ }
+}
Name: dali2-toolkit
Summary: Dali 3D engine Toolkit
-Version: 2.0.51
+Version: 2.0.52
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT
Conflicts: %{name}-resources_480x800
Conflicts: %{name}-resources_720x1280
Conflicts: %{name}-resources_1920x1080
+Conflicts: %{name}-resources_1920x1080_rpi
%description resources_360x360
dali-toolkit default resource files for 360x360
Contain po / sounds / common images / style / style images
Conflicts: %{name}-resources_360x360
Conflicts: %{name}-resources_720x1280
Conflicts: %{name}-resources_1920x1080
+Conflicts: %{name}-resources_1920x1080_rpi
%description resources_480x800
dali-toolkit default resource files for 480x800
Contain po / sounds / common images / style / style images
Conflicts: %{name}-resources_360x360
Conflicts: %{name}-resources_480x800
Conflicts: %{name}-resources_1920x1080
+Conflicts: %{name}-resources_1920x1080_rpi
%description resources_720x1280
dali-toolkit default resource files for 720x1280
Contain po / sounds / common images / style / style images
Conflicts: %{name}-resources_360x360
Conflicts: %{name}-resources_480x800
Conflicts: %{name}-resources_720x1280
+Conflicts: %{name}-resources_1920x1080_rpi
%description resources_1920x1080
dali-toolkit default resource files for 1920x1080
Contain po / sounds / common images / style / style images
+%package resources_1920x1080_rpi
+Summary: default resource files for 1920x1080 on Raspberry Pi 4
+Requires: %{name} = %{version}-%{release}
+Conflicts: %{name}-resources_360x360
+Conflicts: %{name}-resources_480x800
+Conflicts: %{name}-resources_720x1280
+Conflicts: %{name}-resources_1920x1080
+%description resources_1920x1080_rpi
+dali-toolkit default resource files for 1920x1080 on Raspberry Pi 4
+Contain po / sounds / common images / style / style images
+
+
##############################
# devel
##############################
cp -r dali-toolkit/styles/720x1280/* %{buildroot}%{dali_toolkit_style_files}/720x1280
mkdir -p %{buildroot}%{dali_toolkit_style_files}/1920x1080
cp -r dali-toolkit/styles/1920x1080/* %{buildroot}%{dali_toolkit_style_files}/1920x1080
+mkdir -p %{buildroot}%{dali_toolkit_style_files}/1920x1080_rpi
+cp -r dali-toolkit/styles/1920x1080_rpi/* %{buildroot}%{dali_toolkit_style_files}/1920x1080_rpi
# Copy default feedback theme
cp dali-toolkit/styles/default-feedback-theme.json %{buildroot}%{dali_toolkit_style_files}
;;
esac
+%pre resources_1920x1080_rpi
+case "$1" in
+ 2)
+ pushd %{dali_toolkit_style_files}
+ rm -rf ./*
+ popd
+ ;;
+esac
+
##############################
# Post Install
##############################
for FILE in *; do mv ./"${FILE}" ../"${FILE}"; done
popd
+%post resources_1920x1080_rpi
+pushd %{dali_toolkit_style_files}/1920x1080_rpi
+for FILE in *; do mv ./"${FILE}" ../"${FILE}"; done
+popd
+
##############################
# Pre Uninstall
##############################
;;
esac
+%preun resources_1920x1080_rpi
+case "$1" in
+ 0)
+ %preun resources_1920x1080_rpi
+ pushd %{dali_toolkit_style_files}
+ mv images ./1920x1080_rpi
+ mv dali-toolkit-default-theme.json ./1920x1080_rpi
+ popd
+ ;;
+esac
+
##############################
# Post Uninstall
##############################
;;
esac
+%postun resources_1920x1080_rpi
+case "$1" in
+ 0)
+ pushd %{dali_toolkit_style_files}
+ rm -rf *
+ popd
+ ;;
+esac
+
##############################
# Files in Binary Packages
##############################
%{dali_toolkit_style_files}/default-feedback-theme.json
%{_datadir}/locale/*/LC_MESSAGES/*
+%files resources_1920x1080_rpi
+%manifest dali-toolkit-resources.manifest
+%defattr(-,root,root,-)
+%{dali_toolkit_image_files}/*
+%{dali_toolkit_sound_files}/*
+%{dali_toolkit_style_files}/1920x1080_rpi/*
+%{dali_toolkit_style_files}/default-feedback-theme.json
+%{_datadir}/locale/*/LC_MESSAGES/*
+
%files -n %{dali2_scene_loader}
%if 0%{?enable_dali_smack_rules}
%manifest dali-scene-loader.manifest-smack