[Tizen] Be a bit smarter with SetFocusedActorPosition 16/288516/1 accepted/tizen/6.0/unified/20230221.003240 submit/tizen_6.0/20230220.132938
authorArtur Świgoń <a.swigon@samsung.com>
Fri, 17 Feb 2023 12:51:59 +0000 (13:51 +0100)
committerArtur Świgoń <a.swigon@samsung.com>
Fri, 17 Feb 2023 12:52:04 +0000 (13:52 +0100)
The previous calculation method was to always use the center point of a given
actor, regardless of the position of the touch event that caused it to be
focused. In the tricky scenario where a smaller actor is overlaid on top of a
bigger actor such that the smaller actor covers the center of the bigger actor,
a double-tap-and-hold gesture meant to activate the bigger actor would activate
the smaller actor instead.

The calculation method introduced by this patch is a little bit better, but
still not ideal. However, the HighlightedObjectInfo D-Bus method has only two
parameters, the coordinates, taken from GetFocusedActorPosition, which are then
forwarded back into the app as a touch event, so there isn't much more that
could be done in DALi to address this issue.

Change-Id: I03f291f3dece2bd2c10fedd7ce22f8791230b6f4

dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp

index 853c009..e856ec2 100644 (file)
@@ -360,11 +360,23 @@ bool AccessibilityManager::DoSetCurrentFocusActor(const unsigned int actorID)
         actor.Add( GetFocusIndicatorActor() );
       }
 
-      // Send Focused actor information
-      Vector2 windowSize = rootActor.GetCurrentProperty<Vector2>(Actor::Property::SIZE);
-      AccessibilityAdaptor adaptor = AccessibilityAdaptor::Get();
-      adaptor.SetFocusedActorPosition( Vector2((actor.GetCurrentProperty<Vector3>(Actor::Property::WORLD_POSITION).x + (windowSize.width / 2)),
-                                             (actor.GetCurrentProperty<Vector3>(Actor::Property::WORLD_POSITION).y + (windowSize.height / 2))) );
+      auto adaptor = AccessibilityAdaptor::Get();
+      Vector2 readPosition = adaptor.GetReadPosition();
+      auto actorPosition = actor.GetCurrentProperty<Vector2>(Actor::Property::SCREEN_POSITION);
+      auto actorSize = actor.GetCurrentProperty<Vector2>(Actor::Property::SIZE);
+      Rect<> actorRect(actorPosition.x, actorPosition.y, actorSize.width, actorSize.height);
+
+      if(actorRect.Contains(Rect<>(readPosition.x, readPosition.y, 0, 0)))
+      {
+        // If the last touched position is within the extents of the actor,
+        // then use that position. (The center may be covered by some other actor).
+        adaptor.SetFocusedActorPosition(readPosition);
+      }
+      else
+      {
+        // Otherwise, use the center point.
+        adaptor.SetFocusedActorPosition(actorPosition + actorSize / 2);
+      }
 
       // Send notification for the change of focus actor
       mFocusChangedSignal.Emit( GetCurrentFocusActor(), actor );