2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file FWebCtrl_SelectBox.cpp
20 * @brief The file contains the definition of _SelectBox class.
22 * The file contains the definition of _SelectBox class.
25 #include <ewk_popup_menu_item.h>
26 #include <unique_ptr.h>
27 #include <FBaseColAllElementsDeleter.h>
28 #include <FBaseSysLog.h>
29 #include <FCntDownloadRequest.h>
30 #include <FGrpDimension.h>
31 #include <FGrpRectangle.h>
32 #include <FUiCtrlButton.h>
33 #include <FUiCtrlCustomItem.h>
34 #include <FUiCtrlGroupedList.h>
35 #include <FUiCtrlListItemBase.h>
36 #include <FUiCtrlListView.h>
37 #include <FUiCtrlPanel.h>
38 #include <FUiIActionEventListener.h>
39 #include <FUiKeyEventInfo.h>
40 #include <FUiVerticalBoxLayout.h>
41 #include <FCnt_DownloadManagerImpl.h>
42 #include <FSys_SystemResource.h>
43 #include <FUi_ResourceManager.h>
44 #include "FWebCtrl_SelectBox.h"
45 #include "FWebCtrl_WebImpl.h"
48 using namespace Tizen::Base;
49 using namespace Tizen::Base::Collection;
50 using namespace Tizen::Content;
51 using namespace Tizen::Graphics;
52 using namespace Tizen::System;
53 using namespace Tizen::Ui;
54 using namespace Tizen::Ui::Controls;
57 namespace Tizen { namespace Web { namespace Controls
61 static const int POSITION_INVALID = -1;
64 template< class Type > Type
71 int CompareChangedItems(const void* pData1, const void* pData2)
73 SysAssertf(pData1 && pData2, "input parameters are null");
75 const int* pLeft = static_cast<const int*>(pData1);
76 const int* pRight = static_cast<const int*>(pData2);
78 return (*pLeft - *pRight);
82 //Internal class for maintaining states of list elements
87 _ListElement(const String& itemText);
89 virtual ~_ListElement(void) {}
92 void ListElementSetItemEnabled(bool isEnabled);
93 void ListElementSetItemType(short itemType);
94 void ListElementSetItemSelected(bool isSelected);
97 short ListElementGetItemType(void) const { return __itemType; }
99 String ListElementGetString(void) const { return __itemStr; }
101 bool ListElementIsItemEnabled(void) const { return __isEnabled; }
103 bool ListElementIsItemSelected(void) const { return __isSelected; }
116 _ListElement::_ListElement(const String& itemText)
117 : __itemType(_SelectBox::LIST_ITEM_TYPE_NORMAL)
119 , __isSelected(false)
121 __itemStr = itemText;
126 _ListElement::ListElementSetItemEnabled(bool isEnabled)
128 __isEnabled = isEnabled;
133 _ListElement::ListElementSetItemType(short itemType)
135 __itemType = itemType;
140 _ListElement::ListElementSetItemSelected(bool isSelected)
142 __isSelected = isSelected;
146 _SelectBox::_SelectBox(void)
148 , __multiSelection(false)
149 , __SelectedIndex(-1)
152 , __orientation(_CONTROL_ORIENTATION_PORTRAIT)
154 , __pToggledArray(null)
161 _SelectBox::~_SelectBox(void)
163 if (__multiSelection)
165 eina_inarray_flush(__pToggledArray);
166 delete __pToggledArray;
169 __listElementArray.RemoveAll(true);
174 _SelectBox::Construct(Tizen::Web::Controls::_WebImpl* pImpl, bool isMultiSelect, const String& title, int listCount, Evas_Object* pWebView, const String& url)
176 result r = E_SUCCESS;
179 int listItemHeight = 0;
180 int listMaxHeihgt = 0;
181 int listViewHeight = 0;
183 __pWebView = pWebView;
184 __url = const_cast< String& >(url);
187 GET_SHAPE_CONFIG(CONTEXTMENU::LIST_ITEM_HEIGHT, __orientation, listItemHeight);
189 __multiSelection = isMultiSelect;
191 _WebPopupData* pPopupData = _WebPopup::GetPopupData();
192 SysTryReturn(NID_WEB_CTRL, pPopupData, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
194 listMaxHeihgt = listCount * listItemHeight;
196 rect.height = listMaxHeihgt;
197 rect.width = pPopupData->popupDim.width;
201 r = _WebPopup::Construct(!title.IsEmpty(), Dimension(rect.width, rect.height));
202 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
204 if (!title.IsEmpty())
206 Popup::SetTitleText(title);
209 listViewHeight = listCount * listItemHeight;
210 std::unique_ptr<ListView> pListView(new (std::nothrow) ListView());
211 SysTryReturnResult(NID_WEB_CTRL, pListView.get(), E_OUT_OF_MEMORY, "Memory Allocation failed.");
213 r = pListView->Construct(Rectangle(0, 0, GetClientAreaBounds().width, listViewHeight), true, SCROLL_STYLE_FADE_OUT);
214 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
216 r = __listElementArray.Construct();
217 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
219 pListView->SetItemProvider(*this);
220 pListView->AddListViewItemEventListener(*this);
221 pListView->SetTextOfEmptyList(L"");
223 r = AddControl(*pListView);
224 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
226 __pListView = pListView.release();
228 if (__multiSelection)
230 Panel* pButtonPanel = CreateAndAddPanel();
231 SysTryReturn(NID_WEB_CTRL, pButtonPanel, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
233 __panelHeight = pButtonPanel->GetHeight();
235 _SystemResource* pSysResource = _SystemResource::GetInstance();
236 SysAssertf(pSysResource != null, "Failed to get _SystemResource instance");
238 ArrayList idList(SingleObjectDeleter);
239 r = idList.Construct();
240 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
242 idList.Add(*(new Integer(ID_BUTTON_SELECTION)));
244 ArrayList titleList(SingleObjectDeleter);
245 r = titleList.Construct();
246 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
248 titleList.Add(*(new String(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_BUTTON_OK"))));
250 __pToggledArray = eina_inarray_new(sizeof(int), 0);
251 SysTryReturnResult(NID_WEB_CTRL, __pToggledArray, E_OUT_OF_MEMORY, "Memory Allocation failed.");
253 r = CreateAndAddButtons(idList, titleList, pButtonPanel);
254 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
256 SetSize(GetSize().width,GetSize().height + __panelHeight);
259 SetPropagatedKeyEventListener(this);
265 _SelectBox::AddListItem(const String& itemText, int itemType, bool slected)
267 result r = E_SUCCESS;
268 std::unique_ptr<_ListElement> pListElement(new (std::nothrow) _ListElement(itemText));
269 SysTryReturnResult(NID_WEB_CTRL, pListElement.get(), E_OUT_OF_MEMORY, "Memory Allocation failed.");
271 pListElement->ListElementSetItemType(itemType);
272 pListElement->ListElementSetItemSelected(slected);
274 r = __listElementArray.Add(*pListElement);
275 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
277 pListElement.release();
283 _SelectBox::GetSelectedListN(void) const
285 result r = E_SUCCESS;
287 std::unique_ptr<ArrayList, AllElementsDeleter> pSelectedList(new (std::nothrow) ArrayList());
288 SysTryReturn(NID_WEB_CTRL, pSelectedList.get(), null, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.",GetErrorMessage(E_OUT_OF_MEMORY));
290 r = pSelectedList->Construct();
291 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
293 for (int index = 0; index < __pListView->GetItemCount(); index++)
295 if (__pListView->IsItemChecked(index))
297 std::unique_ptr<Integer> pIdxResult(new (std::nothrow) Integer(index));
298 SysTryReturn(NID_WEB_CTRL, pIdxResult.get(), null, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.",GetErrorMessage(E_OUT_OF_MEMORY));
300 r = pSelectedList->Add(*pIdxResult);
301 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Memory Allocation failed.",GetErrorMessage(r));
303 pIdxResult.release();
307 return pSelectedList.release();
311 //IListViewItemProvider
313 _SelectBox::CreateItem(int index, int itemWidth)
315 result r = E_SUCCESS;
316 int listItemXPos = 0;
317 int listItemYPos = 0;
318 int checkBoxWidth = 0;
319 int listItemHeight = 0;
320 int popupBetweenListNBtnGap = 0;
322 ListAnnexStyle subStyle = (__multiSelection) ? LIST_ANNEX_STYLE_MARK : LIST_ANNEX_STYLE_NORMAL;
323 ListAnnexStyle groupStyle = LIST_ANNEX_STYLE_NORMAL;
325 _ListElement* pListElement = static_cast< _ListElement* >(__listElementArray.GetAt(index));
326 SysTryReturn(NID_WEB_CTRL, pListElement, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
328 GET_SHAPE_CONFIG(CONTEXTMENU::LIST_ITEM_HEIGHT, __orientation, listItemHeight);
329 GET_SHAPE_CONFIG(LISTVIEW::ITEM_ELEMENT_LEFT_MARGIN, __orientation, listItemXPos);
330 GET_SHAPE_CONFIG(LIST::LIST_CHECK_ITEM_WIDTH, __orientation, checkBoxWidth);
331 GET_SHAPE_CONFIG(MESSAGEBOX::BUTTON_TOP_MARGIN, __orientation, popupBetweenListNBtnGap);
333 std::unique_ptr<CustomItem> pItem(new (std::nothrow) CustomItem());
334 SysTryReturn(NID_WEB_CTRL, pItem.get(), null, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.",GetErrorMessage(E_OUT_OF_MEMORY));
336 int itemType = pListElement->ListElementGetItemType();
337 Rectangle popupRect = this->GetClientAreaBounds();
339 int listTxtMaxWidth = popupRect.width - listItemXPos - checkBoxWidth - popupBetweenListNBtnGap;
343 case LIST_ITEM_TYPE_NORMAL:
345 case LIST_ITEM_TYPE_SUB:
346 r = pItem->Construct(Dimension(itemWidth, listItemHeight), subStyle);
347 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
350 case LIST_ITEM_TYPE_GROUP:
351 SysLog(NID_WEB_CTRL, "The current value of index [%d] [%d]", index, pListElement->ListElementIsItemEnabled());
352 r = pItem->Construct(Dimension(itemWidth, listItemHeight), groupStyle);
353 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
360 String elementString = pListElement->ListElementGetString();
362 if (elementString.IsEmpty())
364 elementString.Append(L" ");
367 r = pItem->AddElement(Rectangle(listItemXPos, listItemYPos, listTxtMaxWidth, listItemHeight),
368 ID_FORMAT_STRING, elementString, true);
369 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
371 if (IsMultiSelectable())
373 r = __pListView->SetItemChecked(index, pListElement->ListElementIsItemSelected());
374 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
377 r = __pListView->SetItemEnabled(index, !(itemType == LIST_ITEM_TYPE_GROUP));
378 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
380 return pItem.release();
385 _SelectBox::DeleteItem(int index, ListItemBase* pItem, int itemWidth)
395 _SelectBox::GetItemCount(void)
397 return __listElementArray.GetCount();
402 _SelectBox::OnListViewContextItemStateChanged(ListView& listView, int index, int elementId, ListContextItemStatus state)
408 _SelectBox::OnListViewItemStateChanged(ListView& listView, int index, int elementId, ListItemStatus status)
410 if (__multiSelection)
412 int pos = eina_inarray_search(__pToggledArray, &index, CompareChangedItems);
414 if (pos == POSITION_INVALID)
416 eina_inarray_push(__pToggledArray, &index);
420 eina_inarray_remove(__pToggledArray, &index);
425 //In case of single selection ... update the index.
426 if (__url.GetLength() == 0)
428 __SelectedIndex = index;
429 SysLog(NID_WEB_CTRL,"The current value of Update Selected index is %d",index);
432 ewk_view_popup_menu_select(__pWebView, __SelectedIndex);
437 result r = E_SUCCESS;
440 DownloadRequest request(__url);
442 _DownloadManagerImpl* pManagerImpl = _DownloadManagerImpl::GetInstance();
443 SysTryReturnVoidResult(NID_WEB_CTRL, pManagerImpl, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
445 r = pManagerImpl->Start(request, reqId);
446 SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
449 result r = HidePopup();
450 SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
452 __pImpl->SendUserEvent(ID_USER_SCRIPT_SELECTBOX_CLOSE, null);
458 _SelectBox::OnListViewItemSwept(ListView& listView, int index, SweepDirection direction)
465 _SelectBox::OnActionPerformed(const Control& source, int actionId)
467 result r = HidePopup();
468 SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
470 if (__url.GetLength() == 0)
474 case ID_BUTTON_SELECTION:
476 ewk_view_popup_menu_multiple_select(__pWebView, __pToggledArray);
479 case ID_BUTTON_CANCEL:
481 if (__multiSelection)
483 ewk_view_popup_menu_multiple_select(__pWebView, null);
487 ewk_view_popup_menu_select(__pWebView, __prevIndex);
492 SysAssertf(false, "Invalid Action ID");
496 __pImpl->SendUserEvent(ID_USER_SCRIPT_SELECTBOX_CLOSE, null);
500 _SelectBox::OnKeyPressed(Control& source, const KeyEventInfo& keyEventInfo)
506 _SelectBox::OnKeyReleased(Control& source, const KeyEventInfo& keyEventInfo)
508 if ((keyEventInfo.GetKeyCode() == KEY_ESC || keyEventInfo.GetKeyCode() == KEY_BACK) && source.GetShowState() == true)
510 result r = HidePopup();
513 SysLogException(NID_WEB_CTRL, r, "[%s] Propagating.", GetErrorMessage(r));
516 if (__url.GetLength() == 0)
518 if (__multiSelection)
520 ewk_view_popup_menu_multiple_select(__pWebView, null);
524 ewk_view_popup_menu_select(__pWebView, __prevIndex);
528 __pImpl->SendUserEvent(ID_USER_SCRIPT_SELECTBOX_CLOSE, null);
535 _SelectBox::OnPreviewKeyPressed(Control& source, const KeyEventInfo& keyEventInfo)
541 _SelectBox::OnPreviewKeyReleased(Control& source, const KeyEventInfo& keyEventInfo)
547 _SelectBox::TranslateKeyEventInfo(Control& source, KeyEventInfo& keyEventInfo)
553 _SelectBox::UpdateList(Eina_List* pItems, int prevIndex, bool clearPrevList, bool isGroupdList)
555 SysTryReturnResult(NID_WEB_CTRL, __pListView, E_INVALID_STATE, "List View is in an invalid state");
559 __listElementArray.RemoveAll(true);
560 if (__multiSelection)
562 eina_inarray_flush(__pToggledArray);
566 //Create list required for selectBox
567 int itemCount = eina_list_count(pItems);
568 SysTryReturn(NID_WEB_CTRL, itemCount > 0, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred. ItemCount is invalid.", GetErrorMessage(E_SYSTEM));
570 bool isSelected = false;
572 if (!__multiSelection)
574 __prevIndex = prevIndex;
577 for (int itemIndex = 0; itemIndex < itemCount; itemIndex++)
579 Ewk_Popup_Menu_Item* pItem = static_cast<Ewk_Popup_Menu_Item*>(eina_list_nth(pItems, itemIndex));
580 SysTryReturn(NID_WEB_CTRL, pItem, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred. Failed to get item.", GetErrorMessage(E_SYSTEM));
582 if (ewk_popup_menu_item_type_get(pItem) == EWK_POPUP_MENU_ITEM)
584 String text(ewk_popup_menu_item_text_get(pItem));
586 if (__multiSelection)
588 isSelected = ( ewk_popup_menu_item_selected_get(pItem) == EINA_TRUE ) ? true : false;
592 isSelected = (itemIndex == prevIndex) ? true : false;
597 AddListItem(text, _SelectBox::LIST_ITEM_TYPE_GROUP, isSelected);
601 AddListItem(text, _SelectBox::LIST_ITEM_TYPE_NORMAL, isSelected);
606 int listItemHeight = 0;
607 GET_SHAPE_CONFIG(CONTEXTMENU::LIST_ITEM_HEIGHT, __orientation, listItemHeight);
608 int prevCount = (__pListView->GetSize()).height / listItemHeight;
609 int defaultCount = __multiSelection ? DEFAULT_LIST_ITEM_COUNT -1 : DEFAULT_LIST_ITEM_COUNT;
611 if ((prevCount != itemCount)
612 && ((prevCount < defaultCount && itemCount < defaultCount)
613 || (prevCount < defaultCount && itemCount >= defaultCount)
614 || (prevCount >= defaultCount && itemCount < defaultCount)))
616 int listViewNewHeight = ((itemCount < defaultCount) ? itemCount : defaultCount) * listItemHeight;
617 int popupHeight = __multiSelection ? (listViewNewHeight + __panelHeight) : listViewNewHeight;
619 __pListView->SetSize((__pListView->GetSize()).width, listViewNewHeight);
620 SetSize(GetSize().width, popupHeight);
623 __pListView->UpdateList();
629 }}} // Tizen::Web::Controls