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