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"
29 #define efl_scale (elm_config_scale_get() / elm_app_base_scale_get())
31 namespace tizen_browser{
34 EXPORT_SERVICE(QuickAccess, "org.tizen.browser.quickaccess")
36 const int QuickAccess::MAX_TILES_NUMBER = 5;
37 const int QuickAccess::MAX_THUMBNAIL_WIDTH = 840;
38 const int QuickAccess::MAX_THUMBNAIL_HEIGHT = 648;
39 const int QuickAccess::BIG_TILE_INDEX = 0;
40 const int QuickAccess::TOP_RIGHT_TILE_INDEX = 3;
41 const int QuickAccess::BOTTOM_RIGHT_TILE_INDEX = 4;
43 const std::vector<std::string> QuickAccess::TILES_NAMES = {
45 "elm.swallow.small_first",
46 "elm.swallow.small_second",
47 "elm.swallow.small_third",
48 "elm.swallow.small_fourth"
51 typedef struct _HistoryItemData
53 std::shared_ptr<tizen_browser::services::HistoryItem> item;
54 std::shared_ptr<tizen_browser::base_ui::QuickAccess> quickAccess;
57 typedef struct _BookmarkItemData
59 std::shared_ptr<tizen_browser::services::BookmarkItem> item;
60 std::shared_ptr<tizen_browser::base_ui::QuickAccess> quickAccess;
63 QuickAccess::QuickAccess()
66 , m_bookmarksView(nullptr)
67 , m_mostVisitedView(nullptr)
68 , m_bookmarksButton(nullptr)
69 , m_mostVisitedButton(nullptr)
70 , m_bookmarkGengrid(nullptr)
71 , m_bookmarkManagerButton(nullptr)
72 , m_after_history_thumb(false)
73 , m_parentFocusChain(nullptr)
74 , m_bookmark_item_class(nullptr)
77 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
78 edjFilePath = EDJE_DIR;
79 edjFilePath.append("QuickAccess/QuickAccess.edj");
80 elm_theme_extension_add(nullptr, edjFilePath.c_str());
81 QuickAccess::createItemClasses();
84 QuickAccess::~QuickAccess()
86 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
87 elm_gengrid_item_class_free(m_bookmark_item_class);
88 eina_list_free(m_parentFocusChain);
91 void QuickAccess::init(Evas_Object* parent)
98 Evas_Object* QuickAccess::getContent()
102 m_layout = createQuickAccessLayout(m_parent);
107 void QuickAccess::showMostVisited(std::shared_ptr< services::HistoryItemVector > vec)
109 addHistoryItems(vec);
113 void QuickAccess::showBookmarks(std::vector< std::shared_ptr< tizen_browser::services::BookmarkItem > > vec)
115 addBookmarkItems(vec);
119 void QuickAccess::createItemClasses()
121 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
122 if (!m_bookmark_item_class) {
123 m_bookmark_item_class = elm_gengrid_item_class_new();
124 m_bookmark_item_class->item_style = "grid_item";
125 m_bookmark_item_class->func.text_get = _grid_bookmark_text_get;
126 m_bookmark_item_class->func.content_get = _grid_bookmark_content_get;
127 m_bookmark_item_class->func.state_get = nullptr;
128 m_bookmark_item_class->func.del = nullptr;
133 Evas_Object* QuickAccess::createQuickAccessLayout(Evas_Object* parent)
135 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
136 m_desktopMode = true;
138 Evas_Object* layout = elm_layout_add(parent);
139 elm_layout_file_set(layout, edjFilePath.c_str(), "main_layout");
140 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
141 evas_object_size_hint_align_set (layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
143 m_mostVisitedView = createMostVisitedView(layout);
144 m_bookmarksView = createBookmarksView (layout);
149 Evas_Object* QuickAccess::createMostVisitedView (Evas_Object * parent)
151 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
153 Evas_Object* mostVisitedLayout = elm_layout_add(parent);
154 elm_layout_file_set(mostVisitedLayout, edjFilePath.c_str(), "mv_bookmarks");
155 evas_object_size_hint_weight_set(mostVisitedLayout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
156 evas_object_size_hint_align_set (mostVisitedLayout, EVAS_HINT_FILL, EVAS_HINT_FILL);
158 Evas_Object* topButtons = createTopButtons(mostVisitedLayout);
159 elm_object_part_content_set(mostVisitedLayout, "elm.swallow.layoutTop", topButtons);
161 return mostVisitedLayout;
164 Evas_Object* QuickAccess::createBookmarksView (Evas_Object * parent)
166 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
168 Evas_Object *bookmarkViewLayout = elm_layout_add(parent);
169 elm_layout_file_set(bookmarkViewLayout, edjFilePath.c_str(), "mv_bookmarks");
170 evas_object_size_hint_weight_set(bookmarkViewLayout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
171 evas_object_size_hint_align_set(bookmarkViewLayout, EVAS_HINT_FILL, EVAS_HINT_FILL);
173 m_bookmarkGengrid = createBookmarkGengrid(bookmarkViewLayout);
174 elm_object_part_content_set(bookmarkViewLayout, "elm.swallow.grid", m_bookmarkGengrid);
176 Evas_Object* topButtons = createTopButtons(bookmarkViewLayout);
177 elm_object_part_content_set(bookmarkViewLayout, "elm.swallow.layoutTop", topButtons);
179 Evas_Object* bottomButton = createBottomButton(bookmarkViewLayout);
180 elm_object_part_content_set(bookmarkViewLayout, "elm.swallow.layoutBottom", bottomButton);
182 return bookmarkViewLayout;
185 Evas_Object* QuickAccess::createBookmarkGengrid(Evas_Object *parent)
187 Evas_Object *bookmarkGengrid = elm_gengrid_add(parent);
189 elm_gengrid_align_set(bookmarkGengrid, 0, 0);
190 elm_gengrid_select_mode_set(bookmarkGengrid, ELM_OBJECT_SELECT_MODE_ALWAYS);
191 elm_gengrid_multi_select_set(bookmarkGengrid, EINA_FALSE);
192 elm_gengrid_horizontal_set(bookmarkGengrid, EINA_FALSE);
194 elm_scroller_policy_set(bookmarkGengrid, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
195 elm_scroller_page_size_set(bookmarkGengrid, 0, 327);
196 evas_object_size_hint_weight_set(bookmarkGengrid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
197 evas_object_size_hint_align_set(bookmarkGengrid, EVAS_HINT_FILL, EVAS_HINT_FILL);
198 elm_gengrid_item_size_set(bookmarkGengrid, 364 * efl_scale, 320 * efl_scale);
200 return bookmarkGengrid;
203 Evas_Object* QuickAccess::createTopButtons (Evas_Object *parent)
205 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
207 Evas_Object *layoutTop = elm_layout_add(parent);
208 elm_layout_file_set(layoutTop, edjFilePath.c_str(), "top_button_item");
209 evas_object_size_hint_weight_set(layoutTop, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
210 evas_object_size_hint_align_set(layoutTop, EVAS_HINT_FILL, EVAS_HINT_FILL);
211 evas_object_show(layoutTop);
213 Evas_Object *mostVisitedButton = elm_button_add(layoutTop);
214 elm_object_style_set(mostVisitedButton, "invisible_button");
215 evas_object_smart_callback_add(mostVisitedButton, "clicked", _mostVisited_clicked, this);
216 evas_object_show(mostVisitedButton);
217 elm_layout_content_set(layoutTop, "mostvisited_click", mostVisitedButton);
218 m_mostVisitedButton = mostVisitedButton;
220 Evas_Object *bookmarksButton = elm_button_add(layoutTop);
221 elm_object_style_set(bookmarksButton, "invisible_button");
222 evas_object_smart_callback_add(bookmarksButton, "clicked", _bookmark_clicked, this);
223 evas_object_show(bookmarksButton);
224 elm_layout_content_set(layoutTop, "bookmark_click", bookmarksButton);
225 m_bookmarksButton = bookmarksButton;
230 Evas_Object* QuickAccess::createBottomButton(Evas_Object *parent)
232 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
234 Evas_Object *layoutBottom = elm_layout_add(parent);
235 elm_layout_file_set(layoutBottom, edjFilePath.c_str(), "bottom_button_item");
237 evas_object_size_hint_weight_set(layoutBottom, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
238 evas_object_size_hint_align_set(layoutBottom, EVAS_HINT_FILL, EVAS_HINT_FILL);
239 evas_object_show(layoutBottom);
241 m_bookmarkManagerButton = elm_button_add(layoutBottom);
242 elm_object_style_set(m_bookmarkManagerButton, "invisible_button");
243 evas_object_smart_callback_add(m_bookmarkManagerButton, "clicked", _bookmark_manager_clicked, this);
244 evas_object_show(m_bookmarkManagerButton);
246 elm_object_part_content_set(layoutBottom, "bookmarkmanager_click", m_bookmarkManagerButton);
252 void QuickAccess::_mostVisited_clicked(void * data, Evas_Object *, void *)
254 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
255 QuickAccess* quickAccess = reinterpret_cast<QuickAccess *>(data);
256 quickAccess->mostVisitedClicked();
259 void QuickAccess::_bookmark_clicked(void * data, Evas_Object *, void *)
261 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
262 QuickAccess* quickAccess = reinterpret_cast<QuickAccess *>(data);
263 quickAccess->bookmarkClicked();
266 void QuickAccess::_bookmark_manager_clicked(void * data, Evas_Object *, void *)
268 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
269 QuickAccess* quickAccess = static_cast<QuickAccess *>(data);
270 quickAccess->bookmarkManagerClicked();
273 void QuickAccess::addHistoryItem(std::shared_ptr<services::HistoryItem> hi)
275 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
276 M_ASSERT(m_historyItems.size() < MAX_TILES_NUMBER);
278 int tileNumber = m_historyItems.size();
279 HistoryItemData *itemData = new HistoryItemData();
281 itemData->quickAccess = std::shared_ptr<QuickAccess>(this);
283 Evas_Object* tile = elm_button_add(m_mostVisitedView);
284 if (tileNumber == BIG_TILE_INDEX)
285 elm_object_style_set(tile, "big_tile");
287 elm_object_style_set(tile, "small_tile");
288 evas_object_size_hint_weight_set(tile, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
289 evas_object_size_hint_align_set (tile, EVAS_HINT_FILL, EVAS_HINT_FILL);
290 evas_object_show(tile);
291 elm_object_part_content_set(m_mostVisitedView, TILES_NAMES[tileNumber].c_str(), tile);
292 m_tiles.push_back(tile);
294 elm_layout_text_set(tile, "page_title", hi->getTitle().c_str());
295 elm_layout_text_set(tile, "page_url", hi->getUrl().c_str());
296 Evas_Object * thumb = tizen_browser::tools::EflTools::getEvasImage(hi->getThumbnail(), m_parent);
297 elm_object_part_content_set(tile, "elm.thumbnail", thumb);
298 evas_object_smart_callback_add(tile, "clicked", _thumbHistoryClicked, itemData);
300 m_historyItems.push_back(hi);
303 void QuickAccess::addHistoryItems(std::shared_ptr<services::HistoryItemVector> items)
305 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
306 clearHistoryGenlist();
308 for (auto it = items->begin(); it != items->end(); ++it) {
310 if (i > MAX_TILES_NUMBER)
318 void QuickAccess::addBookmarkItem(std::shared_ptr<tizen_browser::services::BookmarkItem> bi)
320 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
321 BookmarkItemData *itemData = new BookmarkItemData();
323 itemData->quickAccess = std::shared_ptr<tizen_browser::base_ui::QuickAccess>(this);
324 elm_gengrid_item_append(m_bookmarkGengrid, m_bookmark_item_class, itemData, _thumbBookmarkClicked, itemData);
327 void QuickAccess::addBookmarkItems(std::vector<std::shared_ptr<tizen_browser::services::BookmarkItem> > items)
329 clearBookmarkGengrid();
330 for (auto it = items.begin(); it != items.end(); ++it) {
331 addBookmarkItem(*it);
336 char* QuickAccess::_grid_bookmark_text_get(void *data, Evas_Object *, const char *part)
338 BookmarkItemData *itemData = reinterpret_cast<BookmarkItemData*>(data);
339 if (!strcmp(part, "page_title")) {
340 return strdup(itemData->item->getTittle().c_str());
342 if (!strcmp(part, "page_url")) {
343 return strdup(itemData->item->getAddress().c_str());
348 Evas_Object * QuickAccess::_grid_bookmark_content_get(void *data, Evas_Object*, const char *part)
350 BROWSER_LOGD("%s:%d %s part=%s", __FILE__, __LINE__, __func__, part);
351 BookmarkItemData *itemData = reinterpret_cast<BookmarkItemData*>(data);
353 if (!strcmp(part, "elm.thumbnail")) {
354 if (itemData->item->getThumbnail()) {
355 Evas_Object * thumb = tizen_browser::tools::EflTools::getEvasImage(itemData->item->getThumbnail(), itemData->quickAccess->m_parent);
366 void QuickAccess::_thumbBookmarkClicked(void * data, Evas_Object * , void *)
368 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
369 HistoryItemData * itemData = reinterpret_cast<HistoryItemData *>(data);
370 itemData->quickAccess->openURLInNewTab(itemData->item, itemData->quickAccess->isDesktopMode());
371 itemData->quickAccess->m_after_history_thumb = false;
374 void QuickAccess::_thumbHistoryClicked(void* data, Evas_Object*, void*)
376 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
377 HistoryItemData * itemData = reinterpret_cast<HistoryItemData *>(data);
378 itemData->quickAccess->mostVisitedTileClicked(itemData->item, DetailPopup::HISTORY_ITEMS_NO);
379 itemData->quickAccess->m_after_history_thumb = true;
382 void QuickAccess::clearHistoryGenlist()
384 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
386 for (auto it = m_tiles.begin(); it != m_tiles.end(); ++it) {
387 evas_object_smart_callback_del(*it, "clicked", _thumbHistoryClicked);
388 evas_object_del(*it);
392 m_historyItems.clear();
395 void QuickAccess::showHistory()
397 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
399 if (elm_layout_content_get(m_layout, "view") == m_mostVisitedView)
402 evas_object_hide(m_bookmarksView);
403 elm_layout_content_unset(m_layout, "view");
404 elm_layout_content_set(m_layout, "view", m_mostVisitedView);
405 evas_object_show(m_mostVisitedView);
408 if (m_historyItems.empty()) {
413 evas_object_show(m_layout);
415 elm_object_focus_set(m_mostVisitedButton, true);
418 void QuickAccess::clearBookmarkGengrid()
420 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
421 elm_gengrid_clear(m_bookmarkGengrid);
424 void QuickAccess::showBookmarks()
426 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
428 if (elm_layout_content_get(m_layout, "view") == m_bookmarksView && m_bookmarksView != nullptr)
431 evas_object_hide(m_mostVisitedView);
432 elm_layout_content_unset(m_layout, "view");
433 elm_layout_content_set(m_layout, "view", m_bookmarksView);
434 evas_object_show(m_bookmarksView);
436 evas_object_show(m_layout);
438 elm_object_focus_set(m_bookmarksButton, true);
441 void QuickAccess::showUI()
443 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
444 evas_object_show(m_layout);
445 if (elm_layout_content_get(m_layout, "view") == m_bookmarksView) {
446 evas_object_show(m_bookmarksView);
448 evas_object_show(m_mostVisitedView);
452 void QuickAccess::hideUI()
454 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
455 evas_object_hide(m_layout);
456 evas_object_hide(m_mostVisitedView);
457 evas_object_hide(m_bookmarksView);
458 clearHistoryGenlist();
459 clearBookmarkGengrid();
462 void QuickAccess::openDetailPopup(std::shared_ptr<services::HistoryItem> currItem, std::shared_ptr<services::HistoryItemVector> prevItems)
464 m_detailPopup.show(m_layout, m_parent, currItem, prevItems);
467 void QuickAccess::showNoHistoryLabel()
469 elm_layout_text_set(m_mostVisitedView, "elm.text.empty", "No visited site");
470 elm_layout_signal_emit(m_mostVisitedView, "empty,view", "quickaccess");
473 void QuickAccess::setEmptyView(bool empty)
475 BROWSER_LOGD("%s:%d %s, empty: %d", __FILE__, __LINE__, __func__, empty);
477 showNoHistoryLabel();
479 elm_layout_signal_emit(m_mostVisitedView, "not,empty,view", "quickaccess");
483 bool QuickAccess::isDesktopMode() const
485 return m_desktopMode;
488 void QuickAccess::setDesktopMode(bool mode)
490 m_desktopMode = mode;
493 DetailPopup& QuickAccess::getDetailPopup()
495 return m_detailPopup;
498 void QuickAccess::backButtonClicked()
500 if (m_detailPopup.isVisible()) {
501 m_detailPopup.hide();
504 switchViewToWebPage();
508 bool QuickAccess::isMostVisitedActive() const
510 return evas_object_visible_get(m_mostVisitedView);
513 void QuickAccess::refreshFocusChain()
515 if (!isMostVisitedActive() && m_after_history_thumb) {
516 m_after_history_thumb = false;
519 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
521 if (!m_parentFocusChain) {
522 m_parentFocusChain = eina_list_clone(elm_object_focus_custom_chain_get(m_parent));
524 elm_object_focus_custom_chain_unset(m_parent);
525 elm_object_focus_custom_chain_set(m_parent, eina_list_clone(m_parentFocusChain));
528 elm_object_focus_custom_chain_append(m_parent, m_mostVisitedButton, NULL);
529 elm_object_focus_custom_chain_append(m_parent, m_bookmarksButton, NULL);
530 if (isMostVisitedActive()) {
531 for (auto tile = m_tiles.begin(); tile != m_tiles.end(); ++tile) {
532 elm_object_focus_custom_chain_append(m_parent, *tile, NULL);
534 // prevent from moving outside of screen
535 elm_object_focus_next_object_set(m_tiles[BIG_TILE_INDEX], m_tiles[BIG_TILE_INDEX], ELM_FOCUS_LEFT);
536 elm_object_focus_next_object_set(m_tiles[TOP_RIGHT_TILE_INDEX], m_tiles[TOP_RIGHT_TILE_INDEX], ELM_FOCUS_RIGHT);
537 elm_object_focus_next_object_set(m_tiles[BOTTOM_RIGHT_TILE_INDEX], m_tiles[BOTTOM_RIGHT_TILE_INDEX], ELM_FOCUS_RIGHT);
539 elm_object_focus_custom_chain_append(m_parent, m_bookmarkGengrid, NULL);
540 elm_object_focus_custom_chain_append(m_parent, m_bookmarkManagerButton, NULL);
541 // prevent from moving outside of screen
542 elm_object_focus_next_object_set(m_bookmarkGengrid, m_bookmarkGengrid, ELM_FOCUS_LEFT);
543 elm_object_focus_next_object_set(m_bookmarkGengrid, m_bookmarkGengrid, ELM_FOCUS_RIGHT);