From: Albert Malewski Date: Tue, 6 Oct 2015 15:18:14 +0000 (+0200) Subject: Implemented new class FocusManager that manages focus in MoreMenu X-Git-Tag: accepted/tizen/tv/20151012.223346~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F39%2F49139%2F8;p=profile%2Ftv%2Fapps%2Fweb%2Fbrowser.git Implemented new class FocusManager that manages focus in MoreMenu [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 --- diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index d961bf6..334c5d4 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -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 index 0000000..90e5b3b --- /dev/null +++ b/core/Tools/FocusManager.cpp @@ -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(data); + Ecore_Event_Key* ev = static_cast(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(data); + Elm_Object_Item* it = static_cast(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 index 0000000..1d4b7db --- /dev/null +++ b/core/Tools/FocusManager.h @@ -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 +#include +#include +#include + +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 verticalFocusVector; + std::vector::iterator focusListIterator; + unsigned int _rowTracker, _prevRowTracker; + Ecore_Event_Handler* handlerDown; + Evas_Object* _gen; +}; + +#endif // FOCUSMANAGER_H + diff --git a/services/MoreMenuUI/MoreMenuUI.cpp b/services/MoreMenuUI/MoreMenuUI.cpp index c5e9bac..a550e06 100644 --- a/services/MoreMenuUI/MoreMenuUI.cpp +++ b/services/MoreMenuUI/MoreMenuUI.cpp @@ -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 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(); +} + } } diff --git a/services/MoreMenuUI/MoreMenuUI.h b/services/MoreMenuUI/MoreMenuUI.h index e9edc23..f60d7af 100644 --- a/services/MoreMenuUI/MoreMenuUI.h +++ b/services/MoreMenuUI/MoreMenuUI.h @@ -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; }; }