[AT-SPI] Add AccessibleImpl::ScrollToChild() 98/255698/12
authorArtur Świgoń <a.swigon@samsung.com>
Mon, 22 Mar 2021 16:07:15 +0000 (17:07 +0100)
committerArtur Świgoń <a.swigon@samsung.com>
Mon, 7 Jun 2021 16:38:35 +0000 (18:38 +0200)
This replaces two virtual methods:
 * EnsureSelfVisible() - redundant, replaced by a simple loop
 * EnsureChildVisible() - renamed to ScrollToChild() to reflect
   that this concerns scrollable containers

Change-Id: I38f7be0a1117dc93ce70b496913b62a400c4432a

automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Controls-BridgeUp.cpp
dali-toolkit/devel-api/controls/accessible-impl.cpp
dali-toolkit/devel-api/controls/accessible-impl.h
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h
dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp
dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.h

index fdd8f10..808cc7a 100644 (file)
@@ -937,3 +937,117 @@ int UtcDaliAccessibilitySignals(void)
 
   END_TEST;
 }
+
+static void Wait(ToolkitTestApplication& application)
+{
+  application.SendNotification();
+  application.Render(16);
+}
+
+int UtcDaliAccessibilityScrollToChildScrollView(void)
+{
+  ToolkitTestApplication application;
+  Dali::Accessibility::TestEnableSC( true );
+
+  ScrollView scrollView = ScrollView::New();
+  application.GetScene().Add( scrollView );
+
+  PushButton actorA = PushButton::New();
+  const Dali::Vector3 positionA = Vector3(100.0f, 400.0f, 0.0f);
+  actorA.SetProperty( Dali::Actor::Property::POSITION, positionA );
+  scrollView.Add(actorA);
+
+  PushButton actorB = PushButton::New();
+  const Dali::Vector3 positionB = Vector3(500.0f, 200.0f, 0.0f);
+  actorB.SetProperty( Dali::Actor::Property::POSITION, positionB );
+  scrollView.Add(actorB);
+
+  Wait(application);
+
+  auto* accessibleParent = dynamic_cast<DevelControl::AccessibleImpl*>(Dali::Accessibility::Accessible::Get(scrollView));
+  DALI_TEST_CHECK(accessibleParent);
+  auto* accessibleA = dynamic_cast<DevelControl::AccessibleImpl*>(Dali::Accessibility::Accessible::Get(actorA));
+  DALI_TEST_CHECK(accessibleA);
+  auto* accessibleB = dynamic_cast<DevelControl::AccessibleImpl*>(Dali::Accessibility::Accessible::Get(actorB));
+  DALI_TEST_CHECK(accessibleB);
+
+  accessibleA->GrabHighlight(); // == scrollView.ScrollTo(actorA)
+  Wait(application);
+  accessibleB->GrabHighlight(); // == scrollView.ScrollTo(actorB)
+  Wait(application);
+
+  Dali::Accessibility::TestEnableSC( false );
+  END_TEST;
+}
+
+namespace {
+  class TestItemFactory : public ItemFactory
+  {
+  public:
+    TestItemFactory()
+    {
+    }
+
+    unsigned int GetNumberOfItems() override
+    {
+      return 2;
+    }
+
+    Dali::Actor NewItem(unsigned int itemId) override
+    {
+      return TextLabel::New(std::to_string(itemId));
+    }
+  };
+}
+
+int UtcDaliAccessibilityScrollToChildItemView(void)
+{
+  ToolkitTestApplication application;
+  Dali::Accessibility::TestEnableSC( true );
+
+  TestItemFactory factory;
+  ItemView view = ItemView::New(factory);
+  Dali::Vector3 vec(480.0f, 800.0f, 0.0f);
+  ItemLayoutPtr layout = DefaultItemLayout::New( DefaultItemLayout::DEPTH );
+
+  view.AddLayout(*layout);
+  view.SetProperty( Actor::Property::SIZE, vec );
+
+  application.GetScene().Add(view);
+  layout->SetOrientation(ControlOrientation::Down);
+  view.ActivateLayout(0, vec, 0.0f);
+
+  Wait(application);
+
+  auto* accessibleParent = dynamic_cast<DevelControl::AccessibleImpl*>(Dali::Accessibility::Accessible::Get(view));
+  DALI_TEST_CHECK(accessibleParent);
+  auto* accessibleA = dynamic_cast<DevelControl::AccessibleImpl*>(Dali::Accessibility::Accessible::Get(view.GetItem(0)));
+  DALI_TEST_CHECK(accessibleA);
+  auto* accessibleB = dynamic_cast<DevelControl::AccessibleImpl*>(Dali::Accessibility::Accessible::Get(view.GetItem(1)));
+  DALI_TEST_CHECK(accessibleB);
+
+  accessibleA->GrabHighlight(); // == view.ScrollToItem(view.GetItemId(actorA))
+  Wait(application);
+  accessibleB->GrabHighlight(); // == view.ScrollToItem(view.GetItemId(actorB))
+  Wait(application);
+
+  Dali::Accessibility::TestEnableSC( false );
+  END_TEST;
+}
+
+int UtcDaliAccessibilityScrollToChildNonScrollable(void)
+{
+  ToolkitTestApplication application;
+  Dali::Accessibility::TestEnableSC( true );
+
+  TextLabel label = TextLabel::New("123");
+
+  auto* accessible = dynamic_cast<DevelControl::AccessibleImpl*>(Dali::Accessibility::Accessible::Get(label));
+  DALI_TEST_CHECK(accessible);
+
+  DALI_TEST_EQUALS(accessible->IsScrollable(), false, TEST_LOCATION);
+  DALI_TEST_EQUALS(accessible->ScrollToChild({}), false, TEST_LOCATION);
+
+  Dali::Accessibility::TestEnableSC( false );
+  END_TEST;
+}
\ No newline at end of file
index 8756121..fd3e72e 100644 (file)
@@ -266,6 +266,23 @@ static Dali::Actor CreateHighlightIndicatorActor()
   return actor;
 }
 
+void AccessibleImpl::ScrollToSelf()
+{
+  auto* child = this;
+  auto* parent = dynamic_cast<Toolkit::DevelControl::AccessibleImpl*>(child->GetParent());
+
+  while (parent)
+  {
+    if (parent->IsScrollable())
+    {
+      parent->ScrollToChild(child->Self());
+    }
+
+    child = parent;
+    parent = dynamic_cast<Toolkit::DevelControl::AccessibleImpl*>(parent->GetParent());
+  }
+}
+
 bool AccessibleImpl::GrabHighlight()
 {
   Dali::Actor self = Self();
@@ -295,7 +312,7 @@ bool AccessibleImpl::GrabHighlight()
   // Remember the highlight actor, so that when the default is changed with
   // SetHighlightActor(), the currently displayed highlight can still be cleared.
   currentHighlightActor = highlight;
-  EnsureSelfVisible();
+  ScrollToSelf();
   self.Add(highlight);
   SetCurrentlyHighlightedActor(self);
   EmitHighlighted(true);
@@ -402,17 +419,9 @@ std::vector<Dali::Accessibility::Relation> AccessibleImpl::GetRelationSet()
   return ret;
 }
 
-void AccessibleImpl::EnsureChildVisible(Actor child)
-{
-}
-
-void AccessibleImpl::EnsureSelfVisible()
+bool AccessibleImpl::ScrollToChild(Actor child)
 {
-  auto parent = dynamic_cast<AccessibleImpl*>(GetParent());
-  if(parent)
-  {
-    parent->EnsureChildVisible(Self());
-  }
+  return false;
 }
 
 Dali::Property::Index AccessibleImpl::GetNamePropertyIndex()
index ed09487..ab168c6 100644 (file)
@@ -62,6 +62,8 @@ protected:
     return handle;
   }
 
+  void ScrollToSelf();
+
 public:
   AccessibleImpl(Dali::Actor self, Dali::Accessibility::Role role, bool modal = false);
 
@@ -207,14 +209,9 @@ public:
 
   /**
    * @brief Makes sure that a given child of this container (e.g. ItemView) is visible
+   * @return false if scrolling is not supported or child is already visible
    */
-  virtual void EnsureChildVisible(Actor child);
-
-  /**
-   * @brief Makes sure this actor is visible (when moving the highlight frame to an
-   * actor that is scrolled out of the viewport)
-   */
-  virtual void EnsureSelfVisible();
+  virtual bool ScrollToChild(Actor child);
 
   /**
    * @brief Returns the index of the property that represents this actor's name
index ecc25b2..e9b58c8 100644 (file)
@@ -1345,11 +1345,11 @@ void ItemView::OnKeyboardFocusChangeCommitted(Actor commitedFocusableActor)
   }
 }
 
-void ItemView::AccessibleImpl::EnsureChildVisible(Actor child)
+bool ItemView::AccessibleImpl::ScrollToChild(Actor child)
 {
-  EnsureSelfVisible();
   auto itemView = Dali::Toolkit::ItemView::DownCast(Self());
   Toolkit::GetImpl(itemView).OnKeyboardFocusChangeCommitted(child);
+  return true;
 }
 
 Animation ItemView::DoAnchoring()
index 9b3d656..7e3d8c1 100644 (file)
@@ -438,7 +438,7 @@ protected:
   {
     using Scrollable::AccessibleImpl::AccessibleImpl;
 
-    void EnsureChildVisible(Actor child) override;
+    bool ScrollToChild(Actor child) override;
   };
 
   /**
index ac062ff..8ca6855 100644 (file)
@@ -1823,10 +1823,17 @@ Toolkit::ScrollView::SnapStartedSignalType& ScrollView::SnapStartedSignal()
   return mSnapStartedSignal;
 }
 
-void ScrollView::AccessibleImpl::EnsureChildVisible(Actor child)
+bool ScrollView::AccessibleImpl::ScrollToChild(Actor child)
 {
   auto scrollView = Dali::Toolkit::ScrollView::DownCast(Self());
-  scrollView.ScrollTo(child);
+  if (Toolkit::GetImpl(scrollView).FindClosestActor() == child)
+  {
+    return false;
+  }
+
+  // FIXME: ScrollTo does not work (snaps back to original position)
+  scrollView.ScrollTo(child, scrollView.GetScrollFlickDuration());
+  return true;
 }
 
 void ScrollView::FindAndUnbindActor(Actor child)
index 11ff969..aee050e 100644 (file)
@@ -790,7 +790,7 @@ protected:
   {
     using Scrollable::AccessibleImpl::AccessibleImpl;
 
-    void EnsureChildVisible(Actor child) override;
+    bool ScrollToChild(Actor child) override;
   };
 
   /**