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>
22 #include <AbstractMainWindow.h>
25 #include "ServiceManager.h"
26 #include "BrowserLogger.h"
27 #include "Tools/EflTools.h"
28 #include "../Tools/BrowserImage.h"
31 namespace tizen_browser{
34 EXPORT_SERVICE(TabUI, "org.tizen.browser.tabui")
36 typedef struct _TabItemData
38 std::shared_ptr<tizen_browser::basic_webengine::TabContent> item;
39 std::shared_ptr<tizen_browser::base_ui::TabUI> tabUI;
44 tizen_browser::base_ui::TabUI* tabUI;
45 Elm_Object_Item * e_item;
49 : m_tab_layout(nullptr)
50 , m_genListActionBar(nullptr)
51 , m_itemClassActionBar(nullptr)
52 , m_genListTop(nullptr)
53 , m_itemClassTop(nullptr)
56 , m_item_class(nullptr)
58 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
59 m_edjFilePath = EDJE_DIR;
60 m_edjFilePath.append("TabUI/TabUI.edj");
68 void TabUI::show(Evas_Object* parent)
70 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
72 elm_theme_extension_add(nullptr, m_edjFilePath.c_str());
73 m_tab_layout = elm_layout_add(parent);
74 elm_layout_file_set(m_tab_layout, m_edjFilePath.c_str(), "tab-layout");
75 evas_object_size_hint_weight_set(m_tab_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
76 evas_object_size_hint_align_set(m_tab_layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
77 evas_object_show(m_tab_layout);
82 m_gengrid = elm_gengrid_add(m_tab_layout);
83 elm_object_part_content_set(m_tab_layout, "tab_gengird", m_gengrid);
85 evas_object_smart_callback_add(m_gengrid, "item,focused", focusItem, nullptr);
86 evas_object_smart_callback_add(m_gengrid, "item,unfocused", unFocusItem, nullptr);
87 evas_object_smart_callback_add(m_gengrid, "activated", _itemSelected, this);
90 m_item_class = elm_gengrid_item_class_new();
91 m_item_class->item_style = "tab_item";
92 m_item_class->func.text_get = _grid_text_get;
93 m_item_class->func.content_get = _tab_grid_content_get;
94 m_item_class->func.state_get = nullptr;
95 m_item_class->func.del = nullptr;
99 elm_gengrid_align_set(m_gengrid, 0, 0);
100 elm_gengrid_select_mode_set(m_gengrid, ELM_OBJECT_SELECT_MODE_ALWAYS);
101 elm_gengrid_multi_select_set(m_gengrid, EINA_FALSE);
102 elm_gengrid_horizontal_set(m_gengrid, EINA_FALSE);
103 elm_gengrid_highlight_mode_set(m_gengrid, EINA_TRUE);
104 elm_scroller_policy_set(m_gengrid, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
105 elm_scroller_page_size_set(m_gengrid, 0, 327);
107 evas_object_size_hint_weight_set(m_gengrid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
108 evas_object_size_hint_align_set(m_gengrid, EVAS_HINT_FILL, EVAS_HINT_FILL);
110 double efl_scale = elm_config_scale_get() / elm_app_base_scale_get();
111 elm_gengrid_item_size_set(m_gengrid, 364 * efl_scale, 320 * efl_scale);
115 void TabUI::showActionBar()
117 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
118 elm_theme_extension_add(nullptr, m_edjFilePath.c_str());
119 m_genListActionBar = elm_genlist_add(m_tab_layout);
120 elm_object_part_content_set(m_tab_layout, "action_bar_genlist", m_genListActionBar);
121 elm_genlist_homogeneous_set(m_genListActionBar, EINA_FALSE);
122 elm_genlist_multi_select_set(m_genListActionBar, EINA_FALSE);
123 elm_genlist_select_mode_set(m_genListActionBar, ELM_OBJECT_SELECT_MODE_ALWAYS);
124 elm_genlist_mode_set(m_genListActionBar, ELM_LIST_LIMIT);
125 elm_genlist_decorate_mode_set(m_genListActionBar, EINA_TRUE);
126 evas_object_size_hint_weight_set(m_genListActionBar, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
128 // evas_object_smart_callback_add(m_genList, "item,focused", focusItem, this);
129 // evas_object_smart_callback_add(m_genList, "item,unfocused", unFocusItem, nullptr);*/
131 m_itemClassActionBar = elm_genlist_item_class_new();
132 m_itemClassActionBar->item_style = "action_bar_items";
133 m_itemClassActionBar->func.text_get = nullptr; // &listTopItemTextGet;
134 m_itemClassActionBar->func.content_get = &listActionBarContentGet;
135 m_itemClassActionBar->func.state_get = nullptr;
136 m_itemClassActionBar->func.del = nullptr;
138 ItemData *id = new ItemData;
140 Elm_Object_Item* elmItem = elm_genlist_item_append(m_genListActionBar, //genlist
141 m_itemClassActionBar, //item Class
143 nullptr, //parent item
144 ELM_GENLIST_ITEM_NONE, //item type
146 nullptr //data passed to above function
148 id->e_item = elmItem;
150 ItemData *id2 = new ItemData;
152 Elm_Object_Item* elmItem2 = elm_genlist_item_append(m_genListActionBar, //genlist
153 m_itemClassActionBar, //item Class
155 nullptr, //parent item
156 ELM_GENLIST_ITEM_NONE, //item type
158 nullptr //data passed to above function
160 id2->e_item = elmItem2;
162 ItemData *id3 = new ItemData;
164 Elm_Object_Item* elmItem3 = elm_genlist_item_append(m_genListActionBar , //genlist
165 m_itemClassActionBar, //item Class
167 nullptr, //parent item
168 ELM_GENLIST_ITEM_NONE, //item type
170 nullptr //data passed to above function
172 id3->e_item = elmItem3;
174 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
177 Evas_Object* TabUI::listActionBarContentGet(void* data, Evas_Object* obj , const char* part)
179 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
181 const char *part_name1 = "newtab_click";
182 static const int part_name1_len = strlen(part_name1);
183 const char *part_name2 = "newincognitotab_clic";
184 static const int part_name2_len = strlen(part_name2);
185 const char *part_name3 = "closetabs_click";
186 static const int part_name3_len = strlen(part_name3);
187 const char *part_name4 = "close_click";
188 static const int part_name4_len = strlen(part_name4);
190 if (!strncmp(part_name1, part, part_name1_len)) {
191 Evas_Object *newtabButton = elm_button_add(obj);
192 elm_object_style_set(newtabButton, "tab_button");
193 evas_object_smart_callback_add(newtabButton, "clicked", tizen_browser::base_ui::TabUI::_newtab_clicked, data);
196 if (!strncmp(part_name2, part, part_name2_len)) {
197 Evas_Object *newincognitotabButton = elm_button_add(obj);
198 elm_object_style_set(newincognitotabButton, "tab_button");
199 evas_object_smart_callback_add(newincognitotabButton, "clicked", tizen_browser::base_ui::TabUI::_newincognitotab_clicked, data);
200 return newincognitotabButton;
202 if (!strncmp(part_name3, part, part_name3_len)) {
203 Evas_Object *closetabsButton = elm_button_add(obj);
204 elm_object_style_set(closetabsButton, "tab_button");
205 evas_object_smart_callback_add(closetabsButton, "clicked", tizen_browser::base_ui::TabUI::_closetabs_clicked, data);
206 return closetabsButton;
208 if (!strncmp(part_name4, part, part_name4_len)) {
209 Evas_Object *close_click = elm_button_add(obj);
210 elm_object_style_set(close_click, "tab_button");
211 evas_object_smart_callback_add(close_click, "clicked", TabUI::close_clicked_cb, data);
218 void TabUI::close_clicked_cb(void* data, Evas_Object*, void*)
220 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
222 ItemData * id = static_cast<ItemData*>(data);
223 id->tabUI->closeTabUIClicked(std::string());
224 id->tabUI->clearItems();
230 evas_object_hide(elm_layout_content_get(m_tab_layout, "action_bar_genlist"));
231 evas_object_hide(elm_layout_content_get(m_tab_layout, "top_bar_genlist"));
232 evas_object_hide(elm_layout_content_get(m_tab_layout, "tab_gengird"));
233 evas_object_hide(m_tab_layout);
236 void TabUI::showTopButtons()
238 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
239 elm_theme_extension_add(nullptr, m_edjFilePath.c_str());
240 m_genListTop = elm_genlist_add(m_tab_layout);
241 elm_object_part_content_set(m_tab_layout, "top_bar_genlist", m_genListTop);
242 elm_genlist_homogeneous_set(m_genListTop, EINA_FALSE);
243 elm_genlist_multi_select_set(m_genListTop, EINA_FALSE);
244 elm_genlist_select_mode_set(m_genListTop, ELM_OBJECT_SELECT_MODE_ALWAYS);
245 elm_genlist_mode_set(m_genListTop, ELM_LIST_LIMIT);
246 elm_genlist_decorate_mode_set(m_genListTop, EINA_TRUE);
247 evas_object_size_hint_weight_set(m_genListTop, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
249 // evas_object_smart_callback_add(m_genList, "item,focused", focusItem, this);
250 // evas_object_smart_callback_add(m_genList, "item,unfocused", unFocusItem, nullptr);
252 m_itemClassTop = elm_genlist_item_class_new();
253 m_itemClassTop->item_style = "top_buttons";
254 m_itemClassTop->func.text_get = nullptr;
255 m_itemClassTop->func.content_get = &listTopButtonItemsContentGet;
256 m_itemClassTop->func.state_get = nullptr;
257 m_itemClassTop->func.del = nullptr;
259 ItemData *id = new ItemData;
261 Elm_Object_Item *elmItem = elm_genlist_item_append(m_genListTop, //genlist
262 m_itemClassTop, //item Class
264 nullptr, //parent item
265 ELM_GENLIST_ITEM_NONE, //item type
267 nullptr //data passed to above function
269 id->e_item = elmItem;
270 ItemData *id2 = new ItemData;
272 Elm_Object_Item *elmItem2 = elm_genlist_item_append(m_genListTop, //genlist
273 m_itemClassTop, //item Class
275 nullptr, //parent item
276 ELM_GENLIST_ITEM_NONE, //item type
278 nullptr //data passed to above function
280 id2->e_item = elmItem2;
282 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
285 Evas_Object* TabUI::listTopButtonItemsContentGet(void* data, Evas_Object* obj , const char* part)
287 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
288 if (data && obj && part) {
289 const char *part_name1 = "openedtabs_button";
290 static const int part_name1_len = strlen(part_name1);
291 const char *part_name2 = "onotherdevices_button";
292 static const int part_name2_len = strlen(part_name2);
294 if (!strncmp(part_name1, part, part_name1_len)) {
295 Evas_Object *openedtabsButton = elm_button_add(obj);
296 elm_object_style_set(openedtabsButton, "tab_button");
297 evas_object_smart_callback_add(openedtabsButton, "clicked", tizen_browser::base_ui::TabUI::_openedtabs_clicked, data);
298 return openedtabsButton;
300 if (!strncmp(part_name2, part, part_name2_len)) {
301 Evas_Object *onotherdevicesButton = elm_button_add(obj);
302 elm_object_style_set(onotherdevicesButton, "tab_button");
303 evas_object_smart_callback_add(onotherdevicesButton, "clicked", tizen_browser::base_ui::TabUI::_onotherdevices_clicked, data);
304 return onotherdevicesButton;
310 void TabUI::_newtab_clicked(void * data, Evas_Object*, void*)
312 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
314 ItemData* itemData = static_cast<ItemData*>(data);
315 itemData->tabUI->clearItems();
316 itemData->tabUI->newTabClicked(std::string());
320 void TabUI::_openedtabs_clicked(void*, Evas_Object*, void*)
322 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
325 void TabUI::_onotherdevices_clicked(void*, Evas_Object*, void*)
327 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
330 void TabUI::_newincognitotab_clicked(void* data, Evas_Object*, void*)
332 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
334 ItemData* itemData = static_cast<ItemData*>(data);
335 itemData->tabUI->clearItems();
336 itemData->tabUI->newIncognitoTabClicked(std::string());
340 void TabUI::_closetabs_clicked(void* data, Evas_Object*, void*)
342 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
344 ItemData* itemData = static_cast<ItemData*>(data);
345 itemData->tabUI->closeTabsClicked(std::string());
349 void TabUI::addTabItem(std::shared_ptr<tizen_browser::basic_webengine::TabContent> hi)
351 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
352 if (m_map_tab_views.size() >= 10)
354 TabItemData *itemData = new TabItemData();
356 itemData->tabUI = std::shared_ptr<tizen_browser::base_ui::TabUI>(this);
357 Elm_Object_Item* tabView = elm_gengrid_item_append(m_gengrid, m_item_class, itemData, nullptr, this);
358 m_map_tab_views.insert(std::pair<std::string,Elm_Object_Item*>(hi->getTitle(),tabView));
360 // unselect by default
361 elm_gengrid_item_selected_set(tabView, EINA_FALSE);
362 setEmptyGengrid(false);
365 void TabUI::addTabItems(std::vector<std::shared_ptr<tizen_browser::basic_webengine::TabContent>>items)
367 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
368 //limiting number of added items to 10
369 auto eit = std::min(items.end(), items.begin() + 10);
370 for (auto it = items.begin(); it != eit; ++it) {
375 char* TabUI::_grid_text_get(void *data, Evas_Object*, const char *part)
377 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
379 TabItemData *itemData = static_cast<TabItemData*>(data);
380 const char *part_name1 = "tab_title";
381 static const int part_name1_len = strlen(part_name1);
382 const char *part_name2 = "tab_url";
383 static const int part_name2_len = strlen(part_name2);
385 if (!strncmp(part_name1, part, part_name1_len)) {
386 return strdup(itemData->item->getTitle().c_str());
388 if (!strncmp(part_name2, part, part_name2_len)) {
389 //return strdup(itemData->item->getUrl().c_str());
396 Evas_Object * TabUI::_tab_grid_content_get(void *data, Evas_Object *obj, const char *part)
398 BROWSER_LOGD("%s:%d %s part=%s", __FILE__, __LINE__, __func__, part);
399 if (data && obj && part) {
400 TabItemData *itemData = static_cast<TabItemData*>(data);
401 const char *part_name1 = "tab_thumbnail";
402 static const int part_name1_len = strlen(part_name1);
403 const char *part_name2 = "tab_thumbButton";
404 static const int part_name2_len = strlen(part_name2);
406 if (!strncmp(part_name2, part, part_name2_len)) {
407 Evas_Object *thumbButton = elm_button_add(obj);
408 elm_object_style_set(thumbButton, "tab_thumbButton");
409 evas_object_smart_callback_add(thumbButton, "clicked", tizen_browser::base_ui::TabUI::_thumbSelected, data);
412 if (!strncmp(part_name1, part, part_name1_len)) {
413 if (itemData->item->getThumbnail()) {
414 return tizen_browser::tools::EflTools::getEvasImage(itemData->item->getThumbnail(), itemData->tabUI->m_parent);
421 void TabUI::_itemSelected(void*, Evas_Object*, void*)
423 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
424 // self->historyClicked(itemData->item);
427 void TabUI::_thumbSelected(void *data, Evas_Object*, void*)
429 BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
431 TabItemData *itemData = static_cast<TabItemData*>(data);
432 itemData->tabUI->clearItems();
433 itemData->tabUI->tabClicked(itemData->item->getId());
437 void TabUI::clearItems()
439 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
441 elm_gengrid_clear(m_gengrid);
442 elm_genlist_clear(m_genListActionBar);
443 elm_genlist_clear(m_genListTop);
444 m_map_tab_views.clear();
447 Evas_Object* TabUI::createNoHistoryLabel()
449 Evas_Object *label = elm_label_add(m_parent);
450 elm_object_text_set(label, "No favorite websites.");
451 evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
452 evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL);
456 void TabUI::setEmptyGengrid(bool setEmpty)
459 elm_object_part_content_set(m_gengrid, "elm.swallow.empty", createNoHistoryLabel());
461 elm_object_part_content_set(m_gengrid, "elm.swallow.empty", nullptr);
465 void TabUI::focusItem(void*, Evas_Object*, void* event_info)
467 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
469 Elm_Object_Item *item = static_cast<Elm_Object_Item*>(event_info);
470 elm_object_item_signal_emit( item, "mouse,in", "over2");
473 elm_gengrid_item_selected_set(item, EINA_TRUE);
477 void TabUI::unFocusItem(void*, Evas_Object*, void* event_info)
479 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
481 Elm_Object_Item *item = static_cast<Elm_Object_Item*>(event_info);
482 elm_object_item_signal_emit( item, "mouse,out", "over2");
484 // unselected manually
485 elm_gengrid_item_selected_set(item, EINA_FALSE);