//INTERNAL INCLUDES
#include <dali/devel-api/adaptor-framework/accessibility.h>
-#include <dali/public-api/adaptor-framework/window.h>
#include <dali/integration-api/debug.h>
+#include <dali/public-api/adaptor-framework/window.h>
namespace Dali
{
virtual void RemoveTopLevelWindow(Accessible* object) = 0;
/**
- * @brief Adds popup window.
+ * @brief Adds object on the top of the stack of "default label" sourcing objects.
*
- * Hierarchy of objects visible for accessibility clients is based on tree-like
- * structure created from Actors objects. This method adds new popup to the tree.
+ * @see GetDefaultLabel
*
* @param[in] object The accessible object
*/
- virtual void AddPopup(Accessible* object) = 0;
+ virtual void RegisterDefaultLabel(Accessible* object) = 0;
/**
- * @brief Removes popup window.
+ * @brief Removes object from the stack of "default label" sourcing objects.
*
- * Hierarchy of objects visible for accessibility clients is based on tree-like
- * structure created from Actors objects. This method removes previously added
- * popup window.
+ * @see GetDefaultLabel
*
* @param[in] object The accessible object
*/
- virtual void RemovePopup(Accessible* object) = 0;
+ virtual void UnregisterDefaultLabel(Accessible* object) = 0;
+
+ /**
+ * @brief Gets the top-most object from the stack of "default label" sourcing objects.
+ *
+ * The "default label" is a reading material (text) derived from an accesibility object
+ * that could be read by screen-reader immediately after the navigation context has changed
+ * (window activates, popup shows up, tab changes) and before first UI element is highlighted.
+ *
+ * @return The handler to accessibility object
+ * @note This is a Tizen only feature not present in upstream ATSPI.
+ * Feature can be enabled/disabled for particular context root object
+ * by setting value of its accessibility attribute "default_label".
+ * Following strings are valid values for "default_label" attribute: "enabled", "disabled".
+ * Any other value will be interpreted as "enabled".
+ */
+ virtual Accessible* GetDefaultLabel() const = 0;
/**
* @brief Sets name of current application which will be visible on accessibility bus.
virtual Address GetAddress();
/**
- * @brief Gets accessibility object, which is "default label" for this object.
- *
- * @return The Accessible object
- */
- virtual Accessible* GetDefaultLabel();
-
- /**
* @brief Deputes an object to perform provided gesture.
*
* @param[in] gestureInfo The structure describing the gesture
return false;
}
-Accessible* Accessible::GetDefaultLabel()
-{
- return this;
-}
-
void Accessible::NotifyAccessibilityStateChange(Dali::Accessibility::States states, bool isRecursive)
{
if(auto data = GetBridgeData())
namespace
{
-
bool SortVertically(Component* lhs, Component* rhs)
{
auto leftRect = lhs->GetExtents(CoordinateType::WINDOW);
}
std::vector<std::vector<Component*>> lines(1);
- Dali::Rect<> lineRect = (*first)->GetExtents(CoordinateType::WINDOW);
- Dali::Rect<> rect;
+ Dali::Rect<> lineRect = (*first)->GetExtents(CoordinateType::WINDOW);
+ Dali::Rect<> rect;
// Split into lines
for(auto it = first; it != children.end(); ++it)
std::ostringstream object;
auto extent = obj->GetExtents(CoordinateType::SCREEN);
object << "name: " << obj->GetName() << " extent: (" << extent.x << ", "
- << extent.y << "), [" << extent.width << ", " << extent.height << "]";
+ << extent.y << "), [" << extent.width << ", " << extent.height << "]";
return object.str();
}
return nullptr;
}
-static std::vector<Component*> GetScrollableParents(Accessible *accessible)
+static std::vector<Component*> GetScrollableParents(Accessible* accessible)
{
std::vector<Component*> scrollableParents;
while(accessible)
{
- accessible = accessible->GetParent();
+ accessible = accessible->GetParent();
auto component = dynamic_cast<Component*>(accessible);
if(component && component->IsScrollable())
{
return scrollableParents;
}
-static std::vector<Component*> GetNonDuplicatedScrollableParents(Accessible *child, Accessible *start)
+static std::vector<Component*> GetNonDuplicatedScrollableParents(Accessible* child, Accessible* start)
{
auto scrollableParentsOfChild = GetScrollableParents(child);
auto scrollableParentsOfStart = GetScrollableParents(start);
{
scrollableParentsOfChild.pop_back();
scrollableParentsOfStart.pop_back();
- }
+ }
return scrollableParentsOfChild;
}
} // anonymous namespace
-
BridgeAccessible::BridgeAccessible()
{
}
std::vector<Component*> vec;
Dali::Rect<> scrollableParentExtents;
- auto nonDuplicatedScrollableParents = GetNonDuplicatedScrollableParents(children.front(), start);
- if (!nonDuplicatedScrollableParents.empty())
+ auto nonDuplicatedScrollableParents = GetNonDuplicatedScrollableParents(children.front(), start);
+ if(!nonDuplicatedScrollableParents.empty())
{
scrollableParentExtents = nonDuplicatedScrollableParents.front()->GetExtents(CoordinateType::WINDOW);
}
children = sortedChildren;
}
-
template<class T>
struct CycleDetection
{
// 2. parent after all children in backward traversing
// 3. Nodes with roles: ATSPI_ROLE_PAGE_TAB, ATSPI_ROLE_POPUP_MENU and ATSPI_ROLE_DIALOG, only when looking for first or last element.
// Objects with those roles shouldnt be reachable, when navigating next / prev.
- bool areAllChildrenVisitedOrMovingForward= (children.size() == 0 || forward || areAllChildrenVisited);
+ bool areAllChildrenVisitedOrMovingForward = (children.size() == 0 || forward || areAllChildrenVisited);
if(!forceNext && node != start && areAllChildrenVisitedOrMovingForward && IsObjectAcceptable(node))
{
// be checked first before using the elm_layout as a node.
if(forceNext && forward)
{
- auto deputy = GetDeputyOfProxyInParent(node);
+ auto deputy = GetDeputyOfProxyInParent(node);
nextRelatedInDirection = GetObjectInRelation(deputy, RelationType::FLOWS_TO);
}
DBus::ValueOrError<Accessible*, uint32_t, std::unordered_map<std::string, std::string>> BridgeAccessible::GetDefaultLabelInfo()
{
- auto defaultLabel = FindSelf()->GetDefaultLabel();
+ auto defaultLabel = GetDefaultLabel();
+ if(defaultLabel == nullptr)
+ {
+ defaultLabel = FindSelf();
+ }
// By default, the text is taken from navigation context root's accessibility properties name and description.
return {defaultLabel, static_cast<uint32_t>(defaultLabel->GetRole()), defaultLabel->GetAttributes()};
}
class BridgeAccessible : public virtual BridgeBase
{
protected:
-
/**
* @brief Constructor.
*/
*/
enum class NeighborSearchMode
{
- NORMAL = 0, ///< Normal
- RECURSE_FROM_ROOT = 1, ///< Recurse from root
- CONTINUE_AFTER_FAILED_RECURSION = 2, ///< Continue after failed recursion
- RECURSE_TO_OUTSIDE = 3, ///< Recurse to outside
+ NORMAL = 0, ///< Normal
+ RECURSE_FROM_ROOT = 1, ///< Recurse from root
+ CONTINUE_AFTER_FAILED_RECURSION = 2, ///< Continue after failed recursion
+ RECURSE_TO_OUTSIDE = 3, ///< Recurse to outside
};
using ReadingMaterialType = DBus::ValueOrError<
*
* The "Default label" is a text that could be read by screen-reader immediately
* after the navigation context has changed (window activates, popup shows up, tab changes) and before first UI element is highlighted.
- * @return The array containing the default label, its role, and its attributes
+ * @return The array containing the Accessible object being a source of default label text, its role, and its attributes
* @note This is a Tizen only feature not present in upstream ATSPI.
* Feature can be enabled/disabled for particular context root object by setting value of its accessibility attribute "default_label".
*/
*/
Dali::Accessibility::Component* CalculateNavigableAccessibleAtPoint(Dali::Accessibility::Accessible* root, Dali::Accessibility::Point point, Dali::Accessibility::CoordinateType type, unsigned int maxRecursionDepth);
-
protected:
bool mIsScreenReaderSuppressed = false;
};
}
}
-void BridgeBase::AddPopup(Accessible* object)
-{
- if(std::find(mPopups.begin(), mPopups.end(), object) != mPopups.end())
- {
- return;
- }
- mPopups.push_back(object);
- if(IsUp())
- {
- object->Emit(WindowEvent::ACTIVATE, 0);
- }
-}
-
-void BridgeBase::RemovePopup(Accessible* object)
-{
- auto it = std::find(mPopups.begin(), mPopups.end(), object);
- if(it == mPopups.end())
- {
- return;
- }
- mPopups.erase(it);
-
- if(IsUp())
- {
- object->Emit(WindowEvent::DEACTIVATE, 0);
- if(mPopups.empty())
- {
- mApplication.mChildren.back()->Emit(WindowEvent::ACTIVATE, 0);
- }
- else
- {
- mPopups.back()->Emit(WindowEvent::ACTIVATE, 0);
- }
- }
-}
-
void BridgeBase::OnWindowVisibilityChanged(Dali::Window window, bool visible)
{
if(visible)
{
Dali::Accessibility::Bridge::GetCurrentBridge()->WindowHidden(window); // Called when Window is hidden and iconified.
}
-
}
void BridgeBase::OnWindowFocusChanged(Dali::Window window, bool focusIn)
mApplication.mChildren.push_back(windowAccessible);
SetIsOnRootLevel(windowAccessible);
+ RegisterDefaultLabel(windowAccessible);
+
Dali::Window window = Dali::DevelWindow::Get(windowAccessible->GetInternalActor());
if(window)
{
}
}
+ UnregisterDefaultLabel(windowAccessible);
+
for(auto i = 0u; i < mApplication.mChildren.size(); ++i)
{
if(mApplication.mChildren[i] == windowAccessible)
}
}
+void BridgeBase::RegisterDefaultLabel(Accessible* object)
+{
+ if(std::find(mDefaultLabels.begin(), mDefaultLabels.end(), object) == mDefaultLabels.end())
+ {
+ mDefaultLabels.push_back(object);
+ }
+}
+
+void BridgeBase::UnregisterDefaultLabel(Accessible* object)
+{
+ auto it = std::find(mDefaultLabels.begin(), mDefaultLabels.end(), object);
+ if(it != mDefaultLabels.end())
+ {
+ mDefaultLabels.erase(it);
+ }
+}
+
std::string BridgeBase::StripPrefix(const std::string& path)
{
auto size = strlen(AtspiPath);
return &mApplication;
}
- void* accessible;
+ void* accessible;
std::istringstream tmp{path};
if(!(tmp >> accessible))
{
Accessible* BridgeBase::FindSelf() const
{
- auto path = DBus::DBusServer::getCurrentObjectPath();
+ auto path = DBus::DBusServer::getCurrentObjectPath();
auto size = strlen(AtspiPath);
if(path.size() <= size)
{
*/
// EXTERNAL INCLUDES
+#include <dali/public-api/actors/layer.h>
#include <dali/public-api/dali-adaptor-version.h>
#include <dali/public-api/signals/connection-tracker.h>
-#include <dali/public-api/actors/layer.h>
#include <memory>
// INTERNAL INCLUDES
void RemoveTopLevelWindow(Dali::Accessibility::Accessible* windowAccessible) override;
/**
- * @copydoc Dali::Accessibility::Bridge::AddPopup()
+ * @copydoc Dali::Accessibility::Bridge::RegisterDefaultLabel()
+ */
+ void RegisterDefaultLabel(Dali::Accessibility::Accessible* object) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Bridge::UnregisterDefaultLabel()
*/
- void AddPopup(Dali::Accessibility::Accessible* object) override;
+ void UnregisterDefaultLabel(Dali::Accessibility::Accessible* object) override;
/**
- * @copydoc Dali::Accessibility::Bridge::RemovePopup()
+ * @copydoc Dali::Accessibility::Bridge::GetDefaultLabel()
*/
- void RemovePopup(Dali::Accessibility::Accessible* object) override;
+ Dali::Accessibility::Accessible* GetDefaultLabel() const override
+ {
+ return mDefaultLabels.empty() ? nullptr : mDefaultLabels.back();
+ }
/**
* @copydoc Dali::Accessibility::Bridge::GetApplication()
protected:
mutable AppAccessible mApplication;
- std::vector<Dali::Accessibility::Accessible*> mPopups;
+ std::vector<Dali::Accessibility::Accessible*> mDefaultLabels;
private:
-
/**
* @brief Sets an ID.
* @param[in] id An ID (integer value)
return {};
}
-Accessibility::Accessible* Accessibility::Accessible::GetDefaultLabel()
-{
- return nullptr;
-}
-
Accessibility::Address Accessibility::Accessible::GetAddress()
{
return {};
{
}
- void AddPopup(Accessibility::Accessible* object) override
+ void RegisterDefaultLabel(Accessibility::Accessible* object) override
{
}
- void RemovePopup(Accessibility::Accessible* object) override
+ void UnregisterDefaultLabel(Accessibility::Accessible* object) override
{
}
+ Dali::Accessibility::Accessible* GetDefaultLabel() const override
+ {
+ return nullptr;
+ }
+
void SetApplicationName(std::string name) override
{
}