fix gbs/obs build failure
[framework/osp/web.git] / src / controls / FWebCtrl_SelectBox.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FWebCtrl_SelectBox.cpp
20  * @brief               The file contains the definition of _SelectBox class.
21  *
22  * The file contains the definition of _SelectBox class.
23  */
24 #include <ewk_view.h>
25 #include <ewk_popup_menu_item.h>
26 #include <unique_ptr.h>
27 #include <FBaseColAllElementsDeleter.h>
28 #include <FBaseSysLog.h>
29 #include <FGrpDimension.h>
30 #include <FGrpRectangle.h>
31 #include <FUiCtrlButton.h>
32 #include <FUiCtrlCustomItem.h>
33 #include <FUiCtrlGroupedList.h>
34 #include <FUiCtrlListItemBase.h>
35 #include <FUiCtrlListView.h>
36 #include <FUiCtrlPanel.h>
37 #include <FUiIActionEventListener.h>
38 #include <FUiKeyEventInfo.h>
39 #include <FUiVerticalBoxLayout.h>
40 #include <FSys_SystemResource.h>
41 #include <FUi_ResourceManager.h>
42 #include "FWebCtrl_SelectBox.h"
43
44
45 using namespace Tizen::Base;
46 using namespace Tizen::Base::Collection;
47 using namespace Tizen::Graphics;
48 using namespace Tizen::System;
49 using namespace Tizen::Ui;
50 using namespace Tizen::Ui::Controls;
51
52
53 namespace Tizen { namespace Web { namespace Controls
54 {
55
56
57 static const int POSITION_INVALID = -1;
58
59
60 template< class Type > Type
61 Max(Type a, Type b)
62 {
63         return a > b ? a : b;
64 }
65
66
67 int CompareChangedItems(const void* pData1, const void* pData2)
68 {
69         SysAssertf(pData1 && pData2, "input parameters are null");
70
71     const int* pLeft = static_cast<const int*>(pData1);
72     const int* pRight = static_cast<const int*>(pData2);
73
74     return (*pLeft - *pRight);
75 }
76
77
78 //Internal class for maintaining states of list elements
79 class _ListElement
80         : public Object
81 {
82 public:
83         _ListElement(const String& itemText);
84
85         virtual ~_ListElement(void) {}
86
87         //Set functions
88         void ListElementSetItemEnabled(bool isEnabled);
89         void ListElementSetItemType(short itemType);
90         void ListElementSetItemSelected(bool isSelected);
91
92         //Get functions
93         short ListElementGetItemType(void) const { return __itemType; }
94
95         String ListElementGetString(void) const { return __itemStr; }
96
97         bool ListElementIsItemEnabled(void) const { return __isEnabled; }
98
99         bool ListElementIsItemSelected(void) const { return __isSelected; }
100
101 private:
102         _ListElement(void);
103
104 private:
105         String __itemStr;
106         short __itemType;
107         bool __isEnabled;
108         bool __isSelected;
109 }; // _ListElement
110
111
112 _ListElement::_ListElement(const String& itemText)
113         : __itemType(_SelectBox::LIST_ITEM_TYPE_NORMAL)
114         , __isEnabled(true)
115         , __isSelected(false)
116 {
117         __itemStr = itemText;
118 }
119
120
121 void
122 _ListElement::ListElementSetItemEnabled(bool isEnabled)
123 {
124         __isEnabled = isEnabled;
125 }
126
127
128 void
129 _ListElement::ListElementSetItemType(short itemType)
130 {
131         __itemType = itemType;
132 }
133
134
135 void
136 _ListElement::ListElementSetItemSelected(bool isSelected)
137 {
138         __isSelected = isSelected;
139 }
140
141
142 _SelectBox::_SelectBox(void)
143         : __pListView(null)
144         , __multiSelection(false)
145         , __SelectedIndex(-1)
146         , __prevIndex(-1)
147         , __orientation(_CONTROL_ORIENTATION_PORTRAIT)
148         , __pWebView(null)
149         , __pToggledArray(null)
150 {
151 }
152
153
154 _SelectBox::~_SelectBox(void)
155 {
156         if (__multiSelection)
157         {
158                 eina_inarray_flush(__pToggledArray);
159                 delete __pToggledArray;
160         }
161
162         __listElementArray.RemoveAll(true);
163 }
164
165
166 result
167 _SelectBox::Construct(bool isMultiSelect, const String& title, int listCount, Evas_Object* pWebView)
168 {
169         result r = E_SUCCESS;
170         Rectangle rect;
171
172         int listItemHeight = 0;
173         int listMaxHeihgt = 0;
174         int listViewHeight = 0;
175
176         __pWebView = pWebView;
177
178         GET_SHAPE_CONFIG(CONTEXTMENU::LIST_ITEM_HEIGHT, __orientation, listItemHeight);
179
180         __multiSelection = isMultiSelect;
181
182         _WebPopupData* pPopupData = _WebPopup::GetPopupData();
183         SysTryReturn(NID_WEB_CTRL, pPopupData, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
184
185         listMaxHeihgt = listCount * listItemHeight + pPopupData->btnDim.height + pPopupData->spacePad;
186
187         rect.height = listMaxHeihgt;
188         rect.width = pPopupData->popupDim.width;
189         rect.x = 0;
190         rect.y = 0;
191
192         r = _WebPopup::Construct(!title.IsEmpty(), Dimension(rect.width, rect.height));
193         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
194
195         if (!title.IsEmpty())
196         {
197                 Popup::SetTitleText(title);
198         }
199
200         listViewHeight = listCount * listItemHeight;
201         std::unique_ptr<ListView> pListView(new (std::nothrow) ListView());
202         SysTryReturnResult(NID_WEB_CTRL, pListView.get(), E_OUT_OF_MEMORY, "Memory Allocation failed.");
203
204         r = pListView->Construct(Rectangle(0, 0, GetClientAreaBounds().width, listViewHeight), true, SCROLL_STYLE_FADE_OUT);
205         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
206
207         r = __listElementArray.Construct();
208         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
209
210         pListView->SetItemProvider(*this);
211         pListView->AddListViewItemEventListener(*this);
212         pListView->SetTextOfEmptyList(L"");
213
214         r = AddControl(*pListView);
215         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
216
217         __pListView = pListView.release();
218
219         Panel* pButtonPanel = CreateAndAddPanel();
220         SysTryReturn(NID_WEB_CTRL, pButtonPanel, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
221
222         _SystemResource* pSysResource = _SystemResource::GetInstance();
223         SysAssertf(pSysResource != null, "Failed to get _SystemResource instance");
224
225         ArrayList idList;
226         r = idList.Construct();
227         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
228
229         idList.Add(*(new Integer(ID_BUTTON_CANCEL)));
230         if (__multiSelection)
231         {
232                 idList.Add(*(new Integer(ID_BUTTON_SELECTION)));
233         }
234
235         ArrayList titleList;
236         r = titleList.Construct();
237         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
238
239         titleList.Add(*(new String(pSysResource->GetString("sys_string", "IDS_COM_POP_CANCEL"))));
240         if (__multiSelection)
241         {
242                 titleList.Add(*(new String(pSysResource->GetString("sys_string", "IDS_COM_BODY_DONE"))));
243
244                 __pToggledArray = eina_inarray_new(sizeof(int), 0);
245                 SysTryReturnResult(NID_WEB_CTRL, __pToggledArray, E_OUT_OF_MEMORY, "Memory Allocation failed.");
246         }
247
248         r = CreateAndAddButtons(idList, titleList, pButtonPanel);
249         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
250
251         std::unique_ptr<VerticalBoxLayout> pLayout(dynamic_cast< VerticalBoxLayout* >(GetLayoutN()));
252         SysTryReturn(NID_WEB_CTRL, pLayout.get(), r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
253
254         pLayout->SetSpacing(*pButtonPanel,  pPopupData->spacePad);
255
256         SetPropagatedKeyEventListener(this);
257         
258         return r;
259 }
260
261 result
262 _SelectBox::AddListItem(const String& itemText, int itemType, bool slected)
263 {
264         result r = E_SUCCESS;
265         std::unique_ptr<_ListElement> pListElement(new (std::nothrow) _ListElement(itemText));
266         SysTryReturnResult(NID_WEB_CTRL, pListElement.get(), E_OUT_OF_MEMORY, "Memory Allocation failed.");
267
268         pListElement->ListElementSetItemType(itemType);
269         pListElement->ListElementSetItemSelected(slected);
270
271         r = __listElementArray.Add(*pListElement);
272         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
273
274         pListElement.release();
275         return r;
276 }
277
278
279 IList*
280 _SelectBox::GetSelectedListN(void) const
281 {
282         result r = E_SUCCESS;
283
284         std::unique_ptr<ArrayList, AllElementsDeleter> pSelectedList(new (std::nothrow) ArrayList());
285         SysTryReturn(NID_WEB_CTRL, pSelectedList.get(), null, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.",GetErrorMessage(E_OUT_OF_MEMORY));
286
287         r = pSelectedList->Construct();
288         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
289
290         for (int index = 0; index < __pListView->GetItemCount(); index++)
291         {
292                 if (__pListView->IsItemChecked(index))
293                 {
294                         std::unique_ptr<Integer> pIdxResult(new (std::nothrow) Integer(index));
295                         SysTryReturn(NID_WEB_CTRL, pIdxResult.get(), null, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.",GetErrorMessage(E_OUT_OF_MEMORY));
296
297                         r = pSelectedList->Add(*pIdxResult);
298                         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Memory Allocation failed.",GetErrorMessage(r));
299
300                         pIdxResult.release();
301                 }
302         }
303
304         return pSelectedList.release();
305 }
306
307
308 //IListViewItemProvider
309 ListItemBase*
310 _SelectBox::CreateItem(int index, int itemWidth)
311 {
312         result r = E_SUCCESS;
313         int listItemXPos = 0;
314         int listItemYPos = 0;
315         int checkBoxWidth = 0;
316         int listItemHeight = 0;
317         int popupBetweenListNBtnGap = 0;
318
319         ListAnnexStyle subStyle = (__multiSelection) ? LIST_ANNEX_STYLE_MARK : LIST_ANNEX_STYLE_NORMAL;
320         ListAnnexStyle groupStyle = LIST_ANNEX_STYLE_NORMAL;
321
322         _ListElement* pListElement = static_cast< _ListElement* >(__listElementArray.GetAt(index));
323         SysTryReturn(NID_WEB_CTRL, pListElement, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
324
325         GET_SHAPE_CONFIG(CONTEXTMENU::LIST_ITEM_HEIGHT, __orientation, listItemHeight);
326         GET_SHAPE_CONFIG(LISTVIEW::ITEM_ELEMENT_LEFT_MARGIN, __orientation, listItemXPos);
327         GET_SHAPE_CONFIG(LIST::LIST_CHECK_ITEM_WIDTH, __orientation, checkBoxWidth);
328         GET_SHAPE_CONFIG(MESSAGEBOX::BUTTON_TOP_MARGIN, __orientation, popupBetweenListNBtnGap);
329
330         std::unique_ptr<CustomItem> pItem(new (std::nothrow) CustomItem());
331         SysTryReturn(NID_WEB_CTRL, pItem.get(), null, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.",GetErrorMessage(E_OUT_OF_MEMORY));
332
333         int itemType = pListElement->ListElementGetItemType();
334         Rectangle popupRect = this->GetClientAreaBounds();
335
336         int listTxtMaxWidth = popupRect.width - listItemXPos - checkBoxWidth - popupBetweenListNBtnGap;
337
338         switch (itemType)
339         {
340         case LIST_ITEM_TYPE_NORMAL:
341         //fall through
342         case LIST_ITEM_TYPE_SUB:
343                 r = pItem->Construct(Dimension(itemWidth, listItemHeight), subStyle);
344                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
345                 break;
346
347         case LIST_ITEM_TYPE_GROUP:
348                 SysLog(NID_WEB_CTRL, "The current value of index [%d] [%d]", index, pListElement->ListElementIsItemEnabled());
349                 r = pItem->Construct(Dimension(itemWidth, listItemHeight), groupStyle);
350                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
351                 break;
352
353         default:
354                 return null;
355         }
356
357         String elementString = pListElement->ListElementGetString();
358
359         if (elementString.IsEmpty())
360         {
361                 elementString.Append(L" ");
362         }
363
364         r = pItem->AddElement(Rectangle(listItemXPos, listItemYPos, listTxtMaxWidth, listItemHeight),
365                                                   ID_FORMAT_STRING, elementString, true);
366         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
367
368         if (IsMultiSelectable())
369         {
370                 r = __pListView->SetItemChecked(index, pListElement->ListElementIsItemSelected());
371                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
372         }
373
374         r = __pListView->SetItemEnabled(index, !(itemType == LIST_ITEM_TYPE_GROUP));
375         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
376
377         return pItem.release();
378 }
379
380
381 bool
382 _SelectBox::DeleteItem(int index, ListItemBase* pItem, int itemWidth)
383 {
384         delete pItem;
385         pItem = null;
386
387         return true;
388 }
389
390
391 int
392 _SelectBox::GetItemCount(void)
393 {
394         return __listElementArray.GetCount();
395 }
396
397
398 void
399 _SelectBox::OnListViewContextItemStateChanged(ListView& listView, int index, int elementId, ListContextItemStatus state)
400 {
401 }
402
403
404 void
405 _SelectBox::OnListViewItemStateChanged(ListView& listView, int index, int elementId, ListItemStatus status)
406 {
407         if (__multiSelection)
408         {
409                 int pos = eina_inarray_search(__pToggledArray, &index, CompareChangedItems);
410
411                 if (pos == POSITION_INVALID)
412                 {
413                         eina_inarray_push(__pToggledArray, &index);
414                 }
415                 else
416                 {
417                         eina_inarray_remove(__pToggledArray, &index);
418                 }
419         }
420         else
421         {
422                 //In case of single selection ... update the index.
423                 __SelectedIndex = index;
424                 SysLog(NID_WEB_CTRL,"The current value of Update Selected index is %d",index);
425                 if (__pWebView)
426                 {
427                         ewk_view_popup_menu_select(__pWebView, __SelectedIndex);
428                 }
429
430                 result r = HidePopup(__SelectedIndex);
431                 SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
432         }
433 }
434
435
436 void
437 _SelectBox::OnListViewItemSwept(ListView& listView, int index, SweepDirection direction)
438 {
439
440 }
441
442
443 void
444 _SelectBox::OnActionPerformed(const Control& source, int actionId)
445 {
446         switch (actionId)
447         {
448         case ID_BUTTON_SELECTION:
449         {
450                 ewk_view_popup_menu_multiple_select(__pWebView, __pToggledArray);
451                 break;
452         }
453         case ID_BUTTON_CANCEL:
454         {
455                 if (__multiSelection)
456                 {
457                         ewk_view_popup_menu_multiple_select(__pWebView, null);
458                 }
459                 else
460                 {
461                         ewk_view_popup_menu_select(__pWebView, __prevIndex);
462                 }
463                 break;
464         }
465         default:
466                 SysAssertf(false, "Invalid Action ID");
467         }
468
469         result r = HidePopup(__SelectedIndex);
470         SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
471 }
472
473 bool
474 _SelectBox::OnKeyPressed(Control& source, const KeyEventInfo& keyEventInfo)
475 {
476         return true;
477 }
478
479 bool
480 _SelectBox::OnKeyReleased(Control& source, const KeyEventInfo& keyEventInfo)
481 {
482         if ((keyEventInfo.GetKeyCode() == KEY_ESC || keyEventInfo.GetKeyCode() == KEY_BACK) && source.GetShowState() == true)
483         {
484                 if (__multiSelection)
485                 {
486                         ewk_view_popup_menu_multiple_select(__pWebView, null);
487                 }
488                 else
489                 {
490                         ewk_view_popup_menu_select(__pWebView, __prevIndex);
491                 }
492                 result r = HidePopup(__SelectedIndex);
493                 if (IsFailed(r))
494                 {
495                         SysLogException(NID_WEB_CTRL, r, "[%s] Propagating.", GetErrorMessage(r));
496                 }
497         }
498
499         return true;
500 }
501
502 bool
503 _SelectBox::OnPreviewKeyPressed(Control& source, const KeyEventInfo& keyEventInfo)
504 {
505         return false;
506 }
507
508 bool
509 _SelectBox::OnPreviewKeyReleased(Control& source, const KeyEventInfo& keyEventInfo)
510 {
511         return false;
512 }
513
514 bool
515 _SelectBox::TranslateKeyEventInfo(Control& source, KeyEventInfo& keyEventInfo)
516 {
517         return false;
518 }
519
520 result
521 _SelectBox::UpdateList(Eina_List* pItems, int prevIndex, bool clearPrevList, bool isGroupdList)
522 {
523         SysTryReturnResult(NID_WEB_CTRL, __pListView, E_INVALID_STATE, "List View is in an invalid state");
524
525         if (clearPrevList)
526         {
527                 __listElementArray.RemoveAll(true);
528                 if (__multiSelection)
529                 {
530                         eina_inarray_flush(__pToggledArray);
531                 }
532         }
533
534         //Create list required for selectBox
535         int itemCount = eina_list_count(pItems);
536         SysTryReturn(NID_WEB_CTRL, itemCount > 0, E_SYSTEM, E_SYSTEM, "[%s]  A system error has been occurred. ItemCount is invalid.", GetErrorMessage(E_SYSTEM));
537
538         bool isSelected = false;
539
540         if (!__multiSelection)
541         {
542                 __prevIndex = prevIndex;
543         }
544
545         for (int itemIndex = 0; itemIndex < itemCount; itemIndex++)
546         {
547                 Ewk_Popup_Menu_Item* pItem = static_cast<Ewk_Popup_Menu_Item*>(eina_list_nth(pItems, itemIndex));
548                 SysTryReturn(NID_WEB_CTRL, pItem, E_SYSTEM, E_SYSTEM, "[%s]  A system error has been occurred. Failed to get item.", GetErrorMessage(E_SYSTEM));
549
550                 if (ewk_popup_menu_item_type_get(pItem) == EWK_POPUP_MENU_ITEM)
551                 {
552                         String text(ewk_popup_menu_item_text_get(pItem));
553
554                         if (__multiSelection)
555                         {
556                                 isSelected = ( ewk_popup_menu_item_selected_get(pItem) == EINA_TRUE ) ? true : false;
557                         }
558                         else
559                         {
560                                 isSelected = (itemIndex == prevIndex) ? true : false;
561                         }
562
563                         if (isGroupdList)
564                         {
565                                 AddListItem(text, _SelectBox::LIST_ITEM_TYPE_GROUP, isSelected);
566                         }
567                         else
568                         {
569                                 AddListItem(text, _SelectBox::LIST_ITEM_TYPE_NORMAL, isSelected);
570                         }
571                 }
572         }
573
574         __pListView->UpdateList();
575
576         return E_SUCCESS;
577 }
578
579
580 }}} // Tizen::Web::Controls