From: Artur Świgoń Date: Tue, 15 Jun 2021 18:09:51 +0000 (+0200) Subject: [AT-SPI] Sort children spatially in navigation X-Git-Tag: dali_2.0.34~8 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git;a=commitdiff_plain;h=5594e51c7dd944ee07bfa0a13d313b5196530f26 [AT-SPI] Sort children spatially in navigation Without this patch, the navigation order reflects the order of adding actors to the scene, and only by coincidence is this correct in most cases. Change-Id: I401adeb960963a4b2b04ce9538eec7800250a841 --- diff --git a/dali/internal/accessibility/bridge/bridge-accessible.cpp b/dali/internal/accessibility/bridge/bridge-accessible.cpp index 4fcd582..309be51 100644 --- a/dali/internal/accessibility/bridge/bridge-accessible.cpp +++ b/dali/internal/accessibility/bridge/bridge-accessible.cpp @@ -19,6 +19,7 @@ #include // EXTERNAL INCLUDES +#include #include //comment out 2 lines below to get more logs @@ -29,6 +30,72 @@ using namespace Dali::Accessibility; #define GET_NAVIGABLE_AT_POINT_MAX_RECURSION_DEPTH 10000 +namespace { + +bool SortVertically(Component* lhs, Component* rhs) +{ + auto leftRect = lhs->GetExtents(CoordType::WINDOW); + auto rightRect = rhs->GetExtents(CoordType::WINDOW); + + return leftRect.y < rightRect.y; +} + +bool SortHorizontally(Component* lhs, Component* rhs) +{ + auto leftRect = lhs->GetExtents(CoordType::WINDOW); + auto rightRect = rhs->GetExtents(CoordType::WINDOW); + + return leftRect.x < rightRect.x; +} + +std::vector> SplitLines(const std::vector& children) +{ + // Find first with non-zero area + auto first = std::find_if(children.begin(), children.end(), [](Component* component) -> bool { + auto extents = component->GetExtents(CoordType::WINDOW); + return extents.height != 0.0f && extents.width != 0.0f; + }); + + if(first == children.end()) + { + return {}; + } + + std::vector> lines(1); + Dali::Rect<> lineRect = (*first)->GetExtents(CoordType::WINDOW); + Dali::Rect<> rect; + + // Split into lines + for(auto it = first; it != children.end(); ++it) + { + auto child = *it; + + rect = child->GetExtents(CoordType::WINDOW); + if(rect.height == 0.0f || rect.width == 0.0f) + { + // Zero area, ignore + continue; + } + + if(lineRect.y + (0.25 * lineRect.height) >= rect.y) + { + // Same line + lines.back().push_back(child); + } + else + { + // Start a new line + lineRect = rect; + lines.emplace_back(); + lines.back().push_back(child); + } + } + + return lines; +} + +} // anonymous namespace + BridgeAccessible::BridgeAccessible() { } @@ -356,7 +423,26 @@ Accessible* BridgeAccessible::GetCurrentlyHighlighted() std::vector BridgeAccessible::ValidChildrenGet(const std::vector& children, Accessible* start, Accessible* root) { - return children; + std::vector vec; + std::vector ret; + + for(auto child : children) + { + if(auto* component = dynamic_cast(child); component) + { + vec.push_back(component); + } + } + + std::sort(vec.begin(), vec.end(), &SortVertically); + + for(auto& line : SplitLines(vec)) + { + std::sort(line.begin(), line.end(), &SortHorizontally); + ret.insert(ret.end(), line.begin(), line.end()); + } + + return ret; } static bool DeputyIs(Accessible* obj)