Implemented new class FocusManager that manages focus in MoreMenu 39/49139/8
authorAlbert Malewski <a.malewski@samsung.com>
Tue, 6 Oct 2015 15:18:14 +0000 (17:18 +0200)
committerJanusz Majnert <j.majnert@samsung.com>
Thu, 8 Oct 2015 12:10:15 +0000 (05:10 -0700)
[Issue]    https://bugs.tizen.org/jira/browse/TT-183
[Problem]  There was a problem with navigation in MoreMenu.
[Cause]    Disabled "Add to bookmarks" button was blocking moving
           the focus.
[Solution] This is a workaround (because 'custom focus chain' API
           did not work properly. I have created new class that
           stores objects to focus and implements mechanism of
           mooving the focus.
[Verify]   Launch browser > Navigate to More menu > Use arrows to
           move the focus.

Change-Id: I3942e97c3176a204fc2ccd8738344f179cf1e89b

core/CMakeLists.txt
core/Tools/FocusManager.cpp [new file with mode: 0644]
core/Tools/FocusManager.h [new file with mode: 0644]
services/MoreMenuUI/MoreMenuUI.cpp
services/MoreMenuUI/MoreMenuUI.h

index d961bf6..334c5d4 100644 (file)
@@ -38,6 +38,7 @@ set(browserCore_SRCS
     Tools/BookmarkItem.cpp
     Tools/FeedItem.cpp
     Tools/FeedChannel.cpp
+    Tools/FocusManager.cpp
     BrowserConstants.cpp
     )
 
@@ -75,6 +76,7 @@ set(browserCore_HDRS
     Tools/GeneralTools.h
     Tools/FeedItem.h
     Tools/FeedChannel.h
+    Tools/FocusManager.h
     )
 
 if(TIZEN_BUILD)
diff --git a/core/Tools/FocusManager.cpp b/core/Tools/FocusManager.cpp
new file mode 100644 (file)
index 0000000..90e5b3b
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FocusManager.h"
+#include "BrowserLogger.h"
+
+FocusManager::FocusManager()
+    : _rowTracker(0)
+    , _prevRowTracker(0)
+{
+    BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+}
+
+FocusManager::~FocusManager()
+{
+    BROWSER_LOGD("[%s:%d]", __PRETTY_FUNCTION__, __LINE__);
+}
+
+void FocusManager::startFocusManager(Evas_Object* gengrid)
+{
+    BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+    handlerDown = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_down_cb, this);
+    if (gengrid)
+        evas_object_smart_callback_add(gengrid, "item,focused", _row_tracker, this);
+}
+
+void FocusManager::stopFocusManager()
+{
+    BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+    verticalFocusVector.clear();
+    ecore_event_handler_del(handlerDown);
+}
+Eina_Bool FocusManager::_key_down_cb(void* data, int type, void* event)
+{
+    BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+    FocusManager* fm = static_cast<FocusManager*>(data);
+    Ecore_Event_Key* ev = static_cast<Ecore_Event_Key*>(event);
+    const std::string keyName = ev->keyname;
+
+    if (!keyName.compare("Up")) {
+        BROWSER_LOGD("[%s:%d] Keyname: %s", __PRETTY_FUNCTION__, __LINE__, ev->keyname);
+        if (fm->_prevRowTracker) {
+            fm->_prevRowTracker = 0;
+            return EINA_FALSE;
+        }
+        if (fm->focusListIterator == fm->verticalFocusVector.begin()) {
+            elm_object_focus_set(*(fm->focusListIterator), EINA_TRUE);
+            return EINA_FALSE;
+        }
+        --(fm->focusListIterator);
+        if (elm_object_disabled_get(*(fm->focusListIterator)) == EINA_TRUE)
+            --(fm->focusListIterator);
+        elm_object_focus_set(*(fm->focusListIterator), EINA_TRUE);
+        return EINA_TRUE;
+    }
+    else if (!keyName.compare("Down")) {
+        BROWSER_LOGD("[%s:%d] Keyname: %s", __PRETTY_FUNCTION__, __LINE__, ev->keyname);
+        if (fm->focusListIterator == fm->verticalFocusVector.end()-1) {
+            elm_object_focus_set(*(fm->focusListIterator), EINA_TRUE);
+            return EINA_FALSE;
+        }
+        ++(fm->focusListIterator);
+        if (elm_object_disabled_get(*(fm->focusListIterator)) == EINA_TRUE)
+            ++(fm->focusListIterator);
+        elm_object_focus_set(*(fm->focusListIterator), EINA_TRUE);
+        return EINA_TRUE;
+    }
+    return EINA_FALSE;
+}
+
+void FocusManager::_row_tracker(void* data, Evas_Object*, void* event)
+{
+    BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+    FocusManager* fm = static_cast<FocusManager*>(data);
+    Elm_Object_Item* it = static_cast<Elm_Object_Item*>(event);
+    unsigned int x, y;
+    elm_gengrid_item_pos_get(it, &x, &y);
+    fm->_prevRowTracker = fm->_rowTracker;
+    fm->_rowTracker = y;
+    BROWSER_LOGD("[%s:%d] prev Y:%d, Actual Y:%d", __PRETTY_FUNCTION__, __LINE__, fm->_prevRowTracker, fm->_rowTracker);
+}
+
+void FocusManager::addItem(Evas_Object* it)
+{
+    BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+    verticalFocusVector.push_back(it);
+}
+
+void FocusManager::setIterator()
+{
+    BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+    focusListIterator = verticalFocusVector.begin();
+}
diff --git a/core/Tools/FocusManager.h b/core/Tools/FocusManager.h
new file mode 100644 (file)
index 0000000..1d4b7db
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FOCUSMANAGER_H
+#define FOCUSMANAGER_H
+
+#include <Evas.h>
+#include <Ecore.h>
+#include <Elementary.h>
+#include <vector>
+
+class FocusManager
+{
+public:
+    FocusManager();
+    ~FocusManager();
+
+    /**
+     *  This function runs FocusManager. Set the gengrid as the parameter of this function to run _raw_tracker. If the view does not have gengrid, set nullptr.
+     *  Before you call this function, add Evas_Object elements to verticalFocusVector using addItem(Evas_Object*) function and set focusListIterator using setIterator() function.
+     */
+    void startFocusManager(Evas_Object*);
+
+    /**
+     *  This function stops FocusManager.
+     */
+    void stopFocusManager();
+
+    /**
+     *  Use this function to add Evas_Object to FocusManager. The order matters.
+     */
+    void addItem(Evas_Object*);
+
+    /**
+     *  Use this function set focusListIterator. Call it after adding items. This function sets iterator at the beginnig of the verticalFocusVector.
+     */
+    void setIterator();
+private:
+    static Eina_Bool _key_down_cb(void *data, int type, void *event);
+    static void _row_tracker(void *data, Evas_Object *obj, void *event);
+
+    std::vector<Evas_Object*> verticalFocusVector;
+    std::vector<Evas_Object*>::iterator focusListIterator;
+    unsigned int _rowTracker, _prevRowTracker;
+    Ecore_Event_Handler* handlerDown;
+    Evas_Object* _gen;
+};
+
+#endif // FOCUSMANAGER_H
+
index c5e9bac..a550e06 100644 (file)
@@ -98,6 +98,7 @@ void MoreMenuUI::showUI()
     addItems();
     evas_object_show(m_mm_layout);
     evas_object_show(elm_object_part_content_get(m_mm_layout,"current_tab_bar"));
+    m_focusManager.startFocusManager(m_gengrid);
     evas_object_show(m_gengrid);
     setFocus(EINA_TRUE);
 }
@@ -111,6 +112,7 @@ void MoreMenuUI::hideUI()
     evas_object_hide(elm_object_part_content_get(m_mm_layout,"current_tab_bar"));
     clearItems();
     evas_object_del(m_gengrid);
+    m_focusManager.stopFocusManager();
 }
 
 
@@ -148,6 +150,7 @@ void MoreMenuUI::createGengrid()
     evas_object_size_hint_weight_set(m_gengrid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
     evas_object_size_hint_align_set(m_gengrid, EVAS_HINT_FILL, EVAS_HINT_FILL);
     elm_gengrid_item_size_set(m_gengrid, 364 * efl_scale, 320 * efl_scale);
+    evas_object_show(m_gengrid);
 }
 
 void MoreMenuUI::showCurrentTab()
@@ -167,11 +170,13 @@ void MoreMenuUI::showCurrentTab()
 
     m_bookmarkButton = elm_button_add(m_mm_layout);
     elm_object_style_set(m_bookmarkButton, "hidden_button");
+    evas_object_show(m_bookmarkButton);
     evas_object_smart_callback_add(m_bookmarkButton, "clicked", _star_clicked, this);
 
     m_bookmarkIcon = elm_icon_add(m_mm_layout);
     elm_object_part_content_set(m_current_tab_bar, "bookmark_ico", m_bookmarkIcon);
     elm_object_part_content_set(m_current_tab_bar, "star_click", m_bookmarkButton);
+    createFocusVector();
 }
 
 void MoreMenuUI::setFavIcon(std::shared_ptr<tizen_browser::tools::BrowserImage> favicon)
@@ -566,5 +571,14 @@ void MoreMenuUI::setFocus(Eina_Bool focusable)
         elm_object_focus_set(elm_object_part_content_get(m_current_tab_bar, "close_click"), focusable);
 }
 
+void MoreMenuUI::createFocusVector()
+{
+    BROWSER_LOGD("[%s:%d]", __PRETTY_FUNCTION__, __LINE__);
+    m_focusManager.addItem(elm_object_part_content_get(m_current_tab_bar, "close_click"));
+    m_focusManager.addItem(m_bookmarkButton);
+    m_focusManager.addItem(m_gengrid);
+    m_focusManager.setIterator();
+}
+
 }
 }
index e9edc23..f60d7af 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "BookmarkItem.h"
 #include "services/HistoryService/HistoryItem.h"
+#include "FocusManager.h"
 
 namespace tizen_browser{
 namespace base_ui{
@@ -98,6 +99,7 @@ private:
     static Evas_Object * _grid_content_get(void *data, Evas_Object *obj, const char *part);
     static void _thumbSelected(void * data, Evas_Object * obj, void * event_info);
     static void _exitClicked();
+    void createFocusVector();
 
     void setDocIcon();
 
@@ -122,6 +124,7 @@ private:
     bool m_gengridSetup;
     bool m_desktopMode;
     Eina_Bool m_isBookmark;
+    FocusManager m_focusManager;
 };
 
 }