{
InstallLogFunction(TestLogFunction);
DefaultErrorCallback("Hello world!");
- DALI_TEST_EQUAL(std::string(sBuffer), "2: DefaultErrorCallback Hello world!");
+ DALI_TEST_EQUAL(std::string(sBuffer), "2: string-callback.cpp: DefaultErrorCallback(26) > Hello world!");
END_TEST;
}
#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;
namespace Dali
{
+const Rect<int> TestApplication::DEFAULT_SURFACE_RECT = Rect<int>(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
+
bool TestApplication::mLoggingEnabled = true;
TestApplication::TestApplication(uint32_t surfaceWidth,
bool TestApplication::RenderWithPartialUpdate(std::vector<Rect<int>>& damagedRects, Rect<int>& clippingRect)
{
- mCore->RenderScene(mRenderStatus, mScene, true /*render the off-screen buffers*/, clippingRect);
+ mCore->RenderScene(mRenderStatus, mScene, true /*render the off-screen buffers*/);
mCore->RenderScene(mRenderStatus, mScene, false /*render the surface*/, clippingRect);
mCore->PostRender(false /*do not skip rendering*/);
static const uint32_t DEFAULT_SURFACE_WIDTH = 480;
static const uint32_t DEFAULT_SURFACE_HEIGHT = 800;
+ static const Rect<int> DEFAULT_SURFACE_RECT;
+
static constexpr uint32_t DEFAULT_HORIZONTAL_DPI = 220;
static constexpr uint32_t DEFAULT_VERTICAL_DPI = 217;
public:
CanvasRenderer( const Vector2& size )
: mDrawable(nullptr),
- mPixelBuffer( Devel::PixelBuffer::New(size.width, size.height, Dali::Pixel::RGBA8888) ),
+ mTexture ( Dali::Texture::New( Dali::TextureType::TEXTURE_2D, Pixel::RGBA8888, size.width, size.height ) ),
mSize(size),
mViewBox(size)
{
return true;
}
+ Dali::Texture GetRasterizedTexture()
+ {
+ return mTexture;
+ }
+
bool Rasterize()
{
return true;
return false;
}
- Devel::PixelBuffer GetPixelBuffer()
- {
- return mPixelBuffer;
- }
-
-
bool SetSize(Vector2 size)
{
mSize = size;
public:
Dali::CanvasRenderer::Drawable* mDrawable;
- Devel::PixelBuffer mPixelBuffer;
+ Dali::Texture mTexture;
Vector2 mSize;
Vector2 mViewBox;
};
return Internal::Adaptor::GetImplementation(*this).Rasterize();
}
-Devel::PixelBuffer CanvasRenderer::GetPixelBuffer()
+Dali::Texture CanvasRenderer::GetRasterizedTexture()
{
- return Internal::Adaptor::GetImplementation(*this).GetPixelBuffer();
+ return Internal::Adaptor::GetImplementation(*this).GetRasterizedTexture();
}
bool CanvasRenderer::AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
+#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
#include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h>
#include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-signals-devel.h>
#include <dali/devel-api/rendering/renderer-devel.h>
attributes.Clear();
attributes.Add( DevelImageVisual::Property::PLAY_RANGE, array );
- DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
+ DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes );
application.SendNotification();
application.Render();
attributes.Clear();
attributes.Add( DevelImageVisual::Property::PLAY_RANGE, array );
- DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
+ DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes );
application.SendNotification();
application.Render();
attributes.Clear();
attributes.Add( DevelImageVisual::Property::PLAY_RANGE, array );
- DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
+ DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes );
application.SendNotification();
application.Render();
attributes.Clear();
attributes.Add( DevelImageVisual::Property::PLAY_RANGE, array );
- DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
+ DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes );
application.SendNotification();
application.Render();
Property::Map attributes;
attributes.Add( DevelImageVisual::Property::PLAY_RANGE, array );
- DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
+ DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes );
DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 3 );
array.PushBack( 4 );
attributes.Add( DevelImageVisual::Property::PLAY_RANGE, array );
- DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
+ DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes );
attributes.Clear();
DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
attributes.Add( DevelImageVisual::Property::PLAY_RANGE, playRange );
attributes.Add( DevelImageVisual::Property::LOOP_COUNT, 5 );
- DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
+ DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes );
application.SendNotification();
application.Render();
attributes.Add( DevelImageVisual::Property::PLAY_RANGE, playRange );
- DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
+ DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes );
application.SendNotification();
application.Render();
attributes.Add( DevelImageVisual::Property::LOOP_COUNT, 10 );
- DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
+ DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes );
application.SendNotification();
application.Render();
// Change stop behavior
attributes.Add( DevelImageVisual::Property::STOP_BEHAVIOR, DevelImageVisual::StopBehavior::LAST_FRAME );
- DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
+ DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes );
attributes.Clear();
attributes.Add( DevelImageVisual::Property::STOP_BEHAVIOR, DevelImageVisual::StopBehavior::CURRENT_FRAME );
attributes.Add( DevelImageVisual::Property::LOOP_COUNT, -1 );
- DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
+ DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes );
attributes.Clear();
// Change stop behavior
attributes.Add( DevelImageVisual::Property::STOP_BEHAVIOR, DevelImageVisual::StopBehavior::CURRENT_FRAME );
- DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
+ DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes );
// Play again
DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
// Change looping mode
attributes.Add( DevelImageVisual::Property::LOOPING_MODE, DevelImageVisual::LoopingMode::RESTART );
- DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
+ DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes );
// Play again
DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
Property::Map attributes;
attributes.Add( DevelImageVisual::Property::STOP_BEHAVIOR, DevelImageVisual::StopBehavior::LAST_FRAME );
- DevelControl::DoAction( actor1, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
- DevelControl::DoAction( actor2, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
+ DevelControl::DoAction( actor1, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes );
+ DevelControl::DoAction( actor2, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes );
DevelControl::DoAction( actor1, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, Property::Map() );
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
#include <dali-toolkit/devel-api/visuals/arc-visual-properties-devel.h>
-#include <dali-toolkit/devel-api/visuals/arc-visual-actions-devel.h>
+#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
#include <dali/devel-api/rendering/renderer-devel.h>
#include "dummy-control.h"
.Add( DevelArcVisual::Property::START_ANGLE, startAngle )
.Add( DevelArcVisual::Property::SWEEP_ANGLE, sweepAngle );
- DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelArcVisual::Action::UPDATE_PROPERTY, attributes );
+ DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes );
application.SendNotification();
application.Render();
END_TEST;
}
-int UtcDaliCanvasViewRasterizeTaskGetBufferSizeP(void)
-{
- ToolkitTestApplication application;
-
- Dali::Toolkit::Internal::CanvasView* dummyInternalCanvasView = new Dali::Toolkit::Internal::CanvasView(Vector2(100,100));
- DALI_TEST_CHECK( dummyInternalCanvasView );
-
- Dali::CanvasRenderer dummyCanvasRenderer = Dali::CanvasRenderer::New(Vector2(100, 100));
- DALI_TEST_CHECK( dummyCanvasRenderer );
-
- IntrusivePtr<Dali::Toolkit::Internal::CanvasRendererRasterizingTask> task = new Dali::Toolkit::Internal::CanvasRendererRasterizingTask(dummyInternalCanvasView, dummyCanvasRenderer);
- DALI_TEST_CHECK( task );
-
- //There is no rasterized buffer.
- DALI_TEST_EQUALS( task->GetBufferSize(), Vector2(0, 0), TEST_LOCATION );
-
- END_TEST;
-}
-
-int UtcDaliCanvasViewRasterizeTaskGetPixelDataP(void)
-{
-
- Dali::Toolkit::Internal::CanvasView* dummyInternalCanvasView = new Dali::Toolkit::Internal::CanvasView(Vector2(100,100));
- DALI_TEST_CHECK( dummyInternalCanvasView );
-
- Dali::CanvasRenderer dummyCanvasRenderer = Dali::CanvasRenderer::New(Vector2(100, 100));
- DALI_TEST_CHECK( dummyCanvasRenderer );
-
- IntrusivePtr<Dali::Toolkit::Internal::CanvasRendererRasterizingTask> task = new Dali::Toolkit::Internal::CanvasRendererRasterizingTask(dummyInternalCanvasView, dummyCanvasRenderer);
- DALI_TEST_CHECK( task );
-
- DALI_TEST_EQUALS( task->GetPixelData(), PixelData(), TEST_LOCATION );
-
- END_TEST;
-}
-
int UtcDaliCanvasViewRasterizeThreadP(void)
{
ToolkitTestApplication application;
{
ToolkitTestApplication application;
- Dali::Toolkit::Internal::CanvasView* dummyInternalCanvasView = new Dali::Toolkit::Internal::CanvasView(Vector2(100,100));
- DALI_TEST_CHECK( dummyInternalCanvasView );
+ Dali::Toolkit::CanvasView canvasView = Dali::Toolkit::CanvasView::New(Vector2(100, 100));
+ Dali::Toolkit::Internal::CanvasView& dummyInternalCanvasView = GetImpl(canvasView);
Dali::CanvasRenderer dummyCanvasRenderer = Dali::CanvasRenderer::New(Vector2(100, 100));
DALI_TEST_CHECK( dummyCanvasRenderer );
- IntrusivePtr<Dali::Toolkit::Internal::CanvasRendererRasterizingTask> task = new Dali::Toolkit::Internal::CanvasRendererRasterizingTask(dummyInternalCanvasView, dummyCanvasRenderer);
+ IntrusivePtr<Dali::Toolkit::Internal::CanvasRendererRasterizingTask> task = new Dali::Toolkit::Internal::CanvasRendererRasterizingTask(&dummyInternalCanvasView, dummyCanvasRenderer);
DALI_TEST_CHECK( task );
Dali::Toolkit::Internal::CanvasViewRasterizeThread *dummyThread = new Dali::Toolkit::Internal::CanvasViewRasterizeThread();
dummyThread->Process(false);
- PixelData pixelData = CreatePixelData( 100, 100 );
+ auto texture = Texture::New( Dali::TextureType::TEXTURE_2D, Pixel::RGBA8888, 100, 100 );
- dummyThread->RasterizationCompletedSignal().Connect(dummyInternalCanvasView, &Dali::Toolkit::Internal::CanvasView::ApplyRasterizedImage);
- dummyThread->RasterizationCompletedSignal().Emit(pixelData);
+ dummyThread->RasterizationCompletedSignal().Connect(&dummyInternalCanvasView, &Dali::Toolkit::Internal::CanvasView::ApplyRasterizedImage);
+ dummyThread->RasterizationCompletedSignal().Emit(texture);
application.SendNotification();
application.Render();
{
}
-int UtcDaliGlViewRegisterGlCallbackN(void)
+int UtcDaliGlViewRegisterGlCallbacksN(void)
{
ToolkitTestApplication application;
- tet_infoline("UtcDaliGlViewRegisterGlCallback");
+ tet_infoline("UtcDaliGlViewRegisterGlCallbacksN");
GlView view;
try
{
- view.RegisterGlCallback(Dali::MakeCallback(glInit), Dali::MakeCallback(glRenderFrame), Dali::MakeCallback(glTerminate));
+ view.RegisterGlCallbacks(Dali::MakeCallback(glInit), Dali::MakeCallback(glRenderFrame), Dali::MakeCallback(glTerminate));
DALI_TEST_CHECK(false);
}
catch(...)
application.GetScene().Add( view );
view.SetRenderingMode(GlView::RenderingMode::CONTINUOUS);
view.SetGraphicsConfig(true, true, 0, GlView::GraphicsApiVersion::GLES_VERSION_2_0);
- view.RegisterGlCallback(Dali::MakeCallback(glInit), Dali::MakeCallback(glRenderFrame), Dali::MakeCallback(glTerminate));
+ view.RegisterGlCallbacks(Dali::MakeCallback(glInit), Dali::MakeCallback(glRenderFrame), Dali::MakeCallback(glTerminate));
view.SetResizeCallback(Dali::MakeCallback(resizeCB));
application.SendNotification();
application.GetScene().Add( view );
view.SetRenderingMode(GlView::RenderingMode::CONTINUOUS);
view.SetGraphicsConfig(true, true, 0, GlView::GraphicsApiVersion::GLES_VERSION_2_0);
- view.RegisterGlCallback(Dali::MakeCallback(glInit), Dali::MakeCallback(glRenderFrame), Dali::MakeCallback(glTerminate));
+ view.RegisterGlCallbacks(Dali::MakeCallback(glInit), Dali::MakeCallback(glRenderFrame), Dali::MakeCallback(glTerminate));
application.SendNotification();
application.Render();
application.GetScene().Add( view );
view.SetGraphicsConfig(true, true, 0, GlView::GraphicsApiVersion::GLES_VERSION_2_0);
- view.RegisterGlCallback(Dali::MakeCallback(glInit), Dali::MakeCallback(glRenderFrame), Dali::MakeCallback(glTerminate));
+ view.RegisterGlCallbacks(Dali::MakeCallback(glInit), Dali::MakeCallback(glRenderFrame), Dali::MakeCallback(glTerminate));
view.SetResizeCallback(Dali::MakeCallback(resizeCB));
view.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
view.SetProperty(Actor::Property::SIZE, Vector2(360.0f, 360.0f));
application.SendNotification();
application.Render();
+ // EMOJI + ZWJ + EMOJI case for coverage.
+ const std::string emojiWithZWJ = "👩‍🔬";
+ label.SetProperty( TextLabel::Property::TEXT, emojiWithZWJ );
+
+ application.SendNotification();
+ application.Render();
+
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;
application.SendNotification();
application.Render(20);
- Transition transition = Transition::New(control1, control2, TimePeriod(-0.1f, -0.1f));
+ Transition transition = Transition::New(control1, control2, true, TimePeriod(-0.1f, -0.1f));
TimePeriod timePeriod = transition.GetTimePeriod();
DALI_TEST_EQUALS(0.0f, timePeriod.durationSeconds, TEST_LOCATION);
DALI_TEST_EQUALS(0.0f, timePeriod.delaySeconds, TEST_LOCATION);
application.SendNotification();
application.Render(20);
- Transition transition = Transition::New(control1, control2, TimePeriod(-0.1f));
+ Transition transition = Transition::New(control1, control2, true, TimePeriod(-0.1f));
TimePeriod timePeriod = transition.GetTimePeriod();
DALI_TEST_EQUALS(0.0f, timePeriod.durationSeconds, TEST_LOCATION);
DALI_TEST_EQUALS(0.0f, timePeriod.delaySeconds, TEST_LOCATION);
application.SendNotification();
application.Render(20);
- Transition transition = Transition::New(control1, control2, TimePeriod(0.5f));
+ Transition transition = Transition::New(control1, control2, true, TimePeriod(0.5f));
TransitionSet transitionSet = TransitionSet::New();
transitionSet.AddTransition(transition);
transitionSet.Play();
END_TEST;
}
+int UtcDaliTransitionBetweenControlPair2(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTransitionBetweenControlPair2 - source target will be transitioned.");
+
+ Vector3 sourcePosition(100, 200, 0);
+ Vector3 sourceSize(150, 150, 0);
+ Vector3 sourceScale(1, 2, 0);
+ Vector4 sourceColor(1.0f, 1.0f, 1.0f, 0.5f);
+ float sourceOpacity(0.5f);
+ float sourceRadius(30.f);
+ float sourceBorderlineWidth(60.0f);
+ Vector4 sourceBorderlineColor(1.0f, 0.0f, 0.0f, 1.0f);
+ float sourceBorderlineOffset(1.f);
+ Vector4 sourceRadiusV4 = Vector4(sourceRadius, sourceRadius, sourceRadius, sourceRadius);
+
+ Vector3 destinationPosition(50, 50, 0);
+ Vector3 destinationSize(120, 120, 0);
+ Vector3 destinationScale(2, 1, 0);
+ Vector4 destinationColor(1.0f, 0.5f, 1.0f, 0.8f);
+ float destinationOpacity(0.8f);
+ float destinationRadius(50.f);
+ float destinationBorderlineWidth(80.0f);
+ Vector4 destinationBorderlineColor(0.5f, 1.0f, 0.5f, 0.3f);
+ float destinationBorderlineOffset(-1.0f);
+ Vector4 destinationRadiusV4 = Vector4(destinationRadius, destinationRadius, destinationRadius, destinationRadius);
+
+ Control control1 = Control::New();
+ control1.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ control1.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ control1.SetProperty(Actor::Property::POSITION, sourcePosition);
+ control1.SetProperty(Actor::Property::SIZE, sourceSize);
+ control1.SetProperty(Actor::Property::SCALE, sourceScale);
+ control1.SetProperty(Actor::Property::COLOR, sourceColor);
+ control1.SetProperty(Actor::Property::OPACITY, sourceOpacity);
+ Property::Map controlProperty1;
+ controlProperty1.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR);
+ controlProperty1.Insert(Toolkit::ColorVisual::Property::MIX_COLOR, Vector4(1.0f, 0.0f, 0.0f, 1.0f));
+ controlProperty1.Insert(Toolkit::DevelVisual::Property::CORNER_RADIUS, sourceRadius);
+ controlProperty1.Insert(Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, sourceBorderlineWidth);
+ controlProperty1.Insert(Toolkit::DevelVisual::Property::BORDERLINE_COLOR, sourceBorderlineColor);
+ controlProperty1.Insert(Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, sourceBorderlineOffset);
+ control1.SetProperty(Toolkit::Control::Property::BACKGROUND, controlProperty1);
+
+ Control control2 = Control::New();
+ control2.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ control2.SetProperty(Actor::Property::ANCHOR_POINT, ParentOrigin::CENTER);
+ control2.SetProperty(Actor::Property::POSITION, destinationPosition);
+ control2.SetProperty(Actor::Property::SIZE, destinationSize);
+ control2.SetProperty(Actor::Property::SCALE, destinationScale);
+ control2.SetProperty(Actor::Property::COLOR, destinationColor);
+ control2.SetProperty(Actor::Property::OPACITY, destinationOpacity);
+ Property::Map controlProperty2;
+ controlProperty2.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR);
+ controlProperty2.Insert(Toolkit::ColorVisual::Property::MIX_COLOR, Vector4(1.0f, 1.0f, 0.0f, 0.5f));
+ controlProperty2.Insert(Toolkit::DevelVisual::Property::CORNER_RADIUS, destinationRadius);
+ controlProperty2.Insert(Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, destinationBorderlineWidth);
+ controlProperty2.Insert(Toolkit::DevelVisual::Property::BORDERLINE_COLOR, destinationBorderlineColor);
+ controlProperty2.Insert(Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, destinationBorderlineOffset);
+ control2.SetProperty(Toolkit::Control::Property::BACKGROUND, controlProperty2);
+
+ DALI_TEST_EQUALS(destinationPosition, control2.GetProperty<Vector3>(Actor::Property::POSITION), TEST_LOCATION);
+ Property::Map backgroundMap = control2.GetProperty<Property::Map>(Toolkit::Control::Property::BACKGROUND);
+ Vector4 cornerRadius = backgroundMap.Find(Toolkit::DevelVisual::Property::CORNER_RADIUS)->Get<Vector4>();
+ DALI_TEST_EQUALS(destinationRadiusV4, cornerRadius, TEST_LOCATION);
+ float borderlineWidth = backgroundMap.Find(Toolkit::DevelVisual::Property::BORDERLINE_WIDTH)->Get<float>();
+ DALI_TEST_EQUALS(destinationBorderlineWidth, borderlineWidth, TEST_LOCATION);
+ Vector4 borderlineColor = backgroundMap.Find(Toolkit::DevelVisual::Property::BORDERLINE_COLOR)->Get<Vector4>();
+ DALI_TEST_EQUALS(destinationBorderlineColor, borderlineColor, TEST_LOCATION);
+ float borderlineOffset = backgroundMap.Find(Toolkit::DevelVisual::Property::BORDERLINE_OFFSET)->Get<float>();
+ DALI_TEST_EQUALS(destinationBorderlineOffset, borderlineOffset, TEST_LOCATION);
+
+ application.GetScene().Add(control1);
+ application.GetScene().Add(control2);
+
+ application.SendNotification();
+ application.Render(20);
+
+ Transition transition = Transition::New(control1, control2, false, TimePeriod(0.5f));
+ TransitionSet transitionSet = TransitionSet::New();
+ transitionSet.AddTransition(transition);
+ transitionSet.Play();
+
+ bool signalReceived(false);
+ TransitionFinishCheck finishCheck(signalReceived);
+ transitionSet.FinishedSignal().Connect(&application, finishCheck);
+
+ application.SendNotification();
+ application.Render(50);
+
+ // We didn't expect the animation to finish yet
+ application.SendNotification();
+ finishCheck.CheckSignalNotReceived();
+
+ DALI_TEST_NOT_EQUALS(destinationPosition, control1.GetCurrentProperty<Vector3>(Actor::Property::POSITION), 0.00001f, TEST_LOCATION);
+ DALI_TEST_EQUALS(1, control1.GetRendererCount(), TEST_LOCATION);
+
+ Dali::Renderer renderer = control1.GetRendererAt(0);
+ Property::Index index = renderer.GetPropertyIndex(DevelVisual::Property::CORNER_RADIUS);
+ cornerRadius = renderer.GetCurrentProperty<Vector4>(index);
+ DALI_TEST_NOT_EQUALS(destinationRadiusV4, cornerRadius, 0.00001f, TEST_LOCATION);
+
+ index = renderer.GetPropertyIndex(DevelVisual::Property::BORDERLINE_WIDTH);
+ borderlineWidth = renderer.GetCurrentProperty<float>(index);
+ DALI_TEST_NOT_EQUALS(destinationBorderlineWidth, borderlineWidth, 0.00001f, TEST_LOCATION);
+
+ index = renderer.GetPropertyIndex(DevelVisual::Property::BORDERLINE_COLOR);
+ borderlineColor = renderer.GetCurrentProperty<Vector4>(index);
+ DALI_TEST_NOT_EQUALS(destinationBorderlineColor, borderlineColor, 0.00001f, TEST_LOCATION);
+
+ index = renderer.GetPropertyIndex(DevelVisual::Property::BORDERLINE_OFFSET);
+ borderlineOffset = renderer.GetCurrentProperty<float>(index);
+ DALI_TEST_NOT_EQUALS(destinationBorderlineOffset, borderlineOffset, 0.00001f, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(700);
+
+ // We did expect the animation to finish
+ application.SendNotification();
+ finishCheck.CheckSignalReceived();
+
+ // After the transition is finished,
+ // every current and renderer propeties of control1 are equal to destination properties.
+ DALI_TEST_EQUALS(destinationPosition, control1.GetCurrentProperty<Vector3>(Actor::Property::POSITION), TEST_LOCATION);
+ DALI_TEST_EQUALS(destinationSize, control1.GetCurrentProperty<Vector3>(Actor::Property::SIZE), TEST_LOCATION);
+ DALI_TEST_EQUALS(destinationScale, control1.GetCurrentProperty<Vector3>(Actor::Property::SCALE), TEST_LOCATION);
+ DALI_TEST_EQUALS(destinationColor, control1.GetCurrentProperty<Vector4>(Actor::Property::COLOR), TEST_LOCATION);
+ DALI_TEST_EQUALS(destinationOpacity, control1.GetCurrentProperty<float>(Actor::Property::OPACITY), TEST_LOCATION);
+
+ DALI_TEST_EQUALS(1, control1.GetRendererCount(), TEST_LOCATION);
+ renderer = control1.GetRendererAt(0);
+ index = renderer.GetPropertyIndex(DevelVisual::Property::CORNER_RADIUS);
+ cornerRadius = renderer.GetCurrentProperty<Vector4>(index);
+ DALI_TEST_EQUALS(destinationRadiusV4, cornerRadius, TEST_LOCATION);
+
+ index = renderer.GetPropertyIndex(DevelVisual::Property::BORDERLINE_WIDTH);
+ borderlineWidth = renderer.GetCurrentProperty<float>(index);
+ DALI_TEST_EQUALS(destinationBorderlineWidth, borderlineWidth, TEST_LOCATION);
+
+ index = renderer.GetPropertyIndex(DevelVisual::Property::BORDERLINE_COLOR);
+ borderlineColor = renderer.GetCurrentProperty<Vector4>(index);
+ DALI_TEST_EQUALS(destinationBorderlineColor, borderlineColor, TEST_LOCATION);
+
+ index = renderer.GetPropertyIndex(DevelVisual::Property::BORDERLINE_OFFSET);
+ borderlineOffset = renderer.GetCurrentProperty<float>(index);
+ DALI_TEST_EQUALS(destinationBorderlineOffset, borderlineOffset, TEST_LOCATION);
+
+ // every actor properties of control1 are returned to the source properties.
+ DALI_TEST_EQUALS(sourcePosition, control1.GetProperty<Vector3>(Actor::Property::POSITION), TEST_LOCATION);
+ DALI_TEST_EQUALS(sourceSize, control1.GetProperty<Vector3>(Actor::Property::SIZE), TEST_LOCATION);
+ DALI_TEST_EQUALS(sourceScale, control1.GetProperty<Vector3>(Actor::Property::SCALE), TEST_LOCATION);
+ DALI_TEST_EQUALS(sourceColor, control1.GetProperty<Vector4>(Actor::Property::COLOR), TEST_LOCATION);
+ DALI_TEST_EQUALS(sourceOpacity, control1.GetProperty<float>(Actor::Property::OPACITY), TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(20);
+
+ // after next update, renderer properties are returned to the source properties.
+ DALI_TEST_EQUALS(1, control1.GetRendererCount(), TEST_LOCATION);
+ renderer = control1.GetRendererAt(0);
+ index = renderer.GetPropertyIndex(DevelVisual::Property::CORNER_RADIUS);
+ cornerRadius = renderer.GetCurrentProperty<Vector4>(index);
+ DALI_TEST_EQUALS(sourceRadiusV4, cornerRadius, TEST_LOCATION);
+
+ index = renderer.GetPropertyIndex(DevelVisual::Property::BORDERLINE_WIDTH);
+ borderlineWidth = renderer.GetCurrentProperty<float>(index);
+ DALI_TEST_EQUALS(sourceBorderlineWidth, borderlineWidth, TEST_LOCATION);
+
+ index = renderer.GetPropertyIndex(DevelVisual::Property::BORDERLINE_COLOR);
+ borderlineColor = renderer.GetCurrentProperty<Vector4>(index);
+ DALI_TEST_EQUALS(sourceBorderlineColor, borderlineColor, TEST_LOCATION);
+
+ index = renderer.GetPropertyIndex(DevelVisual::Property::BORDERLINE_OFFSET);
+ borderlineOffset = renderer.GetCurrentProperty<float>(index);
+ DALI_TEST_EQUALS(sourceBorderlineOffset, borderlineOffset, TEST_LOCATION);
+
+ END_TEST;
+}
+
int UtcDaliTransitionBetweenControlPairWithoutEmptySourceBackground(void)
{
ToolkitTestApplication application;
application.SendNotification();
application.Render(20);
- Transition transition = Transition::New(control1, control2, TimePeriod(0.5f));
+ Transition transition = Transition::New(control1, control2, true, TimePeriod(0.5f));
TransitionSet transitionSet = TransitionSet::New();
transitionSet.AddTransition(transition);
transitionSet.Play();
Vector3 startWorldPosition = control1.GetProperty<Vector3>(Actor::Property::WORLD_POSITION);
Vector3 finishWorldPosition = control2.GetProperty<Vector3>(Actor::Property::WORLD_POSITION);
- Transition transition = Transition::New(control1, control2, TimePeriod(0.5f));
+ Transition transition = Transition::New(control1, control2, true, TimePeriod(0.5f));
TransitionSet transitionSet = TransitionSet::New();
transitionSet.AddTransition(transition);
transitionSet.Play();
Vector3 startWorldPosition = control1.GetProperty<Vector3>(Actor::Property::WORLD_POSITION);
Vector3 finishWorldPosition = control2.GetProperty<Vector3>(Actor::Property::WORLD_POSITION);
- Transition transition = Transition::New(control1, control2, TimePeriod(0.5f, 0.5f));
+ Transition transition = Transition::New(control1, control2, true, TimePeriod(0.5f, 0.5f));
TransitionSet transitionSet = TransitionSet::New();
transitionSet.AddTransition(transition);
transitionSet.Play();
application.SendNotification();
application.Render(20);
- Transition transition = Transition::New(control1, control2, TimePeriod(0.5f));
+ Transition transition = Transition::New(control1, control2, true, TimePeriod(0.5f));
TransitionSet transitionSet = TransitionSet::New();
transitionSet.AddTransition(transition);
transitionSet.Play();
application.SendNotification();
application.Render(20);
- Transition transition = Transition::New(control1, control2, TimePeriod(0.5f));
+ Transition transition = Transition::New(control1, control2, true, TimePeriod(0.5f));
transition.TransitionWithChild(true);
TransitionSet transitionSet = TransitionSet::New();
transitionSet.AddTransition(transition);
control3.SetProperty(Actor::Property::INHERIT_ORIENTATION, true);
control3.SetProperty(Actor::Property::INHERIT_SCALE, true);
- transition = Transition::New(control1, control3, TimePeriod(0.5f));
+ transition = Transition::New(control1, control3, true, TimePeriod(0.5f));
transitionSet = TransitionSet::New();
transitionSet.AddTransition(transition);
transitionSet.Play();
bool signalReceived(false);
TransitionFinishCheck finishCheck(signalReceived);
- transition = Transition::New(control1, control3, TimePeriod(0.5f));
+ transition = Transition::New(control1, control3, true, TimePeriod(0.5f));
transitionSet = TransitionSet::New();
transitionSet.AddTransition(transition);
transitionSet.Play();
bool signalReceived(false);
TransitionFinishCheck finishCheck(signalReceived);
- transition = Transition::New(control1, control3, TimePeriod(0.5f));
+ transition = Transition::New(control1, control3, true, TimePeriod(0.5f));
transitionSet = TransitionSet::New();
transitionSet.AddTransition(transition);
transitionSet.Play();
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;
+}
parent->ScrollToChild(child->Self());
}
- child = parent;
parent = dynamic_cast<Toolkit::DevelControl::AccessibleImpl*>(parent->GetParent());
}
}
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();
/**
- * @brief Makes sure that a given child of this container (e.g. ItemView) is visible
+ * @brief Makes sure that a given child (descendant) of this container (e.g. ItemView) is visible
* @return false if scrolling is not supported or child is already visible
*/
virtual bool ScrollToChild(Actor child);
return controlDataImpl.GetVisualProperty(index, visualPropertyKey);
}
-void CreateTransitions(Control control, Dali::Animation& animation, Dali::Toolkit::Control source, AlphaFunction alphaFunction, TimePeriod timePeriod)
-{
- if(animation)
- {
- // make visual transition of control visual.
- Internal::Control& internalControl = Toolkit::Internal::GetImplementation(control);
- Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get(internalControl);
- controlDataImpl.MakeVisualTransition(animation, source, Toolkit::Control::Property::BACKGROUND, alphaFunction, timePeriod);
- controlDataImpl.MakeVisualTransition(animation, source, Toolkit::DevelControl::Property::SHADOW, alphaFunction, timePeriod);
- internalControl.OnCreateTransitions(animation, source, alphaFunction, timePeriod);
- }
-}
-
static Toolkit::Internal::Control::Impl* GetControlImplementation(Dali::Actor actor)
{
Dali::Toolkit::Control control = Toolkit::Control::DownCast(actor);
DALI_TOOLKIT_API Dali::Property GetVisualProperty(Control control, Dali::Property::Index index, Dali::Property::Key visualPropertyKey);
/**
- * @brief Retrieve visual/renderer property animation between this Control and source control.
- * Input animation must be created before this method called.
- * And the animations between this method created are added the input animation.
- * This method generates visual/renderer property animation but not creates Actor property animation.
- *
- * @param[in] control The control
- * @param[in] animation generated animation
- * @param[in] source source control of the animation.
- * @param[in] alphaFunction AlphaFunction of the animation
- * @param[in] timePeriod TimePeriod of the animation
- */
-DALI_TOOLKIT_API void CreateTransitions(Control control, Dali::Animation& animation, Dali::Toolkit::Control source, AlphaFunction alphaFunction, TimePeriod timePeriod);
-
-/**
* @brief The signal is emmited as a succession of "activate" signal send by accessibility client.
* @return The signal to connect to
*/
SET( devel_api_header_files
${devel_api_src_dir}/direction-enums.h
${devel_api_src_dir}/toolkit-property-index-ranges.h
+ ${devel_api_src_dir}/toolkit-action-index-ranges.h
)
SET( devel_api_accessibility-manager_header_files
${devel_api_src_dir}/visuals/animated-image-visual-actions-devel.h
${devel_api_src_dir}/visuals/animated-vector-image-visual-actions-devel.h
${devel_api_src_dir}/visuals/animated-vector-image-visual-signals-devel.h
- ${devel_api_src_dir}/visuals/arc-visual-actions-devel.h
${devel_api_src_dir}/visuals/arc-visual-properties-devel.h
- ${devel_api_src_dir}/visuals/color-visual-actions-devel.h
${devel_api_src_dir}/visuals/color-visual-properties-devel.h
${devel_api_src_dir}/visuals/image-visual-properties-devel.h
${devel_api_src_dir}/visuals/image-visual-actions-devel.h
${devel_api_src_dir}/visuals/text-visual-properties-devel.h
+ ${devel_api_src_dir}/visuals/visual-actions-devel.h
${devel_api_src_dir}/visuals/visual-properties-devel.h
)
--- /dev/null
+#ifndef DALI_TOOLKIT_ACTION_INDEX_RANGES_H
+#define DALI_TOOLKIT_ACTION_INDEX_RANGES_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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/property-index-ranges.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+/**
+ * @addtogroup dali_toolkit_controls
+ * @{
+ */
+
+/**
+ * @brief Enumeration for the start and end action ranges.
+ */
+enum ActionRanges
+{
+ VISUAL_ACTION_BASE_START_INDEX = 0, ///< Visual Action Base Start Index.
+ VISUAL_ACTION_BASE_END_INDEX = VISUAL_ACTION_BASE_START_INDEX + 100, ///< Visual Action Base End Index.
+ VISUAL_ACTION_START_INDEX = VISUAL_ACTION_BASE_END_INDEX + 1, ///< Visual Action Start Index.
+ VISUAL_ACTION_END_INDEX = VISUAL_ACTION_START_INDEX + 100000, ///< Visual Action End Index.
+};
+
+/**
+ * @}
+ */
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_ACTION_INDEX_RANGES_H
#define DALI_TOOLKIT_DEVEL_API_VISUALS_ANIMATED_IMAGE_VISUAL_ACTIONS_DEVEL_H
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * 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.
* limitations under the License.
*
*/
+#include <dali-toolkit/devel-api/toolkit-action-index-ranges.h>
namespace Dali
{
*/
enum Type
{
- PLAY, ///< Play the animated GIF. This is also Default playback mode.
- PAUSE, ///< Pause the animated GIF.
- STOP, ///< Stop the animated GIF.
- JUMP_TO ///< Jump to the specified frame. Property::INTEGER value should be passed.
+ PLAY = VISUAL_ACTION_START_INDEX, ///< Play the animated GIF. This is also Default playback mode.
+ PAUSE, ///< Pause the animated GIF.
+ STOP, ///< Stop the animated GIF.
+ JUMP_TO ///< Jump to the specified frame. Property::INTEGER value should be passed.
};
} // namespace Action
* limitations under the License.
*
*/
+#include <dali-toolkit/devel-api/toolkit-action-index-ranges.h>
namespace Dali
{
*/
enum Type
{
- PLAY, ///< Play the animated vector image.
- PAUSE, ///< Pause the animated vector image.
- STOP, ///< Stop the animated vector image. This is also Default playback mode.
- JUMP_TO, ///< Jump to the specified frame. Property::INTEGER value should be passed.
- UPDATE_PROPERTY ///< Update the properties of the animated vector image.
+ PLAY = VISUAL_ACTION_START_INDEX, ///< Play the animated vector image.
+ PAUSE, ///< Pause the animated vector image.
+ STOP, ///< Stop the animated vector image. This is also Default playback mode.
+ JUMP_TO, ///< Jump to the specified frame. Property::INTEGER value should be passed.
};
} // namespace Action
+++ /dev/null
-#ifndef DALI_TOOLKIT_DEVEL_API_VISUALS_ARC_VISUAL_ACTIONS_DEVEL_H
-#define DALI_TOOLKIT_DEVEL_API_VISUALS_ARC_VISUAL_ACTIONS_DEVEL_H
-
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-namespace Dali
-{
-namespace Toolkit
-{
-namespace DevelArcVisual
-{
-/**
- * @brief Actions that the arc visual can perform. These actions are called through the Visual::Base::DoAction API.
- */
-namespace Action
-{
-/**
- * @brief The available actions for this visual
- */
-enum Type
-{
- /**
- * @brief Update the properties of the visual.
- * @note DevelArcVisual::Property::THICKNESS, DevelArcVisual::Property::START_ANGLE and DevelArcVisual::Property::SWEEP_ANGLE can be updated.
- */
- UPDATE_PROPERTY = 0
-};
-
-} // namespace Action
-
-} // namespace DevelArcVisual
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // DALI_TOOLKIT_DEVEL_API_VISUALS_ARC_VISUAL_ACTIONS_DEVEL_H
#define DALI_TOOLKIT_DEVEL_API_VISUALS_IMAGE_VISUAL_ACTIONS_DEVEL_H
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * 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.
* limitations under the License.
*
*/
+#include <dali-toolkit/devel-api/toolkit-action-index-ranges.h>
namespace Dali
{
*/
enum Type
{
- RELOAD = 0 ///< Force reloading of the image, all visuals using this image will get the latest one.
+ RELOAD = VISUAL_ACTION_START_INDEX ///< Force reloading of the image, all visuals using this image will get the latest one.
};
} // namespace Action
-#ifndef DALI_TOOLKIT_DEVEL_API_VISUALS_COLOR_VISUAL_ACTIONS_DEVEL_H
-#define DALI_TOOLKIT_DEVEL_API_VISUALS_COLOR_VISUAL_ACTIONS_DEVEL_H
+#ifndef DALI_TOOLKIT_DEVEL_API_VISUALS_VISUAL_ACTIONS_DEVEL_H
+#define DALI_TOOLKIT_DEVEL_API_VISUALS_VISUAL_ACTIONS_DEVEL_H
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * 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.
*
*/
+// EXTERNAL INCLUDES
+#include <dali-toolkit/devel-api/toolkit-action-index-ranges.h>
+
namespace Dali
{
namespace Toolkit
{
-namespace DevelColorVisual
+namespace DevelVisual
{
+
/**
- * @brief Actions that the color visual can perform. These actions are called through the Visual::Base::DoAction API.
+ * @brief Actions that the visual can perform. These actions are called through the Visual::Base::DoAction API.
*/
namespace Action
{
/**
* @brief Update the properties of the visual.
*/
- UPDATE_PROPERTY = 0
+ UPDATE_PROPERTY = VISUAL_ACTION_BASE_START_INDEX
};
} // namespace Action
-} // namespace DevelColorVisual
+} // namespace DevelVisual
} // namespace Toolkit
} // namespace Dali
-#endif // DALI_TOOLKIT_DEVEL_API_VISUALS_COLOR_VISUAL_ACTIONS_DEVEL_H
+#endif // DALI_TOOLKIT_DEVEL_API_VISUALS_VISUAL_ACTIONS_DEVEL_H
#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>
}
}
-void CanvasView::ApplyRasterizedImage(PixelData rasterizedPixelData)
+void CanvasView::ApplyRasterizedImage(Texture rasterizedTexture)
{
- if(rasterizedPixelData)
+ if (rasterizedTexture && rasterizedTexture.GetWidth() != 0 && rasterizedTexture.GetHeight() != 0)
{
- auto rasterizedPixelDataWidth = rasterizedPixelData.GetWidth();
- auto rasterizedPixelDataHeight = rasterizedPixelData.GetHeight();
-
- if(rasterizedPixelDataWidth > 0 && rasterizedPixelDataHeight > 0)
+ if(!mTextureSet)
{
- if(!mTexture || mTexture.GetWidth() != rasterizedPixelDataWidth || mTexture.GetHeight() != rasterizedPixelDataHeight)
- {
- mTexture = Texture::New(TextureType::TEXTURE_2D, rasterizedPixelData.GetPixelFormat(), rasterizedPixelDataWidth, rasterizedPixelDataHeight);
- mTexture.Upload(rasterizedPixelData);
+ std::string fragmentShader = SHADER_CANVAS_VIEW_FRAG.data();
+ DevelTexture::ApplyNativeFragmentShader(rasterizedTexture, fragmentShader);
- if(!mTextureSet)
- {
- mTextureSet = TextureSet::New();
- Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
- Shader shader = Shader::New(SHADER_CANVAS_VIEW_VERT, SHADER_CANVAS_VIEW_FRAG);
- Renderer renderer = Renderer::New(geometry, shader);
- renderer.SetTextures(mTextureSet);
- renderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true);
-
- Actor actor = Self();
- if(actor)
- {
- actor.AddRenderer(renderer);
- }
- }
- mTextureSet.SetTexture(0, mTexture);
- }
- else
- {
- //Update texture
- mTexture.Upload(rasterizedPixelData);
- }
+ mTextureSet = TextureSet::New();
+ Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
+ 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);
}
+ mTextureSet.SetTexture(0, rasterizedTexture);
}
//If there are accumulated changes to CanvasRenderer during Rasterize, Rasterize once again.
/**
* @bried Apply the rasterized image to the canvas view
*
- * @param[in] rasterizedPixelData The pixel buffer with the rasterized pixels
+ * @param[in] rasterizedTexture The texture with the rasterized pixels
*/
- void ApplyRasterizedImage(PixelData rasterizedPixelData);
+ void ApplyRasterizedImage(Texture rasterizedTexture);
private:
CanvasView(const CanvasView&) = delete;
CanvasRendererRasterizingTask::CanvasRendererRasterizingTask(CanvasView* canvasView, CanvasRenderer canvasRenderer)
: mCanvasView(canvasView),
mCanvasRenderer(canvasRenderer),
- mPixelData(PixelData()),
- mBufferSize(0, 0)
+ mRasterizedTexture()
{
}
{
if(mCanvasRenderer && mCanvasRenderer.Rasterize())
{
- Devel::PixelBuffer pixbuf = mCanvasRenderer.GetPixelBuffer();
- auto width = pixbuf.GetWidth();
- auto height = pixbuf.GetHeight();
- if(width > 0 && height > 0)
- {
- mBufferSize.width = width;
- mBufferSize.height = height;
-
- mPixelData = Devel::PixelBuffer::Convert(pixbuf);
- return true;
- }
+ return true;
}
return false;
}
return mCanvasView.Get();
}
-PixelData CanvasRendererRasterizingTask::GetPixelData() const
-{
- return mPixelData;
-}
-
-Vector2 CanvasRendererRasterizingTask::GetBufferSize() const
+Texture CanvasRendererRasterizingTask::GetRasterizedTexture()
{
- return mBufferSize;
+ return mCanvasRenderer.GetRasterizedTexture();
}
CanvasViewRasterizeThread::CanvasViewRasterizeThread()
{
while(CanvasRendererRasterizingTaskPtr task = NextCompletedTask())
{
- RasterizationCompletedSignal().Emit(task->GetPixelData());
+ RasterizationCompletedSignal().Emit(task->GetRasterizedTexture()); // Here texture get
}
UnregisterProcessor();
#include <dali/devel-api/threading/thread.h>
#include <dali/integration-api/adaptor-framework/log-factory-interface.h>
#include <dali/public-api/common/intrusive-ptr.h>
-#include <dali/public-api/images/pixel-data.h>
#include <dali/public-api/object/ref-object.h>
#include <dali/public-api/rendering/texture-set.h>
#include <memory>
/**
* Get the rasterization result.
- * @return The pixel data with the rasterized pixels.
+ * @return The texture with the rasterized pixels.
*/
- PixelData GetPixelData() const;
-
- /**
- * Get size of rasterization result.
- * @return The size of the pixel data.
- */
- Vector2 GetBufferSize() const;
+ Texture GetRasterizedTexture();
private:
// Undefined
private:
CanvasViewPtr mCanvasView;
CanvasRenderer mCanvasRenderer;
- PixelData mPixelData;
- Vector2 mBufferSize;
+ Texture mRasterizedTexture;
};
/**
{
public:
/// @brief ApplyRasterizedImage Event signal type
- using RasterizationCompletedSignalType = Signal<void(PixelData)>;
+ using RasterizationCompletedSignalType = Signal<void(Texture)>;
public:
/**
#include <limits>
// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
#include <dali-toolkit/devel-api/asset-manager/asset-manager.h>
#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
mNeedToEmitResourceReady(false),
mDispatchKeyEvents(true)
{
- Dali::Accessibility::Accessible::RegisterControlAccessibilityGetter(
+ Dali::Accessibility::Accessible::RegisterExternalAccessibleGetter(
[](Dali::Actor actor) -> Dali::Accessibility::Accessible* {
return Control::Impl::GetAccessibilityObject(actor);
});
return Dali::Property(handle, Property::INVALID_INDEX);
}
-void Control::Impl::MakeVisualTransition(Dali::Animation& animation, Dali::Toolkit::Control source, Dali::Property::Index visualIndex, AlphaFunction alphaFunction, TimePeriod timePeriod)
+void Control::Impl::CreateTransitions(std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& sourceProperties,
+ std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& destinationProperties,
+ Dali::Toolkit::Control source, Dali::Toolkit::Control destination)
{
- Dali::Toolkit::Control sourceHandle = Dali::Toolkit::Control::DownCast(source);
- Property::Map sourceMap = sourceHandle.GetProperty<Property::Map>(visualIndex);
- Dali::Toolkit::Control destinationHandle = Dali::Toolkit::Control::DownCast(mControlImpl.Self());
- Property::Map destinationMap = destinationHandle.GetProperty<Property::Map>(visualIndex);
-
- Vector4 mixColor(1.0f, 1.0f, 1.0f, 1.0f);
- Vector4 cornerRadius(0.0f, 0.0f, 0.0f, 0.0f);
- float borderlineWidth(0.0f);
- Vector4 borderlineColor(0.0f, 0.0f, 0.0f, 1.0f);
- float borderlineOffset(0.0f);
-
- if(!destinationMap.Empty())
+ // Retrieves background properties to be transitioned.
+ Dali::Property::Map backgroundSourcePropertyMap, backgroundDestinationPropertyMap;
+ mControlImpl.MakeVisualTransition(backgroundSourcePropertyMap, backgroundDestinationPropertyMap, source, destination, Toolkit::Control::Property::BACKGROUND);
+ if(backgroundSourcePropertyMap.Count() > 0)
{
- static auto findValueVector4 = [](const Property::Map& map, Property::Index index, const Vector4& defaultValue = Vector4()) -> Vector4 {
- Property::Value* propertyValue = map.Find(index);
- if(propertyValue)
- {
- return propertyValue->Get<Vector4>();
- }
- return defaultValue;
- };
-
- static auto findValueFloat = [](const Property::Map& map, Property::Index index, const float& defaultValue = 0.0f) -> float {
- Property::Value* propertyValue = map.Find(index);
- if(propertyValue)
- {
- return propertyValue->Get<float>();
- }
- return defaultValue;
- };
-
- mixColor = findValueVector4(destinationMap, Dali::Toolkit::Visual::Property::MIX_COLOR, mixColor);
- cornerRadius = findValueVector4(destinationMap, Toolkit::DevelVisual::Property::CORNER_RADIUS, cornerRadius);
- borderlineWidth = findValueFloat(destinationMap, Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, borderlineWidth);
- borderlineColor = findValueVector4(destinationMap, Toolkit::DevelVisual::Property::BORDERLINE_COLOR, borderlineColor);
- borderlineOffset = findValueFloat(destinationMap, Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, borderlineOffset);
-
- if(sourceMap.Empty())
- {
- sourceMap.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR);
- sourceMap.Insert(Dali::Toolkit::Visual::Property::MIX_COLOR, Color::TRANSPARENT);
- sourceMap.Insert(Toolkit::DevelVisual::Property::CORNER_RADIUS, cornerRadius);
- sourceMap.Insert(Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, borderlineWidth);
- sourceMap.Insert(Toolkit::DevelVisual::Property::BORDERLINE_COLOR, borderlineColor);
- sourceMap.Insert(Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, borderlineOffset);
- }
-
- Vector4 sourceMixColor = findValueVector4(sourceMap, Dali::Toolkit::Visual::Property::MIX_COLOR, mixColor);
- Vector4 sourceCornerRadius = findValueVector4(sourceMap, Toolkit::DevelVisual::Property::CORNER_RADIUS, cornerRadius);
- float sourceBorderlineWidth = findValueFloat(sourceMap, Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, borderlineWidth);
- Vector4 sourceBorderlineColor = findValueVector4(sourceMap, Toolkit::DevelVisual::Property::BORDERLINE_COLOR, borderlineColor);
- float sourceBorderlineOffset = findValueFloat(sourceMap, Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, borderlineOffset);
-
- std::vector<Dali::Property> properties;
- std::vector<std::pair<Property::Value, Property::Value>> values;
-
- if(Vector3(sourceMixColor) != Vector3(mixColor))
- {
- properties.push_back(GetVisualProperty(visualIndex, Dali::Toolkit::Visual::Property::MIX_COLOR));
- values.push_back(std::make_pair(Vector3(sourceMixColor), Vector3(mixColor)));
- }
-
- if(std::abs(sourceMixColor.a - mixColor.a) > Math::MACHINE_EPSILON_1)
- {
- properties.push_back(GetVisualProperty(visualIndex, Dali::Toolkit::Visual::Property::OPACITY));
- values.push_back(std::make_pair(sourceMixColor.a, mixColor.a));
- }
-
- if(sourceCornerRadius != cornerRadius)
- {
- properties.push_back(GetVisualProperty(visualIndex, Dali::Toolkit::DevelVisual::Property::CORNER_RADIUS));
- values.push_back(std::make_pair(sourceCornerRadius, cornerRadius));
- }
+ sourceProperties.push_back(std::pair<Dali::Property::Index, Dali::Property::Map>(Toolkit::Control::Property::BACKGROUND, backgroundSourcePropertyMap));
+ destinationProperties.push_back(std::pair<Dali::Property::Index, Dali::Property::Map>(Toolkit::Control::Property::BACKGROUND, backgroundDestinationPropertyMap));
+ }
- if(sourceBorderlineWidth != borderlineWidth)
- {
- properties.push_back(GetVisualProperty(visualIndex, Dali::Toolkit::DevelVisual::Property::BORDERLINE_WIDTH));
- values.push_back(std::make_pair(sourceBorderlineWidth, borderlineWidth));
- }
+ // Retrieves shadow properties to be transitioned.
+ Dali::Property::Map shadowSourcePropertyMap, shadowDestinationPropertyMap;
+ mControlImpl.MakeVisualTransition(shadowSourcePropertyMap, shadowDestinationPropertyMap, source, destination, Toolkit::DevelControl::Property::SHADOW);
+ if(shadowSourcePropertyMap.Count() > 0)
+ {
+ sourceProperties.push_back(std::pair<Dali::Property::Index, Dali::Property::Map>(Toolkit::DevelControl::Property::SHADOW, shadowSourcePropertyMap));
+ destinationProperties.push_back(std::pair<Dali::Property::Index, Dali::Property::Map>(Toolkit::DevelControl::Property::SHADOW, shadowDestinationPropertyMap));
+ }
- if(sourceBorderlineColor != borderlineColor)
- {
- properties.push_back(GetVisualProperty(visualIndex, Dali::Toolkit::DevelVisual::Property::BORDERLINE_COLOR));
- values.push_back(std::make_pair(sourceBorderlineColor, borderlineColor));
- }
+ // Retrieves transition from inherited class.
+ mControlImpl.OnCreateTransitions(sourceProperties, destinationProperties, source, destination);
+}
- if(sourceBorderlineOffset != borderlineOffset)
+void Control::Impl::UpdateVisualProperties(const std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& properties)
+{
+ for(auto&& data : properties)
+ {
+ if(data.first == Toolkit::Control::Property::BACKGROUND)
{
- properties.push_back(GetVisualProperty(visualIndex, Dali::Toolkit::DevelVisual::Property::BORDERLINE_OFFSET));
- values.push_back(std::make_pair(sourceBorderlineOffset, borderlineOffset));
+ DoAction(Toolkit::Control::Property::BACKGROUND, DevelVisual::Action::UPDATE_PROPERTY, data.second);
}
-
- for(uint32_t i = 0; i < properties.size(); ++i)
+ else if(data.first == Toolkit::DevelControl::Property::SHADOW)
{
- if(timePeriod.delaySeconds > 0.0f)
- {
- Dali::KeyFrames initialKeyframes = Dali::KeyFrames::New();
- initialKeyframes.Add(0.0f, values[i].first);
- initialKeyframes.Add(1.0f, values[i].first);
- animation.AnimateBetween(properties[i], initialKeyframes, TimePeriod(timePeriod.delaySeconds));
- }
- Dali::KeyFrames keyframes = Dali::KeyFrames::New();
- keyframes.Add(0.0f, values[i].first);
- keyframes.Add(1.0f, values[i].second);
- animation.AnimateBetween(properties[i], keyframes, alphaFunction, timePeriod);
+ DoAction(Toolkit::DevelControl::Property::SHADOW, DevelVisual::Action::UPDATE_PROPERTY, data.second);
}
}
+ mControlImpl.OnUpdateVisualProperties(properties);
}
void Control::Impl::EmitResourceReadySignal()
Dali::Property GetVisualProperty(Dali::Property::Index index, Dali::Property::Key visualPropertyKey);
/**
- * @brief Make visual transition from source control to this control about specific Property::Index
- * If both of source and this control have Property::Index property, than create animation between them.
+ * @brief Retrieves source and destination visual properties for the Transition of this Control.
+ * The properties of this Control will be transitioned from the propeties of source Control to that of destination control.
+ * If a property value is different between source and destination Control,
+ * the property information of each Control will be included in sourceProperties and destinationProperties.
*
- * @param[in] animation Return animation from source to this control.
- * @param[in] source Source control to be used property animation.
- * @param[in] visualIndex Property::Index to make animation.
- * @param[in] alphaFunction alpha function of the animation.
- * @param[in] timePeriod time period of the animation.
+ * @param[out] sourceProperties Source property list to be applied on this Control.
+ * @param[out] destinationProperties Destination property list to be applied on this Control.
+ * @param[in] source Source control of the animation.
+ * @param[in] destination Destination control of the animation.
+ *
+ * @note This method do not handle Actor properties.
+ * And the size and order of the sourceProperties and destinationProperties must be synchronized.
+ *
+ * This method triggers Control::OnCreateTransition().
+ */
+ void CreateTransitions(std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& sourceProperties,
+ std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& destinationProperties,
+ Dali::Toolkit::Control source, Dali::Toolkit::Control destination);
+
+ /**
+ * @brief Update visual properties.
+ * @param[in] properties Property list to be used to update visual properties of this Control.
+ *
+ * @note This method triggers Control::OnUpdateVisualProperties().
*/
- void MakeVisualTransition(Dali::Animation& animation, Dali::Toolkit::Control source, Dali::Property::Index visualIndex, AlphaFunction alphaFunction, TimePeriod timePeriod);
+ void UpdateVisualProperties(const std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& properties);
/**
* @brief Gets the current control's accessible object.
// currently not called from code so compiler will optimize these away, kept here for future debugging
#define FLEX_CONTAINER_TAG "DALI Toolkit::FlexContainer "
-#define FC_LOG(fmt, args, ...) Debug::LogMessage(Debug::DebugInfo, FLEX_CONTAINER_TAG fmt, ##args)
+#define FC_LOG(fmt, args, ...) Debug::LogMessageWithFunctionLine(Debug::DebugInfo, FLEX_CONTAINER_TAG fmt, ##args)
// #define FLEX_CONTAINER_DEBUG 1
#if defined(FLEX_CONTAINER_DEBUG)
}
}
-void GlView::RegisterGlCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
+void GlView::RegisterGlCallbacks(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
{
if(mRenderThread)
{
- mRenderThread->RegisterGlCallback(initCallback, renderFrameCallback, terminateCallback);
+ mRenderThread->RegisterGlCallbacks(initCallback, renderFrameCallback, terminateCallback);
}
}
GlView(Dali::Toolkit::GlView::ColorFormat colorFormat);
/**
- * @copydoc Dali::Toolkit::GlView::RegisterGlCallback()
+ * @copydoc Dali::Toolkit::GlView::RegisterGlCallbacks()
*/
- void RegisterGlCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback);
+ void RegisterGlCallbacks(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback);
/**
* @copydoc Dali::Toolkit::GlView::SetResizeCallback()
}
}
-void GlViewRenderThread::RegisterGlCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
+void GlViewRenderThread::RegisterGlCallbacks(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
{
if(!mGlInitCallback && !mGlRenderFrameCallback && !mGlTerminateCallback)
{
virtual ~GlViewRenderThread();
/**
- * @copydoc Dali::Toolkit::GlView::RegisterGlCallback()
+ * @copydoc Dali::Toolkit::GlView::RegisterGlCallbacks()
*/
- void RegisterGlCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback);
+ void RegisterGlCallbacks(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback);
/**
* @copydoc Dali::Toolkit::GlView::SetResizeCallback()
#include <dali/public-api/object/type-registry.h>
// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
}
}
-void ImageView::OnCreateTransitions(Dali::Animation& animation, Dali::Toolkit::Control source, AlphaFunction alphaFunction, TimePeriod timePeriod)
+void ImageView::OnCreateTransitions(std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& sourceProperties,
+ std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& destinationProperties,
+ Dali::Toolkit::Control source,
+ Dali::Toolkit::Control destination)
{
- Dali::Toolkit::ImageView destinationHandle = Toolkit::ImageView(GetOwner());
- Toolkit::Visual::Base destinationVisual = DevelControl::GetVisual(GetImplementation(destinationHandle), Toolkit::ImageView::Property::IMAGE);
- Property::Map destinationMap;
-
- if(!destinationVisual)
- {
- return;
- }
-
- destinationVisual.CreatePropertyMap(destinationMap);
-
- static auto findValueVector4 = [](const Property::Map& map, Property::Index index, const Vector4& defaultValue = Vector4()) -> Vector4 {
- Property::Value* propertyValue = map.Find(index);
- if(propertyValue)
- {
- return propertyValue->Get<Vector4>();
- }
- return defaultValue;
- };
-
- static auto findValueFloat = [](const Property::Map& map, Property::Index index, const float& defaultValue = 0.0f) -> float {
- Property::Value* propertyValue = map.Find(index);
- if(propertyValue)
- {
- return propertyValue->Get<float>();
- }
- return defaultValue;
- };
-
- Vector4 sourceMixColor(0.0f, 0.0f, 0.0f, 0.0f);
- Vector4 sourceCornerRadius(0.0f, 0.0f, 0.0f, 0.0f);
- float sourceBorderlineWidth(0.0f);
- Vector4 sourceBorderlineColor(0.0f, 0.0f, 0.0f, 1.0f);
- float sourceBorderlineOffset(0.0f);
- Vector4 destinationMixColor = findValueVector4(destinationMap, Dali::Toolkit::Visual::Property::MIX_COLOR, sourceMixColor);
- Vector4 destinationCornerRadius = findValueVector4(destinationMap, Toolkit::DevelVisual::Property::CORNER_RADIUS, sourceCornerRadius);
- float destinationBorderlineWidth = findValueFloat(destinationMap, Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, sourceBorderlineWidth);
- Vector4 destinationBorderlineColor = findValueVector4(destinationMap, Toolkit::DevelVisual::Property::BORDERLINE_COLOR, sourceBorderlineColor);
- float destinationBorderlineOffset = findValueFloat(destinationMap, Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, sourceBorderlineOffset);
-
- Dali::Toolkit::ImageView sourceHandle = Dali::Toolkit::ImageView::DownCast(source);
- Toolkit::Visual::Base sourceVisual;
- Property::Map sourceMap;
-
- if(sourceHandle)
- {
- sourceVisual = DevelControl::GetVisual(GetImplementation(sourceHandle), Toolkit::ImageView::Property::IMAGE);
- }
-
- if(sourceVisual)
+ // Retrieves image properties to be transitioned.
+ Dali::Property::Map imageSourcePropertyMap, imageDestinationPropertyMap;
+ MakeVisualTransition(imageSourcePropertyMap, imageDestinationPropertyMap, source, destination, Toolkit::ImageView::Property::IMAGE);
+ if(imageSourcePropertyMap.Count() > 0)
{
- sourceVisual.CreatePropertyMap(sourceMap);
- sourceMixColor = findValueVector4(sourceMap, Dali::Toolkit::Visual::Property::MIX_COLOR, sourceMixColor);
- sourceCornerRadius = findValueVector4(sourceMap, Toolkit::DevelVisual::Property::CORNER_RADIUS, sourceCornerRadius);
- sourceBorderlineWidth = findValueFloat(sourceMap, Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, sourceBorderlineWidth);
- sourceBorderlineColor = findValueVector4(sourceMap, Toolkit::DevelVisual::Property::BORDERLINE_COLOR, sourceBorderlineColor);
- sourceBorderlineOffset = findValueFloat(sourceMap, Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, sourceBorderlineOffset);
+ sourceProperties.push_back(std::pair<Dali::Property::Index, Dali::Property::Map>(Toolkit::ImageView::Property::IMAGE, imageSourcePropertyMap));
+ destinationProperties.push_back(std::pair<Dali::Property::Index, Dali::Property::Map>(Toolkit::ImageView::Property::IMAGE, imageDestinationPropertyMap));
}
+}
- std::vector<Dali::Property> properties;
- std::vector<std::pair<Property::Value, Property::Value>> values;
-
- if(Vector3(sourceMixColor) != Vector3(destinationMixColor))
- {
- properties.push_back(DevelControl::GetVisualProperty(destinationHandle, Toolkit::ImageView::Property::IMAGE, Toolkit::Visual::Property::MIX_COLOR));
- values.push_back(std::make_pair(Vector3(sourceMixColor), Vector3(destinationMixColor)));
- }
- if(std::abs(sourceMixColor.a - destinationMixColor.a) > Math::MACHINE_EPSILON_1)
- {
- properties.push_back(DevelControl::GetVisualProperty(destinationHandle, Toolkit::ImageView::Property::IMAGE, Toolkit::Visual::Property::OPACITY));
- values.push_back(std::make_pair(sourceMixColor.a, destinationMixColor.a));
- }
- if(sourceCornerRadius != destinationCornerRadius)
- {
- properties.push_back(DevelControl::GetVisualProperty(destinationHandle, Toolkit::ImageView::Property::IMAGE, Toolkit::DevelVisual::Property::CORNER_RADIUS));
- values.push_back(std::make_pair(sourceCornerRadius, destinationCornerRadius));
- }
- if(sourceBorderlineWidth != destinationBorderlineWidth)
- {
- properties.push_back(DevelControl::GetVisualProperty(destinationHandle, Toolkit::ImageView::Property::IMAGE, Toolkit::DevelVisual::Property::BORDERLINE_WIDTH));
- values.push_back(std::make_pair(sourceBorderlineWidth, destinationBorderlineWidth));
- }
- if(sourceBorderlineColor != destinationBorderlineColor)
- {
- properties.push_back(DevelControl::GetVisualProperty(destinationHandle, Toolkit::ImageView::Property::IMAGE, Toolkit::DevelVisual::Property::BORDERLINE_COLOR));
- values.push_back(std::make_pair(sourceBorderlineColor, destinationBorderlineColor));
- }
- if(sourceBorderlineOffset != destinationBorderlineOffset)
+void ImageView::OnUpdateVisualProperties(const std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& properties)
+{
+ Toolkit::Visual::Base visual = DevelControl::GetVisual(*this, Toolkit::ImageView::Property::IMAGE);
+ if(visual)
{
- properties.push_back(DevelControl::GetVisualProperty(destinationHandle, Toolkit::ImageView::Property::IMAGE, Toolkit::DevelVisual::Property::BORDERLINE_OFFSET));
- values.push_back(std::make_pair(sourceBorderlineOffset, destinationBorderlineOffset));
- }
+ Dali::Toolkit::Control handle(GetOwner());
- for(uint32_t i = 0; i < properties.size(); ++i)
- {
- if(timePeriod.delaySeconds > 0.0f)
+ for(auto&& data : properties)
{
- Dali::KeyFrames initialKeyframes = Dali::KeyFrames::New();
- initialKeyframes.Add(0.0f, values[i].first);
- initialKeyframes.Add(1.0f, values[i].first);
- animation.AnimateBetween(properties[i], initialKeyframes, TimePeriod(timePeriod.delaySeconds));
+ if(data.first == Toolkit::ImageView::Property::IMAGE)
+ {
+ DevelControl::DoAction(handle, Toolkit::ImageView::Property::IMAGE, DevelVisual::Action::UPDATE_PROPERTY, data.second);
+ break;
+ }
}
- Dali::KeyFrames keyframes = Dali::KeyFrames::New();
- keyframes.Add(0.0f, values[i].first);
- keyframes.Add(1.0f, values[i].second);
- animation.AnimateBetween(properties[i], keyframes, alphaFunction, timePeriod);
}
}
/**
* @copydoc Toolkit::Control::OnCreateTransitions()
*/
- virtual void OnCreateTransitions(Dali::Animation& animation, Dali::Toolkit::Control source, AlphaFunction alphaFunction, TimePeriod timePeriod) override;
+ virtual void OnCreateTransitions(std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& sourceProperties,
+ std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& destinationProperties,
+ Dali::Toolkit::Control source,
+ Dali::Toolkit::Control destination) override;
+
+ /**
+ * @copydoc Toolkit::Control::OnUpdateVisualProperties()
+ */
+ virtual void OnUpdateVisualProperties(const std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& properties) override;
private:
/**
--- /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/controls/scrollable/scroll-view/scroll-view-impl-constraints.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view-constraints.h>
+#include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+namespace
+{
+
+float FinalDefaultAlphaFunction(float offset)
+{
+ return offset * 0.5f;
+}
+
+/**
+ * Internal Relative position Constraint
+ * Generates the relative position value of the scroll view
+ * based on the absolute position, and it's relation to the
+ * scroll domain. This is a value from 0.0f to 1.0f in each
+ * scroll position axis.
+ */
+void InternalRelativePositionConstraint(Vector2& relativePosition, const PropertyInputContainer& inputs)
+{
+ Vector2 position = -inputs[0]->GetVector2();
+ const Vector2& min = inputs[1]->GetVector2();
+ const Vector2& max = inputs[2]->GetVector2();
+ const Vector3& size = inputs[3]->GetVector3();
+
+ position.x = WrapInDomain(position.x, min.x, max.x);
+ position.y = WrapInDomain(position.y, min.y, max.y);
+
+ Vector2 domainSize = (max - min) - size.GetVectorXY();
+
+ relativePosition.x = domainSize.x > Math::MACHINE_EPSILON_1 ? fabsf((position.x - min.x) / domainSize.x) : 0.0f;
+ relativePosition.y = domainSize.y > Math::MACHINE_EPSILON_1 ? fabsf((position.y - min.y) / domainSize.y) : 0.0f;
+}
+
+/**
+ * Internal scroll domain Constraint
+ * Generates the scroll domain of the scroll view.
+ */
+void InternalScrollDomainConstraint(Vector2& scrollDomain, const PropertyInputContainer& inputs)
+{
+ const Vector2& min = inputs[0]->GetVector2();
+ const Vector2& max = inputs[1]->GetVector2();
+ const Vector3& size = inputs[2]->GetVector3();
+
+ scrollDomain = (max - min) - size.GetVectorXY();
+}
+
+/**
+ * Internal maximum scroll position Constraint
+ * Generates the maximum scroll position of the scroll view.
+ */
+void InternalPrePositionMaxConstraint(Vector2& scrollMax, const PropertyInputContainer& inputs)
+{
+ const Vector2& max = inputs[0]->GetVector2();
+ const Vector3& size = inputs[1]->GetVector3();
+
+ scrollMax = max - size.GetVectorXY();
+}
+
+/**
+ * Internal Pre-Position Property Constraint.
+ *
+ * Generates position property based on current position + gesture displacement.
+ * Or generates position property based on positionX/Y.
+ * Note: This is the position prior to any clamping at scroll boundaries.
+ */
+struct InternalPrePositionConstraint
+{
+ InternalPrePositionConstraint(const Vector2& initialPanPosition,
+ const Vector2& initialPanMask,
+ bool axisAutoLock,
+ float axisAutoLockGradient,
+ ScrollView::LockAxis initialLockAxis,
+ const Vector2& maxOvershoot,
+ const RulerPtr& rulerX,
+ const RulerPtr& rulerY)
+ : mLocalStart(initialPanPosition),
+ mInitialPanMask(initialPanMask),
+ mMaxOvershoot(maxOvershoot),
+ mAxisAutoLockGradient(axisAutoLockGradient),
+ mLockAxis(initialLockAxis),
+ mAxisAutoLock(axisAutoLock),
+ mWasPanning(false)
+ {
+ const RulerDomain& rulerDomainX = rulerX->GetDomain();
+ const RulerDomain& rulerDomainY = rulerY->GetDomain();
+ mDomainMin = Vector2(rulerDomainX.min, -rulerDomainY.min);
+ mDomainMax = Vector2(-rulerDomainX.max, -rulerDomainY.max);
+ mClampX = rulerDomainX.enabled;
+ mClampY = rulerDomainY.enabled;
+ mFixedRulerX = rulerX->GetType() == Ruler::FIXED;
+ mFixedRulerY = rulerY->GetType() == Ruler::FIXED;
+ }
+
+ void operator()(Vector2& scrollPostPosition, const PropertyInputContainer& inputs)
+ {
+ const Vector2& panPosition = inputs[0]->GetVector2();
+ const bool& inGesture = inputs[1]->GetBoolean();
+
+ // First check if we are within a gesture.
+ // The ScrollView may have received a start gesture from ::OnPan()
+ // while the finish gesture is received now in this constraint.
+ // This gesture must then be rejected as the value will be "old".
+ // Typically the last value from the end of the last gesture.
+ // If we are rejecting the gesture, we simply don't modify the constraint target.
+ if(inGesture)
+ {
+ if(!mWasPanning)
+ {
+ mPrePosition = scrollPostPosition;
+ mStartPosition = mPrePosition;
+ mCurrentPanMask = mInitialPanMask;
+ mWasPanning = true;
+ }
+
+ // Calculate Deltas...
+ const Vector2& currentPosition = panPosition;
+ Vector2 panDelta(currentPosition - mLocalStart);
+
+ // Axis Auto Lock - locks the panning to the horizontal or vertical axis if the pan
+ // appears mostly horizontal or mostly vertical respectively...
+ if(mAxisAutoLock)
+ {
+ mLockAxis = GetLockAxis(panDelta, mLockAxis, mAxisAutoLockGradient);
+ if(mLockAxis == ScrollView::LockVertical)
+ {
+ mCurrentPanMask.y = 0.0f;
+ }
+ else if(mLockAxis == ScrollView::LockHorizontal)
+ {
+ mCurrentPanMask.x = 0.0f;
+ }
+ }
+
+ // Restrict deltas based on ruler enable/disable and axis-lock state...
+ panDelta *= mCurrentPanMask;
+
+ // Perform Position transform based on input deltas...
+ scrollPostPosition = mPrePosition;
+ scrollPostPosition += panDelta;
+
+ // if no wrapping then clamp preposition to maximum overshoot amount
+ const Vector3& size = inputs[2]->GetVector3();
+ if(mClampX)
+ {
+ float newXPosition = Clamp(scrollPostPosition.x, (mDomainMax.x + size.x) - mMaxOvershoot.x, mDomainMin.x + mMaxOvershoot.x);
+ if((newXPosition < scrollPostPosition.x - Math::MACHINE_EPSILON_1) || (newXPosition > scrollPostPosition.x + Math::MACHINE_EPSILON_1))
+ {
+ mPrePosition.x = newXPosition;
+ mLocalStart.x = panPosition.x;
+ }
+ scrollPostPosition.x = newXPosition;
+ }
+ if(mClampY)
+ {
+ float newYPosition = Clamp(scrollPostPosition.y, (mDomainMax.y + size.y) - mMaxOvershoot.y, mDomainMin.y + mMaxOvershoot.y);
+ if((newYPosition < scrollPostPosition.y - Math::MACHINE_EPSILON_1) || (newYPosition > scrollPostPosition.y + Math::MACHINE_EPSILON_1))
+ {
+ mPrePosition.y = newYPosition;
+ mLocalStart.y = panPosition.y;
+ }
+ scrollPostPosition.y = newYPosition;
+ }
+
+ // If we are using a fixed ruler in a particular axis, limit the maximum pages scrolled on that axis.
+ if(mFixedRulerX || mFixedRulerY)
+ {
+ // Here we limit the maximum amount that can be moved from the starting position of the gesture to one page.
+ // We do this only if we have a fixed ruler (on that axis) and the mode is enabled.
+ // Note: 1.0f is subtracted to keep the value within one page size (otherwise we stray on to the page after).
+ // Note: A further 1.0f is subtracted to handle a compensation that happens later within the flick handling code in SnapWithVelocity().
+ // When a flick is completed, an adjustment of 1.0f is sometimes made to allow for the scenario where:
+ // A flick finishes before the update thread has advanced the scroll position past the previous snap point.
+ Vector2 viewPageSizeLimit(size.x - (1.0f + 1.0f), size.y - (1.0f - 1.0f));
+ Vector2 minPosition(mStartPosition.x - viewPageSizeLimit.x, mStartPosition.y - viewPageSizeLimit.y);
+ Vector2 maxPosition(mStartPosition.x + viewPageSizeLimit.x, mStartPosition.y + viewPageSizeLimit.y);
+
+ if(mFixedRulerX)
+ {
+ scrollPostPosition.x = Clamp(scrollPostPosition.x, minPosition.x, maxPosition.x);
+ }
+ if(mFixedRulerY)
+ {
+ scrollPostPosition.y = Clamp(scrollPostPosition.y, minPosition.y, maxPosition.y);
+ }
+ }
+ }
+ }
+
+ Vector2 mPrePosition;
+ Vector2 mLocalStart;
+ Vector2 mStartPosition; ///< The start position of the gesture - used to limit scroll amount (not modified by clamping).
+ Vector2 mInitialPanMask; ///< Initial pan mask (based on ruler settings).
+ Vector2 mCurrentPanMask; ///< Current pan mask that can be altered by axis lock mode.
+ Vector2 mDomainMin;
+ Vector2 mDomainMax;
+ Vector2 mMaxOvershoot;
+
+ float mAxisAutoLockGradient; ///< Set by ScrollView
+ ScrollView::LockAxis mLockAxis;
+
+ bool mAxisAutoLock : 1; ///< Set by ScrollView
+ bool mWasPanning : 1;
+ bool mClampX : 1;
+ bool mClampY : 1;
+ bool mFixedRulerX : 1;
+ bool mFixedRulerY : 1;
+};
+
+/**
+ * Internal Position Property Constraint.
+ *
+ * Generates position property based on pre-position
+ * Note: This is the position after clamping.
+ * (uses result of InternalPrePositionConstraint)
+ */
+struct InternalPositionConstraint
+{
+ InternalPositionConstraint(const RulerDomain& domainX, const RulerDomain& domainY, bool wrap)
+ : mDomainMin(-domainX.min, -domainY.min),
+ mDomainMax(-domainX.max, -domainY.max),
+ mClampX(domainX.enabled),
+ mClampY(domainY.enabled),
+ mWrap(wrap)
+ {
+ }
+
+ void operator()(Vector2& position, const PropertyInputContainer& inputs)
+ {
+ position = inputs[0]->GetVector2();
+ const Vector2& size = inputs[3]->GetVector3().GetVectorXY();
+ const Vector2& min = inputs[1]->GetVector2();
+ const Vector2& max = inputs[2]->GetVector2();
+
+ if(mWrap)
+ {
+ position.x = -WrapInDomain(-position.x, min.x, max.x);
+ position.y = -WrapInDomain(-position.y, min.y, max.y);
+ }
+ else
+ {
+ // clamp post position to domain
+ position.x = mClampX ? Clamp(position.x, mDomainMax.x + size.x, mDomainMin.x) : position.x;
+ position.y = mClampY ? Clamp(position.y, mDomainMax.y + size.y, mDomainMin.y) : position.y;
+ }
+ }
+
+ Vector2 mDomainMin;
+ Vector2 mDomainMax;
+ bool mClampX;
+ bool mClampY;
+ bool mWrap;
+};
+
+/**
+ * This constraint updates the X overshoot property using the difference
+ * SCROLL_PRE_POSITION.x and SCROLL_POSITION.x, returning a relative value between 0.0f and 1.0f
+ */
+struct OvershootXConstraint
+{
+ OvershootXConstraint(float maxOvershoot)
+ : mMaxOvershoot(maxOvershoot)
+ {
+ }
+
+ void operator()(float& current, const PropertyInputContainer& inputs)
+ {
+ if(inputs[2]->GetBoolean())
+ {
+ const Vector2& scrollPrePosition = inputs[0]->GetVector2();
+ const Vector2& scrollPostPosition = inputs[1]->GetVector2();
+ float newOvershoot = scrollPrePosition.x - scrollPostPosition.x;
+ current = (newOvershoot > 0.0f ? std::min(newOvershoot, mMaxOvershoot) : std::max(newOvershoot, -mMaxOvershoot)) / mMaxOvershoot;
+ }
+ else
+ {
+ current = 0.0f;
+ }
+ }
+
+ float mMaxOvershoot;
+};
+
+/**
+ * This constraint updates the Y overshoot property using the difference
+ * SCROLL_PRE_POSITION.y and SCROLL_POSITION.y, returning a relative value between 0.0f and 1.0f
+ */
+struct OvershootYConstraint
+{
+ OvershootYConstraint(float maxOvershoot)
+ : mMaxOvershoot(maxOvershoot)
+ {
+ }
+
+ void operator()(float& current, const PropertyInputContainer& inputs)
+ {
+ if(inputs[2]->GetBoolean())
+ {
+ const Vector2& scrollPrePosition = inputs[0]->GetVector2();
+ const Vector2& scrollPostPosition = inputs[1]->GetVector2();
+ float newOvershoot = scrollPrePosition.y - scrollPostPosition.y;
+ current = (newOvershoot > 0.0f ? std::min(newOvershoot, mMaxOvershoot) : std::max(newOvershoot, -mMaxOvershoot)) / mMaxOvershoot;
+ }
+ else
+ {
+ current = 0.0f;
+ }
+ }
+
+ float mMaxOvershoot;
+};
+
+/**
+ * Internal Position-Delta Property Constraint.
+ *
+ * Generates position-delta property based on scroll-position + scroll-offset properties.
+ */
+void InternalPositionDeltaConstraint(Vector2& current, const PropertyInputContainer& inputs)
+{
+ const Vector2& scrollPosition = inputs[0]->GetVector2();
+ const Vector2& scrollOffset = inputs[1]->GetVector2();
+
+ current = scrollPosition + scrollOffset;
+}
+
+/**
+ * Internal Final Position Constraint
+ * The position of content is:
+ * of scroll-position + f(scroll-overshoot)
+ * where f(...) function defines how overshoot
+ * should affect final-position.
+ */
+struct InternalFinalConstraint
+{
+ InternalFinalConstraint(AlphaFunctionPrototype functionX,
+ AlphaFunctionPrototype functionY)
+ : mFunctionX(functionX),
+ mFunctionY(functionY)
+ {
+ }
+
+ void operator()(Vector2& current, const PropertyInputContainer& inputs)
+ {
+ const float& overshootx = inputs[1]->GetFloat();
+ const float& overshooty = inputs[2]->GetFloat();
+ Vector2 offset(mFunctionX(overshootx),
+ mFunctionY(overshooty));
+
+ current = inputs[0]->GetVector2() - offset;
+ }
+
+ AlphaFunctionPrototype mFunctionX;
+ AlphaFunctionPrototype mFunctionY;
+};
+
+} // namespace
+
+void ScrollViewConstraints::UpdateMainInternalConstraint(ScrollView& scrollView)
+{
+ // TODO: Only update the constraints which have changed, rather than remove all and add all again.
+ // Requires a dali-core ApplyConstraintAt, or a ReplaceConstraint. The former is probably more flexible.
+ Actor scrollViewActor = scrollView.Self();
+ PanGestureDetector detector(scrollView.GetPanGestureDetector());
+
+ if(mScrollMainInternalPositionConstraint)
+ {
+ mScrollMainInternalPositionConstraint.Remove();
+ mScrollMainInternalDeltaConstraint.Remove();
+ mScrollMainInternalFinalConstraint.Remove();
+ mScrollMainInternalRelativeConstraint.Remove();
+ mScrollMainInternalDomainConstraint.Remove();
+ mScrollMainInternalPrePositionMaxConstraint.Remove();
+ }
+ if(mScrollMainInternalPrePositionConstraint)
+ {
+ mScrollMainInternalPrePositionConstraint.Remove();
+ }
+
+ // TODO: It's probably better to use a local displacement value as this will give a displacement when scrolling just commences
+ // but we need to make sure than the gesture system gives displacement since last frame (60Hz), not displacement since last touch event (90Hz).
+
+ // 1. First calculate the pre-position (this is the scroll position if no clamping has taken place)
+ Vector2 initialPanMask = Vector2(scrollView.mRulerX->IsEnabled() ? 1.0f : 0.0f, scrollView.mRulerY->IsEnabled() ? 1.0f : 0.0f);
+
+ if(scrollView.mLockAxis == ScrollView::LockVertical)
+ {
+ initialPanMask.y = 0.0f;
+ }
+ else if(scrollView.mLockAxis == ScrollView::LockHorizontal)
+ {
+ initialPanMask.x = 0.0f;
+ }
+
+ if(scrollView.mPanning)
+ {
+ mScrollMainInternalPrePositionConstraint = Constraint::New<Vector2>(scrollViewActor,
+ Toolkit::ScrollView::Property::SCROLL_PRE_POSITION,
+ InternalPrePositionConstraint(scrollView.mPanStartPosition,
+ initialPanMask,
+ scrollView.mAxisAutoLock,
+ scrollView.mAxisAutoLockGradient,
+ scrollView.mLockAxis,
+ scrollView.mMaxOvershoot,
+ scrollView.mRulerX,
+ scrollView.mRulerY));
+ mScrollMainInternalPrePositionConstraint.AddSource(Source(detector, PanGestureDetector::Property::LOCAL_POSITION));
+ mScrollMainInternalPrePositionConstraint.AddSource(Source(detector, PanGestureDetector::Property::PANNING));
+ mScrollMainInternalPrePositionConstraint.AddSource(Source(scrollViewActor, Actor::Property::SIZE));
+ mScrollMainInternalPrePositionConstraint.Apply();
+ }
+
+ // 2. Second calculate the clamped position (actual position)
+ mScrollMainInternalPositionConstraint = Constraint::New<Vector2>(scrollViewActor,
+ Toolkit::ScrollView::Property::SCROLL_POSITION,
+ InternalPositionConstraint(scrollView.mRulerX->GetDomain(),
+ scrollView.mRulerY->GetDomain(),
+ scrollView.mWrapMode));
+ mScrollMainInternalPositionConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_PRE_POSITION));
+ mScrollMainInternalPositionConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::SCROLL_POSITION_MIN));
+ mScrollMainInternalPositionConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::SCROLL_POSITION_MAX));
+ mScrollMainInternalPositionConstraint.AddSource(Source(scrollViewActor, Actor::Property::SIZE));
+ mScrollMainInternalPositionConstraint.Apply();
+
+ mScrollMainInternalDeltaConstraint = Constraint::New<Vector2>(scrollViewActor, Toolkit::ScrollView::Property::SCROLL_POSITION_DELTA, InternalPositionDeltaConstraint);
+ mScrollMainInternalDeltaConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_POSITION));
+ mScrollMainInternalDeltaConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_DOMAIN_OFFSET));
+ mScrollMainInternalDeltaConstraint.Apply();
+
+ mScrollMainInternalFinalConstraint = Constraint::New<Vector2>(scrollViewActor, Toolkit::ScrollView::Property::SCROLL_FINAL, InternalFinalConstraint(FinalDefaultAlphaFunction, FinalDefaultAlphaFunction));
+ mScrollMainInternalFinalConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_POSITION));
+ mScrollMainInternalFinalConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::OVERSHOOT_X));
+ mScrollMainInternalFinalConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::OVERSHOOT_Y));
+ mScrollMainInternalFinalConstraint.Apply();
+
+ mScrollMainInternalRelativeConstraint = Constraint::New<Vector2>(scrollViewActor, Toolkit::Scrollable::Property::SCROLL_RELATIVE_POSITION, InternalRelativePositionConstraint);
+ mScrollMainInternalRelativeConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_POSITION));
+ mScrollMainInternalRelativeConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::SCROLL_POSITION_MIN));
+ mScrollMainInternalRelativeConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::SCROLL_POSITION_MAX));
+ mScrollMainInternalRelativeConstraint.AddSource(LocalSource(Actor::Property::SIZE));
+ mScrollMainInternalRelativeConstraint.Apply();
+
+ mScrollMainInternalDomainConstraint = Constraint::New<Vector2>(scrollViewActor, Toolkit::ScrollView::Property::SCROLL_DOMAIN_SIZE, InternalScrollDomainConstraint);
+ mScrollMainInternalDomainConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::SCROLL_POSITION_MIN));
+ mScrollMainInternalDomainConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::SCROLL_POSITION_MAX));
+ mScrollMainInternalDomainConstraint.AddSource(LocalSource(Actor::Property::SIZE));
+ mScrollMainInternalDomainConstraint.Apply();
+
+ mScrollMainInternalPrePositionMaxConstraint = Constraint::New<Vector2>(scrollViewActor, Toolkit::ScrollView::Property::SCROLL_PRE_POSITION_MAX, InternalPrePositionMaxConstraint);
+ mScrollMainInternalPrePositionMaxConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::SCROLL_POSITION_MAX));
+ mScrollMainInternalPrePositionMaxConstraint.AddSource(LocalSource(Actor::Property::SIZE));
+ mScrollMainInternalPrePositionMaxConstraint.Apply();
+
+ // When panning we want to make sure overshoot values are affected by pre position and post position
+ SetOvershootConstraintsEnabled(scrollView, !scrollView.mWrapMode);
+}
+
+void ScrollViewConstraints::SetOvershootConstraintsEnabled(ScrollView& scrollView, bool enabled)
+{
+ Actor scrollViewActor(scrollView.Self());
+ // remove and reset, it may now be in wrong order with the main internal constraints
+ if(mScrollMainInternalOvershootXConstraint)
+ {
+ mScrollMainInternalOvershootXConstraint.Remove();
+ mScrollMainInternalOvershootXConstraint.Reset();
+ mScrollMainInternalOvershootYConstraint.Remove();
+ mScrollMainInternalOvershootYConstraint.Reset();
+ }
+ if(enabled)
+ {
+ mScrollMainInternalOvershootXConstraint = Constraint::New<float>(scrollViewActor, Toolkit::ScrollView::Property::OVERSHOOT_X, OvershootXConstraint(scrollView.mMaxOvershoot.x));
+ mScrollMainInternalOvershootXConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_PRE_POSITION));
+ mScrollMainInternalOvershootXConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_POSITION));
+ mScrollMainInternalOvershootXConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::CAN_SCROLL_HORIZONTAL));
+ mScrollMainInternalOvershootXConstraint.Apply();
+
+ mScrollMainInternalOvershootYConstraint = Constraint::New<float>(scrollViewActor, Toolkit::ScrollView::Property::OVERSHOOT_Y, OvershootYConstraint(scrollView.mMaxOvershoot.y));
+ mScrollMainInternalOvershootYConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_PRE_POSITION));
+ mScrollMainInternalOvershootYConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_POSITION));
+ mScrollMainInternalOvershootYConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::CAN_SCROLL_VERTICAL));
+ mScrollMainInternalOvershootYConstraint.Apply();
+ }
+ else
+ {
+ scrollViewActor.SetProperty(Toolkit::ScrollView::Property::OVERSHOOT_X, 0.0f);
+ scrollViewActor.SetProperty(Toolkit::ScrollView::Property::OVERSHOOT_Y, 0.0f);
+ }
+}
+
+void ScrollViewConstraints::SetInternalConstraints(ScrollView& scrollView)
+{
+ // Internal constraints (applied to target ScrollBase Actor itself) /////////
+ UpdateMainInternalConstraint(scrollView);
+
+ // User definable constraints to apply to all child actors //////////////////
+ Actor scrollViewActor = scrollView.Self();
+
+ // Apply some default constraints to ScrollView & its bound actors
+ // Movement + Wrap function
+
+ Constraint constraint;
+
+ // MoveActor (scrolling)
+ constraint = Constraint::New<Vector3>(scrollViewActor, Actor::Property::POSITION, MoveActorConstraint);
+ constraint.AddSource(Source(scrollViewActor, Toolkit::ScrollView::Property::SCROLL_POSITION));
+ constraint.SetRemoveAction(Constraint::DISCARD);
+ scrollView.ApplyConstraintToBoundActors(constraint);
+
+ // WrapActor (wrap functionality)
+ constraint = Constraint::New<Vector3>(scrollViewActor, Actor::Property::POSITION, WrapActorConstraint);
+ constraint.AddSource(LocalSource(Actor::Property::SCALE));
+ constraint.AddSource(LocalSource(Actor::Property::ANCHOR_POINT));
+ constraint.AddSource(LocalSource(Actor::Property::SIZE));
+ constraint.AddSource(Source(scrollViewActor, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN));
+ constraint.AddSource(Source(scrollViewActor, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX));
+ constraint.AddSource(Source(scrollViewActor, Toolkit::ScrollView::Property::WRAP));
+ constraint.SetRemoveAction(Constraint::DISCARD);
+ scrollView.ApplyConstraintToBoundActors(constraint);
+}
+
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_TOOLKIT_INTERNAL_SCROLL_VIEW_CONSTRAINTS_H
+#define DALI_TOOLKIT_INTERNAL_SCROLL_VIEW_CONSTRAINTS_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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/animation/constraint.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+class ScrollView;
+
+/// Sets up and owns the Constraints used by the ScrollView class
+class ScrollViewConstraints
+{
+public:
+
+ ScrollViewConstraints() = default; ///< Default Constructor
+ ~ScrollViewConstraints() = default; ///< Default Non-Virtual Destructor
+
+ // Not copyable or moveable
+ ScrollViewConstraints(const ScrollViewConstraints&) = delete;
+ ScrollViewConstraints(ScrollViewConstraints&&) = delete;
+ ScrollViewConstraints& operator=(const ScrollViewConstraints&) = delete;
+ ScrollViewConstraints& operator=(ScrollViewConstraints&&) = delete;
+
+ /**
+ * Updates the main internal scroll constraints with new ruler and domain values
+ *
+ * @param[in] scrollView A reference to the scroll view object
+ */
+ void UpdateMainInternalConstraint(Internal::ScrollView& scrollView);
+
+ /**
+ * Enables/disables the overshoot constraints
+ *
+ * @param[in] scrollView A reference to the scroll view object
+ * @param[in] enabled whether to enable or disable the overshoot constraints
+ */
+ void SetOvershootConstraintsEnabled(ScrollView& scrollView, bool enabled);
+
+ /**
+ * Sets internal constraints for this ScrollView.
+ * Many of these internal constraints are based on properties within ScrollView.
+ *
+ * @param[in] scrollView A reference to the scroll view object
+ */
+ void SetInternalConstraints(ScrollView& scrollView);
+
+public:
+
+ Constraint mScrollMainInternalPrePositionConstraint;
+ Constraint mScrollMainInternalPositionConstraint;
+ Constraint mScrollMainInternalOvershootXConstraint;
+ Constraint mScrollMainInternalOvershootYConstraint;
+ Constraint mScrollMainInternalDeltaConstraint;
+ Constraint mScrollMainInternalFinalConstraint;
+ Constraint mScrollMainInternalRelativeConstraint;
+ Constraint mScrollMainInternalDomainConstraint;
+ Constraint mScrollMainInternalPrePositionMaxConstraint;
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_SCROLL_VIEW_CONSTRAINTS_H
//#define ENABLED_SCROLL_STATE_LOGGING
#ifdef ENABLED_SCROLL_STATE_LOGGING
-#define DALI_LOG_SCROLL_STATE(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, "%s:%d " format "\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define DALI_LOG_SCROLL_STATE(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::DebugInfo, "%s:%d " format "\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define DALI_LOG_SCROLL_STATE(format, ...)
#endif
// TODO: Orientation.
// TODO: upgrade Vector2/3 to support returning Unit vectors, normals, & cross product (dot product is already provided)
-using namespace Dali;
-
namespace
{
-const float DEFAULT_SLOW_SNAP_ANIMATION_DURATION(0.5f); ///< Default Drag-Release animation time.
-const float DEFAULT_FAST_SNAP_ANIMATION_DURATION(0.25f); ///< Default Drag-Flick animation time.
-const float DEFAULT_SNAP_OVERSHOOT_DURATION(0.5f); ///< Default Overshoot snapping animation time.
-const float DEFAULT_MAX_OVERSHOOT(100.0f); ///< Default maximum allowed overshoot in pixels
-
-const float DEFAULT_AXIS_AUTO_LOCK_GRADIENT(0.36f); ///< Default Axis-AutoLock gradient threshold. default is 0.36:1 (20 degrees)
-const float DEFAULT_FRICTION_COEFFICIENT(1.0f); ///< Default Friction Co-efficient. (in stage diagonals per second)
-const float DEFAULT_FLICK_SPEED_COEFFICIENT(1.0f); ///< Default Flick speed coefficient (multiples input touch velocity)
-const float DEFAULT_MAX_FLICK_SPEED(3.0f); ///< Default Maximum flick speed. (in stage diagonals per second)
-
-const Vector2 DEFAULT_MIN_FLICK_DISTANCE(30.0f, 30.0f); ///< minimum distance for pan before flick allowed
-const float DEFAULT_MIN_FLICK_SPEED_THRESHOLD(500.0f); ///< Minimum pan speed required for flick in pixels/s
-const float FREE_FLICK_SPEED_THRESHOLD = 200.0f; ///< Free-Flick threshold in pixels/ms
-const float AUTOLOCK_AXIS_MINIMUM_DISTANCE2 = 100.0f; ///< Auto-lock axis after minimum distance squared.
-const float FLICK_ORTHO_ANGLE_RANGE = 75.0f; ///< degrees. (if >45, then supports diagonal flicking)
-const Vector2 DEFAULT_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION = Vector2(0.17f, 0.1f); ///< The step of horizontal scroll distance in the proportion of stage size for each wheel event received.
-const unsigned long MINIMUM_TIME_BETWEEN_DOWN_AND_UP_FOR_RESET(150u);
-const float TOUCH_DOWN_TIMER_INTERVAL = 100.0f;
-const float DEFAULT_SCROLL_UPDATE_DISTANCE(30.0f); ///< Default distance to travel in pixels for scroll update signal
+using namespace Dali;
+
+constexpr float DEFAULT_SLOW_SNAP_ANIMATION_DURATION(0.5f); ///< Default Drag-Release animation time.
+constexpr float DEFAULT_FAST_SNAP_ANIMATION_DURATION(0.25f); ///< Default Drag-Flick animation time.
+constexpr float DEFAULT_SNAP_OVERSHOOT_DURATION(0.5f); ///< Default Overshoot snapping animation time.
+constexpr float DEFAULT_MAX_OVERSHOOT(100.0f); ///< Default maximum allowed overshoot in pixels
+
+constexpr float DEFAULT_AXIS_AUTO_LOCK_GRADIENT(0.36f); ///< Default Axis-AutoLock gradient threshold. default is 0.36:1 (20 degrees)
+constexpr float DEFAULT_FRICTION_COEFFICIENT(1.0f); ///< Default Friction Co-efficient. (in stage diagonals per second)
+constexpr float DEFAULT_FLICK_SPEED_COEFFICIENT(1.0f); ///< Default Flick speed coefficient (multiples input touch velocity)
+constexpr float DEFAULT_MAX_FLICK_SPEED(3.0f); ///< Default Maximum flick speed. (in stage diagonals per second)
+
+constexpr Dali::Vector2 DEFAULT_MIN_FLICK_DISTANCE(30.0f, 30.0f); ///< minimum distance for pan before flick allowed
+constexpr float DEFAULT_MIN_FLICK_SPEED_THRESHOLD(500.0f); ///< Minimum pan speed required for flick in pixels/s
+
+constexpr float FREE_FLICK_SPEED_THRESHOLD = 200.0f; ///< Free-Flick threshold in pixels/ms
+constexpr float AUTOLOCK_AXIS_MINIMUM_DISTANCE2 = 100.0f; ///< Auto-lock axis after minimum distance squared.
+constexpr float FLICK_ORTHO_ANGLE_RANGE = 75.0f; ///< degrees. (if >45, then supports diagonal flicking)
+
+constexpr Dali::Vector2 DEFAULT_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION(0.17f, 0.1f); ///< The step of horizontal scroll distance in the proportion of stage size for each wheel event received.
+
+constexpr unsigned long MINIMUM_TIME_BETWEEN_DOWN_AND_UP_FOR_RESET(150u);
+constexpr float TOUCH_DOWN_TIMER_INTERVAL = 100.0f;
+constexpr float DEFAULT_SCROLL_UPDATE_DISTANCE(30.0f); ///< Default distance to travel in pixels for scroll update signal
const std::string INTERNAL_MAX_POSITION_PROPERTY_NAME("internalMaxPosition");
{
if(bias == Dali::Toolkit::DIRECTION_BIAS_NONE)
{
- return ShortestDistanceInDomain(a, b, start, end);
+ return Dali::ShortestDistanceInDomain(a, b, start, end);
}
// (a-start + end-b)
float size = end - start;
* @param anchor The Anchor point of interest.
* @return The position of the Anchor
*/
-Vector3 GetPositionOfAnchor(Actor& actor, const Vector3& anchor)
+Dali::Vector3 GetPositionOfAnchor(Dali::Actor& actor, const Dali::Vector3& anchor)
{
- Vector3 childPosition = actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION);
- Vector3 childAnchor = -actor.GetCurrentProperty<Vector3>(Actor::Property::ANCHOR_POINT) + anchor;
- Vector3 childSize = actor.GetCurrentProperty<Vector3>(Actor::Property::SIZE);
+ Dali::Vector3 childPosition = actor.GetCurrentProperty<Dali::Vector3>(Dali::Actor::Property::POSITION);
+ Dali::Vector3 childAnchor = -actor.GetCurrentProperty<Dali::Vector3>(Dali::Actor::Property::ANCHOR_POINT) + anchor;
+ Dali::Vector3 childSize = actor.GetCurrentProperty<Dali::Vector3>(Dali::Actor::Property::SIZE);
return childPosition + childAnchor * childSize;
}
-// AlphaFunctions /////////////////////////////////////////////////////////////////////////////////
+/**
+ * Returns the closest actor to the given position
+ * @param[in] actor The scrollview actor
+ * @param[in] internalActor The internal actor (to ignore)
+ * @param[in] position The given position
+ * @param[in] dirX Direction to search in
+ * @param[in] dirY Direction to search in
+ * @param[in] dirZ Direction to search in
+ * @return the closest child actor
+ */
+using FindDirection = Dali::Toolkit::Internal::ScrollView::FindDirection;
-float FinalDefaultAlphaFunction(float offset)
+Actor FindClosestActorToPosition(
+ CustomActor actor, Actor internalActor, const Vector3& position, FindDirection dirX, FindDirection dirY, FindDirection dirZ)
{
- return offset * 0.5f;
+ Actor closestChild;
+ float closestDistance2 = 0.0f;
+ Vector3 actualPosition = position;
+
+ unsigned int numChildren = actor.GetChildCount();
+
+ for(unsigned int i = 0; i < numChildren; ++i)
+ {
+ Actor child = actor.GetChildAt(i);
+
+ if(internalActor == child) // ignore internal actor.
+ {
+ continue;
+ }
+
+ Vector3 childPosition = GetPositionOfAnchor(child, AnchorPoint::CENTER);
+
+ Vector3 delta = childPosition - actualPosition;
+
+ // X-axis checking (only find Actors to the [dirX] of actualPosition)
+ if(dirX > FindDirection::All) // != All,None
+ {
+ FindDirection deltaH = delta.x > 0 ? FindDirection::Right : FindDirection::Left;
+ if(dirX != deltaH)
+ {
+ continue;
+ }
+ }
+
+ // Y-axis checking (only find Actors to the [dirY] of actualPosition)
+ if(dirY > FindDirection::All) // != All,None
+ {
+ FindDirection deltaV = delta.y > 0 ? FindDirection::Down : FindDirection::Up;
+ if(dirY != deltaV)
+ {
+ continue;
+ }
+ }
+
+ // Z-axis checking (only find Actors to the [dirZ] of actualPosition)
+ if(dirZ > FindDirection::All) // != All,None
+ {
+ FindDirection deltaV = delta.y > 0 ? FindDirection::In : FindDirection::Out;
+ if(dirZ != deltaV)
+ {
+ continue;
+ }
+ }
+
+ // compare child to closest child in terms of distance.
+ float distance2 = 0.0f;
+
+ // distance2 = the Square of the relevant dimensions of delta
+ if(dirX != FindDirection::None)
+ {
+ distance2 += delta.x * delta.x;
+ }
+
+ if(dirY != FindDirection::None)
+ {
+ distance2 += delta.y * delta.y;
+ }
+
+ if(dirZ != FindDirection::None)
+ {
+ distance2 += delta.z * delta.z;
+ }
+
+ if(closestChild) // Next time.
+ {
+ if(distance2 < closestDistance2)
+ {
+ closestChild = child;
+ closestDistance2 = distance2;
+ }
+ }
+ else // First time.
+ {
+ closestChild = child;
+ closestDistance2 = distance2;
+ }
+ }
+
+ return closestChild;
}
+// AlphaFunctions /////////////////////////////////////////////////////////////////////////////////
+
/**
* ConstantDecelerationAlphaFunction
* Newtoninan distance for constant deceleration
return progress * 2.0f - progress * progress;
}
-// Internal Constraints ///////////////////////////////////////////////////////////////////////////
-
/**
- * Internal Relative position Constraint
- * Generates the relative position value of the scroll view
- * based on the absolute position, and it's relation to the
- * scroll domain. This is a value from 0.0f to 1.0f in each
- * scroll position axis.
+ * Clamp a position
+ * @param[in] size The size to clamp to
+ * @param[in] rulerX The horizontal ruler
+ * @param[in] rulerY The vertical ruler
+ * @param[in,out] position The position to clamp
+ * @param[out] clamped the clamped state
*/
-void InternalRelativePositionConstraint(Vector2& relativePosition, const PropertyInputContainer& inputs)
+void ClampPosition(const Vector3& size, Dali::Toolkit::RulerPtr rulerX, Dali::Toolkit::RulerPtr rulerY, Vector2& position, Dali::Toolkit::ClampState2D& clamped)
{
- Vector2 position = -inputs[0]->GetVector2();
- const Vector2& min = inputs[1]->GetVector2();
- const Vector2& max = inputs[2]->GetVector2();
- const Vector3& size = inputs[3]->GetVector3();
-
- position.x = WrapInDomain(position.x, min.x, max.x);
- position.y = WrapInDomain(position.y, min.y, max.y);
-
- Vector2 domainSize = (max - min) - size.GetVectorXY();
-
- relativePosition.x = domainSize.x > Math::MACHINE_EPSILON_1 ? fabsf((position.x - min.x) / domainSize.x) : 0.0f;
- relativePosition.y = domainSize.y > Math::MACHINE_EPSILON_1 ? fabsf((position.y - min.y) / domainSize.y) : 0.0f;
+ position.x = -rulerX->Clamp(-position.x, size.width, 1.0f, clamped.x); // NOTE: X & Y rulers think in -ve coordinate system.
+ position.y = -rulerY->Clamp(-position.y, size.height, 1.0f, clamped.y); // That is scrolling RIGHT (e.g. 100.0, 0.0) means moving LEFT.
}
/**
- * Internal scroll domain Constraint
- * Generates the scroll domain of the scroll view.
+ * TODO: In situations where axes are different (X snap, Y free)
+ * Each axis should really have their own independent animation (time and equation)
+ * Consider, X axis snapping to nearest grid point (EaseOut over fixed time)
+ * Consider, Y axis simulating physics to arrive at a point (Physics equation over variable time)
+ * Currently, the axes have been split however, they both use the same EaseOut equation.
+ *
+ * @param[in] scrollView The main scrollview
+ * @param[in] rulerX The X ruler
+ * @param[in] rulerY The Y ruler
+ * @param[in] lockAxis Which axis (if any) is locked.
+ * @param[in] velocity Current pan velocity
+ * @param[in] maxOvershoot Maximum overshoot
+ * @param[in] inAcessibilityPan True if we are currently panning with accessibility
+ * @param[out] positionSnap The target position of snap animation
+ * @param[out] positionDuration The duration of the snap animation
+ * @param[out] alphaFunction The snap animation alpha function
+ * @param[out] isFlick if we are flicking or not
+ * @param[out] isFreeFlick if we are free flicking or not
*/
-void InternalScrollDomainConstraint(Vector2& scrollDomain, const PropertyInputContainer& inputs)
+void SnapWithVelocity(
+ Dali::Toolkit::Internal::ScrollView& scrollView,
+ Dali::Toolkit::RulerPtr rulerX,
+ Dali::Toolkit::RulerPtr rulerY,
+ Dali::Toolkit::Internal::ScrollView::LockAxis lockAxis,
+ Vector2 velocity,
+ Vector2 maxOvershoot,
+ Vector2& positionSnap,
+ Vector2& positionDuration,
+ AlphaFunction& alphaFunction,
+ bool inAccessibilityPan,
+ bool& isFlick,
+ bool& isFreeFlick)
{
- const Vector2& min = inputs[0]->GetVector2();
- const Vector2& max = inputs[1]->GetVector2();
- const Vector3& size = inputs[2]->GetVector3();
+ // Animator takes over now, touches are assumed not to interfere.
+ // And if touches do interfere, then we'll stop animation, update PrePosition
+ // to current mScroll's properties, and then resume.
+ // Note: For Flicking this may work a bit different...
- scrollDomain = (max - min) - size.GetVectorXY();
-}
+ float angle = atan2(velocity.y, velocity.x);
+ float speed2 = velocity.LengthSquared();
+ float biasX = 0.5f;
+ float biasY = 0.5f;
+ FindDirection horizontal = FindDirection::None;
+ FindDirection vertical = FindDirection::None;
-/**
- * Internal maximum scroll position Constraint
- * Generates the maximum scroll position of the scroll view.
- */
-void InternalPrePositionMaxConstraint(Vector2& scrollMax, const PropertyInputContainer& inputs)
-{
- const Vector2& max = inputs[0]->GetVector2();
- const Vector3& size = inputs[1]->GetVector3();
+ using LockAxis = Dali::Toolkit::Internal::ScrollView::LockAxis;
+
+ // orthoAngleRange = Angle tolerance within the Exact N,E,S,W direction
+ // that will be accepted as a general N,E,S,W flick direction.
+
+ const float orthoAngleRange = FLICK_ORTHO_ANGLE_RANGE * M_PI / 180.0f;
+ const float flickSpeedThreshold2 = scrollView.GetMinimumSpeedForFlick() * scrollView.GetMinimumSpeedForFlick();
+
+ // Flick logic X Axis
+
+ if(rulerX->IsEnabled() && lockAxis != LockAxis::LockHorizontal)
+ {
+ horizontal = FindDirection::All;
+
+ if(speed2 > flickSpeedThreshold2 || // exceeds flick threshold
+ inAccessibilityPan) // With AccessibilityPan its easier to move between snap positions
+ {
+ if((angle >= -orthoAngleRange) && (angle < orthoAngleRange)) // Swiping East
+ {
+ biasX = 0.0f, horizontal = FindDirection::Left;
+
+ // This guards against an error where no movement occurs, due to the flick finishing
+ // before the update-thread has advanced mScrollPostPosition past the the previous snap point.
+ positionSnap.x += 1.0f;
+ }
+ else if((angle >= M_PI - orthoAngleRange) || (angle < -M_PI + orthoAngleRange)) // Swiping West
+ {
+ biasX = 1.0f, horizontal = FindDirection::Right;
+
+ // This guards against an error where no movement occurs, due to the flick finishing
+ // before the update-thread has advanced mScrollPostPosition past the the previous snap point.
+ positionSnap.x -= 1.0f;
+ }
+ }
+ }
+
+ // Flick logic Y Axis
+
+ if(rulerY->IsEnabled() && lockAxis != LockAxis::LockVertical)
+ {
+ vertical = FindDirection::All;
+
+ if(speed2 > flickSpeedThreshold2 || // exceeds flick threshold
+ inAccessibilityPan) // With AccessibilityPan its easier to move between snap positions
+ {
+ if((angle >= M_PI_2 - orthoAngleRange) && (angle < M_PI_2 + orthoAngleRange)) // Swiping South
+ {
+ biasY = 0.0f, vertical = FindDirection::Up;
+ }
+ else if((angle >= -M_PI_2 - orthoAngleRange) && (angle < -M_PI_2 + orthoAngleRange)) // Swiping North
+ {
+ biasY = 1.0f, vertical = FindDirection::Down;
+ }
+ }
+ }
+
+ // isFlick: Whether this gesture is a flick or not.
+ isFlick = (horizontal != FindDirection::All || vertical != FindDirection::All);
+ // isFreeFlick: Whether this gesture is a flick under free panning criteria.
+ isFreeFlick = velocity.LengthSquared() > (FREE_FLICK_SPEED_THRESHOLD * FREE_FLICK_SPEED_THRESHOLD);
+
+ if(isFlick || isFreeFlick)
+ {
+ positionDuration = Vector2::ONE * scrollView.GetScrollFlickDuration();
+ alphaFunction = scrollView.GetScrollFlickAlphaFunction();
+ }
+
+ // Calculate next positionSnap ////////////////////////////////////////////////////////////
+
+ if(scrollView.GetActorAutoSnap())
+ {
+ Vector3 size = scrollView.Self().GetCurrentProperty<Vector3>(Actor::Property::SIZE);
+
+ Actor child = scrollView.FindClosestActorToPosition(Vector3(size.width * 0.5f, size.height * 0.5f, 0.0f), horizontal, vertical);
+
+ if(!child && isFlick)
+ {
+ // If we conducted a direction limited search and found no actor, then just snap to the closest actor.
+ child = scrollView.FindClosestActorToPosition(Vector3(size.width * 0.5f, size.height * 0.5f, 0.0f));
+ }
+
+ if(child)
+ {
+ Vector2 position = scrollView.Self().GetCurrentProperty<Vector2>(Toolkit::ScrollView::Property::SCROLL_POSITION);
+
+ // Get center-point of the Actor.
+ Vector3 childPosition = GetPositionOfAnchor(child, AnchorPoint::CENTER);
+
+ if(rulerX->IsEnabled())
+ {
+ positionSnap.x = position.x - childPosition.x + size.width * 0.5f;
+ }
+ if(rulerY->IsEnabled())
+ {
+ positionSnap.y = position.y - childPosition.y + size.height * 0.5f;
+ }
+ }
+ }
+
+ Vector2 startPosition = positionSnap;
+ positionSnap.x = -rulerX->Snap(-positionSnap.x, biasX); // NOTE: X & Y rulers think in -ve coordinate system.
+ positionSnap.y = -rulerY->Snap(-positionSnap.y, biasY); // That is scrolling RIGHT (e.g. 100.0, 0.0) means moving LEFT.
+
+ Dali::Toolkit::ClampState2D clamped;
+ Vector3 size = scrollView.Self().GetCurrentProperty<Vector3>(Actor::Property::SIZE);
+ Vector2 clampDelta(Vector2::ZERO);
+ ClampPosition(size, rulerX, rulerY, positionSnap, clamped);
+
+ if((rulerX->GetType() == Dali::Toolkit::Ruler::FREE || rulerY->GetType() == Dali::Toolkit::Ruler::FREE) &&
+ isFreeFlick && !scrollView.GetActorAutoSnap())
+ {
+ // Calculate target position based on velocity of flick.
+
+ // a = Deceleration (Set to diagonal stage length * friction coefficient)
+ // u = Initial Velocity (Flick velocity)
+ // v = 0 (Final Velocity)
+ // t = Time (Velocity / Deceleration)
+ Vector2 stageSize = Stage::GetCurrent().GetSize();
+ float stageLength = Vector3(stageSize.x, stageSize.y, 0.0f).Length();
+ float a = (stageLength * scrollView.GetFrictionCoefficient());
+ Vector3 u = Vector3(velocity.x, velocity.y, 0.0f) * scrollView.GetFlickSpeedCoefficient();
+ float speed = u.Length();
+ u /= speed;
+
+ // TODO: Change this to a decay function. (faster you flick, the slower it should be)
+ speed = std::min(speed, stageLength * scrollView.GetMaxFlickSpeed());
+ u *= speed;
+ alphaFunction = ConstantDecelerationAlphaFunction;
+
+ float t = speed / a;
+
+ if(rulerX->IsEnabled() && rulerX->GetType() == Dali::Toolkit::Ruler::FREE)
+ {
+ positionSnap.x += t * u.x * 0.5f;
+ }
+
+ if(rulerY->IsEnabled() && rulerY->GetType() == Dali::Toolkit::Ruler::FREE)
+ {
+ positionSnap.y += t * u.y * 0.5f;
+ }
+
+ clampDelta = positionSnap;
+ ClampPosition(size, rulerX, rulerY, positionSnap, clamped);
+
+ if((positionSnap - startPosition).LengthSquared() > Math::MACHINE_EPSILON_0)
+ {
+ clampDelta -= positionSnap;
+ clampDelta.x = clampDelta.x > 0.0f ? std::min(clampDelta.x, maxOvershoot.x) : std::max(clampDelta.x, -maxOvershoot.x);
+ clampDelta.y = clampDelta.y > 0.0f ? std::min(clampDelta.y, maxOvershoot.y) : std::max(clampDelta.y, -maxOvershoot.y);
+ }
+ else
+ {
+ clampDelta = Vector2::ZERO;
+ }
+
+ // If Axis is Free and has velocity, then calculate time taken
+ // to reach target based on velocity in axis.
+ if(rulerX->IsEnabled() && rulerX->GetType() == Dali::Toolkit::Ruler::FREE)
+ {
+ float deltaX = fabsf(startPosition.x - positionSnap.x);
+
+ if(fabsf(u.x) > Math::MACHINE_EPSILON_1)
+ {
+ positionDuration.x = fabsf(deltaX / u.x);
+ }
+ else
+ {
+ positionDuration.x = 0;
+ }
+ }
+
+ if(rulerY->IsEnabled() && rulerY->GetType() == Dali::Toolkit::Ruler::FREE)
+ {
+ float deltaY = fabsf(startPosition.y - positionSnap.y);
+
+ if(fabsf(u.y) > Math::MACHINE_EPSILON_1)
+ {
+ positionDuration.y = fabsf(deltaY / u.y);
+ }
+ else
+ {
+ positionDuration.y = 0;
+ }
+ }
+ }
- scrollMax = max - size.GetVectorXY();
+ if(scrollView.IsOvershootEnabled())
+ {
+ // Scroll to the end of the overshoot only when overshoot is enabled.
+ positionSnap += clampDelta;
+ }
}
} // unnamed namespace
DALI_TYPE_REGISTRATION_END()
-/**
- * Returns whether to lock scrolling to a particular axis
- *
- * @param[in] panDelta Distance panned since gesture started
- * @param[in] currentLockAxis The current lock axis value
- * @param[in] lockGradient How quickly to lock to a particular axis
- *
- * @return The new axis lock state
- */
-ScrollView::LockAxis GetLockAxis(const Vector2& panDelta, ScrollView::LockAxis currentLockAxis, float lockGradient)
-{
- if(panDelta.LengthSquared() > AUTOLOCK_AXIS_MINIMUM_DISTANCE2 &&
- currentLockAxis == ScrollView::LockPossible)
- {
- float dx = fabsf(panDelta.x);
- float dy = fabsf(panDelta.y);
- if(dx * lockGradient >= dy)
- {
- // 0.36:1 gradient to the horizontal (deviate < 20 degrees)
- currentLockAxis = ScrollView::LockVertical;
- }
- else if(dy * lockGradient > dx)
- {
- // 0.36:1 gradient to the vertical (deviate < 20 degrees)
- currentLockAxis = ScrollView::LockHorizontal;
- }
- else
- {
- currentLockAxis = ScrollView::LockNone;
- }
- }
- return currentLockAxis;
-}
-
-/**
- * Internal Pre-Position Property Constraint.
- *
- * Generates position property based on current position + gesture displacement.
- * Or generates position property based on positionX/Y.
- * Note: This is the position prior to any clamping at scroll boundaries.
- */
-struct InternalPrePositionConstraint
-{
- InternalPrePositionConstraint(const Vector2& initialPanPosition,
- const Vector2& initialPanMask,
- bool axisAutoLock,
- float axisAutoLockGradient,
- ScrollView::LockAxis initialLockAxis,
- const Vector2& maxOvershoot,
- const RulerPtr& rulerX,
- const RulerPtr& rulerY)
- : mLocalStart(initialPanPosition),
- mInitialPanMask(initialPanMask),
- mMaxOvershoot(maxOvershoot),
- mAxisAutoLockGradient(axisAutoLockGradient),
- mLockAxis(initialLockAxis),
- mAxisAutoLock(axisAutoLock),
- mWasPanning(false)
- {
- const RulerDomain& rulerDomainX = rulerX->GetDomain();
- const RulerDomain& rulerDomainY = rulerY->GetDomain();
- mDomainMin = Vector2(rulerDomainX.min, -rulerDomainY.min);
- mDomainMax = Vector2(-rulerDomainX.max, -rulerDomainY.max);
- mClampX = rulerDomainX.enabled;
- mClampY = rulerDomainY.enabled;
- mFixedRulerX = rulerX->GetType() == Ruler::FIXED;
- mFixedRulerY = rulerY->GetType() == Ruler::FIXED;
- }
-
- void operator()(Vector2& scrollPostPosition, const PropertyInputContainer& inputs)
- {
- const Vector2& panPosition = inputs[0]->GetVector2();
- const bool& inGesture = inputs[1]->GetBoolean();
-
- // First check if we are within a gesture.
- // The ScrollView may have received a start gesture from ::OnPan()
- // while the finish gesture is received now in this constraint.
- // This gesture must then be rejected as the value will be "old".
- // Typically the last value from the end of the last gesture.
- // If we are rejecting the gesture, we simply don't modify the constraint target.
- if(inGesture)
- {
- if(!mWasPanning)
- {
- mPrePosition = scrollPostPosition;
- mStartPosition = mPrePosition;
- mCurrentPanMask = mInitialPanMask;
- mWasPanning = true;
- }
-
- // Calculate Deltas...
- const Vector2& currentPosition = panPosition;
- Vector2 panDelta(currentPosition - mLocalStart);
-
- // Axis Auto Lock - locks the panning to the horizontal or vertical axis if the pan
- // appears mostly horizontal or mostly vertical respectively...
- if(mAxisAutoLock)
- {
- mLockAxis = GetLockAxis(panDelta, mLockAxis, mAxisAutoLockGradient);
- if(mLockAxis == ScrollView::LockVertical)
- {
- mCurrentPanMask.y = 0.0f;
- }
- else if(mLockAxis == ScrollView::LockHorizontal)
- {
- mCurrentPanMask.x = 0.0f;
- }
- }
-
- // Restrict deltas based on ruler enable/disable and axis-lock state...
- panDelta *= mCurrentPanMask;
-
- // Perform Position transform based on input deltas...
- scrollPostPosition = mPrePosition;
- scrollPostPosition += panDelta;
-
- // if no wrapping then clamp preposition to maximum overshoot amount
- const Vector3& size = inputs[2]->GetVector3();
- if(mClampX)
- {
- float newXPosition = Clamp(scrollPostPosition.x, (mDomainMax.x + size.x) - mMaxOvershoot.x, mDomainMin.x + mMaxOvershoot.x);
- if((newXPosition < scrollPostPosition.x - Math::MACHINE_EPSILON_1) || (newXPosition > scrollPostPosition.x + Math::MACHINE_EPSILON_1))
- {
- mPrePosition.x = newXPosition;
- mLocalStart.x = panPosition.x;
- }
- scrollPostPosition.x = newXPosition;
- }
- if(mClampY)
- {
- float newYPosition = Clamp(scrollPostPosition.y, (mDomainMax.y + size.y) - mMaxOvershoot.y, mDomainMin.y + mMaxOvershoot.y);
- if((newYPosition < scrollPostPosition.y - Math::MACHINE_EPSILON_1) || (newYPosition > scrollPostPosition.y + Math::MACHINE_EPSILON_1))
- {
- mPrePosition.y = newYPosition;
- mLocalStart.y = panPosition.y;
- }
- scrollPostPosition.y = newYPosition;
- }
-
- // If we are using a fixed ruler in a particular axis, limit the maximum pages scrolled on that axis.
- if(mFixedRulerX || mFixedRulerY)
- {
- // Here we limit the maximum amount that can be moved from the starting position of the gesture to one page.
- // We do this only if we have a fixed ruler (on that axis) and the mode is enabled.
- // Note: 1.0f is subtracted to keep the value within one page size (otherwise we stray on to the page after).
- // Note: A further 1.0f is subtracted to handle a compensation that happens later within the flick handling code in SnapWithVelocity().
- // When a flick is completed, an adjustment of 1.0f is sometimes made to allow for the scenario where:
- // A flick finishes before the update thread has advanced the scroll position past the previous snap point.
- Vector2 viewPageSizeLimit(size.x - (1.0f + 1.0f), size.y - (1.0f - 1.0f));
- Vector2 minPosition(mStartPosition.x - viewPageSizeLimit.x, mStartPosition.y - viewPageSizeLimit.y);
- Vector2 maxPosition(mStartPosition.x + viewPageSizeLimit.x, mStartPosition.y + viewPageSizeLimit.y);
-
- if(mFixedRulerX)
- {
- scrollPostPosition.x = Clamp(scrollPostPosition.x, minPosition.x, maxPosition.x);
- }
- if(mFixedRulerY)
- {
- scrollPostPosition.y = Clamp(scrollPostPosition.y, minPosition.y, maxPosition.y);
- }
- }
- }
- }
-
- Vector2 mPrePosition;
- Vector2 mLocalStart;
- Vector2 mStartPosition; ///< The start position of the gesture - used to limit scroll amount (not modified by clamping).
- Vector2 mInitialPanMask; ///< Initial pan mask (based on ruler settings).
- Vector2 mCurrentPanMask; ///< Current pan mask that can be altered by axis lock mode.
- Vector2 mDomainMin;
- Vector2 mDomainMax;
- Vector2 mMaxOvershoot;
-
- float mAxisAutoLockGradient; ///< Set by ScrollView
- ScrollView::LockAxis mLockAxis;
-
- bool mAxisAutoLock : 1; ///< Set by ScrollView
- bool mWasPanning : 1;
- bool mClampX : 1;
- bool mClampY : 1;
- bool mFixedRulerX : 1;
- bool mFixedRulerY : 1;
-};
-
-/**
- * Internal Position Property Constraint.
- *
- * Generates position property based on pre-position
- * Note: This is the position after clamping.
- * (uses result of InternalPrePositionConstraint)
- */
-struct InternalPositionConstraint
-{
- InternalPositionConstraint(const RulerDomain& domainX, const RulerDomain& domainY, bool wrap)
- : mDomainMin(-domainX.min, -domainY.min),
- mDomainMax(-domainX.max, -domainY.max),
- mClampX(domainX.enabled),
- mClampY(domainY.enabled),
- mWrap(wrap)
- {
- }
-
- void operator()(Vector2& position, const PropertyInputContainer& inputs)
- {
- position = inputs[0]->GetVector2();
- const Vector2& size = inputs[3]->GetVector3().GetVectorXY();
- const Vector2& min = inputs[1]->GetVector2();
- const Vector2& max = inputs[2]->GetVector2();
-
- if(mWrap)
- {
- position.x = -WrapInDomain(-position.x, min.x, max.x);
- position.y = -WrapInDomain(-position.y, min.y, max.y);
- }
- else
- {
- // clamp post position to domain
- position.x = mClampX ? Clamp(position.x, mDomainMax.x + size.x, mDomainMin.x) : position.x;
- position.y = mClampY ? Clamp(position.y, mDomainMax.y + size.y, mDomainMin.y) : position.y;
- }
- }
-
- Vector2 mDomainMin;
- Vector2 mDomainMax;
- bool mClampX;
- bool mClampY;
- bool mWrap;
-};
-
-/**
- * This constraint updates the X overshoot property using the difference
- * SCROLL_PRE_POSITION.x and SCROLL_POSITION.x, returning a relative value between 0.0f and 1.0f
- */
-struct OvershootXConstraint
-{
- OvershootXConstraint(float maxOvershoot)
- : mMaxOvershoot(maxOvershoot)
- {
- }
-
- void operator()(float& current, const PropertyInputContainer& inputs)
- {
- if(inputs[2]->GetBoolean())
- {
- const Vector2& scrollPrePosition = inputs[0]->GetVector2();
- const Vector2& scrollPostPosition = inputs[1]->GetVector2();
- float newOvershoot = scrollPrePosition.x - scrollPostPosition.x;
- current = (newOvershoot > 0.0f ? std::min(newOvershoot, mMaxOvershoot) : std::max(newOvershoot, -mMaxOvershoot)) / mMaxOvershoot;
- }
- else
- {
- current = 0.0f;
- }
- }
-
- float mMaxOvershoot;
-};
-
-/**
- * This constraint updates the Y overshoot property using the difference
- * SCROLL_PRE_POSITION.y and SCROLL_POSITION.y, returning a relative value between 0.0f and 1.0f
- */
-struct OvershootYConstraint
-{
- OvershootYConstraint(float maxOvershoot)
- : mMaxOvershoot(maxOvershoot)
- {
- }
-
- void operator()(float& current, const PropertyInputContainer& inputs)
- {
- if(inputs[2]->GetBoolean())
- {
- const Vector2& scrollPrePosition = inputs[0]->GetVector2();
- const Vector2& scrollPostPosition = inputs[1]->GetVector2();
- float newOvershoot = scrollPrePosition.y - scrollPostPosition.y;
- current = (newOvershoot > 0.0f ? std::min(newOvershoot, mMaxOvershoot) : std::max(newOvershoot, -mMaxOvershoot)) / mMaxOvershoot;
- }
- else
- {
- current = 0.0f;
- }
- }
-
- float mMaxOvershoot;
-};
-
-/**
- * Internal Position-Delta Property Constraint.
- *
- * Generates position-delta property based on scroll-position + scroll-offset properties.
- */
-void InternalPositionDeltaConstraint(Vector2& current, const PropertyInputContainer& inputs)
-{
- const Vector2& scrollPosition = inputs[0]->GetVector2();
- const Vector2& scrollOffset = inputs[1]->GetVector2();
-
- current = scrollPosition + scrollOffset;
-}
-
-/**
- * Internal Final Position Constraint
- * The position of content is:
- * of scroll-position + f(scroll-overshoot)
- * where f(...) function defines how overshoot
- * should affect final-position.
- */
-struct InternalFinalConstraint
-{
- InternalFinalConstraint(AlphaFunctionPrototype functionX,
- AlphaFunctionPrototype functionY)
- : mFunctionX(functionX),
- mFunctionY(functionY)
- {
- }
-
- void operator()(Vector2& current, const PropertyInputContainer& inputs)
- {
- const float& overshootx = inputs[1]->GetFloat();
- const float& overshooty = inputs[2]->GetFloat();
- Vector2 offset(mFunctionX(overshootx),
- mFunctionY(overshooty));
-
- current = inputs[0]->GetVector2() - offset;
- }
-
- AlphaFunctionPrototype mFunctionX;
- AlphaFunctionPrototype mFunctionY;
-};
-
} // namespace
///////////////////////////////////////////////////////////////////////////////////////////////////
self.SetProperty(Toolkit::Scrollable::Property::CAN_SCROLL_HORIZONTAL, mCanScrollHorizontal);
UpdatePropertyDomain();
- SetInternalConstraints();
+ mConstraints.SetInternalConstraints(*this);
// Connect wheel event
self.WheelEventSignal().Connect(this, &ScrollView::OnWheelEvent);
DALI_LOG_SCROLL_STATE("[0x%X]", this);
}
-AlphaFunction ScrollView::GetScrollSnapAlphaFunction() const
-{
- return mSnapAlphaFunction;
-}
-
-void ScrollView::SetScrollSnapAlphaFunction(AlphaFunction alpha)
-{
- mSnapAlphaFunction = alpha;
-}
-
-AlphaFunction ScrollView::GetScrollFlickAlphaFunction() const
-{
- return mFlickAlphaFunction;
-}
-
-void ScrollView::SetScrollFlickAlphaFunction(AlphaFunction alpha)
-{
- mFlickAlphaFunction = alpha;
-}
-
-float ScrollView::GetScrollSnapDuration() const
-{
- return mSnapDuration;
-}
-
-void ScrollView::SetScrollSnapDuration(float time)
-{
- mSnapDuration = time;
-}
-
-float ScrollView::GetScrollFlickDuration() const
-{
- return mFlickDuration;
-}
-
-void ScrollView::SetScrollFlickDuration(float time)
-{
- mFlickDuration = time;
-}
-
void ScrollView::ApplyEffect(Toolkit::ScrollViewEffect effect)
{
Dali::Toolkit::ScrollView self = Dali::Toolkit::ScrollView::DownCast(Self());
RemoveConstraintsFromBoundActors();
}
-const RulerPtr ScrollView::GetRulerX() const
-{
- return mRulerX;
-}
-
-const RulerPtr ScrollView::GetRulerY() const
-{
- return mRulerY;
-}
-
void ScrollView::SetRulerX(RulerPtr ruler)
{
mRulerX = ruler;
UpdatePropertyDomain();
- UpdateMainInternalConstraint();
+ mConstraints.UpdateMainInternalConstraint(*this);
}
void ScrollView::SetRulerY(RulerPtr ruler)
mRulerY = ruler;
UpdatePropertyDomain();
- UpdateMainInternalConstraint();
+ mConstraints.UpdateMainInternalConstraint(*this);
}
void ScrollView::UpdatePropertyDomain()
}
}
-bool ScrollView::GetScrollSensitive()
-{
- return mSensitive;
-}
-
void ScrollView::SetScrollSensitive(bool sensitive)
{
Actor self = Self();
mMaxOvershoot.y = overshootY;
mUserMaxOvershoot = mMaxOvershoot;
mDefaultMaxOvershoot = false;
- UpdateMainInternalConstraint();
-}
-
-void ScrollView::SetSnapOvershootAlphaFunction(AlphaFunction alpha)
-{
- mSnapOvershootAlphaFunction = alpha;
-}
-
-float ScrollView::GetSnapOvershootDuration()
-{
- return mSnapOvershootDuration;
-}
-
-void ScrollView::SetSnapOvershootDuration(float duration)
-{
- mSnapOvershootDuration = duration;
+ mConstraints.UpdateMainInternalConstraint(*this);
}
bool ScrollView::GetActorAutoSnap()
return mActorAutoSnapEnabled;
}
-void ScrollView::SetActorAutoSnap(bool enable)
-{
- mActorAutoSnapEnabled = enable;
-}
-
void ScrollView::SetAutoResize(bool enable)
{
mAutoResizeContainerEnabled = enable;
// TODO: This needs a lot of issues to be addressed before working.
}
-bool ScrollView::GetWrapMode() const
-{
- return mWrapMode;
-}
-
void ScrollView::SetWrapMode(bool enable)
{
mWrapMode = enable;
Self().SetProperty(Toolkit::ScrollView::Property::WRAP, enable);
}
-int ScrollView::GetScrollUpdateDistance() const
-{
- return mScrollUpdateDistance;
-}
-
-void ScrollView::SetScrollUpdateDistance(int distance)
-{
- mScrollUpdateDistance = distance;
-}
-
-bool ScrollView::GetAxisAutoLock() const
-{
- return mAxisAutoLock;
-}
-
void ScrollView::SetAxisAutoLock(bool enable)
{
mAxisAutoLock = enable;
- UpdateMainInternalConstraint();
-}
-
-float ScrollView::GetAxisAutoLockGradient() const
-{
- return mAxisAutoLockGradient;
+ mConstraints.UpdateMainInternalConstraint(*this);
}
void ScrollView::SetAxisAutoLockGradient(float gradient)
{
DALI_ASSERT_DEBUG(gradient >= 0.0f && gradient <= 1.0f);
mAxisAutoLockGradient = gradient;
- UpdateMainInternalConstraint();
-}
-
-float ScrollView::GetFrictionCoefficient() const
-{
- return mFrictionCoefficient;
+ mConstraints.UpdateMainInternalConstraint(*this);
}
void ScrollView::SetFrictionCoefficient(float friction)
mFrictionCoefficient = friction;
}
-float ScrollView::GetFlickSpeedCoefficient() const
-{
- return mFlickSpeedCoefficient;
-}
-
-void ScrollView::SetFlickSpeedCoefficient(float speed)
-{
- mFlickSpeedCoefficient = speed;
-}
-
-Vector2 ScrollView::GetMinimumDistanceForFlick() const
-{
- return mMinFlickDistance;
-}
-
-void ScrollView::SetMinimumDistanceForFlick(const Vector2& distance)
-{
- mMinFlickDistance = distance;
-}
-
-float ScrollView::GetMinimumSpeedForFlick() const
-{
- return mFlickSpeedThreshold;
-}
-
-void ScrollView::SetMinimumSpeedForFlick(float speed)
-{
- mFlickSpeedThreshold = speed;
-}
-
-float ScrollView::GetMaxFlickSpeed() const
-{
- return mMaxFlickSpeed;
-}
-
-void ScrollView::SetMaxFlickSpeed(float speed)
-{
- mMaxFlickSpeed = speed;
-}
-
-void ScrollView::SetWheelScrollDistanceStep(Vector2 step)
-{
- mWheelScrollDistanceStep = step;
-}
-
-Vector2 ScrollView::GetWheelScrollDistanceStep() const
-{
- return mWheelScrollDistanceStep;
-}
-
unsigned int ScrollView::GetCurrentPage() const
{
// in case animation is currently taking place.
mGestureStackDepth = 0;
self.SetProperty(Toolkit::ScrollView::Property::PANNING, false);
- if(mScrollMainInternalPrePositionConstraint)
+ if(mConstraints.mScrollMainInternalPrePositionConstraint)
{
- mScrollMainInternalPrePositionConstraint.Remove();
+ mConstraints.mScrollMainInternalPrePositionConstraint.Remove();
}
}
Vector2::ONE * duration,
alpha,
true,
- horizontalBias,
- verticalBias,
- SNAP);
-
- if(!animating)
- {
- // if not animating, then this pan has completed right now.
- self.SetProperty(Toolkit::ScrollView::Property::SCROLLING, false);
- mScrolling = false;
-
- // If we have no duration, then in the next update frame, we will be at the position specified as we just set.
- // In this scenario, we cannot return the currentScrollPosition as this is out-of-date and should instead return the requested final position
- Vector2 completedPosition(currentScrollPosition);
- if(duration <= Math::MACHINE_EPSILON_10)
- {
- completedPosition = position;
- }
-
- DALI_LOG_SCROLL_STATE("[0x%X] mScrollCompletedSignal 2 [%.2f, %.2f]", this, completedPosition.x, completedPosition.y);
- SetScrollUpdateNotification(false);
- mScrollCompletedSignal.Emit(completedPosition);
- }
-}
-
-void ScrollView::ScrollTo(const Vector2& position)
-{
- ScrollTo(position, mSnapDuration);
-}
-
-void ScrollView::ScrollTo(const Vector2& position, float duration)
-{
- ScrollTo(position, duration, DIRECTION_BIAS_NONE, DIRECTION_BIAS_NONE);
-}
-
-void ScrollView::ScrollTo(const Vector2& position, float duration, AlphaFunction alpha)
-{
- ScrollTo(position, duration, alpha, DIRECTION_BIAS_NONE, DIRECTION_BIAS_NONE);
-}
-
-void ScrollView::ScrollTo(const Vector2& position, float duration, DirectionBias horizontalBias, DirectionBias verticalBias)
-{
- ScrollTo(position, duration, mSnapAlphaFunction, horizontalBias, verticalBias);
-}
-
-void ScrollView::ScrollTo(const Vector2& position, float duration, AlphaFunction alpha, DirectionBias horizontalBias, DirectionBias verticalBias)
-{
- DALI_LOG_SCROLL_STATE("[0x%X] position[%.2f, %.2f] duration[%.2f], bias[%d, %d]", this, position.x, position.y, duration, int(horizontalBias), int(verticalBias));
- TransformTo(position, duration, alpha, horizontalBias, verticalBias);
-}
-
-void ScrollView::ScrollTo(unsigned int page)
-{
- ScrollTo(page, mSnapDuration);
-}
-
-void ScrollView::ScrollTo(unsigned int page, float duration, DirectionBias bias)
-{
- Vector2 position;
- unsigned int volume;
- unsigned int libraries;
-
- // The position to scroll to is continuous and linear
- // unless a domain has been enabled on the X axis.
- // or if WrapMode has been enabled.
- bool carryX = mRulerX->GetDomain().enabled | mWrapMode;
- bool carryY = mRulerY->GetDomain().enabled | mWrapMode;
-
- position.x = mRulerX->GetPositionFromPage(page, volume, carryX);
- position.y = mRulerY->GetPositionFromPage(volume, libraries, carryY);
-
- ScrollTo(position, duration, bias, bias);
-}
-
-void ScrollView::ScrollTo(Actor& actor)
-{
- ScrollTo(actor, mSnapDuration);
-}
-
-void ScrollView::ScrollTo(Actor& actor, float duration)
-{
- DALI_ASSERT_ALWAYS(actor.GetParent() == Self());
-
- Actor self = Self();
- Vector3 size = self.GetCurrentProperty<Vector3>(Actor::Property::SIZE);
- Vector3 position = actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION);
- Vector2 prePosition = GetPropertyPrePosition();
- position.GetVectorXY() -= prePosition;
-
- ScrollTo(Vector2(position.x - size.width * 0.5f, position.y - size.height * 0.5f), duration);
-}
-
-Actor ScrollView::FindClosestActor()
-{
- Actor self = Self();
- Vector3 size = self.GetCurrentProperty<Vector3>(Actor::Property::SIZE);
-
- return FindClosestActorToPosition(Vector3(size.width * 0.5f, size.height * 0.5f, 0.0f));
-}
-
-Actor ScrollView::FindClosestActorToPosition(const Vector3& position, FindDirection dirX, FindDirection dirY, FindDirection dirZ)
-{
- Actor closestChild;
- float closestDistance2 = 0.0f;
- Vector3 actualPosition = position;
-
- unsigned int numChildren = Self().GetChildCount();
-
- for(unsigned int i = 0; i < numChildren; ++i)
- {
- Actor child = Self().GetChildAt(i);
-
- if(mInternalActor == child) // ignore internal actor.
- {
- continue;
- }
-
- Vector3 childPosition = GetPositionOfAnchor(child, AnchorPoint::CENTER);
-
- Vector3 delta = childPosition - actualPosition;
-
- // X-axis checking (only find Actors to the [dirX] of actualPosition)
- if(dirX > All) // != All,None
- {
- FindDirection deltaH = delta.x > 0 ? Right : Left;
- if(dirX != deltaH)
- {
- continue;
- }
- }
-
- // Y-axis checking (only find Actors to the [dirY] of actualPosition)
- if(dirY > All) // != All,None
- {
- FindDirection deltaV = delta.y > 0 ? Down : Up;
- if(dirY != deltaV)
- {
- continue;
- }
- }
-
- // Z-axis checking (only find Actors to the [dirZ] of actualPosition)
- if(dirZ > All) // != All,None
- {
- FindDirection deltaV = delta.y > 0 ? In : Out;
- if(dirZ != deltaV)
- {
- continue;
- }
- }
-
- // compare child to closest child in terms of distance.
- float distance2 = 0.0f;
-
- // distance2 = the Square of the relevant dimensions of delta
- if(dirX != None)
- {
- distance2 += delta.x * delta.x;
- }
-
- if(dirY != None)
- {
- distance2 += delta.y * delta.y;
- }
-
- if(dirZ != None)
- {
- distance2 += delta.z * delta.z;
- }
-
- if(closestChild) // Next time.
- {
- if(distance2 < closestDistance2)
- {
- closestChild = child;
- closestDistance2 = distance2;
- }
- }
- else // First time.
- {
- closestChild = child;
- closestDistance2 = distance2;
- }
- }
-
- return closestChild;
-}
-
-bool ScrollView::ScrollToSnapPoint()
-{
- DALI_LOG_SCROLL_STATE("[0x%X]", this);
- Vector2 stationaryVelocity = Vector2(0.0f, 0.0f);
- return SnapWithVelocity(stationaryVelocity);
-}
-
-// TODO: In situations where axes are different (X snap, Y free)
-// Each axis should really have their own independent animation (time and equation)
-// Consider, X axis snapping to nearest grid point (EaseOut over fixed time)
-// Consider, Y axis simulating physics to arrive at a point (Physics equation over variable time)
-// Currently, the axes have been split however, they both use the same EaseOut equation.
-bool ScrollView::SnapWithVelocity(Vector2 velocity)
-{
- // Animator takes over now, touches are assumed not to interfere.
- // And if touches do interfere, then we'll stop animation, update PrePosition
- // to current mScroll's properties, and then resume.
- // Note: For Flicking this may work a bit different...
-
- float angle = atan2(velocity.y, velocity.x);
- float speed2 = velocity.LengthSquared();
- AlphaFunction alphaFunction = mSnapAlphaFunction;
- Vector2 positionDuration = Vector2::ONE * mSnapDuration;
- float biasX = 0.5f;
- float biasY = 0.5f;
- FindDirection horizontal = None;
- FindDirection vertical = None;
-
- // orthoAngleRange = Angle tolerance within the Exact N,E,S,W direction
- // that will be accepted as a general N,E,S,W flick direction.
-
- const float orthoAngleRange = FLICK_ORTHO_ANGLE_RANGE * M_PI / 180.0f;
- const float flickSpeedThreshold2 = mFlickSpeedThreshold * mFlickSpeedThreshold;
-
- Vector2 positionSnap = mScrollPrePosition;
-
- // Flick logic X Axis
-
- if(mRulerX->IsEnabled() && mLockAxis != LockHorizontal)
- {
- horizontal = All;
-
- if(speed2 > flickSpeedThreshold2 || // exceeds flick threshold
- mInAccessibilityPan) // With AccessibilityPan its easier to move between snap positions
- {
- if((angle >= -orthoAngleRange) && (angle < orthoAngleRange)) // Swiping East
- {
- biasX = 0.0f, horizontal = Left;
-
- // This guards against an error where no movement occurs, due to the flick finishing
- // before the update-thread has advanced mScrollPostPosition past the the previous snap point.
- positionSnap.x += 1.0f;
- }
- else if((angle >= M_PI - orthoAngleRange) || (angle < -M_PI + orthoAngleRange)) // Swiping West
- {
- biasX = 1.0f, horizontal = Right;
-
- // This guards against an error where no movement occurs, due to the flick finishing
- // before the update-thread has advanced mScrollPostPosition past the the previous snap point.
- positionSnap.x -= 1.0f;
- }
- }
- }
-
- // Flick logic Y Axis
+ horizontalBias,
+ verticalBias,
+ SNAP);
- if(mRulerY->IsEnabled() && mLockAxis != LockVertical)
+ if(!animating)
{
- vertical = All;
+ // if not animating, then this pan has completed right now.
+ self.SetProperty(Toolkit::ScrollView::Property::SCROLLING, false);
+ mScrolling = false;
- if(speed2 > flickSpeedThreshold2 || // exceeds flick threshold
- mInAccessibilityPan) // With AccessibilityPan its easier to move between snap positions
+ // If we have no duration, then in the next update frame, we will be at the position specified as we just set.
+ // In this scenario, we cannot return the currentScrollPosition as this is out-of-date and should instead return the requested final position
+ Vector2 completedPosition(currentScrollPosition);
+ if(duration <= Math::MACHINE_EPSILON_10)
{
- if((angle >= M_PI_2 - orthoAngleRange) && (angle < M_PI_2 + orthoAngleRange)) // Swiping South
- {
- biasY = 0.0f, vertical = Up;
- }
- else if((angle >= -M_PI_2 - orthoAngleRange) && (angle < -M_PI_2 + orthoAngleRange)) // Swiping North
- {
- biasY = 1.0f, vertical = Down;
- }
+ completedPosition = position;
}
- }
- // isFlick: Whether this gesture is a flick or not.
- bool isFlick = (horizontal != All || vertical != All);
- // isFreeFlick: Whether this gesture is a flick under free panning criteria.
- bool isFreeFlick = velocity.LengthSquared() > (FREE_FLICK_SPEED_THRESHOLD * FREE_FLICK_SPEED_THRESHOLD);
-
- if(isFlick || isFreeFlick)
- {
- positionDuration = Vector2::ONE * mFlickDuration;
- alphaFunction = mFlickAlphaFunction;
+ DALI_LOG_SCROLL_STATE("[0x%X] mScrollCompletedSignal 2 [%.2f, %.2f]", this, completedPosition.x, completedPosition.y);
+ SetScrollUpdateNotification(false);
+ mScrollCompletedSignal.Emit(completedPosition);
}
+}
- // Calculate next positionSnap ////////////////////////////////////////////////////////////
-
- if(mActorAutoSnapEnabled)
- {
- Vector3 size = Self().GetCurrentProperty<Vector3>(Actor::Property::SIZE);
+void ScrollView::ScrollTo(const Vector2& position)
+{
+ ScrollTo(position, mSnapDuration);
+}
- Actor child = FindClosestActorToPosition(Vector3(size.width * 0.5f, size.height * 0.5f, 0.0f), horizontal, vertical);
+void ScrollView::ScrollTo(const Vector2& position, float duration)
+{
+ ScrollTo(position, duration, DIRECTION_BIAS_NONE, DIRECTION_BIAS_NONE);
+}
- if(!child && isFlick)
- {
- // If we conducted a direction limited search and found no actor, then just snap to the closest actor.
- child = FindClosestActorToPosition(Vector3(size.width * 0.5f, size.height * 0.5f, 0.0f));
- }
+void ScrollView::ScrollTo(const Vector2& position, float duration, AlphaFunction alpha)
+{
+ ScrollTo(position, duration, alpha, DIRECTION_BIAS_NONE, DIRECTION_BIAS_NONE);
+}
- if(child)
- {
- Vector2 position = Self().GetCurrentProperty<Vector2>(Toolkit::ScrollView::Property::SCROLL_POSITION);
+void ScrollView::ScrollTo(const Vector2& position, float duration, DirectionBias horizontalBias, DirectionBias verticalBias)
+{
+ ScrollTo(position, duration, mSnapAlphaFunction, horizontalBias, verticalBias);
+}
- // Get center-point of the Actor.
- Vector3 childPosition = GetPositionOfAnchor(child, AnchorPoint::CENTER);
+void ScrollView::ScrollTo(const Vector2& position, float duration, AlphaFunction alpha, DirectionBias horizontalBias, DirectionBias verticalBias)
+{
+ DALI_LOG_SCROLL_STATE("[0x%X] position[%.2f, %.2f] duration[%.2f], bias[%d, %d]", this, position.x, position.y, duration, int(horizontalBias), int(verticalBias));
+ TransformTo(position, duration, alpha, horizontalBias, verticalBias);
+}
- if(mRulerX->IsEnabled())
- {
- positionSnap.x = position.x - childPosition.x + size.width * 0.5f;
- }
- if(mRulerY->IsEnabled())
- {
- positionSnap.y = position.y - childPosition.y + size.height * 0.5f;
- }
- }
- }
+void ScrollView::ScrollTo(unsigned int page)
+{
+ ScrollTo(page, mSnapDuration);
+}
- Vector2 startPosition = positionSnap;
- positionSnap.x = -mRulerX->Snap(-positionSnap.x, biasX); // NOTE: X & Y rulers think in -ve coordinate system.
- positionSnap.y = -mRulerY->Snap(-positionSnap.y, biasY); // That is scrolling RIGHT (e.g. 100.0, 0.0) means moving LEFT.
+void ScrollView::ScrollTo(unsigned int page, float duration, DirectionBias bias)
+{
+ Vector2 position;
+ unsigned int volume;
+ unsigned int libraries;
- Vector2 clampDelta(Vector2::ZERO);
- ClampPosition(positionSnap);
+ // The position to scroll to is continuous and linear
+ // unless a domain has been enabled on the X axis.
+ // or if WrapMode has been enabled.
+ bool carryX = mRulerX->GetDomain().enabled | mWrapMode;
+ bool carryY = mRulerY->GetDomain().enabled | mWrapMode;
- if((mRulerX->GetType() == Ruler::FREE || mRulerY->GetType() == Ruler::FREE) && isFreeFlick && !mActorAutoSnapEnabled)
- {
- // Calculate target position based on velocity of flick.
+ position.x = mRulerX->GetPositionFromPage(page, volume, carryX);
+ position.y = mRulerY->GetPositionFromPage(volume, libraries, carryY);
- // a = Deceleration (Set to diagonal stage length * friction coefficient)
- // u = Initial Velocity (Flick velocity)
- // v = 0 (Final Velocity)
- // t = Time (Velocity / Deceleration)
- Vector2 stageSize = Stage::GetCurrent().GetSize();
- float stageLength = Vector3(stageSize.x, stageSize.y, 0.0f).Length();
- float a = (stageLength * mFrictionCoefficient);
- Vector3 u = Vector3(velocity.x, velocity.y, 0.0f) * mFlickSpeedCoefficient;
- float speed = u.Length();
- u /= speed;
+ ScrollTo(position, duration, bias, bias);
+}
- // TODO: Change this to a decay function. (faster you flick, the slower it should be)
- speed = std::min(speed, stageLength * mMaxFlickSpeed);
- u *= speed;
- alphaFunction = ConstantDecelerationAlphaFunction;
+void ScrollView::ScrollTo(Actor& actor)
+{
+ ScrollTo(actor, mSnapDuration);
+}
- float t = speed / a;
+void ScrollView::ScrollTo(Actor& actor, float duration)
+{
+ DALI_ASSERT_ALWAYS(actor.GetParent() == Self());
- if(mRulerX->IsEnabled() && mRulerX->GetType() == Ruler::FREE)
- {
- positionSnap.x += t * u.x * 0.5f;
- }
+ Actor self = Self();
+ Vector3 size = self.GetCurrentProperty<Vector3>(Actor::Property::SIZE);
+ Vector3 position = actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION);
+ Vector2 prePosition = GetPropertyPrePosition();
+ position.GetVectorXY() -= prePosition;
- if(mRulerY->IsEnabled() && mRulerY->GetType() == Ruler::FREE)
- {
- positionSnap.y += t * u.y * 0.5f;
- }
+ ScrollTo(Vector2(position.x - size.width * 0.5f, position.y - size.height * 0.5f), duration);
+}
- clampDelta = positionSnap;
- ClampPosition(positionSnap);
- if((positionSnap - startPosition).LengthSquared() > Math::MACHINE_EPSILON_0)
- {
- clampDelta -= positionSnap;
- clampDelta.x = clampDelta.x > 0.0f ? std::min(clampDelta.x, mMaxOvershoot.x) : std::max(clampDelta.x, -mMaxOvershoot.x);
- clampDelta.y = clampDelta.y > 0.0f ? std::min(clampDelta.y, mMaxOvershoot.y) : std::max(clampDelta.y, -mMaxOvershoot.y);
- }
- else
- {
- clampDelta = Vector2::ZERO;
- }
+Actor ScrollView::FindClosestActor()
+{
+ Actor self = Self();
+ Vector3 size = self.GetCurrentProperty<Vector3>(Actor::Property::SIZE);
- // If Axis is Free and has velocity, then calculate time taken
- // to reach target based on velocity in axis.
- if(mRulerX->IsEnabled() && mRulerX->GetType() == Ruler::FREE)
- {
- float deltaX = fabsf(startPosition.x - positionSnap.x);
+ return FindClosestActorToPosition(Vector3(size.width * 0.5f, size.height * 0.5f, 0.0f));
+}
- if(fabsf(u.x) > Math::MACHINE_EPSILON_1)
- {
- positionDuration.x = fabsf(deltaX / u.x);
- }
- else
- {
- positionDuration.x = 0;
- }
- }
+Actor ScrollView::FindClosestActorToPosition(const Vector3& position, FindDirection dirX, FindDirection dirY, FindDirection dirZ)
+{
+ return ::FindClosestActorToPosition(Self(), mInternalActor, position, dirX, dirY, dirZ);
+}
- if(mRulerY->IsEnabled() && mRulerY->GetType() == Ruler::FREE)
- {
- float deltaY = fabsf(startPosition.y - positionSnap.y);
+bool ScrollView::ScrollToSnapPoint()
+{
+ DALI_LOG_SCROLL_STATE("[0x%X]", this);
+ Vector2 stationaryVelocity = Vector2(0.0f, 0.0f);
+ return SnapWithVelocity(stationaryVelocity);
+}
- if(fabsf(u.y) > Math::MACHINE_EPSILON_1)
- {
- positionDuration.y = fabsf(deltaY / u.y);
- }
- else
- {
- positionDuration.y = 0;
- }
- }
- }
+bool ScrollView::SnapWithVelocity(Vector2 velocity)
+{
+ Vector2 positionSnap = mScrollPrePosition;
+ Vector2 positionDuration = Vector2::ONE * mSnapDuration;
+ AlphaFunction alphaFunction = mSnapAlphaFunction;
+ bool isFlick;
+ bool isFreeFlick;
- if(IsOvershootEnabled())
- {
- // Scroll to the end of the overshoot only when overshoot is enabled.
- positionSnap += clampDelta;
- }
+ ::SnapWithVelocity(*this, mRulerX, mRulerY, mLockAxis, velocity, mMaxOvershoot, positionSnap, positionDuration, alphaFunction, mInAccessibilityPan, isFlick, isFreeFlick);
bool animating = AnimateTo(positionSnap, positionDuration, alphaFunction, false, DIRECTION_BIAS_NONE, DIRECTION_BIAS_NONE, isFlick || isFreeFlick ? FLICK : SNAP);
// Position Delta ///////////////////////////////////////////////////////
if(positionChanged)
{
- UpdateMainInternalConstraint();
+ mConstraints.UpdateMainInternalConstraint(*this);
if(mWrapMode && findShortcuts)
{
// In Wrap Mode, the shortest distance is a little less intuitive...
}
}
- UpdateMainInternalConstraint();
+ mConstraints.UpdateMainInternalConstraint(*this);
}
void ScrollView::AddOverlay(Actor actor)
bool ScrollView::AccessibleImpl::ScrollToChild(Actor child)
{
auto scrollView = Dali::Toolkit::ScrollView::DownCast(Self());
- if (Toolkit::GetImpl(scrollView).FindClosestActor() == child)
+ if(Toolkit::GetImpl(scrollView).FindClosestActor() == child)
{
return false;
}
}
}
UpdatePropertyDomain();
- UpdateMainInternalConstraint();
+ mConstraints.UpdateMainInternalConstraint(*this);
if(IsOvershootEnabled())
{
mOvershootIndicator->Reset();
self.SetProperty(Toolkit::ScrollView::Property::PANNING, true);
self.SetProperty(Toolkit::ScrollView::Property::START_PAGE_POSITION, Vector3(position.x, position.y, 0.0f));
- UpdateMainInternalConstraint();
+ mConstraints.UpdateMainInternalConstraint(*this);
Toolkit::ScrollBar scrollBar = mScrollBar.GetHandle();
if(scrollBar && mTransientScrollBar)
{
mPanning = false;
self.SetProperty(Toolkit::ScrollView::Property::PANNING, false);
- if(mScrollMainInternalPrePositionConstraint)
+ if(mConstraints.mScrollMainInternalPrePositionConstraint)
{
- mScrollMainInternalPrePositionConstraint.Remove();
+ mConstraints.mScrollMainInternalPrePositionConstraint.Remove();
}
Toolkit::ScrollBar scrollBar = mScrollBar.GetHandle();
{
Vector3 size = Self().GetCurrentProperty<Vector3>(Actor::Property::SIZE);
- position.x = -mRulerX->Clamp(-position.x, size.width, 1.0f, clamped.x); // NOTE: X & Y rulers think in -ve coordinate system.
- position.y = -mRulerY->Clamp(-position.y, size.height, 1.0f, clamped.y); // That is scrolling RIGHT (e.g. 100.0, 0.0) means moving LEFT.
+ ::ClampPosition(size, mRulerX, mRulerY, position, clamped);
}
void ScrollView::WrapPosition(Vector2& position) const
}
}
-void ScrollView::UpdateMainInternalConstraint()
-{
- // TODO: Only update the constraints which have changed, rather than remove all and add all again.
- // Requires a dali-core ApplyConstraintAt, or a ReplaceConstraint. The former is probably more flexible.
- Actor self = Self();
- PanGestureDetector detector(GetPanGestureDetector());
-
- if(mScrollMainInternalPositionConstraint)
- {
- mScrollMainInternalPositionConstraint.Remove();
- mScrollMainInternalDeltaConstraint.Remove();
- mScrollMainInternalFinalConstraint.Remove();
- mScrollMainInternalRelativeConstraint.Remove();
- mScrollMainInternalDomainConstraint.Remove();
- mScrollMainInternalPrePositionMaxConstraint.Remove();
- }
- if(mScrollMainInternalPrePositionConstraint)
- {
- mScrollMainInternalPrePositionConstraint.Remove();
- }
-
- // TODO: It's probably better to use a local displacement value as this will give a displacement when scrolling just commences
- // but we need to make sure than the gesture system gives displacement since last frame (60Hz), not displacement since last touch event (90Hz).
-
- // 1. First calculate the pre-position (this is the scroll position if no clamping has taken place)
- Vector2 initialPanMask = Vector2(mRulerX->IsEnabled() ? 1.0f : 0.0f, mRulerY->IsEnabled() ? 1.0f : 0.0f);
-
- if(mLockAxis == LockVertical)
- {
- initialPanMask.y = 0.0f;
- }
- else if(mLockAxis == LockHorizontal)
- {
- initialPanMask.x = 0.0f;
- }
-
- if(mPanning)
- {
- mScrollMainInternalPrePositionConstraint = Constraint::New<Vector2>(self,
- Toolkit::ScrollView::Property::SCROLL_PRE_POSITION,
- InternalPrePositionConstraint(mPanStartPosition,
- initialPanMask,
- mAxisAutoLock,
- mAxisAutoLockGradient,
- mLockAxis,
- mMaxOvershoot,
- mRulerX,
- mRulerY));
- mScrollMainInternalPrePositionConstraint.AddSource(Source(detector, PanGestureDetector::Property::LOCAL_POSITION));
- mScrollMainInternalPrePositionConstraint.AddSource(Source(detector, PanGestureDetector::Property::PANNING));
- mScrollMainInternalPrePositionConstraint.AddSource(Source(self, Actor::Property::SIZE));
- mScrollMainInternalPrePositionConstraint.Apply();
- }
-
- // 2. Second calculate the clamped position (actual position)
- mScrollMainInternalPositionConstraint = Constraint::New<Vector2>(self,
- Toolkit::ScrollView::Property::SCROLL_POSITION,
- InternalPositionConstraint(mRulerX->GetDomain(),
- mRulerY->GetDomain(),
- mWrapMode));
- mScrollMainInternalPositionConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_PRE_POSITION));
- mScrollMainInternalPositionConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::SCROLL_POSITION_MIN));
- mScrollMainInternalPositionConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::SCROLL_POSITION_MAX));
- mScrollMainInternalPositionConstraint.AddSource(Source(self, Actor::Property::SIZE));
- mScrollMainInternalPositionConstraint.Apply();
-
- mScrollMainInternalDeltaConstraint = Constraint::New<Vector2>(self, Toolkit::ScrollView::Property::SCROLL_POSITION_DELTA, InternalPositionDeltaConstraint);
- mScrollMainInternalDeltaConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_POSITION));
- mScrollMainInternalDeltaConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_DOMAIN_OFFSET));
- mScrollMainInternalDeltaConstraint.Apply();
-
- mScrollMainInternalFinalConstraint = Constraint::New<Vector2>(self, Toolkit::ScrollView::Property::SCROLL_FINAL, InternalFinalConstraint(FinalDefaultAlphaFunction, FinalDefaultAlphaFunction));
- mScrollMainInternalFinalConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_POSITION));
- mScrollMainInternalFinalConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::OVERSHOOT_X));
- mScrollMainInternalFinalConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::OVERSHOOT_Y));
- mScrollMainInternalFinalConstraint.Apply();
-
- mScrollMainInternalRelativeConstraint = Constraint::New<Vector2>(self, Toolkit::Scrollable::Property::SCROLL_RELATIVE_POSITION, InternalRelativePositionConstraint);
- mScrollMainInternalRelativeConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_POSITION));
- mScrollMainInternalRelativeConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::SCROLL_POSITION_MIN));
- mScrollMainInternalRelativeConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::SCROLL_POSITION_MAX));
- mScrollMainInternalRelativeConstraint.AddSource(LocalSource(Actor::Property::SIZE));
- mScrollMainInternalRelativeConstraint.Apply();
-
- mScrollMainInternalDomainConstraint = Constraint::New<Vector2>(self, Toolkit::ScrollView::Property::SCROLL_DOMAIN_SIZE, InternalScrollDomainConstraint);
- mScrollMainInternalDomainConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::SCROLL_POSITION_MIN));
- mScrollMainInternalDomainConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::SCROLL_POSITION_MAX));
- mScrollMainInternalDomainConstraint.AddSource(LocalSource(Actor::Property::SIZE));
- mScrollMainInternalDomainConstraint.Apply();
-
- mScrollMainInternalPrePositionMaxConstraint = Constraint::New<Vector2>(self, Toolkit::ScrollView::Property::SCROLL_PRE_POSITION_MAX, InternalPrePositionMaxConstraint);
- mScrollMainInternalPrePositionMaxConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::SCROLL_POSITION_MAX));
- mScrollMainInternalPrePositionMaxConstraint.AddSource(LocalSource(Actor::Property::SIZE));
- mScrollMainInternalPrePositionMaxConstraint.Apply();
-
- // When panning we want to make sure overshoot values are affected by pre position and post position
- SetOvershootConstraintsEnabled(!mWrapMode);
-}
-
-void ScrollView::SetOvershootConstraintsEnabled(bool enabled)
-{
- Actor self(Self());
- // remove and reset, it may now be in wrong order with the main internal constraints
- if(mScrollMainInternalOvershootXConstraint)
- {
- mScrollMainInternalOvershootXConstraint.Remove();
- mScrollMainInternalOvershootXConstraint.Reset();
- mScrollMainInternalOvershootYConstraint.Remove();
- mScrollMainInternalOvershootYConstraint.Reset();
- }
- if(enabled)
- {
- mScrollMainInternalOvershootXConstraint = Constraint::New<float>(self, Toolkit::ScrollView::Property::OVERSHOOT_X, OvershootXConstraint(mMaxOvershoot.x));
- mScrollMainInternalOvershootXConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_PRE_POSITION));
- mScrollMainInternalOvershootXConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_POSITION));
- mScrollMainInternalOvershootXConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::CAN_SCROLL_HORIZONTAL));
- mScrollMainInternalOvershootXConstraint.Apply();
-
- mScrollMainInternalOvershootYConstraint = Constraint::New<float>(self, Toolkit::ScrollView::Property::OVERSHOOT_Y, OvershootYConstraint(mMaxOvershoot.y));
- mScrollMainInternalOvershootYConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_PRE_POSITION));
- mScrollMainInternalOvershootYConstraint.AddSource(LocalSource(Toolkit::ScrollView::Property::SCROLL_POSITION));
- mScrollMainInternalOvershootYConstraint.AddSource(LocalSource(Toolkit::Scrollable::Property::CAN_SCROLL_VERTICAL));
- mScrollMainInternalOvershootYConstraint.Apply();
- }
- else
- {
- self.SetProperty(Toolkit::ScrollView::Property::OVERSHOOT_X, 0.0f);
- self.SetProperty(Toolkit::ScrollView::Property::OVERSHOOT_Y, 0.0f);
- }
-}
-
-void ScrollView::SetInternalConstraints()
-{
- // Internal constraints (applied to target ScrollBase Actor itself) /////////
- UpdateMainInternalConstraint();
-
- // User definable constraints to apply to all child actors //////////////////
- Actor self = Self();
-
- // Apply some default constraints to ScrollView & its bound actors
- // Movement + Wrap function
-
- Constraint constraint;
-
- // MoveActor (scrolling)
- constraint = Constraint::New<Vector3>(self, Actor::Property::POSITION, MoveActorConstraint);
- constraint.AddSource(Source(self, Toolkit::ScrollView::Property::SCROLL_POSITION));
- constraint.SetRemoveAction(Constraint::DISCARD);
- ApplyConstraintToBoundActors(constraint);
-
- // WrapActor (wrap functionality)
- constraint = Constraint::New<Vector3>(self, Actor::Property::POSITION, WrapActorConstraint);
- constraint.AddSource(LocalSource(Actor::Property::SCALE));
- constraint.AddSource(LocalSource(Actor::Property::ANCHOR_POINT));
- constraint.AddSource(LocalSource(Actor::Property::SIZE));
- constraint.AddSource(Source(self, Toolkit::Scrollable::Property::SCROLL_POSITION_MIN));
- constraint.AddSource(Source(self, Toolkit::Scrollable::Property::SCROLL_POSITION_MAX));
- constraint.AddSource(Source(self, Toolkit::ScrollView::Property::WRAP));
- constraint.SetRemoveAction(Constraint::DISCARD);
- ApplyConstraintToBoundActors(constraint);
-}
-
void ScrollView::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
{
Toolkit::ScrollView scrollView = Toolkit::ScrollView::DownCast(Dali::BaseHandle(object));
SetRulerY(rulerY);
}
+ScrollView::LockAxis GetLockAxis(const Vector2& panDelta, ScrollView::LockAxis currentLockAxis, float lockGradient)
+{
+ if(panDelta.LengthSquared() > AUTOLOCK_AXIS_MINIMUM_DISTANCE2 &&
+ currentLockAxis == ScrollView::LockPossible)
+ {
+ float dx = fabsf(panDelta.x);
+ float dy = fabsf(panDelta.y);
+ if(dx * lockGradient >= dy)
+ {
+ // 0.36:1 gradient to the horizontal (deviate < 20 degrees)
+ currentLockAxis = ScrollView::LockVertical;
+ }
+ else if(dy * lockGradient > dx)
+ {
+ // 0.36:1 gradient to the vertical (deviate < 20 degrees)
+ currentLockAxis = ScrollView::LockHorizontal;
+ }
+ else
+ {
+ currentLockAxis = ScrollView::LockNone;
+ }
+ }
+ return currentLockAxis;
+}
+
} // namespace Internal
} // namespace Toolkit
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view-effect.h>
#include <dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view.h>
+#include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl-constraints.h>
namespace Dali
{
/**
* @copydoc Toolkit::ScrollView::GetScrollSnapAlphaFunction
*/
- AlphaFunction GetScrollSnapAlphaFunction() const;
+ AlphaFunction GetScrollSnapAlphaFunction() const
+ {
+ return mSnapAlphaFunction;
+ }
/**
* @copydoc Toolkit::ScrollView::SetScrollSnapAlphaFunction
*/
- void SetScrollSnapAlphaFunction(AlphaFunction alpha);
+ void SetScrollSnapAlphaFunction(AlphaFunction alpha)
+ {
+ mSnapAlphaFunction = alpha;
+ }
/**
* @copydoc Toolkit::ScrollView::GetScrollFlickAlphaFunction
*/
- AlphaFunction GetScrollFlickAlphaFunction() const;
+ AlphaFunction GetScrollFlickAlphaFunction() const
+ {
+ return mFlickAlphaFunction;
+ }
/**
* @copydoc Toolkit::ScrollView::SetScrollFlickAlphaFunction
*/
- void SetScrollFlickAlphaFunction(AlphaFunction alpha);
+ void SetScrollFlickAlphaFunction(AlphaFunction alpha)
+ {
+ mFlickAlphaFunction = alpha;
+ }
/**
* @copydoc Toolkit::ScrollView::GetScrollSnapDuration
*/
- float GetScrollSnapDuration() const;
+ float GetScrollSnapDuration() const
+ {
+ return mSnapDuration;
+ }
/**
* @copydoc Toolkit::ScrollView::SetScrollSnapDuration
*/
- void SetScrollSnapDuration(float time);
+ void SetScrollSnapDuration(float time)
+ {
+ mSnapDuration = time;
+ }
/**
* @copydoc Toolkit::ScrollView::GetScrollFlickDuration
*/
- float GetScrollFlickDuration() const;
+ float GetScrollFlickDuration() const
+ {
+ return mFlickDuration;
+ }
/**
* @copydoc Toolkit::ScrollView::SetScrollFlickDuration
*/
- void SetScrollFlickDuration(float time);
+ void SetScrollFlickDuration(float time)
+ {
+ mFlickDuration = time;
+ }
/**
* @copydoc Toolkit::ScrollView::ApplyEffect
/**
* @copydoc Toolkit::ScrollView::GetRulerX
*/
- const RulerPtr GetRulerX() const;
+ const RulerPtr GetRulerX() const
+ {
+ return mRulerX;
+ }
/**
* @copydoc Toolkit::ScrollView::GetRulerY
*/
- const RulerPtr GetRulerY() const;
+ const RulerPtr GetRulerY() const
+ {
+ return mRulerY;
+ }
/**
* @copydoc Toolkit::ScrollView::SetRulerX
*
* @return whether the touch sensitivity is true or false.
*/
- bool GetScrollSensitive();
+ bool GetScrollSensitive()
+ {
+ return mSensitive;
+ }
/**
* @copydoc Toolkit::ScrollView::SetScrollSensitive
/**
* @copydoc Toolkit::ScrollView::SetSnapOvershootAlphaFunction
*/
- void SetSnapOvershootAlphaFunction(AlphaFunction alpha);
+ void SetSnapOvershootAlphaFunction(AlphaFunction alpha)
+ {
+ mSnapOvershootAlphaFunction = alpha;
+ }
/**
* Retrieve the duartion of Snap Overshoot animation
*
* @return the duration.
*/
- float GetSnapOvershootDuration();
+ float GetSnapOvershootDuration()
+ {
+ return mSnapOvershootDuration;
+ }
/**
* @copydoc Toolkit::ScrollView::SetSnapOvershootDuration
*/
- void SetSnapOvershootDuration(float duration);
+ void SetSnapOvershootDuration(float duration)
+ {
+ mSnapOvershootDuration = duration;
+ }
/**
* Retrieve whether Actor Auto-Snap mode is enabled or not.
/**
* @copydoc Toolkit::ScrollView::SetActorAutoSnap
*/
- void SetActorAutoSnap(bool enable);
+ void SetActorAutoSnap(bool enable)
+ {
+ mActorAutoSnapEnabled = enable;
+ }
/**
* Enables or Disables Auto Resizing mode for ScrollView contents.
*
* @return Wrap Mode Enabled flag.
*/
- bool GetWrapMode() const;
+ bool GetWrapMode() const
+ {
+ return mWrapMode;
+ }
/**
* @copydoc Toolkit::ScrollView::SetWrapMode
/**
* @copydoc Toolkit::ScrollView::GetScrollupdateDistance
*/
- int GetScrollUpdateDistance() const;
+ int GetScrollUpdateDistance() const
+ {
+ return mScrollUpdateDistance;
+ }
/**
* @copydoc Toolkit::ScrollView::SetScrollUpdateDistance
*/
- void SetScrollUpdateDistance(int distance);
+ void SetScrollUpdateDistance(int distance)
+ {
+ mScrollUpdateDistance = distance;
+ }
/**
* @copydoc Toolkit::ScrollView::GetAxisAutoLock
*/
- bool GetAxisAutoLock() const;
+ bool GetAxisAutoLock() const
+ {
+ return mAxisAutoLock;
+ }
/**
* @copydoc Toolkit::ScrollView::SetAxisAutoLock
/**
* @copydoc Toolkit::ScrollView::GetAxisAutoLockGradient
*/
- float GetAxisAutoLockGradient() const;
+ float GetAxisAutoLockGradient() const
+ {
+ return mAxisAutoLockGradient;
+ }
/**
* @copydoc Toolkit::ScrollView::SetAxisAutoLockGradient
/**
* @copydoc Toolkit::ScrollView::GetFrictionCoefficient
*/
- float GetFrictionCoefficient() const;
+ float GetFrictionCoefficient() const
+ {
+ return mFrictionCoefficient;
+ }
/**
* @copydoc Toolkit::ScrollView::SetFrictionCoefficient
/**
* @copydoc Toolkit::ScrollView::GetFlickSpeedCoefficient
*/
- float GetFlickSpeedCoefficient() const;
+ float GetFlickSpeedCoefficient() const
+ {
+ return mFlickSpeedCoefficient;
+ }
/**
* @copydoc Toolkit::ScrollView::SetFlickSpeedCoefficient
*/
- void SetFlickSpeedCoefficient(float speed);
+ void SetFlickSpeedCoefficient(float speed)
+ {
+ mFlickSpeedCoefficient = speed;
+ }
/**
* @copydoc Toolkit::ScrollView::GetMinimumDistanceForFlick
*/
- Vector2 GetMinimumDistanceForFlick() const;
+ Vector2 GetMinimumDistanceForFlick() const
+ {
+ return mMinFlickDistance;
+ }
/**
* @copydoc Toolkit::ScrollView::SetMinimumDistanceForFlick
*/
- void SetMinimumDistanceForFlick(const Vector2& distance);
+ void SetMinimumDistanceForFlick(const Vector2& distance)
+ {
+ mMinFlickDistance = distance;
+ }
/**
* @copydoc Toolkit::ScrollView::GetMinimumSpeedForFlick
*/
- float GetMinimumSpeedForFlick() const;
+ float GetMinimumSpeedForFlick() const
+ {
+ return mFlickSpeedThreshold;
+ }
/**
* @copydoc Toolkit::ScrollView::SetMinimumSpeedForFlick
*/
- void SetMinimumSpeedForFlick(float speed);
+ void SetMinimumSpeedForFlick(float speed)
+ {
+ mFlickSpeedThreshold = speed;
+ }
/**
* @copydoc Toolkit::ScrollView::GetMaxFlickSpeed
*/
- float GetMaxFlickSpeed() const;
+ float GetMaxFlickSpeed() const
+ {
+ return mMaxFlickSpeed;
+ }
/**
* @copydoc Toolkit::ScrollView::SetMaxFlickSpeed
*/
- void SetMaxFlickSpeed(float speed);
+ void SetMaxFlickSpeed(float speed)
+ {
+ mMaxFlickSpeed = speed;
+ }
/**
* @copydoc Toolkit::ScrollView::GetWheelScrollDistanceStep
*/
- Vector2 GetWheelScrollDistanceStep() const;
+ Vector2 GetWheelScrollDistanceStep() const
+ {
+ return mWheelScrollDistanceStep;
+ }
/**
* @copydoc Toolkit::ScrollView::SetWheelScrollDistanceStep
*/
- void SetWheelScrollDistanceStep(Vector2 step);
+ void SetWheelScrollDistanceStep(Vector2 step)
+ {
+ mWheelScrollDistanceStep = step;
+ }
/**
* @copydoc Toolkit::ScrollView::GetCurrentPage
*/
void WrapPosition(Vector2& position) const;
- /**
- * Updates the main internal scroll constraints with new ruler and domain
- * values
- */
- void UpdateMainInternalConstraint();
-
- /**
- * Enables/disables the overshoot constraints
- *
- * @param[in] enabled whether to enable or disable the overshoot constraints
- */
- void SetOvershootConstraintsEnabled(bool enabled);
-
- /**
- * Sets internal constraints for this ScrollView.
- * Many of these internal constraints are based on properties within
- * ScrollView.
- */
- void SetInternalConstraints();
-
protected:
struct AccessibleImpl : public Scrollable::AccessibleImpl
{
ScrollView& operator=(const ScrollView& rhs);
private:
+ ScrollViewConstraints mConstraints;
+
unsigned long mTouchDownTime; ///< The touch down time
int mGestureStackDepth; ///< How many gestures are currently occuring.
Vector2 mWheelScrollDistanceStep; ///< The step of scroll distance in actor coordinates in X and Y axes for each wheel event received.
- //ScrollInternalConstraintsPtr mScrollInternalConstraints;
- Constraint mScrollMainInternalPrePositionConstraint;
- Constraint mScrollMainInternalPositionConstraint;
- Constraint mScrollMainInternalOvershootXConstraint;
- Constraint mScrollMainInternalOvershootYConstraint;
- Constraint mScrollMainInternalDeltaConstraint;
- Constraint mScrollMainInternalFinalConstraint;
- Constraint mScrollMainInternalRelativeConstraint;
- Constraint mScrollMainInternalDomainConstraint;
- Constraint mScrollMainInternalPrePositionMaxConstraint;
-
ScrollOvershootIndicatorPtr mOvershootIndicator;
WeakHandle<Toolkit::ScrollBar> mScrollBar;
bool mCanScrollHorizontal : 1; ///< Local value of our property to check against
bool mCanScrollVertical : 1; ///< Local value of our property to check against
bool mTransientScrollBar : 1; ///< True if scroll-bar should be automatically show/hidden during/after panning
+
+ friend ScrollViewConstraints;
};
+/**
+ * Returns whether to lock scrolling to a particular axis
+ *
+ * @param[in] panDelta Distance panned since gesture started
+ * @param[in] currentLockAxis The current lock axis value
+ * @param[in] lockGradient How quickly to lock to a particular axis
+ *
+ * @return The new axis lock state
+ */
+ScrollView::LockAxis GetLockAxis(const Vector2& panDelta, ScrollView::LockAxis currentLockAxis, float lockGradient);
+
} // namespace Internal
// Helpers for public-api forwarding methods
// currently not called from code so compiler will optimize these away, kept here for future debugging
#define TABLEVIEW_TAG "DALI Toolkit::TableView "
-#define TV_LOG(fmt, args, ...) Debug::LogMessage(Debug::DebugInfo, TABLEVIEW_TAG fmt, ##args)
+#define TV_LOG(fmt, args, ...) Debug::LogMessageWithFunctionLine(Debug::DebugInfo, TABLEVIEW_TAG fmt, ##args)
//#define TABLEVIEW_DEBUG 1
#if defined(TABLEVIEW_DEBUG)
--- /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.
+ */
+
+#include <dali/public-api/actors/layer.h>
+
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
+#include <dali-toolkit/internal/text/text-view.h>
+
+namespace Dali::Toolkit::Internal
+{
+void CommonTextUtils::RenderText(
+ Actor textActor,
+ Text::RendererPtr renderer,
+ Text::ControllerPtr controller,
+ Text::DecoratorPtr decorator,
+ float alignmentOffset,
+ Actor& renderableActor,
+ Actor& backgroundActor,
+ Toolkit::Control& stencil,
+ std::vector<Actor>& clippingDecorationActors,
+ Text::Controller::UpdateTextType updateTextType)
+{
+ Actor newRenderableActor;
+
+ if(Text::Controller::NONE_UPDATED != (Text::Controller::MODEL_UPDATED & updateTextType))
+ {
+ if(renderer)
+ {
+ newRenderableActor = renderer->Render(controller->GetView(),
+ textActor,
+ Property::INVALID_INDEX, // Animatable property not supported
+ alignmentOffset,
+ DepthIndex::CONTENT);
+ }
+
+ if(renderableActor != newRenderableActor)
+ {
+ UnparentAndReset(backgroundActor);
+ UnparentAndReset(renderableActor);
+ renderableActor = newRenderableActor;
+
+ if(renderableActor)
+ {
+ backgroundActor = controller->CreateBackgroundActor();
+ }
+ }
+ }
+
+ if(renderableActor)
+ {
+ const Vector2& scrollOffset = controller->GetTextModel()->GetScrollPosition();
+
+ float renderableActorPositionX, renderableActorPositionY;
+
+ if(stencil)
+ {
+ renderableActorPositionX = scrollOffset.x + alignmentOffset;
+ renderableActorPositionY = scrollOffset.y;
+ }
+ else
+ {
+ Extents padding;
+ padding = textActor.GetProperty<Extents>(Toolkit::Control::Property::PADDING);
+
+ // Support Right-To-Left of padding
+ Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(textActor.GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
+ if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
+ {
+ std::swap(padding.start, padding.end);
+ }
+
+ renderableActorPositionX = scrollOffset.x + alignmentOffset + padding.start;
+ renderableActorPositionY = scrollOffset.y + padding.top;
+ }
+
+ renderableActor.SetProperty(Actor::Property::POSITION, Vector2(renderableActorPositionX, renderableActorPositionY));
+
+ // Make sure the actors are parented correctly with/without clipping
+ Actor self = stencil ? stencil : textActor;
+
+ Actor highlightActor;
+
+ for(std::vector<Actor>::iterator it = clippingDecorationActors.begin(),
+ endIt = clippingDecorationActors.end();
+ it != endIt;
+ ++it)
+ {
+ self.Add(*it);
+ it->LowerToBottom();
+
+ if(it->GetProperty<std::string>(Dali::Actor::Property::NAME) == "HighlightActor")
+ {
+ highlightActor = *it;
+ }
+ }
+ clippingDecorationActors.clear();
+
+ self.Add(renderableActor);
+
+ if(backgroundActor)
+ {
+ if(decorator && decorator->IsHighlightVisible())
+ {
+ self.Add(backgroundActor);
+ backgroundActor.SetProperty(Actor::Property::POSITION, Vector2(renderableActorPositionX, renderableActorPositionY)); // In text field's coords.
+ backgroundActor.LowerBelow(highlightActor);
+ }
+ else
+ {
+ renderableActor.Add(backgroundActor);
+ backgroundActor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f)); // In renderable actor's coords.
+ backgroundActor.LowerToBottom();
+ }
+ }
+ }
+}
+
+} // namespace Dali::Toolkit::Internal
--- /dev/null
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_CONTROLS_COMMON_TEXT_UTILS_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_CONTROLS_COMMON_TEXT_UTILS_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.
+ */
+
+#include <dali-toolkit/internal/text/decorator/text-decorator.h>
+#include <dali-toolkit/internal/text/rendering/text-renderer.h>
+#include <dali-toolkit/internal/text/text-controller.h>
+#include <dali-toolkit/public-api/controls/control.h>
+#include <dali-toolkit/public-api/controls/text-controls/text-editor.h>
+#include <dali/public-api/actors/actor.h>
+
+#include <dali/public-api/common/vector-wrapper.h>
+
+namespace Dali::Toolkit::Internal
+{
+class CommonTextUtils
+{
+public:
+ /**
+ * Common method to render text, setting up background, foreground actors with decorators/stencil.
+ * @param[in] textActor The TextEditor or TextField
+ * @param[in] renderer pointer to the text renderer
+ * @param[in] controller pointer to the text controller
+ * @param[in] decorator pointer to the text decorator
+ * @param[in] alignmentOffset Alignment offset
+ * @param[in,out] renderableActor Actor for rendering text
+ * @param[in,out] backgroundActor Actor for rendering background
+ * @param[in,out] stencil Clipping actor
+ * @param[in,out] clippingDecorationActors Clipping decoration actors
+ * @param[in] updateTextType How the text has been updated
+ */
+ static void RenderText(
+ Actor textActor,
+ Text::RendererPtr renderer,
+ Text::ControllerPtr controller,
+ Text::DecoratorPtr decorator,
+ float alignmentOffset,
+ Actor& renderableActor,
+ Actor& backgroundActor,
+ Toolkit::Control& stencil,
+ std::vector<Actor>& clippingDecorationActors,
+ Text::Controller::UpdateTextType updateTextType);
+};
+
+} // namespace Dali::Toolkit::Internal
+
+#endif //DALI_TOOLKIT_INTERNAL_TEXT_CONTROLS_COMMON_TEXT_UTILS_H
#include <dali/devel-api/object/property-helper-devel.h>
#include <dali/integration-api/adaptor-framework/adaptor.h>
#include <dali/integration-api/debug.h>
+#include <dali/public-api/actors/layer.h>
#include <dali/public-api/adaptor-framework/key.h>
#include <dali/public-api/common/dali-common.h>
#include <dali/public-api/object/type-registry-helper.h>
#include <limits>
// INTERNAL INCLUDES
-#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
#include <dali-toolkit/devel-api/text/rendering-backend.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
+#include <dali-toolkit/internal/controls/text-controls/text-editor-property-handler.h>
#include <dali-toolkit/internal/styling/style-manager-impl.h>
#include <dali-toolkit/internal/text/rendering/text-backend.h>
#include <dali-toolkit/internal/text/text-effects-style.h>
using namespace Dali::Toolkit::Text;
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gTextEditorLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
+#endif
+
namespace Dali
{
namespace Toolkit
{
namespace // unnamed namespace
{
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
-#endif
-
const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::DevelText::DEFAULT_RENDERING_BACKEND;
const float DEFAULT_SCROLL_SPEED = 1200.f; ///< The default scroll speed for the text editor in pixels/second.
} // unnamed namespace
DALI_TYPE_REGISTRATION_END()
// clang-format on
-const char* const IMAGE_MAP_FILENAME_STRING = "filename";
-
-/// Retrieves a filename from a value that is a Property::Map
-std::string GetImageFileNameFromPropertyValue(const Property::Value& value)
+Toolkit::TextEditor::InputStyle::Mask ConvertInputStyle(Text::InputStyle::Mask inputStyleMask)
{
- std::string filename;
- const Property::Map* map = value.GetMap();
- if(map)
+ Toolkit::TextEditor::InputStyle::Mask editorInputStyleMask = Toolkit::TextEditor::InputStyle::NONE;
+
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_COLOR))
{
- const Property::Value* filenameValue = map->Find(IMAGE_MAP_FILENAME_STRING);
- if(filenameValue)
- {
- filenameValue->Get(filename);
- }
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::COLOR);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_FAMILY))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_FAMILY);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_POINT_SIZE))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::POINT_SIZE);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_WEIGHT))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_WIDTH))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_SLANT))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_LINE_SPACING))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::LINE_SPACING);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_UNDERLINE))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::UNDERLINE);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_SHADOW))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::SHADOW);
}
- return filename;
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_EMBOSS))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::EMBOSS);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_OUTLINE))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::OUTLINE);
+ }
+ return editorInputStyleMask;
}
} // namespace
// Second-phase init of the implementation
// This can only be done after the CustomActor connection has been made...
- impl->Initialize();
-
- return handle;
-}
-
-void TextEditor::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
-{
- Toolkit::TextEditor textEditor = Toolkit::TextEditor::DownCast(Dali::BaseHandle(object));
-
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor SetProperty\n");
-
- if(textEditor)
- {
- TextEditor& impl(GetImpl(textEditor));
- DALI_ASSERT_DEBUG(impl.mController && "No text contoller");
- DALI_ASSERT_DEBUG(impl.mDecorator && "No text decorator");
-
- switch(index)
- {
- case Toolkit::DevelTextEditor::Property::RENDERING_BACKEND:
- {
- int backend = value.Get<int>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor %p RENDERING_BACKEND %d\n", impl.mController.Get(), backend);
-
- if(impl.mRenderingBackend != backend)
- {
- impl.mRenderingBackend = backend;
- impl.mRenderer.Reset();
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextEditor::Property::TEXT:
- {
- const std::string& text = value.Get<std::string>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p TEXT %s\n", impl.mController.Get(), text.c_str());
-
- impl.mController->SetText(text);
- break;
- }
- case Toolkit::TextEditor::Property::TEXT_COLOR:
- {
- const Vector4& textColor = value.Get<Vector4>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a);
-
- if(impl.mController->GetDefaultColor() != textColor)
- {
- impl.mController->SetDefaultColor(textColor);
- impl.mController->SetInputColor(textColor);
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextEditor::Property::FONT_FAMILY:
- {
- const std::string& fontFamily = value.Get<std::string>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str());
- impl.mController->SetDefaultFontFamily(fontFamily);
- break;
- }
- case Toolkit::TextEditor::Property::FONT_STYLE:
- {
- SetFontStyleProperty(impl.mController, value, Text::FontStyle::DEFAULT);
- break;
- }
- case Toolkit::TextEditor::Property::POINT_SIZE:
- {
- const float pointSize = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p POINT_SIZE %f\n", impl.mController.Get(), pointSize);
-
- if(!Equals(impl.mController->GetDefaultFontSize(Text::Controller::POINT_SIZE), pointSize))
- {
- impl.mController->SetDefaultFontSize(pointSize, Text::Controller::POINT_SIZE);
- }
- break;
- }
- case Toolkit::TextEditor::Property::HORIZONTAL_ALIGNMENT:
- {
- Text::HorizontalAlignment::Type alignment(static_cast<Text::HorizontalAlignment::Type>(-1)); // Set to invalid value to ensure a valid mode does get set
- if(Text::GetHorizontalAlignmentEnumeration(value, alignment))
- {
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p HORIZONTAL_ALIGNMENT %d\n", impl.mController.Get(), alignment);
- impl.mController->SetHorizontalAlignment(alignment);
- }
- break;
- }
- case Toolkit::TextEditor::Property::SCROLL_THRESHOLD:
- {
- const float threshold = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor %p SCROLL_THRESHOLD %f\n", impl.mController.Get(), threshold);
-
- impl.mDecorator->SetScrollThreshold(threshold);
- break;
- }
- case Toolkit::TextEditor::Property::SCROLL_SPEED:
- {
- const float speed = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor %p SCROLL_SPEED %f\n", impl.mController.Get(), speed);
-
- impl.mDecorator->SetScrollSpeed(speed);
- break;
- }
- case Toolkit::TextEditor::Property::PRIMARY_CURSOR_COLOR:
- {
- const Vector4& color = value.Get<Vector4>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p PRIMARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
-
- impl.mDecorator->SetCursorColor(PRIMARY_CURSOR, color);
- impl.RequestTextRelayout();
- break;
- }
- case Toolkit::TextEditor::Property::SECONDARY_CURSOR_COLOR:
- {
- const Vector4& color = value.Get<Vector4>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p SECONDARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
-
- impl.mDecorator->SetCursorColor(SECONDARY_CURSOR, color);
- impl.RequestTextRelayout();
- break;
- }
- case Toolkit::TextEditor::Property::ENABLE_CURSOR_BLINK:
- {
- const bool enable = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable);
-
- impl.mController->SetEnableCursorBlink(enable);
- impl.RequestTextRelayout();
- break;
- }
- case Toolkit::TextEditor::Property::CURSOR_BLINK_INTERVAL:
- {
- const float interval = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval);
-
- impl.mDecorator->SetCursorBlinkInterval(interval);
- break;
- }
- case Toolkit::TextEditor::Property::CURSOR_BLINK_DURATION:
- {
- const float duration = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration);
-
- impl.mDecorator->SetCursorBlinkDuration(duration);
- break;
- }
- case Toolkit::TextEditor::Property::CURSOR_WIDTH:
- {
- const int width = value.Get<int>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_WIDTH %d\n", impl.mController.Get(), width);
-
- impl.mDecorator->SetCursorWidth(width);
- impl.mController->GetLayoutEngine().SetCursorWidth(width);
- break;
- }
- case Toolkit::TextEditor::Property::GRAB_HANDLE_IMAGE:
- {
- const std::string imageFileName = value.Get<std::string>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str());
-
- if(imageFileName.size())
- {
- impl.mDecorator->SetHandleImage(GRAB_HANDLE, HANDLE_IMAGE_RELEASED, imageFileName);
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE:
- {
- const std::string imageFileName = value.Get<std::string>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str());
-
- if(imageFileName.size())
- {
- impl.mDecorator->SetHandleImage(GRAB_HANDLE, HANDLE_IMAGE_PRESSED, imageFileName);
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT:
- {
- const std::string filename = GetImageFileNameFromPropertyValue(value);
-
- if(filename.size())
- {
- impl.mDecorator->SetHandleImage(LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, filename);
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT:
- {
- const std::string filename = GetImageFileNameFromPropertyValue(value);
-
- if(filename.size())
- {
- impl.mDecorator->SetHandleImage(RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, filename);
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
- {
- const std::string filename = GetImageFileNameFromPropertyValue(value);
-
- if(filename.size())
- {
- impl.mDecorator->SetHandleImage(LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, filename);
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
- {
- const std::string filename = GetImageFileNameFromPropertyValue(value);
-
- if(filename.size())
- {
- impl.mDecorator->SetHandleImage(RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, filename);
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
- {
- const std::string filename = GetImageFileNameFromPropertyValue(value);
-
- if(filename.size())
- {
- impl.mDecorator->SetHandleImage(LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, filename);
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
- {
- const std::string filename = GetImageFileNameFromPropertyValue(value);
-
- if(filename.size())
- {
- impl.mDecorator->SetHandleImage(RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, filename);
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextEditor::Property::SELECTION_HIGHLIGHT_COLOR:
- {
- const Vector4 color = value.Get<Vector4>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p SELECTION_HIGHLIGHT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
-
- impl.mDecorator->SetHighlightColor(color);
- impl.RequestTextRelayout();
- break;
- }
- case Toolkit::TextEditor::Property::DECORATION_BOUNDING_BOX:
- {
- const Rect<int>& box = value.Get<Rect<int> >();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p DECORATION_BOUNDING_BOX %d,%d %dx%d\n", impl.mController.Get(), box.x, box.y, box.width, box.height);
-
- impl.mDecorator->SetBoundingBox(box);
- impl.RequestTextRelayout();
- break;
- }
- case Toolkit::TextEditor::Property::ENABLE_MARKUP:
- {
- const bool enableMarkup = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p ENABLE_MARKUP %d\n", impl.mController.Get(), enableMarkup);
-
- impl.mController->SetMarkupProcessorEnabled(enableMarkup);
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_COLOR:
- {
- const Vector4& inputColor = value.Get<Vector4>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p INPUT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), inputColor.r, inputColor.g, inputColor.b, inputColor.a);
-
- impl.mController->SetInputColor(inputColor);
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_FONT_FAMILY:
- {
- const std::string& fontFamily = value.Get<std::string>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str());
- impl.mController->SetInputFontFamily(fontFamily);
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_FONT_STYLE:
- {
- SetFontStyleProperty(impl.mController, value, Text::FontStyle::INPUT);
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_POINT_SIZE:
- {
- const float pointSize = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize);
- impl.mController->SetInputFontPointSize(pointSize);
- break;
- }
- case Toolkit::TextEditor::Property::LINE_SPACING:
- {
- const float lineSpacing = value.Get<float>();
- impl.mController->SetDefaultLineSpacing(lineSpacing);
- impl.mRenderer.Reset();
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_LINE_SPACING:
- {
- const float lineSpacing = value.Get<float>();
- impl.mController->SetInputLineSpacing(lineSpacing);
- impl.mRenderer.Reset();
- break;
- }
- case Toolkit::TextEditor::Property::UNDERLINE:
- {
- const bool update = SetUnderlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
- if(update)
- {
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_UNDERLINE:
- {
- const bool update = SetUnderlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
- if(update)
- {
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextEditor::Property::SHADOW:
- {
- const bool update = SetShadowProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
- if(update)
- {
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_SHADOW:
- {
- const bool update = SetShadowProperties(impl.mController, value, Text::EffectStyle::INPUT);
- if(update)
- {
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextEditor::Property::EMBOSS:
- {
- const bool update = SetEmbossProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
- if(update)
- {
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_EMBOSS:
- {
- const bool update = SetEmbossProperties(impl.mController, value, Text::EffectStyle::INPUT);
- if(update)
- {
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextEditor::Property::OUTLINE:
- {
- const bool update = SetOutlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
- if(update)
- {
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_OUTLINE:
- {
- const bool update = SetOutlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
- if(update)
- {
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextEditor::Property::SMOOTH_SCROLL:
- {
- const bool enable = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor SMOOTH_SCROLL %d\n", enable);
-
- impl.mScrollAnimationEnabled = enable;
- break;
- }
- case Toolkit::TextEditor::Property::SMOOTH_SCROLL_DURATION:
- {
- const float duration = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor SMOOTH_SCROLL_DURATION %f\n", duration);
-
- impl.mScrollAnimationDuration = duration;
- if(impl.mTextVerticalScroller)
- {
- impl.mTextVerticalScroller->SetDuration(duration);
- }
- break;
- }
- case Toolkit::TextEditor::Property::ENABLE_SCROLL_BAR:
- {
- const bool enable = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor SHOW_SCROLL_BAR %d\n", enable);
-
- impl.mScrollBarEnabled = enable;
- break;
- }
- case Toolkit::TextEditor::Property::SCROLL_BAR_SHOW_DURATION:
- {
- const float duration = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor SCROLL_BAR_SHOW_DURATION %f\n", duration);
-
- impl.mAnimationPeriod.delaySeconds = duration;
- break;
- }
- case Toolkit::TextEditor::Property::SCROLL_BAR_FADE_DURATION:
- {
- const float duration = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor SCROLL_BAR_FADE_DURATION %f\n", duration);
-
- impl.mAnimationPeriod.durationSeconds = duration;
- break;
- }
- case Toolkit::TextEditor::Property::PIXEL_SIZE:
- {
- const float pixelSize = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize);
-
- if(!Equals(impl.mController->GetDefaultFontSize(Text::Controller::PIXEL_SIZE), pixelSize))
- {
- impl.mController->SetDefaultFontSize(pixelSize, Text::Controller::PIXEL_SIZE);
- }
- break;
- }
- case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT:
- {
- const std::string& text = value.Get<std::string>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor::OnPropertySet %p PLACEHOLDER_TEXT %s\n", impl.mController.Get(), text.c_str());
-
- impl.mController->SetPlaceholderText(Controller::PLACEHOLDER_TYPE_INACTIVE, text);
- break;
- }
- case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT_COLOR:
- {
- const Vector4& textColor = value.Get<Vector4>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p PLACEHOLDER_TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a);
-
- if(impl.mController->GetPlaceholderTextColor() != textColor)
- {
- impl.mController->SetPlaceholderTextColor(textColor);
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextEditor::Property::ENABLE_SELECTION:
- {
- const bool enableSelection = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p ENABLE_SELECTION %d\n", impl.mController.Get(), enableSelection);
- impl.mController->SetSelectionEnabled(enableSelection);
- break;
- }
- case Toolkit::TextEditor::Property::PLACEHOLDER:
- {
- const Property::Map* map = value.GetMap();
- if(map)
- {
- impl.mController->SetPlaceholderProperty(*map);
- }
- break;
- }
- case Toolkit::TextEditor::Property::LINE_WRAP_MODE:
- {
- Text::LineWrap::Mode lineWrapMode(static_cast<Text::LineWrap::Mode>(-1)); // Set to invalid value to ensure a valid mode does get set
- if(GetLineWrapModeEnumeration(value, lineWrapMode))
- {
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p LineWrap::MODE %d\n", impl.mController.Get(), lineWrapMode);
- impl.mController->SetLineWrapMode(lineWrapMode);
- }
- break;
- }
- case Toolkit::DevelTextEditor::Property::ENABLE_SHIFT_SELECTION:
- {
- const bool shiftSelection = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p ENABLE_SHIFT_SELECTION %d\n", impl.mController.Get(), shiftSelection);
-
- impl.mController->SetShiftSelectionEnabled(shiftSelection);
- break;
- }
- case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE:
- {
- const bool grabHandleEnabled = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p ENABLE_GRAB_HANDLE %d\n", impl.mController.Get(), grabHandleEnabled);
-
- impl.mController->SetGrabHandleEnabled(grabHandleEnabled);
- break;
- }
- case Toolkit::DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
- {
- impl.mController->SetMatchLayoutDirection(value.Get<bool>() ? DevelText::MatchLayoutDirection::LOCALE : DevelText::MatchLayoutDirection::CONTENTS);
- break;
- }
- case Toolkit::DevelTextEditor::Property::MAX_LENGTH:
- {
- const int max = value.Get<int>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p MAX_LENGTH %d\n", impl.mController.Get(), max);
-
- impl.mController->SetMaximumNumberOfCharacters(max);
- break;
- }
- case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_START:
- {
- uint32_t start = static_cast<uint32_t>(value.Get<int>());
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p SELECTED_TEXT_START %d\n", impl.mController.Get(), start);
- impl.SetTextSelectionRange(&start, nullptr);
- break;
- }
- case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_END:
- {
- uint32_t end = static_cast<uint32_t>(value.Get<int>());
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p SELECTED_TEXT_END %d\n", impl.mController.Get(), end);
- impl.SetTextSelectionRange(nullptr, &end);
- break;
- }
- case Toolkit::DevelTextEditor::Property::ENABLE_EDITING:
- {
- const bool editable = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p ENABLE_EDITING %d\n", impl.mController.Get(), editable);
- impl.SetEditable(editable);
- break;
- }
- case Toolkit::DevelTextEditor::Property::HORIZONTAL_SCROLL_POSITION:
- {
- float horizontalScroll = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p HORIZONTAL_SCROLL_POSITION %d\n", impl.mController.Get(), horizontalScroll);
- if(horizontalScroll >= 0.0f)
- {
- impl.ScrollBy(Vector2(horizontalScroll - impl.GetHorizontalScrollPosition(), 0));
- }
- break;
- }
- case Toolkit::DevelTextEditor::Property::VERTICAL_SCROLL_POSITION:
- {
- float verticalScroll = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p VERTICAL_SCROLL_POSITION %d\n", impl.mController.Get(), verticalScroll);
- if(verticalScroll >= 0.0f)
- {
- impl.ScrollBy(Vector2(0, verticalScroll - impl.GetVerticalScrollPosition()));
- }
- break;
- }
- case Toolkit::DevelTextEditor::Property::FONT_SIZE_SCALE:
- {
- const float scale = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p FONT_SIZE_SCALE %f\n", impl.mController.Get(), scale);
-
- if(!Equals(impl.mController->GetFontSizeScale(), scale))
- {
- impl.mController->SetFontSizeScale(scale);
- }
- break;
- }
- case Toolkit::DevelTextEditor::Property::PRIMARY_CURSOR_POSITION:
- {
- uint32_t position = static_cast<uint32_t>(value.Get<int>());
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p PRIMARY_CURSOR_POSITION %d\n", impl.mController.Get(), position);
- if(impl.mController->SetPrimaryCursorPosition(position, impl.HasKeyInputFocus()))
- {
- impl.SetKeyInputFocus();
- }
- break;
- }
- case Toolkit::DevelTextEditor::Property::GRAB_HANDLE_COLOR:
- {
- const Vector4 color = value.Get<Vector4>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p GRAB_HANDLE_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
-
- impl.mDecorator->SetHandleColor(color);
- impl.RequestTextRelayout();
- break;
- }
- case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE_POPUP:
- {
- const bool grabHandlePopupEnabled = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p ENABLE_GRAB_HANDLE_POPUP %d\n", impl.mController.Get(), grabHandlePopupEnabled);
-
- impl.mController->SetGrabHandlePopupEnabled(grabHandlePopupEnabled);
- break;
- }
- case Toolkit::DevelTextEditor::Property::INPUT_METHOD_SETTINGS:
- {
- const Property::Map* map = value.GetMap();
- if(map)
- {
- impl.mInputMethodOptions.ApplyProperty(*map);
- }
- impl.mController->SetInputModePassword(impl.mInputMethodOptions.IsPassword());
-
- Toolkit::Control control = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
- if(control == textEditor)
- {
- impl.mInputMethodContext.ApplyOptions(impl.mInputMethodOptions);
- }
- break;
- }
- case Toolkit::DevelTextEditor::Property::INPUT_FILTER:
- {
- const Property::Map* map = value.GetMap();
- if(map)
- {
- impl.mController->SetInputFilterOption(*map);
- }
- break;
- }
- case Toolkit::DevelTextEditor::Property::ELLIPSIS:
- {
- const bool ellipsis = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis);
+ impl->Initialize();
- impl.mController->SetTextElideEnabled(ellipsis);
- break;
- }
- case Toolkit::DevelTextEditor::Property::ELLIPSIS_POSITION:
- {
- DevelText::EllipsisPosition::Type ellipsisPositionType(static_cast<DevelText::EllipsisPosition::Type>(-1)); // Set to invalid value to ensure a valid mode does get set
- if(GetEllipsisPositionTypeEnumeration(value, ellipsisPositionType))
- {
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p EllipsisPosition::Type %d\n", impl.mController.Get(), ellipsisPositionType);
- impl.mController->SetEllipsisPosition(ellipsisPositionType);
- }
- break;
- }
- case Toolkit::DevelTextEditor::Property::MIN_LINE_SIZE:
- {
- const float minLineSize = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor %p MIN_LINE_SIZE %f\n", impl.mController.Get(), minLineSize);
+ return handle;
+}
- impl.mController->SetDefaultLineSize(minLineSize);
- impl.mRenderer.Reset();
- break;
- }
- } // switch
- } // texteditor
+void TextEditor::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
+{
+ Toolkit::TextEditor textEditor = Toolkit::TextEditor::DownCast(Dali::BaseHandle(object));
+
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor SetProperty\n");
+
+ if(textEditor)
+ {
+ PropertyHandler::SetProperty(textEditor, index, value);
+ }
}
Property::Value TextEditor::GetProperty(BaseObject* object, Property::Index index)
if(textEditor)
{
- TextEditor& impl(GetImpl(textEditor));
- DALI_ASSERT_DEBUG(impl.mController && "No text contoller");
- DALI_ASSERT_DEBUG(impl.mDecorator && "No text decorator");
-
- switch(index)
- {
- case Toolkit::DevelTextEditor::Property::RENDERING_BACKEND:
- {
- value = impl.mRenderingBackend;
- break;
- }
- case Toolkit::TextEditor::Property::TEXT:
- {
- std::string text;
- impl.mController->GetText(text);
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p returning text: %s\n", impl.mController.Get(), text.c_str());
- value = text;
- break;
- }
- case Toolkit::TextEditor::Property::TEXT_COLOR:
- {
- value = impl.mController->GetDefaultColor();
- break;
- }
- case Toolkit::TextEditor::Property::FONT_FAMILY:
- {
- value = impl.mController->GetDefaultFontFamily();
- break;
- }
- case Toolkit::TextEditor::Property::FONT_STYLE:
- {
- GetFontStyleProperty(impl.mController, value, Text::FontStyle::DEFAULT);
- break;
- }
- case Toolkit::TextEditor::Property::POINT_SIZE:
- {
- value = impl.mController->GetDefaultFontSize(Text::Controller::POINT_SIZE);
- break;
- }
- case Toolkit::TextEditor::Property::HORIZONTAL_ALIGNMENT:
- {
- const char* name = GetHorizontalAlignmentString(impl.mController->GetHorizontalAlignment());
- if(name)
- {
- value = std::string(name);
- }
- break;
- }
- case Toolkit::TextEditor::Property::SCROLL_THRESHOLD:
- {
- value = impl.mDecorator->GetScrollThreshold();
- break;
- }
- case Toolkit::TextEditor::Property::SCROLL_SPEED:
- {
- value = impl.mDecorator->GetScrollSpeed();
- break;
- }
- case Toolkit::TextEditor::Property::PRIMARY_CURSOR_COLOR:
- {
- value = impl.mDecorator->GetColor(PRIMARY_CURSOR);
- break;
- }
- case Toolkit::TextEditor::Property::SECONDARY_CURSOR_COLOR:
- {
- value = impl.mDecorator->GetColor(SECONDARY_CURSOR);
- break;
- }
- case Toolkit::TextEditor::Property::ENABLE_CURSOR_BLINK:
- {
- value = impl.mController->GetEnableCursorBlink();
- break;
- }
- case Toolkit::TextEditor::Property::CURSOR_BLINK_INTERVAL:
- {
- value = impl.mDecorator->GetCursorBlinkInterval();
- break;
- }
- case Toolkit::TextEditor::Property::CURSOR_BLINK_DURATION:
- {
- value = impl.mDecorator->GetCursorBlinkDuration();
- break;
- }
- case Toolkit::TextEditor::Property::CURSOR_WIDTH:
- {
- value = impl.mDecorator->GetCursorWidth();
- break;
- }
- case Toolkit::TextEditor::Property::GRAB_HANDLE_IMAGE:
- {
- value = impl.mDecorator->GetHandleImage(GRAB_HANDLE, HANDLE_IMAGE_RELEASED);
- break;
- }
- case Toolkit::TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE:
- {
- value = impl.mDecorator->GetHandleImage(GRAB_HANDLE, HANDLE_IMAGE_PRESSED);
- break;
- }
- case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT:
- {
- impl.GetHandleImagePropertyValue(value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED);
- break;
- }
- case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT:
- {
- impl.GetHandleImagePropertyValue(value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED);
- break;
- }
- case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
- {
- impl.GetHandleImagePropertyValue(value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED);
- break;
- }
- case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
- {
- impl.GetHandleImagePropertyValue(value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED);
- break;
- }
- case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
- {
- impl.GetHandleImagePropertyValue(value, LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED);
- break;
- }
- case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
- {
- impl.GetHandleImagePropertyValue(value, RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED);
- break;
- }
- case Toolkit::TextEditor::Property::SELECTION_HIGHLIGHT_COLOR:
- {
- value = impl.mDecorator->GetHighlightColor();
- break;
- }
- case Toolkit::TextEditor::Property::DECORATION_BOUNDING_BOX:
- {
- Rect<int> boundingBox;
- impl.mDecorator->GetBoundingBox(boundingBox);
- value = boundingBox;
- break;
- }
- case Toolkit::TextEditor::Property::ENABLE_MARKUP:
- {
- value = impl.mController->IsMarkupProcessorEnabled();
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_COLOR:
- {
- value = impl.mController->GetInputColor();
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_FONT_FAMILY:
- {
- value = impl.mController->GetInputFontFamily();
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_FONT_STYLE:
- {
- GetFontStyleProperty(impl.mController, value, Text::FontStyle::INPUT);
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_POINT_SIZE:
- {
- value = impl.mController->GetInputFontPointSize();
- break;
- }
- case Toolkit::TextEditor::Property::LINE_SPACING:
- {
- value = impl.mController->GetDefaultLineSpacing();
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_LINE_SPACING:
- {
- value = impl.mController->GetInputLineSpacing();
- break;
- }
- case Toolkit::TextEditor::Property::UNDERLINE:
- {
- GetUnderlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_UNDERLINE:
- {
- GetUnderlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
- break;
- }
- case Toolkit::TextEditor::Property::SHADOW:
- {
- GetShadowProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_SHADOW:
- {
- GetShadowProperties(impl.mController, value, Text::EffectStyle::INPUT);
- break;
- }
- case Toolkit::TextEditor::Property::EMBOSS:
- {
- GetEmbossProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_EMBOSS:
- {
- GetEmbossProperties(impl.mController, value, Text::EffectStyle::INPUT);
- break;
- }
- case Toolkit::TextEditor::Property::OUTLINE:
- {
- GetOutlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
- break;
- }
- case Toolkit::TextEditor::Property::INPUT_OUTLINE:
- {
- GetOutlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
- break;
- }
- case Toolkit::TextEditor::Property::SMOOTH_SCROLL:
- {
- value = impl.mScrollAnimationEnabled;
- break;
- }
- case Toolkit::TextEditor::Property::SMOOTH_SCROLL_DURATION:
- {
- value = impl.mScrollAnimationDuration;
- break;
- }
- case Toolkit::TextEditor::Property::ENABLE_SCROLL_BAR:
- {
- value = impl.mScrollBarEnabled;
- break;
- }
- case Toolkit::TextEditor::Property::SCROLL_BAR_SHOW_DURATION:
- {
- value = impl.mAnimationPeriod.delaySeconds;
- break;
- }
- case Toolkit::TextEditor::Property::SCROLL_BAR_FADE_DURATION:
- {
- value = impl.mAnimationPeriod.durationSeconds;
- break;
- }
- case Toolkit::TextEditor::Property::PIXEL_SIZE:
- {
- value = impl.mController->GetDefaultFontSize(Text::Controller::PIXEL_SIZE);
- break;
- }
- case Toolkit::TextEditor::Property::LINE_COUNT:
- {
- float width = textEditor.GetProperty(Actor::Property::SIZE_WIDTH).Get<float>();
- value = impl.mController->GetLineCount(width);
- break;
- }
- case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT:
- {
- std::string text;
- impl.mController->GetPlaceholderText(Controller::PLACEHOLDER_TYPE_INACTIVE, text);
- value = text;
- break;
- }
- case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT_COLOR:
- {
- value = impl.mController->GetPlaceholderTextColor();
- break;
- }
- case Toolkit::TextEditor::Property::ENABLE_SELECTION:
- {
- value = impl.mController->IsSelectionEnabled();
- break;
- }
- case Toolkit::TextEditor::Property::PLACEHOLDER:
- {
- Property::Map map;
- impl.mController->GetPlaceholderProperty(map);
- value = map;
- break;
- }
- case Toolkit::TextEditor::Property::LINE_WRAP_MODE:
- {
- value = impl.mController->GetLineWrapMode();
- break;
- }
- case Toolkit::DevelTextEditor::Property::ENABLE_SHIFT_SELECTION:
- {
- value = impl.mController->IsShiftSelectionEnabled();
- break;
- }
- case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE:
- {
- value = impl.mController->IsGrabHandleEnabled();
- break;
- }
- case Toolkit::DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
- {
- value = impl.mController->GetMatchLayoutDirection() != DevelText::MatchLayoutDirection::CONTENTS;
- break;
- }
- case Toolkit::DevelTextEditor::Property::MAX_LENGTH:
- {
- value = impl.mController->GetMaximumNumberOfCharacters();
- break;
- }
- case Toolkit::DevelTextEditor::Property::SELECTED_TEXT:
- {
- value = impl.mController->GetSelectedText();
- break;
- }
- case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_START:
- {
- Uint32Pair range = impl.GetTextSelectionRange();
- value = static_cast<int>(range.first);
- break;
- }
- case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_END:
- {
- Uint32Pair range = impl.GetTextSelectionRange();
- value = static_cast<int>(range.second);
- break;
- }
- case Toolkit::DevelTextEditor::Property::ENABLE_EDITING:
- {
- value = impl.IsEditable();
- break;
- }
- case Toolkit::DevelTextEditor::Property::HORIZONTAL_SCROLL_POSITION:
- {
- value = impl.GetHorizontalScrollPosition();
- break;
- }
- case Toolkit::DevelTextEditor::Property::VERTICAL_SCROLL_POSITION:
- {
- value = impl.GetVerticalScrollPosition();
- break;
- }
- case Toolkit::DevelTextEditor::Property::FONT_SIZE_SCALE:
- {
- value = impl.mController->GetFontSizeScale();
- break;
- }
- case Toolkit::DevelTextEditor::Property::PRIMARY_CURSOR_POSITION:
- {
- value = static_cast<int>(impl.mController->GetPrimaryCursorPosition());
- break;
- }
- case Toolkit::DevelTextEditor::Property::GRAB_HANDLE_COLOR:
- {
- value = impl.mDecorator->GetHandleColor();
- break;
- }
- case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE_POPUP:
- {
- value = impl.mController->IsGrabHandlePopupEnabled();
- break;
- }
- case Toolkit::DevelTextEditor::Property::INPUT_METHOD_SETTINGS:
- {
- Property::Map map;
- impl.mInputMethodOptions.RetrieveProperty(map);
- value = map;
- break;
- }
- case Toolkit::DevelTextEditor::Property::INPUT_FILTER:
- {
- Property::Map map;
- impl.mController->GetInputFilterOption(map);
- value = map;
- break;
- }
- case Toolkit::DevelTextEditor::Property::ELLIPSIS:
- {
- value = impl.mController->IsTextElideEnabled();
- break;
- }
- case Toolkit::DevelTextEditor::Property::ELLIPSIS_POSITION:
- {
- value = impl.mController->GetEllipsisPosition();
- break;
- }
- case Toolkit::DevelTextEditor::Property::MIN_LINE_SIZE:
- {
- value = impl.mController->GetDefaultLineSize();
- break;
- }
- } //switch
+ value = PropertyHandler::GetProperty(textEditor, index);
}
-
return value;
}
void TextEditor::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor::OnStyleChange\n");
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor::OnStyleChange\n");
switch(change)
{
case StyleChange::DEFAULT_FONT_CHANGE:
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor::OnStyleChange DEFAULT_FONT_CHANGE\n");
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor::OnStyleChange DEFAULT_FONT_CHANGE\n");
const std::string& newFont = GetImpl(styleManager).GetDefaultFontFamily();
// Property system did not set the font so should update it.
mController->UpdateAfterFontChange(newFont);
void TextEditor::OnRelayout(const Vector2& size, RelayoutContainer& container)
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor OnRelayout\n");
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor OnRelayout\n");
Actor self = Self();
if((Text::Controller::NONE_UPDATED != updateTextType) ||
!mRenderer)
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor::OnRelayout %p Displaying new contents\n", mController.Get());
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor::OnRelayout %p Displaying new contents\n", mController.Get());
if(mDecorator &&
(Text::Controller::NONE_UPDATED != (Text::Controller::DECORATOR_UPDATED & updateTextType)))
void TextEditor::RenderText(Text::Controller::UpdateTextType updateTextType)
{
- Actor renderableActor;
-
- if(Text::Controller::NONE_UPDATED != (Text::Controller::MODEL_UPDATED & updateTextType))
- {
- if(mRenderer)
- {
- Dali::Toolkit::TextEditor handle = Dali::Toolkit::TextEditor(GetOwner());
-
- renderableActor = mRenderer->Render(mController->GetView(),
- handle,
- Property::INVALID_INDEX, // Animatable property not supported
- mAlignmentOffset,
- DepthIndex::CONTENT);
- }
-
- if(renderableActor != mRenderableActor)
- {
- UnparentAndReset(mBackgroundActor);
- UnparentAndReset(mRenderableActor);
- mRenderableActor = renderableActor;
-
- if(mRenderableActor)
- {
- mBackgroundActor = mController->CreateBackgroundActor();
- }
- }
- }
-
+ CommonTextUtils::RenderText(Self(), mRenderer, mController, mDecorator, mAlignmentOffset, mRenderableActor, mBackgroundActor, mStencil, mClippingDecorationActors, updateTextType);
if(mRenderableActor)
{
- const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition();
-
- float renderableActorPositionX, renderableActorPositionY;
-
- if(mStencil)
- {
- renderableActorPositionX = scrollOffset.x + mAlignmentOffset;
- renderableActorPositionY = scrollOffset.y;
- }
- else
- {
- Extents padding;
- padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
-
- // Support Right-To-Left of padding
- Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(Self().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
- if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
- {
- std::swap(padding.start, padding.end);
- }
-
- renderableActorPositionX = scrollOffset.x + mAlignmentOffset + padding.start;
- renderableActorPositionY = scrollOffset.y + padding.top;
- }
-
- mRenderableActor.SetProperty(Actor::Property::POSITION, Vector2(renderableActorPositionX, renderableActorPositionY));
- // Make sure the actors are parented correctly with/without clipping
- Actor self = mStencil ? mStencil : Self();
-
- Actor highlightActor;
-
- for(std::vector<Actor>::iterator it = mClippingDecorationActors.begin(),
- endIt = mClippingDecorationActors.end();
- it != endIt;
- ++it)
- {
- self.Add(*it);
- it->LowerToBottom();
-
- if(it->GetProperty<std::string>(Dali::Actor::Property::NAME) == "HighlightActor")
- {
- highlightActor = *it;
- }
- }
- mClippingDecorationActors.clear();
-
- self.Add(mRenderableActor);
-
- if(mBackgroundActor)
- {
- if(mDecorator && mDecorator->IsHighlightVisible())
- {
- self.Add(mBackgroundActor);
- mBackgroundActor.SetProperty(Actor::Property::POSITION, Vector2(renderableActorPositionX, renderableActorPositionY)); // In text field's coords.
- mBackgroundActor.LowerBelow(highlightActor);
- }
- else
- {
- mRenderableActor.Add(mBackgroundActor);
- mBackgroundActor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f)); // In renderable actor's coords.
- mBackgroundActor.LowerToBottom();
- }
- }
-
ApplyScrollPosition();
}
UpdateScrollBar();
void TextEditor::OnKeyInputFocusGained()
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor::OnKeyInputFocusGained %p\n", mController.Get());
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor::OnKeyInputFocusGained %p\n", mController.Get());
if(mInputMethodContext && IsEditable())
{
// All input panel properties, such as layout, return key type, and input hint, should be set before input panel activates (or shows).
void TextEditor::OnKeyInputFocusLost()
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor:OnKeyInputFocusLost %p\n", mController.Get());
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor:OnKeyInputFocusLost %p\n", mController.Get());
if(mInputMethodContext)
{
mInputMethodContext.StatusChangedSignal().Disconnect(this, &TextEditor::KeyboardStatusChanged);
void TextEditor::OnTap(const TapGesture& gesture)
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor::OnTap %p\n", mController.Get());
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor::OnTap %p\n", mController.Get());
if(mInputMethodContext && IsEditable())
{
mInputMethodContext.Activate();
bool TextEditor::OnKeyEvent(const KeyEvent& event)
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor::OnKeyEvent %p keyCode %d\n", mController.Get(), event.GetKeyCode());
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor::OnKeyEvent %p keyCode %d\n", mController.Get(), event.GetKeyCode());
if(Dali::DALI_KEY_ESCAPE == event.GetKeyCode() && mController->ShouldClearFocusOnEscape())
{
void TextEditor::InputStyleChanged(Text::InputStyle::Mask inputStyleMask)
{
Dali::Toolkit::TextEditor handle(GetOwner());
-
- Toolkit::TextEditor::InputStyle::Mask editorInputStyleMask = Toolkit::TextEditor::InputStyle::NONE;
-
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_COLOR))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::COLOR);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_FAMILY))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_FAMILY);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_POINT_SIZE))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::POINT_SIZE);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_WEIGHT))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_WIDTH))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_SLANT))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_LINE_SPACING))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::LINE_SPACING);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_UNDERLINE))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::UNDERLINE);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_SHADOW))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::SHADOW);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_EMBOSS))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::EMBOSS);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_OUTLINE))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::OUTLINE);
- }
-
- mInputStyleChangedSignal.Emit(handle, editorInputStyleMask);
+ mInputStyleChangedSignal.Emit(handle, ConvertInputStyle(inputStyleMask));
}
void TextEditor::AnchorClicked(const std::string& href)
InputMethodContext::CallbackData TextEditor::OnInputMethodContextEvent(Dali::InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor::OnInputMethodContextEvent %p eventName %d\n", mController.Get(), inputMethodContextEvent.eventName);
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor::OnInputMethodContextEvent %p eventName %d\n", mController.Get(), inputMethodContextEvent.eventName);
return mController->OnInputMethodContextEvent(inputMethodContext, inputMethodContextEvent);
}
if(mDecorator)
{
Property::Map map;
- map[IMAGE_MAP_FILENAME_STRING] = mDecorator->GetHandleImage(handleType, handleImageType);
- value = map;
+ map[TextEditor::PropertyHandler::IMAGE_MAP_FILENAME_STRING] = mDecorator->GetHandleImage(handleType, handleImageType);
+
+ value = map;
}
}
void TextEditor::KeyboardStatusChanged(bool keyboardShown)
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor::KeyboardStatusChanged %p keyboardShown %d\n", mController.Get(), keyboardShown);
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor::KeyboardStatusChanged %p keyboardShown %d\n", mController.Get(), keyboardShown);
// Just hide the grab handle when keyboard is hidden.
if(!keyboardShown)
uint32_t mOldSelectionStart;
uint32_t mOldSelectionEnd;
+ struct PropertyHandler;
+
/**
* @brief This structure is to connect TextEditor with Accessible functions.
*/
--- /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.
+ */
+
+#include <dali-toolkit/internal/controls/text-controls/text-editor-property-handler.h>
+
+#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
+
+#include <dali-toolkit/internal/text/decorator/text-decorator.h>
+#include <dali-toolkit/internal/text/text-controller.h>
+#include <dali-toolkit/internal/text/text-effects-style.h>
+#include <dali-toolkit/internal/text/text-enumerations-impl.h>
+#include <dali-toolkit/internal/text/text-font-style.h>
+#include <dali-toolkit/public-api/text/text-enumerations.h>
+#include <dali/integration-api/debug.h>
+
+#if defined(DEBUG_ENABLED)
+extern Debug::Filter* gTextEditorLogFilter;
+#endif
+
+namespace Dali::Toolkit::Internal
+{
+const char* const TextEditor::PropertyHandler::IMAGE_MAP_FILENAME_STRING{"filename"};
+
+/// Retrieves a filename from a value that is a Property::Map
+std::string TextEditor::PropertyHandler::GetImageFileNameFromPropertyValue(const Property::Value& value)
+{
+ std::string filename;
+ const Property::Map* map = value.GetMap();
+ if(map)
+ {
+ const Property::Value* filenameValue = map->Find(TextEditor::PropertyHandler::IMAGE_MAP_FILENAME_STRING);
+ if(filenameValue)
+ {
+ filenameValue->Get(filename);
+ }
+ }
+ return filename;
+}
+
+void TextEditor::PropertyHandler::SetProperty(Toolkit::TextEditor textEditor, Property::Index index, const Property::Value& value)
+{
+ TextEditor& impl(GetImpl(textEditor));
+ DALI_ASSERT_DEBUG(impl.mController && "No text controller");
+ DALI_ASSERT_DEBUG(impl.mDecorator && "No text decorator");
+
+ switch(index)
+ {
+ case Toolkit::DevelTextEditor::Property::RENDERING_BACKEND:
+ {
+ int backend = value.Get<int>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p RENDERING_BACKEND %d\n", impl.mController.Get(), backend);
+
+ if(impl.mRenderingBackend != backend)
+ {
+ impl.mRenderingBackend = backend;
+ impl.mRenderer.Reset();
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::TEXT:
+ {
+ const std::string& text = value.Get<std::string>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p TEXT %s\n", impl.mController.Get(), text.c_str());
+
+ impl.mController->SetText(text);
+ break;
+ }
+ case Toolkit::TextEditor::Property::TEXT_COLOR:
+ {
+ const Vector4& textColor = value.Get<Vector4>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a);
+
+ if(impl.mController->GetDefaultColor() != textColor)
+ {
+ impl.mController->SetDefaultColor(textColor);
+ impl.mController->SetInputColor(textColor);
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::FONT_FAMILY:
+ {
+ const std::string& fontFamily = value.Get<std::string>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str());
+ impl.mController->SetDefaultFontFamily(fontFamily);
+ break;
+ }
+ case Toolkit::TextEditor::Property::FONT_STYLE:
+ {
+ SetFontStyleProperty(impl.mController, value, Text::FontStyle::DEFAULT);
+ break;
+ }
+ case Toolkit::TextEditor::Property::POINT_SIZE:
+ {
+ const float pointSize = value.Get<float>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p POINT_SIZE %f\n", impl.mController.Get(), pointSize);
+
+ if(!Equals(impl.mController->GetDefaultFontSize(Text::Controller::POINT_SIZE), pointSize))
+ {
+ impl.mController->SetDefaultFontSize(pointSize, Text::Controller::POINT_SIZE);
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::HORIZONTAL_ALIGNMENT:
+ {
+ Text::HorizontalAlignment::Type alignment(static_cast<Text::HorizontalAlignment::Type>(-1)); // Set to invalid value to ensure a valid mode does get set
+ if(Text::GetHorizontalAlignmentEnumeration(value, alignment))
+ {
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p HORIZONTAL_ALIGNMENT %d\n", impl.mController.Get(), alignment);
+ impl.mController->SetHorizontalAlignment(alignment);
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SCROLL_THRESHOLD:
+ {
+ const float threshold = value.Get<float>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p SCROLL_THRESHOLD %f\n", impl.mController.Get(), threshold);
+
+ impl.mDecorator->SetScrollThreshold(threshold);
+ break;
+ }
+ case Toolkit::TextEditor::Property::SCROLL_SPEED:
+ {
+ const float speed = value.Get<float>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p SCROLL_SPEED %f\n", impl.mController.Get(), speed);
+
+ impl.mDecorator->SetScrollSpeed(speed);
+ break;
+ }
+ case Toolkit::TextEditor::Property::PRIMARY_CURSOR_COLOR:
+ {
+ const Vector4& color = value.Get<Vector4>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p PRIMARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
+
+ impl.mDecorator->SetCursorColor(Toolkit::Text::PRIMARY_CURSOR, color);
+ impl.RequestTextRelayout();
+ break;
+ }
+ case Toolkit::TextEditor::Property::SECONDARY_CURSOR_COLOR:
+ {
+ const Vector4& color = value.Get<Vector4>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p SECONDARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
+
+ impl.mDecorator->SetCursorColor(Toolkit::Text::SECONDARY_CURSOR, color);
+ impl.RequestTextRelayout();
+ break;
+ }
+ case Toolkit::TextEditor::Property::ENABLE_CURSOR_BLINK:
+ {
+ const bool enable = value.Get<bool>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable);
+
+ impl.mController->SetEnableCursorBlink(enable);
+ impl.RequestTextRelayout();
+ break;
+ }
+ case Toolkit::TextEditor::Property::CURSOR_BLINK_INTERVAL:
+ {
+ const float interval = value.Get<float>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval);
+
+ impl.mDecorator->SetCursorBlinkInterval(interval);
+ break;
+ }
+ case Toolkit::TextEditor::Property::CURSOR_BLINK_DURATION:
+ {
+ const float duration = value.Get<float>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration);
+
+ impl.mDecorator->SetCursorBlinkDuration(duration);
+ break;
+ }
+ case Toolkit::TextEditor::Property::CURSOR_WIDTH:
+ {
+ const int width = value.Get<int>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p CURSOR_WIDTH %d\n", impl.mController.Get(), width);
+
+ impl.mDecorator->SetCursorWidth(width);
+ impl.mController->GetLayoutEngine().SetCursorWidth(width);
+ break;
+ }
+ case Toolkit::TextEditor::Property::GRAB_HANDLE_IMAGE:
+ {
+ const std::string imageFileName = value.Get<std::string>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str());
+
+ if(imageFileName.size())
+ {
+ impl.mDecorator->SetHandleImage(Toolkit::Text::GRAB_HANDLE, Toolkit::Text::HANDLE_IMAGE_RELEASED, imageFileName);
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE:
+ {
+ const std::string imageFileName = value.Get<std::string>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str());
+
+ if(imageFileName.size())
+ {
+ impl.mDecorator->SetHandleImage(Toolkit::Text::GRAB_HANDLE, Toolkit::Text::HANDLE_IMAGE_PRESSED, imageFileName);
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT:
+ {
+ const std::string filename = GetImageFileNameFromPropertyValue(value);
+
+ if(filename.size())
+ {
+ impl.mDecorator->SetHandleImage(Toolkit::Text::LEFT_SELECTION_HANDLE, Toolkit::Text::HANDLE_IMAGE_RELEASED, filename);
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT:
+ {
+ const std::string filename = GetImageFileNameFromPropertyValue(value);
+
+ if(filename.size())
+ {
+ impl.mDecorator->SetHandleImage(Toolkit::Text::RIGHT_SELECTION_HANDLE, Toolkit::Text::HANDLE_IMAGE_RELEASED, filename);
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
+ {
+ const std::string filename = GetImageFileNameFromPropertyValue(value);
+
+ if(filename.size())
+ {
+ impl.mDecorator->SetHandleImage(Toolkit::Text::LEFT_SELECTION_HANDLE, Toolkit::Text::HANDLE_IMAGE_PRESSED, filename);
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
+ {
+ const std::string filename = GetImageFileNameFromPropertyValue(value);
+
+ if(filename.size())
+ {
+ impl.mDecorator->SetHandleImage(Toolkit::Text::RIGHT_SELECTION_HANDLE, Toolkit::Text::HANDLE_IMAGE_PRESSED, filename);
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
+ {
+ const std::string filename = GetImageFileNameFromPropertyValue(value);
+
+ if(filename.size())
+ {
+ impl.mDecorator->SetHandleImage(Toolkit::Text::LEFT_SELECTION_HANDLE_MARKER,
+ Toolkit::Text::HANDLE_IMAGE_RELEASED,
+ filename);
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
+ {
+ const std::string filename = GetImageFileNameFromPropertyValue(value);
+
+ if(filename.size())
+ {
+ impl.mDecorator->SetHandleImage(Toolkit::Text::RIGHT_SELECTION_HANDLE_MARKER,
+ Toolkit::Text::HANDLE_IMAGE_RELEASED,
+ filename);
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HIGHLIGHT_COLOR:
+ {
+ const Vector4 color = value.Get<Vector4>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p SELECTION_HIGHLIGHT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
+
+ impl.mDecorator->SetHighlightColor(color);
+ impl.RequestTextRelayout();
+ break;
+ }
+ case Toolkit::TextEditor::Property::DECORATION_BOUNDING_BOX:
+ {
+ const Rect<int>& box = value.Get<Rect<int> >();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p DECORATION_BOUNDING_BOX %d,%d %dx%d\n", impl.mController.Get(), box.x, box.y, box.width, box.height);
+
+ impl.mDecorator->SetBoundingBox(box);
+ impl.RequestTextRelayout();
+ break;
+ }
+ case Toolkit::TextEditor::Property::ENABLE_MARKUP:
+ {
+ const bool enableMarkup = value.Get<bool>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p ENABLE_MARKUP %d\n", impl.mController.Get(), enableMarkup);
+
+ impl.mController->SetMarkupProcessorEnabled(enableMarkup);
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_COLOR:
+ {
+ const Vector4& inputColor = value.Get<Vector4>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p INPUT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), inputColor.r, inputColor.g, inputColor.b, inputColor.a);
+
+ impl.mController->SetInputColor(inputColor);
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_FONT_FAMILY:
+ {
+ const std::string& fontFamily = value.Get<std::string>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str());
+ impl.mController->SetInputFontFamily(fontFamily);
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_FONT_STYLE:
+ {
+ SetFontStyleProperty(impl.mController, value, Text::FontStyle::INPUT);
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_POINT_SIZE:
+ {
+ const float pointSize = value.Get<float>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize);
+ impl.mController->SetInputFontPointSize(pointSize);
+ break;
+ }
+ case Toolkit::TextEditor::Property::LINE_SPACING:
+ {
+ const float lineSpacing = value.Get<float>();
+ impl.mController->SetDefaultLineSpacing(lineSpacing);
+ impl.mRenderer.Reset();
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_LINE_SPACING:
+ {
+ const float lineSpacing = value.Get<float>();
+ impl.mController->SetInputLineSpacing(lineSpacing);
+ impl.mRenderer.Reset();
+ break;
+ }
+ case Toolkit::TextEditor::Property::UNDERLINE:
+ {
+ const bool update = SetUnderlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+ if(update)
+ {
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_UNDERLINE:
+ {
+ const bool update = SetUnderlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
+ if(update)
+ {
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SHADOW:
+ {
+ const bool update = SetShadowProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+ if(update)
+ {
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_SHADOW:
+ {
+ const bool update = SetShadowProperties(impl.mController, value, Text::EffectStyle::INPUT);
+ if(update)
+ {
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::EMBOSS:
+ {
+ const bool update = SetEmbossProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+ if(update)
+ {
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_EMBOSS:
+ {
+ const bool update = SetEmbossProperties(impl.mController, value, Text::EffectStyle::INPUT);
+ if(update)
+ {
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::OUTLINE:
+ {
+ const bool update = SetOutlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+ if(update)
+ {
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_OUTLINE:
+ {
+ const bool update = SetOutlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
+ if(update)
+ {
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SMOOTH_SCROLL:
+ {
+ const bool enable = value.Get<bool>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor SMOOTH_SCROLL %d\n", enable);
+
+ impl.mScrollAnimationEnabled = enable;
+ break;
+ }
+ case Toolkit::TextEditor::Property::SMOOTH_SCROLL_DURATION:
+ {
+ const float duration = value.Get<float>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor SMOOTH_SCROLL_DURATION %f\n", duration);
+
+ impl.mScrollAnimationDuration = duration;
+ if(impl.mTextVerticalScroller)
+ {
+ impl.mTextVerticalScroller->SetDuration(duration);
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::ENABLE_SCROLL_BAR:
+ {
+ const bool enable = value.Get<bool>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor SHOW_SCROLL_BAR %d\n", enable);
+
+ impl.mScrollBarEnabled = enable;
+ break;
+ }
+ case Toolkit::TextEditor::Property::SCROLL_BAR_SHOW_DURATION:
+ {
+ const float duration = value.Get<float>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor SCROLL_BAR_SHOW_DURATION %f\n", duration);
+
+ impl.mAnimationPeriod.delaySeconds = duration;
+ break;
+ }
+ case Toolkit::TextEditor::Property::SCROLL_BAR_FADE_DURATION:
+ {
+ const float duration = value.Get<float>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor SCROLL_BAR_FADE_DURATION %f\n", duration);
+
+ impl.mAnimationPeriod.durationSeconds = duration;
+ break;
+ }
+ case Toolkit::TextEditor::Property::PIXEL_SIZE:
+ {
+ const float pixelSize = value.Get<float>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize);
+
+ if(!Equals(impl.mController->GetDefaultFontSize(Text::Controller::PIXEL_SIZE), pixelSize))
+ {
+ impl.mController->SetDefaultFontSize(pixelSize, Text::Controller::PIXEL_SIZE);
+ }
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT:
+ {
+ const std::string& text = value.Get<std::string>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor::OnPropertySet %p PLACEHOLDER_TEXT %s\n", impl.mController.Get(), text.c_str());
+
+ impl.mController->SetPlaceholderText(Text::Controller::PLACEHOLDER_TYPE_INACTIVE, text);
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT_COLOR:
+ {
+ const Vector4& textColor = value.Get<Vector4>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p PLACEHOLDER_TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a);
+
+ if(impl.mController->GetPlaceholderTextColor() != textColor)
+ {
+ impl.mController->SetPlaceholderTextColor(textColor);
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::ENABLE_SELECTION:
+ {
+ const bool enableSelection = value.Get<bool>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p ENABLE_SELECTION %d\n", impl.mController.Get(), enableSelection);
+ impl.mController->SetSelectionEnabled(enableSelection);
+ break;
+ }
+ case Toolkit::TextEditor::Property::PLACEHOLDER:
+ {
+ const Property::Map* map = value.GetMap();
+ if(map)
+ {
+ impl.mController->SetPlaceholderProperty(*map);
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::LINE_WRAP_MODE:
+ {
+ Text::LineWrap::Mode lineWrapMode(static_cast<Text::LineWrap::Mode>(-1)); // Set to invalid value to ensure a valid mode does get set
+ if(Toolkit::Text::GetLineWrapModeEnumeration(value, lineWrapMode))
+ {
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p LineWrap::MODE %d\n", impl.mController.Get(), lineWrapMode);
+ impl.mController->SetLineWrapMode(lineWrapMode);
+ }
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::ENABLE_SHIFT_SELECTION:
+ {
+ const bool shiftSelection = value.Get<bool>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p ENABLE_SHIFT_SELECTION %d\n", impl.mController.Get(), shiftSelection);
+
+ impl.mController->SetShiftSelectionEnabled(shiftSelection);
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE:
+ {
+ const bool grabHandleEnabled = value.Get<bool>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p ENABLE_GRAB_HANDLE %d\n", impl.mController.Get(), grabHandleEnabled);
+
+ impl.mController->SetGrabHandleEnabled(grabHandleEnabled);
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
+ {
+ impl.mController->SetMatchLayoutDirection(value.Get<bool>() ? DevelText::MatchLayoutDirection::LOCALE : DevelText::MatchLayoutDirection::CONTENTS);
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::MAX_LENGTH:
+ {
+ const int max = value.Get<int>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p MAX_LENGTH %d\n", impl.mController.Get(), max);
+
+ impl.mController->SetMaximumNumberOfCharacters(max);
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_START:
+ {
+ uint32_t start = static_cast<uint32_t>(value.Get<int>());
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p SELECTED_TEXT_START %d\n", impl.mController.Get(), start);
+ impl.SetTextSelectionRange(&start, nullptr);
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_END:
+ {
+ uint32_t end = static_cast<uint32_t>(value.Get<int>());
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p SELECTED_TEXT_END %d\n", impl.mController.Get(), end);
+ impl.SetTextSelectionRange(nullptr, &end);
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::ENABLE_EDITING:
+ {
+ const bool editable = value.Get<bool>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p ENABLE_EDITING %d\n", impl.mController.Get(), editable);
+ impl.SetEditable(editable);
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::HORIZONTAL_SCROLL_POSITION:
+ {
+ float horizontalScroll = value.Get<float>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p HORIZONTAL_SCROLL_POSITION %d\n", impl.mController.Get(), horizontalScroll);
+ if(horizontalScroll >= 0.0f)
+ {
+ impl.ScrollBy(Vector2(horizontalScroll - impl.GetHorizontalScrollPosition(), 0));
+ }
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::VERTICAL_SCROLL_POSITION:
+ {
+ float verticalScroll = value.Get<float>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p VERTICAL_SCROLL_POSITION %d\n", impl.mController.Get(), verticalScroll);
+ if(verticalScroll >= 0.0f)
+ {
+ impl.ScrollBy(Vector2(0, verticalScroll - impl.GetVerticalScrollPosition()));
+ }
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::FONT_SIZE_SCALE:
+ {
+ const float scale = value.Get<float>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p FONT_SIZE_SCALE %f\n", impl.mController.Get(), scale);
+
+ if(!Equals(impl.mController->GetFontSizeScale(), scale))
+ {
+ impl.mController->SetFontSizeScale(scale);
+ }
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::PRIMARY_CURSOR_POSITION:
+ {
+ uint32_t position = static_cast<uint32_t>(value.Get<int>());
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p PRIMARY_CURSOR_POSITION %d\n", impl.mController.Get(), position);
+ if(impl.mController->SetPrimaryCursorPosition(position, impl.HasKeyInputFocus()))
+ {
+ impl.SetKeyInputFocus();
+ }
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::GRAB_HANDLE_COLOR:
+ {
+ const Vector4 color = value.Get<Vector4>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p GRAB_HANDLE_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
+
+ impl.mDecorator->SetHandleColor(color);
+ impl.RequestTextRelayout();
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE_POPUP:
+ {
+ const bool grabHandlePopupEnabled = value.Get<bool>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p ENABLE_GRAB_HANDLE_POPUP %d\n", impl.mController.Get(), grabHandlePopupEnabled);
+
+ impl.mController->SetGrabHandlePopupEnabled(grabHandlePopupEnabled);
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::INPUT_METHOD_SETTINGS:
+ {
+ const Property::Map* map = value.GetMap();
+ if(map)
+ {
+ impl.mInputMethodOptions.ApplyProperty(*map);
+ }
+ impl.mController->SetInputModePassword(impl.mInputMethodOptions.IsPassword());
+
+ Toolkit::Control control = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
+ if(control == textEditor)
+ {
+ impl.mInputMethodContext.ApplyOptions(impl.mInputMethodOptions);
+ }
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::INPUT_FILTER:
+ {
+ const Property::Map* map = value.GetMap();
+ if(map)
+ {
+ impl.mController->SetInputFilterOption(*map);
+ }
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::ELLIPSIS:
+ {
+ const bool ellipsis = value.Get<bool>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis);
+
+ impl.mController->SetTextElideEnabled(ellipsis);
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::ELLIPSIS_POSITION:
+ {
+ DevelText::EllipsisPosition::Type ellipsisPositionType(static_cast<DevelText::EllipsisPosition::Type>(-1)); // Set to invalid value to ensure a valid mode does get set
+ if(Text::GetEllipsisPositionTypeEnumeration(value, ellipsisPositionType))
+ {
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p EllipsisPosition::Type %d\n", impl.mController.Get(), ellipsisPositionType);
+ impl.mController->SetEllipsisPosition(ellipsisPositionType);
+ }
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::MIN_LINE_SIZE:
+ {
+ const float minLineSize = value.Get<float>();
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p MIN_LINE_SIZE %f\n", impl.mController.Get(), minLineSize);
+
+ impl.mController->SetDefaultLineSize(minLineSize);
+ impl.mRenderer.Reset();
+ break;
+ }
+ }
+}
+
+Property::Value TextEditor::PropertyHandler::GetProperty(Toolkit::TextEditor textEditor, Property::Index index)
+{
+ Property::Value value;
+ TextEditor& impl(GetImpl(textEditor));
+ DALI_ASSERT_DEBUG(impl.mController && "No text controller");
+ DALI_ASSERT_DEBUG(impl.mDecorator && "No text decorator");
+
+ switch(index)
+ {
+ case Toolkit::DevelTextEditor::Property::RENDERING_BACKEND:
+ {
+ value = impl.mRenderingBackend;
+ break;
+ }
+ case Toolkit::TextEditor::Property::TEXT:
+ {
+ std::string text;
+ impl.mController->GetText(text);
+ DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p returning text: %s\n", impl.mController.Get(), text.c_str());
+ value = text;
+ break;
+ }
+ case Toolkit::TextEditor::Property::TEXT_COLOR:
+ {
+ value = impl.mController->GetDefaultColor();
+ break;
+ }
+ case Toolkit::TextEditor::Property::FONT_FAMILY:
+ {
+ value = impl.mController->GetDefaultFontFamily();
+ break;
+ }
+ case Toolkit::TextEditor::Property::FONT_STYLE:
+ {
+ GetFontStyleProperty(impl.mController, value, Text::FontStyle::DEFAULT);
+ break;
+ }
+ case Toolkit::TextEditor::Property::POINT_SIZE:
+ {
+ value = impl.mController->GetDefaultFontSize(Text::Controller::POINT_SIZE);
+ break;
+ }
+ case Toolkit::TextEditor::Property::HORIZONTAL_ALIGNMENT:
+ {
+ const char* name = Text::GetHorizontalAlignmentString(impl.mController->GetHorizontalAlignment());
+ if(name)
+ {
+ value = std::string(name);
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SCROLL_THRESHOLD:
+ {
+ value = impl.mDecorator->GetScrollThreshold();
+ break;
+ }
+ case Toolkit::TextEditor::Property::SCROLL_SPEED:
+ {
+ value = impl.mDecorator->GetScrollSpeed();
+ break;
+ }
+ case Toolkit::TextEditor::Property::PRIMARY_CURSOR_COLOR:
+ {
+ value = impl.mDecorator->GetColor(Text::PRIMARY_CURSOR);
+ break;
+ }
+ case Toolkit::TextEditor::Property::SECONDARY_CURSOR_COLOR:
+ {
+ value = impl.mDecorator->GetColor(Text::SECONDARY_CURSOR);
+ break;
+ }
+ case Toolkit::TextEditor::Property::ENABLE_CURSOR_BLINK:
+ {
+ value = impl.mController->GetEnableCursorBlink();
+ break;
+ }
+ case Toolkit::TextEditor::Property::CURSOR_BLINK_INTERVAL:
+ {
+ value = impl.mDecorator->GetCursorBlinkInterval();
+ break;
+ }
+ case Toolkit::TextEditor::Property::CURSOR_BLINK_DURATION:
+ {
+ value = impl.mDecorator->GetCursorBlinkDuration();
+ break;
+ }
+ case Toolkit::TextEditor::Property::CURSOR_WIDTH:
+ {
+ value = impl.mDecorator->GetCursorWidth();
+ break;
+ }
+ case Toolkit::TextEditor::Property::GRAB_HANDLE_IMAGE:
+ {
+ value = impl.mDecorator->GetHandleImage(Text::GRAB_HANDLE, Text::HANDLE_IMAGE_RELEASED);
+ break;
+ }
+ case Toolkit::TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE:
+ {
+ value = impl.mDecorator->GetHandleImage(Text::GRAB_HANDLE, Text::HANDLE_IMAGE_PRESSED);
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT:
+ {
+ impl.GetHandleImagePropertyValue(value, Text::LEFT_SELECTION_HANDLE, Text::HANDLE_IMAGE_RELEASED);
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT:
+ {
+ impl.GetHandleImagePropertyValue(value, Text::RIGHT_SELECTION_HANDLE, Text::HANDLE_IMAGE_RELEASED);
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
+ {
+ impl.GetHandleImagePropertyValue(value, Text::LEFT_SELECTION_HANDLE, Text::HANDLE_IMAGE_PRESSED);
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
+ {
+ impl.GetHandleImagePropertyValue(value, Text::RIGHT_SELECTION_HANDLE, Text::HANDLE_IMAGE_PRESSED);
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
+ {
+ impl.GetHandleImagePropertyValue(value, Text::LEFT_SELECTION_HANDLE_MARKER, Text::HANDLE_IMAGE_RELEASED);
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
+ {
+ impl.GetHandleImagePropertyValue(value, Text::RIGHT_SELECTION_HANDLE_MARKER, Text::HANDLE_IMAGE_RELEASED);
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HIGHLIGHT_COLOR:
+ {
+ value = impl.mDecorator->GetHighlightColor();
+ break;
+ }
+ case Toolkit::TextEditor::Property::DECORATION_BOUNDING_BOX:
+ {
+ Rect<int> boundingBox;
+ impl.mDecorator->GetBoundingBox(boundingBox);
+ value = boundingBox;
+ break;
+ }
+ case Toolkit::TextEditor::Property::ENABLE_MARKUP:
+ {
+ value = impl.mController->IsMarkupProcessorEnabled();
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_COLOR:
+ {
+ value = impl.mController->GetInputColor();
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_FONT_FAMILY:
+ {
+ value = impl.mController->GetInputFontFamily();
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_FONT_STYLE:
+ {
+ GetFontStyleProperty(impl.mController, value, Text::FontStyle::INPUT);
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_POINT_SIZE:
+ {
+ value = impl.mController->GetInputFontPointSize();
+ break;
+ }
+ case Toolkit::TextEditor::Property::LINE_SPACING:
+ {
+ value = impl.mController->GetDefaultLineSpacing();
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_LINE_SPACING:
+ {
+ value = impl.mController->GetInputLineSpacing();
+ break;
+ }
+ case Toolkit::TextEditor::Property::UNDERLINE:
+ {
+ GetUnderlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_UNDERLINE:
+ {
+ GetUnderlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
+ break;
+ }
+ case Toolkit::TextEditor::Property::SHADOW:
+ {
+ GetShadowProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_SHADOW:
+ {
+ GetShadowProperties(impl.mController, value, Text::EffectStyle::INPUT);
+ break;
+ }
+ case Toolkit::TextEditor::Property::EMBOSS:
+ {
+ GetEmbossProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_EMBOSS:
+ {
+ GetEmbossProperties(impl.mController, value, Text::EffectStyle::INPUT);
+ break;
+ }
+ case Toolkit::TextEditor::Property::OUTLINE:
+ {
+ GetOutlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_OUTLINE:
+ {
+ GetOutlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
+ break;
+ }
+ case Toolkit::TextEditor::Property::SMOOTH_SCROLL:
+ {
+ value = impl.mScrollAnimationEnabled;
+ break;
+ }
+ case Toolkit::TextEditor::Property::SMOOTH_SCROLL_DURATION:
+ {
+ value = impl.mScrollAnimationDuration;
+ break;
+ }
+ case Toolkit::TextEditor::Property::ENABLE_SCROLL_BAR:
+ {
+ value = impl.mScrollBarEnabled;
+ break;
+ }
+ case Toolkit::TextEditor::Property::SCROLL_BAR_SHOW_DURATION:
+ {
+ value = impl.mAnimationPeriod.delaySeconds;
+ break;
+ }
+ case Toolkit::TextEditor::Property::SCROLL_BAR_FADE_DURATION:
+ {
+ value = impl.mAnimationPeriod.durationSeconds;
+ break;
+ }
+ case Toolkit::TextEditor::Property::PIXEL_SIZE:
+ {
+ value = impl.mController->GetDefaultFontSize(Text::Controller::PIXEL_SIZE);
+ break;
+ }
+ case Toolkit::TextEditor::Property::LINE_COUNT:
+ {
+ float width = textEditor.GetProperty(Actor::Property::SIZE_WIDTH).Get<float>();
+ value = impl.mController->GetLineCount(width);
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT:
+ {
+ std::string text;
+ impl.mController->GetPlaceholderText(Text::Controller::PLACEHOLDER_TYPE_INACTIVE, text);
+ value = text;
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT_COLOR:
+ {
+ value = impl.mController->GetPlaceholderTextColor();
+ break;
+ }
+ case Toolkit::TextEditor::Property::ENABLE_SELECTION:
+ {
+ value = impl.mController->IsSelectionEnabled();
+ break;
+ }
+ case Toolkit::TextEditor::Property::PLACEHOLDER:
+ {
+ Property::Map map;
+ impl.mController->GetPlaceholderProperty(map);
+ value = map;
+ break;
+ }
+ case Toolkit::TextEditor::Property::LINE_WRAP_MODE:
+ {
+ value = impl.mController->GetLineWrapMode();
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::ENABLE_SHIFT_SELECTION:
+ {
+ value = impl.mController->IsShiftSelectionEnabled();
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE:
+ {
+ value = impl.mController->IsGrabHandleEnabled();
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
+ {
+ value = impl.mController->GetMatchLayoutDirection() != DevelText::MatchLayoutDirection::CONTENTS;
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::MAX_LENGTH:
+ {
+ value = impl.mController->GetMaximumNumberOfCharacters();
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::SELECTED_TEXT:
+ {
+ value = impl.mController->GetSelectedText();
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_START:
+ {
+ Uint32Pair range = impl.GetTextSelectionRange();
+ value = static_cast<int>(range.first);
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_END:
+ {
+ Uint32Pair range = impl.GetTextSelectionRange();
+ value = static_cast<int>(range.second);
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::ENABLE_EDITING:
+ {
+ value = impl.IsEditable();
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::HORIZONTAL_SCROLL_POSITION:
+ {
+ value = impl.GetHorizontalScrollPosition();
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::VERTICAL_SCROLL_POSITION:
+ {
+ value = impl.GetVerticalScrollPosition();
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::FONT_SIZE_SCALE:
+ {
+ value = impl.mController->GetFontSizeScale();
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::PRIMARY_CURSOR_POSITION:
+ {
+ value = static_cast<int>(impl.mController->GetPrimaryCursorPosition());
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::GRAB_HANDLE_COLOR:
+ {
+ value = impl.mDecorator->GetHandleColor();
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE_POPUP:
+ {
+ value = impl.mController->IsGrabHandlePopupEnabled();
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::INPUT_METHOD_SETTINGS:
+ {
+ Property::Map map;
+ impl.mInputMethodOptions.RetrieveProperty(map);
+ value = map;
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::INPUT_FILTER:
+ {
+ Property::Map map;
+ impl.mController->GetInputFilterOption(map);
+ value = map;
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::ELLIPSIS:
+ {
+ value = impl.mController->IsTextElideEnabled();
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::ELLIPSIS_POSITION:
+ {
+ value = impl.mController->GetEllipsisPosition();
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::MIN_LINE_SIZE:
+ {
+ value = impl.mController->GetDefaultLineSize();
+ break;
+ }
+ } //switch
+ return value;
+}
+
+} // namespace Dali::Toolkit::Internal
--- /dev/null
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_PROPERTY_HANDLER_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_PROPERTY_HANDLER_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.
+ */
+
+#include <dali-toolkit/internal/controls/text-controls/text-editor-impl.h>
+
+namespace Dali::Toolkit::Internal
+{
+/**
+ * Class to manage properties for the TextEditor
+ */
+struct TextEditor::PropertyHandler
+{
+ static const char* const IMAGE_MAP_FILENAME_STRING; //<<< "filename" key for image map
+
+ /**
+ * Set properties on the text editor / controller / decorator
+ *
+ * @param[in] textEditor The handle for the text editor
+ * @param[in] index The property index of the property to set
+ * @param[in] value The value to set
+ */
+ static void SetProperty(Toolkit::TextEditor textEditor, Property::Index index, const Property::Value& value);
+
+ /**
+ * Get properties from the text editor / controller / decorator
+ *
+ * @param[in] textEditor The handle for the text editor
+ * @param[in] index The property index of the property to set
+ * @return the value
+ */
+ static Property::Value GetProperty(Toolkit::TextEditor textEditor, Property::Index index);
+
+private:
+ /**
+ * Method to extract "filename" value from a Property::Map
+ *
+ * @param[in] The property value containing the Property::Map
+ * @return The resulting "filename" value if present
+ */
+ static std::string GetImageFileNameFromPropertyValue(const Property::Value& value);
+};
+
+} // namespace Dali::Toolkit::Internal
+
+#endif //DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_PROPERTY_HANDLER_H
#include <dali/devel-api/common/stage.h>
#include <dali/devel-api/object/property-helper-devel.h>
#include <dali/integration-api/debug.h>
+#include <dali/public-api/actors/layer.h>
#include <dali/public-api/adaptor-framework/key.h>
#include <dali/public-api/common/dali-common.h>
#include <dali/public-api/object/type-registry-helper.h>
#include <cstring>
// INTERNAL INCLUDES
-#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-field-devel.h>
#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
#include <dali-toolkit/devel-api/text/rendering-backend.h>
+#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
+#include <dali-toolkit/internal/controls/text-controls/text-field-property-handler.h>
#include <dali-toolkit/internal/styling/style-manager-impl.h>
#include <dali-toolkit/internal/text/rendering/text-backend.h>
#include <dali-toolkit/internal/text/text-effects-style.h>
using namespace Dali::Toolkit::Text;
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gTextFieldLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
+#endif
+
namespace Dali
{
namespace Toolkit
{
namespace // unnamed namespace
{
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
-#endif
-
const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::DevelText::DEFAULT_RENDERING_BACKEND;
} // unnamed namespace
DALI_TYPE_REGISTRATION_END()
// clang-format on
-const char* const IMAGE_MAP_FILENAME_STRING = "filename";
-
-/// Retrieves a filename from a value that is a Property::Map
-std::string GetImageFileNameFromPropertyValue(const Property::Value& value)
+Toolkit::TextField::InputStyle::Mask ConvertInputStyle(Text::InputStyle::Mask inputStyleMask)
{
- std::string filename;
- const Property::Map* map = value.GetMap();
- if(map)
+ Toolkit::TextField::InputStyle::Mask fieldInputStyleMask = Toolkit::TextField::InputStyle::NONE;
+
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_COLOR))
{
- const Property::Value* filenameValue = map->Find(IMAGE_MAP_FILENAME_STRING);
- if(filenameValue)
- {
- filenameValue->Get(filename);
- }
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::COLOR);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_FAMILY))
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_FAMILY);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_POINT_SIZE))
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::POINT_SIZE);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_WEIGHT))
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_WIDTH))
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_SLANT))
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_UNDERLINE))
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::UNDERLINE);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_SHADOW))
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::SHADOW);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_EMBOSS))
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::EMBOSS);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_OUTLINE))
+ {
+ fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::OUTLINE);
}
- return filename;
+ return fieldInputStyleMask;
}
} // namespace
{
Toolkit::TextField textField = Toolkit::TextField::DownCast(Dali::BaseHandle(object));
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField SetProperty\n");
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField SetProperty\n");
if(textField)
{
- TextField& impl(GetImpl(textField));
- DALI_ASSERT_DEBUG(impl.mController && "No text contoller");
- DALI_ASSERT_DEBUG(impl.mDecorator && "No text decorator");
-
- switch(index)
- {
- case Toolkit::DevelTextField::Property::RENDERING_BACKEND:
- {
- int backend = value.Get<int>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p RENDERING_BACKEND %d\n", impl.mController.Get(), backend);
-
-#ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING
- if(DevelText::RENDERING_VECTOR_BASED == backend)
- {
- backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering
- }
-#endif
- if(impl.mRenderingBackend != backend)
- {
- impl.mRenderingBackend = backend;
- impl.mRenderer.Reset();
-
- // When using the vector-based rendering, the size of the GLyphs are different
- TextAbstraction::GlyphType glyphType = (DevelText::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
- impl.mController->SetGlyphType(glyphType);
- }
- break;
- }
- case Toolkit::TextField::Property::TEXT:
- {
- const std::string& text = value.Get<std::string>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p TEXT %s\n", impl.mController.Get(), text.c_str());
-
- impl.mController->SetText(text);
- break;
- }
- case Toolkit::TextField::Property::PLACEHOLDER_TEXT:
- {
- const std::string& text = value.Get<std::string>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT %s\n", impl.mController.Get(), text.c_str());
-
- impl.mController->SetPlaceholderText(Controller::PLACEHOLDER_TYPE_INACTIVE, text);
- break;
- }
- case Toolkit::TextField::Property::PLACEHOLDER_TEXT_FOCUSED:
- {
- const std::string& text = value.Get<std::string>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_FOCUSED %s\n", impl.mController.Get(), text.c_str());
-
- impl.mController->SetPlaceholderText(Controller::PLACEHOLDER_TYPE_ACTIVE, text);
- break;
- }
- case Toolkit::TextField::Property::FONT_FAMILY:
- {
- const std::string& fontFamily = value.Get<std::string>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str());
- impl.mController->SetDefaultFontFamily(fontFamily);
- break;
- }
- case Toolkit::TextField::Property::FONT_STYLE:
- {
- SetFontStyleProperty(impl.mController, value, Text::FontStyle::DEFAULT);
- break;
- }
- case Toolkit::TextField::Property::POINT_SIZE:
- {
- const float pointSize = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p POINT_SIZE %f\n", impl.mController.Get(), pointSize);
-
- if(!Equals(impl.mController->GetDefaultFontSize(Text::Controller::POINT_SIZE), pointSize))
- {
- impl.mController->SetDefaultFontSize(pointSize, Text::Controller::POINT_SIZE);
- }
- break;
- }
- case Toolkit::TextField::Property::MAX_LENGTH:
- {
- const int max = value.Get<int>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p MAX_LENGTH %d\n", impl.mController.Get(), max);
-
- impl.mController->SetMaximumNumberOfCharacters(max);
- break;
- }
- case Toolkit::TextField::Property::EXCEED_POLICY:
- {
- impl.mExceedPolicy = value.Get<int>();
-
- if(Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == impl.mExceedPolicy)
- {
- impl.EnableClipping();
- }
- else
- {
- UnparentAndReset(impl.mStencil);
- }
- impl.RequestTextRelayout();
- break;
- }
- case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
- {
- Text::HorizontalAlignment::Type alignment(static_cast<Text::HorizontalAlignment::Type>(-1)); // Set to invalid value to ensure a valid mode does get set
- if(GetHorizontalAlignmentEnumeration(value, alignment))
- {
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p HORIZONTAL_ALIGNMENT %d\n", impl.mController.Get(), alignment);
- impl.mController->SetHorizontalAlignment(alignment);
- }
- break;
- }
- case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
- {
- Toolkit::Text::VerticalAlignment::Type alignment(static_cast<Text::VerticalAlignment::Type>(-1)); // Set to invalid value to ensure a valid mode does get set
- if(GetVerticalAlignmentEnumeration(value, alignment))
- {
- impl.mController->SetVerticalAlignment(alignment);
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p VERTICAL_ALIGNMENT %d\n", impl.mController.Get(), alignment);
- }
- break;
- }
- case Toolkit::TextField::Property::TEXT_COLOR:
- {
- const Vector4& textColor = value.Get<Vector4>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a);
-
- if(impl.mController->GetDefaultColor() != textColor)
- {
- impl.mController->SetDefaultColor(textColor);
- impl.mController->SetInputColor(textColor);
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextField::Property::PLACEHOLDER_TEXT_COLOR:
- {
- const Vector4& textColor = value.Get<Vector4>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a);
-
- if(impl.mController->GetPlaceholderTextColor() != textColor)
- {
- impl.mController->SetPlaceholderTextColor(textColor);
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
- {
- const Vector4& color = value.Get<Vector4>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p PRIMARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
-
- impl.mDecorator->SetCursorColor(PRIMARY_CURSOR, color);
- impl.RequestTextRelayout();
- break;
- }
- case Toolkit::TextField::Property::SECONDARY_CURSOR_COLOR:
- {
- const Vector4& color = value.Get<Vector4>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p SECONDARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
-
- impl.mDecorator->SetCursorColor(SECONDARY_CURSOR, color);
- impl.RequestTextRelayout();
- break;
- }
- case Toolkit::TextField::Property::ENABLE_CURSOR_BLINK:
- {
- const bool enable = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable);
-
- impl.mController->SetEnableCursorBlink(enable);
- impl.RequestTextRelayout();
- break;
- }
- case Toolkit::TextField::Property::CURSOR_BLINK_INTERVAL:
- {
- const float interval = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval);
-
- impl.mDecorator->SetCursorBlinkInterval(interval);
- break;
- }
- case Toolkit::TextField::Property::CURSOR_BLINK_DURATION:
- {
- const float duration = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration);
-
- impl.mDecorator->SetCursorBlinkDuration(duration);
- break;
- }
- case Toolkit::TextField::Property::CURSOR_WIDTH:
- {
- const int width = value.Get<int>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p CURSOR_WIDTH %d\n", impl.mController.Get(), width);
-
- impl.mDecorator->SetCursorWidth(width);
- impl.mController->GetLayoutEngine().SetCursorWidth(width);
- break;
- }
- case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
- {
- const std::string imageFileName = value.Get<std::string>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str());
-
- if(imageFileName.size())
- {
- impl.mDecorator->SetHandleImage(GRAB_HANDLE, HANDLE_IMAGE_RELEASED, imageFileName);
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
- {
- const std::string imageFileName = value.Get<std::string>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str());
-
- if(imageFileName.size())
- {
- impl.mDecorator->SetHandleImage(GRAB_HANDLE, HANDLE_IMAGE_PRESSED, imageFileName);
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextField::Property::SCROLL_THRESHOLD:
- {
- const float threshold = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p SCROLL_THRESHOLD %f\n", impl.mController.Get(), threshold);
-
- impl.mDecorator->SetScrollThreshold(threshold);
- break;
- }
- case Toolkit::TextField::Property::SCROLL_SPEED:
- {
- const float speed = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p SCROLL_SPEED %f\n", impl.mController.Get(), speed);
-
- impl.mDecorator->SetScrollSpeed(speed);
- break;
- }
- case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
- {
- const std::string filename = GetImageFileNameFromPropertyValue(value);
-
- if(filename.size())
- {
- impl.mDecorator->SetHandleImage(LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, filename);
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
- {
- const std::string filename = GetImageFileNameFromPropertyValue(value);
-
- if(filename.size())
- {
- impl.mDecorator->SetHandleImage(RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, filename);
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
- {
- const std::string filename = GetImageFileNameFromPropertyValue(value);
-
- if(filename.size())
- {
- impl.mDecorator->SetHandleImage(LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, filename);
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
- {
- const std::string filename = GetImageFileNameFromPropertyValue(value);
-
- if(filename.size())
- {
- impl.mDecorator->SetHandleImage(RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, filename);
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
- {
- const std::string filename = GetImageFileNameFromPropertyValue(value);
-
- if(filename.size())
- {
- impl.mDecorator->SetHandleImage(LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, filename);
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
- {
- const std::string filename = GetImageFileNameFromPropertyValue(value);
-
- if(filename.size())
- {
- impl.mDecorator->SetHandleImage(RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, filename);
- impl.RequestTextRelayout();
- }
- break;
- }
- case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
- {
- const Vector4 color = value.Get<Vector4>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p SELECTION_HIGHLIGHT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
-
- impl.mDecorator->SetHighlightColor(color);
- impl.RequestTextRelayout();
- break;
- }
- case Toolkit::TextField::Property::DECORATION_BOUNDING_BOX:
- {
- const Rect<int> box = value.Get<Rect<int> >();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p DECORATION_BOUNDING_BOX %d,%d %dx%d\n", impl.mController.Get(), box.x, box.y, box.width, box.height);
-
- impl.mDecorator->SetBoundingBox(box);
- impl.RequestTextRelayout();
- break;
- }
- case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
- {
- const Property::Map* map = value.GetMap();
- if(map)
- {
- impl.mInputMethodOptions.ApplyProperty(*map);
- }
- impl.mController->SetInputModePassword(impl.mInputMethodOptions.IsPassword());
-
- Toolkit::Control control = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
- if(control == textField)
- {
- impl.mInputMethodContext.ApplyOptions(impl.mInputMethodOptions);
- }
- break;
- }
- case Toolkit::TextField::Property::INPUT_COLOR:
- {
- const Vector4 inputColor = value.Get<Vector4>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p INPUT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), inputColor.r, inputColor.g, inputColor.b, inputColor.a);
-
- impl.mController->SetInputColor(inputColor);
- break;
- }
- case Toolkit::TextField::Property::ENABLE_MARKUP:
- {
- const bool enableMarkup = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_MARKUP %d\n", impl.mController.Get(), enableMarkup);
-
- impl.mController->SetMarkupProcessorEnabled(enableMarkup);
- break;
- }
- case Toolkit::TextField::Property::INPUT_FONT_FAMILY:
- {
- const std::string& fontFamily = value.Get<std::string>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str());
- impl.mController->SetInputFontFamily(fontFamily);
- break;
- }
- case Toolkit::TextField::Property::INPUT_FONT_STYLE:
- {
- SetFontStyleProperty(impl.mController, value, Text::FontStyle::INPUT);
- break;
- }
- case Toolkit::TextField::Property::INPUT_POINT_SIZE:
- {
- const float pointSize = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize);
- impl.mController->SetInputFontPointSize(pointSize);
- break;
- }
- case Toolkit::TextField::Property::UNDERLINE:
- {
- const bool update = SetUnderlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
- if(update)
- {
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextField::Property::INPUT_UNDERLINE:
- {
- const bool update = SetUnderlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
- if(update)
- {
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextField::Property::SHADOW:
- {
- const bool update = SetShadowProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
- if(update)
- {
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextField::Property::INPUT_SHADOW:
- {
- const bool update = SetShadowProperties(impl.mController, value, Text::EffectStyle::INPUT);
- if(update)
- {
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextField::Property::EMBOSS:
- {
- const bool update = SetEmbossProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
- if(update)
- {
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextField::Property::INPUT_EMBOSS:
- {
- const bool update = SetEmbossProperties(impl.mController, value, Text::EffectStyle::INPUT);
- if(update)
- {
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextField::Property::OUTLINE:
- {
- const bool update = SetOutlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
- if(update)
- {
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextField::Property::INPUT_OUTLINE:
- {
- const bool update = SetOutlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
- if(update)
- {
- impl.mRenderer.Reset();
- }
- break;
- }
- case Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS:
- {
- const Property::Map* map = value.GetMap();
- if(map)
- {
- impl.mController->SetHiddenInputOption(*map);
- }
- break;
- }
- case Toolkit::TextField::Property::PIXEL_SIZE:
- {
- const float pixelSize = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize);
-
- if(!Equals(impl.mController->GetDefaultFontSize(Text::Controller::PIXEL_SIZE), pixelSize))
- {
- impl.mController->SetDefaultFontSize(pixelSize, Text::Controller::PIXEL_SIZE);
- }
- break;
- }
- case Toolkit::TextField::Property::ENABLE_SELECTION:
- {
- const bool enableSelection = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_SELECTION %d\n", impl.mController.Get(), enableSelection);
- impl.mController->SetSelectionEnabled(enableSelection);
- break;
- }
- case Toolkit::TextField::Property::PLACEHOLDER:
- {
- const Property::Map* map = value.GetMap();
- if(map)
- {
- impl.mController->SetPlaceholderProperty(*map);
- }
- break;
- }
- case Toolkit::TextField::Property::ELLIPSIS:
- {
- const bool ellipsis = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis);
-
- impl.mController->SetTextElideEnabled(ellipsis);
- break;
- }
- case Toolkit::DevelTextField::Property::ENABLE_SHIFT_SELECTION:
- {
- const bool shiftSelection = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_SHIFT_SELECTION %d\n", impl.mController.Get(), shiftSelection);
-
- impl.mController->SetShiftSelectionEnabled(shiftSelection);
- break;
- }
- case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE:
- {
- const bool grabHandleEnabled = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_GRAB_HANDLE %d\n", impl.mController.Get(), grabHandleEnabled);
-
- impl.mController->SetGrabHandleEnabled(grabHandleEnabled);
- break;
- }
- case Toolkit::DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
- {
- impl.mController->SetMatchLayoutDirection(value.Get<bool>() ? DevelText::MatchLayoutDirection::LOCALE : DevelText::MatchLayoutDirection::CONTENTS);
- break;
- }
- case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP:
- {
- const bool grabHandlePopupEnabled = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_GRAB_HANDLE_POPUP %d\n", impl.mController.Get(), grabHandlePopupEnabled);
-
- impl.mController->SetGrabHandlePopupEnabled(grabHandlePopupEnabled);
- break;
- }
- case Toolkit::DevelTextField::Property::BACKGROUND:
- {
- const Vector4 backgroundColor = value.Get<Vector4>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p BACKGROUND %f,%f,%f,%f\n", impl.mController.Get(), backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a);
-
- impl.mController->SetBackgroundEnabled(true);
- impl.mController->SetBackgroundColor(backgroundColor);
- break;
- }
- case Toolkit::DevelTextField::Property::SELECTED_TEXT_START:
- {
- uint32_t start = static_cast<uint32_t>(value.Get<int>());
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p SELECTED_TEXT_START %d\n", impl.mController.Get(), start);
- impl.SetTextSelectionRange(&start, nullptr);
- break;
- }
- case Toolkit::DevelTextField::Property::SELECTED_TEXT_END:
- {
- uint32_t end = static_cast<uint32_t>(value.Get<int>());
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p SELECTED_TEXT_END %d\n", impl.mController.Get(), end);
- impl.SetTextSelectionRange(nullptr, &end);
- break;
- }
- case Toolkit::DevelTextField::Property::ENABLE_EDITING:
- {
- const bool editable = value.Get<bool>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_EDITING %d\n", impl.mController.Get(), editable);
- impl.SetEditable(editable);
- break;
- }
- case Toolkit::DevelTextField::Property::FONT_SIZE_SCALE:
- {
- const float scale = value.Get<float>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p FONT_SIZE_SCALE %f\n", impl.mController.Get(), scale);
-
- if(!Equals(impl.mController->GetFontSizeScale(), scale))
- {
- impl.mController->SetFontSizeScale(scale);
- }
- break;
- }
- case Toolkit::DevelTextField::Property::PRIMARY_CURSOR_POSITION:
- {
- uint32_t position = static_cast<uint32_t>(value.Get<int>());
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p PRIMARY_CURSOR_POSITION %d\n", impl.mController.Get(), position);
- if(impl.mController->SetPrimaryCursorPosition(position, impl.HasKeyInputFocus()))
- {
- impl.SetKeyInputFocus();
- }
- break;
- }
- case Toolkit::DevelTextField::Property::GRAB_HANDLE_COLOR:
- {
- const Vector4 color = value.Get<Vector4>();
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p GRAB_HANDLE_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
-
- impl.mDecorator->SetHandleColor(color);
- impl.RequestTextRelayout();
- break;
- }
- case Toolkit::DevelTextField::Property::INPUT_FILTER:
- {
- const Property::Map* map = value.GetMap();
- if(map)
- {
- impl.mController->SetInputFilterOption(*map);
- }
- break;
- }
- case Toolkit::DevelTextField::Property::ELLIPSIS_POSITION:
- {
- DevelText::EllipsisPosition::Type ellipsisPositionType(static_cast<DevelText::EllipsisPosition::Type>(-1)); // Set to invalid value to ensure a valid mode does get set
- if(GetEllipsisPositionTypeEnumeration(value, ellipsisPositionType))
- {
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p EllipsisPosition::Type %d\n", impl.mController.Get(), ellipsisPositionType);
- impl.mController->SetEllipsisPosition(ellipsisPositionType);
- }
- break;
- }
- } // switch
- } // textfield
+ PropertyHandler::SetProperty(textField, index, value);
+ }
}
Property::Value TextField::GetProperty(BaseObject* object, Property::Index index)
if(textField)
{
- TextField& impl(GetImpl(textField));
- DALI_ASSERT_DEBUG(impl.mController && "No text contoller");
- DALI_ASSERT_DEBUG(impl.mDecorator && "No text decorator");
-
- switch(index)
- {
- case Toolkit::DevelTextField::Property::RENDERING_BACKEND:
- {
- value = impl.mRenderingBackend;
- break;
- }
- case Toolkit::TextField::Property::TEXT:
- {
- std::string text;
- impl.mController->GetText(text);
- DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p returning text: %s\n", impl.mController.Get(), text.c_str());
- value = text;
- break;
- }
- case Toolkit::TextField::Property::PLACEHOLDER_TEXT:
- {
- std::string text;
- impl.mController->GetPlaceholderText(Controller::PLACEHOLDER_TYPE_INACTIVE, text);
- value = text;
- break;
- }
- case Toolkit::TextField::Property::PLACEHOLDER_TEXT_FOCUSED:
- {
- std::string text;
- impl.mController->GetPlaceholderText(Controller::PLACEHOLDER_TYPE_ACTIVE, text);
- value = text;
- break;
- }
- case Toolkit::TextField::Property::FONT_FAMILY:
- {
- value = impl.mController->GetDefaultFontFamily();
- break;
- }
- case Toolkit::TextField::Property::FONT_STYLE:
- {
- GetFontStyleProperty(impl.mController, value, Text::FontStyle::DEFAULT);
- break;
- }
- case Toolkit::TextField::Property::POINT_SIZE:
- {
- value = impl.mController->GetDefaultFontSize(Text::Controller::POINT_SIZE);
- break;
- }
- case Toolkit::TextField::Property::MAX_LENGTH:
- {
- value = impl.mController->GetMaximumNumberOfCharacters();
- break;
- }
- case Toolkit::TextField::Property::EXCEED_POLICY:
- {
- value = impl.mExceedPolicy;
- break;
- }
- case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
- {
- const char* name = Text::GetHorizontalAlignmentString(impl.mController->GetHorizontalAlignment());
-
- if(name)
- {
- value = std::string(name);
- }
- break;
- }
- case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
- {
- const char* name = Text::GetVerticalAlignmentString(impl.mController->GetVerticalAlignment());
-
- if(name)
- {
- value = std::string(name);
- }
- break;
- }
- case Toolkit::TextField::Property::TEXT_COLOR:
- {
- value = impl.mController->GetDefaultColor();
- break;
- }
- case Toolkit::TextField::Property::PLACEHOLDER_TEXT_COLOR:
- {
- value = impl.mController->GetPlaceholderTextColor();
- break;
- }
- case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
- {
- value = impl.mDecorator->GetColor(PRIMARY_CURSOR);
- break;
- }
- case Toolkit::TextField::Property::SECONDARY_CURSOR_COLOR:
- {
- value = impl.mDecorator->GetColor(SECONDARY_CURSOR);
- break;
- }
- case Toolkit::TextField::Property::ENABLE_CURSOR_BLINK:
- {
- value = impl.mController->GetEnableCursorBlink();
- break;
- }
- case Toolkit::TextField::Property::CURSOR_BLINK_INTERVAL:
- {
- value = impl.mDecorator->GetCursorBlinkInterval();
- break;
- }
- case Toolkit::TextField::Property::CURSOR_BLINK_DURATION:
- {
- value = impl.mDecorator->GetCursorBlinkDuration();
- break;
- }
- case Toolkit::TextField::Property::CURSOR_WIDTH:
- {
- value = impl.mDecorator->GetCursorWidth();
- break;
- }
- case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
- {
- value = impl.mDecorator->GetHandleImage(GRAB_HANDLE, HANDLE_IMAGE_RELEASED);
- break;
- }
- case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
- {
- value = impl.mDecorator->GetHandleImage(GRAB_HANDLE, HANDLE_IMAGE_PRESSED);
- break;
- }
- case Toolkit::TextField::Property::SCROLL_THRESHOLD:
- {
- value = impl.mDecorator->GetScrollThreshold();
- break;
- }
- case Toolkit::TextField::Property::SCROLL_SPEED:
- {
- value = impl.mDecorator->GetScrollSpeed();
- break;
- }
- case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
- {
- impl.GetHandleImagePropertyValue(value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED);
- break;
- }
- case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
- {
- impl.GetHandleImagePropertyValue(value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED);
- break;
- }
- case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
- {
- impl.GetHandleImagePropertyValue(value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED);
- break;
- }
- case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
- {
- impl.GetHandleImagePropertyValue(value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED);
- break;
- }
- case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
- {
- impl.GetHandleImagePropertyValue(value, LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED);
- break;
- }
- case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
- {
- impl.GetHandleImagePropertyValue(value, RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED);
- break;
- }
- case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
- {
- value = impl.mDecorator->GetHighlightColor();
- break;
- }
- case Toolkit::TextField::Property::DECORATION_BOUNDING_BOX:
- {
- Rect<int> boundingBox;
- impl.mDecorator->GetBoundingBox(boundingBox);
- value = boundingBox;
- break;
- }
- case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
- {
- Property::Map map;
- impl.mInputMethodOptions.RetrieveProperty(map);
- value = map;
- break;
- }
- case Toolkit::TextField::Property::INPUT_COLOR:
- {
- value = impl.mController->GetInputColor();
- break;
- }
- case Toolkit::TextField::Property::ENABLE_MARKUP:
- {
- value = impl.mController->IsMarkupProcessorEnabled();
- break;
- }
- case Toolkit::TextField::Property::INPUT_FONT_FAMILY:
- {
- value = impl.mController->GetInputFontFamily();
- break;
- }
- case Toolkit::TextField::Property::INPUT_FONT_STYLE:
- {
- GetFontStyleProperty(impl.mController, value, Text::FontStyle::INPUT);
- break;
- }
- case Toolkit::TextField::Property::INPUT_POINT_SIZE:
- {
- value = impl.mController->GetInputFontPointSize();
- break;
- }
- case Toolkit::TextField::Property::UNDERLINE:
- {
- GetUnderlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
- break;
- }
- case Toolkit::TextField::Property::INPUT_UNDERLINE:
- {
- GetUnderlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
- break;
- }
- case Toolkit::TextField::Property::SHADOW:
- {
- GetShadowProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
- break;
- }
- case Toolkit::TextField::Property::INPUT_SHADOW:
- {
- GetShadowProperties(impl.mController, value, Text::EffectStyle::INPUT);
- break;
- }
- case Toolkit::TextField::Property::EMBOSS:
- {
- GetEmbossProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
- break;
- }
- case Toolkit::TextField::Property::INPUT_EMBOSS:
- {
- GetEmbossProperties(impl.mController, value, Text::EffectStyle::INPUT);
- break;
- }
- case Toolkit::TextField::Property::OUTLINE:
- {
- GetOutlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
- break;
- }
- case Toolkit::TextField::Property::INPUT_OUTLINE:
- {
- GetOutlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
- break;
- }
- case Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS:
- {
- Property::Map map;
- impl.mController->GetHiddenInputOption(map);
- value = map;
- break;
- }
- case Toolkit::TextField::Property::PIXEL_SIZE:
- {
- value = impl.mController->GetDefaultFontSize(Text::Controller::PIXEL_SIZE);
- break;
- }
- case Toolkit::TextField::Property::ENABLE_SELECTION:
- {
- value = impl.mController->IsSelectionEnabled();
- break;
- }
- case Toolkit::TextField::Property::PLACEHOLDER:
- {
- Property::Map map;
- impl.mController->GetPlaceholderProperty(map);
- value = map;
- break;
- }
- case Toolkit::TextField::Property::ELLIPSIS:
- {
- value = impl.mController->IsTextElideEnabled();
- break;
- }
- case Toolkit::DevelTextField::Property::ENABLE_SHIFT_SELECTION:
- {
- value = impl.mController->IsShiftSelectionEnabled();
- break;
- }
- case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE:
- {
- value = impl.mController->IsGrabHandleEnabled();
- break;
- }
- case Toolkit::DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
- {
- value = impl.mController->GetMatchLayoutDirection() != DevelText::MatchLayoutDirection::CONTENTS;
- break;
- }
- case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP:
- {
- value = impl.mController->IsGrabHandlePopupEnabled();
- break;
- }
- case Toolkit::DevelTextField::Property::BACKGROUND:
- {
- value = impl.mController->GetBackgroundColor();
- break;
- }
- case Toolkit::DevelTextField::Property::SELECTED_TEXT:
- {
- value = impl.mController->GetSelectedText();
- break;
- }
- case Toolkit::DevelTextField::Property::SELECTED_TEXT_START:
- {
- Uint32Pair range = impl.GetTextSelectionRange();
- value = static_cast<int>(range.first);
- break;
- }
- case Toolkit::DevelTextField::Property::SELECTED_TEXT_END:
- {
- Uint32Pair range = impl.GetTextSelectionRange();
- value = static_cast<int>(range.second);
- break;
- }
- case Toolkit::DevelTextField::Property::ENABLE_EDITING:
- {
- value = impl.IsEditable();
- break;
- }
- case Toolkit::DevelTextField::Property::FONT_SIZE_SCALE:
- {
- value = impl.mController->GetFontSizeScale();
- break;
- }
- case Toolkit::DevelTextField::Property::PRIMARY_CURSOR_POSITION:
- {
- value = static_cast<int>(impl.mController->GetPrimaryCursorPosition());
- break;
- }
- case Toolkit::DevelTextField::Property::GRAB_HANDLE_COLOR:
- {
- value = impl.mDecorator->GetHandleColor();
- break;
- }
- case Toolkit::DevelTextField::Property::INPUT_FILTER:
- {
- Property::Map map;
- impl.mController->GetInputFilterOption(map);
- value = map;
- break;
- }
- case Toolkit::DevelTextField::Property::ELLIPSIS_POSITION:
- {
- value = impl.mController->GetEllipsisPosition();
- break;
- }
- } //switch
+ value = PropertyHandler::GetProperty(textField, index);
}
return value;
void TextField::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField::OnStyleChange\n");
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnStyleChange\n");
switch(change)
{
case StyleChange::DEFAULT_FONT_CHANGE:
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField::OnStyleChange DEFAULT_FONT_CHANGE\n");
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnStyleChange DEFAULT_FONT_CHANGE\n");
const std::string& newFont = GetImpl(styleManager).GetDefaultFontFamily();
// Property system did not set the font so should update it.
mController->UpdateAfterFontChange(newFont);
void TextField::OnRelayout(const Vector2& size, RelayoutContainer& container)
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField OnRelayout\n");
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField OnRelayout\n");
Actor self = Self();
if((Text::Controller::NONE_UPDATED != updateTextType) ||
!mRenderer)
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField::OnRelayout %p Displaying new contents\n", mController.Get());
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnRelayout %p Displaying new contents\n", mController.Get());
if(mDecorator &&
(Text::Controller::NONE_UPDATED != (Text::Controller::DECORATOR_UPDATED & updateTextType)))
void TextField::RenderText(Text::Controller::UpdateTextType updateTextType)
{
- Actor renderableActor;
-
- if(Text::Controller::NONE_UPDATED != (Text::Controller::MODEL_UPDATED & updateTextType))
- {
- if(mRenderer)
- {
- Dali::Toolkit::TextField handle = Dali::Toolkit::TextField(GetOwner());
-
- renderableActor = mRenderer->Render(mController->GetView(),
- handle,
- Property::INVALID_INDEX, // Animatable property not supported
- mAlignmentOffset,
- DepthIndex::CONTENT);
- }
-
- if(renderableActor != mRenderableActor)
- {
- UnparentAndReset(mBackgroundActor);
- UnparentAndReset(mRenderableActor);
- mRenderableActor = renderableActor;
-
- if(mRenderableActor)
- {
- mBackgroundActor = mController->CreateBackgroundActor();
- }
- }
- }
-
- if(mRenderableActor)
- {
- const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition();
-
- float renderableActorPositionX, renderableActorPositionY;
-
- if(mStencil)
- {
- renderableActorPositionX = scrollOffset.x + mAlignmentOffset;
- renderableActorPositionY = scrollOffset.y;
- }
- else
- {
- Extents padding;
- padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
-
- // Support Right-To-Left of padding
- Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(Self().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
- if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
- {
- std::swap(padding.start, padding.end);
- }
-
- renderableActorPositionX = scrollOffset.x + mAlignmentOffset + padding.start;
- renderableActorPositionY = scrollOffset.y + padding.top;
- }
-
- mRenderableActor.SetProperty(Actor::Property::POSITION, Vector2(renderableActorPositionX, renderableActorPositionY));
-
- // Make sure the actors are parented correctly with/without clipping
- Actor self = mStencil ? mStencil : Self();
-
- Actor highlightActor;
-
- for(std::vector<Actor>::iterator it = mClippingDecorationActors.begin(),
- endIt = mClippingDecorationActors.end();
- it != endIt;
- ++it)
- {
- self.Add(*it);
- it->LowerToBottom();
-
- if(it->GetProperty<std::string>(Dali::Actor::Property::NAME) == "HighlightActor")
- {
- highlightActor = *it;
- }
- }
- mClippingDecorationActors.clear();
-
- self.Add(mRenderableActor);
-
- if(mBackgroundActor)
- {
- if(mDecorator && mDecorator->IsHighlightVisible())
- {
- self.Add(mBackgroundActor);
- mBackgroundActor.SetProperty(Actor::Property::POSITION, Vector2(renderableActorPositionX, renderableActorPositionY)); // In text field's coords.
- mBackgroundActor.LowerBelow(highlightActor);
- }
- else
- {
- mRenderableActor.Add(mBackgroundActor);
- mBackgroundActor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f)); // In renderable actor's coords.
- mBackgroundActor.LowerToBottom();
- }
- }
- }
+ CommonTextUtils::RenderText(Self(), mRenderer, mController, mDecorator, mAlignmentOffset, mRenderableActor, mBackgroundActor, mStencil, mClippingDecorationActors, updateTextType);
}
void TextField::OnKeyInputFocusGained()
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField::OnKeyInputFocusGained %p\n", mController.Get());
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnKeyInputFocusGained %p\n", mController.Get());
if(mInputMethodContext && IsEditable())
{
// All input panel properties, such as layout, return key type, and input hint, should be set before input panel activates (or shows).
void TextField::OnKeyInputFocusLost()
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField:OnKeyInputFocusLost %p\n", mController.Get());
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField:OnKeyInputFocusLost %p\n", mController.Get());
if(mInputMethodContext)
{
mInputMethodContext.StatusChangedSignal().Disconnect(this, &TextField::KeyboardStatusChanged);
void TextField::OnTap(const TapGesture& gesture)
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField::OnTap %p\n", mController.Get());
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnTap %p\n", mController.Get());
if(mInputMethodContext && IsEditable())
{
mInputMethodContext.Activate();
bool TextField::OnKeyEvent(const KeyEvent& event)
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField::OnKeyEvent %p keyCode %d\n", mController.Get(), event.GetKeyCode());
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnKeyEvent %p keyCode %d\n", mController.Get(), event.GetKeyCode());
if(Dali::DALI_KEY_ESCAPE == event.GetKeyCode() && mController->ShouldClearFocusOnEscape())
{
void TextField::InputStyleChanged(Text::InputStyle::Mask inputStyleMask)
{
Dali::Toolkit::TextField handle(GetOwner());
-
- Toolkit::TextField::InputStyle::Mask fieldInputStyleMask = Toolkit::TextField::InputStyle::NONE;
-
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_COLOR))
- {
- fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::COLOR);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_FAMILY))
- {
- fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_FAMILY);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_POINT_SIZE))
- {
- fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::POINT_SIZE);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_WEIGHT))
- {
- fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_WIDTH))
- {
- fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_SLANT))
- {
- fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_UNDERLINE))
- {
- fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::UNDERLINE);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_SHADOW))
- {
- fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::SHADOW);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_EMBOSS))
- {
- fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::EMBOSS);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_OUTLINE))
- {
- fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::OUTLINE);
- }
-
- mInputStyleChangedSignal.Emit(handle, fieldInputStyleMask);
+ mInputStyleChangedSignal.Emit(handle, ConvertInputStyle(inputStyleMask));
}
void TextField::AnchorClicked(const std::string& href)
InputMethodContext::CallbackData TextField::OnInputMethodContextEvent(Dali::InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField::OnInputMethodContextEvent %p eventName %d\n", mController.Get(), inputMethodContextEvent.eventName);
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnInputMethodContextEvent %p eventName %d\n", mController.Get(), inputMethodContextEvent.eventName);
return mController->OnInputMethodContextEvent(inputMethodContext, inputMethodContextEvent);
}
if(mDecorator)
{
Property::Map map;
- map[IMAGE_MAP_FILENAME_STRING] = mDecorator->GetHandleImage(handleType, handleImageType);
- value = map;
+ map[PropertyHandler::IMAGE_MAP_FILENAME_STRING] = mDecorator->GetHandleImage(handleType, handleImageType);
+
+ value = map;
}
}
void TextField::KeyboardStatusChanged(bool keyboardShown)
{
- DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField::KeyboardStatusChanged %p keyboardShown %d\n", mController.Get(), keyboardShown);
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::KeyboardStatusChanged %p keyboardShown %d\n", mController.Get(), keyboardShown);
// Just hide the grab handle when keyboard is hidden.
if(!keyboardShown)
uint32_t mOldSelectionEnd;
protected:
+ struct PropertyHandler;
+
/**
* @brief This structure is to connect TextField with Accessible functions.
*/
--- /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.
+ */
+
+#include <dali-toolkit/internal/controls/text-controls/text-field-property-handler.h>
+
+#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
+#include <dali-toolkit/devel-api/text/rendering-backend.h>
+
+#include <dali-toolkit/internal/text/decorator/text-decorator.h>
+#include <dali-toolkit/internal/text/text-controller.h>
+#include <dali-toolkit/internal/text/text-effects-style.h>
+#include <dali-toolkit/internal/text/text-enumerations-impl.h>
+#include <dali-toolkit/internal/text/text-font-style.h>
+#include <dali-toolkit/public-api/text/text-enumerations.h>
+#include <dali/integration-api/debug.h>
+
+#if defined(DEBUG_ENABLED)
+extern Debug::Filter* gTextFieldLogFilter;
+#endif
+
+namespace Dali::Toolkit::Internal
+{
+const char* const TextField::PropertyHandler::IMAGE_MAP_FILENAME_STRING{"filename"};
+
+/// Retrieves a filename from a value that is a Property::Map
+std::string TextField::PropertyHandler::GetImageFileNameFromPropertyValue(const Property::Value& value)
+{
+ std::string filename;
+ const Property::Map* map = value.GetMap();
+ if(map)
+ {
+ const Property::Value* filenameValue = map->Find(TextField::PropertyHandler::IMAGE_MAP_FILENAME_STRING);
+ if(filenameValue)
+ {
+ filenameValue->Get(filename);
+ }
+ }
+ return filename;
+}
+
+void TextField::PropertyHandler::SetProperty(Toolkit::TextField textField, Property::Index index, const Property::Value& value)
+{
+ TextField& impl(GetImpl(textField));
+ DALI_ASSERT_DEBUG(impl.mController && "No text controller");
+ DALI_ASSERT_DEBUG(impl.mDecorator && "No text decorator");
+
+ switch(index)
+ {
+ case Toolkit::DevelTextField::Property::RENDERING_BACKEND:
+ {
+ int backend = value.Get<int>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField %p RENDERING_BACKEND %d\n", impl.mController.Get(), backend);
+
+#ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING
+ if(DevelText::RENDERING_VECTOR_BASED == backend)
+ {
+ backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering
+ }
+#endif
+ if(impl.mRenderingBackend != backend)
+ {
+ impl.mRenderingBackend = backend;
+ impl.mRenderer.Reset();
+
+ // When using the vector-based rendering, the size of the GLyphs are different
+ TextAbstraction::GlyphType glyphType = (DevelText::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
+ impl.mController->SetGlyphType(glyphType);
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::TEXT:
+ {
+ const std::string& text = value.Get<std::string>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p TEXT %s\n", impl.mController.Get(), text.c_str());
+
+ impl.mController->SetText(text);
+ break;
+ }
+
+ case Toolkit::TextField::Property::PLACEHOLDER_TEXT:
+ {
+ const std::string& text = value.Get<std::string>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT %s\n", impl.mController.Get(), text.c_str());
+
+ impl.mController->SetPlaceholderText(Text::Controller::PLACEHOLDER_TYPE_INACTIVE, text);
+ break;
+ }
+ case Toolkit::TextField::Property::PLACEHOLDER_TEXT_FOCUSED:
+ {
+ const std::string& text = value.Get<std::string>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_FOCUSED %s\n", impl.mController.Get(), text.c_str());
+
+ impl.mController->SetPlaceholderText(Text::Controller::PLACEHOLDER_TYPE_ACTIVE, text);
+ break;
+ }
+ case Toolkit::TextField::Property::FONT_FAMILY:
+ {
+ const std::string& fontFamily = value.Get<std::string>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str());
+ impl.mController->SetDefaultFontFamily(fontFamily);
+ break;
+ }
+ case Toolkit::TextField::Property::FONT_STYLE:
+ {
+ SetFontStyleProperty(impl.mController, value, Text::FontStyle::DEFAULT);
+ break;
+ }
+ case Toolkit::TextField::Property::POINT_SIZE:
+ {
+ const float pointSize = value.Get<float>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p POINT_SIZE %f\n", impl.mController.Get(), pointSize);
+
+ if(!Equals(impl.mController->GetDefaultFontSize(Text::Controller::POINT_SIZE), pointSize))
+ {
+ impl.mController->SetDefaultFontSize(pointSize, Text::Controller::POINT_SIZE);
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::MAX_LENGTH:
+ {
+ const int max = value.Get<int>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p MAX_LENGTH %d\n", impl.mController.Get(), max);
+
+ impl.mController->SetMaximumNumberOfCharacters(max);
+ break;
+ }
+ case Toolkit::TextField::Property::EXCEED_POLICY:
+ {
+ impl.mExceedPolicy = value.Get<int>();
+
+ if(Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == impl.mExceedPolicy)
+ {
+ impl.EnableClipping();
+ }
+ else
+ {
+ UnparentAndReset(impl.mStencil);
+ }
+ impl.RequestTextRelayout();
+ break;
+ }
+
+ case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
+ {
+ Text::HorizontalAlignment::Type alignment(static_cast<Text::HorizontalAlignment::Type>(-1)); // Set to invalid value to ensure a valid mode does get set
+ if(Text::GetHorizontalAlignmentEnumeration(value, alignment))
+ {
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p HORIZONTAL_ALIGNMENT %d\n", impl.mController.Get(), alignment);
+ impl.mController->SetHorizontalAlignment(alignment);
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
+ {
+ Toolkit::Text::VerticalAlignment::Type alignment(static_cast<Text::VerticalAlignment::Type>(-1)); // Set to invalid value to ensure a valid mode does get set
+ if(Text::GetVerticalAlignmentEnumeration(value, alignment))
+ {
+ impl.mController->SetVerticalAlignment(alignment);
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p VERTICAL_ALIGNMENT %d\n", impl.mController.Get(), alignment);
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::TEXT_COLOR:
+ {
+ const Vector4& textColor = value.Get<Vector4>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a);
+
+ if(impl.mController->GetDefaultColor() != textColor)
+ {
+ impl.mController->SetDefaultColor(textColor);
+ impl.mController->SetInputColor(textColor);
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::PLACEHOLDER_TEXT_COLOR:
+ {
+ const Vector4& textColor = value.Get<Vector4>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a);
+
+ if(impl.mController->GetPlaceholderTextColor() != textColor)
+ {
+ impl.mController->SetPlaceholderTextColor(textColor);
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
+ {
+ const Vector4& color = value.Get<Vector4>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p PRIMARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
+
+ impl.mDecorator->SetCursorColor(Toolkit::Text::PRIMARY_CURSOR, color);
+ impl.RequestTextRelayout();
+ break;
+ }
+ case Toolkit::TextField::Property::SECONDARY_CURSOR_COLOR:
+ {
+ const Vector4& color = value.Get<Vector4>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p SECONDARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
+
+ impl.mDecorator->SetCursorColor(Toolkit::Text::SECONDARY_CURSOR, color);
+ impl.RequestTextRelayout();
+ break;
+ }
+ case Toolkit::TextField::Property::ENABLE_CURSOR_BLINK:
+ {
+ const bool enable = value.Get<bool>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable);
+
+ impl.mController->SetEnableCursorBlink(enable);
+ impl.RequestTextRelayout();
+ break;
+ }
+ case Toolkit::TextField::Property::CURSOR_BLINK_INTERVAL:
+ {
+ const float interval = value.Get<float>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval);
+
+ impl.mDecorator->SetCursorBlinkInterval(interval);
+ break;
+ }
+ case Toolkit::TextField::Property::CURSOR_BLINK_DURATION:
+ {
+ const float duration = value.Get<float>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration);
+
+ impl.mDecorator->SetCursorBlinkDuration(duration);
+ break;
+ }
+ case Toolkit::TextField::Property::CURSOR_WIDTH:
+ {
+ const int width = value.Get<int>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField %p CURSOR_WIDTH %d\n", impl.mController.Get(), width);
+
+ impl.mDecorator->SetCursorWidth(width);
+ impl.mController->GetLayoutEngine().SetCursorWidth(width);
+ break;
+ }
+ case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
+ {
+ const std::string imageFileName = value.Get<std::string>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str());
+
+ if(imageFileName.size())
+ {
+ impl.mDecorator->SetHandleImage(Toolkit::Text::GRAB_HANDLE, Toolkit::Text::HANDLE_IMAGE_RELEASED, imageFileName);
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
+ {
+ const std::string imageFileName = value.Get<std::string>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str());
+
+ if(imageFileName.size())
+ {
+ impl.mDecorator->SetHandleImage(Toolkit::Text::GRAB_HANDLE, Toolkit::Text::HANDLE_IMAGE_PRESSED, imageFileName);
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::SCROLL_THRESHOLD:
+ {
+ const float threshold = value.Get<float>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField %p SCROLL_THRESHOLD %f\n", impl.mController.Get(), threshold);
+
+ impl.mDecorator->SetScrollThreshold(threshold);
+ break;
+ }
+ case Toolkit::TextField::Property::SCROLL_SPEED:
+ {
+ const float speed = value.Get<float>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField %p SCROLL_SPEED %f\n", impl.mController.Get(), speed);
+
+ impl.mDecorator->SetScrollSpeed(speed);
+ break;
+ }
+ case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
+ {
+ const std::string filename = GetImageFileNameFromPropertyValue(value);
+
+ if(filename.size())
+ {
+ impl.mDecorator->SetHandleImage(Toolkit::Text::LEFT_SELECTION_HANDLE, Toolkit::Text::HANDLE_IMAGE_RELEASED, filename);
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
+ {
+ const std::string filename = GetImageFileNameFromPropertyValue(value);
+
+ if(filename.size())
+ {
+ impl.mDecorator->SetHandleImage(Toolkit::Text::RIGHT_SELECTION_HANDLE, Toolkit::Text::HANDLE_IMAGE_RELEASED, filename);
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
+ {
+ const std::string filename = GetImageFileNameFromPropertyValue(value);
+
+ if(filename.size())
+ {
+ impl.mDecorator->SetHandleImage(Toolkit::Text::LEFT_SELECTION_HANDLE, Toolkit::Text::HANDLE_IMAGE_PRESSED, filename);
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
+ {
+ const std::string filename = GetImageFileNameFromPropertyValue(value);
+
+ if(filename.size())
+ {
+ impl.mDecorator->SetHandleImage(Toolkit::Text::RIGHT_SELECTION_HANDLE, Toolkit::Text::HANDLE_IMAGE_PRESSED, filename);
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
+ {
+ const std::string filename = GetImageFileNameFromPropertyValue(value);
+
+ if(filename.size())
+ {
+ impl.mDecorator->SetHandleImage(Toolkit::Text::LEFT_SELECTION_HANDLE_MARKER,
+ Toolkit::Text::HANDLE_IMAGE_RELEASED,
+ filename);
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
+ {
+ const std::string filename = GetImageFileNameFromPropertyValue(value);
+
+ if(filename.size())
+ {
+ impl.mDecorator->SetHandleImage(Toolkit::Text::RIGHT_SELECTION_HANDLE_MARKER,
+ Toolkit::Text::HANDLE_IMAGE_RELEASED,
+ filename);
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
+ {
+ const Vector4 color = value.Get<Vector4>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p SELECTION_HIGHLIGHT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
+
+ impl.mDecorator->SetHighlightColor(color);
+ impl.RequestTextRelayout();
+ break;
+ }
+ case Toolkit::TextField::Property::DECORATION_BOUNDING_BOX:
+ {
+ const Rect<int>& box = value.Get<Rect<int> >();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p DECORATION_BOUNDING_BOX %d,%d %dx%d\n", impl.mController.Get(), box.x, box.y, box.width, box.height);
+
+ impl.mDecorator->SetBoundingBox(box);
+ impl.RequestTextRelayout();
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
+ {
+ const Property::Map* map = value.GetMap();
+ if(map)
+ {
+ impl.mInputMethodOptions.ApplyProperty(*map);
+ }
+ impl.mController->SetInputModePassword(impl.mInputMethodOptions.IsPassword());
+
+ Toolkit::Control control = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
+ if(control == textField)
+ {
+ impl.mInputMethodContext.ApplyOptions(impl.mInputMethodOptions);
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_COLOR:
+ {
+ const Vector4& inputColor = value.Get<Vector4>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p INPUT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), inputColor.r, inputColor.g, inputColor.b, inputColor.a);
+
+ impl.mController->SetInputColor(inputColor);
+ break;
+ }
+ case Toolkit::TextField::Property::ENABLE_MARKUP:
+ {
+ const bool enableMarkup = value.Get<bool>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p ENABLE_MARKUP %d\n", impl.mController.Get(), enableMarkup);
+
+ impl.mController->SetMarkupProcessorEnabled(enableMarkup);
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_FONT_FAMILY:
+ {
+ const std::string& fontFamily = value.Get<std::string>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str());
+ impl.mController->SetInputFontFamily(fontFamily);
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_FONT_STYLE:
+ {
+ SetFontStyleProperty(impl.mController, value, Text::FontStyle::INPUT);
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_POINT_SIZE:
+ {
+ const float pointSize = value.Get<float>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize);
+ impl.mController->SetInputFontPointSize(pointSize);
+ break;
+ }
+ case Toolkit::TextField::Property::UNDERLINE:
+ {
+ const bool update = SetUnderlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+ if(update)
+ {
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_UNDERLINE:
+ {
+ const bool update = SetUnderlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
+ if(update)
+ {
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::SHADOW:
+ {
+ const bool update = SetShadowProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+ if(update)
+ {
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_SHADOW:
+ {
+ const bool update = SetShadowProperties(impl.mController, value, Text::EffectStyle::INPUT);
+ if(update)
+ {
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::EMBOSS:
+ {
+ const bool update = SetEmbossProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+ if(update)
+ {
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_EMBOSS:
+ {
+ const bool update = SetEmbossProperties(impl.mController, value, Text::EffectStyle::INPUT);
+ if(update)
+ {
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::OUTLINE:
+ {
+ const bool update = SetOutlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+ if(update)
+ {
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_OUTLINE:
+ {
+ const bool update = SetOutlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
+ if(update)
+ {
+ impl.mRenderer.Reset();
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS:
+ {
+ const Property::Map* map = value.GetMap();
+ if(map)
+ {
+ impl.mController->SetHiddenInputOption(*map);
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::PIXEL_SIZE:
+ {
+ const float pixelSize = value.Get<float>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize);
+
+ if(!Equals(impl.mController->GetDefaultFontSize(Text::Controller::PIXEL_SIZE), pixelSize))
+ {
+ impl.mController->SetDefaultFontSize(pixelSize, Text::Controller::PIXEL_SIZE);
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::ENABLE_SELECTION:
+ {
+ const bool enableSelection = value.Get<bool>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p ENABLE_SELECTION %d\n", impl.mController.Get(), enableSelection);
+ impl.mController->SetSelectionEnabled(enableSelection);
+ break;
+ }
+ case Toolkit::TextField::Property::PLACEHOLDER:
+ {
+ const Property::Map* map = value.GetMap();
+ if(map)
+ {
+ impl.mController->SetPlaceholderProperty(*map);
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::ELLIPSIS:
+ {
+ const bool ellipsis = value.Get<bool>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis);
+
+ impl.mController->SetTextElideEnabled(ellipsis);
+ break;
+ }
+ case Toolkit::DevelTextField::Property::ENABLE_SHIFT_SELECTION:
+ {
+ const bool shiftSelection = value.Get<bool>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p ENABLE_SHIFT_SELECTION %d\n", impl.mController.Get(), shiftSelection);
+
+ impl.mController->SetShiftSelectionEnabled(shiftSelection);
+ break;
+ }
+ case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE:
+ {
+ const bool grabHandleEnabled = value.Get<bool>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p ENABLE_GRAB_HANDLE %d\n", impl.mController.Get(), grabHandleEnabled);
+
+ impl.mController->SetGrabHandleEnabled(grabHandleEnabled);
+ break;
+ }
+ case Toolkit::DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
+ {
+ impl.mController->SetMatchLayoutDirection(value.Get<bool>() ? DevelText::MatchLayoutDirection::LOCALE : DevelText::MatchLayoutDirection::CONTENTS);
+ break;
+ }
+ case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP:
+ {
+ const bool grabHandlePopupEnabled = value.Get<bool>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p ENABLE_GRAB_HANDLE_POPUP %d\n", impl.mController.Get(), grabHandlePopupEnabled);
+
+ impl.mController->SetGrabHandlePopupEnabled(grabHandlePopupEnabled);
+ break;
+ }
+ case Toolkit::DevelTextField::Property::BACKGROUND:
+ {
+ const Vector4 backgroundColor = value.Get<Vector4>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p BACKGROUND %f,%f,%f,%f\n", impl.mController.Get(), backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a);
+
+ impl.mController->SetBackgroundEnabled(true);
+ impl.mController->SetBackgroundColor(backgroundColor);
+ break;
+ }
+ case Toolkit::DevelTextField::Property::SELECTED_TEXT_START:
+ {
+ uint32_t start = static_cast<uint32_t>(value.Get<int>());
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p SELECTED_TEXT_START %d\n", impl.mController.Get(), start);
+ impl.SetTextSelectionRange(&start, nullptr);
+ break;
+ }
+ case Toolkit::DevelTextField::Property::SELECTED_TEXT_END:
+ {
+ uint32_t end = static_cast<uint32_t>(value.Get<int>());
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p SELECTED_TEXT_END %d\n", impl.mController.Get(), end);
+ impl.SetTextSelectionRange(nullptr, &end);
+ break;
+ }
+ case Toolkit::DevelTextField::Property::ENABLE_EDITING:
+ {
+ const bool editable = value.Get<bool>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p ENABLE_EDITING %d\n", impl.mController.Get(), editable);
+ impl.SetEditable(editable);
+ break;
+ }
+ case Toolkit::DevelTextField::Property::FONT_SIZE_SCALE:
+ {
+ const float scale = value.Get<float>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p FONT_SIZE_SCALE %f\n", impl.mController.Get(), scale);
+
+ if(!Equals(impl.mController->GetFontSizeScale(), scale))
+ {
+ impl.mController->SetFontSizeScale(scale);
+ }
+ break;
+ }
+ case Toolkit::DevelTextField::Property::PRIMARY_CURSOR_POSITION:
+ {
+ uint32_t position = static_cast<uint32_t>(value.Get<int>());
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p PRIMARY_CURSOR_POSITION %d\n", impl.mController.Get(), position);
+ if(impl.mController->SetPrimaryCursorPosition(position, impl.HasKeyInputFocus()))
+ {
+ impl.SetKeyInputFocus();
+ }
+ break;
+ }
+ case Toolkit::DevelTextField::Property::GRAB_HANDLE_COLOR:
+ {
+ const Vector4 color = value.Get<Vector4>();
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p GRAB_HANDLE_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
+
+ impl.mDecorator->SetHandleColor(color);
+ impl.RequestTextRelayout();
+ break;
+ }
+
+ case Toolkit::DevelTextField::Property::INPUT_FILTER:
+ {
+ const Property::Map* map = value.GetMap();
+ if(map)
+ {
+ impl.mController->SetInputFilterOption(*map);
+ }
+ break;
+ }
+ case Toolkit::DevelTextField::Property::ELLIPSIS_POSITION:
+ {
+ DevelText::EllipsisPosition::Type ellipsisPositionType(static_cast<DevelText::EllipsisPosition::Type>(-1)); // Set to invalid value to ensure a valid mode does get set
+ if(Text::GetEllipsisPositionTypeEnumeration(value, ellipsisPositionType))
+ {
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p EllipsisPosition::Type %d\n", impl.mController.Get(), ellipsisPositionType);
+ impl.mController->SetEllipsisPosition(ellipsisPositionType);
+ }
+ break;
+ }
+ }
+}
+
+Property::Value TextField::PropertyHandler::GetProperty(Toolkit::TextField textField, Property::Index index)
+{
+ Property::Value value;
+ TextField& impl(GetImpl(textField));
+ DALI_ASSERT_DEBUG(impl.mController && "No text controller");
+ DALI_ASSERT_DEBUG(impl.mDecorator && "No text decorator");
+
+ switch(index)
+ {
+ case Toolkit::DevelTextField::Property::RENDERING_BACKEND:
+ {
+ value = impl.mRenderingBackend;
+ break;
+ }
+ case Toolkit::TextField::Property::TEXT:
+ {
+ std::string text;
+ impl.mController->GetText(text);
+ DALI_LOG_INFO(gTextFieldLogFilter, Debug::General, "TextField %p returning text: %s\n", impl.mController.Get(), text.c_str());
+ value = text;
+ break;
+ }
+ case Toolkit::TextField::Property::PLACEHOLDER_TEXT:
+ {
+ std::string text;
+ impl.mController->GetPlaceholderText(Text::Controller::PLACEHOLDER_TYPE_INACTIVE, text);
+ value = text;
+ break;
+ }
+ case Toolkit::TextField::Property::PLACEHOLDER_TEXT_FOCUSED:
+ {
+ std::string text;
+ impl.mController->GetPlaceholderText(Text::Controller::PLACEHOLDER_TYPE_ACTIVE, text);
+ value = text;
+ break;
+ }
+ case Toolkit::TextField::Property::FONT_FAMILY:
+ {
+ value = impl.mController->GetDefaultFontFamily();
+ break;
+ }
+ case Toolkit::TextField::Property::FONT_STYLE:
+ {
+ GetFontStyleProperty(impl.mController, value, Text::FontStyle::DEFAULT);
+ break;
+ }
+ case Toolkit::TextField::Property::POINT_SIZE:
+ {
+ value = impl.mController->GetDefaultFontSize(Text::Controller::POINT_SIZE);
+ break;
+ }
+ case Toolkit::TextField::Property::MAX_LENGTH:
+ {
+ value = impl.mController->GetMaximumNumberOfCharacters();
+ break;
+ }
+ case Toolkit::TextField::Property::EXCEED_POLICY:
+ {
+ value = impl.mExceedPolicy;
+ break;
+ }
+ case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
+ {
+ const char* name = Text::GetHorizontalAlignmentString(impl.mController->GetHorizontalAlignment());
+ if(name)
+ {
+ value = std::string(name);
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
+ {
+ const char* name = Text::GetVerticalAlignmentString(impl.mController->GetVerticalAlignment());
+
+ if(name)
+ {
+ value = std::string(name);
+ }
+ break;
+ }
+ case Toolkit::TextField::Property::TEXT_COLOR:
+ {
+ value = impl.mController->GetDefaultColor();
+ break;
+ }
+ case Toolkit::TextField::Property::PLACEHOLDER_TEXT_COLOR:
+ {
+ value = impl.mController->GetPlaceholderTextColor();
+ break;
+ }
+ case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
+ {
+ value = impl.mDecorator->GetColor(Text::PRIMARY_CURSOR);
+ break;
+ }
+ case Toolkit::TextField::Property::SECONDARY_CURSOR_COLOR:
+ {
+ value = impl.mDecorator->GetColor(Text::SECONDARY_CURSOR);
+ break;
+ }
+ case Toolkit::TextField::Property::ENABLE_CURSOR_BLINK:
+ {
+ value = impl.mController->GetEnableCursorBlink();
+ break;
+ }
+ case Toolkit::TextField::Property::CURSOR_BLINK_INTERVAL:
+ {
+ value = impl.mDecorator->GetCursorBlinkInterval();
+ break;
+ }
+ case Toolkit::TextField::Property::CURSOR_BLINK_DURATION:
+ {
+ value = impl.mDecorator->GetCursorBlinkDuration();
+ break;
+ }
+ case Toolkit::TextField::Property::CURSOR_WIDTH:
+ {
+ value = impl.mDecorator->GetCursorWidth();
+ break;
+ }
+ case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
+ {
+ value = impl.mDecorator->GetHandleImage(Text::GRAB_HANDLE, Text::HANDLE_IMAGE_RELEASED);
+ break;
+ }
+ case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
+ {
+ value = impl.mDecorator->GetHandleImage(Text::GRAB_HANDLE, Text::HANDLE_IMAGE_PRESSED);
+ break;
+ }
+ case Toolkit::TextField::Property::SCROLL_THRESHOLD:
+ {
+ value = impl.mDecorator->GetScrollThreshold();
+ break;
+ }
+ case Toolkit::TextField::Property::SCROLL_SPEED:
+ {
+ value = impl.mDecorator->GetScrollSpeed();
+ break;
+ }
+ case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
+ {
+ impl.GetHandleImagePropertyValue(value, Text::LEFT_SELECTION_HANDLE, Text::HANDLE_IMAGE_RELEASED);
+ break;
+ }
+ case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
+ {
+ impl.GetHandleImagePropertyValue(value, Text::RIGHT_SELECTION_HANDLE, Text::HANDLE_IMAGE_RELEASED);
+ break;
+ }
+ case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
+ {
+ impl.GetHandleImagePropertyValue(value, Text::LEFT_SELECTION_HANDLE, Text::HANDLE_IMAGE_PRESSED);
+ break;
+ }
+ case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
+ {
+ impl.GetHandleImagePropertyValue(value, Text::RIGHT_SELECTION_HANDLE, Text::HANDLE_IMAGE_PRESSED);
+ break;
+ }
+ case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
+ {
+ impl.GetHandleImagePropertyValue(value, Text::LEFT_SELECTION_HANDLE_MARKER, Text::HANDLE_IMAGE_RELEASED);
+ break;
+ }
+ case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
+ {
+ impl.GetHandleImagePropertyValue(value, Text::RIGHT_SELECTION_HANDLE_MARKER, Text::HANDLE_IMAGE_RELEASED);
+ break;
+ }
+ case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
+ {
+ value = impl.mDecorator->GetHighlightColor();
+ break;
+ }
+ case Toolkit::TextField::Property::DECORATION_BOUNDING_BOX:
+ {
+ Rect<int> boundingBox;
+ impl.mDecorator->GetBoundingBox(boundingBox);
+ value = boundingBox;
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
+ {
+ Property::Map map;
+ impl.mInputMethodOptions.RetrieveProperty(map);
+ value = map;
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_COLOR:
+ {
+ value = impl.mController->GetInputColor();
+ break;
+ }
+ case Toolkit::TextField::Property::ENABLE_MARKUP:
+ {
+ value = impl.mController->IsMarkupProcessorEnabled();
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_FONT_FAMILY:
+ {
+ value = impl.mController->GetInputFontFamily();
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_FONT_STYLE:
+ {
+ GetFontStyleProperty(impl.mController, value, Text::FontStyle::INPUT);
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_POINT_SIZE:
+ {
+ value = impl.mController->GetInputFontPointSize();
+ break;
+ }
+ case Toolkit::TextField::Property::UNDERLINE:
+ {
+ GetUnderlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_UNDERLINE:
+ {
+ GetUnderlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
+ break;
+ }
+ case Toolkit::TextField::Property::SHADOW:
+ {
+ GetShadowProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_SHADOW:
+ {
+ GetShadowProperties(impl.mController, value, Text::EffectStyle::INPUT);
+ break;
+ }
+ case Toolkit::TextField::Property::EMBOSS:
+ {
+ GetEmbossProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_EMBOSS:
+ {
+ GetEmbossProperties(impl.mController, value, Text::EffectStyle::INPUT);
+ break;
+ }
+ case Toolkit::TextField::Property::OUTLINE:
+ {
+ GetOutlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
+ break;
+ }
+ case Toolkit::TextField::Property::INPUT_OUTLINE:
+ {
+ GetOutlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
+ break;
+ }
+ case Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS:
+ {
+ Property::Map map;
+ impl.mController->GetHiddenInputOption(map);
+ value = map;
+ break;
+ }
+ case Toolkit::TextField::Property::PIXEL_SIZE:
+ {
+ value = impl.mController->GetDefaultFontSize(Text::Controller::PIXEL_SIZE);
+ break;
+ }
+ case Toolkit::TextField::Property::ENABLE_SELECTION:
+ {
+ value = impl.mController->IsSelectionEnabled();
+ break;
+ }
+ case Toolkit::TextField::Property::PLACEHOLDER:
+ {
+ Property::Map map;
+ impl.mController->GetPlaceholderProperty(map);
+ value = map;
+ break;
+ }
+ case Toolkit::TextField::Property::ELLIPSIS:
+ {
+ value = impl.mController->IsTextElideEnabled();
+ break;
+ }
+ case Toolkit::DevelTextField::Property::ENABLE_SHIFT_SELECTION:
+ {
+ value = impl.mController->IsShiftSelectionEnabled();
+ break;
+ }
+ case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE:
+ {
+ value = impl.mController->IsGrabHandleEnabled();
+ break;
+ }
+ case Toolkit::DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
+ {
+ value = impl.mController->GetMatchLayoutDirection() != DevelText::MatchLayoutDirection::CONTENTS;
+ break;
+ }
+ case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP:
+ {
+ value = impl.mController->IsGrabHandlePopupEnabled();
+ break;
+ }
+ case Toolkit::DevelTextField::Property::BACKGROUND:
+ {
+ value = impl.mController->GetBackgroundColor();
+ break;
+ }
+ case Toolkit::DevelTextField::Property::SELECTED_TEXT:
+ {
+ value = impl.mController->GetSelectedText();
+ break;
+ }
+ case Toolkit::DevelTextField::Property::SELECTED_TEXT_START:
+ {
+ Uint32Pair range = impl.GetTextSelectionRange();
+ value = static_cast<int>(range.first);
+ break;
+ }
+ case Toolkit::DevelTextField::Property::SELECTED_TEXT_END:
+ {
+ Uint32Pair range = impl.GetTextSelectionRange();
+ value = static_cast<int>(range.second);
+ break;
+ }
+ case Toolkit::DevelTextField::Property::ENABLE_EDITING:
+ {
+ value = impl.IsEditable();
+ break;
+ }
+ case Toolkit::DevelTextField::Property::FONT_SIZE_SCALE:
+ {
+ value = impl.mController->GetFontSizeScale();
+ break;
+ }
+ case Toolkit::DevelTextField::Property::PRIMARY_CURSOR_POSITION:
+ {
+ value = static_cast<int>(impl.mController->GetPrimaryCursorPosition());
+ break;
+ }
+ case Toolkit::DevelTextField::Property::GRAB_HANDLE_COLOR:
+ {
+ value = impl.mDecorator->GetHandleColor();
+ break;
+ }
+ case Toolkit::DevelTextField::Property::INPUT_FILTER:
+ {
+ Property::Map map;
+ impl.mController->GetInputFilterOption(map);
+ value = map;
+ break;
+ }
+ case Toolkit::DevelTextField::Property::ELLIPSIS_POSITION:
+ {
+ value = impl.mController->GetEllipsisPosition();
+ break;
+ }
+ } //switch
+ return value;
+}
+
+} // namespace Dali::Toolkit::Internal
--- /dev/null
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_FIELD_PROPERTY_HANDLER_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_FIELD_PROPERTY_HANDLER_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.
+ */
+
+#include <dali-toolkit/internal/controls/text-controls/text-field-impl.h>
+
+namespace Dali::Toolkit::Internal
+{
+/**
+ * Class to manage properties for the TextField
+ */
+struct TextField::PropertyHandler
+{
+ static const char* const IMAGE_MAP_FILENAME_STRING; //<<< "filename" key for image map
+
+ /**
+ * Set properties on the text field / controller / decorator
+ *
+ * @param[in] textField The handle for the text field
+ * @param[in] index The property index of the property to set
+ * @param[in] value The value to set
+ */
+ static void SetProperty(Toolkit::TextField textField, Property::Index index, const Property::Value& value);
+
+ /**
+ * Get properties from the text field / controller / decorator
+ *
+ * @param[in] textField The handle for the text field
+ * @param[in] index The property index of the property to set
+ * @return the value
+ */
+ static Property::Value GetProperty(Toolkit::TextField textField, Property::Index index);
+
+private:
+ /**
+ * Method to extract "filename" value from a Property::Map
+ *
+ * @param[in] The property value containing the Property::Map
+ * @return The resulting "filename" value if present
+ */
+ static std::string GetImageFileNameFromPropertyValue(const Property::Value& value);
+};
+
+} // namespace Dali::Toolkit::Internal
+
+#endif //DALI_TOOLKIT_INTERNAL_TEXT_FIELD_PROPERTY_HANDLER_H
${toolkit_src_dir}/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.cpp
${toolkit_src_dir}/controls/scrollable/scroll-view/scroll-view-effect-impl.cpp
${toolkit_src_dir}/controls/scrollable/scroll-view/scroll-view-impl.cpp
+ ${toolkit_src_dir}/controls/scrollable/scroll-view/scroll-view-impl-constraints.cpp
${toolkit_src_dir}/controls/scrollable/scroll-view/scroll-view-page-path-effect-impl.cpp
${toolkit_src_dir}/controls/scene3d-view/scene3d-view-impl.cpp
${toolkit_src_dir}/controls/scene3d-view/gltf-loader.cpp
${toolkit_src_dir}/controls/slider/slider-impl.cpp
${toolkit_src_dir}/controls/super-blur-view/super-blur-view-impl.cpp
${toolkit_src_dir}/controls/table-view/table-view-impl.cpp
+ ${toolkit_src_dir}/controls/text-controls/common-text-utils.cpp
${toolkit_src_dir}/controls/text-controls/text-editor-impl.cpp
+ ${toolkit_src_dir}/controls/text-controls/text-editor-property-handler.cpp
${toolkit_src_dir}/controls/text-controls/text-field-impl.cpp
+ ${toolkit_src_dir}/controls/text-controls/text-field-property-handler.cpp
${toolkit_src_dir}/controls/text-controls/text-label-impl.cpp
${toolkit_src_dir}/controls/text-controls/text-selection-popup-impl.cpp
${toolkit_src_dir}/controls/text-controls/text-selection-toolbar-impl.cpp
${toolkit_src_dir}/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
// solve (v.x - x)^2 + (v.y - x)^2 = (cr / cy * x)^2
#if IS_REQUIRED_ROUNDED_CORNER
- // NOTE : lowspec HW cannot calculate here. need to reduce numeric error
- mediump float A = (cr * cr - 2.0 * cy * cy);
- mediump float B = cy * (v.x + v.y);
- mediump float V = dot(v,v);
- mediump float D = B * B + A * V;
+ // Note : lowspec HW cannot calculate here. need to reduce numeric error
+ highp float A = (cr * cr - 2.0 * cy * cy);
+ highp float B = cy * (v.x + v.y);
+ highp float V = dot(v,v);
+ highp float D = B * B + A * V;
potential = V * (cr + cy) / (sqrt(D) + B);
#else
// We can simplify this value cause cy = 0.8 * blurRadius, cr = 1.2 * blurRadius
// potential = 5.0*(sqrt(4.0*(v.x+v.y)^2 + dot(v,v)) - 2.0*(v.x+v.y));
// = 10.0*(v.x+v.y) * (sqrt(1.0 + (length(v) / (2.0*(v.x+v.y)))^2) - 1.0);
// = 10.0*(v.x+v.y) * (sqrt(1.25 - x + x^2) - 1.0);
- // ~= 10.0*(v.x+v.y) * (0.11803399 - 0.44721360x + 0.35777088x^2 - 0.14310x^3 + O(x^4)) (Taylor series)
+ // ~= 10.0*(v.x+v.y) * (0.11803399 - 0.44721360x + 0.35777088x^2 - 0.14310x^3 + O(x^5)) (Taylor series)
// ~= -1.0557281 * (v.x + v.y) + 2.236068 * length(v) - ~~~ (here, x <= 0.5 * (1.0 - sqrt(0.5)) < 0.1464467)
// Note : This simplify need cause we should use it on lowspec HW.
mediump float x = 0.5 * (1.0 - length(v) / (v.x + v.y));
// Check if whether is right to left markup and Keeps true if the previous value was true.
currentScriptRun.isRightToLeft = currentScriptRun.isRightToLeft || TextAbstraction::IsRightToLeftMark(character);
- if(TextAbstraction::EMOJI == currentScriptRun.script)
+ // ZWJ, ZWNJ between emojis should be treated as EMOJI.
+ if(TextAbstraction::EMOJI == currentScriptRun.script && !(TextAbstraction::IsZeroWidthJoiner(character) || TextAbstraction::IsZeroWidthNonJoiner(character)))
{
// Emojis doesn't mix well with characters common to all scripts. Insert the emoji run.
scripts.Insert(scripts.Begin() + scriptIndex, currentScriptRun);
Vector<ScriptRun>::ConstIterator scriptRunEndIt = scripts.End();
bool isNewParagraphCharacter = false;
- bool isPreviousEmojiScript = false;
+ bool isPreviousEmojiScript = false;
+ FontId previousEmojiFontId = 0u;
CharacterIndex lastCharacter = startIndex + numberOfCharacters;
for(Length index = startIndex; index < lastCharacter; ++index)
currentFontRun.isBoldRequired = false;
}
+ // ZWJ, ZWNJ between emojis should use the previous emoji font.
+ if(isEmojiScript && (TextAbstraction::IsZeroWidthJoiner(character) || TextAbstraction::IsZeroWidthNonJoiner(character)))
+ {
+ if(0u != previousEmojiFontId)
+ {
+ fontId = previousEmojiFontId;
+ isValidFont = true;
+ }
+ }
+
// If the given font is not valid, it means either:
// - there is no cached font for the current script yet or,
// - the user has set a different font than the default one for the current script or,
} // !isValidFont (2)
} // !isValidFont (1)
+ // Store the font id when the first character is an emoji.
+ if(isEmojiScript && !isPreviousEmojiScript)
+ {
+ if(0u != fontId)
+ {
+ previousEmojiFontId = fontId;
+ }
+ }
+
#ifdef DEBUG_ENABLED
{
Dali::TextAbstraction::FontDescription description;
// Need to reshape the glyph as the font may be different in size.
const GlyphInfo& ellipsisGlyph = fontClient.GetEllipsisGlyph(fontClient.GetPointSize(glyphToRemove.fontId));
- if(!firstPenSet)
+ if(!firstPenSet || EqualsZero(glyphToRemove.advance))
{
const Vector2& position = *(elidedPositionsBuffer + indexOfEllipsis);
--- /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;
};
const std::string EMPTY_STRING("");
-int ConvertPixelToPint(float pixel)
+template<typename Type>
+void EnsureCreated(Type*& object)
{
- unsigned int horizontalDpi = 0u;
- unsigned int verticalDpi = 0u;
- Dali::TextAbstraction::FontClient fontClient = Dali::TextAbstraction::FontClient::Get();
- fontClient.GetDpi(horizontalDpi, verticalDpi);
-
- return (pixel * 72.f) / static_cast<float>(horizontalDpi);
+ if(!object)
+ {
+ object = new Type();
+ }
}
-} // namespace
+template<typename Type>
+void EnsureCreated(std::unique_ptr<Type>& object)
+{
+ if(!object)
+ {
+ object = std::unique_ptr<Type>(new Type());
+ }
+}
-namespace Dali
+template<typename Type, typename Arg1>
+void EnsureCreated(Type*& object, Arg1 arg1)
{
-namespace Toolkit
+ if(!object)
+ {
+ object = new Type(arg1);
+ }
+}
+
+template<typename Type, typename Arg1, typename Arg2>
+void EnsureCreated(Type*& object, Arg1 arg1, Arg2 arg2)
{
-namespace Text
+ if(!object)
+ {
+ object = new Type(arg1, arg2);
+ }
+}
+
+float GetDpi()
{
-// public : Constructor.
+ unsigned int horizontalDpi = 0u;
+ unsigned int verticalDpi = 0u;
+ Dali::TextAbstraction::FontClient fontClient = Dali::TextAbstraction::FontClient::Get();
+ fontClient.GetDpi(horizontalDpi, verticalDpi);
+ return static_cast<float>(horizontalDpi);
+}
-ControllerPtr Controller::New()
+float ConvertPixelToPoint(float pixel)
{
- return ControllerPtr(new Controller());
+ return pixel * 72.0f / GetDpi();
}
-ControllerPtr Controller::New(ControlInterface* controlInterface)
+float ConvertPointToPixel(float point)
{
- return ControllerPtr(new Controller(controlInterface));
+ // Pixel size = Point size * DPI / 72.f
+ return point * GetDpi() / 72.0f;
}
-ControllerPtr Controller::New(ControlInterface* controlInterface,
- EditableControlInterface* editableControlInterface,
- SelectableControlInterface* selectableControlInterface,
- AnchorControlInterface* anchorControlInterface)
+void UpdateCursorPosition(Dali::Toolkit::Text::EventData* eventData)
{
- return ControllerPtr(new Controller(controlInterface,
- editableControlInterface,
- selectableControlInterface,
- anchorControlInterface));
+ if(eventData && Dali::Toolkit::Text::EventData::IsEditingState(eventData->mState))
+ {
+ // Update the cursor position if it's in editing mode
+ eventData->mDecoratorUpdated = true;
+ eventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
+ }
}
-// public : Configure the text controller.
+} // namespace
+
+namespace Dali::Toolkit::Text
+{
void Controller::EnableTextInput(DecoratorPtr decorator, InputMethodContext& inputMethodContext)
{
return;
}
- if(NULL == mImpl->mEventData)
- {
- mImpl->mEventData = new EventData(decorator, inputMethodContext);
- }
+ EnsureCreated(mImpl->mEventData, decorator, inputMethodContext);
}
void Controller::SetGlyphType(TextAbstraction::GlyphType glyphType)
if(mImpl->mLayoutEngine.GetLayout() == Layout::Engine::SINGLE_LINE_BOX)
{
+ mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
+ LAYOUT |
+ ALIGN |
+ UPDATE_LAYOUT_SIZE |
+ REORDER);
+
if(enable)
{
DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled for SINGLE_LINE_BOX\n");
- mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
- LAYOUT |
- ALIGN |
- UPDATE_LAYOUT_SIZE |
- UPDATE_DIRECTION |
- REORDER);
+ mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | UPDATE_DIRECTION);
}
else
{
DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled Disabling autoscroll\n");
- mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
- LAYOUT |
- ALIGN |
- UPDATE_LAYOUT_SIZE |
- REORDER);
}
mImpl->mIsAutoScrollEnabled = enable;
float Controller::GetAutoScrollLineAlignment() const
{
float offset = 0.f;
-
- if(mImpl->mModel->mVisualModel &&
- (0u != mImpl->mModel->mVisualModel->mLines.Count()))
+ if(mImpl->mModel->mVisualModel && (0u != mImpl->mModel->mVisualModel->mLines.Count()))
{
offset = (*mImpl->mModel->mVisualModel->mLines.Begin()).alignmentOffset;
}
-
return offset;
}
void Controller::SetHorizontalScrollEnabled(bool enable)
{
- if((NULL != mImpl->mEventData) &&
- mImpl->mEventData->mDecorator)
+ if(mImpl->mEventData && mImpl->mEventData->mDecorator)
{
mImpl->mEventData->mDecorator->SetHorizontalScrollEnabled(enable);
}
}
+
bool Controller::IsHorizontalScrollEnabled() const
{
- if((NULL != mImpl->mEventData) &&
- mImpl->mEventData->mDecorator)
- {
- return mImpl->mEventData->mDecorator->IsHorizontalScrollEnabled();
- }
-
- return false;
+ return mImpl->mEventData && mImpl->mEventData->mDecorator && mImpl->mEventData->mDecorator->IsHorizontalScrollEnabled();
}
void Controller::SetVerticalScrollEnabled(bool enable)
{
- if((NULL != mImpl->mEventData) &&
- mImpl->mEventData->mDecorator)
+ if(mImpl->mEventData && mImpl->mEventData->mDecorator)
{
- if(mImpl->mEventData->mDecorator)
- {
- mImpl->mEventData->mDecorator->SetVerticalScrollEnabled(enable);
- }
+ mImpl->mEventData->mDecorator->SetVerticalScrollEnabled(enable);
}
}
bool Controller::IsVerticalScrollEnabled() const
{
- if((NULL != mImpl->mEventData) &&
- mImpl->mEventData->mDecorator)
- {
- return mImpl->mEventData->mDecorator->IsVerticalScrollEnabled();
- }
-
- return false;
+ return mImpl->mEventData && mImpl->mEventData->mDecorator && mImpl->mEventData->mDecorator->IsVerticalScrollEnabled();
}
void Controller::SetSmoothHandlePanEnabled(bool enable)
{
- if((NULL != mImpl->mEventData) &&
- mImpl->mEventData->mDecorator)
+ if(mImpl->mEventData && mImpl->mEventData->mDecorator)
{
mImpl->mEventData->mDecorator->SetSmoothHandlePanEnabled(enable);
}
bool Controller::IsSmoothHandlePanEnabled() const
{
- if((NULL != mImpl->mEventData) &&
- mImpl->mEventData->mDecorator)
- {
- return mImpl->mEventData->mDecorator->IsSmoothHandlePanEnabled();
- }
-
- return false;
+ return mImpl->mEventData && mImpl->mEventData->mDecorator && mImpl->mEventData->mDecorator->IsSmoothHandlePanEnabled();
}
void Controller::SetMaximumNumberOfCharacters(Length maxCharacters)
{
DALI_ASSERT_DEBUG(NULL != mImpl->mEventData && "TextInput disabled");
- if(NULL != mImpl->mEventData)
+ if(mImpl->mEventData)
{
mImpl->mEventData->mCursorBlinkEnabled = enable;
- if(!enable &&
- mImpl->mEventData->mDecorator)
+ if(!enable && mImpl->mEventData->mDecorator)
{
mImpl->mEventData->mDecorator->StopCursorBlink();
}
bool Controller::GetEnableCursorBlink() const
{
- if(NULL != mImpl->mEventData)
- {
- return mImpl->mEventData->mCursorBlinkEnabled;
- }
-
- return false;
+ return mImpl->mEventData && mImpl->mEventData->mCursorBlinkEnabled;
}
void Controller::SetMultiLineEnabled(bool enable)
{
// Set the alignment.
mImpl->mModel->mVerticalAlignment = alignment;
-
mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | ALIGN);
-
mImpl->RequestRelayout();
}
}
void Controller::SetTextFitMinSize(float minSize, FontSizeType type)
{
- switch(type)
- {
- case POINT_SIZE:
- {
- mImpl->mTextFitMinSize = minSize;
- break;
- }
- case PIXEL_SIZE:
- {
- mImpl->mTextFitMinSize = ConvertPixelToPint(minSize);
- break;
- }
- }
+ mImpl->mTextFitMinSize = (type == POINT_SIZE) ? minSize : ConvertPixelToPoint(minSize);
}
float Controller::GetTextFitMinSize() const
void Controller::SetTextFitMaxSize(float maxSize, FontSizeType type)
{
- switch(type)
- {
- case POINT_SIZE:
- {
- mImpl->mTextFitMaxSize = maxSize;
- break;
- }
- case PIXEL_SIZE:
- {
- mImpl->mTextFitMaxSize = ConvertPixelToPint(maxSize);
- break;
- }
- }
+ mImpl->mTextFitMaxSize = (type == POINT_SIZE) ? maxSize : ConvertPixelToPoint(maxSize);
}
float Controller::GetTextFitMaxSize() const
void Controller::SetTextFitStepSize(float step, FontSizeType type)
{
- switch(type)
- {
- case POINT_SIZE:
- {
- mImpl->mTextFitStepSize = step;
- break;
- }
- case PIXEL_SIZE:
- {
- mImpl->mTextFitStepSize = ConvertPixelToPint(step);
- break;
- }
- }
+ mImpl->mTextFitStepSize = (type == POINT_SIZE) ? step : ConvertPixelToPoint(step);
}
float Controller::GetTextFitStepSize() const
return mImpl->mEventData->mGrabHandlePopupEnabled;
}
-// public : Update
-
void Controller::SetText(const std::string& text)
{
TextUpdater::SetText(*this, text);
mImpl->SendSelectionToClipboard(deleteAfterSending);
}
-// public : Default style & Input style
-
void Controller::SetDefaultFontFamily(const std::string& defaultFontFamily)
{
- if(NULL == mImpl->mFontDefaults)
- {
- mImpl->mFontDefaults = new FontDefaults();
- }
+ EnsureCreated(mImpl->mFontDefaults);
mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily;
DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str());
mImpl->mFontDefaults->familyDefined = !defaultFontFamily.empty();
- if(mImpl->mEventData)
- {
- // Update the cursor position if it's in editing mode
- if(EventData::IsEditingState(mImpl->mEventData->mState))
- {
- mImpl->mEventData->mDecoratorUpdated = true;
- mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font family is updated.
- }
- }
+ // Update the cursor position if it's in editing mode
+ UpdateCursorPosition(mImpl->mEventData);
// Clear the font-specific data
ClearFontData();
const std::string& Controller::GetDefaultFontFamily() const
{
- if(NULL != mImpl->mFontDefaults)
- {
- return mImpl->mFontDefaults->mFontDescription.family;
- }
-
- return EMPTY_STRING;
+ return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.family : EMPTY_STRING;
}
void Controller::SetPlaceholderFontFamily(const std::string& placeholderTextFontFamily)
void Controller::SetDefaultFontWeight(FontWeight weight)
{
- if(NULL == mImpl->mFontDefaults)
- {
- mImpl->mFontDefaults = new FontDefaults();
- }
+ EnsureCreated(mImpl->mFontDefaults);
mImpl->mFontDefaults->mFontDescription.weight = weight;
mImpl->mFontDefaults->weightDefined = true;
- if(mImpl->mEventData)
- {
- // Update the cursor position if it's in editing mode
- if(EventData::IsEditingState(mImpl->mEventData->mState))
- {
- mImpl->mEventData->mDecoratorUpdated = true;
- mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font weight is updated.
- }
- }
+ // Update the cursor position if it's in editing mode
+ UpdateCursorPosition(mImpl->mEventData);
// Clear the font-specific data
ClearFontData();
bool Controller::IsDefaultFontWeightDefined() const
{
- if(NULL != mImpl->mFontDefaults)
- {
- return mImpl->mFontDefaults->weightDefined;
- }
-
- return false;
+ return mImpl->mFontDefaults && mImpl->mFontDefaults->weightDefined;
}
FontWeight Controller::GetDefaultFontWeight() const
{
- if(NULL != mImpl->mFontDefaults)
- {
- return mImpl->mFontDefaults->mFontDescription.weight;
- }
-
- return TextAbstraction::FontWeight::NORMAL;
+ return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.weight : TextAbstraction::FontWeight::NORMAL;
}
void Controller::SetPlaceholderTextFontWeight(FontWeight weight)
bool Controller::IsPlaceholderTextFontWeightDefined() const
{
return PlaceholderHandler::IsPlaceholderTextFontWeightDefined(*this);
- ;
}
FontWeight Controller::GetPlaceholderTextFontWeight() const
void Controller::SetDefaultFontWidth(FontWidth width)
{
- if(NULL == mImpl->mFontDefaults)
- {
- mImpl->mFontDefaults = new FontDefaults();
- }
+ EnsureCreated(mImpl->mFontDefaults);
mImpl->mFontDefaults->mFontDescription.width = width;
mImpl->mFontDefaults->widthDefined = true;
- if(mImpl->mEventData)
- {
- // Update the cursor position if it's in editing mode
- if(EventData::IsEditingState(mImpl->mEventData->mState))
- {
- mImpl->mEventData->mDecoratorUpdated = true;
- mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font width is updated.
- }
- }
+ // Update the cursor position if it's in editing mode
+ UpdateCursorPosition(mImpl->mEventData);
// Clear the font-specific data
ClearFontData();
bool Controller::IsDefaultFontWidthDefined() const
{
- if(NULL != mImpl->mFontDefaults)
- {
- return mImpl->mFontDefaults->widthDefined;
- }
-
- return false;
+ return mImpl->mFontDefaults && mImpl->mFontDefaults->widthDefined;
}
FontWidth Controller::GetDefaultFontWidth() const
{
- if(NULL != mImpl->mFontDefaults)
- {
- return mImpl->mFontDefaults->mFontDescription.width;
- }
-
- return TextAbstraction::FontWidth::NORMAL;
+ return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.width : TextAbstraction::FontWidth::NORMAL;
}
void Controller::SetPlaceholderTextFontWidth(FontWidth width)
void Controller::SetDefaultFontSlant(FontSlant slant)
{
- if(NULL == mImpl->mFontDefaults)
- {
- mImpl->mFontDefaults = new FontDefaults();
- }
+ EnsureCreated(mImpl->mFontDefaults);
mImpl->mFontDefaults->mFontDescription.slant = slant;
mImpl->mFontDefaults->slantDefined = true;
- if(mImpl->mEventData)
- {
- // Update the cursor position if it's in editing mode
- if(EventData::IsEditingState(mImpl->mEventData->mState))
- {
- mImpl->mEventData->mDecoratorUpdated = true;
- mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font slant is updated.
- }
- }
+ // Update the cursor position if it's in editing mode
+ UpdateCursorPosition(mImpl->mEventData);
// Clear the font-specific data
ClearFontData();
bool Controller::IsDefaultFontSlantDefined() const
{
- if(NULL != mImpl->mFontDefaults)
- {
- return mImpl->mFontDefaults->slantDefined;
- }
- return false;
+ return mImpl->mFontDefaults && mImpl->mFontDefaults->slantDefined;
}
FontSlant Controller::GetDefaultFontSlant() const
{
- if(NULL != mImpl->mFontDefaults)
- {
- return mImpl->mFontDefaults->mFontDescription.slant;
- }
-
- return TextAbstraction::FontSlant::NORMAL;
+ return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.slant : TextAbstraction::FontSlant::NORMAL;
}
void Controller::SetPlaceholderTextFontSlant(FontSlant slant)
{
mImpl->mFontSizeScale = scale;
- if(mImpl->mEventData)
- {
- // Update the cursor position if it's in editing mode
- if(EventData::IsEditingState(mImpl->mEventData->mState))
- {
- mImpl->mEventData->mDecoratorUpdated = true;
- mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
- }
- }
+ // Update the cursor position if it's in editing mode
+ UpdateCursorPosition(mImpl->mEventData);
// Clear the font-specific data
ClearFontData();
float Controller::GetFontSizeScale() const
{
- if(nullptr != mImpl->mFontDefaults)
- {
- return mImpl->mFontSizeScale;
- }
-
- return 1.f;
+ return mImpl->mFontDefaults ? mImpl->mFontSizeScale : 1.0f;
}
void Controller::SetDefaultFontSize(float fontSize, FontSizeType type)
{
- if(NULL == mImpl->mFontDefaults)
- {
- mImpl->mFontDefaults = new FontDefaults();
- }
+ EnsureCreated(mImpl->mFontDefaults);
- switch(type)
- {
- case POINT_SIZE:
- {
- mImpl->mFontDefaults->mDefaultPointSize = fontSize;
- mImpl->mFontDefaults->sizeDefined = true;
- break;
- }
- case PIXEL_SIZE:
- {
- // Point size = Pixel size * 72.f / DPI
- unsigned int horizontalDpi = 0u;
- unsigned int verticalDpi = 0u;
- TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
- fontClient.GetDpi(horizontalDpi, verticalDpi);
-
- mImpl->mFontDefaults->mDefaultPointSize = (fontSize * 72.f) / static_cast<float>(horizontalDpi);
- mImpl->mFontDefaults->sizeDefined = true;
- break;
- }
- }
+ mImpl->mFontDefaults->mDefaultPointSize = (type == POINT_SIZE) ? fontSize : ConvertPixelToPoint(fontSize);
+ mImpl->mFontDefaults->sizeDefined = true;
- if(mImpl->mEventData)
- {
- // Update the cursor position if it's in editing mode
- if(EventData::IsEditingState(mImpl->mEventData->mState))
- {
- mImpl->mEventData->mDecoratorUpdated = true;
- mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
- }
- }
+ // Update the cursor position if it's in editing mode
+ UpdateCursorPosition(mImpl->mEventData);
// Clear the font-specific data
ClearFontData();
float Controller::GetDefaultFontSize(FontSizeType type) const
{
- float value = 0.0f;
- if(NULL != mImpl->mFontDefaults)
+ if(mImpl->mFontDefaults)
{
- switch(type)
- {
- case POINT_SIZE:
- {
- value = mImpl->mFontDefaults->mDefaultPointSize;
- break;
- }
- case PIXEL_SIZE:
- {
- // Pixel size = Point size * DPI / 72.f
- unsigned int horizontalDpi = 0u;
- unsigned int verticalDpi = 0u;
- TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
- fontClient.GetDpi(horizontalDpi, verticalDpi);
-
- value = mImpl->mFontDefaults->mDefaultPointSize * static_cast<float>(horizontalDpi) / 72.f;
- break;
- }
- }
- return value;
+ return (type == POINT_SIZE) ? mImpl->mFontDefaults->mDefaultPointSize : ConvertPointToPixel(mImpl->mFontDefaults->mDefaultPointSize);
}
-
- return value;
+ return 0.0f;
}
void Controller::SetPlaceholderTextFontSize(float fontSize, FontSizeType type)
if(!mImpl->IsShowingPlaceholderText())
{
mImpl->mModel->mVisualModel->SetTextColor(color);
-
mImpl->mModel->mLogicalModel->mColorRuns.Clear();
-
mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | COLOR);
-
mImpl->RequestRelayout();
}
}
void Controller::SetShadowOffset(const Vector2& shadowOffset)
{
mImpl->mModel->mVisualModel->SetShadowOffset(shadowOffset);
-
mImpl->RequestRelayout();
}
void Controller::SetShadowColor(const Vector4& shadowColor)
{
mImpl->mModel->mVisualModel->SetShadowColor(shadowColor);
-
mImpl->RequestRelayout();
}
if(fabsf(GetShadowBlurRadius() - shadowBlurRadius) > Math::MACHINE_EPSILON_1)
{
mImpl->mModel->mVisualModel->SetShadowBlurRadius(shadowBlurRadius);
-
mImpl->RequestRelayout();
}
}
void Controller::SetUnderlineColor(const Vector4& color)
{
mImpl->mModel->mVisualModel->SetUnderlineColor(color);
-
mImpl->RequestRelayout();
}
void Controller::SetUnderlineEnabled(bool enabled)
{
mImpl->mModel->mVisualModel->SetUnderlineEnabled(enabled);
-
mImpl->RequestRelayout();
}
void Controller::SetUnderlineHeight(float height)
{
mImpl->mModel->mVisualModel->SetUnderlineHeight(height);
-
mImpl->RequestRelayout();
}
void Controller::SetOutlineColor(const Vector4& color)
{
mImpl->mModel->mVisualModel->SetOutlineColor(color);
-
mImpl->RequestRelayout();
}
void Controller::SetOutlineWidth(uint16_t width)
{
mImpl->mModel->mVisualModel->SetOutlineWidth(width);
-
mImpl->RequestRelayout();
}
void Controller::SetBackgroundColor(const Vector4& color)
{
mImpl->mModel->mVisualModel->SetBackgroundColor(color);
-
mImpl->RequestRelayout();
}
void Controller::SetBackgroundEnabled(bool enabled)
{
mImpl->mModel->mVisualModel->SetBackgroundEnabled(enabled);
-
mImpl->RequestRelayout();
}
void Controller::SetDefaultEmbossProperties(const std::string& embossProperties)
{
- if(NULL == mImpl->mEmbossDefaults)
- {
- mImpl->mEmbossDefaults = new EmbossDefaults();
- }
-
+ EnsureCreated(mImpl->mEmbossDefaults);
mImpl->mEmbossDefaults->properties = embossProperties;
}
const std::string& Controller::GetDefaultEmbossProperties() const
{
- if(NULL != mImpl->mEmbossDefaults)
- {
- return mImpl->mEmbossDefaults->properties;
- }
-
- return EMPTY_STRING;
+ return mImpl->mEmbossDefaults ? mImpl->mEmbossDefaults->properties : EMPTY_STRING;
}
void Controller::SetDefaultOutlineProperties(const std::string& outlineProperties)
{
- if(NULL == mImpl->mOutlineDefaults)
- {
- mImpl->mOutlineDefaults = new OutlineDefaults();
- }
-
+ EnsureCreated(mImpl->mOutlineDefaults);
mImpl->mOutlineDefaults->properties = outlineProperties;
}
const std::string& Controller::GetDefaultOutlineProperties() const
{
- if(NULL != mImpl->mOutlineDefaults)
- {
- return mImpl->mOutlineDefaults->properties;
- }
-
- return EMPTY_STRING;
+ return mImpl->mOutlineDefaults ? mImpl->mOutlineDefaults->properties : EMPTY_STRING;
}
void Controller::RelayoutForNewLineSize()
mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | LAYOUT);
//remove selection
- if((mImpl->mEventData != nullptr) && (mImpl->mEventData->mState == EventData::SELECTING))
+ if(mImpl->mEventData && mImpl->mEventData->mState == EventData::SELECTING)
{
mImpl->ChangeState(EventData::EDITING);
}
void Controller::SetInputColor(const Vector4& color)
{
- if(NULL != mImpl->mEventData)
+ if(mImpl->mEventData)
{
mImpl->mEventData->mInputStyle.textColor = color;
mImpl->mEventData->mInputStyle.isDefaultColor = false;
const Vector4& Controller::GetInputColor() const
{
- if(NULL != mImpl->mEventData)
- {
- return mImpl->mEventData->mInputStyle.textColor;
- }
-
- // Return the default text's color if there is no EventData.
- return mImpl->mTextColor;
+ // Return event text input color if we have it, otherwise just return the default text's color
+ return mImpl->mEventData ? mImpl->mEventData->mInputStyle.textColor : mImpl->mTextColor;
}
void Controller::SetInputFontFamily(const std::string& fontFamily)
void Controller::SetInputLineSpacing(float lineSpacing)
{
- if(NULL != mImpl->mEventData)
+ if(mImpl->mEventData)
{
mImpl->mEventData->mInputStyle.lineSpacing = lineSpacing;
mImpl->mEventData->mInputStyle.isLineSpacingDefined = true;
float Controller::GetInputLineSpacing() const
{
- if(NULL != mImpl->mEventData)
- {
- return mImpl->mEventData->mInputStyle.lineSpacing;
- }
-
- return 0.f;
+ return mImpl->mEventData ? mImpl->mEventData->mInputStyle.lineSpacing : 0.0f;
}
void Controller::SetInputShadowProperties(const std::string& shadowProperties)
{
- if(NULL != mImpl->mEventData)
+ if(mImpl->mEventData)
{
mImpl->mEventData->mInputStyle.shadowProperties = shadowProperties;
}
const std::string& Controller::GetInputShadowProperties() const
{
- if(NULL != mImpl->mEventData)
- {
- return mImpl->mEventData->mInputStyle.shadowProperties;
- }
-
- return EMPTY_STRING;
+ return mImpl->mEventData ? mImpl->mEventData->mInputStyle.shadowProperties : EMPTY_STRING;
}
void Controller::SetInputUnderlineProperties(const std::string& underlineProperties)
{
- if(NULL != mImpl->mEventData)
+ if(mImpl->mEventData)
{
mImpl->mEventData->mInputStyle.underlineProperties = underlineProperties;
}
const std::string& Controller::GetInputUnderlineProperties() const
{
- if(NULL != mImpl->mEventData)
- {
- return mImpl->mEventData->mInputStyle.underlineProperties;
- }
-
- return EMPTY_STRING;
+ return mImpl->mEventData ? mImpl->mEventData->mInputStyle.underlineProperties : EMPTY_STRING;
}
void Controller::SetInputEmbossProperties(const std::string& embossProperties)
{
- if(NULL != mImpl->mEventData)
+ if(mImpl->mEventData)
{
mImpl->mEventData->mInputStyle.embossProperties = embossProperties;
}
const std::string& Controller::GetInputEmbossProperties() const
{
- if(NULL != mImpl->mEventData)
- {
- return mImpl->mEventData->mInputStyle.embossProperties;
- }
-
- return GetDefaultEmbossProperties();
+ return mImpl->mEventData ? mImpl->mEventData->mInputStyle.embossProperties : GetDefaultEmbossProperties();
}
void Controller::SetInputOutlineProperties(const std::string& outlineProperties)
{
- if(NULL != mImpl->mEventData)
+ if(mImpl->mEventData)
{
mImpl->mEventData->mInputStyle.outlineProperties = outlineProperties;
}
const std::string& Controller::GetInputOutlineProperties() const
{
- if(NULL != mImpl->mEventData)
- {
- return mImpl->mEventData->mInputStyle.outlineProperties;
- }
-
- return GetDefaultOutlineProperties();
+ return mImpl->mEventData ? mImpl->mEventData->mInputStyle.outlineProperties : GetDefaultOutlineProperties();
}
void Controller::SetInputModePassword(bool passwordInput)
{
- if(NULL != mImpl->mEventData)
+ if(mImpl->mEventData)
{
mImpl->mEventData->mPasswordInput = passwordInput;
}
bool Controller::IsInputModePassword()
{
- if(NULL != mImpl->mEventData)
- {
- return mImpl->mEventData->mPasswordInput;
- }
- return false;
+ return mImpl->mEventData && mImpl->mEventData->mPasswordInput;
}
void Controller::SetNoTextDoubleTapAction(NoTextTap::Action action)
{
- if(NULL != mImpl->mEventData)
+ if(mImpl->mEventData)
{
mImpl->mEventData->mDoubleTapAction = action;
}
Controller::NoTextTap::Action Controller::GetNoTextDoubleTapAction() const
{
- NoTextTap::Action action = NoTextTap::NO_ACTION;
-
- if(NULL != mImpl->mEventData)
- {
- action = mImpl->mEventData->mDoubleTapAction;
- }
-
- return action;
+ return mImpl->mEventData ? mImpl->mEventData->mDoubleTapAction : NoTextTap::NO_ACTION;
}
void Controller::SetNoTextLongPressAction(NoTextTap::Action action)
{
- if(NULL != mImpl->mEventData)
+ if(mImpl->mEventData)
{
mImpl->mEventData->mLongPressAction = action;
}
Controller::NoTextTap::Action Controller::GetNoTextLongPressAction() const
{
- NoTextTap::Action action = NoTextTap::NO_ACTION;
-
- if(NULL != mImpl->mEventData)
- {
- action = mImpl->mEventData->mLongPressAction;
- }
-
- return action;
+ return mImpl->mEventData ? mImpl->mEventData->mLongPressAction : NoTextTap::NO_ACTION;
}
bool Controller::IsUnderlineSetByString()
mImpl->mFontStyleSetByString = setByString;
}
-// public : Queries & retrieves.
-
Layout::Engine& Controller::GetLayoutEngine()
{
return mImpl->mLayoutEngine;
int Controller::GetLineCount(float width)
{
GetHeightForWidth(width);
- int numberofLines = mImpl->mModel->GetNumberOfLines();
- return numberofLines;
+ return mImpl->mModel->GetNumberOfLines();
}
const ModelInterface* const Controller::GetTextModel() const
void Controller::SetHiddenInputOption(const Property::Map& options)
{
- if(NULL == mImpl->mHiddenInput)
- {
- mImpl->mHiddenInput = new HiddenText(this);
- }
+ EnsureCreated<HiddenText, Controller*>(mImpl->mHiddenInput, this);
mImpl->mHiddenInput->SetProperties(options);
}
void Controller::GetHiddenInputOption(Property::Map& options)
{
- if(NULL != mImpl->mHiddenInput)
+ if(mImpl->mHiddenInput)
{
mImpl->mHiddenInput->GetProperties(options);
}
void Controller::SetInputFilterOption(const Property::Map& options)
{
- if(!mImpl->mInputFilter)
- {
- mImpl->mInputFilter = std::unique_ptr<InputFilter>(new InputFilter());
- }
+ EnsureCreated(mImpl->mInputFilter);
mImpl->mInputFilter->SetProperties(options);
}
void Controller::GetInputFilterOption(Property::Map& options)
{
- if(NULL != mImpl->mInputFilter)
+ if(mImpl->mInputFilter)
{
mImpl->mInputFilter->GetProperties(options);
}
mImpl->mModel->mVisualModel->SetEllipsisPosition(ellipsisPosition);
}
-// public : Relayout.
-
Controller::UpdateTextType Controller::Relayout(const Size& size, Dali::LayoutDirection::Type layoutDirection)
{
return Relayouter::Relayout(*this, size, layoutDirection);
mImpl->RequestRelayout();
}
-// public : Input style change signals.
-
bool Controller::IsInputStyleChangedSignalsQueueEmpty()
{
return (NULL == mImpl->mEventData) || (0u == mImpl->mEventData->mInputStyleChangedQueue.Count());
void Controller::ProcessInputStyleChangedSignals()
{
- if(NULL == mImpl->mEventData)
- {
- // Nothing to do.
- return;
- }
-
- for(Vector<InputStyle::Mask>::ConstIterator it = mImpl->mEventData->mInputStyleChangedQueue.Begin(),
- endIt = mImpl->mEventData->mInputStyleChangedQueue.End();
- it != endIt;
- ++it)
+ if(mImpl->mEventData)
{
- const InputStyle::Mask mask = *it;
-
- if(NULL != mImpl->mEditableControlInterface)
+ if(mImpl->mEditableControlInterface)
{
- // Emit the input style changed signal.
- mImpl->mEditableControlInterface->InputStyleChanged(mask);
+ // Emit the input style changed signal for each mask
+ std::for_each(mImpl->mEventData->mInputStyleChangedQueue.begin(),
+ mImpl->mEventData->mInputStyleChangedQueue.end(),
+ [&](const auto mask) { mImpl->mEditableControlInterface->InputStyleChanged(mask); } );
}
- }
- mImpl->mEventData->mInputStyleChangedQueue.Clear();
+ mImpl->mEventData->mInputStyleChangedQueue.Clear();
+ }
}
-// public : Text-input Event Queuing.
-
void Controller::KeyboardFocusGainEvent()
{
EventHandler::KeyboardFocusGainEvent(*this);
if(!IsEditable())
{
- return "";
+ return EMPTY_STRING;
}
mImpl->SendSelectionToClipboard(true); // Synchronous call to modify text
EventHandler::PasteClipboardItemEvent(*this);
}
-// protected : Inherit from Text::Decorator::ControllerInterface.
-
void Controller::GetTargetSize(Vector2& targetSize)
{
targetSize = mImpl->mModel->mVisualModel->mControlSize;
void Controller::AddDecoration(Actor& actor, bool needsClipping)
{
- if(NULL != mImpl->mEditableControlInterface)
+ if(mImpl->mEditableControlInterface)
{
mImpl->mEditableControlInterface->AddDecoration(actor, needsClipping);
}
float Controller::GetHorizontalScrollPosition()
{
- if(mImpl->mEventData)
- {
- //scroll values are negative internally so we convert them to positive numbers
- return -mImpl->mModel->mScrollPosition.x;
- }
- return 0;
+ // Scroll values are negative internally so we convert them to positive numbers
+ return mImpl->mEventData ? -mImpl->mModel->mScrollPosition.x : 0.0f;
}
float Controller::GetVerticalScrollPosition()
{
- if(mImpl->mEventData)
- {
- //scroll values are negative internally so we convert them to positive numbers
- return -mImpl->mModel->mScrollPosition.y;
- }
- return 0;
+ // Scroll values are negative internally so we convert them to positive numbers
+ return mImpl->mEventData ? -mImpl->mModel->mScrollPosition.y : 0.0f;
}
void Controller::DecorationEvent(HandleType handleType, HandleState state, float x, float y)
EventHandler::DecorationEvent(*this, handleType, state, x, y);
}
-// protected : Inherit from TextSelectionPopup::TextPopupButtonCallbackInterface.
-
void Controller::TextPopupButtonTouched(Dali::Toolkit::TextSelectionPopup::Buttons button)
{
EventHandler::TextPopupButtonTouched(*this, button);
mImpl->RequestRelayout();
}
-// private : Update.
-
void Controller::InsertText(const std::string& text, Controller::InsertType type)
{
TextUpdater::InsertText(*this, text, type);
TextUpdater::PasteText(*this, stringToPaste);
}
-bool Controller::RemoveText(int cursorOffset,
- int numberOfCharacters,
- UpdateInputStyleType type)
+bool Controller::RemoveText(int cursorOffset, int numberOfCharacters, UpdateInputStyleType type)
{
return TextUpdater::RemoveText(*this, cursorOffset, numberOfCharacters, type);
}
return TextUpdater::RemoveSelectedText(*this);
}
-void Controller::InsertTextAnchor(int numberOfCharacters,
- CharacterIndex previousCursorIndex)
+void Controller::InsertTextAnchor(int numberOfCharacters, CharacterIndex previousCursorIndex)
{
TextUpdater::InsertTextAnchor(*this, numberOfCharacters, previousCursorIndex);
}
-void Controller::RemoveTextAnchor(int cursorOffset,
- int numberOfCharacters,
- CharacterIndex previousCursorIndex)
+void Controller::RemoveTextAnchor(int cursorOffset, int numberOfCharacters, CharacterIndex previousCursorIndex)
{
TextUpdater::RemoveTextAnchor(*this, cursorOffset, numberOfCharacters, previousCursorIndex);
}
-// private : Relayout.
-
-bool Controller::DoRelayout(const Size& size,
- OperationsMask operationsRequired,
- Size& layoutSize)
+bool Controller::DoRelayout(const Size& size, OperationsMask operationsRequired, Size& layoutSize)
{
return Relayouter::DoRelayout(*this, size, operationsRequired, layoutSize);
}
Relayouter::CalculateVerticalOffset(*this, controlSize);
}
-// private : Events.
-
void Controller::ProcessModifyEvents()
{
EventHandler::ProcessModifyEvents(*this);
void Controller::ResetScrollPosition()
{
- if(NULL != mImpl->mEventData)
+ if(mImpl->mEventData)
{
// Reset the scroll position.
mImpl->mModel->mScrollPosition = Vector2::ZERO;
return mImpl->CreateBackgroundActor();
}
-// private : Private contructors & copy operator.
-
-Controller::Controller()
-: Controller(nullptr, nullptr, nullptr, nullptr)
-{
-}
-
-Controller::Controller(ControlInterface* controlInterface)
-: Controller(controlInterface, nullptr, nullptr, nullptr)
-{
-}
-
Controller::Controller(ControlInterface* controlInterface,
EditableControlInterface* editableControlInterface,
SelectableControlInterface* selectableControlInterface,
{
}
-// The copy constructor and operator are left unimplemented.
-
-// protected : Destructor.
-
Controller::~Controller()
{
delete mImpl;
}
-} // namespace Text
-
-} // namespace Toolkit
-
-} // namespace Dali
+} // namespace Dali::Toolkit::Text
#include <dali-toolkit/internal/text/text-selectable-control-interface.h>
#include <dali-toolkit/public-api/text/text-enumerations.h>
-namespace Dali
-{
-namespace Toolkit
-{
-namespace Text
+namespace Dali::Toolkit::Text
{
class Controller;
class ControlInterface;
*
* @return A pointer to a new Controller.
*/
- static ControllerPtr New();
+ static ControllerPtr New()
+ {
+ return ControllerPtr(new Controller());
+ }
/**
* @brief Create a new instance of a Controller.
*
* @return A pointer to a new Controller.
*/
- static ControllerPtr New(ControlInterface* controlInterface);
+ static ControllerPtr New(ControlInterface* controlInterface)
+ {
+ return ControllerPtr(new Controller(controlInterface));
+ }
/**
* @brief Create a new instance of a Controller.
static ControllerPtr New(ControlInterface* controlInterface,
EditableControlInterface* editableControlInterface,
SelectableControlInterface* selectableControlInterface,
- AnchorControlInterface* anchorControlInterface);
+ AnchorControlInterface* anchorControlInterface)
+ {
+ return ControllerPtr(new Controller(controlInterface,
+ editableControlInterface,
+ selectableControlInterface,
+ anchorControlInterface));
+ }
public: // Configure the text controller.
/**
/**
* @brief Private constructor.
*/
- Controller();
+ Controller()
+ : Controller(nullptr, nullptr, nullptr, nullptr)
+ {
+ }
/**
* @brief Private constructor.
*/
- Controller(ControlInterface* controlInterface);
+ Controller(ControlInterface* controlInterface)
+ : Controller(controlInterface, nullptr, nullptr, nullptr)
+ {
+ }
/**
* @brief Private constructor.
SelectableControlInterface* selectableControlInterface,
AnchorControlInterface* anchorControlInterface);
- // Undefined
- Controller(const Controller& handle);
-
- // Undefined
- Controller& operator=(const Controller& handle);
+ Controller(const Controller& handle) = delete;
+ Controller& operator=(const Controller& handle) = delete;
protected: // Destructor.
/**
Impl* mImpl;
};
-} // namespace Text
-
-} // namespace Toolkit
-
-} // namespace Dali
+} // namespace Dali::Toolkit::Text
#endif // DALI_TOOLKIT_TEXT_CONTROLLER_H
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.
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
namespace
{
const Dali::AlphaFunction DEFAULT_ALPHA_FUNCTION(Dali::AlphaFunction::DEFAULT);
-
} // anonymous namespace
-TransitionPtr Transition::New(Dali::Toolkit::Control source, Dali::Toolkit::Control destination, TimePeriod timePeriod)
+TransitionPtr Transition::New(Dali::Toolkit::Control source, Dali::Toolkit::Control destination, bool useDestinationTarget, TimePeriod timePeriod)
{
float delaySeconds = timePeriod.delaySeconds;
if(delaySeconds < 0.0f)
durationSeconds = 0.0f;
}
- TransitionPtr transition = new Transition(source, destination, TimePeriod(delaySeconds, durationSeconds));
+ TransitionPtr transition = new Transition(source, destination, useDestinationTarget, TimePeriod(delaySeconds, durationSeconds));
// Second-phase construction
transition->Initialize();
return transition;
}
-Transition::Transition(Dali::Toolkit::Control source, Dali::Toolkit::Control destination, TimePeriod timePeriod)
+Transition::Transition(Dali::Toolkit::Control source, Dali::Toolkit::Control destination, bool useDestinationTarget, TimePeriod timePeriod)
: TransitionBase(),
+ mUseDestinationTarget(useDestinationTarget),
+ mOriginalSize(),
mSourceControl(source),
mDestinationControl(destination)
{
- SetTarget(destination);
+ SetTarget(mUseDestinationTarget ? destination : source);
SetTimePeriod(timePeriod);
SetPairTransition(true);
}
}
//Make startPropertyMap and finishPropertyMap to use for property animation.
- Matrix sourceWorldTransform = sourceControl[Dali::Actor::Property::WORLD_MATRIX];
+ Matrix sourceWorldTransform = GetWorldTransform(sourceControl);
Vector3 sourcePosition, sourceScale;
Quaternion sourceOrientation;
sourceWorldTransform.GetTransformComponents(sourcePosition, sourceOrientation, sourceScale);
- Vector3 destinationPosition = destinationControl[Dali::Actor::Property::POSITION];
- Vector3 destinationScale = destinationControl[Dali::Actor::Property::SCALE];
- Quaternion destinationOrientation = destinationControl[Dali::Actor::Property::ORIENTATION];
- Vector4 targetColor = destinationControl[Dali::Actor::Property::COLOR];
- Vector3 targetSize = destinationControl[Dali::Actor::Property::SIZE];
+ Matrix destinationWorldTransform = GetWorldTransform(destinationControl);
+ Vector3 destinationPosition, destinationScale;
+ Quaternion destinationOrientation;
+ destinationWorldTransform.GetTransformComponents(destinationPosition, destinationOrientation, destinationScale);
Property::Map startPropertyMap;
Property::Map finishPropertyMap;
startPropertyMap.Insert(Dali::Actor::Property::SCALE, sourceScale);
finishPropertyMap.Insert(Dali::Actor::Property::SCALE, destinationScale);
- Vector4 sourceColor = sourceControl.GetCurrentProperty<Vector4>(Dali::Actor::Property::WORLD_COLOR);
+ Vector4 sourceColor = GetWorldColor(sourceControl);
+ Vector4 destinationColor = GetWorldColor(destinationControl);
startPropertyMap.Insert(Dali::Actor::Property::COLOR, sourceColor);
- finishPropertyMap.Insert(Dali::Actor::Property::COLOR, targetColor);
+ finishPropertyMap.Insert(Dali::Actor::Property::COLOR, destinationColor);
// Set animation for other properties if source and destination is different.
- Vector3 sourceSize = sourceControl.GetCurrentProperty<Vector3>(Dali::Actor::Property::SIZE);
- if(sourceSize != targetSize)
+ Vector3 sourceSize = sourceControl[Dali::Actor::Property::SIZE];
+ Vector3 destinationSize = destinationControl[Dali::Actor::Property::SIZE];
+ if(sourceSize != destinationSize)
{
startPropertyMap.Insert(Dali::Actor::Property::SIZE, sourceSize);
- finishPropertyMap.Insert(Dali::Actor::Property::SIZE, targetSize);
+ finishPropertyMap.Insert(Dali::Actor::Property::SIZE, destinationSize);
+ if(!mUseDestinationTarget)
+ {
+ mOriginalSize = GetTargetControl().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
+ }
}
SetStartPropertyMap(startPropertyMap);
SetFinishPropertyMap(finishPropertyMap);
// source View becomes transparent during transition.
+ Dali::Toolkit::Control waitingControl = GetWaitingControl();
if(IsTransitionWithChild())
{
- sourceControl[Dali::Actor::Property::VISIBLE] = false;
+ waitingControl[Dali::Actor::Property::VISIBLE] = false;
}
else
{
- GetImplementation(sourceControl).SetTransparent(true);
+ GetImplementation(waitingControl).SetTransparent(true);
}
Dali::Animation animation = GetAnimation();
DALI_LOG_ERROR("animation is still not initialized\n");
return;
}
- Dali::Toolkit::DevelControl::CreateTransitions(destinationControl, animation, sourceControl, GetAlphaFunction(), GetTimePeriod());
+
+ mOriginalVisualProperties.clear();
+ std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>> destinationVisualProperties;
+ Dali::Toolkit::Control targetControl = GetTargetControl();
+ Internal::Control& internalControl = Toolkit::Internal::GetImplementation(targetControl);
+ Internal::Control::Impl& controlDataImpl = Toolkit::Internal::Control::Impl::Get(internalControl);
+ controlDataImpl.CreateTransitions(mOriginalVisualProperties, destinationVisualProperties, sourceControl, destinationControl);
+
+ for(uint32_t index = 0; index < mOriginalVisualProperties.size(); ++index)
+ {
+ Dali::Property::Map source = mOriginalVisualProperties[index].second;
+ Dali::Property::Map destination = destinationVisualProperties[index].second;
+ for(size_t i = 0; i < source.Count(); ++i)
+ {
+ Dali::Property property = DevelControl::GetVisualProperty(targetControl, mOriginalVisualProperties[index].first, source.GetKeyAt(i));
+ if(GetTimePeriod().delaySeconds > 0.0f)
+ {
+ Dali::KeyFrames initialKeyframes = Dali::KeyFrames::New();
+ initialKeyframes.Add(0.0f, source.GetValue(i));
+ animation.AnimateBetween(property, initialKeyframes, TimePeriod(GetTimePeriod().delaySeconds));
+ }
+ Dali::KeyFrames keyframes = Dali::KeyFrames::New();
+ keyframes.Add(0.0f, source.GetValue(i));
+ keyframes.Add(1.0f, destination.GetValue(i));
+ animation.AnimateBetween(property, keyframes, GetAlphaFunction(), GetTimePeriod());
+ }
+ }
}
void Transition::OnFinished()
{
- Dali::Toolkit::Control sourceControl = mSourceControl.GetHandle();
- if(!sourceControl)
+ Dali::Toolkit::Control waitingControl = GetWaitingControl();
+ if(!waitingControl)
{
return;
}
+ if(!mUseDestinationTarget)
+ {
+ Dali::Toolkit::Control target = GetTargetControl();
+ Dali::Animation resetAnimation = Dali::Animation::New(0.0f);
+ if(mOriginalSize != target.GetProperty<Vector3>(Dali::Actor::Property::SIZE))
+ {
+ // Use Animation not to notify size change and not to change width and height resize policy.
+ resetAnimation.AnimateTo(Dali::Property(target, Dali::Actor::Property::SIZE), mOriginalSize);
+ }
+ resetAnimation.Play();
+
+ Dali::Toolkit::Control targetControl = GetTargetControl();
+ Internal::Control& internalControl = Toolkit::Internal::GetImplementation(targetControl);
+ Internal::Control::Impl& controlDataImpl = Toolkit::Internal::Control::Impl::Get(internalControl);
+ controlDataImpl.UpdateVisualProperties(mOriginalVisualProperties);
+ }
+
if(IsTransitionWithChild())
{
- sourceControl[Dali::Actor::Property::VISIBLE] = true;
+ waitingControl[Dali::Actor::Property::VISIBLE] = true;
}
else
{
- GetImplementation(sourceControl).SetTransparent(false);
+ GetImplementation(waitingControl).SetTransparent(false);
}
}
+Dali::Toolkit::Control Transition::GetTargetControl()
+{
+ Dali::Toolkit::Control target = mUseDestinationTarget ? mDestinationControl.GetHandle() : mSourceControl.GetHandle();
+ return target;
+}
+
+Dali::Toolkit::Control Transition::GetWaitingControl()
+{
+ Dali::Toolkit::Control waitingControl = mUseDestinationTarget ? mSourceControl.GetHandle() : mDestinationControl.GetHandle();
+ return waitingControl;
+}
+
} // namespace Internal
} // namespace Toolkit
* @brief Create a new Transition object.
* @param[in] source A source control of this transition.
* @param[in] destination A destination control of this transition.
+ * @param[in] useDestinationTarget True if this transition uses destination control as target.
* @param[in] timePeriod The timePeriod of the animation.
* @return A smart-pointer to the newly allocated Transition.
*/
- static TransitionPtr New(Dali::Toolkit::Control source, Dali::Toolkit::Control destination, TimePeriod timePeriod);
+ static TransitionPtr New(Dali::Toolkit::Control source, Dali::Toolkit::Control destination, bool useDestinationTarget, TimePeriod timePeriod);
protected:
/**
*/
Transition(Dali::Toolkit::Control source,
Dali::Toolkit::Control destination,
+ bool useDestinationTarget,
TimePeriod timePeriod);
/**
Transition& operator=(const Transition& rhs);
private:
- WeakHandle<Dali::Toolkit::Control> mSourceControl;
- WeakHandle<Dali::Toolkit::Control> mDestinationControl;
+ Dali::Toolkit::Control GetTargetControl();
+ Dali::Toolkit::Control GetWaitingControl();
+
+private:
+ bool mUseDestinationTarget;
+ Vector3 mOriginalSize;
+ std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>> mOriginalVisualProperties;
+ WeakHandle<Dali::Toolkit::Control> mSourceControl;
+ WeakHandle<Dali::Toolkit::Control> mDestinationControl;
};
} // namespace Internal
// 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);
mUrlIndex(0),
mFrameCount(0),
mImageSize(),
+ mActionStatus(DevelAnimatedImageVisual::Action::PLAY),
mWrapModeU(WrapMode::DEFAULT),
mWrapModeV(WrapMode::DEFAULT),
- mActionStatus(DevelAnimatedImageVisual::Action::PLAY),
mStopBehavior(DevelImageVisual::StopBehavior::CURRENT_FRAME),
mStartFirstFrame(false),
mIsJumpTo(false)
uint32_t mFrameCount; // Number of frames
ImageDimensions mImageSize;
+ DevelAnimatedImageVisual::Action::Type mActionStatus;
+
Dali::WrapMode::Type mWrapModeU : 3;
Dali::WrapMode::Type mWrapModeV : 3;
- DevelAnimatedImageVisual::Action::Type mActionStatus : 3;
DevelImageVisual::StopBehavior::Type mStopBehavior : 2;
bool mStartFirstFrame : 1;
bool mIsJumpTo : 1;
#include <dali/integration-api/debug.h>
// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
#include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-signals-devel.h>
#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
#include <dali-toolkit/internal/visuals/animated-vector-image/vector-animation-manager.h>
}
break;
}
- case DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY:
- {
- const Property::Map* map = attributes.GetMap();
- if(map)
- {
- DoSetProperties(*map);
- }
- break;
- }
}
TriggerVectorRasterization();
#include <dali/integration-api/debug.h>
//INTERNAL INCLUDES
-#include <dali-toolkit/devel-api/visuals/arc-visual-actions-devel.h>
#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
#include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
}
}
-void ArcVisual::OnDoAction(const Property::Index actionId, const Property::Value& attributes)
-{
- // Check if action is valid for this visual type and perform action if possible
- switch(actionId)
- {
- case DevelArcVisual::Action::UPDATE_PROPERTY:
- {
- const Property::Map* map = attributes.GetMap();
- if(map)
- {
- DoSetProperties(*map);
- }
- break;
- }
- }
-}
-
void ArcVisual::OnInitialize()
{
Geometry geometry = mFactoryCache.GetGeometry(VisualFactoryCache::QUAD_GEOMETRY);
*/
void OnSetTransform() override;
- /**
- * @copydoc Visual::Base::OnDoAction
- */
- void OnDoAction(const Property::Index actionId, const Property::Value& attributes) override;
-
private:
// Undefined
ArcVisual(const ArcVisual& arcVisual) = delete;
#include <dali/integration-api/debug.h>
//INTERNAL INCLUDES
-#include <dali-toolkit/devel-api/visuals/color-visual-actions-devel.h>
#include <dali-toolkit/devel-api/visuals/color-visual-properties-devel.h>
#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
#include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
}
}
-void ColorVisual::OnDoAction(const Property::Index actionId, const Property::Value& attributes)
-{
- // Check if action is valid for this visual type and perform action if possible
- switch(actionId)
- {
- case DevelColorVisual::Action::UPDATE_PROPERTY:
- {
- const Property::Map* map = attributes.GetMap();
- if(map)
- {
- DoSetProperties(*map);
- }
- break;
- }
- }
-}
-
void ColorVisual::UpdateShader()
{
if(mImpl->mRenderer)
void OnSetTransform() override;
/**
- * @copydoc Visual::Base::OnDoAction
- */
- void OnDoAction(const Property::Index actionId, const Property::Value& attributes) override;
-
- /**
* @copydoc Visual::Base::UpdateShader
*/
void UpdateShader() override;
#include <dali/devel-api/images/pixel-data-devel.h>
#include <dali/devel-api/rendering/renderer-devel.h>
#include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
-#include <dali/public-api/animation/constraints.h>
#include <string.h>
// INTERNAL HEADER
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);
- const Vector4& defaultColor = mController->GetTextModel()->GetDefaultColor();
- Dali::Property::Index shaderTextColorIndex = mImpl->mRenderer.RegisterProperty("uTextColorAnimatable", defaultColor);
+ const Vector4& defaultColor = mController->GetTextModel()->GetDefaultColor();
+ if(mTextColorAnimatableIndex == Property::INVALID_INDEX)
+ {
+ mTextColorAnimatableIndex = mImpl->mRenderer.RegisterProperty("uTextColorAnimatable", defaultColor);
+ }
+ else
+ {
+ 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)
{
- Constraint colorConstraint = Constraint::New<Vector4>(mImpl->mRenderer, shaderTextColorIndex, TextColorConstraint);
- colorConstraint.AddSource(Source(actor, mAnimatableTextColorPropertyIndex));
- colorConstraint.Apply();
-
- // Make zero if the alpha value of text color is zero to skip rendering text
- Constraint opacityConstraint = Constraint::New<float>(mImpl->mRenderer, Dali::DevelRenderer::Property::OPACITY, OpacityConstraint);
- opacityConstraint.AddSource(Source(actor, mAnimatableTextColorPropertyIndex));
- opacityConstraint.Apply();
+ if(!mColorConstraint)
+ {
+ 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();
}
// Renderer needs textures and to be added to control
void TextVisual::DoSetOffScene(Actor& actor)
{
+ if(mColorConstraint)
+ {
+ mColorConstraint.Remove();
+ }
+ if(mOpacityConstraint)
+ {
+ mOpacityConstraint.Remove();
+ }
+
RemoveRenderer(actor);
// Resets the control handle.
*/
// EXTERNAL INCLUDES
+#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/object/base-object.h>
#include <dali/public-api/object/weak-handle.h>
Text::ControllerPtr mController; ///< The text's controller.
Text::TypesetterPtr mTypesetter; ///< The text's typesetter.
WeakHandle<Actor> mControl; ///< The control where the renderer is added.
+ 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;
};
#include <dali/integration-api/debug.h>
//INTERNAL HEARDER
+#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
#include <dali-toolkit/internal/helpers/property-helper.h>
#include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
{
mImpl->mBorderlineWidth = width;
}
+
+ if(mImpl->mBorderlineWidthIndex != Property::INVALID_INDEX)
+ {
+ mImpl->mRenderer.SetProperty(mImpl->mBorderlineWidthIndex, mImpl->mBorderlineWidth);
+ }
break;
}
case Toolkit::DevelVisual::Property::BORDERLINE_COLOR:
{
mImpl->mBorderlineColor = color;
}
+
+ if(mImpl->mBorderlineColorIndex != Property::INVALID_INDEX)
+ {
+ mImpl->mRenderer.SetProperty(mImpl->mBorderlineColorIndex, mImpl->mBorderlineColor);
+ }
break;
}
case Toolkit::DevelVisual::Property::BORDERLINE_OFFSET:
{
mImpl->mBorderlineOffset = offset;
}
+
+ if(mImpl->mBorderlineOffsetIndex != Property::INVALID_INDEX)
+ {
+ mImpl->mRenderer.SetProperty(mImpl->mBorderlineOffsetIndex, mImpl->mBorderlineOffset);
+ }
break;
}
case Toolkit::DevelVisual::Property::CORNER_RADIUS:
mImpl->mCornerRadius = Vector4(radius, radius, radius, radius);
}
}
+
+ if(mImpl->mCornerRadiusIndex != Property::INVALID_INDEX)
+ {
+ mImpl->mRenderer.SetProperty(mImpl->mCornerRadiusIndex, mImpl->mCornerRadius);
+ }
break;
}
case Toolkit::DevelVisual::Property::CORNER_RADIUS_POLICY:
void Visual::Base::DoAction(const Property::Index actionId, const Property::Value attributes)
{
OnDoAction(actionId, attributes);
+
+ // Check if action is valid for this visual type and perform action if possible
+ switch(actionId)
+ {
+ case DevelVisual::Action::UPDATE_PROPERTY:
+ {
+ const Property::Map* map = attributes.GetMap();
+ if(map)
+ {
+ SetProperties(*map);
+ }
+ break;
+ }
+ }
}
void Visual::Base::SetDepthIndex(int index)
#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
-#include <dali-toolkit/devel-api/visuals/color-visual-actions-devel.h>
+#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
#include <dali-toolkit/devel-api/visuals/color-visual-properties-devel.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
#include <dali-toolkit/internal/styling/style-manager-impl.h>
if(visual && visual.GetType() == Toolkit::Visual::COLOR)
{
// Update background color only
- mImpl->DoAction(Toolkit::Control::Property::BACKGROUND, DevelColorVisual::Action::UPDATE_PROPERTY, map);
+ mImpl->DoAction(Toolkit::Control::Property::BACKGROUND, DevelVisual::Action::UPDATE_PROPERTY, map);
return;
}
mImpl->SignalDisconnected(slotObserver, callback);
}
+void Control::MakeVisualTransition(Dali::Property::Map& sourcePropertyMap, Dali::Property::Map& destinationPropertyMap,
+ Dali::Toolkit::Control source, Dali::Toolkit::Control destination, Dali::Property::Index visualIndex)
+{
+ sourcePropertyMap.Clear();
+ destinationPropertyMap.Clear();
+
+ Toolkit::Visual::Base sourceVisual = DevelControl::GetVisual(GetImplementation(source), visualIndex);
+ Toolkit::Visual::Base destinationVisual = DevelControl::GetVisual(GetImplementation(destination), visualIndex);
+
+ // If source or destination doesn't have the visual, do not create transition for the visual.
+ if(!sourceVisual || !destinationVisual)
+ {
+ return;
+ }
+
+ Property::Map sourceMap;
+ Property::Map destinationMap;
+ sourceVisual.CreatePropertyMap(sourceMap);
+ destinationVisual.CreatePropertyMap(destinationMap);
+
+ static auto findValueVector4 = [](const Property::Map& map, Property::Index index, const Vector4& defaultValue = Vector4()) -> Vector4
+ {
+ Property::Value* propertyValue = map.Find(index);
+ if(propertyValue)
+ {
+ return propertyValue->Get<Vector4>();
+ }
+ return defaultValue;
+ };
+
+ static auto findValueFloat = [](const Property::Map& map, Property::Index index, const float& defaultValue = 0.0f) -> float
+ {
+ Property::Value* propertyValue = map.Find(index);
+ if(propertyValue)
+ {
+ return propertyValue->Get<float>();
+ }
+ return defaultValue;
+ };
+
+ Vector4 defaultMixColor(Color::TRANSPARENT);
+ Vector4 defaultCornerRadius(0.0f, 0.0f, 0.0f, 0.0f);
+ float defaultBorderlineWidth(0.0f);
+ Vector4 defaultBorderlineColor(0.0f, 0.0f, 0.0f, 1.0f);
+ float defaultBorderlineOffset(0.0f);
+
+ Vector4 sourceMixColor = findValueVector4(sourceMap, Dali::Toolkit::Visual::Property::MIX_COLOR, defaultMixColor);
+ Vector4 sourceCornerRadius = findValueVector4(sourceMap, Toolkit::DevelVisual::Property::CORNER_RADIUS, defaultCornerRadius);
+ float sourceBorderlineWidth = findValueFloat(sourceMap, Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, defaultBorderlineWidth);
+ Vector4 sourceBorderlineColor = findValueVector4(sourceMap, Toolkit::DevelVisual::Property::BORDERLINE_COLOR, defaultBorderlineColor);
+ float sourceBorderlineOffset = findValueFloat(sourceMap, Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, defaultBorderlineOffset);
+
+ Vector4 destinationMixColor = findValueVector4(destinationMap, Dali::Toolkit::Visual::Property::MIX_COLOR, defaultMixColor);
+ Vector4 destinationCornerRadius = findValueVector4(destinationMap, Toolkit::DevelVisual::Property::CORNER_RADIUS, defaultCornerRadius);
+ float destinationBorderlineWidth = findValueFloat(destinationMap, Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, defaultBorderlineWidth);
+ Vector4 destinationBorderlineColor = findValueVector4(destinationMap, Toolkit::DevelVisual::Property::BORDERLINE_COLOR, defaultBorderlineColor);
+ float destinationBorderlineOffset = findValueFloat(destinationMap, Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, defaultBorderlineOffset);
+
+ // If the value of the source Control and that of destination Control is different, the property should be transitioned.
+ if(Vector3(sourceMixColor) != Vector3(destinationMixColor))
+ {
+ sourcePropertyMap.Add(Dali::Toolkit::Visual::Property::MIX_COLOR, Vector3(sourceMixColor));
+ destinationPropertyMap.Add(Dali::Toolkit::Visual::Property::MIX_COLOR, Vector3(destinationMixColor));
+ }
+
+ if(std::abs(sourceMixColor.a - destinationMixColor.a) > Math::MACHINE_EPSILON_1)
+ {
+ sourcePropertyMap.Add(Dali::Toolkit::Visual::Property::OPACITY, sourceMixColor.a);
+ destinationPropertyMap.Add(Dali::Toolkit::Visual::Property::OPACITY, destinationMixColor.a);
+ }
+
+ if(sourceCornerRadius != destinationCornerRadius)
+ {
+ sourcePropertyMap.Add(Dali::Toolkit::DevelVisual::Property::CORNER_RADIUS, sourceCornerRadius);
+ destinationPropertyMap.Add(Dali::Toolkit::DevelVisual::Property::CORNER_RADIUS, destinationCornerRadius);
+ }
+
+ if(sourceBorderlineWidth != destinationBorderlineWidth)
+ {
+ sourcePropertyMap.Add(Dali::Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, sourceBorderlineWidth);
+ destinationPropertyMap.Add(Dali::Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, destinationBorderlineWidth);
+ }
+
+ if(sourceBorderlineColor != destinationBorderlineColor)
+ {
+ sourcePropertyMap.Add(Dali::Toolkit::DevelVisual::Property::BORDERLINE_COLOR, sourceBorderlineColor);
+ destinationPropertyMap.Add(Dali::Toolkit::DevelVisual::Property::BORDERLINE_COLOR, destinationBorderlineColor);
+ }
+
+ if(sourceBorderlineOffset != destinationBorderlineOffset)
+ {
+ sourcePropertyMap.Add(Dali::Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, sourceBorderlineOffset);
+ destinationPropertyMap.Add(Dali::Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, destinationBorderlineOffset);
+ }
+}
+
Control& GetImplementation(Dali::Toolkit::Control& handle)
{
CustomActorImpl& customInterface = handle.GetImplementation();
namespace Internal
{
+
/**
* @brief This is the internal base class for all controls.
*
return NULL;
}
- // Transition
+ // Transition APIs
+
+ /**
+ * @brief Make visual transition from source control to destination control about specific Visual.
+ * If both of source and destination control have same visual index, than generates information for the transition of this Control.
+ *
+ * @param[out] sourcePropertyMap Source property map to be applied on this Control.
+ * @param[out] destinationPropertyMap Destination property map to be applied on this Control.
+ * @param[in] source Source control of the animation.
+ * @param[in] destination Destination control of the animation.
+ * @param[in] visualIndex Property::Index to make animation.
+ */
+ void MakeVisualTransition(Dali::Property::Map& sourcePropertyMap, Dali::Property::Map& destinationPropertyMap,
+ Dali::Toolkit::Control source, Dali::Toolkit::Control destination, Dali::Property::Index visualIndex);
/**
- * @brief Retrieve visual property animations.
- * This Control is a destination.
+ * @brief Retrieves source and destination visual properties for the Transition of this Control.
+ * The properties of this Control will be transitioned from the propeties of source Control to that of destination control.
+ * If a property value is different between source and destination Control,
+ * the property information of each Control will be included in sourceProperties and destinationProperties.
+ *
+ * @param[out] sourceProperties Source property list to be applied on this Control.
+ * @param[out] destinationProperties Destination property list to be applied on this Control.
+ * @param[in] source Source control of the animation.
+ * @param[in] destination Destination control of the animation.
*
- * @param[in] animation generated animation
- * @param[in] source source control of the animation.
- * @param[in] alphaFunction AlphaFunction of the animation
- * @param[in] timePeriod TimePeriod of the animation
+ * @note This method do not handle Actor properties.
+ * And the size and order of the sourceProperties and destinationProperties must be synchronized.
+ */
+ virtual void OnCreateTransitions(std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& sourceProperties,
+ std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& destinationProperties,
+ Dali::Toolkit::Control source,
+ Dali::Toolkit::Control destination)
+ {
+ }
+
+ /**
+ * @brief Update visual properties.
+ * @param[in] properties Property list to be used to update visual properties of this Control.
*/
- virtual void OnCreateTransitions(Dali::Animation& animation, Dali::Toolkit::Control source, AlphaFunction alphaFunction, TimePeriod timePeriod)
+ virtual void OnUpdateVisualProperties(const std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& properties)
{
}
return Control::DownCast<GlView, Internal::GlView>(handle);
}
-void GlView::RegisterGlCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
+void GlView::RegisterGlCallbacks(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
{
- Dali::Toolkit::GetImpl(*this).RegisterGlCallback(initCallback, renderFrameCallback, terminateCallback);
+ Dali::Toolkit::GetImpl(*this).RegisterGlCallbacks(initCallback, renderFrameCallback, terminateCallback);
}
void GlView::SetResizeCallback(CallbackBase* resizeCallback)
* <b>You can't call Dali APIs in your callbacks because it is invoked in GlView's own render thread.</b>
* And this must be called before adding GlView to the scene.
*/
- void RegisterGlCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback);
+ void RegisterGlCallbacks(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback);
/**
* @brief Sets the ResizeCallback of the GlView.
{
const unsigned int TOOLKIT_MAJOR_VERSION = 2;
const unsigned int TOOLKIT_MINOR_VERSION = 0;
-const unsigned int TOOLKIT_MICRO_VERSION = 48;
+const unsigned int TOOLKIT_MICRO_VERSION = 52;
const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
{
}
-Transition Transition::New(Dali::Toolkit::Control source, Dali::Toolkit::Control destination, TimePeriod timePeriod)
+Transition Transition::New(Dali::Toolkit::Control source, Dali::Toolkit::Control destination, bool useDestinationTarget, TimePeriod timePeriod)
{
- Internal::TransitionPtr internal = Dali::Toolkit::Internal::Transition::New(source, destination, timePeriod);
+ Internal::TransitionPtr internal = Dali::Toolkit::Internal::Transition::New(source, destination, useDestinationTarget, timePeriod);
return Transition(internal.Get());
}
/**
* @brief Creates an initialized Transition.
*
- * @param[in] source Source
- * @param[in] destination Destination
+ * @param[in] source A source control of this transition.
+ * @param[in] destination A destination control of this transition.
+ * @param[in] useDestinationTarget True if this transition uses destination control as target.
* @param[in] timePeriod The duration in seconds
* @return A handle to a newly allocated Dali resource
* @note durationSeconds can not be negative.
*/
- static Transition New(Dali::Toolkit::Control source, Dali::Toolkit::Control destination, TimePeriod timePeriod);
+ static Transition New(Dali::Toolkit::Control source, Dali::Toolkit::Control destination, bool useDestinationTarget, TimePeriod timePeriod);
/**
* @brief Downcasts a handle to Transition handle.
--- /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.48
+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