Change TOUCH_AREA to TOUCH_AREA_OFFSET 87/257287/1
authorJoogab Yun <joogab.yun@samsung.com>
Thu, 22 Apr 2021 02:09:26 +0000 (11:09 +0900)
committerJoogab Yun <joogab.yun@samsung.com>
Thu, 22 Apr 2021 02:09:58 +0000 (11:09 +0900)
You can set offset the touch area.

for example)
  Actor actor = Actor::New();
  actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
  actor.SetProperty(DevelActor::Property::TOUCH_AREA_OFFSET, Rect<int>(-100, 100, 100, -100));
  actor.TouchedSignal().Connect(OnTouchCallback);

then touch area is 210x210.
this is actor.width + touchAreaOffset.right - touchAreaOffset.left
and actor.height + touchAreaOffset.bottom -touchAreaOffset.top

This reverts commit 611aa0a439969daefa33e9428d294ce4f9c03f1b.

Change-Id: Ifaafb243f18ec24cfd0089e009a62505e54f60ec

automated-tests/src/dali/utc-Dali-Actor.cpp
automated-tests/src/dali/utc-Dali-TouchProcessing.cpp
dali/devel-api/actors/actor-devel.h
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/actors/actor-property-handler.cpp
dali/internal/event/events/ray-test.cpp

index 02324d3..940902e 100644 (file)
@@ -8577,20 +8577,20 @@ int UtcDaliActorCaptureAllTouchAfterStartPropertyN(void)
   END_TEST;
 }
 
-int UtcDaliActorTouchAreaPropertyP(void)
+int UtcDaliActorTouchAreaOffsetPropertyP(void)
 {
   TestApplication application;
 
-  Actor   actor     = Actor::New();
-  Vector2 touchArea = actor.GetProperty(DevelActor::Property::TOUCH_AREA).Get<Vector2>();
-  DALI_TEST_EQUALS(touchArea, Vector2::ZERO, TEST_LOCATION);
-  actor.SetProperty(DevelActor::Property::TOUCH_AREA, Vector2(10.f, 10.f));
-  touchArea = actor.GetProperty(DevelActor::Property::TOUCH_AREA).Get<Vector2>();
-  DALI_TEST_EQUALS(touchArea, Vector2(10.f, 10.f), TEST_LOCATION);
+  Actor     actor           = Actor::New();
+  Rect<int> touchAreaOffset = actor.GetProperty(DevelActor::Property::TOUCH_AREA_OFFSET).Get<Rect<int>>();
+  DALI_TEST_EQUALS(Rect<int>(0, 0, 0, 0), touchAreaOffset, TEST_LOCATION);
+  actor.SetProperty(DevelActor::Property::TOUCH_AREA_OFFSET, Rect<int>(10, 20, 30, 40));
+  touchAreaOffset = actor.GetProperty(DevelActor::Property::TOUCH_AREA_OFFSET).Get<Rect<int>>();
+  DALI_TEST_EQUALS(Rect<int>(10, 20, 30, 40), touchAreaOffset, TEST_LOCATION);
   END_TEST;
 }
 
-int UtcDaliActorTouchAreaPropertyN(void)
+int UtcDaliActorTouchAreaOffsetPropertyN(void)
 {
   TestApplication application;
 
@@ -8599,12 +8599,12 @@ int UtcDaliActorTouchAreaPropertyN(void)
   // Make sure setting invalid types does not cause a crash
   try
   {
-    actor.SetProperty(DevelActor::Property::TOUCH_AREA, 1.0f);
-    actor.SetProperty(DevelActor::Property::TOUCH_AREA, Vector2::ONE);
-    actor.SetProperty(DevelActor::Property::TOUCH_AREA, Vector3::ONE);
-    actor.SetProperty(DevelActor::Property::TOUCH_AREA, Vector4::ONE);
-    actor.SetProperty(DevelActor::Property::TOUCH_AREA, Property::Map());
-    actor.SetProperty(DevelActor::Property::TOUCH_AREA, Property::Array());
+    actor.SetProperty(DevelActor::Property::TOUCH_AREA_OFFSET, 1.0f);
+    actor.SetProperty(DevelActor::Property::TOUCH_AREA_OFFSET, Vector2::ONE);
+    actor.SetProperty(DevelActor::Property::TOUCH_AREA_OFFSET, Vector3::ONE);
+    actor.SetProperty(DevelActor::Property::TOUCH_AREA_OFFSET, Vector4::ONE);
+    actor.SetProperty(DevelActor::Property::TOUCH_AREA_OFFSET, Property::Map());
+    actor.SetProperty(DevelActor::Property::TOUCH_AREA_OFFSET, Property::Array());
     tet_result(TET_PASS);
   }
   catch(...)
index 5f2d395..ac66e4d 100644 (file)
@@ -2137,7 +2137,7 @@ int UtcDaliTouchEventIntercept(void)
   END_TEST;
 }
 
-int UtcDaliTouchArea(void)
+int UtcDaliTouchAreaOffset(void)
 {
   TestApplication application;
 
@@ -2163,7 +2163,7 @@ int UtcDaliTouchArea(void)
   data.Reset();
 
   // set a bigger touch area
-  actor.SetProperty(DevelActor::Property::TOUCH_AREA, Vector2(200.0f, 200.0f));
+  actor.SetProperty(DevelActor::Property::TOUCH_AREA_OFFSET, Rect<int>(-70, 70, 70, -70)); // left, right, bottom, top
 
   // Render and notify
   application.SendNotification();
@@ -2177,21 +2177,36 @@ int UtcDaliTouchArea(void)
   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
   data.Reset();
 
+  // set a offset touch area
+  actor.SetProperty(DevelActor::Property::TOUCH_AREA_OFFSET, Rect<int>(50, 100, -50, 0)); // left, right, bottom, top
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Emit a down signal
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(190.0f, 25.0f)));
+  // The actor touched signal is called because the touch area is inside touchArea.
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
+  DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
+  data.Reset();
+
   // set a smaller touch area
-  actor.SetProperty(DevelActor::Property::TOUCH_AREA, Vector2(50.0f, 50.0f));
+  actor.SetProperty(DevelActor::Property::TOUCH_AREA_OFFSET, Rect<int>(50, 0, 0, 50));
 
   // Render and notify
   application.SendNotification();
   application.Render();
 
   // Emit a down signal
-  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(80.0f, 80.0f)));
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(40.0f, 40.0f)));
   // The actor touched signal is not called because the touch area is outside touchArea.
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
   data.Reset();
 
   // Emit a down signal
-  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(30.0f, 30.0f)));
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(90.0f, 90.0f)));
   // The actor touched signal is called because the touch area is inside touchArea.
   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
index 5821af0..3df66b4 100755 (executable)
@@ -2,7 +2,7 @@
 #define DALI_ACTOR_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.
@@ -120,18 +120,36 @@ enum Type
   CAPTURE_ALL_TOUCH_AFTER_START,
 
   /**
-    * @brief If you set the TOUCH_AREA on an actor, when you touch the actor, the touch area is used rather than the size of the actor
-    * @details Name "touchArea", type Property::Vector2
-    * @note Default is Vector2::ZERO.
+    * @brief If you set the TOUCH_AREA_OFFSET on an actor, when you touch the actor, the touch area is expand from the size of actor.
+    * @details Name "touchAreaOffset", type Property::Rect<int> (left, right, bottom, top)
     * @note for example
     *  Actor actor = Actor::New();
-    *  actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
-    *  actor.SetProperty(DevelActor::Property::TOUCH_AREA, Vector2(200.0f, 200.0f));
+    *  actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f));
+    *  actor.SetProperty(DevelActor::Property::TOUCH_AREA_OFFSET, Rect<int>(-10, 20, 30, -40));
     *  actor.TouchedSignal().Connect(OnTouchCallback);
     *
-    *  If you want to reset the touch area to an area different with the size of the actor, you can set this TOUCH_AREA property.
+    * +---------------------+
+    * |         ^           |
+    * |         |           |
+    * |         | -40       |
+    * |         |           |
+    * |         |           |
+    * |    +----+----+      |
+    * |    |         |      |
+    * | -10|         | 20   |
+    * |<---+         +----->|
+    * |    |         |      |
+    * |    |         |      |
+    * |    +----+----+      |
+    * |         |           |
+    * |         | 30        |
+    * |         |           |
+    * |         v           |
+    * +---------------------+
+
+    *  The actual touched size is actor.width + touchAreaOffset.right - touchAreaOffset.left and actor.height + touchAreaOffset.bottom - touchAreaOffset.top
     */
-  TOUCH_AREA,
+  TOUCH_AREA_OFFSET,
 
   /**
    * @brief Determines which blend equation will be used to render renderers of this actor.
index 408c273..776c3f3 100644 (file)
@@ -146,7 +146,7 @@ DALI_PROPERTY("keyboardFocusable", BOOLEAN, true, false, false, Dali::Actor::Pro
 DALI_PROPERTY("siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER)
 DALI_PROPERTY("updateSizeHint", VECTOR2, true, false, false, Dali::DevelActor::Property::UPDATE_SIZE_HINT)
 DALI_PROPERTY("captureAllTouchAfterStart", BOOLEAN, true, false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START)
-DALI_PROPERTY("touchArea", VECTOR2, true, false, false, Dali::DevelActor::Property::TOUCH_AREA)
+DALI_PROPERTY("touchAreaOffset", RECTANGLE, true, false, false, Dali::DevelActor::Property::TOUCH_AREA_OFFSET)
 DALI_PROPERTY("blendEquation", INTEGER, true, false, false, Dali::DevelActor::Property::BLEND_EQUATION)
 DALI_PROPERTY_TABLE_END(DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties)
 
@@ -1321,7 +1321,7 @@ Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
   mTargetPosition(Vector3::ZERO),
   mTargetScale(Vector3::ONE),
   mAnimatedSize(Vector3::ZERO),
-  mTouchArea(Vector2::ZERO),
+  mTouchAreaOffset(0, 0, 0, 0),
   mName(),
   mSortedDepth(0u),
   mDepth(0u),
index 106af0d..eb0ee82 100644 (file)
@@ -1363,21 +1363,21 @@ public:
   }
 
   /**
-   * Sets the touch area of an actor.
-   * @param [in] area The new area.
+   * Sets the touch area offset of an actor.
+   * @param [in] offset The new offset of area (left, right, bottom, top).
    */
-  void SetTouchArea(Vector2 area)
+  void SetTouchAreaOffset(Rect<int> offset)
   {
-    mTouchArea = area;
+    mTouchAreaOffset = offset;
   }
 
   /**
-   * Retrieve the Actor's touch area.
-   * @return The Actor's touch area.
+   * Retrieve the Actor's touch area offset.
+   * @return The Actor's touch area offset.
    */
-  const Vector2& GetTouchArea() const
+  const Rect<int>& GetTouchAreaOffset() const
   {
-    return mTouchArea;
+    return mTouchAreaOffset;
   }
 
   // Gestures
@@ -2024,7 +2024,7 @@ protected:
   Vector3    mTargetPosition;    ///< Event-side storage for position (not a pointer as most actors will have a position)
   Vector3    mTargetScale;       ///< Event-side storage for scale
   Vector3    mAnimatedSize;      ///< Event-side storage for size animation
-  Vector2    mTouchArea;         ///< touch area
+  Rect<int>  mTouchAreaOffset;   ///< touch area offset (left, right, bottom, top)
 
   ConstString mName;            ///< Name of the actor
   uint32_t    mSortedDepth;     ///< The sorted depth index. A combination of tree traversal and sibling order.
index 02fc9ce..111a088 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -577,12 +577,12 @@ void Actor::PropertyHandler::SetDefaultProperty(Internal::Actor& actor, Property
       break;
     }
 
-    case Dali::DevelActor::Property::TOUCH_AREA:
+    case Dali::DevelActor::Property::TOUCH_AREA_OFFSET:
     {
-      Vector2 vec2Value;
-      if(property.Get(vec2Value))
+      Rect<int> rectValue;
+      if(property.Get(rectValue))
       {
-        actor.SetTouchArea(vec2Value);
+        actor.SetTouchAreaOffset(rectValue);
       }
       break;
     }
@@ -1634,9 +1634,9 @@ bool Actor::PropertyHandler::GetCachedPropertyValue(const Internal::Actor& actor
       break;
     }
 
-    case Dali::DevelActor::Property::TOUCH_AREA:
+    case Dali::DevelActor::Property::TOUCH_AREA_OFFSET:
     {
-      value = actor.GetTouchArea();
+      value = actor.GetTouchAreaOffset();
       break;
     }
 
index 8659edf..9f3aa92 100644 (file)
@@ -105,18 +105,19 @@ bool RayTest::SphereTest(const Internal::Actor& actor, const Vector4& rayOrigin,
     return false;
   }
 
-  const Node&       node        = actor.GetNode();
-  const BufferIndex bufferIndex = EventThreadServices::Get().GetEventBufferIndex();
-  const Vector3&    translation = node.GetWorldPosition(bufferIndex);
-  const Vector3&    size        = actor.GetTouchArea() == Vector2::ZERO ? node.GetSize(bufferIndex) : Vector3(actor.GetTouchArea());
-  const Vector3&    scale       = node.GetWorldScale(bufferIndex);
+  const Node&       node            = actor.GetNode();
+  const BufferIndex bufferIndex     = EventThreadServices::Get().GetEventBufferIndex();
+  const Vector3&    translation     = node.GetWorldPosition(bufferIndex);
+  const Vector3&    size            = node.GetSize(bufferIndex);
+  const Vector3&    scale           = node.GetWorldScale(bufferIndex);
+  const Rect<int>&  touchAreaOffset = actor.GetTouchAreaOffset(); // (left, right, bottom, top)
 
   // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed.
-  const Vector3 rayOriginLocal(rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z);
+  const Vector3 rayOriginLocal(rayOrigin.x - translation.x - (touchAreaOffset.left + touchAreaOffset.right) * 0.5, rayOrigin.y - translation.y - (touchAreaOffset.top + touchAreaOffset.bottom) * 0.5, rayOrigin.z - translation.z);
 
   // Computing the radius is not needed, a square radius is enough so can just use size but we do need to scale the sphere
-  const float width  = size.width * scale.width;
-  const float height = size.height * scale.height;
+  const float width  = size.width * scale.width + touchAreaOffset.right - touchAreaOffset.left;
+  const float height = size.height * scale.height + touchAreaOffset.bottom - touchAreaOffset.top;
 
   float squareSphereRadius = 0.5f * (width * width + height * height);
 
@@ -153,12 +154,13 @@ bool RayTest::ActorTest(const Internal::Actor& actor, const Vector4& rayOrigin,
       // Ray travels distance * rayDirLocal to intersect with plane.
       distance = a / b;
 
-      const Vector2& size = actor.GetTouchArea() == Vector2::ZERO ? Vector2(node.GetSize(EventThreadServices::Get().GetEventBufferIndex())) : actor.GetTouchArea();
-      hitPointLocal.x     = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
-      hitPointLocal.y     = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
+      const Vector2&   size            = Vector2(node.GetSize(EventThreadServices::Get().GetEventBufferIndex()));
+      const Rect<int>& touchAreaOffset = actor.GetTouchAreaOffset(); // (left, right, bottom, top)
+      hitPointLocal.x                  = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f;
+      hitPointLocal.y                  = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f;
 
       // Test with the actor's geometry.
-      hit = (hitPointLocal.x >= 0.f) && (hitPointLocal.x <= size.x) && (hitPointLocal.y >= 0.f) && (hitPointLocal.y <= size.y);
+      hit = (hitPointLocal.x >= touchAreaOffset.left) && (hitPointLocal.x <= (size.x + touchAreaOffset.right) && (hitPointLocal.y >= touchAreaOffset.top) && (hitPointLocal.y <= (size.y + touchAreaOffset.bottom)));
     }
   }