}
} // unnamed namespace
-ControlAccessible::ControlAccessible(Dali::Actor self, Dali::Accessibility::Role role, bool modal)
-: ActorAccessible(self),
- mIsModal(modal)
+ControlAccessible::ControlAccessible(Dali::Actor self)
+: ActorAccessible(self)
{
- auto control = Dali::Toolkit::Control::DownCast(Self());
+ auto control = Toolkit::Control::DownCast(self);
Internal::Control& internalControl = Toolkit::Internal::GetImplementation(control);
Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get(internalControl);
- if(controlImpl.mAccessibilityRole == Dali::Accessibility::Role::UNKNOWN)
- {
- controlImpl.mAccessibilityRole = role;
- }
- Self().PropertySetSignal().Connect(&controlImpl, [this, &controlImpl](Dali::Handle& handle, Dali::Property::Index index, Dali::Property::Value value) {
+ self.PropertySetSignal().Connect(&controlImpl, [this, &controlImpl](Dali::Handle& handle, Dali::Property::Index index, Dali::Property::Value value) {
if(this->Self() != Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
{
return;
Dali::Accessibility::States ControlAccessible::CalculateStates()
{
- Dali::Actor self = Self();
- Dali::Accessibility::States state;
- state[Dali::Accessibility::State::FOCUSABLE] = self.GetProperty<bool>(Actor::Property::KEYBOARD_FOCUSABLE);
- state[Dali::Accessibility::State::FOCUSED] = Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor() == self;
+ using Dali::Accessibility::State;
- if(self.GetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE).GetType() == Dali::Property::NONE)
- {
- state[Dali::Accessibility::State::HIGHLIGHTABLE] = false;
- }
- else
- {
- state[Dali::Accessibility::State::HIGHLIGHTABLE] = self.GetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE).Get<bool>();
- }
+ Dali::Actor self = Self();
+ Dali::Accessibility::States states;
- state[Dali::Accessibility::State::HIGHLIGHTED] = GetCurrentlyHighlightedActor() == self;
- state[Dali::Accessibility::State::ENABLED] = true;
- state[Dali::Accessibility::State::SENSITIVE] = true;
- state[Dali::Accessibility::State::VISIBLE] = self.GetProperty<bool>(Actor::Property::VISIBLE);
+ states[State::FOCUSABLE] = self.GetProperty<bool>(Actor::Property::KEYBOARD_FOCUSABLE);
+ states[State::FOCUSED] = Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor() == self;
+ states[State::HIGHLIGHTABLE] = self.GetProperty<bool>(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE);
+ states[State::HIGHLIGHTED] = GetCurrentlyHighlightedActor() == self;
+ states[State::ENABLED] = true;
+ states[State::SENSITIVE] = true;
+ states[State::VISIBLE] = self.GetProperty<bool>(Actor::Property::VISIBLE);
+ states[State::SHOWING] = IsShowing();
+ states[State::DEFUNCT] = !self.GetProperty(Dali::DevelActor::Property::CONNECTED_TO_SCENE).Get<bool>();
- if(mIsModal)
- {
- state[Dali::Accessibility::State::MODAL] = true;
- }
- state[Dali::Accessibility::State::SHOWING] = IsShowing();
- state[Dali::Accessibility::State::DEFUNCT] = !self.GetProperty(Dali::DevelActor::Property::CONNECTED_TO_SCENE).Get<bool>();
- return state;
+ return states;
}
Dali::Accessibility::States ControlAccessible::GetStates()
// Clear the old highlight.
if(oldHighlightedActor)
{
- auto oldHighlightObject = dynamic_cast<Dali::Accessibility::Component*>(Internal::Control::Impl::GetAccessibilityObject(oldHighlightedActor));
- if(oldHighlightObject)
+ auto oldHighlightedObject = Dali::Accessibility::Component::DownCast(Accessible::Get(oldHighlightedActor));
+ if(oldHighlightedObject)
{
- oldHighlightObject->ClearHighlight();
+ oldHighlightedObject->ClearHighlight();
}
}
/**
* @brief Represents the Accessible object for Dali::Toolkit::Control and derived classes
*
- * You can create a derived class (and register it using SetAccessibilityConstructor)
+ * You can create a derived class (and override Control::CreateAccessibleObject)
* in order to customize Accessibility for a given control.
*
- * @see Dali::Toolkit::DevelControl::SetAccessibilityConstructor
* @see Dali::Accessibility::Accessible
* @see Dali::Accessibility::Component
* @see Dali::Accessibility::Collection
protected:
Vector2 mLastPosition{0.0f, 0.0f};
Dali::WeakHandle<Dali::Actor> mCurrentHighlightActor;
- bool mIsModal = false;
- bool mIsRoot = false;
void ScrollToSelf();
bool IsShowing();
public:
- ControlAccessible(Dali::Actor self, Dali::Accessibility::Role role, bool modal = false);
+ ControlAccessible(Dali::Actor self);
/**
* @copydoc Dali::Accessibility::Accessible::GetName()
GetControlImplementation(control).mAccessibilityRelations.clear();
}
-void SetAccessibilityConstructor(Dali::Actor control, std::function<std::unique_ptr<Dali::Accessibility::Accessible>(Dali::Actor)> constructor)
-{
- GetControlImplementation(Toolkit::Control::DownCast(control)).mAccessibilityConstructor = constructor;
-}
-
void AppendAccessibilityAttribute(Toolkit::Control control, const std::string& key, const std::string& value)
{
GetControlImplementation(control).AppendAccessibilityAttribute(key, value);
bool ClearAccessibilityHighlight(Toolkit::Control control)
{
- auto* accessible = Dali::Accessibility::Component::DownCast(GetControlImplementation(control).GetAccessibilityObject());
-
- return accessible ? accessible->ClearHighlight() : false;
+ return GetControlImplementation(control).GetAccessibleObject()->ClearHighlight();
}
bool GrabAccessibilityHighlight(Toolkit::Control control)
{
- auto* accessible = Dali::Accessibility::Component::DownCast(GetControlImplementation(control).GetAccessibilityObject());
-
- return accessible ? accessible->GrabHighlight() : false;
+ return GetControlImplementation(control).GetAccessibleObject()->GrabHighlight();
}
Dali::Accessibility::States GetAccessibilityStates(Toolkit::Control control)
{
- auto* accessible = GetControlImplementation(control).GetAccessibilityObject();
-
- return accessible->GetStates();
+ return GetControlImplementation(control).GetAccessibleObject()->GetStates();
}
void NotifyAccessibilityStateChange(Toolkit::Control control, Dali::Accessibility::States states, bool recurse)
{
- GetControlImplementation(control).GetAccessibilityObject()->NotifyAccessibilityStateChange(std::move(states), recurse);
+ GetControlImplementation(control).GetAccessibleObject()->NotifyAccessibilityStateChange(std::move(states), recurse);
}
} // namespace DevelControl
*/
DALI_TOOLKIT_API void NotifyAccessibilityStateChange(Toolkit::Control control, Dali::Accessibility::States states, bool recurse);
-/**
- * The method allows to set specific constructor for creating accessibility structure
- *
- * Thank to this method hierarchy of accessibility objects can be based on internal hierarchy of Actors.
- * It prevents from necessity of keeping two trees synchronized.
- * The method should be called inside OnInitialize method of all classes inheriting from Control.
- *
- * Possible usage can be as follows:
- * @code
- * SetAccessibilityConstructor( []( Dali::Actor actor ) {
- return std::unique_ptr< Dali::Accessibility::Accessible >(
- new ControlAccessible( actor, Dali::Accessibility::Role::DIALOG, true ) );
- } );
- * @endcode
- *
- * param constructor callback creating Accessible object
- */
-DALI_TOOLKIT_API void SetAccessibilityConstructor(Dali::Actor control, std::function<std::unique_ptr<Dali::Accessibility::Accessible>(Dali::Actor)> constructor);
-
} // namespace DevelControl
} // namespace Toolkit
void Alignment::OnInitialize()
{
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
}
void Alignment::OnRelayout(const Vector2& size, RelayoutContainer& container)
// bind properties for / set shader constants to defaults
SetupProperties();
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::ANIMATION));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::ANIMATION);
}
void BloomView::OnSizeSet(const Vector3& targetSize)
return OnKeyboardEnter();
}
+DevelControl::ControlAccessible* Button::CreateAccessibleObject()
+{
+ return new ButtonAccessible(Self());
+}
+
bool Button::OnTouch(Actor actor, const TouchEvent& touch)
{
if(!IsDisabled() && (actor == touch.GetHitActor(0)))
return mForegroundPadding;
}
-std::string Button::AccessibleImpl::GetNameRaw() const
+std::string Button::ButtonAccessible::GetNameRaw() const
{
std::string labelText;
auto slf = Toolkit::Button::DownCast(Self());
return labelText;
}
-Property::Index Button::AccessibleImpl::GetNamePropertyIndex()
+Property::Index Button::ButtonAccessible::GetNamePropertyIndex()
{
Property::Index label = Toolkit::Button::Property::LABEL;
Property::Map labelMap = Self().GetProperty<Property::Map>(label);
}
}
-Dali::Accessibility::States Button::AccessibleImpl::CalculateStates()
+Dali::Accessibility::States Button::ButtonAccessible::CalculateStates()
{
auto tmp = DevelControl::ControlAccessible::CalculateStates();
tmp[Dali::Accessibility::State::SELECTABLE] = true;
bool OnAccessibilityActivated() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Toolkit::Control::OnKeyboardEnter()
*/
bool OnKeyboardEnter() override;
bool mClickActionPerforming; ///< Used to manage signal emissions during action
protected:
- struct AccessibleImpl : public DevelControl::ControlAccessible
+ class ButtonAccessible : public DevelControl::ControlAccessible
{
+ public:
using DevelControl::ControlAccessible::ControlAccessible;
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+ */
Dali::Accessibility::States CalculateStates() override;
- std::string GetNameRaw() const override;
- Property::Index GetNamePropertyIndex() override;
+
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetNameRaw()
+ */
+ std::string GetNameRaw() const override;
+
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetNamePropertyIndex()
+ */
+ Property::Index GetNamePropertyIndex() override;
};
};
{
Button::OnInitialize();
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::CHECK_BOX));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::CHECK_BOX);
}
-Dali::Accessibility::States CheckBoxButton::AccessibleImpl::CalculateStates()
+DevelControl::ControlAccessible* CheckBoxButton::CreateAccessibleObject()
{
- auto state = Button::AccessibleImpl::CalculateStates();
+ return new CheckBoxButton::CheckBoxButtonAccessible(Self());
+}
+
+Dali::Accessibility::States CheckBoxButton::CheckBoxButtonAccessible::CalculateStates()
+{
+ auto state = Button::ButtonAccessible::CalculateStates();
auto self = Toolkit::Button::DownCast(Self());
if(self.GetProperty<bool>(Toolkit::Button::Property::SELECTED))
{
void CheckBoxButton::OnStateChange(State newState)
{
// TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
- if(Dali::Accessibility::IsUp() && (Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self())
- && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+ if((Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
{
- Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
+ GetAccessibleObject()->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
}
}
*/
void OnInitialize() override;
+ /**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
private:
// Undefined
CheckBoxButton(const CheckBoxButton&);
CheckBoxButton& operator=(const CheckBoxButton&);
protected:
- struct AccessibleImpl : public Button::AccessibleImpl
+ class CheckBoxButtonAccessible : public Button::ButtonAccessible
{
- using Button::AccessibleImpl::AccessibleImpl;
+ public:
+ using Button::ButtonAccessible::ButtonAccessible;
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+ */
Dali::Accessibility::States CalculateStates() override;
};
+
void OnStateChange(State newState) override;
};
Actor self = Self();
self.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::PUSH_BUTTON));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::PUSH_BUTTON);
+}
+
+DevelControl::ControlAccessible* PushButton::CreateAccessibleObject()
+{
+ return new PushButtonAccessible(Self());
}
void PushButton::SetIconAlignment(const PushButton::IconAlignment iconAlignment)
return value;
}
-Dali::Accessibility::States PushButton::AccessibleImpl::CalculateStates()
+Dali::Accessibility::States PushButton::PushButtonAccessible::CalculateStates()
{
- auto state = Button::AccessibleImpl::CalculateStates();
+ auto state = Button::ButtonAccessible::CalculateStates();
auto self = Toolkit::Button::DownCast(Self());
state[Dali::Accessibility::State::PRESSED] = self.GetProperty<bool>(Toolkit::Button::Property::SELECTED);
return state;
void PushButton::OnStateChange(State newState)
{
// TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
- if(Dali::Accessibility::IsUp() && (Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self())
- && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+ if((Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
{
- Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(Dali::Accessibility::State::PRESSED, newState == SELECTED_STATE ? 1 : 0, 0);
+ auto* accessible = GetAccessibleObject();
+
+ accessible->EmitStateChanged(Dali::Accessibility::State::PRESSED, newState == SELECTED_STATE ? 1 : 0, 0);
if(Self().GetProperty<bool>(Toolkit::Button::Property::TOGGLABLE))
{
- Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
+ accessible->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
}
}
}
*/
void OnInitialize() override;
+ /**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
private:
/**
* @brief Sets the alignment mode to use to align the icon to the label.
IconAlignment mIconAlignment; ///< The alignment of the icon against the label.
protected:
- struct AccessibleImpl : public Button::AccessibleImpl
+ class PushButtonAccessible : public Button::ButtonAccessible
{
- using Button::AccessibleImpl::AccessibleImpl;
+ public:
+ using Button::ButtonAccessible::ButtonAccessible;
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+ */
Dali::Accessibility::States CalculateStates() override;
};
+
void OnStateChange(State newState) override;
};
{
Button::OnInitialize();
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::RADIO_BUTTON));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::RADIO_BUTTON);
+}
+
+DevelControl::ControlAccessible* RadioButton::CreateAccessibleObject()
+{
+ return new RadioButtonAccessible(Self());
}
bool RadioButton::OnToggleReleased()
}
// TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
- if(Dali::Accessibility::IsUp() && (Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self())
- && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+ if((Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
{
- Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
+ GetAccessibleObject()->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
}
}
-Dali::Accessibility::States RadioButton::AccessibleImpl::CalculateStates()
+Dali::Accessibility::States RadioButton::RadioButtonAccessible::CalculateStates()
{
- auto state = Button::AccessibleImpl::CalculateStates();
+ auto state = Button::ButtonAccessible::CalculateStates();
auto self = Toolkit::Button::DownCast(Self());
if(self.GetProperty<bool>(Toolkit::Button::Property::SELECTED))
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Toolkit::Internal::Button::OnStateChange
*/
void OnStateChange(State newState) override;
RadioButton& operator=(const RadioButton& origin);
protected:
- struct AccessibleImpl : public Button::AccessibleImpl
+ class RadioButtonAccessible : public Button::ButtonAccessible
{
- using Button::AccessibleImpl::AccessibleImpl;
+ public:
+ using Button::ButtonAccessible::ButtonAccessible;
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+ */
Dali::Accessibility::States CalculateStates() override;
};
};
Actor self = Self();
self.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::TOGGLE_BUTTON));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::TOGGLE_BUTTON);
+}
+
+DevelControl::ControlAccessible* ToggleButton::CreateAccessibleObject()
+{
+ return new ToggleButtonAccessible(Self());
}
void ToggleButton::SetProperty(BaseObject* object, Property::Index propertyIndex, const Property::Value& value)
RelayoutRequest();
}
-Dali::Accessibility::States ToggleButton::AccessibleImpl::CalculateStates()
+Dali::Accessibility::States ToggleButton::ToggleButtonAccessible::CalculateStates()
{
- auto states = Button::AccessibleImpl::CalculateStates();
+ auto states = Button::ButtonAccessible::CalculateStates();
auto button = Toolkit::ToggleButton::DownCast(Self());
if(button.GetProperty<int>(Toolkit::ToggleButton::Property::CURRENT_STATE_INDEX))
{
return states;
}
-std::string ToggleButton::AccessibleImpl::GetDescriptionRaw() const
+std::string ToggleButton::ToggleButtonAccessible::GetDescriptionRaw() const
{
auto button = Toolkit::ToggleButton::DownCast(Self());
auto index = button.GetProperty<int>(Toolkit::ToggleButton::Property::CURRENT_STATE_INDEX);
return tooltips[index].Get<std::string>();
}
-Property::Index ToggleButton::AccessibleImpl::GetDescriptionPropertyIndex()
+Property::Index ToggleButton::ToggleButtonAccessible::GetDescriptionPropertyIndex()
{
return Toolkit::ToggleButton::Property::TOOLTIPS;
}
void ToggleButton::OnStateChange(State newState)
{
// TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
- if(Dali::Accessibility::IsUp() && (Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
- && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+ if((Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
{
- Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged(Dali::Accessibility::State::CHECKED, mCurrentToggleIndex ? 1 : 0, 0);
- Dali::Accessibility::Accessible::Get(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::DESCRIPTION);
+ auto* accessible = GetAccessibleObject();
+
+ accessible->EmitStateChanged(Dali::Accessibility::State::CHECKED, mCurrentToggleIndex ? 1 : 0, 0);
+ accessible->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::DESCRIPTION);
}
}
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Toolkit::Internal::Button::OnRelayout
*/
void OnRelayout(const Vector2& size, RelayoutContainer& container) override;
std::vector<Toolkit::Visual::Base> mToggleDisabledSelectedVisuals; ///< Save all disabled selected visuals.
std::vector<std::string> mToggleTooltips; ///< Toggle tooltips.
unsigned int mCurrentToggleIndex; ///< The index of state.
+
protected:
- struct AccessibleImpl : public Button::AccessibleImpl
+ class ToggleButtonAccessible : public Button::ButtonAccessible
{
- using Button::AccessibleImpl::AccessibleImpl;
+ public:
+ using Button::ButtonAccessible::ButtonAccessible;
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+ */
Dali::Accessibility::States CalculateStates() override;
- std::string GetDescriptionRaw() const override;
- Property::Index GetDescriptionPropertyIndex() override;
+
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetDescriptionRaw()
+ */
+ std::string GetDescriptionRaw() const override;
+
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetDescriptionPropertyIndex()
+ */
+ Property::Index GetDescriptionPropertyIndex() override;
};
+
void OnStateChange(State newState) override;
};
// CanvasView can relayout in the OnImageReady, alternative to a signal would be to have a upcall from the Control to CanvasView
Dali::Toolkit::Control handle(GetOwner());
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::IMAGE));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::IMAGE);
Adaptor::Get().RegisterProcessor(*this, true);
}
return rect.width > 0 && rect.height > 0;
}
+Dali::Accessibility::Accessible* ExternalAccessibleGetter(Dali::Actor actor)
+{
+ auto control = Toolkit::Control::DownCast(actor);
+ if (!control)
+ {
+ return nullptr;
+ }
+
+ auto& controlImpl = Toolkit::Internal::GetImplementation(control);
+
+ return controlImpl.GetAccessibleObject();
+}
+
} // unnamed namespace
// clang-format off
mNeedToEmitResourceReady(false),
mDispatchKeyEvents(true)
{
- Dali::Accessibility::Accessible::RegisterExternalAccessibleGetter(
- [](Dali::Actor actor) -> Dali::Accessibility::Accessible* {
- return Control::Impl::GetAccessibilityObject(actor);
- });
-
- mAccessibilityConstructor = [](Dali::Actor actor) -> std::unique_ptr<Dali::Accessibility::Accessible> {
- return std::unique_ptr<Dali::Accessibility::Accessible>(new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::UNKNOWN));
- };
+ Dali::Accessibility::Accessible::RegisterExternalAccessibleGetter(&ExternalAccessibleGetter);
}
Control::Impl::~Impl()
void Control::Impl::CheckHighlightedObjectGeometry()
{
- auto accessible = dynamic_cast<Dali::Toolkit::DevelControl::ControlAccessible*>(mAccessibilityObject.get());
- if(!accessible)
- {
- DALI_LOG_ERROR("accessible is not a pointer to a DevelControl::ControlAccessible type");
- return;
- }
-
+ auto accessible = GetAccessibleObject();
auto lastPosition = accessible->GetLastPosition();
auto accessibleRect = accessible->GetExtents(Dali::Accessibility::CoordinateType::WINDOW);
auto rect = GetShowingGeometry(accessibleRect, accessible);
// notify AT-clients on outgoing moves only
if(mAccessibilityLastScreenRelativeMoveType != Dali::Accessibility::ScreenRelativeMoveType::INSIDE)
{
- mAccessibilityObject.get()->EmitMovedOutOfScreen(mAccessibilityLastScreenRelativeMoveType);
+ accessible->EmitMovedOutOfScreen(mAccessibilityLastScreenRelativeMoveType);
}
break;
}
{
controlImpl.mImpl->mAccessibilityHidden = hidden;
- auto* accessible = controlImpl.mImpl->GetAccessibilityObject();
+ auto* accessible = controlImpl.GetAccessibleObject();
auto* parent = dynamic_cast<Dali::Accessibility::ActorAccessible*>(accessible->GetParent());
if (parent)
{
mIdleCallback = nullptr;
}
-Dali::Accessibility::Accessible* Control::Impl::GetAccessibilityObject()
+Toolkit::DevelControl::ControlAccessible* Control::Impl::GetAccessibleObject()
{
- if(!mAccessibilityObject)
+ if(!mAccessibleObject)
{
- mAccessibilityObject = mAccessibilityConstructor(mControlImpl.Self());
+ mAccessibleObject.reset(mControlImpl.CreateAccessibleObject());
}
- return mAccessibilityObject.get();
-}
-Dali::Accessibility::Accessible* Control::Impl::GetAccessibilityObject(Dali::Actor actor)
-{
- if(actor)
- {
- auto control = Dali::Toolkit::Control::DownCast(actor);
- if(control)
- {
- auto controlImpl = static_cast<Internal::Control*>(&control.GetImplementation());
- return controlImpl->mImpl->GetAccessibilityObject();
- }
- }
- return nullptr;
+ return mAccessibleObject.get();
}
} // namespace Internal
void UpdateVisualProperties(const std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& properties);
/**
- * @brief Gets the current control's accessible object.
- *
- * @return The handle to Accessible object
- */
- Dali::Accessibility::Accessible* GetAccessibilityObject();
-
- /**
- * @brief Gets Accessible object handle.
- *
- * The method acquires Accessible handle from Actor object
- * @param actor Actor object
- * @return The handle to Accessible object
+ * @copydoc Dali::Toolkit::Internal::Control::GetAccessibleObject()
*/
- static Dali::Accessibility::Accessible* GetAccessibilityObject(Dali::Actor actor);
+ Toolkit::DevelControl::ControlAccessible* GetAccessibleObject();
private:
/**
Dali::Accessibility::Role mAccessibilityRole = Dali::Accessibility::Role::UNKNOWN;
std::map<Dali::Accessibility::RelationType, std::set<Accessibility::Accessible*>> mAccessibilityRelations;
- std::function<std::unique_ptr<Dali::Accessibility::Accessible>(Actor)> mAccessibilityConstructor;
- std::unique_ptr<Dali::Accessibility::Accessible> mAccessibilityObject;
+ std::unique_ptr<Toolkit::DevelControl::ControlAccessible> mAccessibleObject;
// Gesture Detection
PinchGestureDetector mPinchGestureDetector;
mChildrenRoot.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
self.Add(mChildrenRoot);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
}
void EffectsView::OnSizeSet(const Vector3& targetSize)
self.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
SetAsKeyboardFocusGroup(true);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
}
} // namespace Internal
mInternalRoot.Add(mVertBlurActor);
mInternalRoot.Add(mRenderDownsampledCamera);
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
}
void GaussianBlurView::OnSizeSet(const Vector3& targetSize)
Dali::Toolkit::Control handle(GetOwner());
handle.ResourceReadySignal().Connect(this, &ImageView::OnResourceReady);
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::IMAGE));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::IMAGE);
}
void ImageView::SetImage(const Property::Map& map)
constraint.AddSource(Source(self, Actor::Property::WORLD_SCALE));
constraint.Apply();
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
}
Magnifier::~Magnifier()
Shader shader = Shader::New(SHADER_MODEL3D_VIEW_SIMPLE_SHADER_VERT, SHADER_MODEL3D_VIEW_SIMPLE_SHADER_FRAG);
mRenderer = Renderer::New(mesh, shader);
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::IMAGE));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::IMAGE);
}
void Model3dView::LoadGeometry()
void NavigationView::OnInitialize()
{
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
}
void NavigationView::OnSceneConnection(int depth)
// enable the pan gesture which is attached to the control
EnableGestureDetection(GestureType::Value(GestureType::PAN));
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::PAGE_TAB_LIST));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::PAGE_TAB_LIST);
}
Shader PageTurnView::CreateShader(const Property::Map& shaderMap)
DevelControl::AppendAccessibilityAttribute(Toolkit::Control::DownCast(self), "sub-role", "Alert");
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(new AccessibleImpl(actor, Dali::Accessibility::Role::DIALOG, true));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::DIALOG);
+}
+
+DevelControl::ControlAccessible* Popup::CreateAccessibleObject()
+{
+ return new PopupAccessible(Self());
}
Popup::~Popup()
}
}
-std::string Popup::AccessibleImpl::GetNameRaw() const
+std::string Popup::PopupAccessible::GetNameRaw() const
{
auto popup = Toolkit::Popup::DownCast(Self());
std::string title;
return title;
}
-Dali::Accessibility::States Popup::AccessibleImpl::CalculateStates()
+Dali::Accessibility::States Popup::PopupAccessible::CalculateStates()
{
auto states = DevelControl::ControlAccessible::CalculateStates();
auto popup = Toolkit::Popup::DownCast(Self());
auto displayState = popup.GetProperty<std::string>(Toolkit::Popup::Property::DISPLAY_STATE);
states[Dali::Accessibility::State::SHOWING] = (displayState == "SHOWN" || displayState == "SHOWING");
+ states[Dali::Accessibility::State::MODAL] = true;
return states;
}
static Property::Value GetProperty(BaseObject* object, Property::Index propertyIndex);
protected:
- struct AccessibleImpl : public DevelControl::ControlAccessible
+ class PopupAccessible : public DevelControl::ControlAccessible
{
+ public:
using DevelControl::ControlAccessible::ControlAccessible;
- std::string GetNameRaw() const override;
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetNameRaw()
+ */
+ std::string GetNameRaw() const override;
+
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+ */
Dali::Accessibility::States CalculateStates() override;
};
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* Called whenever the popup layout is re-set up.
* Normally due to a change in contents.
* Note: This is only done when the popup is shown.
void ProgressBar::OnInitialize()
{
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::PROGRESS_BAR));
- });
- //Enable highightability
- Self().SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+ // Accessibility
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::PROGRESS_BAR);
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+}
+
+DevelControl::ControlAccessible* ProgressBar::CreateAccessibleObject()
+{
+ return new ProgressBarAccessible(Self());
}
void ProgressBar::OnRelayout(const Vector2& size, RelayoutContainer& container)
mValueChangedSignal.Emit(self, mProgressValue, mSecondaryProgressValue);
if(Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
{
- Control::Impl::GetAccessibilityObject(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
+ GetAccessibleObject()->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
}
RelayoutRequest();
}
}
}
-double ProgressBar::AccessibleImpl::GetMinimum() const
+double ProgressBar::ProgressBarAccessible::GetMinimum() const
{
return DEFAULT_LOWER_BOUND;
}
-double ProgressBar::AccessibleImpl::GetCurrent() const
+double ProgressBar::ProgressBarAccessible::GetCurrent() const
{
auto self = Toolkit::ProgressBar::DownCast(Self());
return self.GetProperty(Toolkit::ProgressBar::Property::PROGRESS_VALUE).Get<float>();
}
-double ProgressBar::AccessibleImpl::GetMaximum() const
+double ProgressBar::ProgressBarAccessible::GetMaximum() const
{
return DEFAULT_UPPER_BOUND;
}
-bool ProgressBar::AccessibleImpl::SetCurrent(double current)
+bool ProgressBar::ProgressBarAccessible::SetCurrent(double current)
{
if(current < GetMinimum() || current > GetMaximum())
{
return true;
}
-double ProgressBar::AccessibleImpl::GetMinimumIncrement() const
+double ProgressBar::ProgressBarAccessible::GetMinimumIncrement() const
{
return 0.0;
}
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* Get the range of the valid values the ProgressBar handle can move between
*
* @param[in] currentSize The current size of the ProgressBar
Property::Map mSecondaryProgressVisualMap; ///< To backup visual properties when switching determinate/indeterminate.
protected:
- struct AccessibleImpl : public DevelControl::ControlAccessible,
- public virtual Dali::Accessibility::Value
+ class ProgressBarAccessible : public DevelControl::ControlAccessible,
+ public virtual Dali::Accessibility::Value
{
+ public:
using DevelControl::ControlAccessible::ControlAccessible;
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMinimum()
+ */
double GetMinimum() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetCurrent()
+ */
double GetCurrent() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMaximum()
+ */
double GetMaximum() const override;
- bool SetCurrent(double) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::SetCurrent()
+ */
+ bool SetCurrent(double) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMinimumIncrement()
+ */
double GetMinimumIncrement() const override;
};
};
void ScrollBar::OnInitialize()
{
+ auto self = Self();
+
CreateDefaultIndicatorActor();
- Self().SetProperty(Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D);
+ self.SetProperty(Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D);
+
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::SCROLL_BAR);
+}
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::SCROLL_BAR));
- });
+DevelControl::ControlAccessible* ScrollBar::CreateAccessibleObject()
+{
+ return new ScrollBarAccessible(Self());
}
void ScrollBar::SetScrollPropertySource(Handle handle, Property::Index propertyScrollPosition, Property::Index propertyMinScrollPosition, Property::Index propertyMaxScrollPosition, Property::Index propertyScrollContentSize)
mScrollPositionIntervalReachedSignal.Emit(scrollableHandle.GetCurrentProperty<float>(mPropertyScrollPosition));
if(Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
{
- Control::Impl::GetAccessibilityObject(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
+ GetAccessibleObject()->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
}
}
}
return handle;
}
-double ScrollBar::AccessibleImpl::GetMinimum() const
+double ScrollBar::ScrollBarAccessible::GetMinimum() const
{
auto self = Toolkit::ScrollBar::DownCast(Self());
Handle scrollableHandle = GetImpl(self).mScrollableObject.GetHandle();
return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(self).mPropertyMinScrollPosition) : 0.0f;
}
-double ScrollBar::AccessibleImpl::GetCurrent() const
+double ScrollBar::ScrollBarAccessible::GetCurrent() const
{
auto self = Toolkit::ScrollBar::DownCast(Self());
Handle scrollableHandle = GetImpl(self).mScrollableObject.GetHandle();
return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(self).mPropertyScrollPosition) : 0.0f;
}
-double ScrollBar::AccessibleImpl::GetMaximum() const
+double ScrollBar::ScrollBarAccessible::GetMaximum() const
{
auto self = Toolkit::ScrollBar::DownCast(Self());
Handle scrollableHandle = GetImpl(self).mScrollableObject.GetHandle();
return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(self).mPropertyMaxScrollPosition) : 1.0f;
}
-bool ScrollBar::AccessibleImpl::SetCurrent(double current)
+bool ScrollBar::ScrollBarAccessible::SetCurrent(double current)
{
if(current < GetMinimum() || current > GetMaximum())
{
return true;
}
-double ScrollBar::AccessibleImpl::GetMinimumIncrement() const
+double ScrollBar::ScrollBarAccessible::GetMinimumIncrement() const
{
return 1.0;
}
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Toolkit::Control::OnPan
*/
void OnPan(const PanGesture& gesture) override;
bool mIndicatorFirstShow : 1; ///< True if the indicator has never been shown
protected:
- struct AccessibleImpl : public DevelControl::ControlAccessible,
- public virtual Dali::Accessibility::Value
+ class ScrollBarAccessible : public DevelControl::ControlAccessible,
+ public virtual Dali::Accessibility::Value
{
+ public:
using DevelControl::ControlAccessible::ControlAccessible;
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMinimum()
+ */
double GetMinimum() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetCurrent()
+ */
double GetCurrent() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMaximum()
+ */
double GetMaximum() const override;
- bool SetCurrent(double) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::SetCurrent()
+ */
+ bool SetCurrent(double) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMinimumIncrement()
+ */
double GetMinimumIncrement() const override;
};
};
// Connect wheel event
self.WheelEventSignal().Connect(this, &ItemView::OnWheelEvent);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(new AccessibleImpl(actor, Dali::Accessibility::Role::SCROLL_PANE));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::SCROLL_PANE);
+}
+
+DevelControl::ControlAccessible* ItemView::CreateAccessibleObject()
+{
+ return new ItemViewAccessible(Self());
}
ItemView::~ItemView()
}
}
-bool ItemView::AccessibleImpl::ScrollToChild(Actor child)
+bool ItemView::ItemViewAccessible::ScrollToChild(Actor child)
{
auto itemView = Dali::Toolkit::ItemView::DownCast(Self());
Toolkit::GetImpl(itemView).OnKeyboardFocusChangeCommitted(child);
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Toolkit::Control::OnAccessibilityPan()
*/
bool OnAccessibilityPan(PanGesture gesture) override;
void OnKeyboardFocusChangeCommitted(Actor commitedFocusableActor) override;
protected:
- struct AccessibleImpl : public Scrollable::AccessibleImpl
+ class ItemViewAccessible : public Scrollable::ScrollableAccessible
{
- using Scrollable::AccessibleImpl::AccessibleImpl;
+ public:
+ using Scrollable::ScrollableAccessible::ScrollableAccessible;
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::ScrollToChild()
+ */
bool ScrollToChild(Actor child) override;
};
// Connect wheel event
self.WheelEventSignal().Connect(this, &ScrollView::OnWheelEvent);
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::SCROLL_PANE));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::SCROLL_PANE);
+}
+
+DevelControl::ControlAccessible* ScrollView::CreateAccessibleObject()
+{
+ return new ScrollViewAccessible(Self());
}
void ScrollView::OnSceneConnection(int depth)
return mSnapStartedSignal;
}
-bool ScrollView::AccessibleImpl::ScrollToChild(Actor child)
+bool ScrollView::ScrollViewAccessible::ScrollToChild(Actor child)
{
auto scrollView = Dali::Toolkit::ScrollView::DownCast(Self());
if(Toolkit::GetImpl(scrollView).FindClosestActor() == child)
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc CustomActorImpl::OnSceneConnection()
*/
void OnSceneConnection(int depth) override;
void WrapPosition(Vector2& position) const;
protected:
- struct AccessibleImpl : public Scrollable::AccessibleImpl
+ class ScrollViewAccessible : public Scrollable::ScrollableAccessible
{
- using Scrollable::AccessibleImpl::AccessibleImpl;
+ public:
+ using Scrollable::ScrollableAccessible::ScrollableAccessible;
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::ScrollToChild()
+ */
bool ScrollToChild(Actor child) override;
};
{
}
-bool Scrollable::AccessibleImpl::IsScrollable() const
+bool Scrollable::ScrollableAccessible::IsScrollable() const
{
return true;
}
void Scrollable::OnInitialize()
{
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::SCROLL_PANE));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::SCROLL_PANE);
+}
+
+DevelControl::ControlAccessible* Scrollable::CreateAccessibleObject()
+{
+ return new ScrollableAccessible(Self());
}
bool Scrollable::IsOvershootEnabled() const
virtual void SetOvershootSize(const Vector2& size) = 0;
protected: // From Control
- struct AccessibleImpl : public DevelControl::ControlAccessible
+ class ScrollableAccessible : public DevelControl::ControlAccessible
{
+ public:
using DevelControl::ControlAccessible::ControlAccessible;
+ /**
+ * @copydoc Dali::Accessibility::Component::IsScrollable()
+ */
bool IsScrollable() const override;
};
*/
virtual void OnInitialize() override;
+ /**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
private:
/**
* Temporary function to override EnableScrollOvershoot functionality for overshoot
blurStrengthConstraint.AddSource(Source(self, mBlurStrengthPropertyIndex));
blurStrengthConstraint.Apply();
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
}
void ShadowView::OnChildAdd(Actor& child)
// Size the Slider actor to a default
self.SetProperty(Actor::Property::SIZE, Vector2(DEFAULT_HIT_REGION.x, DEFAULT_HIT_REGION.y));
- // Set the Slider to be highlightable in Screen Reader mode
- self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
-
// Connect to the touch signal
self.TouchedSignal().Connect(this, &Slider::OnTouch);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::SLIDER));
- });
+ // Accessibility
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::SLIDER);
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+}
+
+DevelControl::ControlAccessible* Slider::CreateAccessibleObject()
+{
+ return new SliderAccessible(Self());
}
void Slider::OnRelayout(const Vector2& size, RelayoutContainer& container)
DisplayValue(mValue, true);
if(Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
{
- Control::Impl::GetAccessibilityObject(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
+ GetAccessibleObject()->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
}
}
return value;
}
-double Slider::AccessibleImpl::GetMinimum() const
+double Slider::SliderAccessible::GetMinimum() const
{
auto self = Toolkit::Slider::DownCast(Self());
return self.GetProperty(Toolkit::Slider::Property::LOWER_BOUND).Get<float>();
}
-double Slider::AccessibleImpl::GetCurrent() const
+double Slider::SliderAccessible::GetCurrent() const
{
auto self = Toolkit::Slider::DownCast(Self());
return self.GetProperty(Toolkit::Slider::Property::VALUE).Get<float>();
}
-double Slider::AccessibleImpl::GetMaximum() const
+double Slider::SliderAccessible::GetMaximum() const
{
auto self = Toolkit::Slider::DownCast(Self());
return self.GetProperty(Toolkit::Slider::Property::UPPER_BOUND).Get<float>();
}
-bool Slider::AccessibleImpl::SetCurrent(double current)
+bool Slider::SliderAccessible::SetCurrent(double current)
{
if(current < GetMinimum() || current > GetMaximum())
return false;
return true;
}
-double Slider::AccessibleImpl::GetMinimumIncrement() const
+double Slider::SliderAccessible::GetMinimumIncrement() const
{
auto self = Toolkit::Slider::DownCast(Self());
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* Hit region touch
*
* @param[in] actor The actor the event is raised for
mSnapToMarks : 1; ///< Turn on or off snapping to marks
protected:
- struct AccessibleImpl : public DevelControl::ControlAccessible,
- public virtual Dali::Accessibility::Value
+ class SliderAccessible : public DevelControl::ControlAccessible,
+ public virtual Dali::Accessibility::Value
{
+ public:
using DevelControl::ControlAccessible::ControlAccessible;
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMinimum()
+ */
double GetMinimum() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetCurrent()
+ */
double GetCurrent() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMaximum()
+ */
double GetMaximum() const override;
- bool SetCurrent(double) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::SetCurrent()
+ */
+ bool SetCurrent(double) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Value::GetMinimumIncrement()
+ */
double GetMinimumIncrement() const override;
};
};
mBlurStrengthPropertyIndex = self.RegisterUniqueProperty("blurStrength", 0.f);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
}
void SuperBlurView::SetTexture(Texture texture)
self.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
SetAsKeyboardFocusGroup(true);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::TABLE));
- });
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::TABLE);
}
void TableView::ResizeContainers(unsigned int rows, unsigned int columns)
* limitations under the License.
*/
+// EXTERNAL INCLUDES
#include <dali/public-api/actors/layer.h>
+// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
+#include <dali-toolkit/internal/text/character-set-conversion.h>
+#include <dali-toolkit/internal/text/hidden-text.h>
#include <dali-toolkit/internal/text/text-view.h>
namespace Dali::Toolkit::Internal
}
}
+std::size_t TextControlAccessible::GetCharacterCount() const
+{
+ return GetWholeText().size();
+}
+
+std::size_t TextControlAccessible::GetCursorOffset() const
+{
+ return 0u;
+}
+
+Rect<> TextControlAccessible::GetRangeExtents(std::size_t startOffset, std::size_t endOffset, Accessibility::CoordinateType type)
+{
+ if(!ValidateRange(GetWholeText(), startOffset, endOffset))
+ {
+ return {0, 0, 0, 0};
+ }
+
+ auto rect = GetTextController()->GetTextBoundingRectangle(startOffset, endOffset - 1);
+ auto extents = GetExtents(type);
+
+ rect.x += extents.x;
+ rect.y += extents.y;
+
+ return rect;
+}
+
+Accessibility::Range TextControlAccessible::GetRangeOfSelection(std::size_t selectionIndex) const
+{
+ // Since DALi supports only one selection, indices other than 0 are ignored
+ if(selectionIndex > 0)
+ {
+ return {};
+ }
+
+ auto indices = GetTextController()->GetSelectionIndexes();
+ auto startOffset = static_cast<std::size_t>(indices.first);
+ auto endOffset = static_cast<std::size_t>(indices.second);
+ auto text = GetText(startOffset, endOffset);
+
+ return {startOffset, endOffset, text};
+}
+
+std::string TextControlAccessible::GetText(std::size_t startOffset, std::size_t endOffset) const
+{
+ auto text = GetWholeText();
+
+ if(!ValidateRange(text, startOffset, endOffset))
+ {
+ return {};
+ }
+
+ if(IsHiddenInput())
+ {
+ std::uint32_t substituteCharacterUtf32 = GetSubstituteCharacter();
+ std::string substituteCharacterUtf8;
+ std::string substituteText;
+
+ Toolkit::Text::Utf32ToUtf8(&substituteCharacterUtf32, 1, substituteCharacterUtf8);
+
+ while(substituteText.length() < endOffset - startOffset)
+ {
+ substituteText.append(substituteCharacterUtf8);
+ }
+
+ return substituteText;
+ }
+
+ return text.substr(startOffset, endOffset - startOffset);
+}
+
+Accessibility::Range TextControlAccessible::GetTextAtOffset(std::size_t offset, Accessibility::TextBoundary boundary) const
+{
+ Accessibility::Range range{};
+
+ if(IsHiddenInput())
+ {
+ // Returning empty object, as there is no possibility to parse the textfield
+ // when its content is hidden.
+ return range;
+ }
+
+ auto text = GetWholeText();
+ auto textSize = text.size();
+
+ switch(boundary)
+ {
+ case Dali::Accessibility::TextBoundary::CHARACTER:
+ {
+ if(offset < textSize)
+ {
+ range.content = text[offset];
+ range.startOffset = offset;
+ range.endOffset = offset + 1;
+ }
+ break;
+ }
+
+ case Dali::Accessibility::TextBoundary::WORD:
+ case Dali::Accessibility::TextBoundary::LINE:
+ {
+ std::vector<char> breaks(textSize, '\0');
+
+ if(boundary == Dali::Accessibility::TextBoundary::WORD)
+ {
+ Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast<const utf8_t*>(text.c_str()), textSize, "", breaks.data());
+ }
+ else
+ {
+ Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast<const utf8_t*>(text.c_str()), textSize, "", breaks.data());
+ }
+
+ std::size_t index = 0u;
+ std::size_t counter = 0u;
+
+ while(index < textSize && counter <= offset)
+ {
+ auto start = index;
+ if(breaks[index])
+ {
+ while(breaks[index])
+ {
+ index++;
+ }
+ counter++;
+ }
+ else
+ {
+ if(boundary == Dali::Accessibility::TextBoundary::WORD)
+ {
+ index++;
+ }
+ if(boundary == Dali::Accessibility::TextBoundary::LINE)
+ {
+ counter++;
+ }
+ }
+
+ if((counter > 0) && ((counter - 1) == offset))
+ {
+ range.content = text.substr(start, index - start + 1);
+ range.startOffset = start;
+ range.endOffset = index + 1;
+ }
+
+ if(boundary == Dali::Accessibility::TextBoundary::LINE)
+ {
+ index++;
+ }
+ }
+ break;
+ }
+
+ case Dali::Accessibility::TextBoundary::SENTENCE: // Not supported by default
+ case Dali::Accessibility::TextBoundary::PARAGRAPH: // Not supported by libunibreak library
+ default:
+ {
+ break;
+ }
+ }
+
+ return range;
+}
+
+bool TextControlAccessible::RemoveSelection(std::size_t selectionIndex)
+{
+ // Since DALi supports only one selection, indices other than 0 are ignored
+ if(selectionIndex > 0)
+ {
+ return false;
+ }
+
+ GetTextController()->SetSelection(0, 0);
+
+ return true;
+}
+
+bool TextControlAccessible::SetCursorOffset(std::size_t offset)
+{
+ return false;
+}
+
+bool TextControlAccessible::SetRangeOfSelection(std::size_t selectionIndex, std::size_t startOffset, std::size_t endOffset)
+{
+ // Since DALi supports only one selection, indices other than 0 are ignored
+ if(selectionIndex > 0)
+ {
+ return false;
+ }
+
+ // Lack of ValidateRange() is intentional
+
+ GetTextController()->SetSelection(startOffset, endOffset);
+
+ return true;
+}
+
+Accessibility::Hyperlink* TextControlAccessible::GetLink(std::int32_t linkIndex) const
+{
+ if(linkIndex < 0 || linkIndex >= GetLinkCount())
+ {
+ return nullptr;
+ }
+
+ auto anchor = GetTextAnchors()[linkIndex];
+
+ return Accessibility::Hyperlink::DownCast(Accessibility::Accessible::Get(anchor));
+}
+
+std::int32_t TextControlAccessible::GetLinkCount() const
+{
+ return static_cast<std::int32_t>(GetTextAnchors().size());
+}
+
+std::int32_t TextControlAccessible::GetLinkIndex(std::int32_t characterOffset) const
+{
+ return GetTextController()->GetAnchorIndex(static_cast<std::size_t>(characterOffset));
+}
+
+std::string TextControlAccessible::GetWholeText() const
+{
+ std::string text;
+
+ GetTextController()->GetText(text);
+
+ return text;
+}
+
+std::uint32_t TextControlAccessible::GetSubstituteCharacter() const
+{
+ return Toolkit::Text::STAR;
+}
+
+bool TextControlAccessible::IsHiddenInput() const
+{
+ return false;
+}
+
+bool TextControlAccessible::ValidateRange(const std::string& string, std::size_t begin, std::size_t end)
+{
+ auto size = string.size();
+
+ if(end <= begin || begin >= size || end > size)
+ {
+ return false;
+ }
+
+ // TODO: Check whether the range [begin, end) describes a valid substring:
+ // 1. It does not break multi-byte UTF-8 sequences.
+ // 2. It does not break graphemes (compound emojis, glyphs with combining characters etc.).
+
+ return true;
+}
+
+Accessibility::States EditableTextControlAccessible::CalculateStates()
+{
+ using Dali::Accessibility::State;
+
+ auto states = DevelControl::ControlAccessible::CalculateStates();
+ auto focusControl = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
+
+ states[State::EDITABLE] = true;
+ states[State::FOCUSABLE] = true;
+ states[State::FOCUSED] = (Self() == focusControl);
+
+ return states;
+}
+
+std::size_t EditableTextControlAccessible::GetCursorOffset() const
+{
+ return GetTextController()->GetCursorPosition();
+}
+
+bool EditableTextControlAccessible::SetCursorOffset(std::size_t offset)
+{
+ if(offset > GetCharacterCount())
+ {
+ return false;
+ }
+
+ GetTextController()->ResetCursorPosition(offset);
+ RequestTextRelayout();
+
+ return true;
+}
+
+bool EditableTextControlAccessible::CopyText(std::size_t startPosition, std::size_t endPosition)
+{
+ auto text = GetWholeText();
+
+ if(!ValidateRange(text, startPosition, endPosition))
+ {
+ return false;
+ }
+
+ GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
+
+ return true;
+}
+
+bool EditableTextControlAccessible::CutText(std::size_t startPosition, std::size_t endPosition)
+{
+ if(!CopyText(startPosition, endPosition))
+ {
+ return false;
+ }
+
+ return DeleteText(startPosition, endPosition);
+}
+
+bool EditableTextControlAccessible::DeleteText(std::size_t startPosition, std::size_t endPosition)
+{
+ auto text = GetWholeText();
+
+ if(!ValidateRange(text, startPosition, endPosition))
+ {
+ return false;
+ }
+
+ return SetTextContents(text.erase(startPosition, endPosition - startPosition));
+}
+
+bool EditableTextControlAccessible::InsertText(std::size_t startPosition, std::string newText)
+{
+ auto text = GetWholeText();
+
+ if(!ValidateRange(text, startPosition, startPosition + 1))
+ {
+ return false;
+ }
+
+ return SetTextContents(text.insert(startPosition, std::move(newText)));
+}
+
+bool EditableTextControlAccessible::SetTextContents(std::string newContents)
+{
+ GetTextController()->SetText(std::move(newContents));
+
+ return true;
+}
+
} // namespace Dali::Toolkit::Internal
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/atspi-interfaces/editable-text.h>
+#include <dali/devel-api/atspi-interfaces/hypertext.h>
+#include <dali/devel-api/atspi-interfaces/text.h>
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/common/vector-wrapper.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-accessible.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-anchor-devel.h>
#include <dali-toolkit/internal/text/decorator/text-decorator.h>
#include <dali-toolkit/internal/text/rendering/text-renderer.h>
#include <dali-toolkit/internal/text/text-controller.h>
#include <dali-toolkit/public-api/controls/control.h>
#include <dali-toolkit/public-api/controls/text-controls/text-editor.h>
-#include <dali/public-api/actors/actor.h>
-
-#include <dali/public-api/common/vector-wrapper.h>
namespace Dali::Toolkit::Internal
{
std::vector<Toolkit::TextAnchor>& anchorActors);
};
+class TextControlAccessible : public DevelControl::ControlAccessible,
+ public virtual Dali::Accessibility::Text,
+ public virtual Dali::Accessibility::Hypertext
+{
+public:
+ using DevelControl::ControlAccessible::ControlAccessible;
+
+ // Text
+
+ /**
+ * @copydoc Dali::Accessibility::Text::GetCharacterCount()
+ */
+ std::size_t GetCharacterCount() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::GetCursorOffset()
+ */
+ std::size_t GetCursorOffset() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::GetRangeExtents()
+ */
+ Rect<> GetRangeExtents(std::size_t startOffset, std::size_t endOffset, Accessibility::CoordinateType type) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
+ */
+ Accessibility::Range GetRangeOfSelection(std::size_t selectionIndex) const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::GetText()
+ */
+ std::string GetText(std::size_t startOffset, std::size_t endOffset) const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
+ */
+ Accessibility::Range GetTextAtOffset(std::size_t offset, Accessibility::TextBoundary boundary) const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::RemoveSelection()
+ */
+ bool RemoveSelection(std::size_t selectionIndex) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::SetCursorOffset()
+ */
+ bool SetCursorOffset(std::size_t offset) override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
+ */
+ bool SetRangeOfSelection(std::size_t selectionIndex, std::size_t startOffset, std::size_t endOffset) override;
+
+ // Hypertext
+
+ /**
+ * @copydoc Dali::Accessibility::Hypertext::GetLink()
+ */
+ Accessibility::Hyperlink* GetLink(std::int32_t linkIndex) const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Hypertext::GetLinkCount()
+ */
+ std::int32_t GetLinkCount() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Hypertext::GetLinkIndex()
+ */
+ std::int32_t GetLinkIndex(std::int32_t characterOffset) const override;
+
+protected:
+ /**
+ * @brief Gets whole text.
+ *
+ * @return The text
+ */
+ std::string GetWholeText() const;
+
+ /**
+ * @brief Gets text anchors.
+ *
+ * @return Text anchors
+ */
+ virtual const std::vector<Toolkit::TextAnchor>& GetTextAnchors() const = 0;
+
+ /**
+ * @brief Gets text controller.
+ *
+ * @return The text controller
+ */
+ virtual Toolkit::Text::ControllerPtr GetTextController() const = 0;
+
+ /**
+ * @brief Get substitute character for hidden text.
+ *
+ * @return The substitute character (Unicode codepoint)
+ */
+ virtual std::uint32_t GetSubstituteCharacter() const;
+
+ /**
+ * @brief Checks whether text should be hidden (replaced with substitute characters).
+ *
+ * @return True if text should be hidden, false otherwise
+ */
+ virtual bool IsHiddenInput() const;
+
+ /**
+ * @brief Checks whether [startPosition, endPosition) is a valid, non-empty range within a given string.
+ *
+ * @param string Source string
+ * @param begin Start index (inclusive)
+ * @param end End index (exclusive)
+ * @return true if the range is valid, false otherwise
+ */
+ static bool ValidateRange(const std::string& string, std::size_t begin, std::size_t end);
+};
+
+class EditableTextControlAccessible : public TextControlAccessible,
+ public virtual Dali::Accessibility::EditableText
+{
+public:
+ using TextControlAccessible::TextControlAccessible;
+
+ /**
+ * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
+ */
+ Accessibility::States CalculateStates() override;
+
+ // Text
+
+ /**
+ * @copydoc Dali::Accessibility::Text::GetCursorOffset()
+ */
+ std::size_t GetCursorOffset() const override;
+
+ /**
+ * @copydoc Dali::Accessibility::Text::SetCursorOffset()
+ */
+ bool SetCursorOffset(std::size_t offset) override;
+
+ // EditableText
+
+ /**
+ * @copydoc Dali::Accessibility::EditableText::CopyText()
+ */
+ bool CopyText(size_t startPosition, size_t endPosition) override;
+
+ /**
+ * @copydoc Dali::Accessibility::EditableText::CutText()
+ */
+ bool CutText(size_t startPosition, size_t endPosition) override;
+
+ /**
+ * @copydoc Dali::Accessibility::EditableText::DeleteText()
+ */
+ bool DeleteText(size_t startPosition, size_t endPosition) override;
+
+ /**
+ * @copydoc Dali::Accessibility::EditableText::InsertText()
+ */
+ bool InsertText(size_t startPosition, std::string text) override;
+
+ /**
+ * @copydoc Dali::Accessibility::EditableText::SetTextContents()
+ */
+ bool SetTextContents(std::string newContents) override;
+
+protected:
+ /**
+ * @brief Requests text relayout.
+ */
+ virtual void RequestTextRelayout() = 0;
+};
+
} // namespace Dali::Toolkit::Internal
#endif //DALI_TOOLKIT_INTERNAL_TEXT_CONTROLS_COMMON_TEXT_UTILS_H
{
Actor self = Self();
- // Enable highlightability
- self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+ // Accessibility
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::LINK);
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+}
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::LINK));
- });
+DevelControl::ControlAccessible* TextAnchor::CreateAccessibleObject()
+{
+ return new TextAnchorAccessible(Self());
}
TextAnchor::TextAnchor()
{
}
-int32_t TextAnchor::AccessibleImpl::GetEndIndex() const
+int32_t TextAnchor::TextAnchorAccessible::GetEndIndex() const
{
auto self = Toolkit::TextAnchor::DownCast(Self());
return self.GetProperty(Toolkit::TextAnchor::Property::END_CHARACTER_INDEX).Get<int>();
}
-int32_t TextAnchor::AccessibleImpl::GetStartIndex() const
+int32_t TextAnchor::TextAnchorAccessible::GetStartIndex() const
{
auto self = Toolkit::TextAnchor::DownCast(Self());
return self.GetProperty(Toolkit::TextAnchor::Property::START_CHARACTER_INDEX).Get<int>();
}
-int32_t TextAnchor::AccessibleImpl::GetAnchorCount() const
+int32_t TextAnchor::TextAnchorAccessible::GetAnchorCount() const
{
return 1;
}
-Dali::Accessibility::Accessible* TextAnchor::AccessibleImpl::GetAnchorAccessible(int32_t anchorIndex) const
+Dali::Accessibility::Accessible* TextAnchor::TextAnchorAccessible::GetAnchorAccessible(int32_t anchorIndex) const
{
- return Control::Impl::GetAccessibilityObject(Self());
+ return const_cast<TextAnchorAccessible*>(this);
}
-std::string TextAnchor::AccessibleImpl::GetAnchorUri(int32_t anchorIndex) const
+std::string TextAnchor::TextAnchorAccessible::GetAnchorUri(int32_t anchorIndex) const
{
auto self = Toolkit::TextAnchor::DownCast(Self());
return self.GetProperty(Toolkit::TextAnchor::Property::URI).Get<std::string>();
}
-bool TextAnchor::AccessibleImpl::IsValid() const
+bool TextAnchor::TextAnchorAccessible::IsValid() const
{
return !GetAnchorUri(0).empty();
}
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Control::OnPropertySet()
*/
// void OnPropertySet(Property::Index index, const Property::Value& propertyValue) override;
/**
* @brief This structure is to connect TextAnchor with Accessible functions.
*/
- struct AccessibleImpl : public DevelControl::ControlAccessible,
- public virtual Dali::Accessibility::Hyperlink
+ class TextAnchorAccessible : public DevelControl::ControlAccessible,
+ public virtual Dali::Accessibility::Hyperlink
{
+ public:
using DevelControl::ControlAccessible::ControlAccessible;
+
/**
* @copydoc Dali::Accessibility::Hyperlink::GetEndIndex()
*/
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/controls/control-devel.h>
-#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
#include <dali-toolkit/devel-api/text/rendering-backend.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
self.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT);
self.OnSceneSignal().Connect(this, &TextEditor::OnSceneConnect);
- //Enable highightability
- self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
-
DevelControl::SetInputMethodContext(*this, mInputMethodContext);
// Creates an extra control to be used as stencil buffer.
self.Add(mStencil);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::ENTRY));
- });
+ // Accessibility
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::ENTRY);
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
Accessibility::Bridge::EnabledSignal().Connect(this, &TextEditor::OnAccessibilityStatusChanged);
Accessibility::Bridge::DisabledSignal().Connect(this, &TextEditor::OnAccessibilityStatusChanged);
}
+DevelControl::ControlAccessible* TextEditor::CreateAccessibleObject()
+{
+ return new TextEditorAccessible(Self());
+}
+
void TextEditor::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
{
DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor::OnStyleChange\n");
void TextEditor::TextInserted(unsigned int position, unsigned int length, const std::string& content)
{
- if(Accessibility::IsUp())
- {
- Control::Impl::GetAccessibilityObject(Self())->EmitTextInserted(position, length, content);
- }
+ GetAccessibleObject()->EmitTextInserted(position, length, content);
}
void TextEditor::TextDeleted(unsigned int position, unsigned int length, const std::string& content)
{
- if(Accessibility::IsUp())
- {
- Control::Impl::GetAccessibilityObject(Self())->EmitTextDeleted(position, length, content);
- }
+ GetAccessibleObject()->EmitTextDeleted(position, length, content);
}
void TextEditor::CursorPositionChanged(unsigned int oldPosition, unsigned int newPosition)
{
- if(Accessibility::IsUp())
- {
- Control::Impl::GetAccessibilityObject(Self())->EmitTextCursorMoved(newPosition);
- }
+ GetAccessibleObject()->EmitTextCursorMoved(newPosition);
if((oldPosition != newPosition) && !mCursorPositionChanged)
{
}
}
-std::string TextEditor::AccessibleImpl::GetName() const
-{
- auto self = Toolkit::TextEditor::DownCast(Self());
- return self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-}
-
-std::string TextEditor::AccessibleImpl::GetText(size_t startOffset, size_t endOffset) const
-{
- if(endOffset <= startOffset)
- {
- return {};
- }
-
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-
- if(startOffset > text.size() || endOffset > text.size())
- {
- return {};
- }
-
- return text.substr(startOffset, endOffset - startOffset);
-}
-
-size_t TextEditor::AccessibleImpl::GetCharacterCount() const
-{
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-
- return text.size();
-}
-
-size_t TextEditor::AccessibleImpl::GetCursorOffset() const
-{
- auto slf = Toolkit::TextEditor::DownCast(Self());
- return Dali::Toolkit::GetImpl(slf).GetTextController()->GetCursorPosition();
-}
-
-bool TextEditor::AccessibleImpl::SetCursorOffset(size_t offset)
-{
- auto slf = Toolkit::TextEditor::DownCast(Self());
- auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
- if(offset > txt.size())
- {
- return false;
- }
-
- auto& slfImpl = Dali::Toolkit::GetImpl(slf);
- slfImpl.GetTextController()->ResetCursorPosition(offset);
- slfImpl.RequestTextRelayout();
-
- return true;
-}
-
-Dali::Accessibility::Range TextEditor::AccessibleImpl::GetTextAtOffset(size_t offset, Dali::Accessibility::TextBoundary boundary) const
-{
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
- auto textSize = text.size();
-
- auto range = Dali::Accessibility::Range{};
-
- switch(boundary)
- {
- case Dali::Accessibility::TextBoundary::CHARACTER:
- {
- if(offset < textSize)
- {
- range.content = text[offset];
- range.startOffset = offset;
- range.endOffset = offset + 1;
- }
- break;
- }
- case Dali::Accessibility::TextBoundary::WORD:
- case Dali::Accessibility::TextBoundary::LINE:
- {
- auto textString = text.c_str();
- auto breaks = std::vector<char>(textSize, 0);
-
- if(boundary == Dali::Accessibility::TextBoundary::WORD)
- {
- Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
- }
- else
- {
- Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
- }
-
- auto index = 0u;
- auto counter = 0u;
- while(index < textSize && counter <= offset)
- {
- auto start = index;
- if(breaks[index])
- {
- while(breaks[index])
- {
- index++;
- }
- counter++;
- }
- else
- {
- if(boundary == Dali::Accessibility::TextBoundary::WORD)
- {
- index++;
- }
- if(boundary == Dali::Accessibility::TextBoundary::LINE)
- {
- counter++;
- }
- }
-
- if((counter > 0) && ((counter - 1) == offset))
- {
- range.content = text.substr(start, index - start + 1);
- range.startOffset = start;
- range.endOffset = index + 1;
- }
-
- if(boundary == Dali::Accessibility::TextBoundary::LINE)
- {
- index++;
- }
- }
- break;
- }
- case Dali::Accessibility::TextBoundary::SENTENCE:
- {
- /* not supported by default */
- break;
- }
- case Dali::Accessibility::TextBoundary::PARAGRAPH:
- {
- /* Paragraph is not supported by libunibreak library */
- break;
- }
- default:
- break;
- }
-
- return range;
-}
-
-Dali::Accessibility::Range TextEditor::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex) const
-{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return {};
- }
-
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
- std::string value{};
- controller->RetrieveSelection(value);
- auto indices = controller->GetSelectionIndexes();
-
- return {static_cast<size_t>(indices.first), static_cast<size_t>(indices.second), value};
-}
-
-bool TextEditor::AccessibleImpl::RemoveSelection(size_t selectionIndex)
+std::string TextEditor::TextEditorAccessible::GetName() const
{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return false;
- }
-
- auto self = Toolkit::TextEditor::DownCast(Self());
- Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(0, 0);
- return true;
+ return GetWholeText();
}
-bool TextEditor::AccessibleImpl::SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset)
+const std::vector<Toolkit::TextAnchor>& TextEditor::TextEditorAccessible::GetTextAnchors() const
{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return false;
- }
-
- auto self = Toolkit::TextEditor::DownCast(Self());
- Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(startOffset, endOffset);
- return true;
-}
-
-Rect<> TextEditor::AccessibleImpl::GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type)
-{
- if (endOffset <= startOffset || endOffset <= 0)
- {
- return {0, 0, 0, 0};
- }
-
auto self = Toolkit::TextEditor::DownCast(Self());
- auto rect = Dali::Toolkit::GetImpl(self).GetTextController()->GetTextBoundingRectangle(startOffset, endOffset - 1);
-
- auto componentExtents = this->GetExtents(type);
- rect.x += componentExtents.x;
- rect.y += componentExtents.y;
-
- return rect;
+ return Toolkit::GetImpl(self).mAnchorActors;
}
-bool TextEditor::AccessibleImpl::CopyText(size_t startPosition, size_t endPosition)
+Toolkit::Text::ControllerPtr TextEditor::TextEditorAccessible::GetTextController() const
{
- if(endPosition <= startPosition)
- {
- return false;
- }
-
auto self = Toolkit::TextEditor::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
- Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
- return true;
+ return Toolkit::GetImpl(self).GetTextController();
}
-bool TextEditor::AccessibleImpl::CutText(size_t startPosition, size_t endPosition)
+void TextEditor::TextEditorAccessible::RequestTextRelayout()
{
- if(endPosition <= startPosition)
- {
- return false;
- }
+ auto self = Toolkit::TextEditor::DownCast(Self());
+ auto& selfImpl = Toolkit::GetImpl(self);
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
- Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
-
- self.SetProperty(Toolkit::TextEditor::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
-
- return true;
-}
-
-bool TextEditor::AccessibleImpl::DeleteText(size_t startPosition, size_t endPosition)
-{
- if(endPosition <= startPosition)
- {
- return false;
- }
-
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-
- self.SetProperty(Toolkit::TextEditor::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
-
- return true;
-}
-
-Dali::Accessibility::States TextEditor::AccessibleImpl::CalculateStates()
-{
- using namespace Dali::Accessibility;
-
- auto states = DevelControl::ControlAccessible::CalculateStates();
- states[State::EDITABLE] = true;
- states[State::FOCUSABLE] = true;
-
- Toolkit::Control focusControl = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
- if(Self() == focusControl)
- {
- states[State::FOCUSED] = true;
- }
-
- return states;
-}
-
-bool TextEditor::AccessibleImpl::InsertText(size_t startPosition, std::string text)
-{
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto insertedText = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
-
- insertedText.insert(startPosition, text);
-
- self.SetProperty(Toolkit::TextEditor::Property::TEXT, std::move(insertedText));
-
- return true;
-}
-
-bool TextEditor::AccessibleImpl::SetTextContents(std::string newContents)
-{
- auto self = Toolkit::TextEditor::DownCast(Self());
- self.SetProperty(Toolkit::TextEditor::Property::TEXT, std::move(newContents));
- return true;
-}
-
-int32_t TextEditor::AccessibleImpl::GetLinkCount() const
-{
- auto self = Toolkit::TextEditor::DownCast(Self());
- return Dali::Toolkit::GetImpl(self).mAnchorActors.size();
-}
-
-Accessibility::Hyperlink* TextEditor::AccessibleImpl::GetLink(int32_t linkIndex) const
-{
- if(linkIndex < 0 || linkIndex >= GetLinkCount())
- {
- return nullptr;
- }
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto anchorActor = Dali::Toolkit::GetImpl(self).mAnchorActors[linkIndex];
- return dynamic_cast<Accessibility::Hyperlink*>(Dali::Accessibility::Accessible::Get(anchorActor));
-}
-
-int32_t TextEditor::AccessibleImpl::GetLinkIndex(int32_t characterOffset) const
-{
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
- return controller->GetAnchorIndex(static_cast<size_t>(characterOffset));
+ selfImpl.RequestTextRelayout();
}
} // namespace Internal
#include <dali-toolkit/devel-api/controls/scroll-bar/scroll-bar.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
#include <dali-toolkit/internal/text/decorator/text-decorator.h>
#include <dali-toolkit/internal/text/rendering/text-renderer.h>
#include <dali-toolkit/internal/text/text-anchor-control-interface.h>
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Control::OnStyleChange()
*/
void OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change) override;
/**
* @brief This structure is to connect TextEditor with Accessible functions.
*/
- struct AccessibleImpl : public DevelControl::ControlAccessible,
- public virtual Dali::Accessibility::EditableText,
- public virtual Dali::Accessibility::Hypertext
+ class TextEditorAccessible : public EditableTextControlAccessible
{
- using DevelControl::ControlAccessible::ControlAccessible;
+ public:
+ using EditableTextControlAccessible::EditableTextControlAccessible;
/**
* @copydoc Dali::Accessibility::Accessible::GetName()
*/
std::string GetName() const override;
+ protected:
/**
- * @copydoc Dali::Accessibility::Text::GetText()
- */
- std::string GetText(size_t startOffset, size_t endOffset) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetCharacterCount()
- */
- size_t GetCharacterCount() const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetCursorOffset()
- */
- size_t GetCursorOffset() const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::SetCursorOffset()
- */
- bool SetCursorOffset(size_t offset) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
- */
- Accessibility::Range GetTextAtOffset(size_t offset, Accessibility::TextBoundary boundary) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
- */
- Accessibility::Range GetRangeOfSelection(size_t selectionIndex) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::RemoveSelection()
- */
- bool RemoveSelection(size_t selectionIndex) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
- */
- bool SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetRangeExtents()
- */
- Rect<> GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type) override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::CopyText()
- */
- bool CopyText(size_t startPosition, size_t endPosition) override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::CutText()
- */
- bool CutText(size_t startPosition, size_t endPosition) override;
-
- /**
- * @copydoc Dali::Accessibility::Accessible::GetStates()
- */
- Accessibility::States CalculateStates() override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::InsertText()
- */
- bool InsertText(size_t startPosition, std::string text) override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::SetTextContents()
- */
- bool SetTextContents(std::string newContents) override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::DeleteText()
- */
- bool DeleteText(size_t startPosition, size_t endPosition) override;
-
- /**
- * @copydoc Dali::Accessibility::Hypertext::GetLink()
+ * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextAnchors()
*/
- Accessibility::Hyperlink* GetLink(int32_t linkIndex) const override;
+ const std::vector<Toolkit::TextAnchor>& GetTextAnchors() const override;
/**
- * @copydoc Dali::Accessibility::Hypertext::GetLinkIndex()
+ * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextController()
*/
- int32_t GetLinkIndex(int32_t characterOffset) const override;
+ Toolkit::Text::ControllerPtr GetTextController() const override;
/**
- * @copydoc Dali::Accessibility::Hypertext::GetLinkCount()
+ * @copydoc Dali::Toolkit::Internal::EditableTextControlAccessible::RequestTextRelayout()
*/
- int32_t GetLinkCount() const override;
+ void RequestTextRelayout() override;
};
};
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-field-devel.h>
-#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
#include <dali-toolkit/devel-api/text/rendering-backend.h>
#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
#include <dali-toolkit/internal/controls/text-controls/text-field-property-handler.h>
return fieldInputStyleMask;
}
-bool IsHiddenInput(Toolkit::TextField textField)
-{
- Property::Map hiddenInputSettings = textField.GetProperty<Property::Map>(Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS);
- auto mode = hiddenInputSettings.Find(Toolkit::HiddenInput::Property::MODE);
- if(mode && (mode->Get<int>() != Toolkit::HiddenInput::Mode::HIDE_NONE))
- {
- return true;
- }
- return false;
-}
-
-char GetSubstituteCharacter(Toolkit::TextField textField)
-{
- Property::Map hiddenInputSettings = textField.GetProperty<Property::Map>(Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS);
- auto substChar = hiddenInputSettings.Find(Toolkit::HiddenInput::Property::SUBSTITUTE_CHARACTER);
- if(substChar)
- {
- return static_cast<char>(substChar->Get<int>());
- }
- return STAR;
-}
-
} // namespace
Toolkit::TextField TextField::New()
self.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT);
self.OnSceneSignal().Connect(this, &TextField::OnSceneConnect);
- //Enable highightability
- self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
-
DevelControl::SetInputMethodContext(*this, mInputMethodContext);
if(Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy)
EnableClipping();
}
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::ENTRY));
- });
+ // Accessibility
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::ENTRY);
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
Accessibility::Bridge::EnabledSignal().Connect(this, &TextField::OnAccessibilityStatusChanged);
Accessibility::Bridge::DisabledSignal().Connect(this, &TextField::OnAccessibilityStatusChanged);
}
+DevelControl::ControlAccessible* TextField::CreateAccessibleObject()
+{
+ return new TextFieldAccessible(Self());
+}
+
void TextField::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
{
DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnStyleChange\n");
void TextField::TextInserted(unsigned int position, unsigned int length, const std::string& content)
{
- if(Accessibility::IsUp())
- {
- Control::Impl::GetAccessibilityObject(Self())->EmitTextInserted(position, length, content);
- }
+ GetAccessibleObject()->EmitTextInserted(position, length, content);
}
void TextField::TextDeleted(unsigned int position, unsigned int length, const std::string& content)
{
- if(Accessibility::IsUp())
- {
- Control::Impl::GetAccessibilityObject(Self())->EmitTextDeleted(position, length, content);
- }
+ GetAccessibleObject()->EmitTextDeleted(position, length, content);
}
void TextField::CursorPositionChanged(unsigned int oldPosition, unsigned int newPosition)
{
- if(Accessibility::IsUp())
- {
- Control::Impl::GetAccessibilityObject(Self())->EmitTextCursorMoved(newPosition);
- }
+ GetAccessibleObject()->EmitTextCursorMoved(newPosition);
if((oldPosition != newPosition) && !mCursorPositionChanged)
{
return mController->GetTextPosition(startIndex, endIndex);
}
-std::string TextField::AccessibleImpl::GetName() const
+std::string TextField::TextFieldAccessible::GetName() const
{
- auto self = Toolkit::TextField::DownCast(Self());
- if(IsHiddenInput(self))
+ if(IsHiddenInput())
{
return {};
}
- return self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
-}
-
-std::string TextField::AccessibleImpl::GetText(size_t startOffset, size_t endOffset) const
-{
- if(endOffset <= startOffset)
- {
- return {};
- }
-
- auto self = Toolkit::TextField::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
-
- if(startOffset > text.size() || endOffset > text.size())
- {
- return {};
- }
- if(IsHiddenInput(self))
- {
- return std::string(endOffset - startOffset, GetSubstituteCharacter(self));
- }
- return text.substr(startOffset, endOffset - startOffset);
+ return GetWholeText();
}
-size_t TextField::AccessibleImpl::GetCharacterCount() const
+const std::vector<Toolkit::TextAnchor>& TextField::TextFieldAccessible::GetTextAnchors() const
{
auto self = Toolkit::TextField::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
- return text.size();
+ return Toolkit::GetImpl(self).mAnchorActors;
}
-size_t TextField::AccessibleImpl::GetCursorOffset() const
+Toolkit::Text::ControllerPtr TextField::TextFieldAccessible::GetTextController() const
{
auto self = Toolkit::TextField::DownCast(Self());
- return Dali::Toolkit::GetImpl(self).GetTextController()->GetCursorPosition();
-}
-
-bool TextField::AccessibleImpl::SetCursorOffset(size_t offset)
-{
- auto self = Toolkit::TextField::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
- if(offset > text.size())
- {
- return false;
- }
-
- auto& selfImpl = Dali::Toolkit::GetImpl(self);
- selfImpl.GetTextController()->ResetCursorPosition(offset);
- selfImpl.RequestTextRelayout();
-
- return true;
-}
-
-Dali::Accessibility::Range TextField::AccessibleImpl::GetTextAtOffset(
- size_t offset, Dali::Accessibility::TextBoundary boundary) const
-{
- auto self = Toolkit::TextField::DownCast(Self());
- auto range = Dali::Accessibility::Range{};
-
- if(IsHiddenInput(self))
- {
- // Returning empty object, as there is no possibility to parse the textfield
- // when its content is hidden.
- return range;
- }
-
- auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
- auto textSize = text.size();
-
- switch(boundary)
- {
- case Dali::Accessibility::TextBoundary::CHARACTER:
- {
- if(offset < textSize)
- {
- range.content = text[offset];
- range.startOffset = offset;
- range.endOffset = offset + 1;
- }
- break;
- }
- case Dali::Accessibility::TextBoundary::WORD:
- case Dali::Accessibility::TextBoundary::LINE:
- {
- auto textString = text.c_str();
- auto breaks = std::vector<char>(textSize, 0);
-
- if(boundary == Dali::Accessibility::TextBoundary::WORD)
- {
- Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
- }
- else
- {
- Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
- }
-
- auto index = 0u;
- auto counter = 0u;
- while(index < textSize && counter <= offset)
- {
- auto start = index;
- if(breaks[index])
- {
- while(breaks[index])
- {
- index++;
- }
- counter++;
- }
- else
- {
- if(boundary == Dali::Accessibility::TextBoundary::WORD)
- {
- index++;
- }
- if(boundary == Dali::Accessibility::TextBoundary::LINE)
- {
- counter++;
- }
- }
-
- if((counter > 0) && ((counter - 1) == offset))
- {
- range.content = text.substr(start, index - start + 1);
- range.startOffset = start;
- range.endOffset = index + 1;
- }
-
- if(boundary == Dali::Accessibility::TextBoundary::LINE)
- {
- index++;
- }
- }
- break;
- }
- case Dali::Accessibility::TextBoundary::SENTENCE:
- {
- /* not supported by default */
- break;
- }
- case Dali::Accessibility::TextBoundary::PARAGRAPH:
- {
- /* Paragraph is not supported by libunibreak library */
- break;
- }
- default:
- break;
- }
- return range;
+ return Toolkit::GetImpl(self).GetTextController();
}
-Dali::Accessibility::Range TextField::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex) const
+std::uint32_t TextField::TextFieldAccessible::GetSubstituteCharacter() const
{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return {};
- }
-
- auto self = Toolkit::TextField::DownCast(Self());
- auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
- auto indices = controller->GetSelectionIndexes();
-
- auto startOffset = static_cast<size_t>(indices.first);
- auto endOffset = static_cast<size_t>(indices.second);
+ auto self = Toolkit::TextField::DownCast(Self());
+ auto hiddenInputSettings = self.GetProperty<Property::Map>(Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS);
+ auto substChar = hiddenInputSettings.Find(Toolkit::HiddenInput::Property::SUBSTITUTE_CHARACTER);
- if(IsHiddenInput(self))
- {
- return {startOffset, endOffset, std::string(endOffset - startOffset, GetSubstituteCharacter(self))};
- }
-
- std::string value{};
- controller->RetrieveSelection(value);
- return {startOffset, endOffset, value};
-}
-
-bool TextField::AccessibleImpl::RemoveSelection(size_t selectionIndex)
-{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return false;
- }
-
- auto self = Toolkit::TextField::DownCast(Self());
- Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(0, 0);
- return true;
-}
-
-bool TextField::AccessibleImpl::SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset)
-{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return false;
- }
-
- auto self = Toolkit::TextField::DownCast(Self());
- Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(startOffset, endOffset);
- return true;
-}
-
-Rect<> TextField::AccessibleImpl::GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type)
-{
- if (endOffset <= startOffset || endOffset <= 0)
- {
- return {0, 0, 0, 0};
- }
-
- auto self = Toolkit::TextField::DownCast(Self());
- auto rect = Dali::Toolkit::GetImpl(self).GetTextController()->GetTextBoundingRectangle(startOffset, endOffset - 1);
-
- auto componentExtents = this->GetExtents(type);
-
- rect.x += componentExtents.x;
- rect.y += componentExtents.y;
-
- return rect;
-}
-
-bool TextField::AccessibleImpl::CopyText(size_t startPosition, size_t endPosition)
-{
- if(endPosition <= startPosition)
- {
- return false;
- }
-
- auto self = Toolkit::TextField::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
- Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
-
- return true;
-}
-
-bool TextField::AccessibleImpl::CutText(size_t startPosition, size_t endPosition)
-{
- if(endPosition <= startPosition)
- {
- return false;
- }
-
- auto self = Toolkit::TextField::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
- Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
-
- self.SetProperty(Toolkit::TextField::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
-
- return true;
-}
-
-bool TextField::AccessibleImpl::DeleteText(size_t startPosition, size_t endPosition)
-{
- if(endPosition <= startPosition)
- {
- return false;
- }
-
- auto self = Toolkit::TextField::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
-
- self.SetProperty(Toolkit::TextField::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
-
- return true;
-}
-
-Dali::Accessibility::States TextField::AccessibleImpl::CalculateStates()
-{
- using namespace Dali::Accessibility;
-
- auto states = DevelControl::ControlAccessible::CalculateStates();
-
- states[State::EDITABLE] = true;
- states[State::FOCUSABLE] = true;
-
- Toolkit::Control focusControl = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
- if(Self() == focusControl)
+ if(substChar)
{
- states[State::FOCUSED] = true;
+ return static_cast<std::uint32_t>(substChar->Get<int>());
}
- return states;
+ return TextControlAccessible::GetSubstituteCharacter();
}
-bool TextField::AccessibleImpl::InsertText(size_t startPosition, std::string text)
+bool TextField::TextFieldAccessible::IsHiddenInput() const
{
- auto self = Toolkit::TextField::DownCast(Self());
- auto insertedText = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
-
- insertedText.insert(startPosition, text);
-
- self.SetProperty(Toolkit::TextField::Property::TEXT, std::move(insertedText));
+ auto self = Toolkit::TextField::DownCast(Self());
+ auto hiddenInputSettings = self.GetProperty<Property::Map>(Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS);
+ auto mode = hiddenInputSettings.Find(Toolkit::HiddenInput::Property::MODE);
- return true;
+ return (mode && (mode->Get<int>() != Toolkit::HiddenInput::Mode::HIDE_NONE));
}
-bool TextField::AccessibleImpl::SetTextContents(std::string newContents)
+void TextField::TextFieldAccessible::RequestTextRelayout()
{
- auto self = Toolkit::TextField::DownCast(Self());
- self.SetProperty(Toolkit::TextField::Property::TEXT, std::move(newContents));
- return true;
-}
+ auto self = Toolkit::TextField::DownCast(Self());
+ auto& selfImpl = Toolkit::GetImpl(self);
-int32_t TextField::AccessibleImpl::GetLinkCount() const
-{
- auto self = Toolkit::TextField::DownCast(Self());
- return Dali::Toolkit::GetImpl(self).mAnchorActors.size();
-}
-
-Accessibility::Hyperlink* TextField::AccessibleImpl::GetLink(int32_t linkIndex) const
-{
- if(linkIndex < 0 || linkIndex >= GetLinkCount())
- {
- return nullptr;
- }
- auto self = Toolkit::TextField::DownCast(Self());
- auto anchorActor = Dali::Toolkit::GetImpl(self).mAnchorActors[linkIndex];
- return dynamic_cast<Accessibility::Hyperlink*>(Dali::Accessibility::Accessible::Get(anchorActor));
-}
-
-int32_t TextField::AccessibleImpl::GetLinkIndex(int32_t characterOffset) const
-{
- auto self = Toolkit::TextField::DownCast(Self());
- auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
- return controller->GetAnchorIndex(static_cast<size_t>(characterOffset));
+ selfImpl.RequestTextRelayout();
}
} // namespace Internal
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-field-devel.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
#include <dali-toolkit/internal/text/decorator/text-decorator.h>
#include <dali-toolkit/internal/text/rendering/text-renderer.h>
#include <dali-toolkit/internal/text/text-anchor-control-interface.h>
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Control::OnStyleChange()
*/
void OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change) override;
/**
* @brief This structure is to connect TextField with Accessible functions.
*/
- struct AccessibleImpl : public DevelControl::ControlAccessible,
- public virtual Dali::Accessibility::EditableText,
- public virtual Dali::Accessibility::Hypertext
+ class TextFieldAccessible : public EditableTextControlAccessible
{
- using DevelControl::ControlAccessible::ControlAccessible;
+ public:
+ using EditableTextControlAccessible::EditableTextControlAccessible;
/**
* @copydoc Dali::Accessibility::Accessible::GetName()
*/
std::string GetName() const override;
+ protected:
/**
- * @copydoc Dali::Accessibility::Text::GetText()
- */
- std::string GetText(size_t startOffset, size_t endOffset) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetCharacterCount()
- */
- size_t GetCharacterCount() const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetCursorOffset()
- */
- size_t GetCursorOffset() const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::SetCursorOffset()
- */
- bool SetCursorOffset(size_t offset) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
- */
- Accessibility::Range GetTextAtOffset(size_t offset, Accessibility::TextBoundary boundary) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
- */
- Accessibility::Range GetRangeOfSelection(size_t selectionIndex) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::RemoveSelection()
- */
- bool RemoveSelection(size_t selectionIndex) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
- */
- bool SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetRangeExtents()
- */
- Rect<> GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type) override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::CopyText()
- */
- bool CopyText(size_t startPosition, size_t endPosition) override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::CutText()
- */
- bool CutText(size_t startPosition, size_t endPosition) override;
-
- /**
- * @copydoc Dali::Accessibility::Accessible::GetStates()
- */
- Accessibility::States CalculateStates() override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::InsertText()
- */
- bool InsertText(size_t startPosition, std::string text) override;
-
- /**
- * @copydoc Dali::Accessibility::EditableText::SetTextContents()
+ * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextAnchors()
*/
- bool SetTextContents(std::string newContents) override;
+ const std::vector<Toolkit::TextAnchor>& GetTextAnchors() const override;
/**
- * @copydoc Dali::Accessibility::EditableText::DeleteText()
+ * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextController()
*/
- bool DeleteText(size_t startPosition, size_t endPosition) override;
+ Toolkit::Text::ControllerPtr GetTextController() const override;
/**
- * @copydoc Dali::Accessibility::Hypertext::GetLink()
+ * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetSubstituteCharacter()
*/
- Accessibility::Hyperlink* GetLink(int32_t linkIndex) const override;
+ std::uint32_t GetSubstituteCharacter() const override;
/**
- * @copydoc Dali::Accessibility::Hypertext::GetLinkIndex()
+ * @copydoc Dali::Toolkit::Internal::TextControlAccessible::IsHiddenInput()
*/
- int32_t GetLinkIndex(int32_t characterOffset) const override;
+ bool IsHiddenInput() const override;
/**
- * @copydoc Dali::Accessibility::Hypertext::GetLinkCount()
+ * @copydoc Dali::Toolkit::Internal::EditableTextControlAccessible::RequestTextRelayout()
*/
- int32_t GetLinkCount() const override;
+ void RequestTextRelayout() override;
};
};
self.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
self.SetResizePolicy(ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT);
- // Enable highlightability
- self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
-
// Enable the text ellipsis.
mController->SetTextElideEnabled(true); // If false then text larger than control will overflow
Layout::Engine& engine = mController->GetLayoutEngine();
engine.SetCursorWidth(0u); // Do not layout space for the cursor.
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new AccessibleImpl(actor, Dali::Accessibility::Role::LABEL));
- });
+ // Accessibility
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::LABEL);
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
Accessibility::Bridge::EnabledSignal().Connect(this, &TextLabel::OnAccessibilityStatusChanged);
Accessibility::Bridge::DisabledSignal().Connect(this, &TextLabel::OnAccessibilityStatusChanged);
}
+DevelControl::ControlAccessible* TextLabel::CreateAccessibleObject()
+{
+ return new TextLabelAccessible(Self());
+}
+
void TextLabel::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
{
DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextLabel::OnStyleChange\n");
return mController->GetTextPosition(startIndex, endIndex);
}
-std::string TextLabel::AccessibleImpl::GetNameRaw() const
+std::string TextLabel::TextLabelAccessible::GetNameRaw() const
{
- auto self = Toolkit::TextLabel::DownCast(Self());
- return self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
+ return GetWholeText();
}
-Property::Index TextLabel::AccessibleImpl::GetNamePropertyIndex()
+Property::Index TextLabel::TextLabelAccessible::GetNamePropertyIndex()
{
return Toolkit::TextLabel::Property::TEXT;
}
-std::string TextLabel::AccessibleImpl::GetText(size_t startOffset, size_t endOffset) const
+const std::vector<Toolkit::TextAnchor>& TextLabel::TextLabelAccessible::GetTextAnchors() const
{
- if(endOffset <= startOffset)
- {
- return {};
- }
-
auto self = Toolkit::TextLabel::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
-
- if(startOffset > text.size() || endOffset > text.size())
- {
- return {};
- }
- return text.substr(startOffset, endOffset - startOffset);
+ return Toolkit::GetImpl(self).mAnchorActors;
}
-size_t TextLabel::AccessibleImpl::GetCharacterCount() const
+Toolkit::Text::ControllerPtr TextLabel::TextLabelAccessible::GetTextController() const
{
auto self = Toolkit::TextLabel::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
-
- return text.size();
-}
-
-size_t TextLabel::AccessibleImpl::GetCursorOffset() const
-{
- return {};
-}
-
-bool TextLabel::AccessibleImpl::SetCursorOffset(size_t offset)
-{
- return {};
-}
-
-Dali::Accessibility::Range TextLabel::AccessibleImpl::GetTextAtOffset(size_t offset, Dali::Accessibility::TextBoundary boundary) const
-{
- auto self = Toolkit::TextLabel::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
- auto textSize = text.size();
- auto range = Dali::Accessibility::Range{};
-
- switch(boundary)
- {
- case Dali::Accessibility::TextBoundary::CHARACTER:
- {
- if(offset < textSize)
- {
- range.content = text[offset];
- range.startOffset = offset;
- range.endOffset = offset + 1;
- }
- break;
- }
- case Dali::Accessibility::TextBoundary::WORD:
- case Dali::Accessibility::TextBoundary::LINE:
- {
- auto textString = text.c_str();
- auto breaks = std::vector<char>(textSize, 0);
-
- if(boundary == Dali::Accessibility::TextBoundary::WORD)
- {
- Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
- }
- else
- {
- Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
- }
-
- auto index = 0u;
- auto counter = 0u;
- while(index < textSize && counter <= offset)
- {
- auto start = index;
- if(breaks[index])
- {
- while(breaks[index])
- {
- index++;
- }
- counter++;
- }
- else
- {
- if(boundary == Dali::Accessibility::TextBoundary::WORD)
- {
- index++;
- }
- if(boundary == Dali::Accessibility::TextBoundary::LINE)
- {
- counter++;
- }
- }
-
- if((counter > 0) && ((counter - 1) == offset))
- {
- range.content = text.substr(start, index - start + 1);
- range.startOffset = start;
- range.endOffset = index + 1;
- }
-
- if(boundary == Dali::Accessibility::TextBoundary::LINE)
- {
- index++;
- }
- }
- break;
- }
- case Dali::Accessibility::TextBoundary::SENTENCE:
- {
- /* not supported by default */
- break;
- }
- case Dali::Accessibility::TextBoundary::PARAGRAPH:
- {
- /* Paragraph is not supported by libunibreak library */
- break;
- }
- default:
- break;
- }
-
- return range;
-}
-
-Dali::Accessibility::Range TextLabel::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex) const
-{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return {};
- }
-
- auto self = Toolkit::TextLabel::DownCast(Self());
- auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
- std::string value{};
- controller->RetrieveSelection(value);
- auto indices = controller->GetSelectionIndexes();
-
- return {static_cast<size_t>(indices.first), static_cast<size_t>(indices.second), value};
-}
-
-bool TextLabel::AccessibleImpl::RemoveSelection(size_t selectionIndex)
-{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return false;
- }
-
- auto self = Toolkit::TextLabel::DownCast(Self());
- Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(0, 0);
- return true;
-}
-
-bool TextLabel::AccessibleImpl::SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset)
-{
- // Since DALi supports only one selection indexes higher than 0 are ignored
- if(selectionIndex > 0)
- {
- return false;
- }
-
- auto self = Toolkit::TextLabel::DownCast(Self());
- Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(startOffset, endOffset);
- return true;
-}
-
-Rect<> TextLabel::AccessibleImpl::GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type)
-{
- if (endOffset <= startOffset || endOffset <= 0)
- {
- return {0, 0, 0, 0};
- }
-
- auto self = Toolkit::TextLabel::DownCast(Self());
- auto rect = Dali::Toolkit::GetImpl(self).GetTextController()->GetTextBoundingRectangle(startOffset, endOffset - 1);
-
- auto componentExtents = this->GetExtents(type);
-
- rect.x += componentExtents.x;
- rect.y += componentExtents.y;
-
- return rect;
-}
-
-int32_t TextLabel::AccessibleImpl::GetLinkCount() const
-{
- auto self = Toolkit::TextLabel::DownCast(Self());
- return Dali::Toolkit::GetImpl(self).mAnchorActors.size();
-}
-
-Accessibility::Hyperlink* TextLabel::AccessibleImpl::GetLink(int32_t linkIndex) const
-{
- if(linkIndex < 0 || linkIndex >= GetLinkCount())
- {
- return nullptr;
- }
- auto self = Toolkit::TextLabel::DownCast(Self());
- auto anchorActor = Dali::Toolkit::GetImpl(self).mAnchorActors[linkIndex];
- return dynamic_cast<Accessibility::Hyperlink*>(Dali::Accessibility::Accessible::Get(anchorActor));
-}
-
-int32_t TextLabel::AccessibleImpl::GetLinkIndex(int32_t characterOffset) const
-{
- auto self = Toolkit::TextLabel::DownCast(Self());
- auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
- return controller->GetAnchorIndex(static_cast<size_t>(characterOffset));
+ return Toolkit::GetImpl(self).GetTextController();
}
} // namespace Internal
// INTERNAL INCLUDES
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
#include <dali-toolkit/internal/text/rendering/text-renderer.h>
#include <dali-toolkit/internal/text/text-anchor-control-interface.h>
#include <dali-toolkit/internal/text/text-control-interface.h>
void OnInitialize() override;
/**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
+ /**
* @copydoc Control::OnStyleChange()
*/
void OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change) override;
/**
* @brief This structure is to connect TextLabel with Accessible functions.
*/
- struct AccessibleImpl : public DevelControl::ControlAccessible,
- public virtual Dali::Accessibility::Text,
- public virtual Dali::Accessibility::Hypertext
+ class TextLabelAccessible : public TextControlAccessible
{
- using DevelControl::ControlAccessible::ControlAccessible;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetText()
- */
- std::string GetText(size_t startOffset, size_t endOffset) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetCharacterCount()
- */
- size_t GetCharacterCount() const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetCursorOffset()
- */
- size_t GetCursorOffset() const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::SetCursorOffset()
- */
- bool SetCursorOffset(size_t offset) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
- */
- Accessibility::Range GetTextAtOffset(size_t offset, Accessibility::TextBoundary boundary) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
- */
- Accessibility::Range GetRangeOfSelection(size_t selectionIndex) const override;
-
- /**
- * @copydoc Dali::Accessibility::Text::RemoveSelection()
- */
- bool RemoveSelection(size_t selectionIndex) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
- */
- bool SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset) override;
-
- /**
- * @copydoc Dali::Accessibility::Text::GetRangeExtents()
- */
- Rect<> GetRangeExtents(size_t startOffset, size_t endOffset, Accessibility::CoordinateType type) override;
+ public:
+ using TextControlAccessible::TextControlAccessible;
/**
* @copydoc Dali::Accessibility::Text::GetNameRaw()
*/
Property::Index GetNamePropertyIndex() override;
+ protected:
/**
- * @copydoc Dali::Accessibility::Hypertext::GetLink()
- */
- Accessibility::Hyperlink* GetLink(int32_t linkIndex) const override;
-
- /**
- * @copydoc Dali::Accessibility::Hypertext::GetLinkIndex()
+ * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextAnchors()
*/
- int32_t GetLinkIndex(int32_t characterOffset) const override;
+ const std::vector<Toolkit::TextAnchor>& GetTextAnchors() const override;
/**
- * @copydoc Dali::Accessibility::Hypertext::GetLinkCount()
+ * @copydoc Dali::Toolkit::Internal::TextControlAccessible::GetTextController()
*/
- int32_t GetLinkCount() const override;
+ Toolkit::Text::ControllerPtr GetTextController() const override;
};
};
self.SetResizePolicy(ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS);
self.SetProperty(Actor::Property::COLOR_ALPHA, 0.0f);
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::DIALOG, true));
- });
-
- //Enable highightability
+ // Accessibility
self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+ self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::DIALOG);
+}
+
+DevelControl::ControlAccessible* TextSelectionPopup::CreateAccessibleObject()
+{
+ return new TextSelectionPopupAccessible(Self());
+}
+
+Dali::Accessibility::States TextSelectionPopup::TextSelectionPopupAccessible::CalculateStates()
+{
+ auto states = ControlAccessible::CalculateStates();
+
+ states[Dali::Accessibility::State::MODAL] = true;
+
+ return states;
}
void TextSelectionPopup::HideAnimationFinished(Animation& animation)
#include <string>
// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/controls/table-view/table-view.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-selection-toolbar.h>
*/
void OnInitialize() override;
+ /**
+ * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
+ */
+ DevelControl::ControlAccessible* CreateAccessibleObject() override;
+
private: // Implementation
void HideAnimationFinished(Animation& animation);
*/
virtual ~TextSelectionPopup();
+protected:
+ class TextSelectionPopupAccessible : public DevelControl::ControlAccessible
+ {
+ public:
+ using DevelControl::ControlAccessible::ControlAccessible;
+
+ /**
+ * @copydoc DevelControl::ControlAccessible::CalculateStates()
+ */
+ Dali::Accessibility::States CalculateStates() override;
+ };
+
private:
// Undefined copy constructor and assignment operators
TextSelectionPopup(const TextSelectionPopup&);
{
SetUp();
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::TOOL_BAR));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::TOOL_BAR);
}
void TextSelectionToolbar::OnRelayout(const Vector2& size, RelayoutContainer& container)
mLayout.SetRelativeWidth(0, mLeftRelativeSpace);
mLayout.SetRelativeWidth(1, mRightRelativeSpace);
- DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::TOOL_BAR));
- });
+ Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::TOOL_BAR);
}
void ToolBar::OnChildAdd(Actor& child)
Actor self = Self();
mVideoPlayer.FinishedSignal().Connect(this, &VideoView::EmitSignalFinish);
- DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
- return std::unique_ptr<Dali::Accessibility::Accessible>(
- new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::VIDEO));
- });
-
- //Enable highightability
- Self().SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+ // Accessibility
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::VIDEO);
+ self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
//update self property
self.RegisterProperty(IS_VIDEO_VIEW_PROPERTY_NAME, true, Property::READ_WRITE);
RelayoutRequest();
}
+Toolkit::DevelControl::ControlAccessible* Control::GetAccessibleObject()
+{
+ return mImpl->GetAccessibleObject();
+}
+
void Control::EnableGestureDetection(GestureType::Value type)
{
if((type & GestureType::PINCH) && !mImpl->mPinchGestureDetector)
return false; // Accessibility zoom action is not handled by default
}
+DevelControl::ControlAccessible* Control::CreateAccessibleObject()
+{
+ return new DevelControl::ControlAccessible(Self());
+}
+
Actor Control::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
{
return Actor();
if(Accessibility::IsUp())
{
- auto self = mImpl->GetAccessibilityObject(Self());
+ auto self = GetAccessibleObject();
self->EmitFocused(focusGained);
auto parent = self->GetParent();
if(parent && !self->GetStates()[Dali::Accessibility::State::MANAGES_DESCENDANTS])
}
case Actor::Property::VISIBLE:
{
- if(Dali::Accessibility::IsUp() && !Self().GetProperty<bool>(Toolkit::DevelControl::Property::ACCESSIBILITY_HIDDEN))
- {
- Dali::Accessibility::Accessible::Get(Self())->EmitVisible(Self().GetProperty(Actor::Property::VISIBLE).Get<bool>());
- }
+ GetAccessibleObject()->EmitVisible(Self().GetProperty<bool>(Actor::Property::VISIBLE));
break;
}
}
class StyleManager;
+namespace DevelControl
+{
+class ControlAccessible;
+
+} // namespace DevelControl
+
namespace Internal
{
*/
void ClearBackground();
+ // Accessibility
+
+ /**
+ * @brief Gets the Accessible object that represents this control.
+ *
+ * This method calls CreateAccessibleObject() if necessary, so a non-null return is expected.
+ *
+ * @return The Accessible object
+ *
+ * @see CreateAccessibleObject()
+ */
+ Toolkit::DevelControl::ControlAccessible* GetAccessibleObject();
+
// Gesture Detection
/**
*/
virtual bool OnAccessibilityZoom();
+ /**
+ * @brief This method should be overriden by deriving classes when they wish to be
+ * represented by a custom Accessible object implementation.
+ *
+ * The AT-SPI infrastructure is responsible for destroying the returned object.
+ *
+ * Currently, this method is called at most once in a given Control's lifetime, when
+ * GetAccessibleObject() is called for the first time. A future version of the
+ * AT-SPI infrastructure, however, may delete the Accessible object and request a new
+ * one to be created (by calling this method) multiple times, for example during
+ * scene connection and disconnection.
+ *
+ * @return The newly created Accessible object
+ *
+ * @see GetAccessibleObject()
+ */
+ virtual DevelControl::ControlAccessible* CreateAccessibleObject();
+
// Keyboard focus
/**