This is because TextField and TextEditor use PanGesture, parent actors will not be able to receive PanGesture.
So let's propagate the pan gesture to the parent unless the text is being scrolled by the pan gesture.
Change-Id: Ia3b9995fab97287cbf4db271f3912712b7f78695
#include <dali/devel-api/adaptor-framework/clipboard.h>
#include <dali/devel-api/adaptor-framework/key-devel.h>
#include <dali/devel-api/text-abstraction/font-client.h>
+#include <dali/devel-api/events/pan-gesture-devel.h>
#include <dali/integration-api/events/key-event-integ.h>
#include <dali/integration-api/events/touch-event-integ.h>
#include <dali/public-api/rendering/renderer.h>
bool& mFinishedCalled;
};
+
+// Stores data that is populated in the callback and will be read by the test cases
+struct SignalData
+{
+ SignalData()
+ : functorCalled(false),
+ voidFunctorCalled(false),
+ receivedGesture()
+ {
+ }
+
+ void Reset()
+ {
+ functorCalled = false;
+ voidFunctorCalled = false;
+
+ receivedGesture.Reset();
+
+ pannedActor.Reset();
+ }
+
+ bool functorCalled;
+ bool voidFunctorCalled;
+ PanGesture receivedGesture;
+ Actor pannedActor;
+};
+
+// Functor that sets the data when called
+struct GestureReceivedFunctor
+{
+ GestureReceivedFunctor(SignalData& data)
+ : signalData(data)
+ {
+ }
+
+ void operator()(Actor actor, const PanGesture& pan)
+ {
+ signalData.functorCalled = true;
+ signalData.receivedGesture = pan;
+ signalData.pannedActor = actor;
+ }
+
+ void operator()()
+ {
+ signalData.voidFunctorCalled = true;
+ }
+
+ SignalData& signalData;
+};
+
+
} // namespace
int UtcDaliToolkitTextEditorConstructorP(void)
application.Render();
END_TEST;
-}
\ No newline at end of file
+}
+
+int utcDaliTextEditorPanGesturePropagation(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextEditorPanGesturePropagation");
+
+ Actor actor = Actor::New();
+ actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ application.GetScene().Add(actor);
+
+ TextEditor editor = TextEditor::New();
+ DALI_TEST_CHECK(editor);
+
+ editor.SetProperty(TextEditor::Property::TEXT, "This is a long text for the size of the text-editor.");
+ editor.SetProperty(TextEditor::Property::POINT_SIZE, 10.f);
+
+ editor.SetProperty(Actor::Property::SIZE, Vector2(30.f, 500.f));
+ editor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ editor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ actor.Add(editor);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ SignalData data;
+ GestureReceivedFunctor functor(data);
+
+ PanGestureDetector detector = PanGestureDetector::New();
+ detector.Attach(actor);
+ detector.DetectedSignal().Connect(&application, functor);
+
+ // Tap first to get the focus.
+ TestGenerateTap(application, 3.0f, 25.0f, 100);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Pan the text editor
+ uint32_t time = 100;
+ TestStartPan(application, Vector2(10.0f, 50.0f), Vector2(10.0f, 50.0f), time);
+ TestMovePan(application, Vector2(10.0f, 30.0f), time);
+ TestEndPan(application, Vector2(10.0f, 50.0f), time);
+ application.SendNotification();
+ application.Render();
+
+ // The text scrolls because there is text that is scrolling.
+ DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ // Set the size large enough to prevent scrolling.
+ editor.SetProperty(Actor::Property::SIZE, Vector2(500.f, 500.f));
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ time = 200;
+ TestStartPan(application, Vector2(10.0f, 50.0f), Vector2(10.0f, 50.0f), time);
+ TestMovePan(application, Vector2(10.0f, 30.0f), time);
+ TestEndPan(application, Vector2(10.0f, 50.0f), time);
+
+ // Because scrolling is not possible, the pan gesture is propagated.
+ DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+
+ END_TEST;
+}
#include <unistd.h>
#include <iostream>
-#include <dali/integration-api/events/key-event-integ.h>
-#include <dali/integration-api/events/touch-event-integ.h>
-#include <dali/public-api/rendering/renderer.h>
-#include <dali/devel-api/actors/actor-devel.h>
#include <dali-toolkit-test-suite-utils.h>
#include <dali-toolkit/dali-toolkit.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup.h>
#include <dali-toolkit/devel-api/text/rendering-backend.h>
#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
+#include <dali/devel-api/actors/actor-devel.h>
#include <dali/devel-api/adaptor-framework/key-devel.h>
+#include <dali/devel-api/events/pan-gesture-devel.h>
#include <dali/devel-api/text-abstraction/font-client.h>
+#include <dali/integration-api/events/key-event-integ.h>
+#include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/public-api/rendering/renderer.h>
#include "test-text-geometry-utils.h"
#include "toolkit-clipboard.h"
return true;
}
+
+// Stores data that is populated in the callback and will be read by the test cases
+struct SignalData
+{
+ SignalData()
+ : functorCalled(false),
+ voidFunctorCalled(false),
+ receivedGesture()
+ {
+ }
+
+ void Reset()
+ {
+ functorCalled = false;
+ voidFunctorCalled = false;
+
+ receivedGesture.Reset();
+
+ pannedActor.Reset();
+ }
+
+ bool functorCalled;
+ bool voidFunctorCalled;
+ PanGesture receivedGesture;
+ Actor pannedActor;
+};
+
+// Functor that sets the data when called
+struct GestureReceivedFunctor
+{
+ GestureReceivedFunctor(SignalData& data)
+ : signalData(data)
+ {
+ }
+
+ void operator()(Actor actor, const PanGesture& pan)
+ {
+ signalData.functorCalled = true;
+ signalData.receivedGesture = pan;
+ signalData.pannedActor = actor;
+ }
+
+ void operator()()
+ {
+ signalData.voidFunctorCalled = true;
+ }
+
+ SignalData& signalData;
+};
+
} // namespace
int UtcDaliToolkitTextFieldConstructorP(void)
application.Render();
END_TEST;
-}
\ No newline at end of file
+}
+
+int utcDaliTextFieldPanGesturePropagation(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextFieldPanGesturePropagation");
+
+ Actor actor = Actor::New();
+ actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ application.GetScene().Add(actor);
+
+ TextField field = TextField::New();
+ DALI_TEST_CHECK(field);
+
+ field.SetProperty(TextField::Property::TEXT, "This is a long text for the size of the text-field.");
+ field.SetProperty(TextField::Property::POINT_SIZE, 10.f);
+
+ field.SetProperty(Actor::Property::SIZE, Vector2(50.f, 100.f));
+ field.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ field.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ actor.Add(field);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ SignalData data;
+ GestureReceivedFunctor functor(data);
+
+ PanGestureDetector detector = PanGestureDetector::New();
+ detector.Attach(actor);
+ detector.DetectedSignal().Connect(&application, functor);
+
+ // Tap first to get the focus.
+ TestGenerateTap(application, 3.0f, 25.0f, 100);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Pan the text field
+ uint32_t time = 100;
+ TestStartPan(application, Vector2(40.0f, 50.0f), Vector2(40.0f, 50.0f), time);
+ TestMovePan(application, Vector2(10.0f, 50.0f), time);
+ TestEndPan(application, Vector2(40.0f, 50.0f), time);
+ application.SendNotification();
+ application.Render();
+
+ // The text scrolls because there is text that is scrolling.
+ DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ // Set the size large enough to prevent scrolling.
+ field.SetProperty(Actor::Property::SIZE, Vector2(700.f, 100.f));
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ time = 200;
+ TestStartPan(application, Vector2(40.0f, 50.0f), Vector2(40.0f, 50.0f), time);
+ TestMovePan(application, Vector2(10.0f, 50.0f), time);
+ TestEndPan(application, Vector2(40.0f, 50.0f), time);
+
+ // Because scrolling is not possible, the pan gesture is propagated.
+ DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+
+ END_TEST;
+}
void TextEditor::OnPan(const PanGesture& gesture)
{
mController->PanEvent(gesture.GetState(), gesture.GetDisplacement());
+ if(gesture.GetState() == GestureState::STARTED && !mController->IsScrollable(gesture.GetDisplacement()))
+ {
+ Dali::DevelActor::SetNeedGesturePropagation(Self(), true);
+ }
}
void TextEditor::OnLongPress(const LongPressGesture& gesture)
void TextField::OnPan(const PanGesture& gesture)
{
mController->PanEvent(gesture.GetState(), gesture.GetDisplacement());
+ if(gesture.GetState() == GestureState::STARTED && !mController->IsScrollable(gesture.GetDisplacement()))
+ {
+ Dali::DevelActor::SetNeedGesturePropagation(Self(), true);
+ }
}
void TextField::OnLongPress(const LongPressGesture& gesture)
}
}
+bool Controller::Impl::IsScrollable(const Vector2& displacement)
+{
+ bool isScrollable = false;
+ if(mEventData)
+ {
+ const bool isHorizontalScrollEnabled = mEventData->mDecorator->IsHorizontalScrollEnabled();
+ const bool isVerticalScrollEnabled = mEventData->mDecorator->IsVerticalScrollEnabled();
+ if(isHorizontalScrollEnabled ||isVerticalScrollEnabled)
+ {
+ const Vector2& targetSize = mModel->mVisualModel->mControlSize;
+ const Vector2& layoutSize = mModel->mVisualModel->GetLayoutSize();
+ const Vector2& scrollPosition = mModel->mScrollPosition;
+
+ if(isHorizontalScrollEnabled)
+ {
+ const float displacementX = displacement.x;
+ const float positionX = scrollPosition.x + displacementX;
+ if(layoutSize.width > targetSize.width && -positionX > 0.f && -positionX < layoutSize.width - targetSize.width)
+ {
+ isScrollable = true;
+ }
+ }
+
+ if(isVerticalScrollEnabled)
+ {
+ const float displacementY = displacement.y;
+ const float positionY = scrollPosition.y + displacementY;
+ if(layoutSize.height > targetSize.height && -positionY > 0 && -positionY < layoutSize.height - targetSize.height)
+ {
+ isScrollable = true;
+ }
+ }
+ }
+ }
+ return isScrollable;
+}
+
float Controller::Impl::GetHorizontalScrollPosition()
{
// Scroll values are negative internally so we convert them to positive numbers
void ScrollBy(Vector2 scroll);
/**
+ * @copydoc Controller::IsScrollable()
+ */
+ bool IsScrollable(const Vector2& displacement);
+
+ /**
* @copydoc Controller::GetHorizontalScrollPosition()
*/
float GetHorizontalScrollPosition();
mImpl->ScrollBy(scroll);
}
+bool Controller::IsScrollable(const Vector2& displacement)
+{
+ return mImpl->IsScrollable(displacement);
+}
+
float Controller::GetHorizontalScrollPosition()
{
return mImpl->GetHorizontalScrollPosition();
virtual void ScrollBy(Vector2 scroll);
/**
+ * @brief Whether the text is scrollable.
+ * @return Returns true if the text is scrollable.
+ */
+ bool IsScrollable(const Vector2& displacement);
+
+ /**
* @copydoc Dali::Toolkit::Internal::TextEditor::GetHorizontalScrollPosition()
*/
float GetHorizontalScrollPosition();