[AT-SPI] Add notification for a11y name/description change
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-label-impl.cpp
index d1c1b1a..d02fd67 100755 (executable)
@@ -479,6 +479,8 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
   }
 }
 
+Text::ControllerPtr TextLabel::getController() { return mController; }
+
 Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index index )
 {
   Property::Value value;
@@ -719,6 +721,9 @@ void TextLabel::OnInitialize()
   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
 
@@ -729,6 +734,11 @@ void TextLabel::OnInitialize()
 
   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 ) );
+  } );
 }
 
 void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
@@ -973,6 +983,169 @@ TextLabel::~TextLabel()
 {
 }
 
+std::string TextLabel::AccessibleImpl::GetNameRaw()
+{
+  auto slf = Toolkit::TextLabel::DownCast( self );
+  return slf.GetProperty( Toolkit::TextLabel::Property::TEXT ).Get< std::string >();
+}
+
+Property::Index TextLabel::AccessibleImpl::GetNamePropertyIndex()
+{
+  return Toolkit::TextLabel::Property::TEXT;
+}
+
+std::string TextLabel::AccessibleImpl::GetText( size_t startOffset,
+                                                size_t endOffset )
+{
+  if( endOffset <= startOffset )
+    return {};
+
+  auto slf = Toolkit::TextLabel::DownCast( self );
+  auto txt =
+      slf.GetProperty( Toolkit::TextLabel::Property::TEXT ).Get< std::string >();
+
+  if( startOffset > txt.size() || endOffset > txt.size() )
+    return {};
+
+  return txt.substr( startOffset, endOffset - startOffset );
+}
+
+size_t TextLabel::AccessibleImpl::GetCharacterCount()
+{
+  auto slf = Toolkit::TextLabel::DownCast( self );
+  auto txt =
+      slf.GetProperty( Toolkit::TextLabel::Property::TEXT ).Get< std::string >();
+
+  return txt.size();
+}
+
+size_t TextLabel::AccessibleImpl::GetCaretOffset()
+{
+    return {};
+}
+
+bool TextLabel::AccessibleImpl::SetCaretOffset(size_t offset)
+{
+    return {};
+}
+
+Dali::Accessibility::Range TextLabel::AccessibleImpl::GetTextAtOffset(
+    size_t offset, Dali::Accessibility::TextBoundary boundary )
+{
+  auto slf = Toolkit::TextLabel::DownCast( self );
+  auto txt = slf.GetProperty( Toolkit::TextLabel::Property::TEXT ).Get< std::string >();
+  auto txt_size = txt.size();
+
+  auto range = Dali::Accessibility::Range{};
+
+  switch(boundary)
+  {
+    case Dali::Accessibility::TextBoundary::CHARACTER:
+      {
+        if (offset < txt_size)
+        {
+          range.content = txt[offset];
+          range.startOffset = offset;
+          range.endOffset = offset + 1;
+        }
+      }
+      break;
+    case Dali::Accessibility::TextBoundary::WORD:
+    case Dali::Accessibility::TextBoundary::LINE:
+      {
+        auto txt_c_string = txt.c_str();
+        auto breaks = std::vector< char >( txt_size, 0 );
+        if(boundary == Dali::Accessibility::TextBoundary::WORD)
+          Accessibility::Accessible::FindWordSeparationsUtf8((const utf8_t *) txt_c_string, txt_size, "", breaks.data());
+        else
+          Accessibility::Accessible::FindLineSeparationsUtf8((const utf8_t *) txt_c_string, txt_size, "", breaks.data());
+        auto index = 0u;
+        auto counter = 0u;
+        while( index < txt_size && 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 - 1) == offset)
+          {
+            range.content = txt.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 efl */
+      }
+      break;
+    case Dali::Accessibility::TextBoundary::PARAGRAPH:
+      {
+        /* Paragraph is not supported by libunibreak library */
+      }
+      break;
+    default:
+      break;
+  }
+
+  return range;
+}
+
+Dali::Accessibility::Range
+TextLabel::AccessibleImpl::GetSelection( size_t selectionNum )
+{
+  // Since DALi supports only one selection indexes higher than 0 are ignored
+  if( selectionNum > 0 )
+    return {};
+
+  auto slf = Toolkit::TextLabel::DownCast( self );
+  auto ctrl = Dali::Toolkit::GetImpl( slf ).getController();
+  std::string ret;
+  ctrl->RetrieveSelection( ret );
+  auto r = ctrl->GetSelectionIndexes();
+
+  return { static_cast<size_t>(r.first), static_cast<size_t>(r.second), ret };
+}
+
+bool TextLabel::AccessibleImpl::RemoveSelection( size_t selectionNum )
+{
+  // Since DALi supports only one selection indexes higher than 0 are ignored
+  if( selectionNum > 0 )
+    return false;
+
+  auto slf = Toolkit::TextLabel::DownCast( self );
+  Dali::Toolkit::GetImpl( slf ).getController()->SetSelection( 0, 0 );
+  return true;
+}
+
+bool TextLabel::AccessibleImpl::SetSelection( size_t selectionNum,
+                                              size_t startOffset,
+                                              size_t endOffset )
+{
+  // Since DALi supports only one selection indexes higher than 0 are ignored
+  if( selectionNum > 0 )
+    return false;
+
+  auto slf = Toolkit::TextLabel::DownCast( self );
+  Dali::Toolkit::GetImpl( slf ).getController()->SetSelection( startOffset,
+                                                               endOffset );
+  return true;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit