From e76d269194d8bd700d35932c259134dffdb0d639 Mon Sep 17 00:00:00 2001 From: Adam Skobodzinski Date: Wed, 14 Oct 2015 11:49:17 +0200 Subject: [PATCH] Adding UrlHistoryList class and other classes managing display of 'URL from history' [Issue] https://bugs.tizen.org/jira/browse/TT-161 [Problem] 'Display URL from browser history that matches to given keyword.' [Solution] Adding necessary class and .edc files. Usage implemention in other commit. Signed-off-by: Adam Skobodzinski Change-Id: I35c8b86409e024e107498a552623840553fb3735 --- services/QuickAccess/CMakeLists.txt | 10 + .../QuickAccess/UrlHistoryList/GenlistManager.cpp | 236 +++++++++++++++++++++ .../QuickAccess/UrlHistoryList/GenlistManager.h | 121 +++++++++++ .../UrlHistoryList/GenlistManagerCallbacks.cpp | 119 +++++++++++ .../UrlHistoryList/GenlistManagerCallbacks.h | 73 +++++++ .../QuickAccess/UrlHistoryList/UrlHistoryList.cpp | 83 ++++++++ .../QuickAccess/UrlHistoryList/UrlHistoryList.h | 71 +++++++ .../UrlHistoryList/UrlMatchesStyler.cpp | 131 ++++++++++++ .../QuickAccess/UrlHistoryList/UrlMatchesStyler.h | 109 ++++++++++ .../QuickAccess/UrlHistoryList/WidgetListManager.h | 51 +++++ services/QuickAccess/edc/UrlHistoryList.edc | 142 +++++++++++++ 11 files changed, 1146 insertions(+) create mode 100644 services/QuickAccess/UrlHistoryList/GenlistManager.cpp create mode 100644 services/QuickAccess/UrlHistoryList/GenlistManager.h create mode 100644 services/QuickAccess/UrlHistoryList/GenlistManagerCallbacks.cpp create mode 100644 services/QuickAccess/UrlHistoryList/GenlistManagerCallbacks.h create mode 100644 services/QuickAccess/UrlHistoryList/UrlHistoryList.cpp create mode 100644 services/QuickAccess/UrlHistoryList/UrlHistoryList.h create mode 100644 services/QuickAccess/UrlHistoryList/UrlMatchesStyler.cpp create mode 100644 services/QuickAccess/UrlHistoryList/UrlMatchesStyler.h create mode 100644 services/QuickAccess/UrlHistoryList/WidgetListManager.h create mode 100644 services/QuickAccess/edc/UrlHistoryList.edc diff --git a/services/QuickAccess/CMakeLists.txt b/services/QuickAccess/CMakeLists.txt index bacd28d..9d794bd 100644 --- a/services/QuickAccess/CMakeLists.txt +++ b/services/QuickAccess/CMakeLists.txt @@ -3,11 +3,20 @@ project(QuickAccess) set(QuickAccess_SRCS QuickAccess.cpp DetailPopup.cpp + UrlHistoryList/UrlHistoryList.cpp + UrlHistoryList/GenlistManager.cpp + UrlHistoryList/GenlistManagerCallbacks.cpp + UrlHistoryList/UrlMatchesStyler.cpp ) set(QuickAccess_HEADERS QuickAccess.h DetailPopup.h + UrlHistoryList/UrlHistoryList.h + UrlHistoryList/WidgetListManager.h + UrlHistoryList/GenlistManager.h + UrlHistoryList/GenlistManagerCallbacks.h + UrlHistoryList/UrlMatchesStyler.h ) include(Coreheaders) @@ -29,6 +38,7 @@ install(TARGETS ${PROJECT_NAME} set(edcFiles QuickAccess.edc DetailPopup.edc + UrlHistoryList.edc ) foreach(edec ${edcFiles}) diff --git a/services/QuickAccess/UrlHistoryList/GenlistManager.cpp b/services/QuickAccess/UrlHistoryList/GenlistManager.cpp new file mode 100644 index 0000000..c29dfc5 --- /dev/null +++ b/services/QuickAccess/UrlHistoryList/GenlistManager.cpp @@ -0,0 +1,236 @@ +/* + * 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 "GenlistManager.h" +#include "GenlistManagerCallbacks.h" +#include "UrlMatchesStyler.h" + +namespace tizen_browser { +namespace services { + +GenlistManager::GenlistManager() +{ + m_urlMatchesStyler = make_shared(); + + m_historyItemClass = elm_genlist_item_class_new(); + m_historyItemClass->item_style = "url_historylist_grid_item"; + m_historyItemClass->func.text_get = nullptr; + m_historyItemClass->func.content_get = m_contentGet; + m_historyItemClass->func.state_get = nullptr; + m_historyItemClass->func.del = nullptr; + + m_historyItemSpaceClass = elm_genlist_item_class_new(); + m_historyItemSpaceClass->item_style = "url_historylist_grid_item_space"; + m_historyItemSpaceClass->func.text_get = nullptr; + m_historyItemSpaceClass->func.content_get = nullptr; + m_historyItemSpaceClass->func.state_get = nullptr; + m_historyItemSpaceClass->func.del = nullptr; +} + +GenlistManager::~GenlistManager() +{ + elm_genlist_item_class_free(m_historyItemClass); +} + +void GenlistManager::clearWidget() +{ + elm_genlist_clear(m_genlist); + elm_genlist_clear(m_genlist); + elm_genlist_clear(m_genlist); + elm_genlist_clear(m_genlist); +} + +void GenlistManager::onMouseFocusChange(bool mouseInsideWidget) +{ + this->mouseInsideWidget = mouseInsideWidget; +} + +Evas_Object* GenlistManager::createWidget(Evas_Object* parentLayout) +{ + if (!widgetExists()) { + m_parentLayout = parentLayout; + m_genlist = elm_genlist_add(parentLayout); + evas_object_size_hint_weight_set(m_genlist, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(m_genlist, EVAS_HINT_FILL, + EVAS_HINT_FILL); + if (!genlistShowScrollbar) { + elm_scroller_policy_set(m_genlist, ELM_SCROLLER_POLICY_OFF, + ELM_SCROLLER_POLICY_OFF); + } + + evas_object_smart_callback_add(m_genlist, "scroll,anim,stop", + GenlistManagerCallbacks::cb_genlistAnimStop, this); + evas_object_smart_callback_add(m_genlist, "edge,top", + GenlistManagerCallbacks::cb_genlistEdgeTop, this); + evas_object_smart_callback_add(m_genlist, "edge,bottom", + GenlistManagerCallbacks::cb_genlistEdgeBottom, this); + + evas_object_smart_callback_add(m_genlist, "activated", + GenlistManagerCallbacks::cb_genlistActivated, this); + evas_object_smart_callback_add(m_genlist, "pressed", + GenlistManagerCallbacks::cb_genlistPressed, this); + evas_object_smart_callback_add(m_genlist, "selected", + GenlistManagerCallbacks::cb_genlistSelected, this); + + evas_object_event_callback_add(m_genlist, EVAS_CALLBACK_MOUSE_IN, + GenlistManagerCallbacks::cb_genlistMouseIn, this); + evas_object_event_callback_add(m_genlist, EVAS_CALLBACK_MOUSE_OUT, + GenlistManagerCallbacks::cb_genlistMouseOut, this); + evas_object_smart_callback_add(m_genlist, "unselected", + GenlistManagerCallbacks::cb_genlistUnselected, this); + evas_object_smart_callback_add(m_genlist, "focused", + GenlistManagerCallbacks::cb_genlistFocused, this); + } + return m_genlist; +} + +Evas_Object* GenlistManager::getWidget() +{ + if (!widgetExists()) + createWidget(m_parentLayout); + return m_genlist; +} + +void GenlistManager::showWidget(const string& editedUrl, + shared_ptr matchedEntries) +{ + clearWidget(); + prepareUrlsVector(editedUrl, matchedEntries); + + m_itemUrlFirst = m_itemUrlLast = nullptr; + Elm_Object_Item* itemAppended; + for (auto it : m_readyUrls) { + itemAppended = elm_genlist_item_append(m_genlist, m_historyItemClass, + it.get(), nullptr, ELM_GENLIST_ITEM_NONE, nullptr, this); + if (!m_itemUrlFirst) + m_itemUrlFirst = itemAppended; + } + m_itemUrlLast = itemAppended; + + if (widgetPreviouslyHidden) { + widgetPreviouslyHidden = false; + startScrollIn(); + } +} + +void GenlistManager::hideWidget() +{ + if (widgetPreviouslyHidden) + return; + startScrollOut(); + widgetPreviouslyHidden = true; +} + +bool GenlistManager::isWidgetHidden() +{ + return widgetPreviouslyHidden; +} + +void GenlistManager::onMouseClick() +{ + if (!mouseInsideWidget) { + hideWidget(); + } +} + +void GenlistManager::startScrollIn() +{ + if (m_itemUrlFirst) { + addSpaces(); + elm_genlist_item_show(m_itemSpaceLast, ELM_GENLIST_ITEM_SCROLLTO_TOP); + elm_genlist_item_bring_in(m_itemUrlFirst, + ELM_GENLIST_ITEM_SCROLLTO_TOP); + } +} + +void GenlistManager::startScrollOut() +{ + addSpaces(); + if (m_itemSpaceFirst) { + elm_genlist_item_bring_in(m_itemSpaceFirst, + ELM_GENLIST_ITEM_SCROLLTO_TOP); + } +} + +void GenlistManager::setLastEdgeTop(bool edgeTop) +{ + lastEdgeTop = edgeTop; +} + +bool GenlistManager::getLastEdgeTop() +{ + return lastEdgeTop; +} + +void GenlistManager::addSpaces() +{ + if (m_itemUrlLast) { + m_itemSpaceFirst = m_itemSpaceLast = nullptr; + Elm_Object_Item* itemAppended; + for (auto i = 0; i < historyItemsVisibleMax; ++i) { + // append spaces to the last url item, so they can be easily cleared + itemAppended = elm_genlist_item_append(m_genlist, + m_historyItemSpaceClass, nullptr, m_itemUrlLast, + ELM_GENLIST_ITEM_NONE, nullptr, this); + if (!m_itemSpaceFirst) + m_itemSpaceFirst = itemAppended; + } + m_itemSpaceLast = itemAppended; + } +} + +void GenlistManager::removeSpaces() +{ + if (m_itemUrlLast) { + elm_genlist_item_subitems_clear(m_itemUrlLast); + } + m_itemSpaceFirst = m_itemSpaceLast = nullptr; +} + +Evas_Object* GenlistManager::m_contentGet(void *data, Evas_Object *obj, + const char *part) +{ + Evas_Object* label = elm_label_add(obj); + if (strcmp(part, "matched_url") == 0) { + const string * const item = reinterpret_cast(data); + if (item) { + elm_object_text_set(label, item->c_str()); + evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(label, EVAS_HINT_FILL, + EVAS_HINT_FILL); + } + } + return label; +} + +void GenlistManager::prepareUrlsVector(const string& editedUrl, + shared_ptr matchedEntries) +{ + // free previously used urls. IMPORTANT: it has to be assured that previous + // genlist items are not using these pointers. + m_readyUrls.clear(); + for (auto it : *matchedEntries) { + m_readyUrls.push_back( + make_shared < string + > (m_urlMatchesStyler->getUrlHighlightedMatches( + it->getUrl(), editedUrl))); + } +} + +} /* namespace services */ +} /* namespace tizen_browser */ diff --git a/services/QuickAccess/UrlHistoryList/GenlistManager.h b/services/QuickAccess/UrlHistoryList/GenlistManager.h new file mode 100644 index 0000000..05d5cd3 --- /dev/null +++ b/services/QuickAccess/UrlHistoryList/GenlistManager.h @@ -0,0 +1,121 @@ +/* + * 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 GENLISTMANAGER_H_ +#define GENLISTMANAGER_H_ + +#include + +#include "BrowserLogger.h" +#include "WidgetListManager.h" + +using namespace std; + +namespace tizen_browser { +namespace services { + +class GenlistManagerCallbacks; +class UrlMatchesStyler; +typedef shared_ptr UrlMatchesStylerPtr; + +class GenlistManager: public WidgetListManager +{ + friend class GenlistManagerCallbacks; +public: + GenlistManager(); + virtual ~GenlistManager(); + + virtual Evas_Object* createWidget(Evas_Object* parentLayout); + virtual Evas_Object* getWidget(); + + virtual void showWidget(const string& editedUrl, + shared_ptr matchedEntries); + virtual void hideWidget(); + void onMouseClick(); + + bool isWidgetHidden(); + + /** + * Add empty list elements to allow scroll in effect. + */ + void addSpaces(); + void removeSpaces(); + + void clearWidget(); + +private: + + static Evas_Object* m_contentGet(void *data, Evas_Object *obj, + const char *part); + bool widgetExists() + { + return m_genlist != nullptr; + } + void prepareUrlsVector(const string& editedUrl, + shared_ptr matchedEntries); + void startScrollIn(); + void startScrollOut(); + void setLastEdgeTop(bool edgeTop); + bool getLastEdgeTop(); + void onMouseFocusChange(bool mouseInsideWidget); + + Evas_Object* m_parentLayout = nullptr; + Evas_Object* m_genlist = nullptr; + const bool genlistShowScrollbar = false; + + // don't know how to get from edc: + const int historyItemH = 82; + const int historyItemsVisibleMax = 5; + // don't know how to calculate: + const int genlistH = historyItemH * historyItemsVisibleMax; + + /* + * Set to true, whenever hide request occurs. Set to false, whenever show + * request occurs. Needed to indicate when genlist should slide in. + */ + bool widgetPreviouslyHidden = true; + /* + * If mouse click received and mouse is outside widget, hide it. + */ + bool mouseInsideWidget = true; + /* + * needed to indicate direction of the scroll in 'anim,stop' callback + */ + bool lastEdgeTop = true; + + Elm_Gengrid_Item_Class * m_historyItemClass; + Elm_Gengrid_Item_Class * m_historyItemSpaceClass; + Elm_Object_Item* m_itemUrlFirst = nullptr; + Elm_Object_Item* m_itemUrlLast = nullptr; + Elm_Object_Item* m_itemSpaceFirst = nullptr; + Elm_Object_Item* m_itemSpaceLast = nullptr; + + /* + * keeps shared pointers to strings, that are ready to be displayed, so they can be + * passed through EFL, until they're not needed. IMPORTANT: it has to be + * assured, that list is not cleared until all EFL items has created their + * labels from these pointers in m_contentGet(). in case of segfaults, delete copy of pointers + * manually in m_contentGet(). + */ + vector> m_readyUrls; + UrlMatchesStylerPtr m_urlMatchesStyler; + +}; + +} /* namespace services */ +} /* namespace tizen_browser */ + +#endif /* GENLISTMANAGER_H_ */ diff --git a/services/QuickAccess/UrlHistoryList/GenlistManagerCallbacks.cpp b/services/QuickAccess/UrlHistoryList/GenlistManagerCallbacks.cpp new file mode 100644 index 0000000..25c3868 --- /dev/null +++ b/services/QuickAccess/UrlHistoryList/GenlistManagerCallbacks.cpp @@ -0,0 +1,119 @@ +/* + * 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 "BrowserLogger.h" +#include "GenlistManagerCallbacks.h" +#include "GenlistManager.h" + +namespace tizen_browser +{ +namespace services +{ + +GenlistManagerCallbacks::GenlistManagerCallbacks() +{ +} + +GenlistManagerCallbacks::~GenlistManagerCallbacks() +{ +} + +void GenlistManagerCallbacks::cb_genlistAnimStop(void *data, Evas_Object *obj, + void *event_info) +{ +} + +void GenlistManagerCallbacks::cb_genlistEdgeTop(void *data, Evas_Object *obj, + void *event_info) +{ + BROWSER_LOGD("@@ %s", __FUNCTION__); + auto manager = static_cast(data); + manager->setLastEdgeTop(false); + // spaces added for 'slide in' effect are not longer needed + manager->removeSpaces(); +} + +void GenlistManagerCallbacks::cb_genlistEdgeBottom(void *data, Evas_Object *obj, + void *event_info) +{ + auto manager = static_cast(data); + manager->setLastEdgeTop(true); + if (manager->isWidgetHidden()) + { + manager->clearWidget(); + evas_object_hide(manager->getWidget()); + } +} + +void GenlistManagerCallbacks::cb_genlistActivated(void *data, Evas_Object *obj, + void *event_info) +{ +} +void GenlistManagerCallbacks::cb_genlistPressed(void *data, Evas_Object *obj, + void *event_info) +{ +} +void GenlistManagerCallbacks::cb_genlistSelected(void *data, Evas_Object *obj, + void *event_info) +{ +} +void GenlistManagerCallbacks::cb_genlistUnselected(void *data, Evas_Object *obj, + void *event_info) +{ +} + +void GenlistManagerCallbacks::cb_genlistFocused(void *data, Evas_Object *obj, + void *event_info) +{ +} + +void GenlistManagerCallbacks::cb_genlistUnfocused(void *data, Evas_Object *obj, + void *event_info) +{ +} + +void GenlistManagerCallbacks::cb_genlistMouseIn(void *data, Evas *e, + Evas_Object *obj, void *event_info) +{ + auto manager = static_cast(data); + manager->onMouseFocusChange(true); +} +void GenlistManagerCallbacks::cb_genlistMouseOut(void *data, Evas *e, + Evas_Object *obj, void *event_info) +{ + auto manager = static_cast(data); + manager->onMouseFocusChange(false); +} + +void GenlistManagerCallbacks::cb_itemFocused(void *data, Evas_Object *obj, + void *event_info) +{ +} +void GenlistManagerCallbacks::cb_itemUnfocused(void *data, Evas_Object *obj, + void *event_info) +{ +} +void GenlistManagerCallbacks::cb_itemMouseIn(void *data, Elm_Object_Item *it, + const char *emission, const char *source) +{ +} +void GenlistManagerCallbacks::cb_itemMouseOut(void *data, Evas *e, + Evas_Object *obj, void *event_info) +{ +} + +} /* namespace services */ +} /* namespace tizen_browser */ diff --git a/services/QuickAccess/UrlHistoryList/GenlistManagerCallbacks.h b/services/QuickAccess/UrlHistoryList/GenlistManagerCallbacks.h new file mode 100644 index 0000000..25ff418 --- /dev/null +++ b/services/QuickAccess/UrlHistoryList/GenlistManagerCallbacks.h @@ -0,0 +1,73 @@ +/* + * 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 GENLISTMANAGERCALLBACKS_H_ +#define GENLISTMANAGERCALLBACKS_H_ + +#include +#include + +class GenlistManager; + +namespace tizen_browser +{ +namespace services +{ + +class GenlistManagerCallbacks +{ +public: + GenlistManagerCallbacks(); + virtual ~GenlistManagerCallbacks(); + + static void cb_genlistAnimStop(void *data, Evas_Object *obj, + void *event_info); + static void cb_genlistEdgeTop(void *data, Evas_Object *obj, + void *event_info); + static void cb_genlistEdgeBottom(void *data, Evas_Object *obj, + void *event_info); + + static void cb_genlistActivated(void *data, Evas_Object *obj, + void *event_info); + static void cb_genlistPressed(void *data, Evas_Object *obj, + void *event_info); + static void cb_genlistSelected(void *data, Evas_Object *obj, + void *event_info); + static void cb_genlistUnselected(void *data, Evas_Object *obj, + void *event_info); + + static void cb_genlistFocused(void *data, Evas_Object *obj, + void *event_info); + static void cb_genlistUnfocused(void *data, Evas_Object *obj, + void *event_info); + static void cb_genlistMouseIn(void *data, Evas *e, Evas_Object *obj, + void *event_info); + static void cb_genlistMouseOut(void *data, Evas *e, Evas_Object *obj, + void *event_info); + + static void cb_itemFocused(void *data, Evas_Object *obj, void *event_info); + static void cb_itemUnfocused(void *data, Evas_Object *obj, + void *event_info); + static void cb_itemMouseIn(void *data, Elm_Object_Item *it, + const char *emission, const char *source); + static void cb_itemMouseOut(void *data, Evas *e, Evas_Object *obj, + void *event_info); +}; + +} /* namespace services */ +} /* namespace tizen_browser */ + +#endif /* GENLISTMANAGERCALLBACKS_H_ */ diff --git a/services/QuickAccess/UrlHistoryList/UrlHistoryList.cpp b/services/QuickAccess/UrlHistoryList/UrlHistoryList.cpp new file mode 100644 index 0000000..fd76489 --- /dev/null +++ b/services/QuickAccess/UrlHistoryList/UrlHistoryList.cpp @@ -0,0 +1,83 @@ +/* + * 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 +#include "UrlHistoryList.h" +#include "GenlistManager.h" + +#include "BrowserLogger.h" + +namespace tizen_browser +{ +namespace base_ui +{ + +UrlHistoryList::UrlHistoryList() : + m_layout(nullptr) +{ + m_edjFilePath = EDJE_DIR; + m_edjFilePath.append("MainUI/UrlHistoryList.edj"); + m_widgetListManager = make_shared(); +} + +UrlHistoryList::~UrlHistoryList() +{ +} + +void UrlHistoryList::show() +{ + if (m_layout) + { + evas_object_show(m_layout); + } +} + +Evas_Object* UrlHistoryList::getLayout() +{ + return m_layout; +} + +void UrlHistoryList::createLayout(Evas_Object* parentLayout) +{ + m_layout = elm_layout_add(parentLayout); + elm_layout_file_set(m_layout, m_edjFilePath.c_str(), "url_history_list"); + + Evas_Object* widgetList = m_widgetListManager->createWidget(m_layout); +} + +void UrlHistoryList::onURLEntryEdit(const string& editedUrl, + shared_ptr matchedEntries) +{ + Evas_Object* widgetList = m_widgetListManager->getWidget(); + if (matchedEntries->size() == 0) + { + m_widgetListManager->hideWidget(); + } + else + { + elm_object_part_content_set(m_layout, "list_swallow", widgetList); + m_widgetListManager->showWidget(editedUrl, matchedEntries); + evas_object_show(widgetList); + } +} + +void UrlHistoryList::onMouseClick() +{ + m_widgetListManager->onMouseClick(); +} + +}/* namespace base_ui */ +} /* namespace tizen_browser */ diff --git a/services/QuickAccess/UrlHistoryList/UrlHistoryList.h b/services/QuickAccess/UrlHistoryList/UrlHistoryList.h new file mode 100644 index 0000000..fa9934a --- /dev/null +++ b/services/QuickAccess/UrlHistoryList/UrlHistoryList.h @@ -0,0 +1,71 @@ +/* + * 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 URLHISTORYLIST_H_ +#define URLHISTORYLIST_H_ + +#include +#include + +#include "services/HistoryService/HistoryItem.h" + +using namespace std; + +namespace tizen_browser +{ + +namespace services +{ +class WidgetListManager; +typedef shared_ptr WidgetListManagerPtr; +} + +namespace base_ui +{ + +/** + * Manages list of url matches (URL from history). Manages top layout, creates + * widget displaying url items. + */ +class UrlHistoryList +{ +public: + UrlHistoryList(); + virtual ~UrlHistoryList(); + void show(); + void createLayout(Evas_Object* parentLayout); + Evas_Object *getLayout(); + + /** + * \brief entered url is edited (edited before acceptation) + */ + void onURLEntryEdit(const string& editedUrl, + shared_ptr matchedEntries); + void onMouseClick(); + +private: + + Evas_Object* m_layout; + string m_edjFilePath; + + services::WidgetListManagerPtr m_widgetListManager; + +}; + +} /* namespace base_ui */ +} /* namespace tizen_browser */ + +#endif /* URLHISTORYLIST_H_ */ diff --git a/services/QuickAccess/UrlHistoryList/UrlMatchesStyler.cpp b/services/QuickAccess/UrlHistoryList/UrlMatchesStyler.cpp new file mode 100644 index 0000000..c97758b --- /dev/null +++ b/services/QuickAccess/UrlHistoryList/UrlMatchesStyler.cpp @@ -0,0 +1,131 @@ +/* + * 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 "UrlMatchesStyler.h" + +namespace tizen_browser { +namespace services { + +UrlMatchesStyler::UrlMatchesStyler() : + TAG_WHOLE_URL(""), + TAG_WHOLE_URL_CLOSE(""), + TAG_HIGHLIGHT(""), + TAG_HIGHLIGHT_CLOSE(closeTag(TAG_HIGHLIGHT)), + TAG_COLOR(""), + TAG_COLOR_CLOSE(closeTag(TAG_COLOR)), + TAG_COMPLETE(TAG_HIGHLIGHT + TAG_COLOR), + TAG_COMPLETE_CLOSE(TAG_HIGHLIGHT_CLOSE + TAG_COLOR_CLOSE), + TAGS_COMPLETE_LEN(TAG_COMPLETE.length() + TAG_COMPLETE_CLOSE.length()) { +} + +UrlMatchesStyler::~UrlMatchesStyler() { +} + +string UrlMatchesStyler::closeTag(const string& tag) const { + string closedTag(tag); + return string(closedTag.insert(1, "/")); +} + +string UrlMatchesStyler::getUrlHighlightedMatches(const string& styledUrl, + const string& highlightingKeywords) const { + vector < string > keywords; + splitKeywordsString(highlightingKeywords, keywords); + + int_pairs rangesHighlight; + for (auto key : keywords) { + fillOccuranceRanges(styledUrl, key, rangesHighlight); + } + + int_pairs mergedRangesHighlight; + mergeRanges(rangesHighlight, mergedRangesHighlight); + return getTaggedString(styledUrl, mergedRangesHighlight); +} + +void UrlMatchesStyler::splitKeywordsString(const string& keywordsString, + vector& resultKeywords) const { + boost::algorithm::split(resultKeywords, keywordsString, + boost::is_any_of("\t "), boost::token_compress_on); + // remove empty elements + for (auto it = resultKeywords.begin(); it != resultKeywords.end();) { + if ((*it).empty()) { + it = resultKeywords.erase(it); + } else { + ++it; + } + } +} + +void UrlMatchesStyler::fillOccuranceRanges(const string& _checkedString, + const string& _searchedMatch, int_pairs& resultRanges) const { + if (_checkedString.empty() || _searchedMatch.empty()) + return; + + string checkedString(_checkedString); + string searchedMatch(_searchedMatch); + boost::algorithm::to_lower(checkedString); + boost::algorithm::to_lower(searchedMatch); + + int len = searchedMatch.length(); + vector positions; + getMatchesPositions(checkedString, searchedMatch, positions); + for (auto pos : positions) { + resultRanges.push_back( { pos, pos + len - 1 }); + } +} + +void UrlMatchesStyler::getMatchesPositions(const string& checkedString, + const string& searchedMatch, vector& resultPositions) const { + boost::regex match_regex(searchedMatch); + for (auto it = boost::sregex_iterator(checkedString.begin(), + checkedString.end(), match_regex); it != boost::sregex_iterator(); + ++it) { + resultPositions.push_back(it->position()); + } +} + +void UrlMatchesStyler::mergeRanges(int_pairs& ranges, int_pairs& result) const { + if (ranges.size() == 0) + return; + sort(ranges.begin(), ranges.end()); + + auto current = *(ranges.begin()); + for (auto it = ranges.begin() + 1; it != ranges.end(); ++it) { + if (current.second >= it->first) { + current.second = max(current.second, it->second); + } else { + result.push_back(current); + current = *it; + } + } + result.push_back(current); +} + +string UrlMatchesStyler::getTaggedString(const string& strToHighlight, + const int_pairs& ranges) const { + string strResult(strToHighlight); + int insertOffset = 0; + for (auto pair : ranges) { + strResult.insert(pair.second + insertOffset + 1, TAG_COMPLETE_CLOSE); + strResult.insert(pair.first + insertOffset, TAG_COMPLETE); + insertOffset += TAGS_COMPLETE_LEN; + } + strResult.insert(strResult.length(), TAG_WHOLE_URL_CLOSE); + strResult.insert(0, TAG_WHOLE_URL); + return strResult; +} + +} /* namespace services */ +} /* namespace tizen_browser */ diff --git a/services/QuickAccess/UrlHistoryList/UrlMatchesStyler.h b/services/QuickAccess/UrlHistoryList/UrlMatchesStyler.h new file mode 100644 index 0000000..d100b29 --- /dev/null +++ b/services/QuickAccess/UrlHistoryList/UrlMatchesStyler.h @@ -0,0 +1,109 @@ +/* + * 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 URLMATCHESSTYLER_H_ +#define URLMATCHESSTYLER_H_ + +#include +#include +#include +#include +#include "BrowserLogger.h" + +using namespace std; + +namespace tizen_browser { +namespace services { + +class UrlMatchesStyler { +public: + UrlMatchesStyler(); + virtual ~UrlMatchesStyler(); + + /** + * @brief Get string containing EFL tags, which are highlighting given keywords. + * @param styledUrl url which will be styled + * @param highlightingKeyword keywords (entered url) indicating which + * fragments should be highlighted + * @return styledUrl enriched with EFL tags + */ + string getUrlHighlightedMatches(const string& styledUrl, + const string& highlightingKeywords) const; + +private: + typedef vector> int_pairs; + const string FONT_COLOR_HIGHLIGHT = "#4088D3"; + const string FONT_COLOR_NORMAL = "#888888"; + const string FONT_SIZE = "35"; + const string TAG_WHOLE_URL; + const string TAG_WHOLE_URL_CLOSE; + const string TAG_HIGHLIGHT, TAG_HIGHLIGHT_CLOSE; + const string TAG_COLOR, TAG_COLOR_CLOSE; + const string TAG_COMPLETE, TAG_COMPLETE_CLOSE; + const int TAGS_COMPLETE_LEN; + + /** + * @brief adds '/' to a tag ( -> ) + * @param tag tag to be closed + * @return closed tag + */ + string closeTag(const string& tag) const; + /** + * @brief splits given string by removing spaces + * @param keywordsString string to split + * @param resultKeywords vector to which result strings are stored + */ + void splitKeywordsString(const string& keywordsString, + vector& resultKeywords) const; + /** + * @brief Fills vector with ranges describing beginnings end ends of occurrences of one string in another. + * @param checkedString the subject of search + * @param searchedMatch match to be searched for + * @param resultRanges vector filled with found ranges + */ + void fillOccuranceRanges(const string& checkedString, + const string& searchedMatch, int_pairs& resultRanges) const; + /** + * @brief Searches the string for positions of occurrences of another string. + * @param checkedString the subject of search + * @param searchedMatch string to be searched for + * @param resultPositions vector filled with result positions + */ + void getMatchesPositions(const string& checkedString, + const string& searchedMatch, vector& resultPositions) const; + /** + * @brief merges ranges + * @param ranges vector of ranges to merge + * @param result vector filled with merged ranges + */ + void mergeRanges(int_pairs& ranges, int_pairs& result) const; + /** + * @brief get string enriched with opening and closing tags on given positions + * @param strToHighlight string to be enriched with tags + * @param ranges positions of opening and closing tags + * @param tag opening tag (for every pair.first) + * @param tagClose closing tag (for every pair.second) + * @return string with tags + */ + string getTaggedString(const string& strToHighlight, + const int_pairs& ranges) const; + +}; + +} /* namespace services */ +} /* namespace tizen_browser */ + +#endif /* URLMATCHESSTYLER_H_ */ diff --git a/services/QuickAccess/UrlHistoryList/WidgetListManager.h b/services/QuickAccess/UrlHistoryList/WidgetListManager.h new file mode 100644 index 0000000..18c22b5 --- /dev/null +++ b/services/QuickAccess/UrlHistoryList/WidgetListManager.h @@ -0,0 +1,51 @@ +/* + * 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 WIDGETLISTMANAGER_H_ +#define WIDGETLISTMANAGER_H_ + +#include +#include +#include "services/HistoryService/HistoryItem.h" + +namespace tizen_browser +{ +namespace services +{ + +/** + * Interface for classes managing list-like widgets. + * TODO: consider if it could be used in whole application, not only for URL + * list. + */ +class WidgetListManager +{ +public: + virtual ~WidgetListManager() + { + } + virtual Evas_Object* createWidget(Evas_Object* parentLayout) = 0; + virtual Evas_Object* getWidget() = 0; + virtual void hideWidget() = 0; + virtual void showWidget(const std::string& editedUrl, + std::shared_ptr matchedEntries) = 0; + virtual void onMouseClick() = 0; +}; + +} /* namespace services */ +} /* namespace tizen_browser */ + +#endif /* WIDGETLISTMANAGER_H_ */ diff --git a/services/QuickAccess/edc/UrlHistoryList.edc b/services/QuickAccess/edc/UrlHistoryList.edc new file mode 100644 index 0000000..9cc5fb3 --- /dev/null +++ b/services/QuickAccess/edc/UrlHistoryList.edc @@ -0,0 +1,142 @@ +#define URI_INPUTBOX_LENGTH 1720 +#define URI_INPUTBOX_LENGTH_SMALL 1460 +#define HISTORY_ITEM_W URI_INPUTBOX_LENGTH +#define HISTORY_ITEM_H 82 +#define HISTORY_ITEMS_VISIBLE_MAX 5 +/* + Right now, has to be a multiple of item's height. +*/ +#define LIST_MAX_H HISTORY_ITEM_H*HISTORY_ITEMS_VISIBLE_MAX + +collections { + group { + name: "url_history_list"; + parts + { + part { + name: "bg"; + type: RECT; + mouse_events: 1; + description + { + color: 232 122 32 150; + state: "default" 0.0; + visible: 0; + min: URI_INPUTBOX_LENGTH LIST_MAX_H; + max: -1 -1; + align: 0.0 0.0; + fixed: 1 1; + rel1 + { + relative: 0 0; + } + rel2 + { + relative: 1.0 1.0; + } + } + } + + part { + name: "list_swallow"; + type: SWALLOW; + description { + color: 255 0 0 150; + min: URI_INPUTBOX_LENGTH LIST_MAX_H; + max: -1 -1; + visible: 1; + align: 0.0 0.0; + rel1 { + relative: 0 0; + offset: 0 0; + } + rel2 { + relative: 1.0 0.5; + } + } + } + } + } + + group { + name: "elm/genlist/item/url_historylist_grid_item/default"; + data.item: "contents" "matched_url"; + parts { + part { + name: "bg"; + type: RECT; + mouse_events: 1; + description { + state: "default" 0.0; + min: URI_INPUTBOX_LENGTH HISTORY_ITEM_H; + max: -1 -1; + visible: 1; + color: 255 255 255 255; + align: 0.0 0.0; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + color: 0 119 246 255; + } + } + part { + name: "matched_url"; + type: SWALLOW; + scale: 1; + description { + state: "default" 0.0; + fixed: 0 1; + visible: 1; + align: 0.0 0.0; + rel1 { + to: "bg"; + relative: 0.0 0.0; + offset: 48 0; + } + rel2 { + to: "bg"; + relative: 1.0 1.0; + } + + } + } + } + programs { + program { + name: "focused"; + signal: "mouse,in"; + source: "matched_url"; + action: STATE_SET "focused" 0.0; + target: "bg"; + } + program { + name: "selected"; + signal: "mouse,out"; + source: "matched_url"; + action: STATE_SET "default" 0.0; + target: "bg"; + } + } + } + + group { + name: "elm/genlist/item/url_historylist_grid_item_space/default"; + parts { + part { + name: "bg"; + type: RECT; + mouse_events: 1; + description { + state: "default" 0.0; + visible: 0; + min: URI_INPUTBOX_LENGTH HISTORY_ITEM_H; + max: -1 -1; + visible: 1; + color: 255 255 255 0; + align: 0.0 0.0; + } + } + } + } +} -- 2.7.4