Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / controls / FUiCtrl_CustomListImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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         FUiCtrl_CustomListImpl.cpp
20 * @brief        This file contains implementation of _CustomListImpl class
21 */
22
23 #include <FUiCtrlCustomListItem.h>
24 #include <FUiCtrlCustomListItemFormat.h>
25 #include <FBaseSysLog.h>
26 #include "FUi_ResourceSizeInfo.h"
27 #include "FUi_UiBuilder.h"
28 #include "FUiCtrl_CustomListItemFormatImpl.h"
29 #include "FUiCtrl_CustomListItemImpl.h"
30 #include "FUiCtrl_CustomListImpl.h"
31 #include "FUiCtrl_ListListener.h"
32 #include "FUiCtrl_ListItemBaseImpl.h"
33
34 #include "FUiCtrl_TableViewItemProvider.h"
35
36 using namespace Tizen::Base;
37 using namespace Tizen::Base::Collection;
38 using namespace Tizen::Graphics;
39
40 namespace Tizen { namespace Ui { namespace Controls
41 {
42
43 extern const int INVALID_INDEX;
44
45 _CustomListItemDataProvider::_CustomListItemDataProvider(_CustomListImpl* pList)
46         : __pList(pList)
47 {
48 }
49
50 _CustomListItemDataProvider::~_CustomListItemDataProvider(void)
51 {
52 }
53
54 int
55 _CustomListItemDataProvider::GetItemCount(void)
56 {
57         SysTryReturn(NID_UI_CTRL, __pList, -1, E_SYSTEM, "[E_SYSTEM] A system error has occurred. Item provider not constructed properly.");
58         return __pList->GetItemCount();
59 }
60
61 TableViewItem*
62 _CustomListItemDataProvider::CreateItem(int index, int itemWidth)
63 {
64         SysTryReturn(NID_UI_CTRL, __pList, null, E_SYSTEM, "[E_SYSTEM] A system error has occurred. Item provider not constructed properly.");
65
66         CustomListItem* pCustomListItem = __pList->GetCustomListItemAt(-1, index);
67         SysTryReturn(NID_UI_CTRL, pCustomListItem, null, E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to get an item at index(%d).", index);
68
69         _CustomListItemImpl* pCustomListItemImpl = null;
70         pCustomListItemImpl = pCustomListItem->__pCustomListItemImpl;
71         SysTryReturn(NID_UI_CTRL, pCustomListItemImpl, null, E_SYSTEM, "[E_SYSTEM] A system error has occurred. CustomListItem not yet constructed.");
72
73         _TableViewItemParams tableViewItemParams;
74         tableViewItemParams.pItem = pCustomListItem;
75         tableViewItemParams.width = itemWidth;
76         tableViewItemParams.itemId = pCustomListItemImpl->itemId;
77         tableViewItemParams.groupIndex = -1;
78         tableViewItemParams.itemIndex = index;
79         tableViewItemParams.isDividerEnabled = __pList->_isDividerEnabled;
80         tableViewItemParams.pCheckBitmaps = __pList->_pCheckBitmaps;
81         tableViewItemParams.annexStyle = __pList->_annexStyle;
82
83         result r = _CustomListItemImpl::CreateTableViewItem(tableViewItemParams);
84         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
85
86         pCustomListItemImpl->__pTableViewItemData->AddTouchEventListener(*__pList);
87
88         return pCustomListItemImpl->__pTableViewItemData;
89 }
90
91 bool
92 _CustomListItemDataProvider::DeleteItem(const int itemIndex, TableViewItem* pItem)
93 {
94         _TableViewItemData* pTableViewItemData = dynamic_cast<_TableViewItemData*>(pItem);
95         delete pTableViewItemData;
96
97         CustomListItem* pCustomListItem = __pList->GetCustomListItemAt(-1, itemIndex);
98         pCustomListItem->__pCustomListItemImpl->__pTableViewItemData = null;
99
100         return true;
101 }
102
103 void
104 _CustomListItemDataProvider::UpdateItem(int itemIndex, TableViewItem* pItem)
105 {
106     //return true;
107 }
108
109 int
110 _CustomListItemDataProvider::GetDefaultItemHeight(void)
111 {
112         SysTryReturn(NID_UI_CTRL, __pList, 0, E_SYSTEM, "[E_SYSTEM] A system error has occurred. Item provider not constructed properly.");
113
114         CustomListItem* pCustomListItem = __pList->GetCustomListItemAt(-1, 0);
115         SysTryReturn(NID_UI_CTRL, pCustomListItem, 0, E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to get first item");
116
117         _CustomListItemImpl* pCustomListItemImpl = null;
118         pCustomListItemImpl = pCustomListItem->__pCustomListItemImpl;
119         SysTryReturn(NID_UI_CTRL, pCustomListItemImpl, 0, E_SYSTEM, "[E_SYSTEM] A system error has occurred. CustomListItem not yet constructed.");
120
121         return pCustomListItemImpl->height;
122 }
123
124 _CustomListImpl*
125 _CustomListImpl::GetInstance(CustomList& customList)
126 {
127         return static_cast<_CustomListImpl*>(customList._pControlImpl);
128 }
129
130 const _CustomListImpl*
131 _CustomListImpl::GetInstance(const CustomList& customList)
132 {
133         return static_cast<const _CustomListImpl*>(customList._pControlImpl);
134 }
135
136 _CustomListImpl::_CustomListImpl(Control* pList, _TableView* pCore)
137         : _ListBaseImpl(pList, pCore)
138         , __pItemProvider(null)
139 {
140 }
141
142 _CustomListImpl::~_CustomListImpl(void)
143 {
144         RemoveAllFromItemsList();
145
146         __itemListenersList.RemoveAll(true);
147
148         delete __pItemProvider;
149 }
150
151 const char*
152 _CustomListImpl::GetPublicClassName(void) const
153 {
154         return "CustomList";
155 }
156
157 const CustomList&
158 _CustomListImpl::GetPublic(void) const
159 {
160         return static_cast<const CustomList&>(_ControlImpl::GetPublic());
161 }
162
163 CustomList&
164 _CustomListImpl::GetPublic(void)
165 {
166         return static_cast<CustomList&>(_ControlImpl::GetPublic());
167 }
168
169 const _TableView&
170 _CustomListImpl::GetCore(void) const
171 {
172         return static_cast<const _TableView&>(_ControlImpl::GetCore());
173 }
174
175 _TableView&
176 _CustomListImpl::GetCore(void)
177 {
178         return static_cast<_TableView&>(_ControlImpl::GetCore());
179 }
180
181 _CustomListImpl*
182 _CustomListImpl::CreateCustomListImplN(CustomList* pControl, const Rectangle& bounds, bool itemDivider)
183 {
184         result r = E_SUCCESS;
185
186         r = GET_SIZE_INFO(CustomList).CheckInitialSizeValid(Dimension(bounds.width, bounds.height), _CONTROL_ORIENTATION_PORTRAIT);
187         SysTryReturn(NID_UI_CTRL, (r == E_SUCCESS), null, r, "[%s] Propagating.", GetErrorMessage(r));
188
189         _TableView* pCore = null;
190         _CustomListImpl* pImpl = null;
191
192         pCore = _TableView::CreateTableViewN(TABLE_VIEW_STYLE_SIMPLE, itemDivider, TABLE_VIEW_SCROLL_BAR_STYLE_FADE_OUT);
193
194         r = GetLastResult();
195         SysTryReturn(NID_UI_CTRL, pCore, null, r, "[%s] Propagating.", GetErrorMessage(r));
196
197         pImpl = new (std::nothrow) _CustomListImpl(pControl, pCore);
198         SysTryCatch(NID_UI_CTRL, pImpl, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
199
200         ClearLastResult();
201
202         return pImpl;
203
204 CATCH:
205         delete pCore;
206         return null;
207 }
208
209 result
210 _CustomListImpl::InitializeBounds(const Rectangle& rect)
211 {
212         result r = E_SUCCESS;
213
214         r = InitializeBoundsProperties(GET_SIZE_INFO(CustomList), rect, GetCore().GetOrientation());
215         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
216
217         return E_SUCCESS;
218 }
219
220 result
221 _CustomListImpl::AddCustomItemEventListener(const ICustomItemEventListener& listener)
222 {
223         _ListListener* pListenersList = new (std::nothrow) _ListListener();
224         SysTryReturn(NID_UI_CTRL, pListenersList, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
225
226         pListenersList->pListener = const_cast<ICustomItemEventListener*>(&listener);
227
228         __itemListenersList.Add(*pListenersList);
229
230         return E_SUCCESS;
231 }
232
233 result
234 _CustomListImpl::RemoveCustomItemEventListener(const ICustomItemEventListener& listener)
235 {
236         _ListListener* pListenersList = null;
237         result r = E_SYSTEM;
238
239         int count = __itemListenersList.GetCount();
240
241         for (int itemListenerCount = 0; itemListenerCount < count; itemListenerCount++)
242         {
243                 pListenersList = dynamic_cast<_ListListener*>(__itemListenersList.GetAt(itemListenerCount));
244
245                 if ((pListenersList != null) && (pListenersList->pListener == &listener))
246                 {
247                         r = E_SUCCESS;
248                         __itemListenersList.RemoveAt(itemListenerCount, true);
249                         break;
250                 }
251         }
252
253         return r;
254 }
255
256 result
257 _CustomListImpl::Initialize(void)
258 {
259         result r = E_SUCCESS;
260
261         __pItemProvider = new (std::nothrow) _CustomListItemDataProvider(this);
262         SysTryReturnResult(NID_UI_CTRL, __pItemProvider != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
263
264         TableViewStyle style = GetCore().GetTableViewStyle();
265         SysTryReturn(NID_UI_CTRL, style == TABLE_VIEW_STYLE_SIMPLE, E_INVALID_OPERATION, E_INVALID_OPERATION, "[E_INVALID_OPERATION] The style of TableView is not TABLE_VIEW_STYLE_SIMPLE");
266
267         _TableViewItemProvider* pItemProvider = _TableViewItemProvider::CreateTableViewItemProviderN(style);
268         SysTryReturn(NID_UI_CTRL, pItemProvider != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
269
270         r = pItemProvider->SetSimpleStyleItemProvider(__pItemProvider);
271
272         if (r != E_SUCCESS)
273         {
274                 delete pItemProvider;
275                 SysTryReturn(NID_UI_CTRL, false, r, r, "[%s] Propagating.", GetErrorMessage(r));
276         }
277
278         r = GetCore().SetItemProvider(pItemProvider);
279         SysTryReturn(NID_UI_CTRL, (r == E_SUCCESS), r, r, "[%s] Propagating.", GetErrorMessage(r));
280
281         r = GetCore().AddTableViewItemEventListener(*this);
282         SysTryReturn(NID_UI_CTRL, (r == E_SUCCESS), r, r, "[%s] Propagating.", GetErrorMessage(r));
283
284         return r;
285 }
286
287 result
288 _CustomListImpl::AddItem(const CustomListItem& item, int itemId)
289 {
290         return InsertItemAt(GetItemCount(), item, itemId);
291 }
292
293 result
294 _CustomListImpl::InsertItemAt(int index, const CustomListItem& item, int itemId)
295 {
296         result r = E_SUCCESS;
297
298         SysTryReturnResult(NID_UI_CTRL, (index >= 0 && index <= GetItemCount()),
299                         E_INVALID_ARG, "The index %d is invalid.", index);
300
301         item.__pCustomListItemImpl->itemId = itemId;
302
303         r = InsertIntoItemsList(item, -1, index);
304         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to insert an item.");
305
306         if (GetCore().GetFirstDrawnFlag() == false)
307         {
308                 r = GetCore().RefreshTableView(0, index, TABLE_VIEW_REFRESH_TYPE_ITEM_ADD);
309                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[%s] Propagating.",GetErrorMessage(r));
310         }
311
312         return r;
313
314 CATCH:
315         RemoveFromItemsList(-1, index);
316         return E_SYSTEM;
317 }
318
319 result
320 _CustomListImpl::SetItemAt(int index, const CustomListItem& item, int itemId)
321 {
322         SysTryReturnResult(NID_UI_CTRL, (index >= 0 && index < GetItemCount()),
323                         E_INVALID_ARG, "The index %d is invalid.", index);
324
325         SysTryReturnResult(NID_UI_CTRL, (IsItemNew(item) == true), E_SYSTEM, "A system error has occurred. The item already exists.");
326
327         result r = E_SUCCESS;
328
329         item.__pCustomListItemImpl->__pTableViewItemData = GetTableViewItemAt(-1, index);
330
331         _CheckElementModel* pOldCheckElement = GetCheckElementAt(-1, index);
332         _CheckBoxBitmapType oldCheckStatus = (pOldCheckElement) ? (pOldCheckElement->GetCheckBoxStatus()) : CHECK_BOX_UNCHECKED;
333
334         item.__pCustomListItemImpl->itemId = itemId;
335
336         _CheckElementModel* pCheckElement = item.__pCustomListItemImpl->GetCheckElement();
337
338         if (pCheckElement)
339         {
340                 pCheckElement->SetCheckBoxStatus(oldCheckStatus);
341         }
342
343         r = SetInItemsList(item, -1, index);
344         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, E_SYSTEM, "A system error has occurred. Failed to set an item.");
345
346         _TableViewItemUpdateParams updateParams;
347         updateParams.pItem = const_cast<CustomListItem*>(&item);
348         updateParams.isDividerEnabled = _isDividerEnabled;
349         updateParams.pCheckBitmaps = _pCheckBitmaps;
350         updateParams.annexStyle = _annexStyle;
351
352         r = _CustomListItemImpl::UpdateTableViewItem(updateParams);
353         SysTryReturn(NID_UI_CTRL, (r == E_SUCCESS), E_SYSTEM, E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to refresh an item.");
354
355         if (GetCore().GetFirstDrawnFlag() == false)
356         {
357                 r = GetCore().RefreshTableView(0, index, TABLE_VIEW_REFRESH_TYPE_ITEM_MODIFY);
358                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, E_SYSTEM, "Propagating.");
359         }
360
361         return r;
362 }
363
364 result
365 _CustomListImpl::RemoveItemAt(int index)
366 {
367         result r = E_SUCCESS;
368
369         SysTryReturnResult(NID_UI_CTRL, (index >= 0 && index < GetItemCount()),
370                         E_INVALID_ARG, "The index %d is invalid.", index);
371
372         int groupIndex = 0;
373
374         if (GetCore().GetFirstDrawnFlag() == false)
375         {
376                 r = GetCore().RefreshTableView(groupIndex, index, TABLE_VIEW_REFRESH_TYPE_ITEM_REMOVE);
377                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, E_SYSTEM, "Propagating.");
378         }
379
380         r = RemoveFromItemsList(-1, index);
381         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, E_SYSTEM, "A system error has occurred. Failed to remove an item.");
382
383         return r;
384 }
385
386 result
387 _CustomListImpl::RemoveAllItems(void)
388 {
389         result r = E_SUCCESS;
390         result finalResult = E_SUCCESS;
391
392         for (int index = GetItemCount() - 1; index >= 0; index--)
393         {
394                 r = RemoveItemAt(index);
395
396                 if (r != E_SUCCESS)
397                 {
398                         finalResult = r;
399                         SysLog(NID_UI_CTRL, "[E_SYSTEM] A system error has occurred. Item at %d index not removed successfully.", index);
400                 }
401         }
402
403         return finalResult;
404 }
405
406 result
407 _CustomListImpl::SetItemEnabled(int index, bool enable)
408 {
409         result r = E_SUCCESS;
410
411         SysTryReturnResult(NID_UI_CTRL, (index >= 0 && index < GetItemCount()),
412                         E_SYSTEM, "[E_SYSTEM] A system error has occurred. The index %d is invalid.", index);
413
414         _CheckElementModel* pCheckElementModel = GetCheckElementAt(-1, index);
415
416         if (pCheckElementModel)
417         {
418                 if (enable)
419                 {
420                         if (pCheckElementModel->GetCheckBoxStatus() == CHECK_BOX_DISABLED)
421                         {
422                                 pCheckElementModel->SetCheckBoxStatus(CHECK_BOX_CHECKED);
423                         }
424                 }
425                 else
426                 {
427                         if (pCheckElementModel->GetCheckBoxStatus() == CHECK_BOX_CHECKED)
428                         {
429                                 if (_annexStyle == TABLE_VIEW_ANNEX_STYLE_MARK)
430                                 {
431                                         pCheckElementModel->SetCheckBoxStatus(CHECK_BOX_DISABLED);
432                                 }
433                         }
434                 }
435         }
436
437         r = GetCore().SetItemEnabled(0, index, enable);
438         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[%s] Propagating.", GetErrorMessage(r));
439
440         DrawItem(-1, index);
441
442         return r;
443 }
444
445 bool
446 _CustomListImpl::IsItemEnabled(int index) const
447 {
448         return GetCore().IsItemEnabled(0, index);
449 }
450
451 result
452 _CustomListImpl::SetItemChecked(int groupIndex, int itemIndex, bool check)
453 {
454         return SetItemChecked(itemIndex, check);
455 }
456
457 result
458 _CustomListImpl::SetItemChecked(int index, bool check)
459 {
460         SysTryReturnResult(NID_UI_CTRL, (index >= 0 && index < GetItemCount()), E_SYSTEM, "[E_SYSTEM] A system error has occurred. The index %d is invalid.", index);
461
462         SysTryReturnResult(NID_UI_CTRL, (_annexStyle != TABLE_VIEW_ANNEX_STYLE_NORMAL), E_SYSTEM, "[E_SYSTEM] A system error has occurred. List style should not be TABLE_VIEW_ANNEX_STYLE_NORMAL");
463
464         if (IsItemChecked(index) == check)
465         {
466                 return E_SUCCESS;
467         }
468
469         SysTryReturnResult(NID_UI_CTRL, (IsItemEnabled(index)), E_SYSTEM, "[E_SYSTEM] A system error has occurred. The List item is not enabled at index %d.", index);
470
471         if (_annexStyle == TABLE_VIEW_ANNEX_STYLE_RADIO)
472         {
473                 if (check)
474                 {
475                         if (_currentRadioIndex != -1)
476                         {
477                                 _CheckElementModel* pOldCheckElementModel = GetCheckElementAt(-1, _currentRadioIndex);
478                                 SysTryReturnResult(NID_UI_CTRL, pOldCheckElementModel, E_SYSTEM, "A system error has occurred. tableViewItem is not constructed correctly.");
479
480                                 pOldCheckElementModel->SetCheckBoxStatus(CHECK_BOX_UNCHECKED);
481
482                                 _TableViewItemData* pOldRadioItem = GetTableViewItemAt(-1, _currentRadioIndex);
483                                 SysTryReturnResult(NID_UI_CTRL, pOldRadioItem, E_SYSTEM, "A system error has occurred. Failed to get item at %d index.", _currentRadioIndex);
484
485                                 pOldRadioItem->Invalidate(true);
486                         }
487                         _currentRadioIndex = index;
488                 }
489                 else
490                 {
491                         _currentRadioIndex = -1;
492                 }
493         }
494
495         _CheckElementModel* pCheckElementModel = GetCheckElementAt(-1, index);
496         SysTryReturnResult(NID_UI_CTRL, pCheckElementModel, E_SYSTEM, "A system error has occurred. TableViewItem is not constructed correctly.");
497
498         pCheckElementModel->SetCheckBoxStatus((_CheckBoxBitmapType)check);
499
500         DrawItem(-1, index);
501
502         return E_SUCCESS;
503 }
504
505 bool
506 _CustomListImpl::IsItemChecked(int groupIndex, int subIndex) const
507 {
508         return IsItemChecked(subIndex);
509 }
510
511 bool
512 _CustomListImpl::IsItemChecked(int index) const
513 {
514         SysTryReturn(NID_UI_CTRL, (_annexStyle != TABLE_VIEW_ANNEX_STYLE_NORMAL),
515                         false, E_SYSTEM, "[E_SYSTEM] A system error has occurred. list style should not be TABLE_VIEW_ANNEX_STYLE_NORMAL.");
516
517         SysTryReturn(NID_UI_CTRL, (index >= 0 && index < GetItemCount()),
518                         false, E_INVALID_ARG, "[E_INVALID_ARG] The index %d is invalid.", index);
519
520         const _CheckElementModel* pCheckElement = GetCheckElementAt(-1, index);
521         SysTryReturn(NID_UI_CTRL, pCheckElement, false, E_SYSTEM, "[E_SYSTEM] A system error has occurred. CheckElement is not constructed properly.");
522
523         return (bool)pCheckElement->GetCheckBoxStatus();
524 }
525
526 result
527 _CustomListImpl::SetAllItemsChecked(bool check)
528 {
529         SysTryReturnResult(NID_UI_CTRL, (_annexStyle != TABLE_VIEW_ANNEX_STYLE_NORMAL), E_SYSTEM, "[E_SYSTEM] A system error has occurred. List style should not be TABLE_VIEW_ANNEX_STYLE_NORMAL");
530         SysTryReturnResult(NID_UI_CTRL, (_annexStyle != TABLE_VIEW_ANNEX_STYLE_RADIO), E_SYSTEM, "[E_SYSTEM] A system error has occurred. List style should not be TABLE_VIEW_ANNEX_STYLE_RADIO");
531
532         _CheckElementModel* pCheckElement = null;
533
534         for (int index = 0; index < GetItemCount(); index++)
535         {
536                 if (IsItemEnabled(index))
537                 {
538                         pCheckElement = GetCheckElementAt(-1, index);
539                         SysTryReturnResult(NID_UI_CTRL, (pCheckElement != null), E_SYSTEM, "[E_SYSTEM] A system error has occurred. Checkbox element not created");
540
541                         pCheckElement->SetCheckBoxStatus((_CheckBoxBitmapType)check);
542                 }
543         }
544
545         GetCore().Draw();
546
547         return E_SUCCESS;
548 }
549
550 result
551 _CustomListImpl::RemoveAllCheckedItems(void)
552 {
553         result r = E_SUCCESS;
554         result finalResult = E_SUCCESS;
555
556         SysTryReturnResult(NID_UI_CTRL, (_annexStyle != TABLE_VIEW_ANNEX_STYLE_NORMAL), E_SYSTEM, "[E_SYSTEM] A system error has occurred. List style should not be TABLE_VIEW_ANNEX_STYLE_NORMAL");
557         SysTryReturnResult(NID_UI_CTRL, (_annexStyle != TABLE_VIEW_ANNEX_STYLE_RADIO), E_SYSTEM, "[E_SYSTEM] A system error has occurred. List style should not be TABLE_VIEW_ANNEX_STYLE_RADIO");
558
559         for (int index = GetItemCount() -1; index >= 0; index--)
560         {
561                 if (IsItemChecked(index))
562                 {
563                         r = RemoveItemAt(index);
564
565                         if (r != E_SUCCESS)
566                         {
567                                 finalResult = r;
568                                 SysLog(NID_UI_CTRL, "Item at %d index not removed successfully.", index);
569                         }
570                 }
571         }
572
573         return finalResult;
574 }
575
576 int
577 _CustomListImpl::GetFirstCheckedItemIndex(void) const
578 {
579         SysTryReturn(NID_UI_CTRL, (_annexStyle != TABLE_VIEW_ANNEX_STYLE_NORMAL), INVALID_INDEX, E_SYSTEM, "[E_SYSTEM] A system error has occurred. List style should not be TABLE_VIEW_ANNEX_STYLE_NORMAL");
580
581         for (int index = 0; index < GetItemCount(); index++)
582         {
583                 if (IsItemChecked(index))
584                 {
585                         SetLastResult(E_SUCCESS);
586                         return index;
587                 }
588         }
589         SetLastResult(E_SUCCESS);
590         return INVALID_INDEX;
591 }
592
593 int
594 _CustomListImpl::GetLastCheckedItemIndex(void) const
595 {
596         SysTryReturn(NID_UI_CTRL, (_annexStyle != TABLE_VIEW_ANNEX_STYLE_NORMAL), INVALID_INDEX, E_SYSTEM, "[E_SYSTEM] A system error has occurred. List style should not be TABLE_VIEW_ANNEX_STYLE_NORMAL");
597
598         for (int index = GetItemCount() - 1; index >= 0; index--)
599         {
600                 if (IsItemChecked(index))
601                 {
602                         SetLastResult(E_SUCCESS);
603                         return index;
604                 }
605         }
606         SetLastResult(E_SUCCESS);
607         return INVALID_INDEX;
608 }
609
610 int
611 _CustomListImpl::GetNextCheckedItemIndexAfter(int index) const
612 {
613         SysTryReturn(NID_UI_CTRL, (_annexStyle != TABLE_VIEW_ANNEX_STYLE_NORMAL), INVALID_INDEX, E_SYSTEM, "[E_SYSTEM] A system error has occurred. List style should not be TABLE_VIEW_ANNEX_STYLE_NORMAL");
614
615         SysTryReturn(NID_UI_CTRL, (index >= 0 && index < GetItemCount()),
616                                 INVALID_INDEX, E_SYSTEM, "[E_SYSTEM] A system error has occurred. The index %d is invalid.", index);
617
618         for (int itemCount = index + 1; itemCount < GetItemCount(); itemCount++)
619         {
620                 if (IsItemChecked(itemCount))
621                 {
622                         SetLastResult(E_SUCCESS);
623                         return itemCount;
624                 }
625         }
626         SetLastResult(E_SUCCESS);
627         return INVALID_INDEX;
628 }
629
630 int
631 _CustomListImpl::GetItemIndexFromItemId(int itemId) const
632 {
633         for (int index = 0; index < GetItemCount(); index++)
634         {
635                 const CustomListItem* pCustomListItem = GetCustomListItemAt(-1, index);
636                 SysTryReturn(NID_UI_CTRL, pCustomListItem, INVALID_INDEX, E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to get an item at index(%d).", index);
637
638                 SysTryReturn(NID_UI_CTRL, pCustomListItem->__pCustomListItemImpl, INVALID_INDEX, E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to get an item at index(%d).", index);
639
640                 if (pCustomListItem->__pCustomListItemImpl->itemId == itemId)
641                 {
642                         SetLastResult(E_SUCCESS);
643                         return index;
644                 }
645         }
646         SetLastResult(E_SUCCESS);
647         return INVALID_INDEX;
648 }
649
650 void
651 _CustomListImpl::ScrollToBottom(void)
652 {
653         GetCore().SetBottomDrawnItemIndex(0 ,GetItemCount() - 1);
654         GetCore().Draw();
655         return;
656 }
657 void
658 _CustomListImpl::ScrollToTop(void)
659 {
660         GetCore().SetTopDrawnItemIndex(0,0);
661         GetCore().Draw();
662         return;
663 }
664
665 result
666 _CustomListImpl::ScrollToTop(int index)
667 {
668         SysTryReturnResult(NID_UI_CTRL, (index >= 0 && index < GetItemCount()), E_INVALID_ARG, "Invalid index(%d).", index);
669
670         result r = GetCore().SetTopDrawnItemIndex(0, index);
671         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[%s] Propagating.", GetErrorMessage(r));
672
673         GetCore().Draw();
674
675         return r;
676 }
677
678 result
679 _CustomListImpl::RefreshItem(int index)
680 {
681         SysTryReturnResult(NID_UI_CTRL, (index >= 0 && index < GetItemCount()), E_INVALID_ARG, "Invalid index(%d).", index);
682
683         int topItemIndex = -1;
684         int bottomItemIndex = -1;
685         int groupIndex = -1;
686
687         GetCore().GetTopDrawnItemIndex(groupIndex, topItemIndex);
688         GetCore().GetBottomDrawnItemIndex(groupIndex, bottomItemIndex);
689
690         SysTryReturnResult(NID_UI_CTRL, (index >= topItemIndex && index <= bottomItemIndex), E_INVALID_OPERATION,
691                                           "Index should be within drawn item range %d.", index);
692
693         result r = E_SUCCESS;
694
695         _TableViewItemUpdateParams updateParams;
696         updateParams.pItem = GetCustomListItemAt(-1, index);
697         updateParams.isDividerEnabled = _isDividerEnabled;
698         updateParams.pCheckBitmaps = _pCheckBitmaps;
699         updateParams.annexStyle = _annexStyle;
700
701         r = _CustomListItemImpl::UpdateTableViewItem(updateParams);
702         SysTryReturnResult(NID_UI_CTRL, (r == E_SUCCESS), E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to refresh an item.");
703
704         DrawItem(-1, index);
705
706         return E_SUCCESS;
707 }
708
709 int
710 _CustomListImpl::GetItemIdAt(int index) const
711 {
712         SysTryReturn(NID_UI_CTRL, (index >= 0 && index < GetItemCount()),
713                                 -1, E_INVALID_ARG, "[E_INVALID_ARG] The index %d is invalid.", index);
714
715         const CustomListItem* pCustomListItem = GetCustomListItemAt(-1, index);
716         SysTryReturn(NID_UI_CTRL, pCustomListItem, -1, E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to get an item at index(%d).", index);
717
718         SysTryReturn(NID_UI_CTRL, pCustomListItem->__pCustomListItemImpl, -1, E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to get an item at index(%d).", index);
719
720         SetLastResult(E_SUCCESS);
721         return pCustomListItem->__pCustomListItemImpl->itemId;
722 }
723
724 void
725 _CustomListImpl::OnTableViewItemStateChanged(_TableView& tableView, int itemIndex, _TableViewItem* pItem, TableViewItemStatus status)
726 {
727         ItemStatus itemStatus = ITEM_HIGHLIGHTED;
728
729         switch (status)
730         {
731         case TABLE_VIEW_ITEM_STATUS_SELECTED:
732                 itemStatus = ITEM_SELECTED;
733                 break;
734         case TABLE_VIEW_ITEM_STATUS_HIGHLIGHTED:
735                 itemStatus = ITEM_HIGHLIGHTED;
736                 break;
737         case TABLE_VIEW_ITEM_STATUS_CHECKED:
738                 itemStatus = ITEM_CHECKED;
739                 break;
740         case TABLE_VIEW_ITEM_STATUS_UNCHECKED:
741                 itemStatus = ITEM_UNCHECKED;
742                 break;
743         default:
744                 SetLastResult(E_SYSTEM);
745                 break;
746         }
747
748         if ((!_isDividerEnabled) && (_annexStyle != TABLE_VIEW_ANNEX_STYLE_NORMAL))
749         {
750                 bool isChecked = IsItemChecked(itemIndex);
751
752                 if (isChecked)
753                 {
754                         itemStatus = ITEM_UNCHECKED;
755                 }
756                 else
757                 {
758                         itemStatus = ITEM_CHECKED;
759                 }
760
761                 SetItemChecked(itemIndex, !isChecked);
762         }
763
764         ProcessItemStateChange(-1, itemIndex, itemStatus);
765         return;
766 }
767
768 void
769 _CustomListImpl::OnTableViewContextItemActivationStateChanged(_TableView& tableView, int itemIndex, _TableViewItem* pContextItem, bool activated)
770 {
771         return;
772 }
773
774 void
775 _CustomListImpl::OnTableViewItemReordered(_TableView& tableView, int itemIndexFrom, int itemIndexTo)
776 {
777         return;
778 }
779
780 void
781 _CustomListImpl::OnGroupedTableViewGroupItemStateChanged(_TableView& tableView, int groupIndex, _TableViewItem* pItem, TableViewItemStatus status)
782 {
783         return;
784 }
785
786 void
787 _CustomListImpl::OnGroupedTableViewItemStateChanged(_TableView& tableView, int groupIndex, int itemIndex, _TableViewItem* pItem, TableViewItemStatus status)
788 {
789         return;
790 }
791
792 void
793 _CustomListImpl::OnGroupedTableViewContextItemActivationStateChanged(_TableView& tableView, int groupIndex, int itemIndex, _TableViewItem* pContextItem, bool activated)
794 {
795         return;
796 }
797
798 void
799 _CustomListImpl::OnGroupedTableViewItemReordered(_TableView& tableView, int groupIndexFrom, int itemIndexFrom, int groupIndexTo, int itemIndexTo)
800 {
801         return;
802 }
803
804 void
805 _CustomListImpl::OnSectionTableViewItemStateChanged(_TableView& tableView, int sectionIndex, int itemIndex, _TableViewItem* pItem, TableViewItemStatus status)
806 {
807         return;
808 }
809
810 void
811 _CustomListImpl::OnSectionTableViewContextItemActivationStateChanged(_TableView& tableView, int sectionIndex, int itemIndex, _TableViewItem* pContextItem, bool activated)
812 {
813         return;
814 }
815
816 void
817 _CustomListImpl::OnTableViewItemSwept(_TableView& tableView, int groupIndex, int itemIndex, TableViewSweepDirection direction)
818 {
819         return;
820 }
821
822 void
823 _CustomListImpl::ProcessItemStateChange(int groupIndex, int index, int elementId, ItemStatus itemStatus)
824 {
825         int itemId = GetItemIdAt(index);
826
827         _ListListener* pListenerList = null;
828         ICustomItemEventListener* pEventListener = null;
829
830         int count = __itemListenersList.GetCount();
831         for (int listenerCount = 0; listenerCount < count; listenerCount++)
832         {
833                 pListenerList = dynamic_cast<_ListListener*>(__itemListenersList.GetAt(listenerCount));
834                 SysTryReturnVoidResult(NID_UI_CTRL, (pListenerList != null), E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to get Listener.");
835
836                 pEventListener = dynamic_cast<ICustomItemEventListener*>(pListenerList->pListener);
837                 SysTryReturnVoidResult(NID_UI_CTRL, (pEventListener != null), E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to get Listener.");
838
839                 pEventListener->OnItemStateChanged(GetPublic(), index, itemId, elementId, itemStatus);
840         }
841         SetLastResult(E_SUCCESS);
842
843         return;
844 }
845
846 void
847 _CustomListImpl::ProcessItemStateChange(int groupIndex, int index, ItemStatus itemStatus)
848 {
849         int itemId = GetItemIdAt(index);
850
851         _ListListener* pListenerList = null;
852         ICustomItemEventListener* pEventListener = null;
853
854         int count = __itemListenersList.GetCount();
855         for (int listenerCount = 0; listenerCount < count; listenerCount++)
856         {
857                 pListenerList = dynamic_cast<_ListListener*>(__itemListenersList.GetAt(listenerCount));
858                 SysTryReturnVoidResult(NID_UI_CTRL, (pListenerList != null), E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to get Listener.");
859
860                 pEventListener = dynamic_cast<ICustomItemEventListener*>(pListenerList->pListener);
861                 SysTryReturnVoidResult(NID_UI_CTRL, (pEventListener != null), E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to get Listener.");
862
863                 pEventListener->OnItemStateChanged(GetPublic(), index, itemId, itemStatus);
864         }
865         SetLastResult(E_SUCCESS);
866
867         return;
868 }
869
870 class _CustomListMaker
871         : public _UiBuilderControlMaker
872 {
873 public:
874         _CustomListMaker(_UiBuilder* uibuilder)
875                 : _UiBuilderControlMaker(uibuilder){};
876         virtual ~_CustomListMaker(){};
877         static _UiBuilderControlMaker*
878         GetInstance(_UiBuilder* uibuilder)
879         {
880                 _CustomListMaker* pCustomListMaker = new (std::nothrow) _CustomListMaker(uibuilder);
881                 return pCustomListMaker;
882         };
883 protected:
884         virtual Control*
885         Make(_UiBuilderControl* pControl)
886         {
887                 result r = E_SYSTEM;
888                 _UiBuilderControlLayout* pControlProperty = null;
889                 CustomList* pCustomList = null;
890
891                 Tizen::Base::String elementString;
892                 Color color;
893                 Rectangle rect;
894
895                 CustomListStyle style = CUSTOM_LIST_STYLE_NORMAL;
896                 bool isItemDivider = true;
897
898                 GetProperty(pControl, &pControlProperty);
899
900                 if (pControlProperty == null)
901                 {
902                         return null;
903                 }
904
905                 pCustomList = new (std::nothrow) CustomList();
906                 if (pCustomList == null)
907                 {
908                         return null;
909                 }
910
911                 rect = pControlProperty->GetRect();
912
913                 Tizen::Base::String styleString;
914                 styleString = pControlProperty->GetStyle();
915
916                 if (styleString.Equals(L"CUSTOM_LIST_STYLE_NORMAL", false))
917                 {
918                         style = CUSTOM_LIST_STYLE_NORMAL;
919                 }
920                 else if (styleString.Equals(L"CUSTOM_LIST_STYLE_RADIO", false))
921                 {
922                         style = CUSTOM_LIST_STYLE_RADIO;
923                 }
924                 else if (styleString.Equals(L"CUSTOM_LIST_STYLE_RADIO_WITH_DIVIDER", false))
925                 {
926                         style = CUSTOM_LIST_STYLE_RADIO_WITH_DIVIDER;
927                 }
928                 else if (styleString.Equals(L"CUSTOM_LIST_STYLE_MARK", false))
929                 {
930                         style = CUSTOM_LIST_STYLE_MARK;
931                 }
932                 else if (styleString.Equals(L"CUSTOM_LIST_STYLE_MARK_WITH_DIVIDER", false))
933                 {
934                         style = CUSTOM_LIST_STYLE_MARK_WITH_DIVIDER;
935                 }
936                 else if (styleString.Equals(L"CUSTOM_LIST_STYLE_ONOFF", false))
937                 {
938                         style = CUSTOM_LIST_STYLE_ONOFF;
939                 }
940                 else if (styleString.Equals(L"CUSTOM_LIST_STYLE_ONOFF_WITH_DIVIDER", false))
941                 {
942                         style = CUSTOM_LIST_STYLE_ONOFF_WITH_DIVIDER;
943                 }
944                 else
945                 {
946                         style = CUSTOM_LIST_STYLE_NORMAL;
947                 }
948
949                 //Construct
950                 if (pControl->GetElement(L"itemDivider", elementString))
951                 {
952                         if (elementString.Equals(L"true", false))
953                         {
954                                 isItemDivider = true;
955                         }
956                         else
957                         {
958                                 isItemDivider = false;
959                         }
960                 }
961
962                 r = pCustomList->Construct(rect, style, isItemDivider);
963                 if (r != E_SUCCESS)
964                 {
965                         delete pCustomList;
966                         return null;
967                 }
968
969                 if (pControl->GetElement(L"textOfEmptyList", elementString))
970                 {
971                         pCustomList->SetTextOfEmptyList(elementString);
972                 }
973
974                 if (pControl->GetElement(L"colorOfEmptyListText", elementString))
975                 {
976                         ConvertStringToColor(elementString, color);
977                         pCustomList->SetTextColorOfEmptyList(color);
978                 }
979
980                 return pCustomList;
981         }
982
983 };// _ButtonMaker
984
985 _CustomListRegister::_CustomListRegister(void)
986 {
987         _UiBuilderControlTableManager* pUiBuilderControlTableManager = _UiBuilderControlTableManager::GetInstance();
988
989         if (pUiBuilderControlTableManager)
990         {
991                 pUiBuilderControlTableManager->RegisterControl(L"CustomList", _CustomListMaker::GetInstance);
992         }
993 }
994 _CustomListRegister::~_CustomListRegister(void)
995 {
996         _UiBuilderControlTableManager* pUiBuilderControlTableManager = _UiBuilderControlTableManager::GetInstance();
997
998         if (pUiBuilderControlTableManager)
999         {
1000                 pUiBuilderControlTableManager->UnregisterControl(L"CustomList");
1001         }
1002 }
1003 static _CustomListRegister CustomListRegisterToUiBuilder;
1004 }}} //Tizen::Ui::Controls