2 * Copyright (c) 2015 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 "MoreMenuUI.h"
23 #include "ServiceManager.h"
24 #include "BrowserLogger.h"
25 #include "Tools/EflTools.h"
26 #include "../Tools/BrowserImage.h"
28 #define efl_scale (elm_config_scale_get() / elm_app_base_scale_get())
30 namespace tizen_browser{
33 EXPORT_SERVICE(MoreMenuUI, "org.tizen.browser.moremenuui")
36 tizen_browser::base_ui::MoreMenuUI * m_moreMenu;
37 std::shared_ptr<tizen_browser::services::HistoryItem> h_item;
38 Elm_Object_Item * e_item;
41 typedef struct _MoreItemData
44 std::shared_ptr<tizen_browser::base_ui::MoreMenuUI> moreMenuUI;
47 MoreMenuUI::MoreMenuUI()
48 : m_current_tab_bar(nullptr)
49 , m_mm_layout(nullptr)
52 , m_toastPopup(nullptr)
54 , m_bookmarkIcon(nullptr)
55 , m_item_class(nullptr)
59 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
60 m_edjFilePath = EDJE_DIR;
61 m_edjFilePath.append("MoreMenuUI/MoreMenu.edj");
62 m_item_class = createItemClass();
65 MoreMenuUI::~MoreMenuUI()
67 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
69 elm_gengrid_item_class_free(m_item_class);
70 evas_object_del(m_gengrid);
73 Elm_Gengrid_Item_Class* MoreMenuUI::createItemClass()
75 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
76 Elm_Gengrid_Item_Class* item_class = elm_gengrid_item_class_new();
77 item_class->item_style = "menu_item";
78 item_class->func.text_get = _grid_text_get;
79 item_class->func.content_get = _grid_content_get;
80 item_class->func.state_get = NULL;
81 item_class->func.del = NULL;
85 void MoreMenuUI::init(Evas_Object* parent)
87 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
93 void MoreMenuUI::showUI()
95 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
96 M_ASSERT(m_mm_layout);
97 createGengrid(); // recreate gengrid because icons could have changed
99 evas_object_show(m_mm_layout);
100 evas_object_show(elm_object_part_content_get(m_mm_layout,"current_tab_bar"));
101 m_focusManager.startFocusManager(m_gengrid);
102 evas_object_show(m_gengrid);
106 void MoreMenuUI::hideUI()
108 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
109 M_ASSERT(m_mm_layout);
110 setFocus(EINA_FALSE);
111 evas_object_hide(m_mm_layout);
112 evas_object_hide(elm_object_part_content_get(m_mm_layout,"current_tab_bar"));
114 evas_object_del(m_gengrid);
115 m_focusManager.stopFocusManager();
119 Evas_Object* MoreMenuUI::getContent()
121 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
123 createMoreMenuLayout();
127 void MoreMenuUI::createMoreMenuLayout()
129 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
131 elm_theme_extension_add(NULL, m_edjFilePath.c_str());
132 m_mm_layout = elm_layout_add(m_parent);
133 elm_layout_file_set(m_mm_layout, m_edjFilePath.c_str(), "moremenu-layout");
134 evas_object_size_hint_weight_set(m_mm_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
135 evas_object_size_hint_align_set(m_mm_layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
138 void MoreMenuUI::createGengrid()
140 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
141 m_gengrid = elm_gengrid_add(m_mm_layout);
142 elm_object_part_content_set(m_mm_layout, "elm.swallow.grid", m_gengrid);
144 elm_gengrid_align_set(m_gengrid, 0, 0);
145 elm_gengrid_select_mode_set(m_gengrid, ELM_OBJECT_SELECT_MODE_ALWAYS);
146 elm_gengrid_multi_select_set(m_gengrid, EINA_FALSE);
147 elm_gengrid_horizontal_set(m_gengrid, EINA_FALSE);
148 elm_scroller_policy_set(m_gengrid, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
149 elm_scroller_page_size_set(m_gengrid, 0, 327);
150 evas_object_size_hint_weight_set(m_gengrid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
151 evas_object_size_hint_align_set(m_gengrid, EVAS_HINT_FILL, EVAS_HINT_FILL);
152 elm_gengrid_item_size_set(m_gengrid, 364 * efl_scale, 320 * efl_scale);
153 evas_object_show(m_gengrid);
156 void MoreMenuUI::showCurrentTab()
158 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
159 m_current_tab_bar = elm_layout_add(m_mm_layout);
160 elm_layout_file_set(m_current_tab_bar, m_edjFilePath.c_str(), "current_tab_layout");
161 evas_object_size_hint_weight_set(m_current_tab_bar, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
162 elm_object_part_content_set(m_mm_layout, "current_tab_bar", m_current_tab_bar);
164 Evas_Object* button = elm_button_add(m_current_tab_bar);
165 elm_object_style_set(button, "hidden_button");
166 evas_object_smart_callback_add(button, "clicked", _close_clicked, this);
167 elm_object_part_content_set(m_current_tab_bar, "close_click", button);
168 evas_object_show(button);
169 elm_object_focus_set(button, EINA_TRUE);
171 m_bookmarkButton = elm_button_add(m_mm_layout);
172 elm_object_style_set(m_bookmarkButton, "hidden_button");
173 evas_object_show(m_bookmarkButton);
174 evas_object_smart_callback_add(m_bookmarkButton, "clicked", _star_clicked, this);
176 m_bookmarkIcon = elm_icon_add(m_mm_layout);
177 elm_object_part_content_set(m_current_tab_bar, "bookmark_ico", m_bookmarkIcon);
178 elm_object_part_content_set(m_current_tab_bar, "star_click", m_bookmarkButton);
182 void MoreMenuUI::setFavIcon(std::shared_ptr<tizen_browser::tools::BrowserImage> favicon)
184 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
185 if(favicon && favicon->imageType != tools::BrowserImage::ImageTypeNoImage) {
187 evas_object_del(m_icon);
189 m_icon = tizen_browser::tools::EflTools::getEvasImage(favicon, m_current_tab_bar);
191 evas_object_size_hint_weight_set(m_icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
192 evas_object_size_hint_align_set(m_icon, EVAS_HINT_FILL, EVAS_HINT_FILL);
193 elm_object_part_content_set(m_current_tab_bar, "favicon", m_icon);
194 evas_object_show(m_icon);
202 void MoreMenuUI::setDocIcon()
204 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
206 evas_object_del(m_icon);
208 m_icon = elm_icon_add(m_mm_layout);
209 elm_image_file_set(m_icon, m_edjFilePath.c_str(), "ico_url.png");
210 evas_object_size_hint_weight_set(m_icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
211 evas_object_size_hint_align_set(m_icon, EVAS_HINT_FILL, EVAS_HINT_FILL);
212 elm_object_part_content_set(m_current_tab_bar, "favicon", m_icon);
215 void MoreMenuUI::setWebTitle(const std::string& title)
217 BROWSER_LOGD("[%s:%d] %s", __PRETTY_FUNCTION__, __LINE__, title.c_str());
218 elm_object_part_text_set(m_current_tab_bar, "webpage_title", title.c_str());
221 void MoreMenuUI::setURL(const std::string& url)
223 BROWSER_LOGD("[%s:%d] %s", __PRETTY_FUNCTION__, __LINE__, url.c_str());
226 elm_object_part_text_set(m_current_tab_bar, "webpage_url", url.c_str());
228 if(true == isBookmark()) {
229 m_isBookmark = EINA_TRUE;
230 changeBookmarkStatus(true);
231 enableAddToBookmarkButton(true);
234 m_isBookmark = EINA_FALSE;
235 changeBookmarkStatus(false);
236 enableAddToBookmarkButton(true);
240 m_isBookmark = EINA_FALSE;
241 elm_object_part_text_set(m_current_tab_bar, "webpage_url", "");
242 elm_object_part_text_set(m_current_tab_bar, "webpage_title", "No Content");
243 changeBookmarkStatus(false);
244 enableAddToBookmarkButton(false);
248 void MoreMenuUI::setHomePageInfo()
254 void MoreMenuUI::changeBookmarkStatus(bool data)
257 m_isBookmark = EINA_TRUE;
258 elm_object_part_text_set(m_current_tab_bar, "add_to_bookmark_text", "Remove Bookmark");
259 elm_image_file_set(m_bookmarkIcon, m_edjFilePath.c_str(), "ic_add_bookmark.png");
262 m_isBookmark = EINA_FALSE;
263 elm_object_part_text_set(m_current_tab_bar, "add_to_bookmark_text", "Add to bookmarks");
264 elm_image_file_set(m_bookmarkIcon, m_edjFilePath.c_str(), "ic_add_bookmark_new.png");
268 void MoreMenuUI::enableAddToBookmarkButton(bool data)
270 if (m_bookmarkButton) {
271 elm_object_disabled_set(m_bookmarkButton, data ? EINA_FALSE : EINA_TRUE);
272 elm_object_style_set(m_bookmarkButton, data ? "hidden_button" : "dimmed_button");
276 void MoreMenuUI::createToastPopup(const char* text)
278 m_toastPopup = elm_popup_add(m_mm_layout);
279 elm_object_style_set(m_toastPopup, "toast");
280 evas_object_size_hint_weight_set(m_toastPopup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
281 evas_object_size_hint_align_set(m_toastPopup, EVAS_HINT_FILL, EVAS_HINT_FILL);
282 elm_object_part_content_set(m_current_tab_bar, "toast_popup", m_toastPopup);
283 elm_object_part_text_set(m_current_tab_bar, "toast_text", text);
284 evas_object_smart_callback_add(m_toastPopup, "timeout", _timeout, this);
285 elm_popup_timeout_set(m_toastPopup, 3.0);
288 void MoreMenuUI::_timeout(void *data, Evas_Object*, void*)
290 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
291 MoreMenuUI *moreMenuUI = static_cast<MoreMenuUI*>(data);
292 elm_object_part_text_set(moreMenuUI->m_current_tab_bar, "toast_text", "");
293 evas_object_del(moreMenuUI->m_toastPopup);
296 void MoreMenuUI::_star_clicked(void* data, Evas_Object*, void*)
298 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
300 MoreMenuUI *moreMenuUI = static_cast<MoreMenuUI*>(data);
302 if (EINA_FALSE == moreMenuUI->m_isBookmark) {
303 moreMenuUI->addToBookmarkClicked(0);
306 moreMenuUI->m_isBookmark = EINA_FALSE;
307 moreMenuUI->deleteBookmark();
312 void MoreMenuUI::_close_clicked(void* data, Evas_Object*, void*)
314 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
316 MoreMenuUI *moreMenuUI = static_cast<MoreMenuUI*>(data);
317 moreMenuUI->closeMoreMenuClicked();
322 void MoreMenuUI::addItems()
324 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
325 for (int i = 0; i <= EXIT_BROWSER; i++) {
326 ItemType type = static_cast<ItemType>(i);
327 // take proper image for desktop/mobile view
328 if (type == ItemType::VIEW_DESKTOP_WEB && m_desktopMode)
330 if (type == ItemType::VIEW_MOBILE_WEB && !m_desktopMode)
333 MoreMenuItemData *itemData = new MoreMenuItemData();
334 itemData->item = type;
335 itemData->moreMenuUI = std::shared_ptr<tizen_browser::base_ui::MoreMenuUI>(this);
336 Elm_Object_Item* bookmarkView = elm_gengrid_item_append(m_gengrid, m_item_class, itemData, _thumbSelected, itemData);
337 m_map_menu_views.insert(std::pair<ItemType, Elm_Object_Item*>(itemData->item, bookmarkView));
338 elm_gengrid_item_selected_set(bookmarkView, EINA_FALSE);
342 void MoreMenuUI::clearItems()
344 BROWSER_LOGD("[%s:%d]", __PRETTY_FUNCTION__, __LINE__);
345 for (auto it = m_map_menu_views.begin(); it != m_map_menu_views.end(); ++it) {
346 Elm_Object_Item* bookmarkView = it->second;
347 Evas_Object *button = elm_object_item_part_content_get(it->second, "thumbbutton_item");
348 evas_object_event_callback_del(button, EVAS_CALLBACK_MOUSE_IN, __cb_mouse_in);
349 evas_object_event_callback_del(button, EVAS_CALLBACK_MOUSE_OUT, __cb_mouse_out);
352 elm_gengrid_clear(m_gengrid);
353 m_map_menu_views.clear();
356 char* MoreMenuUI::_grid_text_get(void* data, Evas_Object*, const char* part)
358 BROWSER_LOGD("%s:%d %s part=%s", __FILE__, __LINE__, __func__, part);
360 MoreMenuItemData *itemData = static_cast<MoreMenuItemData*>(data);
361 const char *part_name = "menu_label";
362 static const int part_name_len = strlen(part_name);
364 if (!strncmp(part_name, part, part_name_len)) {
365 const char* item_name = NULL;
366 switch (itemData->item) {
367 #ifdef READER_MODE_ENABLED
369 item_name = "Reader mode";
372 case BOOKMARK_MANAGER:
373 item_name = "Bookmark Manager";
376 item_name = "History Manager";
379 item_name = "Screen Zoom";
381 #ifdef START_MINIBROWSER_ENABLED
382 case START_MINIBROWSER:
383 item_name = "Start Mini Browser";
386 case VIEW_MOBILE_WEB:
387 item_name = "View Mobile Web";
389 case VIEW_DESKTOP_WEB:
390 item_name = "View Desktop Web";
396 item_name = "Settings";
399 item_name = "Exit Browser";
404 return strdup(item_name);
410 static const char* getImageFileNameForType(ItemType type, bool focused)
412 const char* file_name = NULL;
414 #ifdef READER_MODE_ENABLED
416 file_name = focused ? "ic_more_readermode_foc.png" : "ic_more_readermode_nor.png";
419 case BOOKMARK_MANAGER:
420 file_name = focused ? "ic_more_bookmark_foc.png" : "ic_more_bookmark_nor.png";
423 file_name = focused ? "ic_more_history_foc.png" : "ic_more_history_nor.png";
426 file_name = focused ? "ic_more_zoom_foc.png" : "ic_more_zoom_nor.png";
428 #ifdef START_MINIBROWSER_ENABLED
429 case START_MINIBROWSER:
430 file_name = focused ? "ic_more_minibrowser_foc.png" : "ic_more_minibrowser_nor.png";
433 case VIEW_MOBILE_WEB:
434 file_name = focused ? "ic_more_mobileview_foc.png" : "ic_more_mobileview_nor.png";
436 case VIEW_DESKTOP_WEB:
437 file_name = focused ? "ic_more_desktopview_foc.png" : "ic_more_desktopview_nor.png";
440 file_name = focused ? "ic_more_share_foc.png" : "ic_more_share_nor.png";
443 file_name = focused ? "ic_more_setting_foc.png" : "ic_more_setting_nor.png";
446 file_name = focused ? "ic_more_exit_foc.png" : "ic_more_exit_nor.png";
454 Evas_Object * MoreMenuUI::_grid_content_get(void *data, Evas_Object *obj, const char *part)
456 BROWSER_LOGD("%s:%d %s part=%s", __FILE__, __LINE__, __func__, part);
457 if (data && obj && part) {
458 MoreMenuItemData *itemData = static_cast<MoreMenuItemData*>(data);
459 const char *part_name1 = "thumbnail_item";
460 static const int part_name1_len = strlen(part_name1);
461 const char *part_name2 = "thumbbutton_item";
462 static const int part_name2_len = strlen(part_name2);
464 if (!strncmp(part_name1, part, part_name1_len)) {
465 Evas_Object* thumb_nail = elm_icon_add(obj);
466 const char* file_name = getImageFileNameForType(itemData->item, false);
467 elm_image_file_set(thumb_nail, itemData->moreMenuUI->m_edjFilePath.c_str(), file_name);
471 if (!strncmp(part_name2, part, part_name2_len)) {
472 Evas_Object *thumbButton = elm_button_add(obj);
473 elm_object_style_set(thumbButton, "clickButton");
474 evas_object_event_callback_add(thumbButton, EVAS_CALLBACK_MOUSE_IN, __cb_mouse_in, data);
475 evas_object_event_callback_add(thumbButton, EVAS_CALLBACK_MOUSE_OUT, __cb_mouse_out, data);
482 void MoreMenuUI::__cb_mouse_in(void * data, Evas *, Evas_Object *obj, void *)
484 BROWSER_LOGD("[%s:%d]", __PRETTY_FUNCTION__, __LINE__);
486 elm_object_focus_set(obj, EINA_TRUE);
488 MoreMenuItemData *itemData = static_cast<MoreMenuItemData*>(data);
489 const char *file_name = getImageFileNameForType(itemData->item, true);
490 Elm_Object_Item *selected = itemData->moreMenuUI->m_map_menu_views[itemData->item];
491 Evas_Object *thumb_nail = elm_object_item_part_content_get(selected, "thumbnail_item");
492 elm_image_file_set(thumb_nail, itemData->moreMenuUI->m_edjFilePath.c_str(), file_name);
496 void MoreMenuUI::__cb_mouse_out(void * data, Evas *, Evas_Object *obj, void *)
498 BROWSER_LOGD("[%s:%d]", __PRETTY_FUNCTION__, __LINE__);
500 elm_object_focus_set(obj, EINA_FALSE);
502 MoreMenuItemData *itemData = static_cast<MoreMenuItemData*>(data);
503 const char *file_name = getImageFileNameForType(itemData->item, false);
504 Elm_Object_Item *selected = itemData->moreMenuUI->m_map_menu_views[itemData->item];
505 Evas_Object *thumb_nail = elm_object_item_part_content_get(selected, "thumbnail_item");
506 elm_image_file_set(thumb_nail, itemData->moreMenuUI->m_edjFilePath.c_str(), file_name);
510 void MoreMenuUI::_thumbSelected(void* data, Evas_Object*, void*)
512 BROWSER_LOGD("[%s:%d]", __PRETTY_FUNCTION__, __LINE__);
514 MoreMenuItemData *itemData = static_cast<MoreMenuItemData*>(data);
515 BROWSER_LOGD("type: %d", itemData->item);
516 switch (itemData->item) {
518 itemData->moreMenuUI->historyUIClicked();
521 itemData->moreMenuUI->settingsClicked();
523 case BOOKMARK_MANAGER:
524 itemData->moreMenuUI->bookmarkManagerClicked();
526 #ifdef READER_MODE_ENABLED
528 //TODO: Implement reader mode
532 itemData->moreMenuUI->zoomUIClicked();
534 #ifdef START_MINIBROWSER_ENABLED
535 case START_MINIBROWSER:
536 //TODO: Implement minibrowser launching
539 case VIEW_MOBILE_WEB:
540 itemData->moreMenuUI->switchToMobileMode();
541 itemData->moreMenuUI->m_desktopMode = false;
542 itemData->moreMenuUI->closeMoreMenuClicked();
544 case VIEW_DESKTOP_WEB:
545 itemData->moreMenuUI->switchToDesktopMode();
546 itemData->moreMenuUI->m_desktopMode = true;
547 itemData->moreMenuUI->closeMoreMenuClicked();
555 BROWSER_LOGD("[%s:%d] Warning: Unhandled button.", __PRETTY_FUNCTION__, __LINE__);
561 void MoreMenuUI::_exitClicked()
563 BROWSER_LOGD("[%s:%d]", __PRETTY_FUNCTION__, __LINE__);
567 void MoreMenuUI::setFocus(Eina_Bool focusable)
569 BROWSER_LOGD("[%s:%d]", __PRETTY_FUNCTION__, __LINE__);
570 elm_object_tree_focus_allow_set(getContent(), focusable);
571 if (focusable == EINA_TRUE)
572 elm_object_focus_set(elm_object_part_content_get(m_current_tab_bar, "close_click"), focusable);
575 void MoreMenuUI::createFocusVector()
577 BROWSER_LOGD("[%s:%d]", __PRETTY_FUNCTION__, __LINE__);
578 m_focusManager.addItem(elm_object_part_content_get(m_current_tab_bar, "close_click"));
579 m_focusManager.addItem(m_bookmarkButton);
580 m_focusManager.addItem(m_gengrid);
581 m_focusManager.setIterator();