2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <Elementary.h>
18 #include <boost/concept_check.hpp>
20 #include <AbstractMainWindow.h>
22 #include "QuickAccess.h"
23 #include "ServiceManager.h"
24 #include "BrowserLogger.h"
25 #include "Tools/EflTools.h"
26 #include "../Tools/BrowserImage.h"
27 #include "Tools/GeneralTools.h"
28 #include "UrlHistoryList/UrlHistoryList.h"
30 #define efl_scale (elm_config_scale_get() / elm_app_base_scale_get())
32 namespace tizen_browser{
35 EXPORT_SERVICE(QuickAccess, "org.tizen.browser.quickaccess")
37 const int QuickAccess::MAX_TILES_NUMBER = 5;
38 const int QuickAccess::MAX_THUMBNAIL_WIDTH = 840;
39 const int QuickAccess::MAX_THUMBNAIL_HEIGHT = 648;
40 const int QuickAccess::BIG_TILE_INDEX = 0;
41 const int QuickAccess::TOP_RIGHT_TILE_INDEX = 3;
42 const int QuickAccess::BOTTOM_RIGHT_TILE_INDEX = 4;
44 const std::vector<std::string> QuickAccess::TILES_NAMES = {
46 "elm.swallow.small_first",
47 "elm.swallow.small_second",
48 "elm.swallow.small_third",
49 "elm.swallow.small_fourth"
52 typedef struct _HistoryItemData
54 std::shared_ptr<tizen_browser::services::HistoryItem> item;
55 std::shared_ptr<tizen_browser::base_ui::QuickAccess> quickAccess;
58 typedef struct _BookmarkItemData
60 std::shared_ptr<tizen_browser::services::BookmarkItem> item;
61 std::shared_ptr<tizen_browser::base_ui::QuickAccess> quickAccess;
64 QuickAccess::QuickAccess()
67 , m_bookmarksView(nullptr)
68 , m_mostVisitedView(nullptr)
69 , m_bookmarksButton(nullptr)
70 , m_mostVisitedButton(nullptr)
71 , m_bookmarkGengrid(nullptr)
72 , m_bookmarkManagerButton(nullptr)
73 , m_parentFocusChain(nullptr)
74 , m_bookmark_item_class(nullptr)
76 , m_after_history_thumb(false)
78 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
79 edjFilePath = edjFilePathUrlHistoryList = EDJE_DIR;
80 edjFilePath.append("QuickAccess/QuickAccess.edj");
81 edjFilePathUrlHistoryList.append("QuickAccess/UrlHistoryList.edj");
82 elm_theme_extension_add(nullptr, edjFilePath.c_str());
83 elm_theme_extension_add(nullptr, edjFilePathUrlHistoryList.c_str());
84 QuickAccess::createItemClasses();
86 m_urlHistoryList = std::make_shared<UrlHistoryList>(this);
89 QuickAccess::~QuickAccess()
91 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
92 elm_gengrid_item_class_free(m_bookmark_item_class);
93 eina_list_free(m_parentFocusChain);
96 void QuickAccess::init(Evas_Object* parent)
103 Evas_Object* QuickAccess::getContent()
107 m_layout = createQuickAccessLayout(m_parent);
108 m_urlHistoryListLayout = createUrlHistoryListLayout(m_layout);
113 void QuickAccess::showMostVisited(std::shared_ptr< services::HistoryItemVector > vec)
115 addHistoryItems(vec);
119 void QuickAccess::showBookmarks(std::vector< std::shared_ptr< tizen_browser::services::BookmarkItem > > vec)
121 addBookmarkItems(vec);
125 void QuickAccess::createItemClasses()
127 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
128 if (!m_bookmark_item_class) {
129 m_bookmark_item_class = elm_gengrid_item_class_new();
130 m_bookmark_item_class->item_style = "grid_item";
131 m_bookmark_item_class->func.text_get = _grid_bookmark_text_get;
132 m_bookmark_item_class->func.content_get = _grid_bookmark_content_get;
133 m_bookmark_item_class->func.state_get = nullptr;
134 m_bookmark_item_class->func.del = nullptr;
139 Evas_Object* QuickAccess::createQuickAccessLayout(Evas_Object* parent)
141 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
142 m_desktopMode = true;
144 Evas_Object* layout = elm_layout_add(parent);
145 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
146 evas_object_size_hint_align_set (layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
148 m_mostVisitedView = createMostVisitedView(layout);
149 m_bookmarksView = createBookmarksView (layout);
156 Evas_Object* QuickAccess::createMostVisitedView (Evas_Object * parent)
158 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
160 Evas_Object* mostVisitedLayout = elm_layout_add(parent);
161 elm_layout_file_set(mostVisitedLayout, edjFilePath.c_str(), "mv_bookmarks");
162 evas_object_size_hint_weight_set(mostVisitedLayout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
163 evas_object_size_hint_align_set (mostVisitedLayout, EVAS_HINT_FILL, EVAS_HINT_FILL);
165 Evas_Object* topButtons = createTopButtons(mostVisitedLayout);
166 elm_object_part_content_set(mostVisitedLayout, "elm.swallow.layoutTop", topButtons);
168 return mostVisitedLayout;
171 Evas_Object* QuickAccess::createBookmarksView (Evas_Object * parent)
173 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
175 Evas_Object *bookmarkViewLayout = elm_layout_add(parent);
176 elm_layout_file_set(bookmarkViewLayout, edjFilePath.c_str(), "mv_bookmarks");
177 evas_object_size_hint_weight_set(bookmarkViewLayout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
178 evas_object_size_hint_align_set(bookmarkViewLayout, EVAS_HINT_FILL, EVAS_HINT_FILL);
180 m_bookmarkGengrid = createBookmarkGengrid(bookmarkViewLayout);
181 elm_object_part_content_set(bookmarkViewLayout, "elm.swallow.grid", m_bookmarkGengrid);
183 Evas_Object* topButtons = createTopButtons(bookmarkViewLayout);
184 elm_object_part_content_set(bookmarkViewLayout, "elm.swallow.layoutTop", topButtons);
186 Evas_Object* bottomButton = createBottomButton(bookmarkViewLayout);
187 elm_object_part_content_set(bookmarkViewLayout, "elm.swallow.layoutBottom", bottomButton);
189 return bookmarkViewLayout;
192 Evas_Object* QuickAccess::createBookmarkGengrid(Evas_Object *parent)
194 Evas_Object *bookmarkGengrid = elm_gengrid_add(parent);
196 elm_gengrid_align_set(bookmarkGengrid, 0, 0);
197 elm_gengrid_select_mode_set(bookmarkGengrid, ELM_OBJECT_SELECT_MODE_ALWAYS);
198 elm_gengrid_multi_select_set(bookmarkGengrid, EINA_FALSE);
199 elm_gengrid_horizontal_set(bookmarkGengrid, EINA_FALSE);
201 elm_scroller_policy_set(bookmarkGengrid, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
202 elm_scroller_page_size_set(bookmarkGengrid, 0, 327);
203 evas_object_size_hint_weight_set(bookmarkGengrid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
204 evas_object_size_hint_align_set(bookmarkGengrid, EVAS_HINT_FILL, EVAS_HINT_FILL);
205 elm_gengrid_item_size_set(bookmarkGengrid, 364 * efl_scale, 320 * efl_scale);
207 return bookmarkGengrid;
210 Evas_Object* QuickAccess::createTopButtons (Evas_Object *parent)
212 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
214 Evas_Object *layoutTop = elm_layout_add(parent);
215 elm_layout_file_set(layoutTop, edjFilePath.c_str(), "top_button_item");
216 evas_object_size_hint_weight_set(layoutTop, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
217 evas_object_size_hint_align_set(layoutTop, EVAS_HINT_FILL, EVAS_HINT_FILL);
218 evas_object_show(layoutTop);
220 Evas_Object *mostVisitedButton = elm_button_add(layoutTop);
221 elm_object_style_set(mostVisitedButton, "invisible_button");
222 evas_object_smart_callback_add(mostVisitedButton, "clicked", _mostVisited_clicked, this);
223 evas_object_show(mostVisitedButton);
224 elm_layout_content_set(layoutTop, "mostvisited_click", mostVisitedButton);
225 m_mostVisitedButton = mostVisitedButton;
227 Evas_Object *bookmarksButton = elm_button_add(layoutTop);
228 elm_object_style_set(bookmarksButton, "invisible_button");
229 evas_object_smart_callback_add(bookmarksButton, "clicked", _bookmark_clicked, this);
230 evas_object_show(bookmarksButton);
231 elm_layout_content_set(layoutTop, "bookmark_click", bookmarksButton);
232 m_bookmarksButton = bookmarksButton;
237 Evas_Object* QuickAccess::createBottomButton(Evas_Object *parent)
239 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
241 Evas_Object *layoutBottom = elm_layout_add(parent);
242 elm_layout_file_set(layoutBottom, edjFilePath.c_str(), "bottom_button_item");
244 evas_object_size_hint_weight_set(layoutBottom, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
245 evas_object_size_hint_align_set(layoutBottom, EVAS_HINT_FILL, EVAS_HINT_FILL);
246 evas_object_show(layoutBottom);
248 m_bookmarkManagerButton = elm_button_add(layoutBottom);
249 elm_object_style_set(m_bookmarkManagerButton, "invisible_button");
250 evas_object_smart_callback_add(m_bookmarkManagerButton, "clicked", _bookmark_manager_clicked, this);
251 evas_object_show(m_bookmarkManagerButton);
253 elm_object_part_content_set(layoutBottom, "bookmarkmanager_click", m_bookmarkManagerButton);
258 Evas_Object* QuickAccess::createUrlHistoryListLayout(Evas_Object* parent)
260 Evas_Object* urlHistoryListLayout = elm_layout_add(parent);
261 elm_layout_file_set(urlHistoryListLayout, edjFilePath.c_str(), "url_history_list_layout");
262 evas_object_size_hint_weight_set(urlHistoryListLayout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
263 evas_object_size_hint_align_set (urlHistoryListLayout, EVAS_HINT_FILL, EVAS_HINT_FILL);
265 m_urlHistoryList->createLayout(urlHistoryListLayout);
266 if(m_urlHistoryList->getLayout())
268 elm_object_part_content_set(urlHistoryListLayout, "url_history_list_swallow", m_urlHistoryList->getLayout());
270 return urlHistoryListLayout;
273 void QuickAccess::_mostVisited_clicked(void * data, Evas_Object *, void *)
275 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
276 QuickAccess* quickAccess = reinterpret_cast<QuickAccess *>(data);
277 quickAccess->mostVisitedClicked();
280 void QuickAccess::_bookmark_clicked(void * data, Evas_Object *, void *)
282 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
283 QuickAccess* quickAccess = reinterpret_cast<QuickAccess *>(data);
284 quickAccess->bookmarkClicked();
287 void QuickAccess::_bookmark_manager_clicked(void * data, Evas_Object *, void *)
289 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
290 QuickAccess* quickAccess = static_cast<QuickAccess *>(data);
291 quickAccess->bookmarkManagerClicked();
294 void QuickAccess::addHistoryItem(std::shared_ptr<services::HistoryItem> hi)
296 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
297 M_ASSERT(m_historyItems.size() < MAX_TILES_NUMBER);
299 int tileNumber = m_historyItems.size();
300 HistoryItemData *itemData = new HistoryItemData();
302 itemData->quickAccess = std::shared_ptr<QuickAccess>(this);
304 Evas_Object* tile = elm_button_add(m_mostVisitedView);
305 if (tileNumber == BIG_TILE_INDEX)
306 elm_object_style_set(tile, "big_tile");
308 elm_object_style_set(tile, "small_tile");
309 evas_object_size_hint_weight_set(tile, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
310 evas_object_size_hint_align_set (tile, EVAS_HINT_FILL, EVAS_HINT_FILL);
311 evas_object_show(tile);
312 elm_object_part_content_set(m_mostVisitedView, TILES_NAMES[tileNumber].c_str(), tile);
313 m_tiles.push_back(tile);
315 elm_layout_text_set(tile, "page_title", hi->getTitle().c_str());
316 elm_layout_text_set(tile, "page_url", hi->getUrl().c_str());
317 Evas_Object * thumb = tizen_browser::tools::EflTools::getEvasImage(hi->getThumbnail(), m_parent);
318 elm_object_part_content_set(tile, "elm.thumbnail", thumb);
319 evas_object_smart_callback_add(tile, "clicked", _thumbHistoryClicked, itemData);
321 m_historyItems.push_back(hi);
324 void QuickAccess::addHistoryItems(std::shared_ptr<services::HistoryItemVector> items)
326 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
327 clearHistoryGenlist();
329 for (auto it = items->begin(); it != items->end(); ++it) {
331 if (i > MAX_TILES_NUMBER)
339 void QuickAccess::addBookmarkItem(std::shared_ptr<tizen_browser::services::BookmarkItem> bi)
341 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
342 BookmarkItemData *itemData = new BookmarkItemData();
344 itemData->quickAccess = std::shared_ptr<tizen_browser::base_ui::QuickAccess>(this);
345 elm_gengrid_item_append(m_bookmarkGengrid, m_bookmark_item_class, itemData, _thumbBookmarkClicked, itemData);
348 void QuickAccess::addBookmarkItems(std::vector<std::shared_ptr<tizen_browser::services::BookmarkItem> > items)
350 clearBookmarkGengrid();
351 for (auto it = items.begin(); it != items.end(); ++it) {
352 addBookmarkItem(*it);
357 char* QuickAccess::_grid_bookmark_text_get(void *data, Evas_Object *, const char *part)
359 BookmarkItemData *itemData = reinterpret_cast<BookmarkItemData*>(data);
360 if (!strcmp(part, "page_title")) {
361 return strdup(itemData->item->getTittle().c_str());
363 if (!strcmp(part, "page_url")) {
364 return strdup(itemData->item->getAddress().c_str());
369 Evas_Object * QuickAccess::_grid_bookmark_content_get(void *data, Evas_Object*, const char *part)
371 BROWSER_LOGD("%s:%d %s part=%s", __FILE__, __LINE__, __func__, part);
372 BookmarkItemData *itemData = reinterpret_cast<BookmarkItemData*>(data);
374 if (!strcmp(part, "elm.thumbnail")) {
375 if (itemData->item->getThumbnail()) {
376 Evas_Object * thumb = tizen_browser::tools::EflTools::getEvasImage(itemData->item->getThumbnail(), itemData->quickAccess->m_parent);
387 void QuickAccess::_thumbBookmarkClicked(void * data, Evas_Object * , void *)
389 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
390 HistoryItemData * itemData = reinterpret_cast<HistoryItemData *>(data);
391 itemData->quickAccess->openURLInNewTab(itemData->item, itemData->quickAccess->isDesktopMode());
392 itemData->quickAccess->m_after_history_thumb = false;
395 void QuickAccess::_thumbHistoryClicked(void* data, Evas_Object*, void*)
397 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
398 HistoryItemData * itemData = reinterpret_cast<HistoryItemData *>(data);
399 itemData->quickAccess->mostVisitedTileClicked(itemData->item, DetailPopup::HISTORY_ITEMS_NO);
400 itemData->quickAccess->m_after_history_thumb = true;
403 void QuickAccess::clearHistoryGenlist()
405 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
407 for (auto it = m_tiles.begin(); it != m_tiles.end(); ++it) {
408 evas_object_smart_callback_del(*it, "clicked", _thumbHistoryClicked);
409 evas_object_del(*it);
413 m_historyItems.clear();
416 void QuickAccess::showHistory()
418 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
420 if (elm_layout_content_get(m_layout, "elm.swallow.content") == m_mostVisitedView)
423 evas_object_hide(m_bookmarksView);
424 elm_layout_content_set(m_layout, "elm.swallow.content", m_mostVisitedView);
425 evas_object_show(m_mostVisitedView);
428 if (m_historyItems.empty()) {
433 evas_object_show(m_layout);
435 elm_object_focus_set(m_mostVisitedButton, true);
438 void QuickAccess::clearBookmarkGengrid()
440 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
441 elm_gengrid_clear(m_bookmarkGengrid);
444 void QuickAccess::showBookmarks()
446 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
448 if (elm_layout_content_get(m_layout, "elm.swallow.content") == m_bookmarksView && m_bookmarksView != nullptr)
451 evas_object_hide(m_mostVisitedView);
452 elm_layout_content_set(m_layout, "elm.swallow.content", m_bookmarksView);
453 evas_object_show(m_bookmarksView);
455 evas_object_show(m_layout);
457 elm_object_focus_set(m_bookmarksButton, true);
460 void QuickAccess::showUI()
462 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
463 evas_object_show(m_layout);
464 evas_object_show(m_urlHistoryListLayout);
465 if (elm_layout_content_get(m_layout, "elm.swallow.content") == m_bookmarksView) {
466 evas_object_show(m_bookmarksView);
468 evas_object_show(m_mostVisitedView);
472 void QuickAccess::hideUI()
474 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
475 evas_object_hide(m_layout);
476 evas_object_hide(m_mostVisitedView);
477 evas_object_hide(m_bookmarksView);
478 clearHistoryGenlist();
479 clearBookmarkGengrid();
482 void QuickAccess::openDetailPopup(std::shared_ptr<services::HistoryItem> currItem, std::shared_ptr<services::HistoryItemVector> prevItems)
484 m_detailPopup.show(m_layout, m_parent, currItem, prevItems);
487 void QuickAccess::showNoHistoryLabel()
489 elm_layout_text_set(m_mostVisitedView, "elm.text.empty", "No visited site");
490 elm_layout_signal_emit(m_mostVisitedView, "empty,view", "quickaccess");
493 void QuickAccess::setEmptyView(bool empty)
495 BROWSER_LOGD("%s:%d %s, empty: %d", __FILE__, __LINE__, __func__, empty);
497 showNoHistoryLabel();
499 elm_layout_signal_emit(m_mostVisitedView, "not,empty,view", "quickaccess");
503 bool QuickAccess::isDesktopMode() const
505 return m_desktopMode;
508 void QuickAccess::setDesktopMode(bool mode)
510 m_desktopMode = mode;
513 DetailPopup& QuickAccess::getDetailPopup()
515 return m_detailPopup;
518 UrlHistoryPtr QuickAccess::getUrlHistoryList()
520 return m_urlHistoryList;
523 void QuickAccess::backButtonClicked()
525 if (m_detailPopup.isVisible()) {
526 m_detailPopup.hide();
530 bool QuickAccess::isMostVisitedActive() const
532 return evas_object_visible_get(m_mostVisitedView);
535 void QuickAccess::refreshFocusChain()
537 if (!isMostVisitedActive() && m_after_history_thumb) {
538 m_after_history_thumb = false;
541 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
543 if (!m_parentFocusChain) {
544 m_parentFocusChain = eina_list_clone(elm_object_focus_custom_chain_get(m_parent));
546 elm_object_focus_custom_chain_unset(m_parent);
547 elm_object_focus_custom_chain_set(m_parent, eina_list_clone(m_parentFocusChain));
550 elm_object_focus_custom_chain_append(m_parent, m_mostVisitedButton, NULL);
551 elm_object_focus_custom_chain_append(m_parent, m_bookmarksButton, NULL);
552 if (isMostVisitedActive()) {
553 for (auto tile = m_tiles.begin(); tile != m_tiles.end(); ++tile) {
554 elm_object_focus_custom_chain_append(m_parent, *tile, NULL);
556 // prevent from moving outside of screen
557 elm_object_focus_next_object_set(m_tiles[BIG_TILE_INDEX], m_tiles[BIG_TILE_INDEX], ELM_FOCUS_LEFT);
558 elm_object_focus_next_object_set(m_tiles[TOP_RIGHT_TILE_INDEX], m_tiles[TOP_RIGHT_TILE_INDEX], ELM_FOCUS_RIGHT);
559 elm_object_focus_next_object_set(m_tiles[BOTTOM_RIGHT_TILE_INDEX], m_tiles[BOTTOM_RIGHT_TILE_INDEX], ELM_FOCUS_RIGHT);
561 elm_object_focus_custom_chain_append(m_parent, m_bookmarkGengrid, NULL);
562 elm_object_focus_custom_chain_append(m_parent, m_bookmarkManagerButton, NULL);
563 // prevent from moving outside of screen
564 elm_object_focus_next_object_set(m_bookmarkGengrid, m_bookmarkGengrid, ELM_FOCUS_LEFT);
565 elm_object_focus_next_object_set(m_bookmarkGengrid, m_bookmarkGengrid, ELM_FOCUS_RIGHT);