Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / controls / FUiCtrl_TableViewPresenter.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_TableViewPresenter.cpp
20  * @brief       This is the header file for the _TableViewPresenter class.
21  *
22  * This file contains the declarations of the _TableViewPresenter class.
23  */
24
25 #include <FGrpRectangle.h>
26 #include <FSysSystemTime.h>
27 #include "FUi_ResourceManager.h"
28 #include "FUi_UiTouchEvent.h"
29 #include "FUi_ResourceManager.h"
30 #include "FUiAnim_VisualElement.h"
31 #include "FUiCtrl_FastScroll.h"
32 #include "FUiCtrl_ListViewModel.h"
33 #include "FUiCtrl_Scroll.h"
34 #include "FUiCtrl_TableView.h"
35 #include "FUiCtrl_TableViewItem.h"
36 #include "FUiCtrl_TableViewPresenter.h"
37 #include "FUiCtrl_TableViewItemProviderAdaptor.h"
38
39 using namespace Tizen::Ui::Animations;
40 using namespace Tizen::Graphics;
41 using namespace Tizen::Base;
42 using namespace Tizen::Base::Runtime;
43
44 namespace Tizen { namespace Ui { namespace Controls
45 {
46 _TableViewPresenter::_TableViewPresenter()
47         : __pTableView(null)
48         , __pListModel(null)
49         , __pProviderAdaptor(null)
50         , __topMargin(0)
51         , __bottomMargin(0)
52         , __leftMargin(0)
53         , __modelInitialized(false)
54         , __firstDrawnFlag(true)
55         , __statusChangedFlag(true)
56         , __scrolling(true)
57         , __movedPos(0)
58         , __pItemDrawingProperty(null)
59         , __pBaseVisualElement(null)
60         , __sweepOccured(false)
61         , __sweptItemPosition()
62         , __reservedScrollItemAlignment(TABLE_VIEW_SCROLL_ITEM_ALIGNMENT_TOP)
63         , __firstTouchMoved(0)
64         , __pReorderScrollTimer(null)
65         , __reorderInfo()
66         , __itemTotalHeight(0)
67         , __pFastScrollTimer(null)
68         , __isFastScrollTimerEnabled(false)
69 {
70         __sweptItemTag.itemIndex = -1;
71         __sweptItemTag.groupIndex = -1;
72
73         __reservedScrollItemIndex.itemIndex = -1;
74         __reservedScrollItemIndex.groupIndex = -1;
75 }
76
77 _TableViewPresenter::~_TableViewPresenter()
78 {
79         Dispose();
80 }
81
82 _TableView*
83 _TableViewPresenter::GetView() const
84 {
85         return __pTableView;
86 }
87
88 _ListViewModel*
89 _TableViewPresenter::GetModel(void) const
90 {
91         return __pListModel;
92 }
93
94 bool
95 _TableViewPresenter::Initialize(_TableView* pTableView)
96 {
97         _ScrollPanelPresenter::Initialize(*pTableView);
98
99         __pTableView = pTableView;
100         __pBaseVisualElement = __pTableView->GetVisualElement();
101         __pBaseVisualElement->SetClipChildrenEnabled(true);
102         __pBaseVisualElement->SetSurfaceOpaque(false);
103
104         result r = __itemHeightList.Construct();
105         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, E_OUT_OF_MEMORY, ("[E_OUT_OF_MEMORY] The memory is insufficient."));
106
107         // Create Model
108         __pListModel = new (std::nothrow) _ListViewModel();
109         SysTryReturn(NID_UI_CTRL, __pListModel != null, false, E_OUT_OF_MEMORY, ("[E_OUT_OF_MEMORY] The memory is insufficient."));
110
111         __pItemDrawingProperty = new (std::nothrow) _ItemDrawingProperty();
112         SysTryReturn(NID_UI_CTRL, __pItemDrawingProperty != null, false, E_OUT_OF_MEMORY, ("[E_OUT_OF_MEMORY] The memory is insufficient."));
113
114         // Timer
115         __pFastScrollTimer = new (std::nothrow) Timer();
116         SysTryCatch(NID_UI_CTRL, __pFastScrollTimer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
117
118         __pFastScrollTimer->Construct(*this);
119         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
120
121         return true;
122
123 CATCH:
124         if (__isFastScrollTimerEnabled)
125         {
126                 __pFastScrollTimer->Cancel();
127         }
128
129         delete __pFastScrollTimer;
130         __pFastScrollTimer = null;
131
132         return false;
133 }
134
135 result
136 _TableViewPresenter::Construct(_TableView* pTableView)
137 {
138         result r = E_SUCCESS;
139
140         // Create Model
141         if (!Initialize(pTableView))
142         {
143                 goto CATCH;
144         }
145
146         return r;
147
148 CATCH:
149         Dispose();
150         return r;
151 }
152
153 void
154 _TableViewPresenter::Dispose(void)
155 {
156         DeleteItemHeightList();
157         DetachContextItem(__sweptItemTag);
158
159         delete __pListModel;
160         __pListModel = null;
161
162         delete __pProviderAdaptor;
163         __pProviderAdaptor = null;
164
165         delete __pItemDrawingProperty;
166         __pItemDrawingProperty = null;
167
168         delete __pReorderScrollTimer;
169         __pReorderScrollTimer = null;
170
171         if (__isFastScrollTimerEnabled)
172         {
173                 __pFastScrollTimer->Cancel();
174         }
175
176         delete __pFastScrollTimer;
177         __pFastScrollTimer = null;
178 }
179
180 result
181 _TableViewPresenter::SetItemProvider(const _TableViewItemProvider* pProvider)
182 {
183         result r = E_SUCCESS;
184
185         _TableViewItemProviderAdaptor* pProviderAdaptor = null;
186         pProviderAdaptor = static_cast <_TableViewItemProviderAdaptor*>(__pListModel->GetItemProviderAdaptor());
187
188         if (pProviderAdaptor == null)
189         {
190                 pProviderAdaptor = new (std::nothrow) _TableViewItemProviderAdaptor();
191                 SysTryReturn(NID_UI_CTRL, pProviderAdaptor != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, ("[E_OUT_OF_MEMORY] The memory is insufficient."));
192         }
193
194         r = __pListModel->RegisterItemProviderAdaptor(pProviderAdaptor);
195
196         pProviderAdaptor->SetItemProvider(const_cast <_TableViewItemProvider*>(pProvider));
197         pProviderAdaptor->SetListWidth(__pTableView->GetBounds().width - (GetLeftMargin() * 2));
198         pProviderAdaptor->SetTableViewStyle(__pTableView->GetTableViewStyle());
199
200         SetTableViewItemProviderAdaptor(pProviderAdaptor);
201
202         return r;
203 }
204
205 result
206 _TableViewPresenter::GetItemFromPosition(const Tizen::Graphics::Point& position, TableViewItemTag& itemPos) const
207 {
208         _TableViewItem* pItem = null;
209         TableViewItemTag lastItemPos = {-1, -1};
210
211         __pListModel->GetFirstLoadedItemIndex(itemPos.groupIndex, itemPos.itemIndex);
212         __pListModel->GetLastLoadedItemIndex(lastItemPos.groupIndex, lastItemPos.itemIndex);
213
214         do
215         {
216                 pItem = static_cast <_TableViewItem*>(__pListModel->LoadItem(itemPos.groupIndex, itemPos.itemIndex));
217                 SysTryCatch(NID_UI_CTRL, pItem != null, , E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The index is out of range.");
218
219                 Rectangle itemBounds = pItem->GetBounds();
220                 if (itemBounds.Contains(position))
221                 {
222                         return E_SUCCESS;
223                 }
224
225                 if ((itemPos.itemIndex == lastItemPos.itemIndex) && (itemPos.groupIndex == lastItemPos.groupIndex))
226                 {
227                         break;
228                 }
229
230         } while (GetNextItemPosition(itemPos, itemPos) == true);
231
232 CATCH:
233         itemPos.itemIndex = -1;
234         itemPos.groupIndex = -1;
235
236         return E_OUT_OF_RANGE;
237 }
238
239 result
240 _TableViewPresenter::GetTopDrawnItemIndex(int& groupIndex, int& itemIndex) const
241 {
242         result r = E_SUCCESS;
243
244         TableViewItemTag itemPos;
245         r = GetTopDrawnItem(itemPos);
246
247         groupIndex = itemPos.groupIndex;
248         itemIndex = itemPos.itemIndex;
249
250         return r;
251 }
252
253 result
254 _TableViewPresenter::SetTopDrawnItemIndex(int groupIndex, int itemIndex)
255 {
256         if (IsEmpty())
257         {
258                 return E_INVALID_ARG;
259         }
260
261         if ((groupIndex < 0) || (groupIndex >= GetGroupCount()) || (itemIndex < -1) || (itemIndex >= GetItemCountAt(groupIndex)))
262         {
263                 return E_OUT_OF_RANGE;
264         }
265
266         ScrollToItem(groupIndex, itemIndex, TABLE_VIEW_SCROLL_ITEM_ALIGNMENT_TOP);
267
268         return E_SUCCESS;
269 }
270
271 result
272 _TableViewPresenter::GetBottomDrawnItemIndex(int& groupIndex, int& itemIndex) const
273 {
274         result r = E_SUCCESS;
275
276         TableViewItemTag itemPos;
277         r = GetBottomDrawnItem(itemPos);
278
279         groupIndex = itemPos.groupIndex;
280         itemIndex = itemPos.itemIndex;
281
282         return r;
283 }
284
285 result
286 _TableViewPresenter::SetBottomDrawnItemIndex(int groupIndex, int itemIndex)
287 {
288         if (IsEmpty())
289         {
290                 return E_INVALID_ARG;
291         }
292
293         if ((groupIndex < 0) || (groupIndex >= GetGroupCount()) || (itemIndex < -1) || (itemIndex >= GetItemCountAt(groupIndex)))
294         {
295                 return E_OUT_OF_RANGE;
296         }
297
298         ScrollToItem(groupIndex, itemIndex, TABLE_VIEW_SCROLL_ITEM_ALIGNMENT_BOTTOM);
299
300         return E_SUCCESS;
301 }
302
303 int
304 _TableViewPresenter::GetGroupCount(void) const
305 {
306         return __pListModel->GetAllGroupCount();
307 }
308
309
310 int
311 _TableViewPresenter::GetItemCountAt(int groupIndex) const
312 {
313         return __pListModel->GetItemCountInGroup(groupIndex);
314 }
315
316 bool
317 _TableViewPresenter::HasSectionFooter(int groupIndex) const
318 {
319         if (__pProviderAdaptor == null)
320         {
321                 return false;
322         }
323
324         return __pProviderAdaptor->HasSectionFooter(groupIndex);
325 }
326
327 int
328 _TableViewPresenter::GetItemCount(void) const
329 {
330         return __pListModel->GetAllItemCount();
331 }
332
333 result
334 _TableViewPresenter::RefreshTableView(int groupIndex, int itemIndex, TableViewRefreshType type, bool animation)
335 {
336         _TableViewItemProviderAdaptor* pProviderAdaptor = __pProviderAdaptor;
337
338         SysTryReturn(NID_UI_CTRL, pProviderAdaptor != null, E_INVALID_STATE, E_INVALID_STATE,
339                                 ("[E_INVALID_STATE] This instance isn't constructed."));
340
341         if ((groupIndex < 0) || (groupIndex > GetGroupCount()) || (itemIndex < -1) || (itemIndex > GetItemCountAt(groupIndex)))
342         {
343                 SysLogException(NID_UI_CTRL, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The index is out of range.");
344                 return E_OUT_OF_RANGE;
345         }
346
347         if (groupIndex == GetGroupCount() && itemIndex != -1 && type != TABLE_VIEW_REFRESH_TYPE_ITEM_ADD)
348         {
349                 SysLogException(NID_UI_CTRL, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The index is out of range.");
350                 return E_OUT_OF_RANGE;
351         }
352
353         if (IsEmpty() && type == TABLE_VIEW_REFRESH_TYPE_ITEM_ADD && __pTableView->GetTableViewStyle() == TABLE_VIEW_STYLE_SIMPLE)
354         {
355                 UpdateTableView();
356         }
357
358         _IListItemCommon* pItem = null;
359         TableViewItemTag topDrawnItemPos = {-1, -1};
360         TableViewItemTag refreshItemPos = {groupIndex, itemIndex};
361         int itemHeight = 0;
362
363         GetTopDrawnItem(topDrawnItemPos);
364
365         if (__sweptItemTag.groupIndex == groupIndex && __sweptItemTag.itemIndex == itemIndex)
366         {
367                 ResetSweepItem();
368         }
369
370         switch (type)
371         {
372         case TABLE_VIEW_REFRESH_TYPE_ITEM_ADD:
373                 if (itemIndex == -1)
374                 {
375                         bool emptyState = IsEmpty();
376
377                         int itemCount = pProviderAdaptor->GetItemCount(groupIndex);
378                         if (__pListModel->InsertGroup(groupIndex, itemCount, false) != E_SUCCESS)
379                         {
380                                 SysLogException(NID_UI_CTRL, E_SYSTEM, "[E_SYSTEM] Unable to add Group item.");
381                                 return E_SYSTEM;
382                         }
383
384                         if (emptyState)
385                         {
386                                 GetFirstItem(topDrawnItemPos);
387                         }
388                         else if (groupIndex <= topDrawnItemPos.groupIndex)
389                         {
390                                 topDrawnItemPos.groupIndex++;
391                         }
392                 }
393                 else
394                 {
395                         pItem = pProviderAdaptor->LoadItem(groupIndex, itemIndex);
396                         SysTryReturn(NID_UI_CTRL, pItem != null, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Unable to load item.");
397
398                         if (__pListModel->InsertItemToGroup(pItem, groupIndex, itemIndex) != E_SUCCESS)
399                         {
400                                 pProviderAdaptor->UnloadItem(pItem, groupIndex, itemIndex);
401                                 SysLogException(NID_UI_CTRL, E_SYSTEM, "[E_SYSTEM] Unable to add item.");
402                                 return E_SYSTEM;
403                         }
404
405                         itemHeight = pItem->GetItemHeight();
406
407                         if (!IsValidDrawnItem(groupIndex, itemIndex))
408                         {
409                                 if (__pListModel->UnloadItem(groupIndex, itemIndex) != E_SUCCESS)
410                                 {
411                                         SysLogException(NID_UI_CTRL, E_SYSTEM, "[E_SYSTEM] Unable to unload item.");
412                                 }
413                         }
414                 }
415
416                 RefreshItemHeightList(groupIndex, itemIndex, TABLE_VIEW_REFRESH_TYPE_ITEM_ADD);
417
418                 if (itemIndex != -1)
419                 {
420                         SetItemHeight(refreshItemPos, itemHeight);
421                 }
422
423                 if (__pListModel->GetAllItemCount() == 1)
424                 {
425                         SetStatusChanged(true);
426                 }
427
428                 break;
429
430         case TABLE_VIEW_REFRESH_TYPE_ITEM_REMOVE:
431                 if (itemIndex == -1)
432                 {
433                         if (groupIndex == GetGroupCount())
434                         {
435                                 SysLogException(NID_UI_CTRL, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The index is out of range.");
436                                 return E_OUT_OF_RANGE;
437                         }
438
439                         if (__pListModel->RemoveGroup(groupIndex) != E_SUCCESS)
440                         {
441                                 SysLogException(NID_UI_CTRL, E_SYSTEM, "[E_SYSTEM] Unable to remove group.");
442                                 return E_SYSTEM;
443                         }
444
445                         if (groupIndex < topDrawnItemPos.groupIndex)
446                         {
447                                 topDrawnItemPos.groupIndex--;
448                         }
449
450                         if ((groupIndex == topDrawnItemPos.groupIndex) && (GetItemCountAt(groupIndex) < topDrawnItemPos.itemIndex))
451                         {
452                                 topDrawnItemPos.itemIndex = -1;
453                         }
454
455                         RefreshItemHeightList(groupIndex, itemIndex, TABLE_VIEW_REFRESH_TYPE_ITEM_REMOVE);
456                 }
457                 else
458                 {
459                         if (itemIndex == GetItemCountAt(groupIndex))
460                         {
461                                 SysLogException(NID_UI_CTRL, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The index is out of range.");
462                                 return E_OUT_OF_RANGE;
463                         }
464
465                         if (__pListModel->RemoveItemAt(groupIndex, itemIndex) != E_SUCCESS)
466                         {
467                                 SysLogException(NID_UI_CTRL, E_SYSTEM, "[E_SYSTEM] Unable to remove item.");
468                                 return E_SYSTEM;
469                         }
470
471                         if ((groupIndex == topDrawnItemPos.groupIndex) && (itemIndex < topDrawnItemPos.itemIndex))
472                         {
473                                 GetPreviousItemPosition(topDrawnItemPos, topDrawnItemPos);
474                         }
475
476                         RefreshItemHeightList(groupIndex, itemIndex, TABLE_VIEW_REFRESH_TYPE_ITEM_REMOVE);
477                 }
478
479                 if (GetModel()->IsValidItem(topDrawnItemPos.groupIndex, topDrawnItemPos.itemIndex) == false)
480                 {
481                         GetPreviousItemPosition(topDrawnItemPos, topDrawnItemPos);
482                 }
483
484                 if (__pListModel->GetAllItemCount() == 0)
485                 {
486                         SetStatusChanged(true);
487                 }
488
489                 break;
490
491         case TABLE_VIEW_REFRESH_TYPE_ITEM_MODIFY:
492                 {
493                         TableViewItemTag itemTag = {groupIndex, itemIndex};
494                         _TableViewItem* pTableViewItem = FindItem(itemTag);
495
496                         if (pTableViewItem == null)
497                         {
498                                 return E_SUCCESS;
499                         }
500
501                         if (pProviderAdaptor->UpdateItem(pTableViewItem, itemTag.groupIndex, itemTag.itemIndex))
502                         {
503                                 CheckItemHeightAndRefreshLayout(itemTag, true);
504
505                                 if (__sweptItemTag.groupIndex != itemTag.groupIndex || __sweptItemTag.itemIndex != itemTag.itemIndex)
506                                 {
507                                         ResetSweptItem();
508                                 }
509
510                                 pTableViewItem->SetItemChanged(true);
511                                 pTableViewItem->Invalidate();
512                                 pTableViewItem->AdjustContextItemBounds();
513
514                                 return E_SUCCESS;
515                         }
516                 }
517                 break;
518
519         default:
520                 SysLogException(NID_UI_CTRL, E_SYSTEM, "[E_SYSTEM] Unable to refresh list.");
521                 return E_SYSTEM;
522                 break;
523         }
524
525         AdjustClientAreaBounds(true);
526
527         RefreshItemLayout(topDrawnItemPos, refreshItemPos, type, animation);
528
529         return E_SUCCESS;
530 }
531
532 result
533 _TableViewPresenter::UpdateTableView(void)
534 {
535         if (__modelInitialized == false)
536         {
537                 SetItemDrawingProperty();
538
539                 PreloadItem();
540
541                 __modelInitialized = true;
542         }
543         else
544         {
545                 TableViewItemTag topDrawnTag = {-1, -1};
546                 int shiftingDistance = 0;
547
548                 ResetSweepItem();
549
550                 GetTopDrawnItem(topDrawnTag);
551
552                 if (__pListModel->IsValidItem(topDrawnTag.groupIndex, topDrawnTag.itemIndex))
553                 {
554                         _TableViewItem* pItem = FindItem(topDrawnTag);
555
556                         if (pItem != null)
557                         {
558                                 shiftingDistance = GetScrollPosition() - pItem->GetBounds().y;
559                         }
560                 }
561
562                 __pListModel->RemoveAllItem(false, true);
563
564                 SetScrollPosition(0, false);
565
566                 __statusChangedFlag = true;
567
568                 PreloadItem();
569
570                 if (__pListModel->IsValidItem(topDrawnTag.groupIndex, topDrawnTag.itemIndex))
571                 {
572                         ScrollToItem(topDrawnTag.groupIndex, topDrawnTag.itemIndex, TABLE_VIEW_SCROLL_ITEM_ALIGNMENT_TOP, shiftingDistance);
573                 }
574         }
575
576         return E_SUCCESS;
577 }
578
579 void
580 _TableViewPresenter::AdjustLayoutItems(int scrollPosition)
581 {
582         TableViewItemTag lastLoadedItemPos = {-1, -1};
583         TableViewItemTag firstLoadedItemPos = {-1, -1};
584         TableViewItemTag currentItemPos = {-1, -1};
585         _TableViewItem* pItem = null;
586
587         __pListModel->GetFirstLoadedItemIndex(firstLoadedItemPos.groupIndex, firstLoadedItemPos.itemIndex);
588         __pListModel->GetLastLoadedItemIndex(lastLoadedItemPos.groupIndex, lastLoadedItemPos.itemIndex);
589
590         pItem = FindItem(firstLoadedItemPos);
591
592         if (pItem != null)
593         {
594                 int positionY = pItem->GetPosition().y;
595
596                 currentItemPos = firstLoadedItemPos;
597
598                 while (positionY > scrollPosition && GetPreviousItemPosition(currentItemPos, currentItemPos))
599                 {
600                         pItem = LoadItem(currentItemPos.groupIndex, currentItemPos.itemIndex);
601
602                         if (pItem == null)
603                         {
604                                 break;
605                         }
606
607                         positionY = pItem->GetPosition().y;
608                 }
609         }
610
611         pItem = FindItem(lastLoadedItemPos);
612
613         if (pItem != null)
614         {
615                 int positionY = pItem->GetPosition().y;
616                 int itemHeight = pItem->GetBounds().height;
617                 int limitScreenArea = scrollPosition + __pTableView->GetBounds().height;
618                 currentItemPos = lastLoadedItemPos;
619
620                 while (positionY + itemHeight < limitScreenArea && GetNextItemPosition(currentItemPos, currentItemPos))
621                 {
622                         pItem = LoadItem(currentItemPos.groupIndex, currentItemPos.itemIndex);
623
624                         if (pItem == null)
625                         {
626                                 break;
627                         }
628
629                         positionY = pItem->GetPosition().y;
630                         itemHeight = pItem->GetBounds().height;
631                 }
632         }
633 }
634
635 void
636 _TableViewPresenter::ResetItemLayout(TableViewItemTag& topDrawnItemTag)
637 {
638         if (__pListModel->IsValidItem(topDrawnItemTag.groupIndex, topDrawnItemTag.itemIndex) == false)
639         {
640                 return;
641         }
642
643         DetachAllItem(true);
644
645         _TableViewItem* pItem = LoadItem(topDrawnItemTag.groupIndex, topDrawnItemTag.itemIndex);
646
647         if (pItem == null)
648         {
649                 return;
650         }
651
652         TableViewItemTag currentItem = topDrawnItemTag;
653         TableViewItemTag itemPos = topDrawnItemTag;
654         int screenAreaHeight = __pTableView->GetBounds().height;
655         int loadedItemTotalHeight = 0;
656         Rectangle itemBounds = pItem->GetBounds();
657
658         itemBounds.y = CalculateItemPositionY(itemPos.groupIndex, itemPos.itemIndex);
659         pItem->SetBounds(itemBounds);
660         CheckItemHeightAndRefreshLayout(itemPos, true);
661
662         loadedItemTotalHeight += itemBounds.height;
663
664         while (loadedItemTotalHeight < screenAreaHeight && GetNextItemPosition(currentItem, itemPos))
665         {
666                 pItem = LoadItem(itemPos.groupIndex, itemPos.itemIndex);
667
668                 if (pItem == null)
669                 {
670                         break;
671                 }
672
673                 currentItem = itemPos;
674                 loadedItemTotalHeight += pItem->GetBounds().height;
675         }
676
677         if (loadedItemTotalHeight < screenAreaHeight)
678         {
679                 __pListModel->GetFirstLoadedItemIndex(itemPos.groupIndex, itemPos.itemIndex);
680                 currentItem = itemPos;
681
682                 while (loadedItemTotalHeight < screenAreaHeight && GetPreviousItemPosition(currentItem, itemPos))
683                 {
684                         pItem = LoadItem(itemPos.groupIndex, itemPos.itemIndex);
685
686                         if (pItem == null)
687                         {
688                                 break;
689                         }
690
691                         currentItem = itemPos;
692                         loadedItemTotalHeight += pItem->GetBounds().height;
693                 }
694         }
695 }
696
697 void
698 _TableViewPresenter::GetFirstLoadedItemIndex(int& groupIndex, int& itemIndex) const
699 {
700         __pListModel->GetFirstLoadedItemIndex(groupIndex, itemIndex);
701 }
702
703 void
704 _TableViewPresenter::GetLastLoadedItemIndex(int& groupIndex, int& itemIndex) const
705 {
706         __pListModel->GetLastLoadedItemIndex(groupIndex, itemIndex);
707 }
708
709 void
710 _TableViewPresenter::RefreshItemLayout(int groupIndex, int itemIndex)
711 {
712         TableViewItemTag itemTag = {groupIndex, itemIndex};
713
714         ResetSweepItem();
715
716         RefreshItemLayout(itemTag, itemTag, TABLE_VIEW_REFRESH_TYPE_ITEM_MODIFY, false);
717 }
718
719 void
720 _TableViewPresenter::RefreshItemLayout(TableViewItemTag& topDrawnItemTag, TableViewItemTag& refreshItemTag, TableViewRefreshType type, bool animation)
721 {
722         if (!__pListModel->IsValidItem(topDrawnItemTag.groupIndex, topDrawnItemTag.itemIndex))
723         {
724                 return;
725         }
726
727         if (refreshItemTag.itemIndex == -1)
728         {
729                 animation = false;
730         }
731
732         _TableViewItem* pItem = null;
733
734         TableViewItemTag itemPos = {-1, -1};
735         TableViewItemTag currentItem = {-1, -1};
736
737         int loadItemCount = 0;
738         int maxLoadItemCount = GetMaxItemCachingSize();
739         Rectangle itemBounds(0, 0, 0, 0);
740
741         __pListModel->GetFirstLoadedItemIndex(itemPos.groupIndex, itemPos.itemIndex);
742
743         currentItem = itemPos;
744
745         int itemPositionY = CalculateItemPositionY(itemPos.groupIndex, itemPos.itemIndex);
746
747         do
748         {
749                 pItem = LoadItem(itemPos.groupIndex, itemPos.itemIndex);
750
751                 if (pItem == null)
752                 {
753                         break;
754                 }
755
756                 if (pItem->HasParent())
757                 {
758                         pItem->SetDrawingProperty(__pItemDrawingProperty);
759                         SetItemType(pItem, itemPos);
760                 }
761
762                 itemBounds = pItem->GetBounds();
763                 itemBounds.y = itemPositionY;
764
765                 pItem->StopAllAnimation();
766
767                 if (animation)
768                 {
769                         if (type == TABLE_VIEW_REFRESH_TYPE_ITEM_ADD)
770                         {
771                                 if (itemPos.groupIndex == refreshItemTag.groupIndex && itemPos.itemIndex == refreshItemTag.itemIndex)
772                                 {
773                                         pItem->SetBounds(itemBounds);
774                                         pItem->FadeInOutItem(false, ADD_ITEM_ANIMATION_DURATION, REFRESH_ITEM_ANIMATION_DELAY);
775                                         pItem->ZoomInOutItem(false, ADD_ITEM_ANIMATION_DURATION, REFRESH_ITEM_ANIMATION_DELAY);
776                                 }
777                                 else
778                                 {
779                                         if (!pItem->MoveItem(Point(itemBounds.x, itemBounds.y), ADD_ITEM_ANIMATION_DURATION, 0))
780                                         {
781                                                 pItem->SetBounds(itemBounds);
782                                         }
783                                 }
784                         }
785                         else
786                         {
787                                 if (!pItem->MoveItem(Point(itemBounds.x, itemBounds.y), REMOVE_ITEM_MOVE_ANIMATION_DURATION, REFRESH_ITEM_ANIMATION_DELAY))
788                                 {
789                                         pItem->SetBounds(itemBounds);
790                                 }
791                         }
792                 }
793                 else
794                 {
795                         pItem->SetBounds(itemBounds);
796                 }
797
798                 currentItem = itemPos;
799                 itemPositionY = itemBounds.y + itemBounds.height;
800
801                 loadItemCount++;
802
803         } while (loadItemCount < maxLoadItemCount && GetNextItemPosition(currentItem, itemPos));
804
805         if (loadItemCount < maxLoadItemCount)
806         {
807                 __pListModel->GetFirstLoadedItemIndex(itemPos.groupIndex, itemPos.itemIndex);
808                 currentItem = itemPos;
809
810                 while (loadItemCount < maxLoadItemCount && GetPreviousItemPosition(currentItem, itemPos))
811                 {
812                         pItem = LoadItem(itemPos.groupIndex, itemPos.itemIndex);
813
814                         if (pItem == null)
815                         {
816                                 break;
817                         }
818
819                         currentItem = itemPos;
820
821                         loadItemCount++;
822                 }
823         }
824
825         if (refreshItemTag.itemIndex == -1)
826         {
827                 ScrollToItem(topDrawnItemTag.groupIndex, topDrawnItemTag.itemIndex, TABLE_VIEW_SCROLL_ITEM_ALIGNMENT_TOP);
828         }
829 }
830
831 void
832 _TableViewPresenter::RefreshItemBounds(_TableViewItem* pItem, TableViewItemTag& itemPos)
833 {
834         Rectangle itemBounds;
835
836         if (pItem == null)
837         {
838                 return;
839         }
840
841         itemBounds = pItem->GetBounds();
842
843         itemBounds.y = CalculateItemPositionY(itemPos.groupIndex, itemPos.itemIndex);
844
845         if (itemPos.itemIndex != -1)
846         {
847                 int itemMargin = GetLeftMargin();
848                 itemBounds.x = itemMargin;
849                 itemBounds.width = __pItemDrawingProperty->width - itemBounds.x - itemMargin;
850         }
851         else
852         {
853                 itemBounds.x = 0;
854                 itemBounds.width = __pItemDrawingProperty->width;
855         }
856
857         pItem->SetBounds(itemBounds);
858 }
859
860 result
861 _TableViewPresenter::GetItemIndexFromPosition(const Point& position, int& groupIndex, int& itemIndex) const
862 {
863         result r = E_SUCCESS;
864         TableViewItemTag itemPos;
865
866         Point targetPosition = position;
867         int scrollPosition = GetScrollPosition();
868         targetPosition.y += scrollPosition;
869
870         r = GetItemFromPosition(targetPosition, itemPos);
871
872         if (r != E_SUCCESS)
873         {
874                 groupIndex = -1;
875                 itemIndex = -1;
876                 return r;
877         }
878
879         groupIndex = itemPos.groupIndex;
880         itemIndex = itemPos.itemIndex;
881
882         return r;
883 }
884
885
886 void
887 _TableViewPresenter::PreloadItem(void)
888 {
889         if (GetModel() == null || __pProviderAdaptor == null)
890         {
891                 return;
892         }
893
894         if (__pListModel->GetAllGroupCount() == 0 && (__pProviderAdaptor != null))
895         {
896                 int itemCount = 0;
897                 int groupCount = __pProviderAdaptor->GetGroupCount();
898
899                 for (int i = 0; i < groupCount; i++)
900                 {
901                         itemCount = __pProviderAdaptor->GetItemCount(i);
902                         __pListModel->AddGroup(itemCount, false);
903                 }
904         }
905
906         __pListModel->RestoreItemStatus();
907
908         CreateItemHeightList();
909         AdjustClientAreaBounds(true);
910
911         int cachingSize = 0;
912
913         if (GetItemCount() > TABLEVIEW_MAX_ITEM_COUNT)
914         {
915                 cachingSize = TABLEVIEW_MAX_ITEM_COUNT;
916         }
917         else if (__pListModel->GetMaxCachingSize() < TABLEVIEW_MAX_ITEM_COUNT)
918         {
919                 cachingSize = __pListModel->GetMaxCachingSize();
920         }
921         else
922         {
923                 cachingSize = GetItemCount();
924         }
925
926         TableViewItemTag itemPos = {-1, -1};
927         GetFirstItem(itemPos);
928
929         _TableViewItem* pItem = null;
930         for (int i = 0; i < cachingSize; i++)
931         {
932                 pItem = LoadItem(itemPos.groupIndex, itemPos.itemIndex);
933
934                 if (pItem == null)
935                 {
936                         break;
937                 }
938
939                 if (GetNextItemPosition(itemPos, itemPos) == false)
940                 {
941                         break;
942                 }
943         }
944
945         if (__pTableView->GetScrollStyle() == TABLE_VIEW_SCROLL_BAR_STYLE_FAST_SCROLL)
946         {
947                 _FastScroll* pFastScroll = __pTableView->GetFastScrollBar();
948                 if (pFastScroll != null)
949                 {
950                         pFastScroll->UpdateIndex();
951                         pFastScroll->SetScrollVisibility(IsScrollable());
952                 }
953         }
954 }
955
956 bool
957 _TableViewPresenter::IsItemChecked(int groupIndex, int itemIndex) const
958 {
959         if ((groupIndex < 0) || (groupIndex >= GetGroupCount()) || (itemIndex < -1) || (itemIndex >= GetItemCountAt(groupIndex)))
960         {
961                 return false;
962         }
963
964         return __pListModel->IsItemChecked(groupIndex, itemIndex);
965 }
966
967 result
968 _TableViewPresenter::SetItemChecked(int groupIndex, int itemIndex, bool checked)
969 {
970         if ((groupIndex < 0) || (groupIndex >= GetGroupCount()) || (itemIndex < -1) || (itemIndex >= GetItemCountAt(groupIndex)))
971         {
972                 return E_OUT_OF_RANGE;
973         }
974
975         if (__modelInitialized == false)
976         {
977                 return E_INVALID_STATE;
978         }
979
980         TableViewItemTag itemPos = {groupIndex, itemIndex};
981
982         bool enabled = __pListModel->IsItemEnabled(itemPos.groupIndex, itemPos.itemIndex);
983         SysTryReturn(NID_UI_CTRL, (enabled == true), E_INVALID_OPERATION, E_INVALID_OPERATION,
984                         "[E_INVALID_OPERATION] The item is disabled.");
985
986         if (__pListModel->IsItemChecked(itemPos.groupIndex, itemPos.itemIndex) == checked)
987         {
988                 return E_SUCCESS;
989         }
990
991         TableViewItemTag itemTag = {groupIndex, itemIndex};
992         _TableViewItem *pItem = FindItem(itemTag);
993         if (pItem != null)
994         {
995                 pItem->SetCheckedAnimationEnabled(checked);
996         }
997
998         result r = __pListModel->SetItemChecked(itemPos.groupIndex, itemPos.itemIndex, checked);
999
1000         return r;
1001 }
1002
1003 bool
1004 _TableViewPresenter::IsItemEnabled(int groupIndex, int itemIndex) const
1005 {
1006         if ((groupIndex < 0) || (groupIndex >= GetGroupCount()) || (itemIndex < -1) || (itemIndex >= GetItemCountAt(groupIndex)))
1007         {
1008                 return false;
1009         }
1010
1011         return __pListModel->IsItemEnabled(groupIndex, itemIndex);
1012 }
1013
1014 result
1015 _TableViewPresenter::SetItemEnabled(int groupIndex, int itemIndex, bool enabled)
1016 {
1017         if ((groupIndex < 0) || (groupIndex >= GetGroupCount()) || (itemIndex < -1) || (itemIndex >= GetItemCountAt(groupIndex)))
1018         {
1019                 return E_OUT_OF_RANGE;
1020         }
1021
1022         TableViewItemTag itemPos = {groupIndex, itemIndex};
1023
1024         if (__pListModel->IsItemEnabled(itemPos.groupIndex, itemPos.itemIndex) == enabled)
1025         {
1026                 return E_SUCCESS;
1027         }
1028
1029         result r = __pListModel->SetItemEnabled(itemPos.groupIndex, itemPos.itemIndex, enabled);
1030
1031         return r;
1032 }
1033
1034 result
1035 _TableViewPresenter::SetStatusChanged(bool changed)
1036 {
1037         __statusChangedFlag = changed;
1038
1039         if (__statusChangedFlag == true)
1040         {
1041                 SetItemDrawingProperty();
1042
1043                 if ((__pItemDrawingProperty != null) && (__pItemDrawingProperty->propertyChanged == true))
1044                 {
1045                         __pListModel->SetAllLoadedItemStateChanged(true);
1046                 }
1047         }
1048
1049         return E_SUCCESS;
1050 }
1051
1052 bool
1053 _TableViewPresenter::IsStatusChanged(void) const
1054 {
1055         return __statusChangedFlag;
1056 }
1057
1058 int
1059 _TableViewPresenter::GetTopMargin(void) const
1060 {
1061         return __topMargin;
1062 }
1063
1064 result
1065 _TableViewPresenter::SetTopMargin(int topMargin)
1066 {
1067         __topMargin = topMargin;
1068
1069         return E_SUCCESS;
1070 }
1071
1072 int
1073 _TableViewPresenter::GetBottomMargin(void) const
1074 {
1075         return __bottomMargin;
1076 }
1077
1078 result
1079 _TableViewPresenter::SetBottomMargin(int bottomMargin)
1080 {
1081         __bottomMargin = bottomMargin;
1082
1083         return E_SUCCESS;
1084 }
1085
1086 int
1087 _TableViewPresenter::GetLeftMargin(void) const
1088 {
1089         return __leftMargin;
1090 }
1091
1092 result
1093 _TableViewPresenter::SetLeftMargin(int leftMargin)
1094 {
1095         __leftMargin = leftMargin;
1096
1097         return E_SUCCESS;
1098 }
1099
1100 void
1101 _TableViewPresenter::SetItemType(_TableViewItem* pItem, TableViewItemTag itemPosition)
1102 {
1103         TableViewStyle style = __pTableView->GetTableViewStyle();
1104
1105         int lastItem = GetItemCountAt(itemPosition.groupIndex) - 1;
1106
1107         if (style == TABLE_VIEW_STYLE_SECTION)
1108         {
1109                 if (HasSectionFooter(itemPosition.groupIndex))
1110                 {
1111                         lastItem--;
1112                 }
1113         }
1114
1115         if (itemPosition.itemIndex == -1)
1116         {
1117                 if (style == TABLE_VIEW_STYLE_SECTION)
1118                 {
1119                         pItem->SetItemType(TABLE_VIEW_ITEM_TYPE_HEADER);
1120                 }
1121                 else
1122                 {
1123                         pItem->SetItemType(TABLE_VIEW_ITEM_TYPE_TITLE);
1124                 }
1125         }
1126         else if (style == TABLE_VIEW_STYLE_SECTION || (itemPosition.groupIndex != GetGroupCount() - 1))
1127         {
1128                 if (lastItem == 0)
1129                 {
1130                         pItem->SetItemType(TABLE_VIEW_ITEM_TYPE_ONE);
1131                 }
1132                 else
1133                 {
1134                         if (itemPosition.itemIndex == 0)
1135                         {
1136                                 pItem->SetItemType(TABLE_VIEW_ITEM_TYPE_TOP);
1137                         }
1138                         else if (itemPosition.itemIndex == lastItem)
1139                         {
1140                                 pItem->SetItemType(TABLE_VIEW_ITEM_TYPE_BOTTOM);
1141                         }
1142                         else if (itemPosition.itemIndex == lastItem + 1)
1143                         {       // this case is for TABLE_VIEW_STYLE_SECTION only
1144                                 pItem->SetItemType(TABLE_VIEW_ITEM_TYPE_FOOTER);
1145                         }
1146                         else
1147                         {
1148                                 pItem->SetItemType(TABLE_VIEW_ITEM_TYPE_MIDDLE);
1149                         }
1150                 }
1151         }
1152 }
1153
1154 void
1155 _TableViewPresenter::SetItemLayout(_TableViewItem* pItem, TableViewItemTag& itemPos)
1156 {
1157         _TableViewItem* pSeriesItem = null;
1158         TableViewItemTag seriesItemPos = {-1, -1};
1159         Rectangle seriesItemBounds;
1160         Rectangle itemBounds;
1161         bool validBounds = false;
1162         bool downScroll = true;
1163
1164         if (itemPos.itemIndex != -1)
1165         {
1166                 int itemMargin = GetLeftMargin();
1167                 itemBounds.x = itemMargin;
1168                 itemBounds.width = __pItemDrawingProperty->width - itemBounds.x - itemMargin;
1169         }
1170         else
1171         {
1172                 itemBounds.x = 0;
1173                 itemBounds.width = __pItemDrawingProperty->width;
1174         }
1175
1176         //itemBounds.height = pItem->GetItemHeight();
1177         itemBounds.height = pItem->GetSize().height;
1178
1179         if (itemPos.groupIndex == 0 && itemPos.itemIndex == -1)
1180         {
1181                 itemBounds.y = GetTopMargin();
1182                 validBounds = true;
1183         }
1184         else
1185         {
1186                 if (GetPreviousItemPosition(itemPos, seriesItemPos))
1187                 {
1188                         if (__pListModel->IsLoadedItem(seriesItemPos.groupIndex, seriesItemPos.itemIndex))
1189                         {
1190                                 pSeriesItem = static_cast<_TableViewItem*>(__pListModel->LoadItem(seriesItemPos.groupIndex, seriesItemPos.itemIndex));
1191                                 if ((pSeriesItem != null) && pSeriesItem->HasParent())
1192                                 {
1193                                         if (__pTableView->IsReorderModeEnabled() && (__reorderInfo.groupIndex == seriesItemPos.groupIndex && __reorderInfo.itemIndex == seriesItemPos.itemIndex))
1194                                         {
1195                                                 seriesItemBounds = __reorderInfo.itemBounds;
1196                                         }
1197                                         else
1198                                         {
1199                                                 seriesItemBounds = pSeriesItem->GetBounds();
1200                                         }
1201
1202                                         itemBounds.y = seriesItemBounds.y + seriesItemBounds.height;
1203
1204                                         validBounds = true;
1205                                 }
1206                         }
1207                 }
1208
1209                 if ((!validBounds) && GetNextItemPosition(itemPos, seriesItemPos))
1210                 {
1211                         if (__pListModel->IsLoadedItem(seriesItemPos.groupIndex, seriesItemPos.itemIndex))
1212                         {
1213                                 pSeriesItem = static_cast<_TableViewItem*>(__pListModel->LoadItem(seriesItemPos.groupIndex, seriesItemPos.itemIndex));
1214                                 if ((pSeriesItem != null) && pSeriesItem->HasParent())
1215                                 {
1216                                         if (__pTableView->IsReorderModeEnabled() && (__reorderInfo.groupIndex == seriesItemPos.groupIndex && __reorderInfo.itemIndex == seriesItemPos.itemIndex))
1217                                         {
1218                                                 seriesItemBounds = __reorderInfo.itemBounds;
1219                                         }
1220                                         else
1221                                         {
1222                                                 seriesItemBounds = pSeriesItem->GetBounds();
1223                                         }
1224
1225                                         itemBounds.y = seriesItemBounds.y - itemBounds.height;
1226
1227                                         validBounds = true;
1228                                         downScroll = false;
1229                                 }
1230                         }
1231                 }
1232         }
1233
1234         if (validBounds)
1235         {
1236                 pItem->SetBounds(itemBounds);
1237
1238                 CheckItemHeightAndRefreshLayout(itemPos, downScroll);
1239         }
1240 }
1241
1242 _TableViewItem*
1243 _TableViewPresenter::LoadItem(int groupIndex, int itemIndex)
1244 {
1245         _TableViewItem* pItem = static_cast<_TableViewItem*>(__pListModel->LoadItem(groupIndex, itemIndex));
1246
1247         if ((pItem != null) && !pItem->HasParent())
1248         {
1249                 pItem->SetDrawingProperty(__pItemDrawingProperty);
1250
1251                 TableViewItemTag itemPosition = {groupIndex, itemIndex};
1252                 SetItemType(pItem, itemPosition);
1253                 SetItemLayout(pItem, itemPosition);
1254                 pItem->SetReorderMode(__pTableView->IsReorderModeEnabled());
1255                 pItem->AdjustChildControlMargin();
1256
1257                 __pTableView->AttachChild(*pItem);
1258
1259         }
1260         return pItem;
1261 }
1262
1263 _TableViewItem*
1264 _TableViewPresenter::FindItem(TableViewItemTag& itemTag)
1265 {
1266         if (__pListModel->IsLoadedItem(itemTag.groupIndex, itemTag.itemIndex))
1267         {
1268                 return static_cast<_TableViewItem*>(__pListModel->LoadItem(itemTag.groupIndex, itemTag.itemIndex));
1269         }
1270         return null;
1271 }
1272
1273 void
1274 _TableViewPresenter::UnloadItem(int groupIndex, int itemIndex)
1275 {
1276         __pListModel->UnloadItem(groupIndex, itemIndex);
1277 }
1278
1279 void
1280 _TableViewPresenter::UnloadItem(TableViewItemTag& itemTag)
1281 {
1282         __pListModel->UnloadItem(itemTag.groupIndex, itemTag.itemIndex);
1283
1284         return;
1285 }
1286
1287 void
1288 _TableViewPresenter::DetachItem(TableViewItemTag& itemTag)
1289 {
1290         _TableViewItem *pItem = FindItem(itemTag);
1291
1292         if (pItem != null && pItem->HasParent())
1293         {
1294                 pItem->GetParent()->DetachChild(*pItem);
1295         }
1296 }
1297
1298 void
1299 _TableViewPresenter::DetachContextItem(TableViewItemTag& itemTag)
1300 {
1301         _TableViewItem *pItem = FindItem(itemTag);
1302         if (pItem == null)
1303         {
1304                 return;
1305         }
1306
1307         _TableViewItem* contextItem = pItem->GetContextItem();
1308         if (contextItem != null && contextItem->HasParent())
1309         {
1310                 contextItem->GetParent()->DetachChild(*pItem);
1311         }
1312 }
1313
1314 void
1315 _TableViewPresenter::DetachAllItem(bool removeItem)
1316 {
1317         TableViewItemTag itemPos = {-1, -1};
1318         TableViewItemTag lastItemPos = {-1, -1};
1319
1320         __pListModel->GetFirstLoadedItemIndex(itemPos.groupIndex, itemPos.itemIndex);
1321         __pListModel->GetLastLoadedItemIndex(lastItemPos.groupIndex, lastItemPos.itemIndex);
1322
1323         if (itemPos.groupIndex == -1 && itemPos.itemIndex == -1)
1324         {
1325                 return;
1326         }
1327
1328         do
1329         {
1330                 DetachItem(itemPos);
1331
1332                 if (removeItem)
1333                 {
1334                         UnloadItem(itemPos);
1335                 }
1336
1337                 if (itemPos.itemIndex == lastItemPos.itemIndex && itemPos.groupIndex == lastItemPos.groupIndex)
1338                 {
1339                         break;
1340                 }
1341         } while (GetNextItemPosition(itemPos, itemPos));
1342 }
1343
1344 void
1345 _TableViewPresenter::SetItemDrawingProperty(void)
1346 {
1347         if (__pItemDrawingProperty != null)
1348         {
1349                 __pItemDrawingProperty->propertyChanged = false;
1350
1351                 if (__pItemDrawingProperty->itemDividerEnabled != __pTableView->IsItemDividerEnabled())
1352                 {
1353                         __pItemDrawingProperty->itemDividerEnabled = __pTableView->IsItemDividerEnabled();
1354                         __pItemDrawingProperty->propertyChanged = true;
1355                 }
1356
1357                 if (__pItemDrawingProperty->dividerColor != __pTableView->GetItemDividerColor())
1358                 {
1359                         __pItemDrawingProperty->dividerColor = __pTableView->GetItemDividerColor();
1360                         __pItemDrawingProperty->propertyChanged = true;
1361                 }
1362
1363                 if (__pItemDrawingProperty->sectionStyleEnabled != (__pTableView->GetTableViewStyle() == TABLE_VIEW_STYLE_SECTION))
1364                 {
1365                         __pItemDrawingProperty->sectionStyleEnabled = (__pTableView->GetTableViewStyle() == TABLE_VIEW_STYLE_SECTION);
1366                         __pItemDrawingProperty->propertyChanged = true;
1367                 }
1368
1369                 if (__pItemDrawingProperty->sectionStyleBgColor != __pTableView->GetSectionColor())
1370                 {
1371                         __pItemDrawingProperty->sectionStyleBgColor = __pTableView->GetSectionColor();
1372                         __pItemDrawingProperty->propertyChanged = true;
1373                 }
1374
1375                 if (__pTableView->GetTableViewStyle() != TABLE_VIEW_STYLE_SIMPLE)
1376                 {
1377                         if (__pItemDrawingProperty->groupedLookEnabled != __pTableView->IsGroupedLookEnabled())
1378                         {
1379                                 __pItemDrawingProperty->groupedLookEnabled = __pTableView->IsGroupedLookEnabled();
1380                                 __pItemDrawingProperty->propertyChanged = true;
1381                         }
1382                 }
1383
1384                 if (__pItemDrawingProperty->reorderMode != __pTableView->IsReorderModeEnabled())
1385                 {
1386                         __pItemDrawingProperty->reorderMode = __pTableView->IsReorderModeEnabled();
1387                         __pItemDrawingProperty->propertyChanged = true;
1388                 }
1389
1390                 if (__pItemDrawingProperty->leftMargin != __leftMargin)
1391                 {
1392                         __pItemDrawingProperty->leftMargin = __leftMargin;
1393                         __pItemDrawingProperty->propertyChanged = true;
1394                 }
1395
1396                 if (__pTableView->GetScrollStyle() == TABLE_VIEW_SCROLL_BAR_STYLE_FAST_SCROLL)
1397                 {
1398                         GET_SHAPE_CONFIG(TABLEVIEW::FASTSCROLL_INDEX_WIDTH, _CONTROL_ORIENTATION_PORTRAIT, __pItemDrawingProperty->scrollMargin);
1399                 }
1400                 else
1401                 {
1402                         __pItemDrawingProperty->scrollMargin = 0;
1403                 }
1404
1405                 if (__pItemDrawingProperty->width != __pTableView->GetBounds().width)
1406                 {
1407                         __pItemDrawingProperty->width = __pTableView->GetBounds().width;
1408                         __pItemDrawingProperty->propertyChanged = true;
1409                 }
1410         }
1411 }
1412
1413 void
1414 _TableViewPresenter::OnBoundsChanged(void)
1415 {
1416         _ScrollPanelPresenter::OnBoundsChanged();
1417
1418         if (__pProviderAdaptor != null && __modelInitialized)
1419         {
1420                 int listWidth = __pTableView->GetBounds().width - (GetLeftMargin() * 2);
1421
1422                 if (listWidth != __pProviderAdaptor->GetListWidth())
1423                 {
1424                         __pProviderAdaptor->SetListWidth(listWidth);
1425                         SetItemDrawingProperty();
1426
1427                         AdjustLoadedItemWidth();
1428                 }
1429
1430                 ResetSweepItem();
1431                 SetClientAreaHeight(__itemTotalHeight);
1432
1433                 AdjustLayoutItems(GetScrollPosition());
1434         }
1435 }
1436
1437 result
1438 _TableViewPresenter::Draw(void)
1439 {
1440         result r = _ScrollPanelPresenter::Draw();
1441         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1442
1443     if (__modelInitialized == false)
1444         {
1445                 SetItemDrawingProperty();
1446
1447                 PreloadItem();
1448
1449                 __modelInitialized = true;
1450
1451                 if (__reservedScrollItemIndex.groupIndex != -1 && __reservedScrollItemIndex.itemIndex != -1)
1452                 {
1453                         ScrollToItem(__reservedScrollItemIndex.groupIndex, __reservedScrollItemIndex.itemIndex, __reservedScrollItemAlignment);
1454
1455                         __reservedScrollItemIndex.groupIndex = -1;
1456                         __reservedScrollItemIndex.itemIndex = -1;
1457
1458                         return E_SUCCESS;
1459                 }
1460
1461         }
1462
1463         __firstDrawnFlag = false;
1464
1465         // Draw empty list
1466         if (IsEmpty() == true)
1467         {
1468                 return DrawEmptyTableView();
1469         }
1470
1471         return E_SUCCESS;
1472 }
1473
1474 _UiTouchEventDelivery
1475 _TableViewPresenter::OnPreviewTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
1476 {
1477         _UiTouchEventDelivery response = _ScrollPanelPresenter::OnPreviewTouchPressed(source, touchInfo);
1478
1479         __firstTouchMoved = true;
1480         __sweepOccured = false;
1481
1482         _TableViewItem* pItem = GetTableViewItemFromControl(source);
1483         if (pItem == null)
1484         {
1485                 return response;
1486         }
1487
1488         TableViewItemTag itemPos = {-1, -1};
1489
1490         pItem->GetItemIndex(itemPos.groupIndex, itemPos.itemIndex);
1491
1492         if (itemPos.groupIndex == -1 && itemPos.itemIndex == -1)
1493         {
1494                 return response;
1495         }
1496
1497         if (__pTableView->IsReorderModeEnabled())
1498         {
1499                 if (SelectReorderItem(itemPos.groupIndex, itemPos.itemIndex))
1500                 {
1501                         __reorderInfo.touchPressedPositionY = touchInfo.GetCurrentPosition().y;
1502
1503                         return _UI_TOUCH_EVENT_DELIVERY_NO;
1504                 }
1505         }
1506         else
1507         {
1508                 if (!(pItem == null
1509                                 || pItem->IsContextItem()
1510                                 || pItem->IsItemEnabled() == false
1511                                 || pItem->GetItemType() == TABLE_VIEW_ITEM_TYPE_TITLE
1512                                 || pItem->GetItemType() == TABLE_VIEW_ITEM_TYPE_HEADER
1513                                 || pItem->GetItemType() == TABLE_VIEW_ITEM_TYPE_FOOTER)
1514                                 && ((itemPos.groupIndex != __sweptItemTag.groupIndex)
1515                                                 || (itemPos.itemIndex != __sweptItemTag.itemIndex)))
1516                 {
1517                         ResetSweptItem();
1518                 }
1519         }
1520
1521         _VisualElement* pVisualElement = __pTableView->GetVisualElement();
1522         String animationName(L"EXPAND_GROUP_ANIMATION");
1523         VisualElementValueAnimation* pExpandGroupAnimation = dynamic_cast<VisualElementValueAnimation*>(pVisualElement->GetAnimationN(animationName));
1524         if (pExpandGroupAnimation != null)
1525         {
1526                 pVisualElement->RemoveAnimation(animationName);
1527
1528                 //return _UI_TOUCH_EVENT_DELIVERY_NO;
1529         }
1530
1531         animationName = L"COLLAPSE_GROUP_ANIMATION";
1532         VisualElementValueAnimation* pCollapseGroupAnimation = dynamic_cast<VisualElementValueAnimation*>(pVisualElement->GetAnimationN(animationName));
1533         if (pCollapseGroupAnimation != null)
1534         {
1535                 pVisualElement->RemoveAnimation(animationName);
1536
1537                 //return _UI_TOUCH_EVENT_DELIVERY_NO;
1538         }
1539
1540         return response;
1541 }
1542
1543 _UiTouchEventDelivery
1544 _TableViewPresenter::OnPreviewTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
1545 {
1546         if (__pTableView->IsReorderModeEnabled() && __reorderInfo.itemIndex != -1)
1547         {
1548                 if (!DragSelectedItem(touchInfo.GetCurrentPosition().y - __reorderInfo.touchPressedPositionY, true))
1549                 {
1550                         ResetReorderItem(__reorderInfo.groupIndex, __reorderInfo.itemIndex);
1551                 }
1552
1553                 return _UI_TOUCH_EVENT_DELIVERY_NO;
1554         }
1555
1556         _TableViewItem* pItem = GetTableViewItemFromControl(source);
1557
1558         _UiTouchEventDelivery response = _ScrollPanelPresenter::OnPreviewTouchMoved(source, touchInfo);
1559         if (pItem == null
1560                         || pItem->IsItemEnabled() == false
1561                         || pItem->GetItemType() == TABLE_VIEW_ITEM_TYPE_TITLE
1562                         || pItem->GetItemType() == TABLE_VIEW_ITEM_TYPE_HEADER
1563                         || pItem->GetItemType() == TABLE_VIEW_ITEM_TYPE_FOOTER)
1564         {
1565                 return response;
1566         }
1567
1568         if (__firstTouchMoved)
1569         {
1570                 Point prevTouchPosition = GetPreviousTouchPosition();
1571                 Point currTouchPosition = GetCurrentTouchPosition();
1572                 int moveDistanceX = currTouchPosition.x - prevTouchPosition.x;
1573                 int moveDistanceY = currTouchPosition.y - prevTouchPosition.y;
1574
1575                 if ((pItem->GetContextItem() != null && abs(moveDistanceX) > abs(moveDistanceY * 2)) || pItem->IsContextItem())
1576                 {
1577                         if (!pItem->IsContextItem())
1578                         {
1579                                 pItem->GetItemIndex(__sweptItemTag.groupIndex, __sweptItemTag.itemIndex);
1580                                 __sweptItemPosition = pItem->GetPosition();
1581
1582                                 pItem->AdjustContextItemBounds();
1583                         }
1584
1585                         __sweepOccured = true;
1586
1587                         SweepItem(moveDistanceX);
1588                 }
1589                 else
1590                 {
1591                         ResetSweptItem();
1592                 }
1593         }
1594
1595         __firstTouchMoved = false;
1596
1597         return response;
1598 }
1599
1600 _UiTouchEventDelivery
1601 _TableViewPresenter::OnPreviewTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
1602 {
1603         if (__pTableView->IsReorderModeEnabled() && __reorderInfo.itemIndex != -1)
1604         {
1605                 ResetReorderItem(__reorderInfo.groupIndex, __reorderInfo.itemIndex);
1606
1607                 if (__reorderInfo.blockedTouchReleaseState)
1608                 {
1609                         __reorderInfo.blockedTouchReleaseState = false;
1610
1611                         return _UI_TOUCH_EVENT_DELIVERY_NO;
1612                 }
1613         }
1614
1615         _UiTouchEventDelivery response = _ScrollPanelPresenter::OnPreviewTouchReleased(source, touchInfo);
1616
1617         _TableViewItem* pItem = GetTableViewItemFromControl(source);
1618
1619         if (pItem == null
1620                         || pItem->GetItemType() == TABLE_VIEW_ITEM_TYPE_TITLE
1621                         || pItem->GetItemType() == TABLE_VIEW_ITEM_TYPE_HEADER
1622                         || pItem->GetItemType() == TABLE_VIEW_ITEM_TYPE_FOOTER)
1623         {
1624                 return response;
1625         }
1626
1627         if (pItem->IsContextItem())
1628         {
1629                 pItem = static_cast<_TableViewItem*>(__pListModel->LoadItem(__sweptItemTag.groupIndex, __sweptItemTag.itemIndex));
1630         }
1631
1632         _TableViewItem* pContextItem = pItem->GetContextItem();
1633
1634         if (__sweepOccured)
1635         {
1636                 // Swept event fire
1637                 if (pContextItem == null && __pTableView->IsSweepEnabled())
1638                 {
1639                         Point prevPos = _ScrollPanelPresenter::GetPreviousTouchPosition();
1640
1641                         if (prevPos.x > touchInfo.GetCurrentPosition().x)
1642                         {
1643                                 pItem->FireItemSweepEvent(TABLE_VIEW_SWEEP_DIRECTION_LEFT);
1644                         }
1645                         else if (prevPos.x < touchInfo.GetCurrentPosition().x)
1646                         {
1647                                 pItem->FireItemSweepEvent(TABLE_VIEW_SWEEP_DIRECTION_RIGHT);
1648                         }
1649
1650                         ResetSweptItem();
1651                 }
1652                 else if (pContextItem != null)
1653                 {
1654                         AdjustSweptItemPosition(true);
1655                 }
1656         }
1657
1658         return response;
1659 }
1660
1661 _UiTouchEventDelivery
1662 _TableViewPresenter::OnPreviewTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
1663 {
1664         return _ScrollPanelPresenter::OnPreviewTouchCanceled(source, touchInfo);
1665 }
1666
1667 bool
1668 _TableViewPresenter::OnTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
1669 {
1670         return _ScrollPanelPresenter::OnTouchPressed(source, touchInfo);
1671 }
1672
1673 bool
1674 _TableViewPresenter::OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
1675 {
1676         if (!__sweepOccured || __pTableView->IsReorderModeEnabled())
1677         {
1678                 return _ScrollPanelPresenter::OnTouchMoved(source, touchInfo);
1679         }
1680
1681         if (__sweepOccured)
1682         {
1683                 Point prevTouchPosition = GetPreviousTouchPosition();
1684                 Point currTouchPosition = GetCurrentTouchPosition();
1685                 SweepItem(currTouchPosition.x - prevTouchPosition.x);
1686         }
1687
1688         return true;
1689 }
1690
1691 bool
1692 _TableViewPresenter::OnTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
1693 {
1694         return _ScrollPanelPresenter::OnTouchReleased(source, touchInfo);
1695 }
1696
1697 bool
1698 _TableViewPresenter::OnTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
1699 {
1700         if (__pTableView->IsReorderModeEnabled() && __reorderInfo.itemIndex != -1)
1701         {
1702                 ResetReorderItem(__reorderInfo.groupIndex, __reorderInfo.itemIndex);
1703                 return true;
1704         }
1705
1706         return _ScrollPanelPresenter::OnTouchCanceled(source, touchInfo);
1707 }
1708
1709 bool
1710 _TableViewPresenter::OnFlickGestureDetected(_TouchFlickGestureDetector& gesture)
1711 {
1712         if (__pTableView->IsReorderModeEnabled() && __reorderInfo.itemIndex != -1)
1713         {
1714                 return true;
1715         }
1716
1717         _FlickDirection flickDirection = gesture.GetDirection();
1718
1719         if (flickDirection != _FLICK_DIRECTION_RIGHT && flickDirection != _FLICK_DIRECTION_LEFT)
1720         {
1721                 return _ScrollPanelPresenter::OnFlickGestureDetected(gesture);
1722         }
1723
1724         _Control* gestureControl = gesture.GetControl();
1725
1726         if (gestureControl == null)
1727         {
1728                 return _ScrollPanelPresenter::OnFlickGestureDetected(gesture);
1729         }
1730
1731         _TableViewItem* pItem = GetTableViewItemFromControl(*gestureControl);
1732
1733         if (pItem == null)
1734         {
1735                 return _ScrollPanelPresenter::OnFlickGestureDetected(gesture);
1736         }
1737
1738         if (flickDirection == _FLICK_DIRECTION_RIGHT)
1739         {
1740                 // event fire
1741                 if (pItem->GetContextItem() == null && __pTableView->IsSweepEnabled())
1742                 {
1743                         pItem->FireItemSweepEvent(TABLE_VIEW_SWEEP_DIRECTION_RIGHT);
1744                 }
1745                 else
1746                 {
1747                         if (pItem->GetContextItem() != null)
1748                         {
1749                                 AdjustSweptItemPosition();
1750                         }
1751                 }
1752         }
1753         else if (flickDirection == _FLICK_DIRECTION_LEFT)
1754         {
1755                 // event fire
1756                 if (pItem->GetContextItem() == null && __pTableView->IsSweepEnabled())
1757                 {
1758                         pItem->FireItemSweepEvent(TABLE_VIEW_SWEEP_DIRECTION_LEFT);
1759                 }
1760                 else
1761                 {
1762                         if (pItem->GetContextItem() != null)
1763                         {
1764                                 AdjustSweptItemPosition();
1765                         }
1766                 }
1767         }
1768
1769         return true;
1770 }
1771
1772 bool
1773 _TableViewPresenter::OnFlickGestureCanceled(_TouchFlickGestureDetector& gesture)
1774 {
1775         return _ScrollPanelPresenter::OnFlickGestureCanceled(gesture);
1776 }
1777
1778 bool
1779 _TableViewPresenter::OnPreviewFlickGestureDetected(_TouchFlickGestureDetector& gesture)
1780 {
1781         if (__pTableView->IsReorderModeEnabled() && __reorderInfo.itemIndex != -1)
1782         {
1783                 return true;
1784         }
1785
1786         _FlickDirection flickDirection = gesture.GetDirection();
1787         if (flickDirection != _FLICK_DIRECTION_RIGHT && flickDirection != _FLICK_DIRECTION_LEFT)
1788         {
1789                 return _ScrollPanelPresenter::OnFlickGestureDetected(gesture);
1790         }
1791
1792         return true;
1793 }
1794
1795 void
1796 _TableViewPresenter::OnTimerExpired(Tizen::Base::Runtime::Timer& timer)
1797 {
1798         _ScrollPanelPresenter::OnTimerExpired(timer);
1799
1800         if (&timer == __pReorderScrollTimer)
1801         {
1802                 int distance = 0;
1803
1804                 if (__reorderInfo.isScrollDirectionUp)
1805                 {
1806                         distance = -REORDER_SCROLL_ANIMATION_DISTANCE;
1807                 }
1808                 else
1809                 {
1810                         distance = REORDER_SCROLL_ANIMATION_DISTANCE;
1811                 }
1812
1813                 DragSelectedItem(distance, false);
1814
1815                 distance = ScrollTo(distance + GetScrollPosition());
1816
1817                 StartReorderScrollTimer();
1818         }
1819         else if (&timer == __pFastScrollTimer)
1820         {
1821                 __isFastScrollTimerEnabled = false;
1822
1823                 _FastScroll* pFastScroll = __pTableView->GetFastScrollBar();
1824
1825                 if (pFastScroll != null && !_ScrollPanelPresenter::IsScrollAnimationRunning())
1826                 {
1827                         pFastScroll->SetScrollVisibility(false);
1828                 }
1829         }
1830 }
1831
1832 result
1833 _TableViewPresenter::StartFastScrollTimer(void)
1834 {
1835         result r = E_SUCCESS;
1836
1837         SysTryReturn(NID_UI_CTRL, __pFastScrollTimer != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Timer is not created.");
1838
1839         r = __pFastScrollTimer->Start(FAST_SCROLL_FADE_OUT_DURATION);
1840         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1841
1842         __isFastScrollTimerEnabled = true;
1843
1844         return r;
1845 }
1846
1847 void
1848 _TableViewPresenter::StopFastScrollTimer(void)
1849 {
1850         result r = E_SUCCESS;
1851
1852         SysTryReturnVoidResult(NID_UI_CTRL, __pFastScrollTimer != null, E_INVALID_STATE, "[E_INVALID_STATE] Timer is invalid.");
1853
1854         r = __pFastScrollTimer->Cancel();
1855         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1856
1857         __isFastScrollTimerEnabled = false;
1858
1859         return;
1860 }
1861
1862 bool
1863 _TableViewPresenter::IsEmpty(void) const
1864 {
1865         if (GetItemCount() <= 0)
1866         {
1867                 return true;
1868         }
1869
1870         return false;
1871 }
1872
1873 result
1874 _TableViewPresenter::DrawEmptyTableView(void)
1875 {
1876         return E_SUCCESS;
1877 }
1878
1879 bool
1880 _TableViewPresenter::GetFirstItem(TableViewItemTag& firstItem) const
1881 {
1882         if (IsEmpty())
1883         {
1884                 firstItem.groupIndex = -1;
1885                 firstItem.itemIndex = -1;
1886         }
1887         else
1888         {
1889                 firstItem.groupIndex = 0;
1890                 firstItem.itemIndex = -1;
1891         }
1892
1893         return true;
1894 }
1895
1896 result
1897 _TableViewPresenter::GetTopDrawnItem(TableViewItemTag& itemPos) const
1898 {
1899         _TableViewItem* pItem = null;
1900         TableViewItemTag lastItemPos = {-1, -1};
1901         int scrollPosition = 0;
1902
1903         scrollPosition = GetScrollPosition();
1904
1905         __pListModel->GetFirstLoadedItemIndex(itemPos.groupIndex, itemPos.itemIndex);
1906         __pListModel->GetLastLoadedItemIndex(lastItemPos.groupIndex, lastItemPos.itemIndex);
1907
1908         do
1909         {
1910                 pItem = static_cast <_TableViewItem*>(__pListModel->LoadItem(itemPos.groupIndex, itemPos.itemIndex));
1911                 if (pItem == null)
1912                 {
1913                         break;
1914                 }
1915
1916                 Rectangle itemBounds = pItem->GetBounds();
1917
1918                 if (scrollPosition < (itemBounds.y + itemBounds.height))
1919                 {
1920                         return E_SUCCESS;
1921                 }
1922
1923                 if ((itemPos.itemIndex == lastItemPos.itemIndex) && (itemPos.groupIndex == lastItemPos.groupIndex))
1924                 {
1925                         break;
1926                 }
1927
1928         } while (GetNextItemPosition(itemPos, itemPos) == true);
1929
1930
1931         itemPos.itemIndex = -1;
1932         itemPos.groupIndex = -1;
1933
1934         return E_OUT_OF_RANGE;
1935 }
1936
1937 result
1938 _TableViewPresenter::GetBottomDrawnItem(TableViewItemTag& itemPos) const
1939 {
1940         _TableViewItem* pItem = null;
1941         TableViewItemTag lastItemPos = {-1, -1};
1942
1943         if (IsEmpty())
1944         {
1945                 itemPos.itemIndex = -1;
1946                 itemPos.groupIndex = -1;
1947
1948                 return E_INVALID_STATE;
1949         }
1950
1951         int scrollPosition = GetScrollPosition() + __pTableView->GetBounds().height;
1952
1953         __pListModel->GetFirstLoadedItemIndex(itemPos.groupIndex, itemPos.itemIndex);
1954         __pListModel->GetLastLoadedItemIndex(lastItemPos.groupIndex, lastItemPos.itemIndex);
1955
1956         do
1957         {
1958                 static bool onProcessingByProvider = true;
1959                 pItem = static_cast <_TableViewItem*>(__pListModel->LoadItem(itemPos.groupIndex, itemPos.itemIndex));
1960                 onProcessingByProvider = false;
1961                 if (pItem == null)
1962                 {
1963                         break;
1964                 }
1965
1966                 Rectangle itemBounds = pItem->GetBounds();
1967
1968                 if (itemBounds.y <= scrollPosition && scrollPosition <= (itemBounds.y + itemBounds.height))
1969                 {
1970                         break;
1971                 }
1972
1973                 if ((itemPos.itemIndex == lastItemPos.itemIndex) && (itemPos.groupIndex == lastItemPos.groupIndex))
1974                 {
1975                         break;
1976                 }
1977
1978         } while (GetNextItemPosition(itemPos, itemPos) == true);
1979
1980         return E_SUCCESS;
1981 }
1982
1983 bool
1984 _TableViewPresenter::GetPreviousItemPosition(const TableViewItemTag& currentItemPos, TableViewItemTag& prevItem) const
1985 {
1986         if (IsEmpty())
1987         {
1988                 return false;
1989         }
1990
1991         // check validation of group index
1992         if ((currentItemPos.groupIndex < 0) || (currentItemPos.groupIndex >= __pListModel->GetAllGroupCount()))
1993         {
1994                 return false;
1995         }
1996
1997         // if the current item is the first item
1998         if (currentItemPos.groupIndex == 0 && currentItemPos.itemIndex == -1)
1999         {
2000                 return false;
2001         }
2002
2003         if (currentItemPos.itemIndex == -1)
2004         {
2005                 if (__pListModel->IsGroupExpanded(currentItemPos.groupIndex - 1) == false)
2006                 {
2007                         prevItem.groupIndex = currentItemPos.groupIndex - 1;
2008                         prevItem.itemIndex = -1;
2009
2010                         return true;
2011                 }
2012         }
2013
2014         if (__pListModel->IsGroupExpanded(currentItemPos.groupIndex) == false)
2015         {
2016                 if (currentItemPos.groupIndex == 0 && currentItemPos.itemIndex == -1)
2017                 {
2018                         return false;
2019                 }
2020
2021                 prevItem.groupIndex = currentItemPos.groupIndex - 1;
2022                 prevItem.itemIndex = __pListModel->GetItemCountInGroup(prevItem.groupIndex) - 1;
2023
2024                 return true;
2025         }
2026
2027         if (currentItemPos.itemIndex == -1) // group title item
2028         {
2029                 prevItem.groupIndex = currentItemPos.groupIndex - 1;
2030                 prevItem.itemIndex = __pListModel->GetItemCountInGroup(prevItem.groupIndex) - 1;
2031         }
2032         else
2033         {
2034                 prevItem.groupIndex = currentItemPos.groupIndex;
2035                 prevItem.itemIndex = currentItemPos.itemIndex - 1;
2036         }
2037
2038         return true;
2039 }
2040
2041 bool
2042 _TableViewPresenter::GetNextItemPosition(const TableViewItemTag& currentItem, TableViewItemTag& nextItem) const
2043 {
2044         if (IsEmpty())
2045         {
2046                 return false;
2047         }
2048
2049         int lastGroup = __pListModel->GetAllGroupCount() - 1;
2050         int lastItemInCurrentGroup = __pListModel->GetItemCountInGroup(currentItem.groupIndex) - 1;
2051         int lastItem = __pListModel->GetItemCountInGroup(lastGroup) - 1;
2052
2053         // check validation of group index
2054         if ((currentItem.groupIndex < 0) || (currentItem.groupIndex > lastGroup))
2055         {
2056                 return false;
2057         }
2058
2059         // if the current item is the last item.
2060         if ((currentItem.groupIndex == lastGroup) && (currentItem.itemIndex == lastItem))
2061         {
2062                 return false;
2063         }
2064
2065         if (__pListModel->IsGroupExpanded(currentItem.groupIndex) == false)
2066         {
2067                 if (currentItem.groupIndex == lastGroup)
2068                 {
2069                         return false;
2070                 }
2071
2072                 nextItem.groupIndex = currentItem.groupIndex + 1;
2073                 nextItem.itemIndex = -1;
2074
2075                 return true;
2076         }
2077
2078         if (lastItemInCurrentGroup == currentItem.itemIndex)
2079         {
2080                 nextItem.groupIndex = currentItem.groupIndex + 1;
2081                 nextItem.itemIndex = -1;
2082         }
2083         else
2084         {
2085                 nextItem.groupIndex = currentItem.groupIndex;
2086                 nextItem.itemIndex = currentItem.itemIndex + 1;
2087         }
2088
2089         return true;
2090 }
2091
2092 int
2093 _TableViewPresenter::GetHeightOfAllItems(void) const
2094 {
2095         int groupCount = GetGroupCount();
2096         int totalHeight = 0;
2097
2098         for (int i = 0; i < groupCount; i++)
2099         {
2100                 TableViewItemTag itemTag = {i, -1};
2101
2102                 totalHeight += GetItemHeight(itemTag);
2103
2104                 if (!IsGroupExpanded(i))
2105                 {
2106                         continue;
2107                 }
2108
2109                 int itemCount = GetItemCountAt(i);
2110
2111                 for (int j = 0; j < itemCount; j++)
2112                 {
2113                         itemTag.itemIndex = j;
2114
2115                         totalHeight += GetItemHeight(itemTag);
2116                 }
2117         }
2118
2119         return totalHeight;
2120 }
2121
2122 void
2123 _TableViewPresenter::SetTableViewItemProviderAdaptor(_TableViewItemProviderAdaptor* pProviderAdaptor)
2124 {
2125         __pListModel->RegisterItemProviderAdaptor(pProviderAdaptor);
2126
2127         __pProviderAdaptor = pProviderAdaptor;
2128 }
2129
2130 _TableViewItemProviderAdaptor*
2131 _TableViewPresenter::GetTableViewItemProviderAdaptor(void) const
2132 {
2133         return __pProviderAdaptor;
2134 }
2135
2136 result
2137 _TableViewPresenter::ExpandGroup(int groupIndex, bool withAnimation)
2138 {
2139         if ((groupIndex < 0) || (groupIndex >= GetGroupCount()))
2140         {
2141                 return E_OUT_OF_RANGE;
2142         }
2143
2144         if (__modelInitialized == false)
2145         {
2146                 return E_INVALID_STATE;
2147         }
2148
2149         if (IsGroupExpanded(groupIndex) == true)
2150         {
2151                 return E_SUCCESS;
2152         }
2153
2154         TableViewItemTag topTag;
2155         GetTopDrawnItem(topTag);
2156
2157         TableViewItemTag bottomTag;
2158         GetBottomDrawnItem(bottomTag);
2159
2160         int screenPosition = GetScrollPosition();
2161
2162         __pListModel->SetGroupExpandState(groupIndex, true);
2163
2164         int groupTotalHeight = 0;
2165         int itemCount = GetItemCountAt(groupIndex);
2166         _IListItemCommon* pItem = null;
2167         for (int i = 0; i < itemCount; i++)
2168         {
2169                 pItem = __pListModel->GetItemFromTemporaryBuffer(groupIndex, i);
2170                 groupTotalHeight += pItem->GetItemHeight();
2171         }
2172
2173         AdjustClientAreaBounds(false, groupTotalHeight);
2174
2175         if (groupIndex < topTag.groupIndex || groupIndex > bottomTag.groupIndex)
2176         {
2177                 int firstLoadedGroupIndex = -1;
2178                 int firstLoadedItemIndex = -1;
2179                 __pListModel->GetFirstLoadedItemIndex(firstLoadedGroupIndex, firstLoadedItemIndex);
2180
2181                 TableViewItemTag firstLoadedItemTag = {firstLoadedGroupIndex, firstLoadedItemIndex};
2182                 _TableViewItem* pItem = FindItem(firstLoadedItemTag);
2183                 if (pItem != null)
2184                 {
2185                         int itemPositionY = CalculateItemPositionY(firstLoadedItemTag.groupIndex, firstLoadedItemTag.itemIndex);
2186
2187                         Rectangle itemBounds = pItem->GetBounds();
2188                         itemBounds.y = itemPositionY;
2189                         pItem->SetBounds(itemBounds);
2190
2191                         AttachNextItemsToBottom(firstLoadedItemTag);
2192                         if (groupIndex < topTag.groupIndex)
2193                         {
2194                                 _ScrollPanelPresenter::ScrollTo(screenPosition + groupTotalHeight);
2195                         }
2196                 }
2197
2198                 return E_SUCCESS;
2199         }
2200
2201         TableViewItemTag itemTag;
2202         itemTag.groupIndex = groupIndex;
2203         itemTag.itemIndex = -1;
2204
2205         if (withAnimation)
2206         {
2207                 _VisualElement* pVisualElement = __pTableView->GetVisualElement();
2208                 String animationName(L"EXPAND_GROUP_ANIMATION");
2209                 VisualElementValueAnimation* pExpandGroupAnimation = dynamic_cast<VisualElementValueAnimation*>(pVisualElement->GetAnimationN(animationName));
2210
2211                 if (pExpandGroupAnimation != null)
2212                 {
2213                         pVisualElement->RemoveAnimation(animationName);
2214                 }
2215
2216                 pExpandGroupAnimation = new (std::nothrow) VisualElementValueAnimation();
2217                 SysTryReturn(NID_UI_CTRL, pExpandGroupAnimation != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
2218
2219                 _TableViewItem *pItem = FindItem(itemTag);
2220                 if (pItem == null)
2221                 {
2222                         delete pExpandGroupAnimation;
2223
2224                         return E_SUCCESS;
2225                 }
2226                 Rectangle itemBounds = pItem->GetBounds();
2227                 int startPosition = itemBounds.y + itemBounds.height;
2228
2229                 int endPosition = startPosition + groupTotalHeight;
2230
2231                 if (endPosition > screenPosition + __pTableView->GetBounds().height)
2232                 {
2233                         endPosition = screenPosition + __pTableView->GetBounds().height;
2234                 }
2235
2236                 pExpandGroupAnimation->SetStartValue(Variant(startPosition));
2237                 pExpandGroupAnimation->SetEndValue(Variant(endPosition));
2238                 pExpandGroupAnimation->SetDuration(EXPAND_GROUP_ANIMATION_DURATION);
2239                 pExpandGroupAnimation->SetTimingFunction(VisualElementAnimation::GetTimingFunctionByName(L"EaseInOut"));
2240                 pExpandGroupAnimation->SetVisualElementAnimationStatusEventListener(this);
2241                 pExpandGroupAnimation->SetVisualElementAnimationTickEventListener(this);
2242                 __expandableItemTag.groupIndex = groupIndex;
2243                 __expandableItemTag.itemIndex = -1;
2244                 pVisualElement->AddAnimation(animationName, *pExpandGroupAnimation);
2245
2246                 delete pExpandGroupAnimation;
2247         }
2248         else
2249         {
2250                 LoadItemsToBeVisible(itemTag);
2251                 AttachNextItemsToBottom(itemTag);
2252                 SetLoadedItemsVisibleInGroup(groupIndex, true);
2253
2254                 int currentGroupIndex = -1;
2255                 int currentItemIndex = -1;
2256                 GetBottomDrawnItemIndex(currentGroupIndex, currentItemIndex);
2257
2258                 int lastLoadedGroupIndex = -1;
2259                 int lastLoadedItemIndex = -1;
2260                 __pListModel->GetLastLoadedItemIndex(lastLoadedGroupIndex, lastLoadedItemIndex);
2261
2262                 for (int j = currentGroupIndex; j <= lastLoadedGroupIndex; j++)
2263                 {
2264                         int itemCount = GetItemCountAt(j);
2265
2266                         for (int i = -1; i < itemCount; i++)
2267                         {
2268                                 if (i <= currentItemIndex && j == currentGroupIndex)
2269                                 {
2270                                         continue;
2271                                 }
2272
2273                                 UnloadItem(j, i);
2274                         }
2275                 }
2276         }
2277
2278         return E_SUCCESS;
2279 }
2280
2281 result
2282 _TableViewPresenter::CollapseGroup(int groupIndex, bool withAnimation)
2283 {
2284         if ((groupIndex < 0) || (groupIndex >= GetGroupCount()))
2285         {
2286                 return E_OUT_OF_RANGE;
2287         }
2288
2289         if (__modelInitialized == false)
2290         {
2291                 return E_INVALID_STATE;
2292         }
2293
2294         if (IsGroupExpanded(groupIndex) == false)
2295         {
2296                 return E_SUCCESS;
2297         }
2298
2299         TableViewItemTag itemTag;
2300         GetTopDrawnItem(itemTag);
2301
2302         TableViewItemTag bottomTag;
2303         GetBottomDrawnItem(bottomTag);
2304         int screenPosition = GetScrollPosition();
2305
2306         __pListModel->SetGroupExpandState(groupIndex, false);
2307
2308         ResetSweepItem();
2309
2310         int groupTotalHeight = 0;
2311         int itemCount = GetItemCountAt(groupIndex);
2312         _IListItemCommon* pItem = null;
2313         for (int i = 0; i < itemCount; i++)
2314         {
2315                 pItem = __pListModel->GetItemFromTemporaryBuffer(groupIndex, i);
2316                 groupTotalHeight += pItem->GetItemHeight();
2317         }
2318
2319         if (groupIndex < itemTag.groupIndex || groupIndex > bottomTag.groupIndex)
2320         {
2321                 TableViewItemTag firstLoadedItemTag;
2322                 __pListModel->GetFirstLoadedItemIndex(firstLoadedItemTag.groupIndex, firstLoadedItemTag.itemIndex);
2323
2324                 if (firstLoadedItemTag.groupIndex == groupIndex)
2325                 {
2326                         SetLoadedItemsVisibleInGroup(groupIndex, false);
2327                         firstLoadedItemTag.groupIndex = groupIndex + 1;
2328                         firstLoadedItemTag.itemIndex = -1;
2329                 }
2330
2331                 _TableViewItem* pItem = FindItem(firstLoadedItemTag);
2332                 if (pItem != null)
2333                 {
2334                         int itemPositionY = CalculateItemPositionY(firstLoadedItemTag.groupIndex, firstLoadedItemTag.itemIndex);
2335
2336                         Rectangle itemBounds = pItem->GetBounds();
2337                         itemBounds.y = itemPositionY;
2338                         pItem->SetBounds(itemBounds);
2339
2340                         AttachNextItemsToBottom(firstLoadedItemTag);
2341                         if (groupIndex < itemTag.groupIndex)
2342                         {
2343                                 _ScrollPanelPresenter::ScrollTo(screenPosition - groupTotalHeight);
2344                         }
2345                 }
2346
2347                 for (int i = 0; i < itemCount; i++)
2348                 {
2349                         UnloadItem(groupIndex, i);
2350                 }
2351                 AdjustClientAreaBounds(false, -groupTotalHeight);
2352
2353                 return E_SUCCESS;
2354         }
2355
2356         if (itemTag.groupIndex < groupIndex)
2357         {
2358                 itemTag.groupIndex = groupIndex;
2359                 itemTag.itemIndex = -1;
2360         }
2361
2362         if(__firstDrawnFlag)
2363         {
2364                 withAnimation = false;
2365         }
2366
2367         if (withAnimation)
2368         {
2369                 _TableViewItem *pItem = FindItem(itemTag);
2370                 if (pItem == null)
2371                 {
2372                         return E_SUCCESS;
2373                 }
2374
2375                 _VisualElement* pVisualElement = __pTableView->GetVisualElement();
2376                 String animationName(L"COLLAPSE_GROUP_ANIMATION");
2377                 VisualElementValueAnimation* pCollapseGroupAnimation = dynamic_cast<VisualElementValueAnimation*>(pVisualElement->GetAnimationN(animationName));
2378
2379                 if (pCollapseGroupAnimation != null)
2380                 {
2381                         pVisualElement->RemoveAnimation(animationName);
2382                 }
2383
2384                 pCollapseGroupAnimation = new (std::nothrow) VisualElementValueAnimation();
2385                 SysTryReturn(NID_UI_CTRL, pCollapseGroupAnimation != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
2386
2387                 Rectangle itemBounds = pItem->GetBounds();
2388                 int startPosition = 0;
2389                 if (itemTag.itemIndex == -1)
2390                 {
2391                         startPosition = itemBounds.y + itemBounds.height;
2392                 }
2393                 else
2394                 {
2395                         startPosition = GetScrollPosition();
2396                 }
2397
2398                 if (bottomTag.groupIndex > groupIndex)
2399                 {
2400                         bottomTag.groupIndex = groupIndex+1;
2401                         bottomTag.itemIndex = -1;
2402                 }
2403
2404                 pItem = FindItem(bottomTag);
2405                 if (pItem == null)
2406                 {
2407                         delete pCollapseGroupAnimation;
2408
2409                         return E_SUCCESS;
2410                 }
2411
2412                 itemBounds = pItem->GetBounds();
2413                 int endPosition = itemBounds.y;
2414                 if (bottomTag.groupIndex != groupIndex +1)
2415                 {
2416                         endPosition += itemBounds.height;
2417                 }
2418                 if (endPosition > screenPosition + __pTableView->GetBounds().height)
2419                 {
2420                         endPosition = screenPosition + __pTableView->GetBounds().height;
2421                 }
2422
2423                 pCollapseGroupAnimation->SetStartValue(Variant(endPosition));
2424                 pCollapseGroupAnimation->SetEndValue(Variant(startPosition));
2425                 pCollapseGroupAnimation->SetDuration(COLLAPSE_GROUP_ANIMATION_DURATION);
2426                 pCollapseGroupAnimation->SetTimingFunction(VisualElementAnimation::GetTimingFunctionByName(L"EaseInOut"));
2427                 pCollapseGroupAnimation->SetVisualElementAnimationStatusEventListener(this);
2428                 pCollapseGroupAnimation->SetVisualElementAnimationTickEventListener(this);
2429                 __expandableItemTag.groupIndex = itemTag.groupIndex;
2430                 __expandableItemTag.itemIndex = itemTag.itemIndex;
2431                 pVisualElement->AddAnimation(animationName, *pCollapseGroupAnimation);
2432
2433                 delete pCollapseGroupAnimation;
2434         }
2435         else
2436         {
2437                 TableViewItemTag nextTag = {groupIndex + 1, -1};
2438
2439                 if (itemTag.itemIndex != -1)
2440                 {
2441                         int itemPositionY = CalculateItemPositionY(nextTag.groupIndex, nextTag.itemIndex);
2442                         _TableViewItem* pNextItem = LoadItem(nextTag.groupIndex, nextTag.itemIndex);
2443
2444                         Rectangle itemBounds = pNextItem->GetBounds();
2445                         itemBounds.y = itemPositionY;
2446                         pNextItem->SetBounds(itemBounds);
2447
2448                         AttachNextItemsToBottom(nextTag);
2449
2450                         _ScrollPanelPresenter::ScrollTo(itemPositionY);
2451                 }
2452                 else
2453                 {
2454                         AttachNextItemsToBottom(itemTag);
2455                 }
2456
2457                 LoadItemsToBeVisible(nextTag);
2458                 SetLoadedItemsVisibleInGroup(groupIndex, false);
2459         }
2460
2461         AdjustClientAreaBounds(false, -groupTotalHeight);
2462
2463         return E_SUCCESS;
2464 }
2465
2466 bool
2467 _TableViewPresenter::IsGroupExpanded(int groupIndex) const
2468 {
2469         return __pListModel->IsGroupExpanded(groupIndex);
2470 }
2471
2472 int
2473 _TableViewPresenter::LoadAllItemsInGroup(int groupIndex, bool downward)
2474 {
2475         int itemCountInGroup = __pListModel->GetItemCountInGroup(groupIndex);
2476         _TableViewItem* pItem = null;
2477
2478         if (downward)
2479         {
2480                 for (int i = 0; i < itemCountInGroup; i++)
2481                 {
2482                         pItem = LoadItem(groupIndex, i);
2483
2484                         if (pItem == null)
2485                         {
2486                                 SysLogException(NID_UI_CTRL, E_SYSTEM, "[E_SYSTEM] Unable to load item.");
2487                         }
2488                 }
2489         }
2490         else
2491         {
2492                 for (int i = itemCountInGroup-1; i >= 0; i--)
2493                 {
2494                         pItem = LoadItem(groupIndex, i);
2495
2496                         if (pItem == null)
2497                         {
2498                                 SysLogException(NID_UI_CTRL, E_SYSTEM, "[E_SYSTEM] Unable to load item.");
2499                         }
2500                 }
2501         }
2502
2503         return itemCountInGroup;
2504 }
2505
2506 void
2507 _TableViewPresenter::SetLoadedItemsVisibleInGroup(int groupIndex, bool visible)
2508 {
2509         int itemCountInGroup = __pListModel->GetItemCountInGroup(groupIndex);
2510         _TableViewItem* pItem = null;
2511         TableViewItemTag itemTag;
2512         itemTag.groupIndex = groupIndex;
2513
2514         int firstLoadedGroupIndex = -1;
2515         int firstLoadedItemIndex = -1;
2516         __pListModel->GetFirstLoadedItemIndex(firstLoadedGroupIndex, firstLoadedItemIndex);
2517
2518         if (firstLoadedGroupIndex > groupIndex)
2519         {
2520                 return;
2521         }
2522
2523         int startIndex = 0;
2524         if (groupIndex == firstLoadedGroupIndex && firstLoadedItemIndex > 0)
2525         {
2526                 startIndex = firstLoadedItemIndex;
2527         }
2528
2529         for (int i = startIndex; i < itemCountInGroup; i++)
2530         {
2531                 itemTag.itemIndex = i;
2532                 pItem = FindItem(itemTag);
2533                 if (pItem == null)
2534                 {
2535                         continue;
2536                 }
2537
2538                 pItem->SetVisibleState(visible);
2539         }
2540 }
2541
2542 TableViewItemTag
2543 _TableViewPresenter::LoadItemsToBeVisible(const TableViewItemTag& from)
2544 {
2545         TableViewItemTag bottomTag = from;
2546         TableViewItemTag current;
2547         TableViewItemTag next;
2548
2549         _TableViewItem *pItem = LoadItem(from.groupIndex, from.itemIndex);
2550
2551         if (pItem == null)
2552         {
2553                 return from;
2554         }
2555
2556         Rectangle itemBounds = pItem->GetBounds();
2557         int viewHeight = __pTableView->GetBounds().height;
2558         int scrollPosition = GetScrollPosition();
2559         int itemPosition = itemBounds.y + itemBounds.height - scrollPosition;
2560
2561         while (viewHeight >= itemPosition)
2562         {
2563                 current.groupIndex = bottomTag.groupIndex;
2564                 current.itemIndex = bottomTag.itemIndex;
2565                 if (!GetNextItemPosition(current, next))
2566                 {
2567                         break;
2568                 }
2569
2570                 pItem = LoadItem(next.groupIndex, next.itemIndex);
2571                 bottomTag.groupIndex = next.groupIndex;
2572                 bottomTag.itemIndex = next.itemIndex;
2573                 itemPosition += pItem->GetBounds().height;
2574         }
2575
2576         return bottomTag;
2577 }
2578
2579 void
2580 _TableViewPresenter::AttachNextItemsToBottom(const TableViewItemTag& anchor)
2581 {
2582         TableViewItemTag itemTag = anchor;
2583         TableViewItemTag current;
2584         TableViewItemTag next;
2585
2586         _TableViewItem *pItem = FindItem(itemTag);
2587         if (pItem == null)
2588         {
2589                 return;
2590         }
2591
2592         Rectangle itemBounds = pItem->GetBounds();
2593         int itemPosition = itemBounds.y + itemBounds.height;
2594
2595         current.groupIndex = itemTag.groupIndex;
2596         current.itemIndex = itemTag.itemIndex;
2597         while (GetNextItemPosition(current, next))
2598         {
2599                 pItem = FindItem(next);
2600                 if (pItem == null)
2601                 {
2602                         current = next;
2603                         continue;
2604                 }
2605
2606                 itemBounds = pItem->GetBounds();
2607                 itemBounds.y = itemPosition;
2608                 pItem->SetBounds(itemBounds);
2609                 itemPosition += itemBounds.height;
2610                 current = next;
2611         }
2612 }
2613
2614 bool
2615 _TableViewPresenter::IsAnyItemInGroupLoaded(int groupIndex) const
2616 {
2617         int startGroupIndex = 0;
2618         int endGroupIndex = 0;
2619         int index = 0;
2620
2621         __pListModel->GetFirstLoadedItemIndex(startGroupIndex, index);
2622         __pListModel->GetLastLoadedItemIndex(endGroupIndex, index);
2623
2624         return groupIndex >= startGroupIndex && groupIndex <= endGroupIndex;
2625 }
2626
2627 void
2628 _TableViewPresenter::ScrollToHideNonClientArea(TableViewItemTag& bottomTag)
2629 {
2630         _TableViewItem* pItem = FindItem(bottomTag);
2631         if (pItem == null)
2632         {
2633                 return ;
2634         }
2635
2636         Rectangle itemBounds = pItem->GetBounds();
2637         int viewHeight = __pTableView->GetBounds().height;
2638         int scrollPosition = GetScrollPosition();
2639         int itemBottom = itemBounds.y + itemBounds.height - scrollPosition;
2640
2641         if (itemBottom < viewHeight)
2642         {
2643                 scrollPosition -= viewHeight - itemBottom;
2644                 if (scrollPosition < 0)
2645                 {
2646                         scrollPosition = 0;
2647                 }
2648
2649                 SetScrollPosition(scrollPosition, false);
2650         }
2651 }
2652
2653 void
2654 _TableViewPresenter::AdjustClientAreaBounds(bool reset, int dist)
2655 {
2656         int clientHeight = 0;
2657
2658         if (reset)
2659         {
2660                 __itemTotalHeight = GetHeightOfAllItems();
2661                 clientHeight = __itemTotalHeight;
2662         }
2663         else
2664         {
2665                 __itemTotalHeight = __itemTotalHeight + dist;
2666                 clientHeight = __itemTotalHeight;
2667         }
2668
2669         SetClientAreaHeight(clientHeight);
2670 }
2671
2672 void
2673 _TableViewPresenter::SetClientAreaHeight(int height)
2674 {
2675         Rectangle screenBounds = __pTableView->GetBounds();
2676         Rectangle clientBounds = screenBounds;
2677
2678         clientBounds.height = height;
2679
2680         if (clientBounds.height < screenBounds.height)
2681         {
2682             clientBounds.height = screenBounds.height;
2683         }
2684
2685         SetScrollAreaBounds(clientBounds);
2686
2687         _Scroll* pScroll = __pTableView->GetScrollBar();
2688         if (pScroll != null)
2689         {
2690                 pScroll->SetScrollRange(__pTableView->GetBounds().height, clientBounds.height);
2691         }
2692 }
2693
2694 void
2695 _TableViewPresenter::UnloadInvisibleItems(void)
2696 {
2697         int scrollPosition = GetScrollPosition();
2698         TableViewItemTag itemTag;
2699         __pListModel->GetFirstLoadedItemIndex(itemTag.groupIndex, itemTag.itemIndex);
2700
2701         _TableViewItem* pItem = null;
2702         Rectangle bounds;
2703
2704         while ((pItem = FindItem(itemTag)) != null)
2705         {
2706                 if (itemTag.itemIndex != -1)
2707                 {
2708                         bounds = pItem->GetBounds();
2709                         if (bounds.y + bounds.height < scrollPosition)
2710                         {
2711                                 UnloadItem(itemTag);
2712                         }
2713                         else
2714                         {
2715                                 break;
2716                         }
2717                 }
2718                 __pListModel->GetFirstLoadedItemIndex(itemTag.groupIndex, itemTag.itemIndex);
2719         }
2720
2721         __pListModel->GetLastLoadedItemIndex(itemTag.groupIndex, itemTag.itemIndex);
2722         scrollPosition += __pTableView->GetBounds().height;
2723
2724         while ((pItem = FindItem(itemTag)) != null)
2725         {
2726                 if (itemTag.itemIndex != -1)
2727                 {
2728                         bounds = pItem->GetBounds();
2729                         if (bounds.y > scrollPosition)
2730                         {
2731                                 UnloadItem(itemTag);
2732                         }
2733                         else
2734                         {
2735                                 break;
2736                         }
2737                 }
2738                 __pListModel->GetLastLoadedItemIndex(itemTag.groupIndex, itemTag.itemIndex);
2739         }
2740
2741 }
2742
2743 int
2744 _TableViewPresenter::ScrollToInternal(int newPosition)
2745 {
2746         if (!IsScrollEnabled())
2747         {
2748                 return 0;
2749         }
2750
2751         int previousScrollPosition = _ScrollPanelPresenter::GetScrollPosition();
2752         int scrollAreaHeight = _ScrollPanelPresenter::GetScrollAreaBounds().height;
2753         int currentScrollPosition = (newPosition < 0) ? 0 : (newPosition > scrollAreaHeight ? scrollAreaHeight : newPosition);
2754
2755         LoadItemWithScrollPosition(previousScrollPosition, currentScrollPosition);
2756
2757         return _ScrollPanelPresenter::ScrollToInternal(newPosition);
2758 }
2759
2760 void
2761 _TableViewPresenter::LoadItemWithScrollPosition(int previousScrollPosition, int currentScrollPos)
2762 {
2763         ClearLastResult();
2764
2765         TableViewItemTag lastLoadedItemPos = {-1, -1};
2766         TableViewItemTag firstLoadedItemPos = {-1, -1};
2767         __pListModel->GetLastLoadedItemIndex(lastLoadedItemPos.groupIndex, lastLoadedItemPos.itemIndex);
2768         __pListModel->GetFirstLoadedItemIndex(firstLoadedItemPos.groupIndex, firstLoadedItemPos.itemIndex);
2769
2770         if (currentScrollPos > previousScrollPosition && lastLoadedItemPos.groupIndex != -1)
2771         {
2772                 _TableViewItem* lastItem = static_cast<_TableViewItem*>(__pListModel->LoadItem(lastLoadedItemPos.groupIndex, lastLoadedItemPos.itemIndex));
2773                 if (lastItem == null)
2774                 {
2775                         return;
2776                 }
2777
2778                 while (lastItem->GetBounds().y <= currentScrollPos + __pTableView->GetBounds().height)
2779                 {
2780                         TableViewItemTag nextItemPos = {-1, -1};
2781                         if (GetNextItemPosition(lastLoadedItemPos, nextItemPos))
2782                         {
2783                                 if (nextItemPos.itemIndex == -1)
2784                                 {
2785                                         LoadItem(nextItemPos.groupIndex, nextItemPos.itemIndex);
2786
2787                                         if (!GetNextItemPosition(nextItemPos, nextItemPos))
2788                                         {
2789                                                 break;
2790                                         }
2791                                 }
2792
2793                                 if (nextItemPos.groupIndex != -1)
2794                                 {
2795                                         _TableViewItem* item = LoadItem(nextItemPos.groupIndex, nextItemPos.itemIndex);
2796
2797                                         Rectangle scrollAreaBounds = _ScrollPanelPresenter::GetScrollAreaBounds();
2798                                         if (item->GetBounds().y + item->GetBounds().height >= scrollAreaBounds.height)
2799                                         {
2800                                                 AdjustClientAreaBounds(true);
2801                                         }
2802                                 }
2803                         }
2804                         else
2805                         {
2806                                 break;
2807                         }
2808
2809                         lastLoadedItemPos = nextItemPos;
2810                         lastItem = static_cast<_TableViewItem*>(__pListModel->LoadItem(lastLoadedItemPos.groupIndex, lastLoadedItemPos.itemIndex));
2811                 }
2812         }
2813
2814         if (currentScrollPos < previousScrollPosition && firstLoadedItemPos.groupIndex != -1)
2815         {
2816                 _TableViewItem* firstItem = static_cast<_TableViewItem*>(__pListModel->LoadItem(firstLoadedItemPos.groupIndex, firstLoadedItemPos.itemIndex));
2817                 if (firstItem == null)
2818                 {
2819                         return;
2820                 }
2821
2822                 while (firstItem->GetBounds().y + firstItem->GetBounds().height >= currentScrollPos)
2823                 {
2824                         TableViewItemTag prevItemPos = {-1, -1};
2825                         if (GetPreviousItemPosition(firstLoadedItemPos, prevItemPos))
2826                         {
2827                                 if (prevItemPos.itemIndex == -1)
2828                                 {
2829                                         LoadItem(prevItemPos.groupIndex, prevItemPos.itemIndex);
2830
2831                                         if (!GetPreviousItemPosition(prevItemPos, prevItemPos))
2832                                         {
2833                                                 break;
2834                                         }
2835                                 }
2836
2837                                 if (prevItemPos.groupIndex != -1)
2838                                 {
2839                                         LoadItem(prevItemPos.groupIndex, prevItemPos.itemIndex);
2840                                 }
2841                         }
2842                         else
2843                         {
2844                                 break;
2845                         }
2846
2847                         firstLoadedItemPos = prevItemPos;
2848                         firstItem = static_cast<_TableViewItem*>(__pListModel->LoadItem(firstLoadedItemPos.groupIndex, firstLoadedItemPos.itemIndex));
2849                 }
2850         }
2851 }
2852
2853 void
2854 _TableViewPresenter::ScrollToItem(int groupIndex, int itemIndex, TableViewScrollItemAlignment itemAlignment, int shiftingDistance)
2855 {
2856         TableViewItemTag itemPos = {groupIndex, itemIndex};
2857
2858         if (!__pListModel->IsLoadedItem(groupIndex, itemIndex))
2859         {
2860                 ResetItemLayout(itemPos);
2861         }
2862
2863         _TableViewItem* pItem = FindItem(itemPos);
2864
2865         if (pItem == null)
2866         {
2867                 return;
2868         }
2869
2870         int scrollPosition = pItem->GetBounds().y;
2871
2872         scrollPosition = scrollPosition + shiftingDistance;
2873
2874         SetScrollPosition(scrollPosition, false);
2875
2876         if (itemAlignment == TABLE_VIEW_SCROLL_ITEM_ALIGNMENT_BOTTOM)
2877         {
2878                 SetScrollPosition(scrollPosition - (__pTableView->GetBounds().height - pItem->GetBounds().height), false);
2879         }
2880 }
2881
2882 result
2883 _TableViewPresenter::ScrollByPixel(int scrollDistance)
2884 {
2885         FadeInScrollBar();
2886         result r = GetLastResult();
2887         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
2888
2889         ScrollTo(scrollDistance + GetScrollPosition());
2890         r = GetLastResult();
2891         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
2892
2893         RollbackBouncing(true);
2894         r = GetLastResult();
2895         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
2896
2897         FadeOutScrollBar();
2898         r = GetLastResult();
2899         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
2900
2901         return r;
2902 }
2903
2904 void
2905 _TableViewPresenter::SetScrollEnabled(bool enable)
2906 {
2907         __scrolling = enable;
2908 }
2909
2910 bool
2911 _TableViewPresenter::IsScrollEnabled(void) const
2912 {
2913         return __scrolling;
2914 }
2915
2916 bool
2917 _TableViewPresenter::GetFirstDrawnFlag(void) const
2918 {
2919         return __firstDrawnFlag;
2920 }
2921
2922 int
2923 _TableViewPresenter::GetMaxItemCachingSize(void) const
2924 {
2925         return __pListModel->GetMaxCachingSize();
2926 }
2927
2928 void
2929 _TableViewPresenter::ResetSweepItem(void)
2930 {
2931         if (__sweptItemTag.groupIndex != -1 && __sweptItemTag.itemIndex != -1)
2932         {
2933                 ResetSweptItem();
2934         }
2935 }
2936
2937 int
2938 _TableViewPresenter::GetPressedItemCount(void)
2939 {
2940         _TableViewItem* pItem = null;
2941         TableViewItemTag itemPos = {-1, -1};
2942         TableViewItemTag lastItemPos = {-1, -1};
2943         int count = 0;
2944
2945         __pListModel->GetFirstLoadedItemIndex(itemPos.groupIndex, itemPos.itemIndex);
2946         __pListModel->GetLastLoadedItemIndex(lastItemPos.groupIndex, lastItemPos.itemIndex);
2947
2948         do
2949         {
2950                 pItem = static_cast <_TableViewItem*>(__pListModel->LoadItem(itemPos.groupIndex, itemPos.itemIndex));
2951                 if (pItem == null)
2952                 {
2953                         continue;
2954                 }
2955
2956                 if (pItem->GetDrawingStatus() == TABLE_VIEW_ITEM_DRAWING_STATUS_PRESSED)
2957                 {
2958                         count++;
2959                 }
2960
2961                 if ((itemPos.itemIndex == lastItemPos.itemIndex) && (itemPos.groupIndex == lastItemPos.groupIndex))
2962                 {
2963                         break;
2964                 }
2965         } while (GetNextItemPosition(itemPos, itemPos) == true);
2966
2967         return count;
2968 }
2969
2970 int
2971 _TableViewPresenter::CalculateItemPositionY(int groupIndex, int itemIndex)
2972 {
2973         TableViewItemTag itemPos = {-1, -1};
2974         TableViewItemTag currentItemPos = {-1, -1};
2975         int positionY = 0;
2976
2977         GetFirstItem(itemPos);
2978
2979         if (itemPos.groupIndex == -1 && itemPos.itemIndex == -1)
2980         {
2981                 return 0;
2982         }
2983
2984         if (__pProviderAdaptor == null)
2985         {
2986                 return -1;
2987         }
2988
2989         positionY = GetTopMargin();
2990
2991         while ((itemPos.groupIndex < groupIndex) || ((itemPos.groupIndex == groupIndex) && (itemPos.itemIndex < itemIndex)))
2992         {
2993                 currentItemPos = itemPos;
2994
2995                 int itemHeight = GetItemHeight(itemPos);
2996
2997                 positionY += itemHeight;
2998
2999                 if (!GetNextItemPosition(currentItemPos, itemPos))
3000                 {
3001                         break;
3002                 }
3003         }
3004
3005         return positionY;
3006 }
3007
3008 void
3009 _TableViewPresenter::FadeInScrollBar(void)
3010 {
3011         TableViewScrollBarStyle scrollStyle = __pTableView->GetScrollStyle();
3012
3013         if (scrollStyle == TABLE_VIEW_SCROLL_BAR_STYLE_NONE)
3014         {
3015                 _Scroll* pScroll = __pTableView->GetScrollBar();
3016
3017                 if (pScroll != null)
3018                 {
3019                         pScroll->SetVisibleState(false);
3020                 }
3021         }
3022         else if (scrollStyle == TABLE_VIEW_SCROLL_BAR_STYLE_FAST_SCROLL)
3023         {
3024                 _Scroll* pScroll = __pTableView->GetScrollBar();
3025
3026                 if (pScroll != null)
3027                 {
3028                         pScroll->SetVisibleState(false);
3029                 }
3030
3031                 _FastScroll* pFastScroll = __pTableView->GetFastScrollBar();
3032
3033                 if (pFastScroll != null)
3034                 {
3035                         pFastScroll->SetScrollVisibility(true);
3036                 }
3037         }
3038         else
3039         {
3040                 _ScrollPanelPresenter::FadeInScrollBar();
3041         }
3042 }
3043
3044 void
3045 _TableViewPresenter::FadeOutScrollBar(void)
3046 {
3047         TableViewScrollBarStyle scrollStyle = __pTableView->GetScrollStyle();
3048         if (scrollStyle == TABLE_VIEW_SCROLL_BAR_STYLE_FAST_SCROLL)
3049         {
3050                 StopFastScrollTimer();
3051
3052                 if (!_ScrollPanelPresenter::IsScrollAnimationRunning())
3053                 {
3054                         StartFastScrollTimer();
3055                 }
3056         }
3057         else if (scrollStyle != TABLE_VIEW_SCROLL_BAR_STYLE_FIXED)
3058         {
3059                 _ScrollPanelPresenter::FadeOutScrollBar();
3060         }
3061 }
3062
3063 void
3064 _TableViewPresenter::SweepItem(int x)
3065 {
3066         if (x != 0)
3067         {
3068                 _TableViewItem* pItem = static_cast<_TableViewItem*>(__pListModel->LoadItem(__sweptItemTag.groupIndex, __sweptItemTag.itemIndex));
3069
3070                 if (pItem != null)
3071                 {
3072                         _TableViewItem* pContextItem  = pItem->GetContextItem();
3073
3074                         if (pContextItem != null)
3075                         {
3076                                 int currentPosition = __sweptItemPosition.x + x;
3077                                 int sweepDistance = __pTableView->GetBounds().width;
3078                                 int sweepMargin = 0;
3079                                 int contextItemWidth = pItem->GetBounds().width;
3080                                 bool activated = pItem->IsContextItemActivated();
3081                                 bool needToFireEvent = false;
3082
3083                                 GET_SHAPE_CONFIG(TABLEVIEW::CONTEXTITEM_RIGHT_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, sweepMargin);
3084
3085                                 if (currentPosition >= (sweepDistance - sweepMargin))
3086                                 {
3087                                         currentPosition = (sweepDistance - sweepMargin);
3088                                         needToFireEvent = !activated;
3089                                 }
3090                                 else if (currentPosition <= __leftMargin)
3091                                 {
3092                                         currentPosition = __leftMargin;
3093                                         needToFireEvent = activated;
3094                                 }
3095
3096                                 __sweptItemPosition.x = currentPosition;
3097
3098                                 // Set TableViewItem bounds
3099                                 pItem->SetPosition(__sweptItemPosition);
3100
3101                                 // Set TableViewContextItem bounds
3102                                 if (!__pTableView->IsAncestorOf(*pContextItem))
3103                                 {
3104                                         pContextItem->SetDrawingProperty(__pItemDrawingProperty);
3105                                         __pTableView->InsertChildToBottom(*pContextItem);
3106                                 }
3107
3108                                 contextItemWidth = ((contextItemWidth >  (__sweptItemPosition.x - __leftMargin)) ? (__sweptItemPosition.x - __leftMargin) : contextItemWidth);
3109
3110                                 pContextItem->ExposeContextItem(Rectangle(__leftMargin, __sweptItemPosition.y, contextItemWidth, pContextItem->GetSize().height), pItem->GetSize().width);
3111
3112                                 if (needToFireEvent)
3113                                 {
3114                                         activated = !activated; // ContextItem Activation State Changed
3115
3116                                         __pTableView->FireTableViewContextItemActivationEvent(__sweptItemTag.groupIndex, __sweptItemTag.itemIndex, pContextItem, activated);
3117                                         pItem->SetContextItemActivation(activated);
3118
3119                                         if (!activated)
3120                                         {
3121                                                 ResetSweepItem();
3122                                         }
3123                                 }
3124                         }
3125                 }
3126         }
3127 }
3128
3129 void
3130 _TableViewPresenter::ResetSweptItem(void)
3131 {
3132         _TableViewItem* pItem = static_cast<_TableViewItem*>(__pListModel->LoadItem(__sweptItemTag.groupIndex, __sweptItemTag.itemIndex));
3133
3134         if (pItem != null)
3135         {
3136                 pItem->SetPosition(Point(__leftMargin, __sweptItemPosition.y));
3137
3138                 _TableViewItem* pContextItem = pItem->GetContextItem();
3139                 if (pContextItem != null)
3140                 {
3141                         if (__pTableView->IsAncestorOf(*pContextItem))
3142                         {
3143                                 __pTableView->DetachChild(*pContextItem);
3144                         }
3145
3146                         if (pItem->IsContextItemActivated())
3147                         {
3148                                 __pTableView->FireTableViewContextItemActivationEvent(__sweptItemTag.groupIndex, __sweptItemTag.itemIndex, pContextItem, false);
3149                                 pItem->SetContextItemActivation(false);
3150                         }
3151                 }
3152         }
3153
3154         __sweptItemTag.itemIndex = -1;
3155         __sweptItemTag.groupIndex = -1;
3156
3157         __sweptItemPosition.SetPosition(-1, -1);
3158         __sweepOccured = false;
3159 }
3160
3161 void
3162 _TableViewPresenter::AdjustSweptItemPosition(bool withAnimation)
3163 {
3164         int itemWidth = __pTableView->GetBounds().width;
3165         int sweepDistance = 0;
3166
3167         if (__sweptItemPosition.x == __leftMargin)
3168         {
3169                 ResetSweptItem();
3170                 return;
3171         }
3172
3173         int sweepMargin = 0;
3174         GET_SHAPE_CONFIG(TABLEVIEW::CONTEXTITEM_RIGHT_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, sweepMargin);
3175
3176         if (__sweptItemPosition.x > (itemWidth - sweepMargin) / 2)
3177         {
3178                 sweepDistance = itemWidth - __sweptItemPosition.x;
3179         }
3180         else
3181         {
3182                 sweepDistance = -__sweptItemPosition.x;
3183         }
3184
3185         if (!withAnimation)
3186         {
3187                 SweepItem(sweepDistance);
3188         }
3189         else
3190         {
3191                 _TableViewItem* pItem = static_cast<_TableViewItem*>(__pListModel->LoadItem(__sweptItemTag.groupIndex, __sweptItemTag.itemIndex));
3192
3193                 if (pItem != null)
3194                 {
3195                         VisualElementValueAnimation* pAnimation = null;
3196                         _VisualElement* pVisualElement = __pTableView->GetVisualElement();
3197
3198                         if (pVisualElement != null)
3199                         {
3200                                 int startValue = __sweptItemPosition.x;
3201                                 int endValue = ((sweepDistance > 0) ? (itemWidth - sweepMargin) : __leftMargin);
3202
3203                                 pVisualElement->SetImplicitAnimationEnabled(false);
3204
3205                                 String animationName(L"SWEEP_ITEM_ANIMATION");
3206                                 pAnimation = dynamic_cast<VisualElementValueAnimation*>(pVisualElement->GetAnimationN(animationName));
3207
3208                                 if (pAnimation != null)
3209                                 {
3210                                         pVisualElement->RemoveAnimation(animationName);
3211                                 }
3212
3213                                 pAnimation = new (std::nothrow) VisualElementValueAnimation();
3214                                 SysTryReturnVoidResult(NID_UI_CTRL, pAnimation != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
3215
3216                                 pAnimation->SetStartValue(Variant(startValue));
3217                                 pAnimation->SetEndValue(Variant(endValue));
3218                                 pAnimation->SetTimingFunction(VisualElementAnimation::GetTimingFunctionByName(L"EaseInOut"));
3219                                 pAnimation->SetDuration(SWEEP_ITEM_ANIMATION_DURATION);
3220                                 pAnimation->SetVisualElementAnimationStatusEventListener(this);
3221                                 pAnimation->SetVisualElementAnimationTickEventListener(this);
3222
3223                                 pVisualElement->AddAnimation(animationName, *pAnimation);
3224
3225                                 delete pAnimation;
3226                         }
3227                 }
3228         }
3229 }
3230
3231 void
3232 _TableViewPresenter::AdjustLoadedItemWidth(void)
3233 {
3234         TableViewItemTag lastLoadedItemPos = {-1, -1};
3235         TableViewItemTag firstLoadedItemPos = {-1, -1};
3236         __pListModel->GetLastLoadedItemIndex(lastLoadedItemPos.groupIndex, lastLoadedItemPos.itemIndex);
3237         __pListModel->GetFirstLoadedItemIndex(firstLoadedItemPos.groupIndex, firstLoadedItemPos.itemIndex);
3238
3239         do
3240         {
3241                 _TableViewItem* pItem = FindItem(firstLoadedItemPos);
3242
3243                 if (pItem == null)
3244                 {
3245                         continue;
3246                 }
3247
3248                 Dimension itemSize = pItem->GetSize();
3249                 itemSize.width = __pProviderAdaptor->GetListWidth();
3250
3251                 pItem->SetItemChanged(true);
3252                 pItem->SetSize(itemSize);
3253
3254                 if ((firstLoadedItemPos.itemIndex == lastLoadedItemPos.itemIndex) && (firstLoadedItemPos.groupIndex == lastLoadedItemPos.groupIndex))
3255                 {
3256                         break;
3257                 }
3258         } while (GetNextItemPosition(firstLoadedItemPos, firstLoadedItemPos));
3259 }
3260
3261 bool
3262 _TableViewPresenter::IsValidDrawnItem(int groupIndex, int itemIndex)
3263 {
3264         TableViewItemTag currentItemTag = {groupIndex, itemIndex};
3265         TableViewItemTag itemTag = {-1, -1};
3266
3267         if (GetNextItemPosition(currentItemTag, itemTag))
3268         {
3269                 if (__pListModel->IsLoadedItem(itemTag.groupIndex, itemTag.itemIndex))
3270                 {
3271                         return true;
3272                 }
3273         }
3274
3275         if (GetPreviousItemPosition(currentItemTag, itemTag))
3276         {
3277                 if (__pListModel->IsLoadedItem(itemTag.groupIndex, itemTag.itemIndex))
3278                 {
3279                         return true;
3280                 }
3281         }
3282
3283         return false;
3284 }
3285
3286
3287 bool
3288 _TableViewPresenter::GetTableViewItemPosition(_TableViewItem& item, TableViewItemTag& itemTag)
3289 {
3290         TableViewItemTag lastLoadedItemPos = {-1, -1};
3291         TableViewItemTag firstLoadedItemPos = {-1, -1};
3292         __pListModel->GetLastLoadedItemIndex(lastLoadedItemPos.groupIndex, lastLoadedItemPos.itemIndex);
3293         __pListModel->GetFirstLoadedItemIndex(firstLoadedItemPos.groupIndex, firstLoadedItemPos.itemIndex);
3294
3295         _TableViewItem* pCurrentItem = null;
3296         do
3297         {
3298                 pCurrentItem = static_cast<_TableViewItem*>(__pListModel->LoadItem(firstLoadedItemPos.groupIndex, firstLoadedItemPos.itemIndex));
3299                 if (pCurrentItem == &item)
3300                 {
3301                         itemTag.groupIndex = firstLoadedItemPos.groupIndex;
3302                         itemTag.itemIndex = firstLoadedItemPos.itemIndex;
3303                         return true;
3304                 }
3305
3306                 if ((firstLoadedItemPos.itemIndex == lastLoadedItemPos.itemIndex) && (firstLoadedItemPos.groupIndex == lastLoadedItemPos.groupIndex))
3307                 {
3308                         break;
3309                 }
3310         } while (GetNextItemPosition(firstLoadedItemPos, firstLoadedItemPos));
3311
3312         return false;
3313 }
3314
3315 int
3316 _TableViewPresenter::GetItemHeight(TableViewItemTag itemTag) const
3317 {
3318         int itemHeight = 0;
3319
3320         if (__pTableView->GetTableViewStyle() == TABLE_VIEW_STYLE_SECTION && itemTag.itemIndex != -1)
3321         {
3322                 if (HasSectionFooter(itemTag.groupIndex))
3323                 {
3324                         if (itemTag.itemIndex == GetItemCountAt(itemTag.groupIndex) - 1)
3325                         {
3326                                 GET_SHAPE_CONFIG(TABLEVIEW::GROUPITEM_DEFAULT_HEIGHT, _CONTROL_ORIENTATION_PORTRAIT, itemHeight);
3327
3328                                 return itemHeight;
3329                         }
3330                 }
3331         }
3332
3333         if (__pProviderAdaptor == null)
3334         {
3335                 return -1;
3336         }
3337
3338         int startIndex = 0;
3339         for (int i = 0; i < itemTag.groupIndex; i++)
3340         {
3341                 int itemCount = GetItemCountAt(i);
3342
3343                 startIndex = startIndex + itemCount + 1;
3344         }
3345
3346         itemTag.itemIndex++;
3347         itemTag.itemIndex = startIndex + itemTag.itemIndex;
3348
3349         __itemHeightList.GetAt(itemTag.itemIndex, itemHeight);
3350
3351         return itemHeight;
3352 }
3353
3354 int
3355 _TableViewPresenter::SetItemHeight(TableViewItemTag itemTag, int height)
3356 {
3357         int startIndex = 0;
3358
3359         for (int i = 0; i < itemTag.groupIndex; i++)
3360         {
3361                 int itemCount = GetItemCountAt(i);
3362
3363                 startIndex = startIndex + itemCount + 1;
3364         }
3365
3366         itemTag.itemIndex++;
3367         itemTag.itemIndex = startIndex + itemTag.itemIndex;
3368
3369         int oldHeight = 0;
3370         __itemHeightList.GetAt(itemTag.itemIndex, oldHeight);
3371         __itemHeightList.SetAt(height, itemTag.itemIndex);
3372
3373         return oldHeight;
3374 }
3375
3376
3377 result
3378 _TableViewPresenter::SetReorderMode(bool enabled)
3379 {
3380         ResetSweepItem();
3381
3382         __reorderInfo.itemIndex = -1;
3383         __reorderInfo.groupIndex = -1;
3384
3385         _TableViewItem* pItem = null;
3386         TableViewItemTag itemPos = {-1, -1};
3387         TableViewItemTag lastItemPos = {-1, -1};
3388
3389         __pListModel->GetFirstLoadedItemIndex(itemPos.groupIndex, itemPos.itemIndex);
3390         __pListModel->GetLastLoadedItemIndex(lastItemPos.groupIndex, lastItemPos.itemIndex);
3391
3392         do
3393         {
3394                 pItem = FindItem(itemPos);
3395
3396                 if (pItem != null)
3397                 {
3398                         pItem->SetReorderMode(enabled);
3399
3400                         if (pItem->GetDrawingStatus() == TABLE_VIEW_ITEM_DRAWING_STATUS_PRESSED)
3401                         {
3402                                 if (SelectReorderItem(itemPos.groupIndex, itemPos.itemIndex))
3403                                 {
3404                                         Point itemPosition = pItem->GetPosition();
3405                                         Point touchPosition = pItem->GetLastTouchPressedPosition();
3406
3407                                         __reorderInfo.touchPressedPositionY = itemPosition.y + touchPosition.y - GetScrollPosition();
3408                                         __reorderInfo.blockedTouchReleaseState = true;
3409                                 }
3410                         }
3411                 }
3412
3413                 if ((itemPos.itemIndex == lastItemPos.itemIndex) && (itemPos.groupIndex == lastItemPos.groupIndex))
3414                 {
3415                         break;
3416                 }
3417
3418         } while (GetNextItemPosition(itemPos, itemPos) == true);
3419
3420         return E_SUCCESS;
3421 }
3422
3423 bool
3424 _TableViewPresenter::SelectReorderItem(int groupIndex, int itemIndex)
3425 {
3426         if (itemIndex == -1 || GetPressedItemCount() > 0)
3427         {
3428                 return false;
3429         }
3430
3431         TableViewItemTag itemPos = {groupIndex, itemIndex};
3432         _TableViewItem* pItem = FindItem(itemPos);
3433
3434         if (pItem == null)
3435         {
3436                 return false;
3437         }
3438
3439         pItem->SetDrawingStatus(TABLE_VIEW_ITEM_DRAWING_STATUS_PRESSED);
3440         pItem->SetItemChanged(true);
3441         pItem->Invalidate();
3442
3443         __reorderInfo.itemBounds = pItem->GetBounds();
3444         __reorderInfo.itemIndex = itemIndex;
3445         __reorderInfo.groupIndex = groupIndex;
3446         __reorderInfo.originGroupIndex = groupIndex;
3447         __reorderInfo.originItemIndex = itemIndex;
3448         __reorderInfo.itemBasisPositionY = __reorderInfo.itemBounds.y;
3449
3450         Tizen::System::SystemTime::GetTicks(__reorderInfo.touchPressedTick);
3451
3452         pItem->GetVisualElement()->SetZOrder(null, true);
3453
3454         if (GetScrollAreaBounds().height < __pTableView->GetBounds().height)
3455         {
3456                 int itemHeight = pItem->GetBounds().height;
3457
3458                 __pListModel->GetLastLoadedItemIndex(itemPos.groupIndex, itemPos.itemIndex);
3459
3460                 pItem = FindItem(itemPos);
3461
3462                 if (pItem != null)
3463                 {
3464                         Rectangle itemBounds =  pItem->GetBounds();
3465                         __reorderInfo.nonScrollableLimitArea = itemBounds.y + itemBounds.height - itemHeight;
3466                 }
3467         }
3468         else
3469         {
3470                 __reorderInfo.nonScrollableLimitArea = 0;
3471         }
3472
3473         return true;
3474 }
3475
3476 bool
3477 _TableViewPresenter::ResetReorderItem(int groupIndex, int itemIndex)
3478 {
3479         TableViewItemTag itemPos = {groupIndex, itemIndex};
3480         _TableViewItem* pItem = FindItem(itemPos);
3481
3482         if (pItem == null)
3483         {
3484                 return false;
3485         }
3486
3487         pItem->SetDrawingStatus(TABLE_VIEW_ITEM_DRAWING_STATUS_NORMAL);
3488         pItem->SetItemChanged(true);
3489         pItem->Invalidate();
3490
3491         Point position = Point(__reorderInfo.itemBounds.x, __reorderInfo.itemBounds.y);
3492         pItem->SetPosition(position);
3493
3494         if (__reorderInfo.originGroupIndex != __reorderInfo.groupIndex || __reorderInfo.originItemIndex != __reorderInfo.itemIndex)
3495         {
3496                 if (__pTableView->GetTableViewStyle() == TABLE_VIEW_STYLE_SIMPLE)
3497                 {
3498                         __pTableView->FireTableViewItemReorderEvent(__reorderInfo.originItemIndex, __reorderInfo.itemIndex);
3499                 }
3500                 else if (__pTableView->GetTableViewStyle() == TABLE_VIEW_STYLE_GROUPED)
3501                 {
3502                         __pTableView->FireTableViewItemReorderEvent(__reorderInfo.originGroupIndex, __reorderInfo.originItemIndex, __reorderInfo.groupIndex, __reorderInfo.itemIndex);
3503                 }
3504         }
3505
3506         __reorderInfo.groupIndex = -1;
3507         __reorderInfo.itemIndex = -1;
3508         __reorderInfo.originGroupIndex = -1;
3509         __reorderInfo.originItemIndex = -1;
3510         __reorderInfo.nonScrollableLimitArea = 0;
3511
3512         StopReorderScrollTimer();
3513
3514         return true;
3515 }
3516
3517 bool
3518 _TableViewPresenter::CheckReorderItemScrollAnimation(_TableViewItem *pItem)
3519 {
3520         int currentScrollPosition = GetScrollPosition();
3521         int limitTopPositionY = currentScrollPosition;
3522         int limitBottomPositionY = currentScrollPosition + __pTableView->GetBounds().height - __reorderInfo.itemBounds.height;
3523
3524         int itemPositionY = pItem->GetPosition().y;
3525
3526         if (itemPositionY < limitTopPositionY)
3527         {
3528                 if (__pReorderScrollTimer == null)
3529                 {
3530                         __reorderInfo.isScrollDirectionUp = true;
3531
3532                         return true;
3533                 }
3534         }
3535         else if (itemPositionY > limitBottomPositionY)
3536         {
3537                 if (__pReorderScrollTimer == null)
3538                 {
3539                         __reorderInfo.isScrollDirectionUp = false;
3540
3541                         return true;
3542                 }
3543         }
3544
3545         return false;
3546 }
3547
3548 bool
3549 _TableViewPresenter::DragSelectedItem(int distance, bool relativeCoordinate)
3550 {
3551         TableViewItemTag itemPos = {__reorderInfo.groupIndex, __reorderInfo.itemIndex};
3552         _TableViewItem* pItem = FindItem(itemPos);
3553
3554         if (pItem == null)
3555         {
3556                 return false;
3557         }
3558
3559         if (__firstTouchMoved)
3560         {
3561                 long long currentTick = 0;
3562                 Tizen::System::SystemTime::GetTicks(currentTick);
3563
3564                 if (currentTick - __reorderInfo.touchPressedTick < REORDER_TOUCH_UIACTIVATE_DURATION)
3565                 {
3566                         return false;
3567                 }
3568
3569                 __firstTouchMoved = false;
3570         }
3571
3572         Point itemPosition = pItem->GetPosition();
3573
3574         if (relativeCoordinate)
3575         {
3576                 itemPosition.y = __reorderInfo.itemBasisPositionY + distance;
3577         }
3578         else
3579         {
3580                 itemPosition.y += distance;
3581
3582                 __reorderInfo.itemBasisPositionY += distance;
3583         }
3584
3585         if (itemPosition.y < 0)
3586         {
3587                 itemPosition.y = 0;
3588         }
3589
3590         int scrollAreaHeight = GetScrollAreaBounds().height;
3591         int screenHeight = __pTableView->GetBounds().height;
3592         int limitBottomPositionY = 0;
3593
3594         if (scrollAreaHeight < screenHeight)
3595         {
3596                 limitBottomPositionY = __reorderInfo.nonScrollableLimitArea;
3597         }
3598         else
3599         {
3600                 limitBottomPositionY = scrollAreaHeight - __reorderInfo.itemBounds.height;
3601         }
3602
3603         if (itemPosition.y > limitBottomPositionY)
3604         {
3605                 itemPosition.y = limitBottomPositionY;
3606         }
3607
3608         pItem->SetPosition(itemPosition);
3609
3610         // check scroll
3611         if (CheckReorderItemScrollAnimation(pItem))
3612         {
3613                 if (__pReorderScrollTimer == null)
3614                 {
3615                         StartReorderScrollTimer();
3616                 }
3617         }
3618         else
3619         {
3620                 if (__pReorderScrollTimer != null)
3621                 {
3622                         StopReorderScrollTimer();
3623                 }
3624         }
3625
3626         // check swap
3627         TableViewItemTag moveItemTag = {-1, -1};
3628
3629         if (CheckReorderItemPosition(pItem, moveItemTag))
3630         {
3631                 if (moveItemTag.itemIndex == -1)
3632                 {
3633                         int destGroupIndex = moveItemTag.groupIndex;
3634
3635                         if (destGroupIndex != 0 && destGroupIndex == __reorderInfo.groupIndex)
3636                         {
3637                                 destGroupIndex--;
3638                         }
3639
3640                         if (moveItemTag.groupIndex == 0 || !__pProviderAdaptor->IsReorderable(__reorderInfo.groupIndex, destGroupIndex))
3641                         {
3642 //                              ResetReorderItem(__reorderInfo.groupIndex, __reorderInfo.itemIndex);
3643 //                              itemPosition = pItem->GetPosition();
3644 //
3645 //                              _TableViewItem* pGroupItem = FindItem(moveItemTag);
3646 //
3647 //                              if (pGroupItem == null)
3648 //                              {
3649 //                                      return false;
3650 //                              }
3651 //
3652 //                              Rectangle groupItemBounds = pGroupItem->GetBounds();
3653 //
3654 //                              if (__reorderInfo.groupIndex < moveItemTag.groupIndex)
3655 //                              {
3656 //                                      itemPosition.y = groupItemBounds.y - pItem->GetItemHeight();
3657 //                              }
3658 //                              else
3659 //                              {
3660 //                                      itemPosition.y = groupItemBounds.y + groupItemBounds.height;
3661 //                              }
3662
3663                                 return false;
3664                         }
3665                 }
3666
3667                 ReorderItem(moveItemTag.groupIndex, moveItemTag.itemIndex);
3668         }
3669
3670         return true;
3671 }
3672
3673 bool
3674 _TableViewPresenter::CheckReorderItemPosition(_TableViewItem* pItem, TableViewItemTag& reorderItemTag)
3675 {
3676         TableViewItemTag currentItemTag = {__reorderInfo.groupIndex, __reorderInfo.itemIndex};
3677         TableViewItemTag previousItemTag = {-1, -1};
3678         TableViewItemTag nextItemTag = {-1, -1};
3679
3680         Rectangle itemBounds = pItem->GetBounds();
3681
3682         if (GetPreviousItemPosition(currentItemTag, previousItemTag))
3683         {
3684                 _TableViewItem* pPreviousItem = FindItem(previousItemTag);
3685
3686                 if (pPreviousItem != null)
3687                 {
3688                         Rectangle previousItemBounds = pPreviousItem->GetBounds();
3689
3690                         if (itemBounds.y < previousItemBounds.y + (previousItemBounds.height / 2))
3691                         {
3692                                 //return previousItemIndex;
3693                                 reorderItemTag.groupIndex = previousItemTag.groupIndex;
3694                                 reorderItemTag.itemIndex = previousItemTag.itemIndex;
3695
3696                                 return true;
3697                         }
3698                 }
3699         }
3700
3701         if (GetNextItemPosition(currentItemTag, nextItemTag))
3702         {
3703                 _TableViewItem* pNextItem = FindItem(nextItemTag);
3704
3705                 if (pNextItem != null)
3706                 {
3707                         Rectangle nextItemBounds = pNextItem->GetBounds();
3708
3709                         if (itemBounds.y + itemBounds.height > nextItemBounds.y + (nextItemBounds.height / 2))
3710                         {
3711                                 //return nextItemIndex;
3712                                 reorderItemTag.groupIndex = nextItemTag.groupIndex;
3713                                 reorderItemTag.itemIndex = nextItemTag.itemIndex;
3714
3715                                 return true;
3716                         }
3717                 }
3718         }
3719
3720         reorderItemTag.groupIndex = -1;
3721         reorderItemTag.itemIndex = -1;
3722
3723         return false;
3724 }
3725
3726 bool
3727 _TableViewPresenter::ReorderItem(int destinationGroupIndex, int destinationItemIndex)
3728 {
3729         TableViewItemTag itemPos = {destinationGroupIndex, destinationItemIndex};
3730
3731         _TableViewItem* pItem = FindItem(itemPos);
3732
3733         if (pItem == null)
3734         {
3735                 return false;
3736         }
3737
3738         if (pItem->IsAnimationPlaying())
3739         {
3740                 return false;
3741         }
3742
3743         Rectangle destinationItemBounds = pItem->GetBounds();
3744
3745         Point destinationItemPosition = Point(destinationItemBounds.x, 0);
3746
3747         if ( __reorderInfo.itemIndex > destinationItemIndex && __reorderInfo.groupIndex == destinationGroupIndex)
3748         {
3749                 destinationItemPosition.y = __reorderInfo.itemBounds.y + __reorderInfo.itemBounds.height - destinationItemBounds.height;
3750                 __reorderInfo.itemBounds.y = destinationItemBounds.y;
3751
3752                 if (destinationItemIndex == -1)
3753                 {
3754                         destinationGroupIndex--;
3755                         int itemCount = GetItemCountAt(destinationGroupIndex);
3756                         destinationItemIndex = itemCount;
3757                 }
3758         }
3759         else
3760         {
3761                 destinationItemPosition.y = __reorderInfo.itemBounds.y;
3762                 __reorderInfo.itemBounds.y = destinationItemBounds.y + destinationItemBounds.height - __reorderInfo.itemBounds.height;
3763
3764                 if (destinationItemIndex == -1)
3765                 {
3766                         destinationItemIndex = 0;
3767                 }
3768         }
3769
3770         _ListItemPos originPosition = {__reorderInfo.groupIndex, __reorderInfo.itemIndex};
3771         _ListItemPos destinationPosition = {destinationGroupIndex, destinationItemIndex};
3772
3773         __pListModel->MoveItem(originPosition, destinationPosition);
3774
3775         if (!pItem->MoveItem(destinationItemPosition, REORDER_ITEM_MOVE_ANIMATION_DURATION, 0))
3776         {
3777                 pItem->SetPosition(destinationItemPosition);
3778         }
3779
3780         __reorderInfo.itemIndex = destinationItemIndex;
3781         __reorderInfo.groupIndex = destinationGroupIndex;
3782
3783         return true;
3784 }
3785
3786 void
3787 _TableViewPresenter::StartReorderScrollTimer(void)
3788 {
3789         StopReorderScrollTimer();
3790
3791         __pReorderScrollTimer = new (std::nothrow) Tizen::Base::Runtime::Timer;
3792         SysTryReturnVoidResult(NID_UI_CTRL, __pReorderScrollTimer != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
3793
3794         result r = __pReorderScrollTimer->Construct(*this);
3795         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
3796
3797         r = __pReorderScrollTimer->Start(REORDER_SCROLL_ANIMATION_TIMER_DURATION);
3798         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
3799
3800         return;
3801
3802 CATCH:
3803         StopReorderScrollTimer();
3804 }
3805
3806 void
3807 _TableViewPresenter::StopReorderScrollTimer(void)
3808 {
3809         delete __pReorderScrollTimer;
3810         __pReorderScrollTimer = null;
3811
3812 }
3813
3814 void
3815 _TableViewPresenter::UpdateLayout(void)
3816 {
3817         // nothing
3818 }
3819
3820 bool
3821 _TableViewPresenter::CheckItemHeightAndRefreshLayout(TableViewItemTag itemTag, bool downScroll)
3822 {
3823         _TableViewItem* pItem = FindItem(itemTag);
3824
3825         if (pItem == null)
3826         {
3827                 return false;
3828         }
3829
3830         if (pItem->IsAnimationPlaying())
3831         {
3832                 return false;
3833         }
3834
3835         Rectangle itemBounds = pItem->GetBounds();
3836
3837         if (GetItemHeight(itemTag) == itemBounds.height)
3838         {
3839                 return false;
3840         }
3841
3842         int newHeight = itemBounds.height;
3843         int originHeight = SetItemHeight(itemTag, newHeight);
3844         int dist = newHeight - originHeight;
3845
3846         AdjustClientAreaBounds(false, dist);
3847
3848         if (!downScroll)
3849         {
3850                 itemBounds.y += dist;
3851                 pItem->SetBounds(itemBounds);
3852         }
3853
3854         AttachNextItemsToBottom(itemTag);
3855
3856         return true;
3857 }
3858
3859 bool
3860 _TableViewPresenter::CreateItemHeightList(void)
3861 {
3862         int groupCount = GetGroupCount();
3863         int defaultItemHeight = __pProviderAdaptor->GetDefaultItemHeight();
3864         int defaultGroupItemHeight = __pProviderAdaptor->GetDefaultGroupItemHeight();
3865
3866         result r = __itemHeightList.SetCapacity(GetItemCount());
3867         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory shortage.");
3868
3869         for (int i = 0; i < groupCount; i++)
3870         {
3871                 int itemCount = GetItemCountAt(i);
3872
3873                 if (__pTableView->GetTableViewStyle() == TABLE_VIEW_STYLE_SIMPLE)
3874                 {
3875                         __itemHeightList.Add(0);
3876                 }
3877                 else
3878                 {
3879                         __itemHeightList.Add(defaultGroupItemHeight);
3880                 }
3881
3882                 for (int j = 1; j <= itemCount; j++)
3883                 {
3884                         __itemHeightList.Add(defaultItemHeight);
3885                 }
3886         }
3887
3888         return true;
3889
3890 CATCH:
3891         DeleteItemHeightList();
3892
3893         return false;
3894 }
3895
3896 bool
3897 _TableViewPresenter::RefreshItemHeightList(int groupIndex, int itemIndex, TableViewRefreshType refreshType)
3898 {
3899         int defaultItemHeight = __pProviderAdaptor->GetDefaultItemHeight();
3900         int defaultGroupItemHeight = __pProviderAdaptor->GetDefaultGroupItemHeight();
3901
3902         int startIndex = 0;
3903         for (int i = 0; i < groupIndex; i++)
3904         {
3905                 int itemCount = GetItemCountAt(i);
3906                 startIndex = startIndex + itemCount + 1;
3907         }
3908
3909         int targetIndex = startIndex + itemIndex + 1;
3910
3911         if (refreshType == TABLE_VIEW_REFRESH_TYPE_ITEM_ADD)
3912         {
3913                 if (itemIndex == -1)
3914                 {
3915                         result r = __itemHeightList.SetCapacity(GetItemCount());
3916                         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
3917
3918                         int itemCount = GetItemCountAt(groupIndex);
3919                         for (int i = 0; i < itemCount; i++)
3920                         {
3921                                 __itemHeightList.InsertAt(defaultItemHeight, targetIndex);
3922                         }
3923
3924                         __itemHeightList.InsertAt(defaultGroupItemHeight, targetIndex);
3925
3926                 }
3927                 else
3928                 {
3929                         __itemHeightList.InsertAt(defaultItemHeight, targetIndex);
3930                 }
3931         }
3932         else if (refreshType == TABLE_VIEW_REFRESH_TYPE_ITEM_REMOVE)
3933         {
3934                 if (itemIndex == -1)
3935                 {
3936                         int itemCount = GetItemCountAt(groupIndex) + 1;
3937
3938                         for (int i = 0; i < itemCount; i++)
3939                         {
3940                                 __itemHeightList.RemoveAt(targetIndex);
3941                         }
3942                 }
3943                 else
3944                 {
3945                         __itemHeightList.RemoveAt(targetIndex);
3946                 }
3947         }
3948
3949         return true;
3950 }
3951
3952 void
3953 _TableViewPresenter::CaptureAndStartRemoveItemAnimation(int groupIndex, int itemIndex)
3954 {
3955         TableViewItemTag itemTag = {groupIndex, itemIndex};
3956         _TableViewItem* pItem = FindItem(itemTag);
3957
3958         if (pItem == null)
3959         {
3960                 return;
3961         }
3962
3963         Rectangle itemBounds = pItem->GetBounds();
3964         result r = E_SUCCESS;
3965
3966         _VisualElement* pVisualElement = null;
3967         VisualElementValueAnimation* pAnimation = null;
3968         Canvas* pCanvas = null;
3969
3970         Dimension startValue(100, itemBounds.height);
3971         Dimension endValue(0, 0);
3972
3973         Tizen::Graphics::Bitmap* pBitmap = pItem->GetCapturedBitmapN(true);
3974
3975         if (pBitmap == null)
3976         {
3977                 return;
3978         }
3979
3980         pCanvas = null;
3981         pVisualElement = new (std::nothrow) _VisualElement();
3982         SysTryCatch(NID_UI_CTRL, pVisualElement != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
3983
3984         r = pVisualElement->Construct();
3985         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
3986
3987         pVisualElement->SetImplicitAnimationEnabled(false);
3988         pVisualElement->SetSurfaceOpaque(false);
3989         pVisualElement->SetBounds(FloatRectangle(itemBounds.x, itemBounds.y, itemBounds.width, itemBounds.height));
3990         pVisualElement->SetShowState(true);
3991
3992         GetView()->GetVisualElement()->AttachChild(*pVisualElement);
3993
3994         pCanvas = pVisualElement->GetCanvasN();
3995         SysTryCatch(NID_UI_CTRL, pCanvas != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
3996
3997         pCanvas->Clear();
3998         pCanvas->DrawBitmap(Rectangle(0, 0, itemBounds.width, itemBounds.height), *pBitmap);
3999
4000         pAnimation = new (std::nothrow) VisualElementValueAnimation();
4001         SysTryCatch(NID_UI_CTRL, pAnimation != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
4002
4003         pAnimation->SetTimingFunction(VisualElementAnimation::GetTimingFunctionByName(L"EaseIn"));
4004         pAnimation->SetDuration(REMOVE_ITEM_MOVE_ANIMATION_DURATION);
4005         pAnimation->SetDelay(0);
4006         pAnimation->SetStartValue(Variant(startValue));
4007         pAnimation->SetEndValue(Variant(endValue));
4008         pAnimation->SetVisualElementAnimationStatusEventListener(GetView());
4009         pAnimation->SetVisualElementAnimationTickEventListener(GetView());
4010
4011         r = pVisualElement->AddAnimation(L"RemoveTableViewItem", *pAnimation);
4012         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
4013
4014         delete pAnimation;
4015         delete pCanvas;
4016         delete pBitmap;
4017
4018         return;
4019
4020 CATCH:
4021         delete pCanvas;
4022         delete pBitmap;
4023         pVisualElement->Destroy();
4024 }
4025
4026 void
4027 _TableViewPresenter::DeleteItemHeightList(void)
4028 {
4029         __itemHeightList.RemoveAll();
4030 }
4031
4032 _TableViewItem*
4033 _TableViewPresenter::GetTableViewItemFromControl(const _Control& source)
4034 {
4035         _Control* currentControl = const_cast<_Control*>(&source);
4036         _TableViewItem* pItem = null;
4037
4038         while (__pTableView != currentControl)
4039         {
4040                 pItem = dynamic_cast<_TableViewItem*>(currentControl);
4041
4042                 if ((pItem != null) || (currentControl == null))
4043                 {
4044                         break;
4045                 }
4046
4047                 currentControl = currentControl->GetParent();
4048         }
4049
4050         return pItem;
4051 }
4052
4053 void
4054 _TableViewPresenter::SetLoadedItemsVisibleFromPosition(int position, bool visible)
4055 {
4056         _TableViewItem* pItem;
4057         Rectangle itemBounds;
4058         TableViewItemTag current;
4059         current.groupIndex = __expandableItemTag.groupIndex;
4060         current.itemIndex = __expandableItemTag.itemIndex;
4061
4062         int itemCountInGroup = __pListModel->GetItemCountInGroup(__expandableItemTag.groupIndex);
4063
4064         for (int i = 0; i < itemCountInGroup; i++)
4065         {
4066                 current.itemIndex = i;
4067
4068                 if (visible)
4069                 {
4070                         pItem = LoadItem(current.groupIndex, current.itemIndex);
4071                 }
4072                 else
4073                 {
4074                         pItem = FindItem(current);
4075                 }
4076
4077                 if (pItem == null)
4078                 {
4079                         break;
4080                 }
4081
4082                 itemBounds = pItem->GetBounds();
4083
4084                 if (visible)
4085                 {
4086                         pItem->SetVisibleState(visible);
4087                         pItem->GetVisualElement()->SetZOrder(null, false);
4088
4089                         if (position < itemBounds.y + itemBounds.height)
4090                         {
4091                                 break;
4092                         }
4093                 }
4094                 else
4095                 {
4096                         if (position < itemBounds.y)
4097                         {
4098                                 UnloadItem(current);
4099                         }
4100                 }
4101         }
4102 }
4103
4104 void
4105 _TableViewPresenter::MoveLoadedItemsFromPosition(int position)
4106 {
4107         Rectangle itemBounds;
4108         int itemPosition = position;
4109
4110         TableViewItemTag current;
4111         TableViewItemTag next;
4112
4113         current.groupIndex = __expandableItemTag.groupIndex;
4114         current.itemIndex = __pListModel->GetItemCountInGroup(__expandableItemTag.groupIndex) -1;
4115
4116         int screenPosition = GetScrollPosition();
4117         Rectangle screenBounds = __pTableView->GetBounds();
4118         screenPosition += screenBounds.height;
4119
4120         _TableViewItem* pItem = null;
4121         while (GetNextItemPosition(current, next))
4122         {
4123                 if (screenPosition > itemPosition)
4124                 {
4125                         pItem = LoadItem(next.groupIndex, next.itemIndex);
4126                 }
4127                 else
4128                 {
4129                         pItem = FindItem(next);
4130                 }
4131
4132                 if (pItem == null)
4133                 {
4134                         break;
4135                 }
4136
4137                 itemBounds = pItem->GetBounds();
4138                 itemBounds.y = itemPosition;
4139                 pItem->SetBounds(itemBounds);
4140                 itemPosition += itemBounds.height;
4141
4142                 current = next;
4143         }
4144 }
4145
4146 void
4147 _TableViewPresenter::OnVisualElementAnimationStarted(const Tizen::Ui::Animations::VisualElementAnimation& animation, const Tizen::Base::String& keyName, Tizen::Ui::Animations::VisualElement& target)
4148 {
4149         if (keyName == L"RemoveTableViewItem")
4150         {
4151                 return;
4152         }
4153         _ScrollPanelPresenter::OnVisualElementAnimationStarted(animation, keyName, target);
4154 }
4155
4156 void
4157 _TableViewPresenter::OnVisualElementAnimationRepeated(const Tizen::Ui::Animations::VisualElementAnimation& animation, const Tizen::Base::String& keyName, Tizen::Ui::Animations::VisualElement& target, long currentRepeatCount)
4158 {
4159         if (keyName == L"RemoveTableViewItem")
4160         {
4161                 return;
4162         }
4163         _ScrollPanelPresenter::OnVisualElementAnimationRepeated(animation, keyName, target, currentRepeatCount);
4164 }
4165
4166 void
4167 _TableViewPresenter::OnVisualElementAnimationFinished(const Tizen::Ui::Animations::VisualElementAnimation& animation, const Tizen::Base::String& keyName, Tizen::Ui::Animations::VisualElement& target, bool completedNormally)
4168 {
4169         if (keyName == L"RemoveTableViewItem")
4170         {
4171                 _VisualElement* pVisualElement = GetView()->GetVisualElement();
4172
4173                 pVisualElement->DetachChild(target);
4174
4175                 target.Destroy();
4176                 return;
4177         }
4178         else if (keyName == L"EXPAND_GROUP_ANIMATION")
4179         {
4180                 if (completedNormally == false)
4181                 {
4182                         TableViewItemTag current;
4183                         TableViewItemTag next;
4184
4185                         current.groupIndex = __expandableItemTag.groupIndex;
4186                         current.itemIndex = -1;
4187
4188                         _TableViewItem* pNextItem = null;
4189                         _TableViewItem* pCurrentItem = null;
4190                         pCurrentItem = LoadItem(current.groupIndex, current.itemIndex);
4191
4192                         Rectangle itemBounds;
4193                         Rectangle screenBounds = __pTableView->GetBounds();
4194                         int screenPosition = GetScrollPosition() + screenBounds.height;
4195                         int nextItemPositionY = pCurrentItem->GetBounds().y + pCurrentItem->GetBounds().height;
4196
4197                         while (GetNextItemPosition(current, next))
4198                         {
4199                                 if (screenPosition >= nextItemPositionY)
4200                                 {
4201                                         pCurrentItem = LoadItem(current.groupIndex, current.itemIndex);
4202                                         if (pCurrentItem == null)
4203                                         {
4204                                                 break;
4205                                         }
4206                                         pNextItem = LoadItem(next.groupIndex, next.itemIndex);
4207                                         if (pNextItem == null)
4208                                         {
4209                                                 break;
4210                                         }
4211
4212                                         itemBounds = pNextItem->GetBounds();
4213                                         itemBounds.y = pCurrentItem->GetBounds().y + pCurrentItem->GetBounds().height;
4214                                         pNextItem->SetBounds(itemBounds);
4215                                         nextItemPositionY = itemBounds.y + itemBounds.height;
4216                                 }
4217                                 else
4218                                 {
4219                                         UnloadItem(next.groupIndex, next.itemIndex);
4220                                 }
4221
4222                                 current = next;
4223                         }
4224                 }
4225                 else
4226                 {
4227                         int currentGroupIndex = -1;
4228                         int currentItemIndex = -1;
4229                         GetBottomDrawnItemIndex(currentGroupIndex, currentItemIndex);
4230
4231                         int lastLoadedGroupIndex = -1;
4232                         int lastLoadedItemIndex = -1;
4233                         __pListModel->GetLastLoadedItemIndex(lastLoadedGroupIndex, lastLoadedItemIndex);
4234
4235                         for (int j = currentGroupIndex; j <= lastLoadedGroupIndex; j++)
4236                         {
4237                                 int itemCount = GetItemCountAt(j);
4238
4239                                 for (int i = -1; i < itemCount; i++)
4240                                 {
4241                                         if (i <= currentItemIndex && j == currentGroupIndex)
4242                                         {
4243                                                 continue;
4244                                         }
4245
4246                                         UnloadItem(j, i);
4247                                 }
4248                         }
4249                 }
4250                 return;
4251         }
4252         else if (keyName == L"COLLAPSE_GROUP_ANIMATION")
4253         {
4254                 if (completedNormally == false)
4255                 {
4256                         TableViewItemTag current;
4257                         TableViewItemTag next;
4258
4259                         current.groupIndex = __expandableItemTag.groupIndex;
4260                         current.itemIndex = -1;
4261
4262                         _TableViewItem* pCurrentItem = null;
4263                         int itemCountInGroup = __pListModel->GetItemCountInGroup(__expandableItemTag.groupIndex);
4264
4265                         for (int i = 0; i < itemCountInGroup; i++)
4266                         {
4267                                 UnloadItem(__expandableItemTag.groupIndex, i);
4268                         }
4269
4270                         pCurrentItem = FindItem(current);
4271                         if (pCurrentItem == null)
4272                         {
4273                                 SysTryReturnVoidResult(NID_UI_CTRL, pCurrentItem != null, E_SYSTEM, "[E_SYSTEM] A system error has been occurred.")
4274                         }
4275
4276                         Rectangle itemBounds;
4277                         int nextItemPositionY = pCurrentItem->GetBounds().y + pCurrentItem->GetBounds().height;
4278
4279                         Rectangle screenBounds = __pTableView->GetBounds();
4280                         int screenPosition = GetScrollPosition() + screenBounds.height;
4281
4282                         while (GetNextItemPosition(current, next))
4283                         {
4284                                 current = next;
4285                                 if (screenPosition >= nextItemPositionY)
4286                                 {
4287                                         pCurrentItem = LoadItem(current.groupIndex, current.itemIndex);
4288                                         if (pCurrentItem == null)
4289                                         {
4290                                                 break;
4291                                         }
4292
4293                                         itemBounds = pCurrentItem->GetBounds();
4294                                         itemBounds.y = nextItemPositionY;
4295                                         pCurrentItem->SetBounds(itemBounds);
4296
4297                                         nextItemPositionY = pCurrentItem->GetBounds().y + pCurrentItem->GetBounds().height;
4298                                 }
4299                                 else
4300                                 {
4301                                         UnloadItem(current.groupIndex, current.itemIndex);
4302                                 }
4303                         }
4304                 }
4305                 else
4306                 {
4307                         int scrollPosition = GetScrollPosition();
4308
4309                         int groupItemsHeight = 0;
4310                         _IListItemCommon* pItem = null;
4311                         for (int i = 0; i < __expandableItemTag.itemIndex; i++)
4312                         {
4313                                 pItem = __pListModel->GetItemFromTemporaryBuffer(__expandableItemTag.groupIndex, i);
4314                                 groupItemsHeight += pItem->GetItemHeight();
4315                         }
4316
4317                         _TableViewItem* pTableViewItem = static_cast<_TableViewItem*>(__pListModel->GetItemFromTemporaryBuffer(__expandableItemTag.groupIndex, __expandableItemTag.itemIndex));
4318                         Rectangle itemBounds = pTableViewItem->GetBounds();
4319                         groupItemsHeight += (scrollPosition - itemBounds.y);
4320
4321                         int currentGroupIndex = -1;
4322                         int currentItemIndex = -1;
4323                         GetTopDrawnItemIndex(currentGroupIndex, currentItemIndex);
4324
4325                         int firstLoadedGroupIndex = -1;
4326                         int firstLoadedItemIndex = -1;
4327                         __pListModel->GetFirstLoadedItemIndex(firstLoadedGroupIndex, firstLoadedItemIndex);
4328
4329                         for (int j = firstLoadedGroupIndex; j <= currentGroupIndex; j++)
4330                         {
4331                                 int itemCount = GetItemCountAt(j);
4332
4333                                 for (int i = -1; i < itemCount; i++)
4334                                 {
4335                                         if (i >= currentItemIndex && j == currentGroupIndex)
4336                                         {
4337                                                 break;
4338                                         }
4339
4340                                         UnloadItem(j, i);
4341                                 }
4342                         }
4343
4344                         int itemCount = GetItemCountAt(__expandableItemTag.groupIndex);
4345                         for (int i = 0; i < itemCount; i++)
4346                         {
4347                                 UnloadItem(__expandableItemTag.groupIndex, i);
4348                         }
4349                 }
4350
4351                 return;
4352         }
4353
4354         _ScrollPanelPresenter::OnVisualElementAnimationFinished(animation, keyName, target, completedNormally);
4355 }
4356
4357 void
4358 _TableViewPresenter::OnTickOccurred(const Tizen::Ui::Animations::VisualElementAnimation& animation, const Tizen::Base::String& keyName, Tizen::Ui::Animations::VisualElement& target, const Tizen::Ui::Variant& currentValue)
4359 {
4360         _VisualElement* pVisualElement = __pTableView->GetVisualElement();
4361
4362         if (&target != pVisualElement)
4363         {
4364                 return;
4365         }
4366
4367         if (keyName == L"RemoveTableViewItem")
4368         {
4369                 Dimension value = currentValue.ToDimension();
4370                 target.SetOpacity(value.width);
4371
4372                 FloatRectangle bounds = target.GetBounds();
4373                 bounds.height = value.height;
4374                 target.SetBounds(bounds);
4375
4376                 target.SetFlushNeeded();
4377
4378                 return;
4379         }
4380         else if (keyName == L"EXPAND_GROUP_ANIMATION")
4381         {
4382                 int currentPosition = currentValue.ToInt();
4383                 SetLoadedItemsVisibleFromPosition(currentPosition, true);
4384                 MoveLoadedItemsFromPosition(currentPosition);
4385
4386                 return;
4387         }
4388         else if (keyName == L"COLLAPSE_GROUP_ANIMATION")
4389         {
4390                 int currentPosition = currentValue.ToInt();
4391                 SetLoadedItemsVisibleFromPosition(currentPosition, false);
4392                 MoveLoadedItemsFromPosition(currentPosition);
4393
4394                 return;
4395         }
4396         else if (keyName == L"SWEEP_ITEM_ANIMATION")
4397         {
4398                 int currentPosition = currentValue.ToInt();
4399                 int moveDestance = currentPosition - __sweptItemPosition.x;
4400                 SweepItem(moveDestance);
4401
4402                 return;
4403         }
4404
4405         _ScrollPanelPresenter::OnTickOccurred(animation, keyName, target, currentValue);
4406 }
4407
4408 }}} // Tizen::Ui::Controls