TizenRefApp-8605 [Gallery] Implement custom accessibility highlighting 13/132013/1
authorIgor Nazarov <i.nazarov@samsung.com>
Wed, 31 May 2017 16:37:35 +0000 (19:37 +0300)
committerIgor Nazarov <i.nazarov@samsung.com>
Wed, 31 May 2017 16:37:35 +0000 (19:37 +0300)
order in ImageGrid

Change-Id: Ib0693c56a2219ea65486ee0df9f12d5a0a496045

inc/view/IImageGridListener.h
inc/view/ImageGrid.h
inc/view/helpers.h
src/view/ImageGrid.cpp
src/view/helpers.cpp

index 07227856858802677feaf9c68b8c8af0f71f54a0..3a7d2b95f08bc048d4b4cbfb0ea8869de89eb97d 100644 (file)
@@ -27,6 +27,8 @@ namespace gallery {
                virtual void onItemUnrealized(int itemIndex) = 0;
                virtual void onItemEvent(int itemIndex, int event, int x, int y) = 0;
                virtual void onTransitionFinished() {}
+               virtual Elm_Interface_Atspi_Accessible *onAccessObjectRequest(
+                               bool isFlowsTo) { return nullptr; }
        };
 }
 
index 019031d44c243b12e75b6b77411df48fe246e221..af1a65bebf3a3c1df1381e3a061a816ab23bdc44 100644 (file)
@@ -96,6 +96,7 @@ namespace gallery {
                ucl::Result isItemRealized(int itemIndex) const;
 
                ucl::Result getItemInfo(int itemIndex, ItemInfo &info) const;
+               Elm_Interface_Atspi_Accessible *getAccessObject(bool isFlowsTo);
 
                int getScrolledToItemIndex() const;
                ucl::Result scrollToItem(int itemIndex);
@@ -134,6 +135,7 @@ namespace gallery {
                void removeUnrealizeLock();
 
                void handleItemEvent(int itemIndex, int event, int x, int y) const;
+               Elm_Interface_Atspi_Accessible *getItemAtspi(int itemIndex);
 
                // Selection mode hanling
                void evalSlotSizes();
index abf8b15a9f63f713adfba55d879d24a7458a2565..58175a2adbbb4fc30ebd1761cd35aa7ac102937c 100644 (file)
@@ -37,6 +37,8 @@ namespace gallery {
        void delRotaryEventHandler(Eext_Rotary_Handler_Cb func, void *data);
 
        ucl::LayoutTheme getImageTheme(const char *fileName);
+
+       Elm_Atspi_Relation_Type getFlowRelation(Elm_Atspi_Gesture_Info gestureInfo);
 }
 
 #endif // __GALLERY_VIEW_HELPERS_H__
index 45de1f4b13fde362b251c8dec81d5667b87490a6..ae974d68489cf7eb3863c6f74ae7cf2d17085d73 100644 (file)
@@ -239,7 +239,7 @@ namespace gallery {
                public:
                        friend class RefCountObj<Item>;
                        Item(RefCountObjBase &rc,
-                                       const ImageGrid &imageGrid, ElmWidget &parent) :
+                                       ImageGrid &imageGrid, ElmWidget &parent) :
                                RefCountAware(&rc),
                                m_imageGrid(imageGrid),
                                m_btn(elm_button_add(parent)),
@@ -258,6 +258,9 @@ namespace gallery {
                                m_btn.addEventHandler(BTN_CLICKED, WEAK_DELEGATE(
                                                Item::onClicked, asWeak(*this)));
 
+                               elm_atspi_accessible_gesture_cb_set(m_btn,
+                                               CALLBACK_A(Item::onAtspiGesture), this);
+
                                m_touchParser = makeShared<TouchParser>(m_btn);
                                m_touchParser->setDoubleTapHandler(
                                                DELEGATE(Item::onDoubleTap, this));
@@ -265,6 +268,11 @@ namespace gallery {
                                                DELEGATE(Item::onTapAndHold, this));
                        }
 
+                       ~Item()
+                       {
+                               elm_atspi_accessible_gesture_cb_set(m_btn, nullptr, nullptr);
+                       }
+
                        Widget &getWidget()
                        {
                                return m_btn;
@@ -508,8 +516,39 @@ namespace gallery {
                                }
                        }
 
+                       Eina_Bool onAtspiGesture(Elm_Atspi_Gesture_Info gestureInfo,
+                                       Evas_Object *obj)
+                       {
+                               if (m_realizeIndex == -1) {
+                                       LOG_RETURN_VALUE(RES_ILLEGAL_STATE, EINA_FALSE,
+                                                       "Item is not realized!");
+                               }
+
+                               const Elm_Atspi_Relation_Type relation =
+                                               getFlowRelation(gestureInfo);
+                               if (relation == ELM_ATSPI_RELATION_NULL) {
+                                       return EINA_FALSE;
+                               }
+
+                               const int relationIndex =
+                                               ((relation == ELM_ATSPI_RELATION_FLOWS_TO) ?
+                                                       (m_realizeIndex + 1) :
+                                                       (m_realizeIndex - 1));
+
+                               auto relationObject = m_imageGrid.getItemAtspi(relationIndex);
+                               if (!relationObject) {
+                                       relationObject = m_btn.getEo();
+                               }
+
+                               elm_atspi_accessible_relationships_clear(m_btn);
+                               elm_atspi_accessible_relationship_append(m_btn,
+                                               relation, relationObject);
+
+                               return EINA_FALSE;
+                       }
+
                private:
-                       const ImageGrid &m_imageGrid;
+                       ImageGrid &m_imageGrid;
                        StyledWidget m_btn;
                        StyledWidget m_image;
                        WidgetSRef m_bgImage;
@@ -621,6 +660,11 @@ namespace gallery {
                        m_items[itemOffset]->getInfo(info);
                }
 
+               Elm_Interface_Atspi_Accessible *getItemAtspi(const int itemOffset)
+               {
+                       return m_items[itemOffset]->getWidget().getEo();
+               }
+
        private:
                void setSelected(const int itemOffset, const bool selected)
                {
@@ -1004,6 +1048,14 @@ namespace gallery {
                        });
        }
 
+       Elm_Interface_Atspi_Accessible *ImageGrid::getAccessObject(
+                       const bool isFlowsTo)
+       {
+               const int itemIndex = (isFlowsTo ? 0 : (m_itemCount - 1));
+               scrollToItem(itemIndex);
+               return getItemAtspi(itemIndex);
+       }
+
        template <class FUNC>
        Result ImageGrid::doWithItem(const int itemIndex, FUNC &&func) const
        {
@@ -1131,6 +1183,28 @@ namespace gallery {
                }
        }
 
+       Elm_Interface_Atspi_Accessible *ImageGrid::getItemAtspi(const int itemIndex)
+       {
+               if ((itemIndex < 0) || (itemIndex >= m_itemCount)) {
+                       if (m_listener) {
+                               return m_listener->onAccessObjectRequest(
+                                               (itemIndex >= m_itemCount));
+                       }
+                       return nullptr;
+               }
+
+               Elm_Interface_Atspi_Accessible *result = nullptr;
+
+               FAIL_RETURN_VALUE(doWithItem(itemIndex,
+                       [&result](Slot &slot, const int itemOffset)
+                       {
+                               result = slot.getItemAtspi(itemOffset);
+                               return RES_OK;
+                       }), nullptr, "Failed to get item Atspi!");
+
+               return result;
+       }
+
        bool ImageGrid::updateSlotCount()
        {
                const int newSlotCount = calcSlotCount();
index 402bf35481428e3dd910a9ff80de211e394301a7..14ad066acd9c5ab0bb0f55e740034d173281ac25 100644 (file)
@@ -103,4 +103,19 @@ namespace gallery {
        {
                return {"layout", "gallery_image", fileName};
        }
+
+       Elm_Atspi_Relation_Type getFlowRelation(Elm_Atspi_Gesture_Info gestureInfo)
+       {
+               switch (gestureInfo.type) {
+               case ELM_ATSPI_GESTURE_ONE_FINGER_FLICK_RIGHT:
+               case ELM_ATSPI_GESTURE_ONE_FINGER_FLICK_DOWN:
+                       return ELM_ATSPI_RELATION_FLOWS_TO;
+               case ELM_ATSPI_GESTURE_ONE_FINGER_FLICK_LEFT:
+               case ELM_ATSPI_GESTURE_ONE_FINGER_FLICK_UP:
+                       return ELM_ATSPI_RELATION_FLOWS_FROM;
+               default:
+                       break;
+               }
+               return ELM_ATSPI_RELATION_NULL;
+       }
 }