Task TT-75 Implement "Main page loading UI" view
[profile/tv/apps/web/browser.git] / services / SimpleUI / BookmarksManager.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "BookmarksManager.h"
18 #include <memory>
19 #include <string>
20 #include <iostream>
21 #include <Eina.h>
22 #include <Evas.h>
23 #include "BrowserLogger.h"
24
25 namespace tizen_browser
26 {
27 namespace base_ui
28 {
29
30 BookmarksManagerItem::BookmarksManagerItem()
31     : action(std::make_shared<Action>())
32 {
33
34 }
35 BookmarksManagerItem::BookmarksManagerItem( std::shared_ptr<Action> action)
36     : action(action)
37 {
38
39 }
40
41
42 BookmarksManagerItem::BookmarksManagerItem(const BookmarksManagerItem& source)
43     : action(source.action)
44 {
45
46 }
47 BookmarksManagerItem::BookmarksManagerItem(const BookmarksManagerItem* source)
48     : action(source->action)
49 {
50
51 }
52
53
54 BookmarksManagerItem::~BookmarksManagerItem()
55 {
56     //elm_genlist_item_class_free(m_itemClass);??
57 }
58
59 BookmarksManager::BookmarksManager(std::shared_ptr< Evas_Object > mainWindow, Evas_Object* parentButton)
60     : MenuButton(mainWindow, parentButton)
61     , m_popup (nullptr)
62     , m_isPopupShown (false)
63     , m_genlist(nullptr)
64     , m_itemClass(nullptr)
65     , m_internalPopup(nullptr)
66     , m_internalPopupVisible(false)
67     , m_pointerModeEnabled(true)
68 {
69     std::string edjFilePath = EDJE_DIR;
70     edjFilePath.append("SimpleUI/BookmarksManager.edj");
71     elm_theme_extension_add(0, edjFilePath.c_str());
72
73     m_genlist = elm_genlist_add(m_window.get());
74
75     evas_object_smart_callback_add(m_genlist, "item,focused", focusItem, nullptr);
76     evas_object_smart_callback_add(m_genlist, "item,unfocused", unFocusItem, nullptr);
77
78     elm_object_style_set(m_genlist, "bookmarks_manager");
79     elm_genlist_homogeneous_set(m_genlist, EINA_TRUE);
80     elm_genlist_multi_select_set(m_genlist, EINA_FALSE);
81
82     elm_genlist_select_mode_set(m_genlist, ELM_OBJECT_SELECT_MODE_ALWAYS);
83
84     m_itemClass = elm_genlist_item_class_new();
85     m_itemClass->item_style = "bookmarks_manager_item";
86
87     m_itemClass->func.text_get = &gridTextGet;
88     m_itemClass->func.content_get = &gridOptionLabelGet;
89     m_itemClass->func.state_get = 0;
90     m_itemClass->func.del = 0;
91 }
92
93 BookmarksManager::~BookmarksManager()
94 {
95
96 }
97
98 Evas_Object* BookmarksManager::getContent()
99 {
100     return m_genlist;
101 }
102
103 tizen_browser::base_ui::MenuButton::ListSize BookmarksManager::calculateSize()
104 {
105     ListSize result;
106
107     result.width = 490;
108     result.height = 426;
109
110     return result;
111 }
112
113 Evas_Object* BookmarksManager::getFirstFocus()
114 {
115     return m_genlist;
116 }
117
118 void BookmarksManager::addAction(sharedAction action)
119 {
120     std::shared_ptr<BookmarksManagerItem> bookmarks_managerItem = std::make_shared<BookmarksManagerItem>(action);
121     BROWSER_LOGD("[%s] %x: %s", __func__ , bookmarks_managerItem.get(), bookmarks_managerItem->action->getText().c_str() );
122     Elm_Object_Item* elmItem= elm_genlist_item_append(m_genlist,            //genlist
123                                                       m_itemClass,          //item Class
124                                                       bookmarks_managerItem.get(),        //item data
125                                                       0,                    //parent item
126                                                       ELM_GENLIST_ITEM_NONE,//item type
127                                                       itemClicked,
128                                                       this
129                                                      );
130     m_bookmarks_managerItemsMap[elmItem] = bookmarks_managerItem;
131     BROWSER_LOGD("[%s:%d] \n\t %x:%s ", __PRETTY_FUNCTION__, __LINE__, elmItem, bookmarks_managerItem->action->getText().c_str());
132     if(!bookmarks_managerItem->action->isEnabled()){
133         elm_object_item_disabled_set(elmItem, EINA_TRUE);
134     }
135     if(bookmarks_managerItem->action->isCheckable()){
136         elm_object_item_signal_emit(elmItem,
137                           (bookmarks_managerItem->action->isChecked() ? "switch,on" : "switch,off")
138                           , "BookmarksManagerModel");
139     } else {
140         elm_object_item_signal_emit(elmItem, "switch,hide", "BookmarksManagerModel");
141     }
142     action->enabledChanged.connect(boost::bind(&BookmarksManager::onEnabledChanged, this, action));
143     m_actionButtonMap[action] = elmItem;
144 }
145
146 void BookmarksManager::onEnabledChanged(sharedAction action)
147 {
148     BROWSER_LOGD("[%s]", __func__);
149     refreshAction(action);
150 }
151
152 void BookmarksManager::refreshAction(sharedAction action)
153 {
154     BROWSER_LOGD("[%s]", __func__);
155     if(action->isEnabled())
156         elm_object_item_disabled_set(m_actionButtonMap[action], EINA_FALSE);
157     else
158         elm_object_item_disabled_set(m_actionButtonMap[action], EINA_TRUE);
159 }
160
161 char* BookmarksManager::gridTextGet(void* data, Evas_Object* /*obj*/, const char* part)
162 {
163     BROWSER_LOGD("[%s]", __func__);
164     BookmarksManagerItem *bookmarks_managerItem =reinterpret_cast<BookmarksManagerItem*>(data);
165     if(!strcmp(part, "optionName")){
166         if(!bookmarks_managerItem->action->getText().empty()){
167             return strdup(bookmarks_managerItem->action->getText().c_str());
168         }
169     }
170     return strdup("");
171 }
172
173 Evas_Object* BookmarksManager::gridOptionLabelGet(void* data, Evas_Object* obj, const char* part)
174 {
175     BookmarksManagerItem *bookmarks_managerItem =reinterpret_cast<BookmarksManagerItem*>(data);
176     if(!strcmp(part, "optionValue")){
177         if(bookmarks_managerItem->action->isEnabled() && bookmarks_managerItem->action->isCheckable()){
178             Evas_Object *label = elm_label_add(obj);
179             elm_object_text_set(label, (bookmarks_managerItem->action->isChecked() ? "On" :"Off" ));
180             elm_object_style_set(label, "bookmarks_manager_label");
181             return label;
182         }
183     }
184     return nullptr;
185
186 }
187
188 void BookmarksManager::itemClicked(void* data, Evas_Object* /*o*/, void* event_info)
189 {
190     BROWSER_LOGD("[%s]", __func__);
191
192     BookmarksManager* bookmarks_manager = reinterpret_cast<BookmarksManager*>(data);
193     Elm_Object_Item* elmItem = reinterpret_cast<Elm_Object_Item*>(event_info);
194     BROWSER_LOGD("[%s:%d] \n\t %x", __PRETTY_FUNCTION__, __LINE__, elmItem);
195     if(bookmarks_manager->m_bookmarks_managerItemsMap.count(elmItem)){
196         std::shared_ptr<BookmarksManagerItem> bookmarks_managerItem(bookmarks_manager->m_bookmarks_managerItemsMap[elmItem]);// elm_object_item_data_get(elmItem)
197         if(bookmarks_managerItem->action->isEnabled()){
198             if(bookmarks_managerItem->action->isCheckable()) {
199                 bookmarks_manager->showInternalPopup(elmItem);
200             } else{
201                 bookmarks_managerItem->action->trigger();
202             }
203         }
204     }
205 }
206
207 void BookmarksManager::showPopup()
208 {
209     BROWSER_LOGD("[%s:%d] this: %x ", __PRETTY_FUNCTION__, __LINE__, this);
210
211     if (isPopupShown()){
212         m_isPopupShown = false;
213         unbindFocus();
214         evas_object_hide(m_popup);
215         return;
216     }
217
218     if(!m_popup) {
219         m_popup = elm_popup_add(m_window.get());
220         BROWSER_LOGD("[%s:%d] - new popup: %x ", __PRETTY_FUNCTION__, __LINE__, m_popup);
221         evas_object_smart_callback_add(m_popup, "block,clicked", block_clicked, this);
222       //  elm_object_content_set(m_popup, getContent());
223         elm_object_part_text_set(m_popup, "title,text", "Add to Bookmark");
224
225         Evas_Coord w,h,x,y;
226         evas_object_geometry_get(m_window.get(), &x, &y, &w, &h);
227         evas_object_geometry_set(m_popup,0,0,w,h);
228
229       //elm_object_style_set(m_popup, "message_popup");
230     }
231     //evas_object_resize(m_popup, 480, 800);
232     realShow(m_popup);
233 }
234
235 void BookmarksManager::realShow(Evas_Object* popup)
236 {
237     elm_object_focus_next_object_set(m_parentButton, getFirstFocus(), ELM_FOCUS_DOWN);
238     elm_object_focus_next_object_set(getFirstFocus(), m_parentButton, ELM_FOCUS_UP);
239
240    // ListSize listSize = calculateSize();
241   //  evas_object_size_hint_min_set(m_popup, listSize.width, listSize.height);
242   //  evas_object_size_hint_max_set(m_popup, listSize.width, listSize.height);
243    elm_popup_item_append(popup,"Folde 1",nullptr,nullptr,this);
244    elm_popup_item_append(popup,"Folde 2",nullptr,nullptr,this);
245    elm_popup_item_append(popup,"Folde 3",nullptr,nullptr,this);
246    elm_popup_item_append(popup,"Folde 4",nullptr,nullptr,this);
247    elm_popup_item_append(popup,"Folde 5",nullptr,nullptr,this);
248    elm_popup_item_append(popup,"Folde 6",nullptr,nullptr,this);
249    elm_popup_item_append(popup,"Folde 7",nullptr,nullptr,this);
250    elm_popup_item_append(popup,"Folde 8",nullptr,nullptr,this);
251    elm_popup_item_append(popup,"Folde 8",nullptr,nullptr,this);
252    elm_popup_item_append(popup,"Folde 10",nullptr,nullptr,this);
253    elm_popup_item_append(popup,"Folde 11",nullptr,nullptr,this);
254    elm_popup_item_append(popup,"Folde 12",nullptr,nullptr,this);
255    evas_object_show(popup);
256     m_isPopupShown=true;
257 }
258
259 void BookmarksManager::unbindFocus()
260 {
261     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
262     elm_object_focus_next_object_set(m_parentButton, nullptr, ELM_FOCUS_DOWN);
263 }
264
265 bool BookmarksManager::isPopupShown()
266 {
267     return m_isPopupShown;
268 }
269
270 void BookmarksManager::block_clicked(void *data, Evas_Object *obj, void *event_info)
271 {
272     evas_object_hide(obj);
273 }
274
275 void BookmarksManager::hidePopup()
276 {
277     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
278     evas_object_hide(m_popup);
279     m_isPopupShown = false;
280 }
281
282 void BookmarksManager::showInternalPopup(Elm_Object_Item* listItem)
283 {
284     BROWSER_LOGD("[%s]", __func__);
285     m_internalPopupVisible = true;
286     m_trackedItem = listItem;
287
288     if(!m_internalPopup){
289         m_internalPopup = elm_ctxpopup_add(m_window.get());
290         evas_object_smart_callback_add(m_internalPopup, "dismissed", BookmarksManager::dismissedCtxPopup, this);
291     }
292     Evas_Object * buttonBox = elm_box_add(m_internalPopup);
293     Evas_Object * radioOn = elm_radio_add(m_internalPopup);
294     Evas_Object * radioOff = elm_radio_add(m_internalPopup);
295
296
297     elm_object_text_set(radioOn, "On");
298     elm_object_text_set(radioOff, "Off");
299
300     elm_object_style_set(radioOn, "bookmarks_manager_radio");
301     elm_object_style_set(radioOff, "bookmarks_manager_radio");
302
303     elm_box_pack_end(buttonBox, radioOn);
304     elm_box_pack_end(buttonBox, radioOff);
305
306     m_checkState = (m_bookmarks_managerItemsMap[m_trackedItem]->action->isChecked() ? CheckStateOn : CheckStateOff );
307
308     elm_radio_state_value_set(radioOn, CheckStateOn);//true
309     elm_radio_value_pointer_set(radioOn, reinterpret_cast<int*>(&m_checkState));
310
311     elm_radio_state_value_set(radioOff, CheckStateOff);//false
312     elm_radio_value_pointer_set(radioOff, reinterpret_cast<int*>(&m_checkState));
313
314     elm_radio_group_add(radioOff, radioOn);
315
316     evas_object_smart_callback_add(radioOn, "changed", radioChanged, this);
317     evas_object_smart_callback_add(radioOff, "changed", radioChanged, this);
318
319     evas_object_size_hint_weight_set(buttonBox, EVAS_HINT_EXPAND,EVAS_HINT_EXPAND);
320     evas_object_size_hint_align_set(buttonBox, EVAS_HINT_FILL, EVAS_HINT_FILL);
321
322     evas_object_show(buttonBox);
323     evas_object_show(radioOn);
324     evas_object_show(radioOff);
325
326
327     elm_object_content_set(m_internalPopup, buttonBox);
328     elm_ctxpopup_direction_priority_set(m_internalPopup,
329                                         ELM_CTXPOPUP_DIRECTION_DOWN,
330                                         ELM_CTXPOPUP_DIRECTION_DOWN,
331                                         ELM_CTXPOPUP_DIRECTION_DOWN,
332                                         ELM_CTXPOPUP_DIRECTION_DOWN);
333     Evas_Coord w,h,x,y;
334
335 #if PLATFORM(TIZEN)
336     evas_object_geometry_get(elm_object_item_track(m_trackedItem), &x, &y, &w, &h);
337
338     BROWSER_LOGD("[%s:%d] \n\tx:%d; y:%d; w:%d; h:%d  ", __PRETTY_FUNCTION__, __LINE__,
339                                  x,    y,    w,    h);
340     evas_object_move(m_internalPopup, x + 354, y);//354 is proper value
341 #endif
342
343     elm_object_style_set(m_internalPopup, "bookmarks_manager_button");
344     evas_object_show(m_internalPopup);
345     if(!m_pointerModeEnabled)
346         elm_object_focus_set(radioOn, EINA_TRUE);
347     elm_object_item_signal_emit(m_trackedItem, "selected", "BookmarksManagerModel");
348     elm_object_signal_emit(m_genlist, "show_popup", "BookmarksManagerModel");
349 }
350
351 void BookmarksManager::dismissedCtxPopup(void* data, Evas_Object* obj, void* /*event_info*/)
352 {
353     BROWSER_LOGD("[%s]", __func__);
354     BookmarksManager* bookmarks_manager = static_cast<BookmarksManager*>(data);
355     evas_object_hide(obj);
356     bookmarks_manager->m_internalPopup = 0;
357     elm_object_signal_emit(bookmarks_manager->m_genlist, "hide_popup", "BookmarksManagerModel");
358     elm_object_item_signal_emit(bookmarks_manager->m_trackedItem, "unselected", "BookmarksManagerModel");
359
360 #if PLATFORM(TIZEN)
361     elm_object_item_untrack(bookmarks_manager->m_trackedItem);
362 #endif
363     bookmarks_manager->m_internalPopupVisible = false;
364 }
365
366 void BookmarksManager::radioChanged(void* data, Evas_Object* /*obj*/, void* /*event_info*/)
367 {
368     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
369     BookmarksManager *bookmarks_manager = static_cast<BookmarksManager*>(data);
370     std::shared_ptr<BookmarksManagerItem> bookmarks_managerItem(bookmarks_manager->m_bookmarks_managerItemsMap[bookmarks_manager->m_trackedItem]);
371     bookmarks_managerItem->action->toggle();
372     elm_object_item_signal_emit(bookmarks_manager->m_trackedItem,
373                           (bookmarks_managerItem->action->isChecked() ? "switch,on" : "switch,off")
374                           , "BookmarksManagerModel");
375     elm_genlist_item_update(bookmarks_manager->m_trackedItem);
376     elm_object_signal_emit(bookmarks_manager->m_internalPopup, "elm,state,hide", "elm");
377 }
378
379 void BookmarksManager::focusItem(void* /*data*/, Evas_Object* /*obj*/, void* event_info)
380 {
381     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
382     Elm_Object_Item *item = reinterpret_cast<Elm_Object_Item*>(event_info);
383     elm_object_item_signal_emit( item, "mouse,in", "option*");
384 }
385
386 void BookmarksManager::unFocusItem(void* /*data*/, Evas_Object* /*obj*/, void* event_info)
387 {
388     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
389     Elm_Object_Item *item = reinterpret_cast<Elm_Object_Item*>(event_info);
390     elm_object_item_signal_emit( item, "mouse,out", "option*");
391 }
392
393 void BookmarksManager::setPointerModeEnabled (bool enabled)
394 {
395     m_pointerModeEnabled = enabled;
396 }
397
398 bool BookmarksManager::canBeDismissed()
399 {
400     BROWSER_LOGD("[%s]", __func__);
401     bool internalPopupVisible = m_internalPopup &&  m_internalPopupVisible;
402     if(internalPopupVisible) {
403         elm_ctxpopup_dismiss(m_internalPopup);
404         return false;
405     }
406     return true;
407 }
408
409 }//namespace base_ui
410
411 }//namespace tizen_browser