af251b0c3bf311330427b2567dfcf1d5ff42ed7f
[platform/framework/native/uifw.git] / src / ui / controls / FUiCtrl_GroupedListViewImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file        FUiCtrl_GroupedListViewImpl.cpp
20  * @brief   This is the implementation file for
21  *        _GroupedListViewImpl class.
22  *
23  * This file contains the implementation of _GroupedListViewImpl
24  * class.
25  */
26
27 #include <FBaseSysLog.h>
28 #include <FApp_AppInfo.h>
29 #include <FGrp_TextTextSimple.h>
30 #include "FUi_AccessibilityContainer.h"
31 #include "FUi_AccessibilityElement.h"
32 #include "FUi_AccessibilityManager.h"
33 #include "FUi_CoordinateSystemUtils.h"
34 #include "FUi_ITouchLongPressGestureEventListener.h"
35 #include "FUi_Math.h"
36 #include "FUi_ResourceManager.h"
37 #include "FUi_TouchEventArg.h"
38 #include "FUi_TouchLongPressGestureDetector.h"
39 #include "FUi_TouchManager.h"
40 #include "FUi_UiBuilder.h"
41 #include "FUi_Window.h"
42 #include "FUiCtrl_FastScrollEvent.h"
43 #include "FUiCtrl_FastScrollEventArg.h"
44 #include "FUiCtrl_GroupedListViewImpl.h"
45 #include "FUiCtrl_GroupedListViewItemProviderAdaptor.h"
46 #include "FUiCtrl_Label.h"
47 #include "FUiCtrl_ListItemEvent.h"
48 #include "FUiCtrl_ListItemEventArg.h"
49 #include "FUiCtrl_ListViewItem.h"
50 #include "FUiCtrl_PublicLinkEvent.h"
51 #include "FUiCtrl_ScrollEvent.h"
52 #include "FUiCtrl_ScrollEventArg.h"
53
54 using namespace Tizen::Base;
55 using namespace Tizen::Base::Collection;
56 using namespace Tizen::Base::Runtime;
57 using namespace Tizen::Base::Utility;
58 using namespace Tizen::Graphics;
59 using namespace Tizen::Graphics::_Text;
60
61 namespace Tizen { namespace Ui { namespace Controls
62 {
63
64 class _GroupedListViewImpl::_GroupedListViewPropagatedTouchEventListener
65         : public Tizen::Ui::_IPropagatedTouchEventListener
66         , public Tizen::Ui::_ITouchLongPressGestureEventListener
67 {
68 public:
69
70         _GroupedListViewPropagatedTouchEventListener(_GroupedListViewImpl& impl)
71                 : __impl(impl)
72                 , __core(impl.GetCore())
73                 , __public(impl.GetPublic())
74                 , __oldPreviousPressedTime(0)
75                 , __previousPressedTime(0)
76                 , __currentPressedTime(0)
77                 , __previousPressedPoint(0.0f, 0.0f)
78                 , __currentPressedPoint(0.0f, 0.0f)
79                 , __pLongPressedGesture(null)
80         {
81                 __pTouchManager = _TouchManager::GetInstance();
82                 SysTryReturnVoidResult(NID_UI_CTRL, (__pTouchManager != null), E_SYSTEM, "[E_SYSTEM] System error occurred.");
83
84                 // Add _TouchLongPressGestureDetector
85                 __pLongPressedGesture = new (std::nothrow) _TouchLongPressGestureDetector();
86                 SysTryReturnVoidResult(NID_UI_CTRL, (__pLongPressedGesture != null), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
87
88                 __core.AddGestureDetector(*__pLongPressedGesture);
89                 result r = __pLongPressedGesture->AddGestureListener(*this);
90                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] propagating.", GetErrorMessage(r));
91         }
92
93         virtual ~_GroupedListViewPropagatedTouchEventListener(void)
94         {
95                 if (__pLongPressedGesture != null)
96                 {
97                         __pLongPressedGesture->RemoveGestureListener(*this);
98                         __core.RemoveGestureDetector(*__pLongPressedGesture);
99
100                         delete __pLongPressedGesture;
101                         __pLongPressedGesture = null;
102                 }
103         }
104
105         virtual bool OnTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
106         {
107                 return __impl.CallOnTouchPressed(source, touchInfo);
108         }
109
110         virtual bool OnTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
111         {
112                 return __impl.CallOnTouchReleased(source, touchInfo);
113         }
114
115         virtual bool OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
116         {
117                 return __impl.CallOnTouchMoved(source, touchInfo);
118         }
119
120         virtual bool OnTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
121         {
122                 return __impl.CallOnTouchCanceled(source, touchInfo);
123         }
124
125         virtual _UiTouchEventDelivery OnPreviewTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
126         {
127                 _UiTouchEventDelivery isFiltered = _UI_TOUCH_EVENT_DELIVERY_NO;
128                 IPropagatedTouchEventListener* pListener = __impl.GetPublicPropagatedTouchEventListener();
129
130                 if (pListener != null)
131                 {
132                         Control& control = __impl.GetPublic();
133
134                         TouchEventInfo publicTouchInfo;
135
136                         _TouchEventArg* pEventArg = GetTouchEventArgN(touchInfo);
137                         SysTryReturn(NID_UI, pEventArg, _UI_TOUCH_EVENT_DELIVERY_YES, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory shortage.");
138
139                         publicTouchInfo.Construct(*pEventArg);
140
141                         if (pEventArg)
142                         {
143                                 delete pEventArg;
144                                 pEventArg = null;
145                         }
146
147                         if (pListener->OnTouchPressed(control, publicTouchInfo) == true)
148                         {
149                                 return _UI_TOUCH_EVENT_DELIVERY_NO;
150                         }
151                 }
152
153                 // public TouchEventListener
154                 if (ProcessTouchEventListener(touchInfo) == true)
155                 {
156                         return _UI_TOUCH_EVENT_DELIVERY_NO;
157                 }
158
159                 if (__core.Equals(source))
160                 {
161                         return _UI_TOUCH_EVENT_DELIVERY_NO;
162                 }
163
164                 isFiltered = __impl.OnPreviewTouchPressed(__impl, touchInfo);
165                 if (isFiltered == _UI_TOUCH_EVENT_DELIVERY_NO)
166                 {
167                         return _UI_TOUCH_EVENT_DELIVERY_NO;
168                 }
169
170                 isFiltered = __core.OnPreviewTouchPressed(source, touchInfo);
171
172                 return isFiltered;
173         }
174
175         virtual _UiTouchEventDelivery OnPreviewTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
176         {
177                 _UiTouchEventDelivery isFiltered = _UI_TOUCH_EVENT_DELIVERY_NO;
178                 IPropagatedTouchEventListener* pListener = __impl.GetPublicPropagatedTouchEventListener();
179
180                 if (pListener != null)
181                 {
182                         Control& control = __impl.GetPublic();
183
184                         TouchEventInfo publicTouchInfo;
185
186                         _TouchEventArg* pEventArg = GetTouchEventArgN(touchInfo);
187                         SysTryReturn(NID_UI, pEventArg, _UI_TOUCH_EVENT_DELIVERY_YES, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory shortage.");
188
189                         publicTouchInfo.Construct(*pEventArg);
190
191                         if (pEventArg)
192                         {
193                                 delete pEventArg;
194                                 pEventArg = null;
195                         }
196
197                         if (pListener->OnTouchReleased(control, publicTouchInfo) == true)
198                         {
199                                 return _UI_TOUCH_EVENT_DELIVERY_NO;
200                         }
201                 }
202
203                 // public TouchEventListener
204                 if (ProcessTouchEventListener(touchInfo) == true)
205                 {
206                         return _UI_TOUCH_EVENT_DELIVERY_NO;
207                 }
208
209                 if (__core.Equals(source))
210                 {
211                         return _UI_TOUCH_EVENT_DELIVERY_NO;
212                 }
213
214                 isFiltered = __impl.OnPreviewTouchReleased(__impl, touchInfo);
215                 if (isFiltered == _UI_TOUCH_EVENT_DELIVERY_NO)
216                 {
217                         return _UI_TOUCH_EVENT_DELIVERY_NO;
218                 }
219
220                 isFiltered = __core.OnPreviewTouchReleased(source, touchInfo);
221
222                 return isFiltered;
223         }
224
225         virtual _UiTouchEventDelivery OnPreviewTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
226         {
227                 _UiTouchEventDelivery isFiltered = _UI_TOUCH_EVENT_DELIVERY_NO;
228                 IPropagatedTouchEventListener* pListener = __impl.GetPublicPropagatedTouchEventListener();
229
230                 if (pListener != null)
231                 {
232                         Control& control = __impl.GetPublic();
233
234                         TouchEventInfo publicTouchInfo;
235
236                         _TouchEventArg* pEventArg = GetTouchEventArgN(touchInfo);
237                         SysTryReturn(NID_UI, pEventArg, _UI_TOUCH_EVENT_DELIVERY_YES, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory shortage.");
238
239                         publicTouchInfo.Construct(*pEventArg);
240
241                         if (pEventArg)
242                         {
243                                 delete pEventArg;
244                                 pEventArg = null;
245                         }
246
247                         if (pListener->OnTouchMoved(control, publicTouchInfo) == true)
248                         {
249                                 return _UI_TOUCH_EVENT_DELIVERY_NO;
250                         }
251                 }
252
253                 // public TouchEventListener
254                 if (ProcessTouchEventListener(touchInfo) == true)
255                 {
256                         return _UI_TOUCH_EVENT_DELIVERY_NO;
257                 }
258
259                 if (__core.Equals(source))
260                 {
261                         return _UI_TOUCH_EVENT_DELIVERY_NO;
262                 }
263
264                 isFiltered = __impl.OnPreviewTouchMoved(__impl, touchInfo);
265                 if (isFiltered == _UI_TOUCH_EVENT_DELIVERY_NO)
266                 {
267                         return _UI_TOUCH_EVENT_DELIVERY_NO;
268                 }
269
270                 isFiltered = __core.OnPreviewTouchMoved(source, touchInfo);
271
272                 return isFiltered;
273         }
274
275         virtual _UiTouchEventDelivery OnPreviewTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
276         {
277                 IPropagatedTouchEventListener* pListener = __impl.GetPublicPropagatedTouchEventListener();
278
279                 if (pListener != null)
280                 {
281                         Control& control = __impl.GetPublic();
282
283                         TouchEventInfo publicTouchInfo;
284
285                         _TouchEventArg* pEventArg = GetTouchEventArgN(touchInfo);
286                         SysTryReturn(NID_UI, pEventArg, _UI_TOUCH_EVENT_DELIVERY_YES, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory shortage.");
287
288                         publicTouchInfo.Construct(*pEventArg);
289
290                         if (pEventArg)
291                         {
292                                 delete pEventArg;
293                                 pEventArg = null;
294                         }
295
296                         if (pListener->OnTouchCanceled(control, publicTouchInfo) == true)
297                         {
298                                 return _UI_TOUCH_EVENT_DELIVERY_NO;
299                         }
300                 }
301
302                 // public TouchEventListener
303                 if (ProcessTouchEventListener(touchInfo) == true)
304                 {
305                         return _UI_TOUCH_EVENT_DELIVERY_NO;
306                 }
307
308                 return _UI_TOUCH_EVENT_DELIVERY_YES;
309         }
310
311         virtual void OnTouchPressHandled(const _Control& source)
312         {
313                 __impl.OnTouchPressHandled(source);
314         }
315
316         virtual void OnTouchReleaseHandled(const _Control& source)
317         {
318                 __impl.OnTouchReleaseHandled(source);
319         }
320
321         virtual void OnTouchMoveHandled(const _Control& source)
322         {
323                 __impl.OnTouchMoveHandled(source);
324         }
325
326         virtual void OnTouchCancelHandled(const _Control& source)
327         {
328                 __impl.OnTouchCancelHandled(source);
329         }
330
331         bool OnLongPressGestureDetected(_TouchLongPressGestureDetector& gesture)
332         {
333                 bool filtered = ProcessTouchEventListener();
334
335                 if (!filtered)
336                 {
337                         __impl.FireListViewItemLongPressedEvent();
338                 }
339
340                 return filtered;
341         }
342
343         bool OnLongPressGestureCanceled(_TouchLongPressGestureDetector& gesture)
344         {
345                 return false;
346         }
347
348 private:
349
350         bool ProcessTouchEventListener(const _TouchInfo& touchInfo)
351         {
352                 bool filtered = false;
353
354                 if (touchInfo.GetTouchStatus() == _TOUCH_PRESSED)
355                 {
356                         filtered = ProcessTouchDoublePressed(touchInfo);
357                 }
358
359                 if (!filtered)
360                 {
361                         ProcessTouchEvent(touchInfo);
362                 }
363
364                 filtered = __impl.IsInputEventConsumed();
365
366                 if (filtered)
367                 {
368                         __impl.ResetInputEventConsumed();
369                 }
370
371                 return filtered;
372         }
373
374         bool ProcessTouchEventListener(void)
375         {
376                 // for TouchLongPressed
377                 _TouchInfo touchInfo(0, _TOUCH_LONG_PRESSED, __currentPressedPoint, false, 0);
378
379                 return ProcessTouchEventListener(touchInfo);
380         }
381
382         void ProcessTouchEvent(const _TouchInfo& touchInfo)
383         {
384                 TouchEventInfo publicTouchInfo;
385
386                 _TouchEventArg* pEventArg = GetTouchEventArgN(touchInfo);
387                 SysTryReturnVoidResult(NID_UI, pEventArg, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
388
389                 publicTouchInfo.Construct(*pEventArg);
390
391                 _Control* pDraggedControl = __pTouchManager->GetTouchControlSource();
392
393                 IEnumeratorT<IEventListener*>* pEnumerator = __impl.GetTouchEventListener()->GetEnumeratorN();
394                 if (pEnumerator)
395                 {
396                         while (pEnumerator->MoveNext() == E_SUCCESS)
397                         {
398                                 IEventListener* pListener = null;
399                                 pEnumerator->GetCurrent(pListener);
400
401                                 ITouchEventListener* pTouchEventListener = dynamic_cast <ITouchEventListener*>(pListener);
402                                 if (pTouchEventListener != null)
403                                 {
404                                         FirePublicListener(*pTouchEventListener, publicTouchInfo);
405
406                                         if (touchInfo.GetTouchStatus() == _TOUCH_RELEASED)
407                                         {
408                                                 if (pDraggedControl == null)    //if exist dragged control, don't send focus event
409                                                 {
410                                                         FireFocusListener(*pTouchEventListener, publicTouchInfo);
411                                                 }
412                                         }
413                                         else if (touchInfo.GetTouchStatus() == _TOUCH_MOVED)
414                                         {
415                                                 FireFocusListener(*pTouchEventListener, publicTouchInfo);
416                                         }
417                                 }
418                         }
419
420                         delete pEnumerator;
421                 }
422
423                 delete pEventArg;
424         }
425
426         bool ProcessTouchDoublePressed(const _TouchInfo& touchinfo)
427         {
428                 if (__pTouchManager->GetPointCount() == 1)
429                 {
430                         __oldPreviousPressedTime = __previousPressedTime;
431                         __previousPressedTime = __currentPressedTime;
432                         __currentPressedTime = touchinfo.GetTimeStamp();
433                         __previousPressedPoint.x = __currentPressedPoint.x;
434                         __previousPressedPoint.y = __currentPressedPoint.y;
435                         __currentPressedPoint.x = touchinfo.GetCurrentPosition().x;
436                         __currentPressedPoint.y = touchinfo.GetCurrentPosition().y;
437
438                         if (Math::Abs(__previousPressedTime - __currentPressedTime) < DOUBLE_PRESS_TIME)
439                         {
440                                 if (Math::Abs(__previousPressedTime - __oldPreviousPressedTime) > DOUBLE_PRESS_TIME)
441                                 {
442                                         if ((Math::Abs(__previousPressedPoint.x - __currentPressedPoint.x) < DOUBLE_PRESS_MOVE_ALLOWANCE)
443                                                 && (Math::Abs(__previousPressedPoint.y - __currentPressedPoint.y) < DOUBLE_PRESS_MOVE_ALLOWANCE))
444                                         {
445                                                 _TouchInfo touchInfo(0, _TOUCH_DOUBLE_PRESSED, __currentPressedPoint, false, 0);
446                                                 ProcessTouchEvent(touchInfo);
447
448                                                 return true;
449                                         }
450                                 }
451                         }
452                 }
453
454                 return false;
455         }
456
457         void FirePublicListener(ITouchEventListener& listener, const TouchEventInfo& touchEventInfo)
458         {
459                 switch (touchEventInfo.GetTouchStatus())
460                 {
461                 case TOUCH_PRESSED:
462                         listener.OnTouchPressed(__public, touchEventInfo.GetCurrentPosition(), touchEventInfo);
463                         break;
464                 case TOUCH_LONG_PRESSED:
465                         listener.OnTouchLongPressed(__public, touchEventInfo.GetCurrentPosition(), touchEventInfo);
466                         break;
467                 case TOUCH_RELEASED:
468                         listener.OnTouchReleased(__public, touchEventInfo.GetCurrentPosition(), touchEventInfo);
469                         break;
470                 case TOUCH_MOVED:
471                         listener.OnTouchMoved(__public, touchEventInfo.GetCurrentPosition(), touchEventInfo);
472                         break;
473                 case TOUCH_DOUBLE_PRESSED:
474                         listener.OnTouchDoublePressed(__public, touchEventInfo.GetCurrentPosition(), touchEventInfo);
475                         break;
476                 case TOUCH_FOCUS_IN:
477                         listener.OnTouchFocusIn(__public, touchEventInfo.GetCurrentPosition(), touchEventInfo);
478                         break;
479                 case TOUCH_FOCUS_OUT:
480                         listener.OnTouchFocusOut(__public, touchEventInfo.GetCurrentPosition(), touchEventInfo);
481                         break;
482                 case TOUCH_CANCELED:
483                         listener.OnTouchCanceled(__public, touchEventInfo.GetCurrentPosition(), touchEventInfo);
484                         break;
485                 default:
486                         break;
487                 }
488         }
489
490         void FireFocusListener(ITouchEventListener& listener, const TouchEventInfo& touchEventInfo)
491         {
492                 _ControlManager* pControlManager = _ControlManager::GetInstance();
493                 SysTryReturnVoidResult(NID_UI, pControlManager, E_SYSTEM, "[E_SYSTEM] System error occurred.");
494
495                 Point screenPoint(__pTouchManager->GetScreenPoint(touchEventInfo.GetPointId()).x,
496                                                   __pTouchManager->GetScreenPoint(touchEventInfo.GetPointId()).y);
497
498                 _Control* pTouchedControl = pControlManager->GetTopmostTouchedControl(screenPoint);
499                 SysTryReturnVoidResult(NID_UI, pTouchedControl, E_INVALID_CONDITION, "[E_INVALID_CONDITION] pTouchedControl is null.");
500
501                 if (__pTouchManager->GetFocusedControlSource() != pTouchedControl)
502                 {
503                         if (&(__core) != pTouchedControl)
504                         {
505                                 if (__pTouchManager->GetFocusedControlSource() == &(__core))
506                                 {
507                                         listener.OnTouchFocusOut(__public, touchEventInfo.GetCurrentPosition(), touchEventInfo);
508                                 }
509                         }
510                         else
511                         {
512                                 listener.OnTouchFocusIn(__public, touchEventInfo.GetCurrentPosition(), touchEventInfo);
513                         }
514
515                         __pTouchManager->SetFocusedControlSource(*pTouchedControl);
516                 }
517         }
518
519         _TouchEventArg* GetTouchEventArgN(const _TouchInfo& touchInfo)
520         {
521                 FloatPoint startPoint;
522
523                 _TouchEventArg* pEventArg = new (std::nothrow) _TouchEventArg(__public, touchInfo.GetTouchStatus());
524                 SysTryReturn(NID_UI, pEventArg, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
525
526                 startPoint.SetPosition(__pTouchManager->GetStartPoint(touchInfo.GetPointId()).x - __core.GetAbsoluteBoundsF(true).x,
527                                                                 __pTouchManager->GetStartPoint(touchInfo.GetPointId()).y - __core.GetAbsoluteBoundsF(true).y);
528
529                 pEventArg->SetTouchPosition(touchInfo.GetPointId(), startPoint.x, startPoint.y,
530                                                                         touchInfo.GetCurrentPosition().x, touchInfo.GetCurrentPosition().y);
531
532                 // need to flick distance setting
533
534                 return pEventArg;
535         }
536
537 private:
538         static const int DOUBLE_PRESS_TIME = 500;
539         static const int DOUBLE_PRESS_MOVE_ALLOWANCE = 10;
540
541         _GroupedListViewImpl& __impl;
542         _Control& __core;
543         Control& __public;
544         _TouchManager* __pTouchManager;
545
546         unsigned int __oldPreviousPressedTime;
547         unsigned int __previousPressedTime;
548         unsigned int __currentPressedTime;
549         Tizen::Graphics::FloatPoint __previousPressedPoint;
550         Tizen::Graphics::FloatPoint __currentPressedPoint;
551         _TouchLongPressGestureDetector* __pLongPressedGesture;
552 };
553
554 _GroupedListViewImpl*
555 _GroupedListViewImpl::GetInstance(GroupedListView& groupedListView)
556 {
557         return static_cast <_GroupedListViewImpl*>(groupedListView._pControlImpl);
558 }
559
560 const _GroupedListViewImpl*
561 _GroupedListViewImpl::GetInstance(const GroupedListView& groupedListView)
562 {
563         return static_cast <const _GroupedListViewImpl*>(groupedListView._pControlImpl);
564 }
565
566 _GroupedListViewImpl::_GroupedListViewImpl(GroupedListView* pGroupedList, _TableView* pCore)
567         : _ControlImpl(pGroupedList, pCore)
568         , __pListItemEvent(null)
569         , __pLinkEvent(null)
570         , __pScrollEvent(null)
571         , __pFastScrollEvent(null)
572         , __pEmptyBitmap(null)
573         , __pEmptyText(null)
574         , __pAccessibilityElement(null)
575         , __redrawListView(true)
576         , __isOrientationChanged(false)
577         , __needReloadItems(false)
578         , __pPropagatedTouchEventListener(null)
579 {
580         GET_COLOR_CONFIG(TABLEVIEW::EMPTY_CONTENTS_TEXT_NORMAL, __emptyTextColor);
581 }
582
583 _GroupedListViewImpl::~_GroupedListViewImpl()
584 {
585         delete __pListItemEvent;
586         __pListItemEvent = null;
587
588         delete __pLinkEvent;
589         __pLinkEvent = null;
590
591         delete __pScrollEvent;
592         __pScrollEvent = null;
593
594         delete __pFastScrollEvent;
595         __pFastScrollEvent = null;
596
597         if (__pEmptyBitmap != null)
598         {
599                 GetCore().DetachChild(*__pEmptyBitmap);
600
601                 delete __pEmptyBitmap;
602                 __pEmptyBitmap = null;
603         }
604
605         if (__pEmptyText != null)
606         {
607                 GetCore().DetachChild(*__pEmptyText);
608
609                 delete __pEmptyText;
610                 __pEmptyText = null;
611         }
612
613         _AccessibilityContainer* pContainer = GetCore().GetAccessibilityContainer();
614
615         if ((__pAccessibilityElement != null) && (pContainer != null))
616         {
617                 pContainer->RemoveElement(__pAccessibilityElement);
618         }
619
620         delete __pPropagatedTouchEventListener;
621         __pPropagatedTouchEventListener = null;
622 }
623
624 const char*
625 _GroupedListViewImpl::GetPublicClassName(void) const
626 {
627         return "Tizen::Ui::Controls::GroupedListView";
628 }
629
630 const GroupedListView&
631 _GroupedListViewImpl::GetPublic(void) const
632 {
633         return static_cast <const GroupedListView&>(_ControlImpl::GetPublic());
634 }
635
636 GroupedListView&
637 _GroupedListViewImpl::GetPublic(void)
638 {
639         return static_cast <GroupedListView&>(_ControlImpl::GetPublic());
640 }
641
642 const _TableView&
643 _GroupedListViewImpl::GetCore(void) const
644 {
645         return static_cast <const _TableView&>(_ControlImpl::GetCore());
646 }
647
648 _TableView&
649 _GroupedListViewImpl::GetCore(void)
650 {
651         return static_cast <_TableView&>(_ControlImpl::GetCore());
652 }
653
654 _GroupedListViewImpl*
655 _GroupedListViewImpl::CreateGroupedListViewImplN(GroupedListView* pControl, GroupedListViewStyle style, bool itemDivider, ListScrollStyle scrollStyle)
656 {
657         result r = E_SUCCESS;
658         TableViewScrollBarStyle scrollBarStyle;
659
660         switch (scrollStyle)
661         {
662         case SCROLL_STYLE_FADE_OUT:
663                 scrollBarStyle = TABLE_VIEW_SCROLL_BAR_STYLE_FADE_OUT;
664                 break;
665
666         case SCROLL_STYLE_FIXED:
667                 scrollBarStyle = TABLE_VIEW_SCROLL_BAR_STYLE_FIXED;
668                 break;
669
670         case SCROLL_STYLE_FAST_SCROLL:
671                 scrollBarStyle = TABLE_VIEW_SCROLL_BAR_STYLE_FAST_SCROLL;
672                 break;
673
674         case SCROLL_STYLE_JUMP_TO_TOP:
675                 scrollBarStyle = TABLE_VIEW_SCROLL_BAR_STYLE_JUMP_TO_TOP;
676                 break;
677
678         case SCROLL_STYLE_THUMB:
679                 scrollBarStyle = TABLE_VIEW_SCROLL_BAR_STYLE_THUMB;
680                 break;
681
682         case SCROLL_STYLE_FAST_SCROLL_FIXED:
683                 scrollBarStyle = TABLE_VIEW_SCROLL_BAR_STYLE_FAST_SCROLL_FIXED;
684                 break;
685
686         default:
687                 scrollBarStyle = TABLE_VIEW_SCROLL_BAR_STYLE_NONE;
688                 break;
689         }
690
691         TableViewStyle tableViewStyle = ((style == GROUPED_LIST_VIEW_STYLE_SECTION) ? TABLE_VIEW_STYLE_SECTION : TABLE_VIEW_STYLE_GROUPED);
692
693         _TableView* pCore = _TableView::CreateTableViewN(tableViewStyle, itemDivider, scrollBarStyle);
694         SysTryReturn(NID_UI_CTRL, (pCore != null), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
695
696         _GroupedListViewImpl* pImpl = new (std::nothrow) _GroupedListViewImpl(pControl, pCore);
697
698         r = CheckConstruction(pCore, pImpl);
699         SysTryReturn(NID_UI_CTRL, (r == E_SUCCESS), null, r, "[%s] Propagating.", GetErrorMessage(GetLastResult()));
700
701         pImpl->__pPropagatedTouchEventListener = new (std::nothrow) _GroupedListViewPropagatedTouchEventListener(*pImpl);
702
703         if (pImpl->__pPropagatedTouchEventListener != null)
704         {
705                 pCore->SetPropagatedTouchEventListener(pImpl->__pPropagatedTouchEventListener);
706         }
707
708         return pImpl;
709 }
710
711 result
712 _GroupedListViewImpl::SetItemProvider(IGroupedListViewItemProvider& provider)
713 {
714         result r = E_SUCCESS;
715
716         _GroupedListViewItemProviderAdaptor* pProviderAdaptor =
717                         static_cast <_GroupedListViewItemProviderAdaptor*>(GetCore().GetItemProviderAdaptor());
718
719         if (pProviderAdaptor != null)
720         {
721                 IGroupedListViewItemProvider* pProvider = pProviderAdaptor->GetItemProvider();
722                 if (&provider == pProvider)
723                 {
724                         return r;
725                 }
726         }
727
728         float itemWidth = GetBoundsF().width;
729
730         if (GetCore().GetTableViewStyle() == TABLE_VIEW_STYLE_SECTION)
731         {
732                 float margin = 0.0f;
733                 GET_SHAPE_CONFIG(TABLEVIEW::GROUPITEM_LEFT_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, margin);
734
735                 itemWidth -= (margin * 2.0f);
736         }
737
738         if (pProviderAdaptor == null)
739         {
740                 pProviderAdaptor = new (std::nothrow) _GroupedListViewItemProviderAdaptor(provider);
741                 SysTryReturn(NID_UI_CTRL, (pProviderAdaptor != null), E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
742                                 "[E_OUT_OF_MEMORY] Memory allocation failed.");
743
744                 pProviderAdaptor->SetListViewItemEventListener(*this);
745
746                 r = pProviderAdaptor->SetListWidth(itemWidth);
747                 GetCore().SetItemProviderAdaptor(pProviderAdaptor);
748         }
749         else
750         {
751                 pProviderAdaptor->SetItemProvider(provider);
752                 r = pProviderAdaptor->SetListWidth(itemWidth);
753
754                 UpdateList();
755         }
756
757         __redrawListView = true;
758
759         SetLastResultReturn(r);
760 }
761
762 result
763 _GroupedListViewImpl::SetItemProvider(IGroupedListViewItemProviderF& provider)
764 {
765         result r = E_SUCCESS;
766
767         _GroupedListViewItemProviderAdaptor* pProviderAdaptor =
768                         static_cast <_GroupedListViewItemProviderAdaptor*>(GetCore().GetItemProviderAdaptor());
769
770         if (pProviderAdaptor != null)
771         {
772                 IGroupedListViewItemProviderF* pProvider = pProviderAdaptor->GetItemProviderF();
773                 if (&provider == pProvider)
774                 {
775                         return r;
776                 }
777         }
778
779         float itemWidth = GetBoundsF().width;
780
781         if (GetCore().GetTableViewStyle() == TABLE_VIEW_STYLE_SECTION)
782         {
783                 float margin = 0.0f;
784                 GET_SHAPE_CONFIG(TABLEVIEW::GROUPITEM_LEFT_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, margin);
785
786                 itemWidth -= (margin * 2.0f);
787         }
788
789         if (pProviderAdaptor == null)
790         {
791                 pProviderAdaptor = new (std::nothrow) _GroupedListViewItemProviderAdaptor(provider);
792                 SysTryReturn(NID_UI_CTRL, (pProviderAdaptor != null), E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
793                                 "[E_OUT_OF_MEMORY] Memory allocation failed.");
794
795                 pProviderAdaptor->SetListViewItemEventListener(*this);
796
797                 r = pProviderAdaptor->SetListWidth(itemWidth);
798                 GetCore().SetItemProviderAdaptor(pProviderAdaptor);
799         }
800         else
801         {
802                 pProviderAdaptor->SetItemProvider(provider);
803                 r = pProviderAdaptor->SetListWidth(itemWidth);
804
805                 UpdateList();
806         }
807
808         __redrawListView = true;
809
810         SetLastResultReturn(r);
811
812         return E_SUCCESS;
813 }
814
815 void
816 _GroupedListViewImpl::AddGroupedListViewItemEventListener(IGroupedListViewItemEventListener& listener)
817 {
818         result r = E_SUCCESS;
819
820         if (__pListItemEvent == null)
821         {
822                 __pListItemEvent = new (std::nothrow) _ListItemEvent();
823                 SysTryReturnVoidResult(NID_UI_CTRL, (__pListItemEvent != null), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
824
825                 r = __pListItemEvent->Construct(GetPublic(), CLASSNAME_GROUPEDLISTVIEW);
826                 SysTryReturnVoidResult(NID_UI_CTRL, (r == E_SUCCESS), E_SYSTEM, "[E_SYSTEM] Unable to construct Item Event.");
827         }
828
829         __pListItemEvent->AddListener(listener);
830
831         r = GetCore().AddGroupedTableViewItemEventListener(*this);
832
833         SetLastResult(r);
834 }
835
836 void
837 _GroupedListViewImpl::RemoveGroupedListViewItemEventListener(IGroupedListViewItemEventListener& listener)
838 {
839         result r = E_SUCCESS;
840
841         if (__pListItemEvent != null)
842         {
843                 r = __pListItemEvent->RemoveListener(listener);
844         }
845
846         SetLastResult(r);
847 }
848
849 void
850 _GroupedListViewImpl::AddFastScrollListener(IFastScrollListener& listener)
851 {
852         result r = E_SUCCESS;
853
854         if (__pFastScrollEvent == null)
855         {
856                 __pFastScrollEvent = new (std::nothrow) _FastScrollEvent();
857                 SysTryReturnVoidResult(NID_UI_CTRL, (__pFastScrollEvent != null), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
858
859                 r = __pFastScrollEvent->Construct(GetPublic());
860                 SysTryReturnVoidResult(NID_UI_CTRL, (r == E_SUCCESS), E_SYSTEM, "[E_SYSTEM] Unable to construct FastScroll Event.");
861         }
862
863         __pFastScrollEvent->AddListener(listener);
864
865         r = GetCore().AddFastScrollListener(*this);
866
867         SetLastResult(r);
868 }
869
870 void
871 _GroupedListViewImpl::RemoveFastScrollListener(IFastScrollListener& listener)
872 {
873         result r = E_SUCCESS;
874
875         if (__pFastScrollEvent != null)
876         {
877                 r = __pFastScrollEvent->RemoveListener(listener);
878         }
879
880         SetLastResult(r);
881 }
882
883 void
884 _GroupedListViewImpl::AddScrollEventListener(IScrollEventListener& listener)
885 {
886         result r = E_SUCCESS;
887
888         if (__pScrollEvent == null)
889         {
890                 __pScrollEvent = new (std::nothrow) _ScrollEvent();
891                 SysTryReturnVoidResult(NID_UI_CTRL, (__pScrollEvent != null), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
892
893                 r = __pScrollEvent->Construct(GetPublic());
894                 SysTryReturnVoidResult(NID_UI_CTRL, (r == E_SUCCESS), E_SYSTEM, "[E_SYSTEM] Unable to construct Scroll Event.");
895         }
896
897         __pScrollEvent->AddListener(listener);
898
899         GetCore().AddScrollEventListener(*this);
900
901         SetLastResult(r);
902 }
903
904 void
905 _GroupedListViewImpl::AddScrollEventListener(IScrollEventListenerF& listener)
906 {
907         result r = E_SUCCESS;
908
909         if (__pScrollEvent == null)
910         {
911                 __pScrollEvent = new (std::nothrow) _ScrollEvent();
912                 SysTryReturnVoidResult(NID_UI_CTRL, (__pScrollEvent != null), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
913
914                 r = __pScrollEvent->Construct(GetPublic());
915                 SysTryReturnVoidResult(NID_UI_CTRL, (r == E_SUCCESS), E_SYSTEM, "[E_SYSTEM] Unable to construct Scroll Event.");
916         }
917
918         __pScrollEvent->AddListener(listener);
919
920         GetCore().AddScrollEventListener(*this);
921
922         SetLastResult(r);
923 }
924
925 void
926 _GroupedListViewImpl::RemoveScrollEventListener(IScrollEventListener& listener)
927 {
928         result r = E_SUCCESS;
929
930         if (__pScrollEvent != null)
931         {
932                 r = __pScrollEvent->RemoveListener(listener);
933         }
934
935         SetLastResult(r);
936 }
937
938 void
939 _GroupedListViewImpl::RemoveScrollEventListener(IScrollEventListenerF& listener)
940 {
941         result r = E_SUCCESS;
942
943         if (__pScrollEvent != null)
944         {
945                 r = __pScrollEvent->RemoveListener(listener);
946         }
947
948         SetLastResult(r);
949 }
950
951 void
952 _GroupedListViewImpl::AddUiLinkEventListener(const IUiLinkEventListener& listener)
953 {
954         result r = E_SUCCESS;
955
956         if (__pLinkEvent == null)
957         {
958                 __pLinkEvent = _PublicLinkEvent::CreateInstanceN(GetPublic());
959                 SysTryReturnVoidResult(NID_UI, (__pLinkEvent != null), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
960         }
961
962         r = __pLinkEvent->AddListener(listener);
963
964         SetLastResult(r);
965 }
966
967 void
968 _GroupedListViewImpl::RemoveUiLinkEventListener(const IUiLinkEventListener& listener)
969 {
970         result r = E_SUCCESS;
971
972         if (__pLinkEvent != null)
973         {
974                 r = __pLinkEvent->RemoveListener(listener);
975         }
976
977         SetLastResult(r);
978 }
979
980 result
981 _GroupedListViewImpl::SetSweepEnabled(bool enable)
982 {
983         GetCore().SetSweepEnabled(enable);
984
985         SetLastResultReturn(E_SUCCESS);
986 }
987
988 result
989 _GroupedListViewImpl::SetFastScrollIndex(const String& text, bool useSearchIcon)
990 {
991         result r = GetCore().SetFastScrollIndex(text, useSearchIcon);
992         SysTryReturn(NID_UI_CTRL, (r == E_SUCCESS) || (r == E_SYSTEM), E_INVALID_STATE, E_INVALID_STATE,
993                         "[E_INVALID_STATE] This instance is in an invalid state.");
994
995         SetLastResultReturn(r);
996 }
997
998 result
999 _GroupedListViewImpl::GetTopDrawnItemIndex(int& groupIndex, int& itemIndex) const
1000 {
1001         result r = E_SUCCESS;
1002         r = GetCore().GetTopDrawnItemIndex(groupIndex, itemIndex);
1003         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, E_SYSTEM, "A system error has occurred. Failed to get top drawn item index.");
1004
1005         return r;
1006 }
1007
1008 result
1009 _GroupedListViewImpl::GetBottomDrawnItemIndex(int& groupIndex, int& itemIndex) const
1010 {
1011         result r = E_SUCCESS;
1012         r = GetCore().GetBottomDrawnItemIndex(groupIndex, itemIndex);
1013         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, E_SYSTEM, "A system error has occurred. Failed to get bottom drawn item index.");
1014
1015         return r;
1016 }
1017
1018 result
1019 _GroupedListViewImpl::ScrollToItem(int groupIndex, int itemIndex, ListScrollItemAlignment itemAlignment)
1020 {
1021         result r = E_SUCCESS;
1022
1023         if (itemAlignment == LIST_SCROLL_ITEM_ALIGNMENT_TOP)
1024         {
1025                 r = GetCore().SetTopDrawnItemIndex(groupIndex, itemIndex);
1026         }
1027         else if (itemAlignment == LIST_SCROLL_ITEM_ALIGNMENT_BOTTOM)
1028         {
1029                 r = GetCore().SetBottomDrawnItemIndex(groupIndex, itemIndex);
1030         }
1031         else
1032         {
1033                 SysTryReturn(NID_UI_CTRL, false, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1034                                 "[E_OUT_OF_RANGE] The specified itemAlignment is out of range.");
1035         }
1036
1037         SetLastResultReturn(r);
1038 }
1039
1040 result
1041 _GroupedListViewImpl::SetItemChecked(int groupIndex, int itemIndex, bool check)
1042 {
1043         return GetCore().SetItemChecked(groupIndex, itemIndex, check);
1044 }
1045
1046 bool
1047 _GroupedListViewImpl::IsItemChecked(int groupIndex, int itemIndex) const
1048 {
1049         return GetCore().IsItemChecked(groupIndex, itemIndex);
1050 }
1051
1052 result
1053 _GroupedListViewImpl::SetItemEnabled(int groupIndex, int itemIndex, bool enable)
1054 {
1055         return GetCore().SetItemEnabled(groupIndex, itemIndex, enable);
1056 }
1057
1058 bool
1059 _GroupedListViewImpl::IsItemEnabled(int groupIndex, int itemIndex) const
1060 {
1061         return GetCore().IsItemEnabled(groupIndex, itemIndex);
1062 }
1063
1064 int
1065 _GroupedListViewImpl::GetGroupCount(void) const
1066 {
1067         return GetCore().GetGroupCount();
1068 }
1069
1070 int
1071 _GroupedListViewImpl::GetItemCountAt(int groupIndex) const
1072 {
1073         return GetCore().GetItemCountAt(groupIndex);
1074 }
1075
1076 result
1077 _GroupedListViewImpl::ShowItemDescriptionText(int groupIndex, int itemIndex)
1078 {
1079         return SetItemDescriptionTextShowState(groupIndex, itemIndex, true);
1080 }
1081
1082 result
1083 _GroupedListViewImpl::HideItemDescriptionText(int groupIndex, int itemIndex)
1084 {
1085         return SetItemDescriptionTextShowState(groupIndex, itemIndex, false);
1086 }
1087
1088 result
1089 _GroupedListViewImpl::SetItemDescriptionTextShowState(int groupIndex, int itemIndex, bool show)
1090 {
1091         result r = E_SUCCESS;
1092
1093         SysTryReturn(NID_UI_CTRL, (groupIndex >= 0) && (groupIndex < GetGroupCount()), E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1094                         "[E_OUT_OF_RANGE] The specified groupIndex is out of range.");
1095
1096         SysTryReturn(NID_UI_CTRL, (itemIndex >= 0) && (itemIndex < GetItemCountAt(groupIndex)), E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1097                         "[E_OUT_OF_RANGE] The specified itemIndex is out of range.");
1098
1099         _GroupedListViewItemProviderAdaptor* pProviderAdaptor =
1100                         static_cast <_GroupedListViewItemProviderAdaptor*>(GetCore().GetItemProviderAdaptor());
1101         SysTryReturn(NID_UI_CTRL, (pProviderAdaptor != null), E_SYSTEM, E_SYSTEM, "[E_SYSTEM] _GroupedListItemProviderAdaptor is not set.");
1102
1103         // Save description text show state to provider adaptor
1104         pProviderAdaptor->SetDescriptionTextShowState(groupIndex, itemIndex, show);
1105
1106         if (GetCore().FindItem(groupIndex, itemIndex) != null)
1107         {
1108                 r = GetCore().RefreshTableView(groupIndex, itemIndex, TABLE_VIEW_REFRESH_TYPE_ITEM_MODIFY);
1109         }
1110
1111         SetLastResultReturn(r);
1112 }
1113
1114 result
1115 _GroupedListViewImpl::RefreshList(int groupIndex, int itemIndex, ListRefreshType type)
1116 {
1117         result r = E_SUCCESS;
1118
1119         if (__needReloadItems)
1120         {
1121                 return r;
1122         }
1123
1124         int groupCount = GetCore().GetGroupCount();
1125         int itemCount = GetCore().GetItemCountAt(groupIndex);
1126
1127         if ((groupIndex < 0) || (groupIndex > groupCount) || (itemIndex < -1) || (itemIndex > itemCount) ||
1128                         ((type != LIST_REFRESH_TYPE_ITEM_ADD) && (itemIndex == itemCount)))
1129         {
1130                 SysLogException(NID_UI_CTRL, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The index is out of range.");
1131                 return E_OUT_OF_RANGE;
1132         }
1133
1134         if (type == LIST_REFRESH_TYPE_ITEM_MODIFY)
1135         {
1136                 if (IsContextItemOpened(groupIndex, itemIndex))
1137                 {
1138                         CloseContextItem(groupIndex, itemIndex);
1139                 }
1140
1141                 int topGroupIndex = -1;
1142                 int topItemIndex = -1;
1143                 int bottomGroupIndex = -1;
1144                 int bottomItemIndex = -1;
1145
1146                 GetCore().GetFirstLoadedItemIndex(topGroupIndex, topItemIndex);
1147                 GetCore().GetLastLoadedItemIndex(bottomGroupIndex, bottomItemIndex);
1148
1149                 if ((topGroupIndex > groupIndex) || (bottomGroupIndex < groupIndex) ||
1150                                 ((topGroupIndex == groupIndex) && (topItemIndex > itemIndex)) ||
1151                                 ((bottomGroupIndex == groupIndex) && (bottomItemIndex < itemIndex)))
1152                 {
1153                         // not yet loaded item
1154                         SetLastResultReturn(r);
1155                 }
1156                 else
1157                 {
1158                         _ListViewItem* pListViewItem = static_cast<_ListViewItem*>(GetCore().FindItem(groupIndex, itemIndex));
1159                         _ListViewItemStatus itemStatus;
1160                         memset(&itemStatus, 0, sizeof(_ListViewItemStatus));
1161                         bool needChangeEventTarget = false;
1162                         bool itemFocused = false;
1163
1164                         if (pListViewItem != null && pListViewItem->IsItemSelected())
1165                         {
1166                                 needChangeEventTarget = true;
1167                         }
1168
1169                         if (pListViewItem != null && pListViewItem->GetRootWindow() && pListViewItem->IsFocusModeStateEnabled()
1170                                         && pListViewItem->IsFocused() && pListViewItem->GetRootWindow()->IsActivated())
1171                         {
1172                                 itemFocused = true;
1173                         }
1174
1175                         if (needChangeEventTarget && (pListViewItem != null))
1176                         {
1177                                 pListViewItem->GetCurrentStatus(itemStatus);
1178                                 pListViewItem = null;
1179                         }
1180
1181                         // item unload
1182                         GetCore().UnloadItem(groupIndex, itemIndex);
1183                         // item load
1184                         pListViewItem = static_cast<_ListViewItem*>(GetCore().LoadItem(groupIndex, itemIndex));
1185
1186                         if (needChangeEventTarget && (pListViewItem != null))
1187                         {
1188                                 pListViewItem->SetCurrentStatus(itemStatus);
1189
1190                                 _Control* pTarget = static_cast<_Control*>(pListViewItem);
1191
1192                                 for (int i = 0; i < pListViewItem->GetChildCount(); i++)
1193                                 {
1194                                         if (pListViewItem->GetChild(i)->GetBoundsF().Contains(itemStatus.currentTouchPosition))
1195                                         {
1196                                                 pTarget = pListViewItem->GetChild(i);
1197                                         }
1198                                 }
1199
1200                                 // change touch event target
1201                                 pTarget->SetChangingEventTarget(true);
1202                                 _TouchManager::GetInstance()->SetChangedTouchableTarget(pTarget);
1203                         }
1204
1205                         if (itemFocused && pListViewItem && pListViewItem->IsFocusable()
1206                                         && pListViewItem->GetEnableState() && pListViewItem->GetVisibleState())
1207                         {
1208                                 pListViewItem->SetFocused(true);
1209                                 pListViewItem->DrawFocus();
1210                         }
1211                 }
1212         }
1213         else
1214         {
1215                 r = GetCore().RefreshTableView(groupIndex, itemIndex, static_cast<TableViewRefreshType>(type));
1216         }
1217
1218         CheckEmptyListShowState();
1219
1220         Draw();
1221         Show();
1222
1223         SetLastResultReturn(r);
1224 }
1225
1226 result
1227 _GroupedListViewImpl::RefreshList(int groupIndex, int itemIndex, int elementId)
1228 {
1229         if ((groupIndex < 0) || (groupIndex >= GetCore().GetGroupCount()) || (itemIndex < 0) || (itemIndex >= GetCore().GetItemCountAt(groupIndex)))
1230         {
1231                 return E_OUT_OF_RANGE;
1232         }
1233
1234         result r = E_SUCCESS;
1235         _ListViewItem* pListViewItem = static_cast<_ListViewItem*>(GetCore().FindItem(groupIndex, itemIndex));
1236
1237         if (pListViewItem != null)
1238         {
1239                 r = (pListViewItem->RefreshElement(elementId)) ? E_SUCCESS : E_OUT_OF_RANGE;
1240         }
1241
1242         SetLastResultReturn(r);
1243 }
1244
1245 result
1246 _GroupedListViewImpl::UpdateList(bool isRestoreAnnexFocusValue)
1247 {
1248         __needReloadItems = true;
1249
1250         result r = GetCore().UpdateTableView(isRestoreAnnexFocusValue);
1251
1252         CheckEmptyListShowState();
1253
1254         Invalidate(true);
1255
1256         // API versioning for initial Show() operation
1257         if (Tizen::App::_AppInfo::GetApiVersion() == _API_VERSION_2_0 && Tizen::App::_AppInfo::IsOspCompat())
1258         {
1259                 Show();
1260         }
1261
1262         __needReloadItems = false;
1263
1264         SetLastResultReturn(r);
1265 }
1266
1267 void
1268 _GroupedListViewImpl::SetItemNeedsLazyDeletion(_ListViewItem* pItem)
1269 {
1270         _GroupedListViewItemProviderAdaptor* pProviderAdaptor =
1271                         static_cast <_GroupedListViewItemProviderAdaptor*>(GetCore().GetItemProviderAdaptor());
1272
1273         if (pProviderAdaptor != null)
1274         {
1275                 pProviderAdaptor->SetItemNeedsLazyDeletion(pItem);
1276         }
1277 }
1278
1279 result
1280 _GroupedListViewImpl::GetItemIndexFromPosition(const FloatPoint& position, int& groupIndex, int& itemIndex) const
1281 {
1282         result r = GetCore().GetItemIndexFromPosition(position, groupIndex, itemIndex);
1283
1284         SysTryReturn(NID_UI_CTRL, (r == E_SUCCESS), E_SYSTEM, E_SYSTEM, "[E_SYSTEM] There is no item at the specified position.");
1285
1286         SetLastResultReturn(r);
1287 }
1288
1289 result
1290 _GroupedListViewImpl::GetItemIndexFromPosition(const FloatPoint& position, int& groupIndex, int& itemIndex, int& elementId) const
1291 {
1292         elementId = -1;
1293
1294         result r =  GetCore().GetItemIndexFromPosition(position, groupIndex, itemIndex);
1295         SysTryReturn(NID_UI_CTRL, (r == E_SUCCESS), E_SYSTEM, E_SYSTEM, "[E_SYSTEM] There is no item at the specified position.");
1296
1297         _ListViewItem* pListViewItem = static_cast<_ListViewItem*>(GetCore().FindItem(groupIndex, itemIndex));
1298
1299         if (pListViewItem != null)
1300         {
1301                 FloatPoint originPosition = pListViewItem->GetPositionF();
1302                 originPosition.y -= GetCore().GetScrollPosition();
1303
1304                 elementId = pListViewItem->GetElementIdFromPosition(FloatPoint(position.x - originPosition.x, position.y - originPosition.y));
1305         }
1306
1307         SetLastResultReturn(r);
1308 }
1309
1310 result
1311 _GroupedListViewImpl::SetSectionColor(const Color& color)
1312 {
1313         return GetCore().SetSectionColor(color);
1314 }
1315
1316 Color
1317 _GroupedListViewImpl::GetSectionColor(void) const
1318 {
1319         return GetCore().GetSectionColor();
1320 }
1321
1322 result
1323 _GroupedListViewImpl::SetItemDividerColor(const Color& color)
1324 {
1325         return GetCore().SetItemDividerColor(color);
1326 }
1327
1328 Color
1329 _GroupedListViewImpl::GetItemDividerColor(void) const
1330 {
1331         return GetCore().GetItemDividerColor();
1332 }
1333
1334 void
1335 _GroupedListViewImpl::SetListBackgroundColor(const Color& color)
1336 {
1337         SetBackgroundColor(color);
1338 }
1339
1340 result
1341 _GroupedListViewImpl::SetBackgroundBitmap(const Bitmap* pBitmap)
1342 {
1343         GetCore().SetBackgroundBitmap(const_cast<Bitmap*>(pBitmap));
1344         GetCore().SetBackgroundBitmapStretch(true);
1345
1346         SetLastResultReturn(E_SUCCESS);
1347 }
1348
1349 result
1350 _GroupedListViewImpl::SetBitmapOfEmptyList(const Bitmap* pBitmap)
1351 {
1352         if (pBitmap == null)
1353         {
1354                 if (__pEmptyBitmap != null)
1355                 {
1356                         GetCore().DetachChild(*__pEmptyBitmap);
1357
1358                         delete __pEmptyBitmap;
1359                         __pEmptyBitmap = null;
1360                 }
1361         }
1362         else
1363         {
1364                 if (__pEmptyBitmap == null)
1365                 {
1366                         __pEmptyBitmap = _Label::CreateLabelN();
1367                         SysTryReturn(NID_UI_CTRL, (__pEmptyBitmap != null), E_SYSTEM, E_SYSTEM, "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1368
1369                         __pEmptyBitmap->SetVisibleState(false);
1370                         __pEmptyBitmap->SetMargin(0.0f, 0.0f);
1371
1372                         GetCore().AttachChild(*__pEmptyBitmap);
1373                 }
1374
1375                 __pEmptyBitmap->SetSize(FloatDimension(pBitmap->GetWidthF(), pBitmap->GetHeightF()));
1376                 __pEmptyBitmap->SetBackgroundColor(Color(0, 0, 0, 0));
1377                 __pEmptyBitmap->SetBackgroundBitmap(*pBitmap);
1378         }
1379
1380         AdjustLayoutOfEmptyList();
1381
1382         SetLastResultReturn(E_SUCCESS);
1383 }
1384
1385 result
1386 _GroupedListViewImpl::SetTextOfEmptyList(const String& text)
1387 {
1388         if (text.IsEmpty())
1389         {
1390                 if (__pEmptyText != null)
1391                 {
1392                         GetCore().DetachChild(*__pEmptyText);
1393
1394                         delete __pEmptyText;
1395                         __pEmptyText = null;
1396                 }
1397         }
1398         else
1399         {
1400                 if (__pEmptyText == null)
1401                 {
1402                         __pEmptyText = _Label::CreateLabelN();
1403                         SysTryReturn(NID_UI_CTRL, (__pEmptyText != null), E_SYSTEM, E_SYSTEM, "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1404
1405                         __pEmptyText->SetVisibleState(false);
1406                         __pEmptyText->SetMargin(0.0f, 0.0f);
1407
1408                         GetCore().AttachChild(*__pEmptyText);
1409                 }
1410
1411                 TextObject* pText = new (std::nothrow) TextObject;
1412                 SysTryReturn(NID_UI_CTRL, (pText != null), E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1413
1414                 pText->Construct();
1415
1416                 TextSimple* pSimpleText = new (std::nothrow) TextSimple(const_cast <wchar_t*>(text.GetPointer()), text.GetLength());
1417                 SysTryReturn(NID_UI_CTRL, (pSimpleText != null), E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1418                 pText->AppendElement(*pSimpleText);
1419
1420                 float fontSize = 0.0f;
1421                 GET_SHAPE_CONFIG(LISTVIEW::EMPTY_LIST_TEXT_HEIGHT, _CONTROL_ORIENTATION_PORTRAIT, fontSize);
1422
1423                 Font font;
1424                 font.Construct(GetFont(), FONT_STYLE_PLAIN, fontSize);
1425                 pText->SetFont(&font, 0, pText->GetTextLength());
1426
1427                 FloatDimension listDimension = GetCore().GetSizeF();
1428
1429                 pText->SetBounds(FloatRectangle(0.0f, 0.0f, listDimension.width, 1.0f));
1430                 pText->Compose();
1431
1432                 FloatDimension labelDimension = pText->GetTextExtentF(0, pText->GetTextLength());
1433                 labelDimension.height = pText->GetTotalHeightF();
1434
1435                 if (labelDimension.width > listDimension.width)
1436                 {
1437                         pText->SetBounds(FloatRectangle(0.0f, 0.0f, listDimension.width, 1.0f));
1438                         pText->Compose();
1439
1440                         float labelHeight = pText->GetTotalHeightF();
1441
1442                         labelDimension.width = listDimension.width;
1443                         labelDimension.height = ((listDimension.height < labelHeight) ? listDimension.height : labelHeight);
1444                 }
1445
1446                 delete pText;
1447
1448                 __pEmptyText->SetSize(labelDimension);
1449                 __pEmptyText->SetBackgroundColor(Color(0, 0, 0, 0));
1450                 __pEmptyText->SetMargin(0.0f, 0.0f, 0.0f, 0.0f);
1451                 __pEmptyText->SetTextColor(__emptyTextColor);
1452                 __pEmptyText->SetTextConfig(fontSize, LABEL_TEXT_STYLE_NORMAL);
1453                 __pEmptyText->SetText(text);
1454         }
1455
1456         AdjustLayoutOfEmptyList();
1457
1458         SetLastResultReturn(E_SUCCESS);
1459 }
1460
1461 String
1462 _GroupedListViewImpl::GetTextOfEmptyList(void) const
1463 {
1464         return ((__pEmptyText != null) ? __pEmptyText->GetText() : String());
1465 }
1466
1467 result
1468 _GroupedListViewImpl::SetTextColorOfEmptyList(const Color& color)
1469 {
1470         __emptyTextColor = color;
1471
1472         if (__pEmptyText != null)
1473         {
1474                 __pEmptyText->SetTextColor(color);
1475         }
1476
1477         SetLastResultReturn(E_SUCCESS);
1478 }
1479
1480 Color
1481 _GroupedListViewImpl::GetTextColorOfEmptyList(void) const
1482 {
1483         return __emptyTextColor;
1484 }
1485
1486 result
1487 _GroupedListViewImpl::ExpandGroup(int groupIndex)
1488 {
1489         SysTryReturn(NID_UI_CTRL, (GetCore().GetTableViewStyle() == TABLE_VIEW_STYLE_GROUPED), E_INVALID_OPERATION, E_INVALID_OPERATION,
1490                         "[E_INVALID_OPERATION] The control should be indexed style.");
1491
1492         return GetCore().ExpandGroup(groupIndex);
1493 }
1494
1495 result
1496 _GroupedListViewImpl::CollapseGroup(int groupIndex)
1497 {
1498         SysTryReturn(NID_UI_CTRL, (GetCore().GetTableViewStyle() == TABLE_VIEW_STYLE_GROUPED), E_INVALID_OPERATION, E_INVALID_OPERATION,
1499                         "[E_INVALID_OPERATION] The control should be indexed style.");
1500
1501         return GetCore().CollapseGroup(groupIndex);
1502 }
1503
1504 bool
1505 _GroupedListViewImpl::IsGroupExpanded(int groupIndex) const
1506 {
1507         return GetCore().IsGroupExpanded(groupIndex);
1508 }
1509
1510 result
1511 _GroupedListViewImpl::ExpandAllGroups(void)
1512 {
1513         SysTryReturn(NID_UI_CTRL, (GetCore().GetTableViewStyle() == TABLE_VIEW_STYLE_GROUPED), E_INVALID_OPERATION, E_INVALID_OPERATION,
1514                         "[E_INVALID_OPERATION] The control should be indexed style.");
1515
1516         return GetCore().ExpandAllGroup(true);
1517 }
1518
1519 result
1520 _GroupedListViewImpl::CollapseAllGroups(void)
1521 {
1522         SysTryReturn(NID_UI_CTRL, (GetCore().GetTableViewStyle() == TABLE_VIEW_STYLE_GROUPED), E_INVALID_OPERATION, E_INVALID_OPERATION,
1523                         "[E_INVALID_OPERATION] The control should be indexed style.");
1524
1525         return GetCore().CollapseAllGroup(true);
1526 }
1527
1528 void
1529 _GroupedListViewImpl::CheckEmptyListShowState(void)
1530 {
1531         bool isEmpty = (GetGroupCount() == 0);
1532
1533         if (__pEmptyBitmap != null)
1534         {
1535                 __pEmptyBitmap->SetVisibleState(isEmpty);
1536         }
1537         if (__pEmptyText != null)
1538         {
1539                 __pEmptyText->SetVisibleState(isEmpty);
1540         }
1541
1542         _AccessibilityContainer* pContainer = GetCore().GetAccessibilityContainer();
1543
1544         if (_AccessibilityManager::IsActivated() && (pContainer != null))
1545         {
1546                 if (isEmpty)
1547                 {
1548                         if (__pAccessibilityElement == null)
1549                         {
1550                                 __pAccessibilityElement = new (std::nothrow) _AccessibilityElement(true);
1551
1552                                 SysTryReturnVoidResult(NID_UI_CTRL, (__pAccessibilityElement != null), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1553
1554                                 __pAccessibilityElement->SetName(L"ListView");
1555
1556                                 pContainer->RemoveAllElement();
1557                                 pContainer->AddElement(*__pAccessibilityElement);
1558                         }
1559
1560                         Rectangle bounds = GetBounds();
1561                         __pAccessibilityElement->SetBounds(Rectangle(0, 0, bounds.width, bounds.height));
1562
1563                         String accessibilityLable;
1564
1565                         if (__pEmptyBitmap != null)
1566                         {
1567                                 __pEmptyBitmap->GetAccessibilityContainer()->Activate(false);
1568
1569                                 accessibilityLable += L"Image, ";
1570                         }
1571                         if (__pEmptyText != null)
1572                         {
1573                                 __pEmptyText->GetAccessibilityContainer()->Activate(false);
1574
1575                                 accessibilityLable += __pEmptyText->GetText();
1576                                 accessibilityLable += L", ";
1577                         }
1578
1579                         accessibilityLable += L"No items";
1580
1581                         __pAccessibilityElement->SetLabel(accessibilityLable);
1582                 }
1583                 else
1584                 {
1585                         if (__pAccessibilityElement != null)
1586                         {
1587                                 if (pContainer->RemoveElement(*__pAccessibilityElement) != E_SUCCESS)
1588                                 {
1589                                         delete __pAccessibilityElement;
1590                                 }
1591                                 __pAccessibilityElement = null;
1592                         }
1593                 }
1594         }
1595 }
1596
1597 void
1598 _GroupedListViewImpl::AdjustLayoutOfEmptyList(void)
1599 {
1600         FloatDimension listDimension = GetCore().GetSizeF();
1601         FloatDimension emptyBitmap;
1602         FloatDimension emptyText;
1603         FloatPoint bitmapPos;
1604         FloatPoint textPos;
1605         float totalHeight = 0.0f;
1606         float horizontalSpacing = 0.0f;
1607
1608         if (__pEmptyBitmap != null)
1609         {
1610                 emptyBitmap = __pEmptyBitmap->GetSizeF();
1611         }
1612         if (__pEmptyText != null)
1613         {
1614                 emptyText = __pEmptyText->GetSizeF();
1615
1616                 if (__pEmptyBitmap != null)
1617                 {
1618                         GET_SHAPE_CONFIG(LISTVIEW::EMPTY_LIST_HORIZONTAL_SPACING, _CONTROL_ORIENTATION_PORTRAIT, horizontalSpacing);
1619                 }
1620         }
1621
1622         totalHeight = emptyBitmap.height + horizontalSpacing + emptyText.height;
1623
1624         if ((__pEmptyBitmap != null) && (__pEmptyText != null) && (totalHeight < listDimension.height))
1625         {
1626                 bitmapPos.x = ((_FloatCompare(listDimension.width, emptyBitmap.width)) ? 0.0f : (listDimension.width - emptyBitmap.width) / 2.0f);
1627                 bitmapPos.y = (listDimension.height - totalHeight) / 2.0f;
1628
1629                 textPos.x = ((_FloatCompare(listDimension.width, emptyText.width)) ? 0.0f : (listDimension.width - emptyText.width) / 2.0f);
1630                 textPos.y = bitmapPos.y + emptyBitmap.height + horizontalSpacing;
1631         }
1632         else
1633         {
1634                 if (__pEmptyBitmap != null)
1635                 {
1636                         bitmapPos.x = ((_FloatCompare(listDimension.width, emptyBitmap.width)) ? 0.0f : (listDimension.width - emptyBitmap.width) / 2.0f);
1637                         bitmapPos.y = ((listDimension.height <= totalHeight) ? 0.0f : (listDimension.height - totalHeight) / 2.0f);
1638                 }
1639
1640                 if (__pEmptyText != null)
1641                 {
1642                         textPos.x = ((_FloatCompare(listDimension.width, emptyText.width)) ? 0.0f : (listDimension.width - emptyText.width) / 2.0f);
1643                         textPos.y = ((listDimension.height <= totalHeight ) ? (bitmapPos.y + emptyBitmap.height + horizontalSpacing) : (listDimension.height - totalHeight) / 2.0f);
1644                 }
1645         }
1646
1647         if (__pEmptyBitmap != null)
1648         {
1649                 __pEmptyBitmap->SetPosition(bitmapPos);
1650         }
1651         if (__pEmptyText != null)
1652         {
1653                 __pEmptyText->SetPosition(textPos);
1654         }
1655
1656         CheckEmptyListShowState();
1657         Invalidate(true);
1658 }
1659
1660 result
1661 _GroupedListViewImpl::BeginReorderingMode(void)
1662 {
1663         SysTryReturn(NID_UI_CTRL, (GetCore().GetTableViewStyle() == TABLE_VIEW_STYLE_GROUPED), E_INVALID_OPERATION, E_INVALID_OPERATION,
1664                         "[E_INVALID_OPERATION] Reordering mode is supported only Indexed style.");
1665
1666         result r = GetCore().SetReorderModeEnabled(true);
1667
1668         SetLastResultReturn(r);
1669 }
1670
1671 result
1672 _GroupedListViewImpl::EndReorderingMode(void)
1673 {
1674         SysTryReturn(NID_UI_CTRL, (GetCore().GetTableViewStyle() == TABLE_VIEW_STYLE_GROUPED), E_INVALID_OPERATION, E_INVALID_OPERATION,
1675                         "[E_INVALID_OPERATION] Reordering mode is supported only Indexed style.");
1676
1677         result r = GetCore().SetReorderModeEnabled(false);
1678
1679         SetLastResultReturn(r);
1680 }
1681
1682 bool
1683 _GroupedListViewImpl::IsInReorderingMode(void) const
1684 {
1685         return GetCore().IsReorderModeEnabled();
1686 }
1687
1688 void
1689 _GroupedListViewImpl::SetScrollInputMode(ScrollInputMode mode)
1690 {
1691         GetCore().SetScrollInputMode(mode);
1692 }
1693
1694 ScrollInputMode
1695 _GroupedListViewImpl::GetScrollInputMode(void) const
1696 {
1697         return GetCore().GetScrollInputMode();
1698 }
1699
1700 result
1701 _GroupedListViewImpl::OpenContextItem(int groupIndex, int itemIndex)
1702 {
1703         return GetCore().OpenContextItem(groupIndex, itemIndex);
1704 }
1705
1706 result
1707 _GroupedListViewImpl::CloseContextItem(int groupIndex, int itemIndex)
1708 {
1709         return GetCore().CloseContextItem(groupIndex, itemIndex);
1710 }
1711
1712 bool
1713 _GroupedListViewImpl::IsContextItemOpened(int groupIndex, int itemIndex) const
1714 {
1715         return GetCore().IsContextItemOpened(groupIndex, itemIndex);
1716 }
1717
1718 void
1719 _GroupedListViewImpl::OnListViewContextItemStateChanged(_Control& source, int groupIndex, int itemIndex, int elementId,
1720                 ListContextItemStatus status)
1721 {
1722         if (__pListItemEvent != null)
1723         {
1724                 CloseContextItem(groupIndex, itemIndex);
1725
1726                 _ListViewItem* pListViewItem = static_cast<_ListViewItem*>(GetCore().FindItem(groupIndex, itemIndex));
1727
1728                 SetItemNeedsLazyDeletion(pListViewItem);
1729
1730                 _ListItemEventArg* pArg = new (std::nothrow) _ListItemEventArg(groupIndex, itemIndex, elementId, 0, NOTIFY_TYPE_SELCTED_CONTEXT_ITEM);
1731                 __pListItemEvent->Fire(*pArg);
1732
1733                 SetItemNeedsLazyDeletion(null);
1734         }
1735 }
1736
1737 void
1738 _GroupedListViewImpl::OnGroupedTableViewGroupItemStateChanged(_TableView& tableView, int groupIndex, _TableViewItem* pItem,
1739                 TableViewItemStatus status)
1740 {
1741         FireListViewItemEvent(groupIndex, -1, pItem, status);
1742 }
1743
1744 void
1745 _GroupedListViewImpl::OnGroupedTableViewItemStateChanged(_TableView& tableView, int groupIndex, int itemIndex, _TableViewItem* pItem,
1746                 TableViewItemStatus status)
1747 {
1748         FireListViewItemEvent(groupIndex, itemIndex, pItem, status);
1749 }
1750
1751 void
1752 _GroupedListViewImpl::OnGroupedTableViewContextItemActivationStateChanged(_TableView& tableView, int groupIndex, int itemIndex,
1753                 _TableViewItem* pContextItem, bool activated)
1754 {
1755         _ListViewItem* pListViewItem = static_cast<_ListViewItem*>(GetCore().FindItem(groupIndex, itemIndex));
1756
1757         if (pListViewItem != null)
1758         {
1759                 pListViewItem->SetContextItemActivationState(activated);
1760         }
1761 }
1762
1763 void
1764 _GroupedListViewImpl::OnGroupedTableViewItemReordered(_TableView& tableView, int groupIndexFrom, int itemIndexFrom,
1765                 int groupIndexTo, int itemIndexTo)
1766 {
1767         if (__pListItemEvent != null)
1768         {
1769                 _ListItemEventArg* pArg = new (std::nothrow) _ListItemEventArg(groupIndexFrom, itemIndexFrom, groupIndexTo, itemIndexTo,
1770                                 NOTIFY_TYPE_REORDERED_ITEM);
1771                 __pListItemEvent->Fire(*pArg);
1772         }
1773 }
1774
1775 void
1776 _GroupedListViewImpl::OnSectionTableViewItemStateChanged(_TableView& tableView, int sectionIndex, int itemIndex, _TableViewItem* pItem,
1777                 TableViewItemStatus status)
1778 {
1779         FireListViewItemEvent(sectionIndex, itemIndex, pItem, status);
1780 }
1781
1782 void
1783 _GroupedListViewImpl::OnSectionTableViewContextItemActivationStateChanged(_TableView& tableView, int sectionIndex, int itemIndex,
1784                 _TableViewItem* pContextItem, bool activated)
1785 {
1786         _ListViewItem* pListViewItem = static_cast<_ListViewItem*>(GetCore().FindItem(sectionIndex, itemIndex));
1787
1788         if (pListViewItem != null)
1789         {
1790                 pListViewItem->SetContextItemActivationState(activated);
1791         }
1792 }
1793
1794 void
1795 _GroupedListViewImpl::OnTableViewItemSwept(_TableView& tableView, int groupIndex, int itemIndex, TableViewSweepDirection direction)
1796 {
1797         if (__pListItemEvent != null)
1798         {
1799                 _ListViewItem* pListViewItem = static_cast<_ListViewItem*>(GetCore().FindItem(groupIndex, itemIndex));
1800
1801                 SetItemNeedsLazyDeletion(pListViewItem);
1802
1803                 _ListItemEventArg* pArg = new (std::nothrow) _ListItemEventArg(groupIndex, itemIndex, direction, 0, NOTIFY_TYPE_SWEPT_ITEM);
1804                 __pListItemEvent->Fire(*pArg);
1805
1806                 SetItemNeedsLazyDeletion(null);
1807         }
1808 }
1809
1810 void
1811 _GroupedListViewImpl::FireListViewItemEvent(int groupIndex, int itemIndex, _TableViewItem* pItem, TableViewItemStatus status)
1812 {
1813         if (__pListItemEvent != null)
1814         {
1815                 _ListViewItem* pListViewItem = static_cast<_ListViewItem*>(pItem);
1816
1817                 if (pListViewItem != null)
1818                 {
1819                         SetItemNeedsLazyDeletion(pListViewItem);
1820
1821                         _ListViewItemStateChangedInfo itemInfo;
1822                         pListViewItem->GetLastStateChangedInfo(itemInfo);
1823
1824                         if ((__pLinkEvent != null) && (itemInfo.pUiLinkInfo != null))
1825                         {
1826                                 IEventArg* pLinkEventArg = _PublicLinkEvent::CreateLinkEventArgN(itemInfo.pUiLinkInfo->textInfo,
1827                                                 itemInfo.pUiLinkInfo->linkType, itemInfo.pUiLinkInfo->linkInfo);
1828                                 SysTryReturnVoidResult(NID_UI_CTRL, (pLinkEventArg != null), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Unable to create _LinkEventArg.");
1829                                 __pLinkEvent->Fire(*pLinkEventArg);
1830
1831                         }
1832                         else
1833                         {
1834                                 _ListItemEventArg* pArg = new (std::nothrow) _ListItemEventArg(groupIndex, itemIndex, itemInfo.elementId, 0,
1835                                                 static_cast<NotifyType>(status));
1836                                 __pListItemEvent->Fire(*pArg);
1837                         }
1838
1839                         pListViewItem->ClearLastStateChangedInfo();
1840
1841                         SetItemNeedsLazyDeletion(null);
1842                 }
1843         }
1844 }
1845
1846 void
1847 _GroupedListViewImpl::FireListViewItemLongPressedEvent(void)
1848 {
1849         if (__pListItemEvent != null)
1850         {
1851                 int groupIndex = -1;
1852                 int itemIndex = -1;
1853                 int elementId = -1;
1854
1855                 if ((GetItemIndexFromPosition(GetCurrentTouchPosition(), groupIndex, itemIndex, elementId) == E_SUCCESS) && (itemIndex != -1))
1856                 {
1857                         _ListViewItem* pListViewItem = static_cast<_ListViewItem*>(GetCore().FindItem(groupIndex, itemIndex));
1858
1859                         if ((pListViewItem != null) && (!pListViewItem->IsContextItem()))
1860                         {
1861                                 SetItemNeedsLazyDeletion(pListViewItem);
1862
1863                                 _ListItemEventArg* pArg = new (std::nothrow) _ListItemEventArg(groupIndex, itemIndex, elementId, 0, NOTIFY_TYPE_LONG_PRESSED_ITEM);
1864                                 __pListItemEvent->Fire(*pArg);
1865
1866                                 SetItemNeedsLazyDeletion(null);
1867                         }
1868                 }
1869         }
1870 }
1871
1872 void
1873 _GroupedListViewImpl::OnScrollEndReached(_Control& source, ScrollEndEvent type)
1874 {
1875         if (__pScrollEvent != null)
1876         {
1877                 _ScrollEventArg* pEventArg = _ScrollEventArg::GetScrollEventArgN(GetPublic(), type);
1878                 result r = GetLastResult();
1879                 SysTryReturnVoidResult(NID_UI_CTRL, (r == E_SUCCESS), r, "[%s] Propagating.", GetErrorMessage(r));
1880
1881                 __pScrollEvent->Fire(*pEventArg);
1882         }
1883 }
1884
1885 void
1886 _GroupedListViewImpl::OnScrollPositionChanged(_Control& source, float scrollPosition)
1887 {
1888         if (__pScrollEvent != null)
1889         {
1890                 _ScrollEventArg* pEventArg = _ScrollEventArg::GetScrollEventArgN(GetPublic(), scrollPosition);
1891                 result r = GetLastResult();
1892                 SysTryReturnVoidResult(NID_UI_CTRL, (pEventArg != null), r, "[%s] Propagating.", GetErrorMessage(r));
1893
1894                 __pScrollEvent->Fire(*pEventArg);
1895         }
1896 }
1897
1898 void
1899 _GroupedListViewImpl::OnScrollStopped(_Control& source)
1900 {
1901         if (__pScrollEvent != null)
1902         {
1903                 _ScrollEventArg* pEventArg = _ScrollEventArg::GetScrollEventArgN(GetPublic());
1904                 result r = GetLastResult();
1905                 SysTryReturnVoidResult(NID_UI_CTRL, (r == E_SUCCESS), r, "[%s] Propagating.", GetErrorMessage(r));
1906
1907                 __pScrollEvent->Fire(*pEventArg);
1908         }
1909 }
1910
1911 void
1912 _GroupedListViewImpl::OnUiFastScrollIndexSelected(_Control& source, _FastScrollIndex& index)
1913 {
1914         if (__pFastScrollEvent != null)
1915         {
1916                 String* pIndexText = index.GetIndexText();
1917                 if (pIndexText != null)
1918                 {
1919                         _FastScrollEventArg* pEventArg = new (std::nothrow) _FastScrollEventArg(GetPublic(), *pIndexText);
1920                         __pFastScrollEvent->Fire(*pEventArg);
1921                 }
1922         }
1923 }
1924
1925 void
1926 _GroupedListViewImpl::OnDraw(void)
1927 {
1928         _ControlImpl::OnDraw();
1929
1930         if (__redrawListView)
1931         {
1932                 CheckEmptyListShowState();
1933                 __redrawListView = false;
1934         }
1935 }
1936
1937 void
1938 _GroupedListViewImpl::OnChangeLayout(_ControlOrientation orientation)
1939 {
1940         __isOrientationChanged = true;
1941
1942         if (GetCore().IsFocusModeStateEnabled() && GetCore().GetRootWindow() && GetCore().GetRootWindow()->IsActivated())
1943         {
1944                 GetCore().SetFocusDuringOrientationChange();
1945         }
1946
1947         _ControlImpl::OnChangeLayout(orientation);
1948 }
1949
1950 void
1951 _GroupedListViewImpl::OnBoundsChanged(void)
1952 {
1953         _ControlImpl::OnBoundsChanged();
1954
1955         if (__pEmptyBitmap != null)
1956         {
1957                 SetBitmapOfEmptyList(__pEmptyBitmap->GetBackgroundBitmap());
1958         }
1959         if (__pEmptyText != null)
1960         {
1961                 SetTextOfEmptyList(__pEmptyText->GetText());
1962         }
1963
1964         if (__isOrientationChanged)
1965         {
1966                 __isOrientationChanged = false;
1967
1968                 if (GetCore().IsTableViewFocused() && GetCore().IsFocusModeStateEnabled()
1969                                 && GetCore().GetRootWindow() && GetCore().GetRootWindow()->IsActivated())
1970                 {
1971                         UpdateList(true);
1972                 }
1973                 else
1974                 {
1975                         UpdateList();
1976                 }
1977         }
1978 }
1979
1980 void
1981 _GroupedListViewImpl::OnFontChanged(Font* pFont)
1982 {
1983         String fontName = GetFont();
1984         _GroupedListViewItemProviderAdaptor* pProviderAdaptor =
1985                         static_cast <_GroupedListViewItemProviderAdaptor*>(GetCore().GetItemProviderAdaptor());
1986
1987         if (__pEmptyText != null)
1988         {
1989                 __pEmptyText->SetFont(fontName);
1990                 SetTextOfEmptyList(__pEmptyText->GetText());
1991         }
1992
1993         if (pProviderAdaptor != null)
1994         {
1995                 pProviderAdaptor->SetItemFont(fontName);
1996         }
1997
1998         int firstGroup = -1;
1999         int firstItem = -1;
2000         int lastGroup = -1;
2001         int lastItem = -1;
2002         int currentItem = -1;
2003         int lastItemInGroup = -1;
2004
2005         GetCore().GetFirstLoadedItemIndex(firstGroup, firstItem);
2006         GetCore().GetLastLoadedItemIndex(lastGroup, lastItem);
2007
2008         for (int i = firstGroup; i <= lastGroup; i++)
2009         {
2010                 currentItem = ((i == firstGroup) ? firstItem : -1);
2011                 lastItemInGroup = ((i == lastGroup) ? lastItem : (GetCore().GetItemCountAt(i) - 1));
2012
2013                 for (; currentItem <= lastItemInGroup; currentItem++)
2014                 {
2015                         _ListViewItem* pListViewItem = static_cast<_ListViewItem*>(GetCore().FindItem(i, currentItem));
2016
2017                         if (pListViewItem != null)
2018                         {
2019                                 pListViewItem->SetFont(fontName);
2020                         }
2021                 }
2022         }
2023 }
2024
2025 void
2026 _GroupedListViewImpl::OnFontInfoRequested(unsigned long& style, int& size)
2027 {
2028         float textSize = 0.0f;
2029         OnFontInfoRequested(style, textSize);
2030
2031         size = _CoordinateSystemUtils::ConvertToInteger(textSize);
2032 }
2033
2034 void
2035 _GroupedListViewImpl::OnFontInfoRequested(unsigned long& style, float& size)
2036 {
2037         GET_SHAPE_CONFIG(LISTVIEW::EMPTY_LIST_TEXT_HEIGHT, _CONTROL_ORIENTATION_PORTRAIT, size);
2038         style = FONT_STYLE_PLAIN;
2039 }
2040
2041 FloatPoint
2042 _GroupedListViewImpl::GetCurrentTouchPosition(void)
2043 {
2044         FloatPoint currentTouchPos = _TouchManager::GetInstance()->GetScreenPoint(0);
2045         FloatRectangle bounds = GetCore().GetAbsoluteBoundsF(true);
2046
2047         currentTouchPos.x -= bounds.x;
2048         currentTouchPos.y -= bounds.y;
2049
2050         return currentTouchPos;
2051 }
2052
2053 result
2054 _GroupedListViewImpl::OnTouchEventListenerAdded(void)
2055 {
2056         return E_SUCCESS;
2057 }
2058
2059 result
2060 _GroupedListViewImpl::OnTouchEventListenerRemoved(void)
2061 {
2062         return E_SUCCESS;
2063 }
2064
2065 class _GroupedListViewMaker
2066         : public _UiBuilderControlMaker
2067 {
2068 public:
2069         _GroupedListViewMaker(_UiBuilder* uibuilder)
2070                 : _UiBuilderControlMaker(uibuilder){};
2071
2072         virtual ~_GroupedListViewMaker(){};
2073
2074         static _UiBuilderControlMaker*
2075         GetInstance(_UiBuilder* uibuilder)
2076         {
2077                 _GroupedListViewMaker* pGroupedListViewMaker = new (std::nothrow) _GroupedListViewMaker(uibuilder);
2078                 return pGroupedListViewMaker;
2079         };
2080 protected:
2081         virtual Tizen::Ui::Control*
2082         Make(_UiBuilderControl* pControl)
2083         {
2084                 result r = E_SYSTEM;
2085                 _UiBuilderControlLayout* pControlProperty = null;
2086                 GroupedListView* pGroupedListView = null;
2087                 FloatRectangle rect;
2088
2089                 ListScrollStyle scrollStyle = SCROLL_STYLE_FADE_OUT;
2090                 GroupedListViewStyle style = GROUPED_LIST_VIEW_STYLE_INDEXED;
2091                 ScrollInputMode scrollInputMode = SCROLL_INPUT_MODE_ALLOW_ANY_DIRECTION;
2092
2093                 String elementString;
2094                 bool itemDividerState = true;
2095                 int opacity = 100;
2096                 bool sweepEnabledState = false;
2097                 Color color;
2098
2099                 GetProperty(pControl, &pControlProperty);
2100                 if (pControlProperty == null)
2101                 {
2102                         return null;
2103                 }
2104
2105                 pGroupedListView = new (std::nothrow) GroupedListView();
2106                 if (pGroupedListView == null)
2107                 {
2108                         return null;
2109                 }
2110
2111                 rect = pControlProperty->GetRectF();
2112
2113                 String styleString;
2114                 styleString = pControlProperty->GetStyle();
2115
2116                 if (styleString.Equals(L"GROUPED_LIST_VIEW_STYLE_SECTION", false))
2117                 {
2118                         style = GROUPED_LIST_VIEW_STYLE_SECTION;
2119                 }
2120                 else
2121                 {
2122                         style = GROUPED_LIST_VIEW_STYLE_INDEXED;
2123                 }
2124
2125                 //Construct
2126                 if (pControl->GetElement(L"itemDivider", elementString))
2127                 {
2128                         if (elementString.Equals(L"true", false))
2129                         {
2130                                 itemDividerState = true;
2131                         }
2132                         else
2133                         {
2134                                 itemDividerState = false;
2135                         }
2136                 }
2137
2138                 if (pControl->GetElement(L"listScrollStyle", elementString))
2139                 {
2140                         if (elementString.Equals(L"SCROLL_STYLE_FIXED", false))
2141                         {
2142                                 scrollStyle = SCROLL_STYLE_FIXED;
2143                         }
2144                         else if (elementString.Equals(L"SCROLL_STYLE_FAST_SCROLL", false))
2145                         {
2146                                 scrollStyle = SCROLL_STYLE_FAST_SCROLL;
2147                         }
2148                         else if (elementString.Equals(L"SCROLL_STYLE_JUMP_TO_TOP", false))
2149                         {
2150                                 scrollStyle = SCROLL_STYLE_JUMP_TO_TOP;
2151                         }
2152                         else if (elementString.Equals(L"SCROLL_STYLE_THUMB", false))
2153                         {
2154                                 scrollStyle = SCROLL_STYLE_THUMB;
2155                         }
2156                 }
2157                 else if (pControl->GetElement(L"fastScroll", elementString))
2158                 {
2159                         if (elementString.Equals(L"true", false))
2160                         {
2161                                 scrollStyle = SCROLL_STYLE_FAST_SCROLL;
2162                         }
2163                 }
2164
2165                 r = pGroupedListView->Construct(rect, style, itemDividerState, scrollStyle);
2166                 SysTryCatch(NID_UI, (r == E_SUCCESS), , r, "[%s] Propagating.", GetErrorMessage(r));
2167
2168                 // Set BackgroundsBitmap
2169                 if (pControl->GetElement("backgroundBitmapPath", elementString))
2170                 {
2171                         Bitmap* pBackgroundBitmap = null;
2172                         pBackgroundBitmap = LoadBitmapN(elementString);
2173                         if (pBackgroundBitmap != null)
2174                         {
2175                                 r = pGroupedListView->SetBackgroundBitmap(pBackgroundBitmap);
2176                                 delete pBackgroundBitmap;
2177                                 pBackgroundBitmap = null;
2178
2179                                 SysTryCatch(NID_UI, (r == E_SUCCESS), , r, "[%s] Propagating.", GetErrorMessage(r));
2180                         }
2181                 }
2182
2183                 // Set Empty List
2184                 if (pControl->GetElement(L"textOfEmptyList", elementString))
2185                 {
2186                         r = pGroupedListView->SetTextOfEmptyList(elementString);
2187                         SysTryCatch(NID_UI, (r == E_SUCCESS), , r, "[%s] Propagating.", GetErrorMessage(r));
2188                 }
2189
2190                 if (pControl->GetElement(L"colorOfEmptyListText", elementString))
2191                 {
2192                         ConvertStringToColor(elementString, color);
2193                         r = pGroupedListView->SetTextColorOfEmptyList(color);
2194                         SysTryCatch(NID_UI, (r == E_SUCCESS), , r, "[%s] Propagating.", GetErrorMessage(r));
2195                 }
2196
2197                 if (pControl->GetElement(L"bitmapPathOfEmptyList", elementString))
2198                 {
2199                         Bitmap* pBackgroundBitmap = null;
2200                         pBackgroundBitmap = LoadBitmapN(elementString); //__image->DecodeN(path,BITMAP_PIXEL_FORMAT_RGB565);
2201                         if (pBackgroundBitmap != null)
2202                         {
2203                                 r = pGroupedListView->SetBitmapOfEmptyList(pBackgroundBitmap);
2204                                 delete pBackgroundBitmap;
2205                                 pBackgroundBitmap = null;
2206
2207                                 SysTryCatch(NID_UI, (r == E_SUCCESS), , r, "[%s] Propagating.", GetErrorMessage(r));
2208                         }
2209                 }
2210
2211                 if (pControl->GetElement(L"backgroundColorOpacity", elementString) || pControl->GetElement(L"BGColorOpacity", elementString))
2212                 {
2213                         Base::Integer::Parse(elementString, opacity);
2214                 }
2215
2216                 if (pControl->GetElement(L"backgroundColor", elementString) || pControl->GetElement(L"BGColor", elementString))
2217                 {
2218                         ConvertStringToColor32(elementString, opacity, color);
2219                         r = pGroupedListView->SetBackgroundColor(color);
2220                         SysTryCatch(NID_UI, (r == E_SUCCESS), , r, "[%s] Propagating.", GetErrorMessage(r));
2221                 }
2222
2223                 if (pControl->GetElement(L"itemDividerColor", elementString))
2224                 {
2225                         ConvertStringToColor(elementString, color);
2226                         r = pGroupedListView->SetItemDividerColor(color);
2227                         SysTryCatch(NID_UI, (r == E_SUCCESS), , r, "[%s] Propagating.", GetErrorMessage(r));
2228                 }
2229
2230                 if (pControl->GetElement(L"sectionColor", elementString))
2231                 {
2232                         ConvertStringToColor(elementString, color);
2233                         r = pGroupedListView->SetSectionColor(color);
2234                         SysTryCatch(NID_UI, (r == E_SUCCESS), , r, "[%s] Propagating.", GetErrorMessage(r));
2235                 }
2236
2237                 if (pControl->GetElement(L"sweepEnabled", elementString))
2238                 {
2239                         {
2240                                 if (elementString.Equals(L"true", false))
2241                                 {
2242                                         sweepEnabledState = true;
2243                                 }
2244                                 else
2245                                 {
2246                                         sweepEnabledState = false;
2247                                 }
2248                         }
2249                         r = pGroupedListView->SetSweepEnabled(sweepEnabledState);
2250                         SysTryCatch(NID_UI, (r == E_SUCCESS), , r, "[%s] Propagating.", GetErrorMessage(r));
2251                 }
2252
2253                 // scroll Input Mode
2254                 if (pControl->GetElement(L"scrollInputMode", elementString))
2255                 {
2256                         if (elementString.Equals(L"SCROLL_INPUT_MODE_RESTRICT_TO_INITIAL_DIRECTION", false))
2257                         {
2258                                 scrollInputMode = SCROLL_INPUT_MODE_RESTRICT_TO_INITIAL_DIRECTION;
2259                         }
2260
2261                         pGroupedListView->SetScrollInputMode(scrollInputMode);
2262                 }
2263
2264                 return pGroupedListView;
2265
2266         CATCH:
2267                 delete pGroupedListView;
2268                 return null;
2269         }
2270
2271 private:
2272 }; // _GroupedListViewMaker
2273
2274 _GroupedListViewRegister::_GroupedListViewRegister()
2275 {
2276           _UiBuilderControlTableManager* pUiBuilderControlTableManager = _UiBuilderControlTableManager::GetInstance();
2277           pUiBuilderControlTableManager->RegisterControl(L"GroupedListView", _GroupedListViewMaker::GetInstance);
2278 }
2279
2280 _GroupedListViewRegister::~_GroupedListViewRegister()
2281 {
2282           _UiBuilderControlTableManager* pUiBuilderControlTableManager = _UiBuilderControlTableManager::GetInstance();
2283           pUiBuilderControlTableManager->UnregisterControl(L"GroupedListView");
2284 }
2285 static _GroupedListViewRegister GroupedListViewRegisterToUIbuilder;
2286 }}} // Tizen::Ui::Controls