remove APIs to apply [ACR][03/30][Remove] Remove APIs in Tizen::Ui namespace
[platform/framework/native/uifw.git] / src / ui / controls / FUiCtrl_ListViewItem.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file        FUiCtrl_ListViewItem.cpp
20  * @brief   This is the implementation file for _ListViewItem class.
21  *
22  * This file contains the implementation of _ListViewItem class.
23  */
24
25 #include <FBaseSysLog.h>
26 #include <FGrp_BitmapImpl.h>
27 #include <FGrp_EnrichedTextImpl.h>
28 #include <FGrp_TextElementImpl.h>
29 #include <FGrp_TextTextCutLink.h>
30 #include <FGrp_TextTextCutLinkParser.h>
31 #include <FGrp_TextTextSimple.h>
32 #include "FUi_AccessibilityContainer.h"
33 #include "FUi_AccessibilityElement.h"
34 #include "FUi_AccessibilityManager.h"
35 #include "FUi_CoordinateSystemUtils.h"
36 #include "FUi_Math.h"
37 #include "FUi_ResourceManager.h"
38 #include "FUiAnim_VisualElement.h"
39 #include "FUiCtrl_Label.h"
40 #include "FUiCtrl_ListViewContextItem.h"
41 #include "FUiCtrl_ListViewItem.h"
42 #include "FUiCtrl_Progress.h"
43 #include "FUiCtrl_UiListViewItemEvent.h"
44 #include "FUiCtrl_UiListViewItemEventArg.h"
45
46 #ifdef MEMORY_LEAK_CHECK
47 #include "mem_leak_check.h"
48 #endif
49
50 using namespace Tizen::Base;
51 using namespace Tizen::Base::Runtime;
52 using namespace Tizen::Base::Utility;
53 using namespace Tizen::Graphics;
54 using namespace Tizen::Graphics::_Text;
55 using namespace Tizen::Ui;
56 using namespace Tizen::Ui::Animations;
57
58 namespace Tizen { namespace Ui { namespace Controls
59 {
60
61 _ListViewItem::_ListViewItem(float itemHeight)
62         : _TableViewItem(itemHeight)
63         , __needAlignContextItem(false)
64         , __touchPressed(false)
65         , __selectedElementId(-1)
66         , __progressLeftMargin(0.0f)
67         , __progressRightMargin(0.0f)
68         , __pProgress(null)
69         , __descriptionTextShowState(false)
70         , __pDescriptionText(null)
71         , __pDivider(null)
72         , __selectionEabled(false)
73         , __fontStyle(0)
74         , __fontSize(0.0f)
75         , __fontName(L"")
76         , __prevTouchPos(-1.0f, -1.0f)
77         , __pTextSlideTimer(null)
78         , __pAccessibilityElement(null)
79 {
80         GET_COLOR_CONFIG(TABLEVIEW::ITEM_DESCRIPTION_TEXT_NORMAL, __descriptionTextColor);
81
82         ___stateChangedInfo.selectionType = LISTVIEW_ITEM_SELECTED;
83         ___stateChangedInfo.elementId = -1;
84         ___stateChangedInfo.pUiLinkInfo = null;
85 }
86
87 _ListViewItem::~_ListViewItem(void)
88 {
89         DeleteAllElement();
90
91         delete ___stateChangedInfo.pUiLinkInfo;
92         ___stateChangedInfo.pUiLinkInfo = null;
93
94         delete __pTextSlideTimer;
95         __pTextSlideTimer = null;
96
97         if (__pProgress != null)
98         {
99                 DetachChild(*__pProgress);
100
101                 delete __pProgress;
102                 __pProgress = null;
103         }
104
105         if (__pDescriptionText != null)
106         {
107                 DetachChild(*__pDescriptionText);
108
109                 delete __pDescriptionText;
110                 __pDescriptionText = null;
111         }
112
113         if (__pDivider != null)
114         {
115                 DetachChild(*__pDivider);
116
117                 delete __pDivider;
118                 __pDivider = null;
119         }
120
121         _AccessibilityContainer* pContainer = GetAccessibilityContainer();
122
123         if ((__pAccessibilityElement != null) && (pContainer != null))
124         {
125                 pContainer->RemoveAllElement();
126                 __pAccessibilityElement = null;
127         }
128 }
129
130 _ListViewItem*
131 _ListViewItem::CreateListViewItemN(float itemHeight)
132 {
133         _ListViewItem* pItem = new (std::nothrow) _ListViewItem(itemHeight);
134         SysTryReturn(NID_UI_CTRL, (pItem != null), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
135
136         pItem->AcquireHandle();
137
138         result r = pItem->Initialize();
139         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r = E_SYSTEM, "[E_SYSTEM] Unable to create _ListViewItem");
140
141         return pItem;
142
143 CATCH:
144         delete pItem;
145
146         return null;
147 }
148
149 void
150 _ListViewItem::SetListViewItemType(ListViewItemType type)
151 {
152         __itemType = type;
153 }
154
155 result
156 _ListViewItem::AddElement(FloatRectangle& rect, int elementId, const String& text, bool textSliding)
157 {
158         result r = E_SUCCESS;
159
160         SysTryReturn(NID_UI_CTRL, (HasElement(elementId) == false), E_INVALID_ARG, E_INVALID_ARG,
161                         ("[E_INVALID_ARG] This elementId already exists."));
162
163         // Convert String to TextObject
164         TextObject* pText = new (std::nothrow) TextObject();
165         pText->Construct();
166
167         if (text.IsEmpty() == false)
168         {
169                 TextSimple* pSimpleText = new (std::nothrow) TextSimple(const_cast <wchar_t*>(text.GetPointer()), text.GetLength());
170                 pText->AppendElement(*pSimpleText);
171
172                 pText->SetAlignment(TEXT_OBJECT_ALIGNMENT_LEFT | TEXT_OBJECT_ALIGNMENT_MIDDLE);
173                 pText->SetWrap(TEXT_OBJECT_WRAP_TYPE_NONE);
174         }
175
176         // Make element object
177         _ListViewItemElement element;
178         memset(&element, 0, sizeof(_ListViewItemElement));
179
180         element.elementId = elementId;
181         element.elementType = LISTVIEW_ITEM_ELEMENT_TEXT;
182         element.bounds = rect;
183
184         element.pTextElement = new (std::nothrow) _ListViewItemElementText();
185         SysTryReturn(NID_UI_CTRL, (element.pTextElement != null), (r = GetLastResult()), r, "[%s] Propagating.", GetErrorMessage(r));
186
187         element.pTextElement->pTextObject = pText;
188         element.pTextElement->textSlidingEnabled = textSliding;
189
190         GET_SHAPE_CONFIG(LISTVIEW::ITEM_DEFAULT_FONT_SIZE, _CONTROL_ORIENTATION_PORTRAIT, element.pTextElement->textSize);
191         GET_COLOR_CONFIG(TABLEVIEW::ITEM_TEXT_NORMAL, element.pTextElement->textColor[LISTVIEW_ITEM_STATUS_NORMAL]);
192         GET_COLOR_CONFIG(TABLEVIEW::ITEM_TEXT_PRESSED, element.pTextElement->textColor[LISTVIEW_ITEM_STATUS_PRESSED]);
193         GET_COLOR_CONFIG(TABLEVIEW::ITEM_TEXT_HIGHLIGHTED, element.pTextElement->textColor[LISTVIEW_ITEM_STATUS_HIGHLIGHTED]);
194
195         // Set Visual element for this element
196         _VisualElement* pVE = new (std::nothrow) _VisualElement();
197         pVE->Construct();
198         pVE->SetImplicitAnimationEnabled(false);
199         pVE->SetContentProvider(&__hitTestVEDelegator);
200         element.pTextElement->pVE = pVE;
201
202         __elements.push_back(element);
203
204         return r;
205 }
206
207 result
208 _ListViewItem::AddElement(FloatRectangle& rect, int elementId, const EnrichedText* pEnrichedText, bool textSliding)
209 {
210         SysTryReturn(NID_UI_CTRL, (HasElement(elementId) == false), E_INVALID_ARG, E_INVALID_ARG,
211                         ("[E_INVALID_ARG] This elementId already exists."));
212
213         SysTryReturn(NID_GRP, (pEnrichedText != null) && (_EnrichedTextImpl::GetInstance(*pEnrichedText) != null),
214                         E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] This _EnrichedText element is null.");
215
216         // Set Text element
217         _EnrichedTextImpl* pCloneText = _EnrichedTextImpl::GetInstance(*pEnrichedText)->GetCloneN();
218         SysTryReturn(NID_GRP, (pCloneText != null), E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] This _EnrichedText element can not clone.");
219
220         TextObject* pText = pCloneText->GetTextObject();
221
222         // Make element object
223         _ListViewItemElement element;
224         memset(&element, 0, sizeof(_ListViewItemElement));
225
226         element.elementId = elementId;
227         element.elementType = LISTVIEW_ITEM_ELEMENT_TEXT;
228         element.bounds = rect;
229
230         element.pTextElement = new (std::nothrow) _ListViewItemElementText();
231         SysTryReturn(NID_UI_CTRL, (element.pTextElement != null), GetLastResult(), GetLastResult(), "[%s] Propagating.",
232                         GetErrorMessage(GetLastResult()));
233
234         element.pTextElement->pTextObject = pText;
235         element.pTextElement->pEnrichedText = pCloneText;
236         element.pTextElement->textSlidingEnabled = textSliding;
237
238         GET_COLOR_CONFIG(TABLEVIEW::ITEM_TEXT_NORMAL, element.pTextElement->textColor[LISTVIEW_ITEM_STATUS_NORMAL]);
239         GET_COLOR_CONFIG(TABLEVIEW::ITEM_TEXT_PRESSED, element.pTextElement->textColor[LISTVIEW_ITEM_STATUS_PRESSED]);
240         GET_COLOR_CONFIG(TABLEVIEW::ITEM_TEXT_HIGHLIGHTED, element.pTextElement->textColor[LISTVIEW_ITEM_STATUS_HIGHLIGHTED]);
241
242         // Set Visual element for this element
243         _VisualElement* pVE = new (std::nothrow) _VisualElement();
244         pVE->Construct();
245         pVE->SetImplicitAnimationEnabled(false);
246         pVE->SetContentProvider(&__hitTestVEDelegator);
247         element.pTextElement->pVE = pVE;
248
249         __elements.push_back(element);
250
251         return E_SUCCESS;
252 }
253
254 result
255 _ListViewItem::AddElement(FloatRectangle& rect, int elementId, const Bitmap* pNormalBitmap, const Bitmap* pPressedBitmap, const Bitmap* pHighlightedBitmap)
256 {
257         SysTryReturn(NID_UI_CTRL, (HasElement(elementId) == false), E_INVALID_ARG, E_INVALID_ARG,
258                         ("[E_INVALID_ARG] This elementId already exists."));
259
260         SysTryReturn(NID_GRP, (pNormalBitmap != null), E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] This Bitmap element is null.");
261
262         _ListViewItemElement element;
263         _VisualElement* pVE = null;
264         Bitmap* pClonePressedBitmap = null;
265         Bitmap* pCloneHighlightedBitmap = null;
266         result r = E_SUCCESS;
267
268         Bitmap* pCloneNormalBitmap = _BitmapImpl::CloneN(*pNormalBitmap);
269         SysTryReturn(NID_UI_CTRL, (pCloneNormalBitmap != null), (r = GetLastResult()), r, "[%s] Propagating.", GetErrorMessage(GetLastResult()));
270
271         if (pPressedBitmap != null)
272         {
273                 pClonePressedBitmap = _BitmapImpl::CloneN(*pPressedBitmap);
274                 SysTryCatch(NID_UI_CTRL, (pClonePressedBitmap != null), (r = GetLastResult()), r, "[%s] Propagating.", GetErrorMessage(GetLastResult()));
275         }
276
277         if (pHighlightedBitmap != null)
278         {
279                 pCloneHighlightedBitmap = _BitmapImpl::CloneN(*pHighlightedBitmap);
280                 SysTryCatch(NID_UI_CTRL, (pCloneHighlightedBitmap != null), (r = GetLastResult()), r, "[%s] Propagating.", GetErrorMessage(GetLastResult()));
281         }
282
283         // Make element object
284         memset(&element, 0, sizeof(_ListViewItemElement));
285
286         element.elementId = elementId;
287         element.elementType = LISTVIEW_ITEM_ELEMENT_BITMAP;
288         element.bounds = rect;
289
290         element.pBitmapElement = new (std::nothrow) _ListViewItemElementBitmap();
291         SysTryCatch(NID_UI_CTRL, (element.pBitmapElement != null), (r = GetLastResult()), r, "[%s] Propagating.", GetErrorMessage(GetLastResult()));
292
293         element.pBitmapElement->pBitmap[LISTVIEW_ITEM_STATUS_NORMAL] = pCloneNormalBitmap;
294         element.pBitmapElement->pBitmap[LISTVIEW_ITEM_STATUS_PRESSED] = pClonePressedBitmap;
295         element.pBitmapElement->pBitmap[LISTVIEW_ITEM_STATUS_HIGHLIGHTED] = pCloneHighlightedBitmap;
296
297         pVE = new (std::nothrow) _VisualElement();
298         pVE->Construct();
299         pVE->SetImplicitAnimationEnabled(false);
300         pVE->SetContentProvider(&__hitTestVEDelegator);
301         element.pBitmapElement->pVE = pVE;
302
303         __elements.push_back(element);
304
305         return E_SUCCESS;
306
307 CATCH:
308         delete pCloneNormalBitmap;
309         delete pClonePressedBitmap;
310         delete pCloneHighlightedBitmap;
311
312         return r;
313 }
314
315 result
316 _ListViewItem::AddElement(FloatRectangle& rect, int elementId, const _ICustomElement* pCustom)
317 {
318         SysTryReturn(NID_UI_CTRL, (HasElement(elementId) == false), E_INVALID_ARG, E_INVALID_ARG,
319                         ("[E_INVALID_ARG] This elementId already exists."));
320
321         SysTryReturn(NID_GRP, (pCustom != null), E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] This Custom element is null.");
322
323         // Make element object
324         _ListViewItemElement element;
325         memset(&element, 0, sizeof(_ListViewItemElement));
326
327         element.elementId = elementId;
328         element.elementType = LISTVIEW_ITEM_ELEMENT_OBJ;
329         element.bounds = rect;
330
331         element.pCustomElement = new (std::nothrow) _ListViewItemElementCustom();
332         SysTryReturn(NID_UI_CTRL, (element.pCustomElement != null), GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
333
334         element.pCustomElement->pCustom = const_cast<_ICustomElement*>(pCustom);
335
336         _VisualElement* pVE = new (std::nothrow) _VisualElement();
337         pVE->Construct();
338         pVE->SetImplicitAnimationEnabled(false);
339         pVE->SetContentProvider(&__hitTestVEDelegator);
340         element.pCustomElement->pVE = pVE;
341
342         if (pVE->GetParent() == null)
343         {
344                 GetVisualElement()->AttachChild(*(pVE));
345                 pVE->SetShowState(true);
346                 pVE->SetBounds(rect);
347         }
348
349         __elements.push_back(element);
350
351         return E_SUCCESS;
352 }
353
354 bool
355 _ListViewItem::DeleteElement(int elementId)
356 {
357         _LinkedList <_ListViewItemElement>::_Iterator iter;
358
359         for (iter = __elements.begin(); iter != __elements.end(); iter++)
360         {
361                 if (iter->elementId == elementId)
362                 {
363                         DeleteElement(&(*iter));
364                         __elements.erase(iter);
365
366                         return true;
367                 }
368         }
369
370         return false;
371 }
372
373 void
374 _ListViewItem::DeleteAllElement(void)
375 {
376         _LinkedList <_ListViewItemElement>::_Iterator iter;
377
378         for (iter = __elements.begin(); iter != __elements.end(); iter++)
379         {
380                 DeleteElement(&(*iter));
381         }
382
383         __elements.clear();
384 }
385
386 void
387 _ListViewItem::DeleteElement(_ListViewItemElement* pElement)
388 {
389         if (pElement->pTextElement != null)
390         {
391                 if (pElement->pTextElement->pEnrichedText != null)
392                 {
393                         (pElement->pTextElement->pEnrichedText)->RemoveAllTextElements(true);
394
395                         delete pElement->pTextElement->pEnrichedText;
396                         pElement->pTextElement->pEnrichedText = null;
397
398                         pElement->pTextElement->pTextObject = null;
399                 }
400                 else
401                 {
402                         delete pElement->pTextElement->pTextObject;
403                         pElement->pTextElement->pTextObject = null;
404                 }
405
406                 if (pElement->pTextElement->pVE != null)
407                 {
408                         pElement->pTextElement->pVE->Destroy();
409                         pElement->pTextElement->pVE = null;
410                 }
411
412                 delete pElement->pTextElement;
413                 pElement->pTextElement = null;
414         }
415
416         if (pElement->pBitmapElement != null)
417         {
418                 for (int i = 0; i < LISTVIEW_ITEM_STATUS_MAX; i++)
419                 {
420                         delete pElement->pBitmapElement->pBitmap[i];
421                         pElement->pBitmapElement->pBitmap[i] = null;
422                 }
423
424                 if (pElement->pBitmapElement->pVE != null)
425                 {
426                         pElement->pBitmapElement->pVE->Destroy();
427                         pElement->pBitmapElement->pVE = null;
428                 }
429
430                 delete pElement->pBitmapElement;
431                 pElement->pBitmapElement = null;
432         }
433
434         if (pElement->pCustomElement)
435         {
436                 delete pElement->pCustomElement->pCustom;
437                 pElement->pCustomElement->pCustom = null;
438
439                 if (pElement->pCustomElement->pVE != null)
440                 {
441                         pElement->pCustomElement->pVE->Destroy();
442                         pElement->pCustomElement->pVE = null;
443                 }
444
445                 delete pElement->pCustomElement;
446                 pElement->pCustomElement = null;
447         }
448 }
449
450 bool
451 _ListViewItem::HasElement(int elementId)
452 {
453         _ListViewItemElement* pElement = GetElement(elementId);
454
455         return (pElement != null);
456 }
457
458 bool
459 _ListViewItem::RefreshElement(int elementId)
460 {
461         _ListViewItemElement* pElement = GetElement(elementId);
462
463         if (pElement != null)
464         {
465                 DrawElement(pElement);
466         }
467
468         return (pElement != null);
469 }
470
471 void
472 _ListViewItem::SetLastStateChangedInfo(void)
473 {
474         ClearLastStateChangedInfo();
475
476         int elementId = GetElementIdFromCurrentTouchPosition();
477         _ListViewItemElement* pElement = GetElement(elementId);
478
479         if ((pElement != null) && (__itemType == LISTVIEW_ITEM_TYPE_CUSTOM))
480         {
481                 _ListViewItemUiLinkInfo* pInfo = null;
482                 int cutlinkTextTouchedIndex = -1;
483
484                 if (IsCutlinkTextSelected(__prevTouchPos, &cutlinkTextTouchedIndex, &pInfo))
485                 {
486                         if ((GetItemStyle() == TABLE_VIEW_ANNEX_STYLE_DETAILED)
487                                         && (pElement->actionElement == true) && (pElement->selectionEnabled == false))
488                         {
489                                 elementId = -1;
490                         }
491
492                         if (cutlinkTextTouchedIndex >= 0)
493                         {
494                                 ___stateChangedInfo.selectionType = LISTVIEW_ITEM_UILINK_SELECTED;
495                                 ___stateChangedInfo.elementId = elementId;
496                                 ___stateChangedInfo.pUiLinkInfo = pInfo;
497                         }
498                         else
499                         {
500                                 ___stateChangedInfo.selectionType = LISTVIEW_ITEM_ELEMENT_SELECTED;
501                                 ___stateChangedInfo.elementId = elementId;
502                         }
503                 }
504                 else
505                 {
506                         if ((GetItemStyle() == TABLE_VIEW_ANNEX_STYLE_DETAILED)
507                                         && (pElement->actionElement == true) && (pElement->selectionEnabled == false))
508                         {
509                                 elementId = -1;
510                         }
511
512                         ___stateChangedInfo.selectionType = LISTVIEW_ITEM_ELEMENT_SELECTED;
513                         ___stateChangedInfo.elementId = elementId;
514                 }
515         }
516         else
517         {
518                 ___stateChangedInfo.selectionType = LISTVIEW_ITEM_ELEMENT_SELECTED;
519                 ___stateChangedInfo.elementId = -1;
520         }
521 }
522
523 bool
524 _ListViewItem::GetLastStateChangedInfo(_ListViewItemStateChangedInfo& changedInfo) const
525 {
526         changedInfo = ___stateChangedInfo;
527
528         return (___stateChangedInfo.selectionType != LISTVIEW_ITEM_SELECTED);
529 }
530
531 void
532 _ListViewItem::ClearLastStateChangedInfo(void)
533 {
534         delete ___stateChangedInfo.pUiLinkInfo;
535
536         ___stateChangedInfo.selectionType = LISTVIEW_ITEM_SELECTED;
537         ___stateChangedInfo.elementId = -1;
538         ___stateChangedInfo.pUiLinkInfo = null;
539 }
540
541 int
542 _ListViewItem::GetElementIdFromPosition(const FloatPoint& position) const
543 {
544         _LinkedList <_ListViewItemElement>::_ReverseIterator reverseIter;
545
546         for (reverseIter = __elements.rbegin(); reverseIter != __elements.rend(); reverseIter++)
547         {
548                 if ((*reverseIter).bounds.Contains(position))
549                 {
550                         return (*reverseIter).elementId;
551                 }
552         }
553
554         return -1;
555 }
556
557 int
558 _ListViewItem::GetElementIdFromCurrentTouchPosition(void) const
559 {
560         return GetElementIdFromPosition(__prevTouchPos);
561 }
562
563 _ListViewItemElement*
564 _ListViewItem::GetElement(int elementId) const
565 {
566         _LinkedList <_ListViewItemElement>::_Iterator iter;
567
568         for (iter = __elements.begin(); iter != __elements.end(); iter++)
569         {
570                 if (iter->elementId == elementId)
571                 {
572                         return &(*iter);
573                 }
574         }
575
576         return null;
577 }
578
579 ListViewItemElementType
580 _ListViewItem::GetElementType(int elementId) const
581 {
582         _ListViewItemElement* pElement = GetElement(elementId);
583
584         return ((pElement != null) ? pElement->elementType : LISTVIEW_ITEM_ELEMENT_INVALID);
585 }
586
587 TextObject*
588 _ListViewItem::GetTextObjectInElement(int elementId) const
589 {
590         _ListViewItemElementText* pElement = GetElementText(elementId);
591
592         return ((pElement != null) ? pElement->pTextObject : null);
593 }
594
595 _ListViewItemElementText*
596 _ListViewItem::GetElementText(int elementId) const
597 {
598         _ListViewItemElement* pElement = GetElement(elementId);
599
600         if ((pElement != null) && (pElement->elementType == LISTVIEW_ITEM_ELEMENT_TEXT)
601                         &&  (pElement->pTextElement->pTextObject != null))
602         {
603                 return pElement->pTextElement;
604         }
605
606         return null;
607 }
608
609 _ListViewItemElementBitmap*
610 _ListViewItem::GetElementBitmap(int elementId) const
611 {
612         _ListViewItemElement* pElement = GetElement(elementId);
613
614         if ((pElement != null) && (pElement->elementType == LISTVIEW_ITEM_ELEMENT_BITMAP))
615         {
616                 return pElement->pBitmapElement;
617         }
618
619         return null;
620 }
621
622 bool
623 _ListViewItem::SetElementSelectionEnabled(int elementId, bool enable)
624 {
625         _ListViewItemElement* pElement = GetElement(elementId);
626
627         if (pElement == null)
628         {
629                 return false;
630         }
631
632         pElement->actionElement = true;
633         pElement->selectionEnabled = enable;
634
635         return true;
636 }
637
638 bool
639 _ListViewItem::GetElementSelectionEnabled(int elementId, bool& enable)
640 {
641         _ListViewItemElement* pElement = GetElement(elementId);
642
643         if ((pElement == null) || (pElement->actionElement == false))
644         {
645                 return false;
646         }
647
648         enable = pElement->selectionEnabled;
649
650         return true;
651 }
652
653 bool
654 _ListViewItem::SetTextCutlinkMask(int elementId, unsigned long mask)
655 {
656         _ListViewItemElementText* pElement = GetElementText(elementId);
657
658         if (pElement == null)
659         {
660                 return false;
661         }
662
663         pElement->cutlinkMaskType = mask;
664
665         return true;
666 }
667
668 bool
669 _ListViewItem::SetTextCutlinkViewMode(int elementId, bool cutlinkViewMode, bool cutlinkParseEnable)
670 {
671         _ListViewItemElementText* pElement = GetElementText(elementId);
672
673         if (pElement == null)
674         {
675                 return false;
676         }
677
678         pElement->cutlinkViewModeEnabled = cutlinkViewMode;
679         pElement->cutlinkParseEnabled = cutlinkParseEnable;
680         pElement->cutlinkMaskType = LINK_TYPE_MAX;
681
682         return true;
683 }
684
685 bool
686 _ListViewItem::SetTextAlignment(int elementId, TextObjectAlignment textAlignment)
687 {
688         TextObject* pTextObject = GetTextObjectInElement(elementId);
689
690         if (pTextObject == null)
691         {
692                 return false;
693         }
694
695         TextObjectAlignment originAlign = pTextObject->GetAlignment();
696
697         // reset original alignment
698         if ((0x0007 & textAlignment) != 0x0000)                 // TextHorizontalAlignment
699         {
700                 originAlign &= 0x0700;
701         }
702         else if ((0x0700 & textAlignment) != 0x0000)    // TextVerticalAlignment
703         {
704                 originAlign &= 0x0007;
705         }
706
707         pTextObject->SetAlignment(originAlign | textAlignment);
708
709         return true;
710 }
711
712 bool
713 _ListViewItem::GetTextAlignment(int elementId, TextObjectAlignment& textAlignment) const
714 {
715         TextObject* pTextObject = GetTextObjectInElement(elementId);
716
717         if (pTextObject == null)
718         {
719                 return false;
720         }
721
722         textAlignment = pTextObject->GetAlignment();
723
724         return true;
725 }
726
727 bool
728 _ListViewItem::SetTextWrapType(int elementId, TextObjectWrapType wrapType)
729 {
730         TextObject* pTextObject = GetTextObjectInElement(elementId);
731
732         if (pTextObject == null)
733         {
734                 return false;
735         }
736
737         pTextObject->SetWrap(wrapType);
738
739         return true;
740 }
741
742 bool
743 _ListViewItem::SetTextSize(int elementId, float textSize)
744 {
745         _ListViewItemElementText* pElement = GetElementText(elementId);
746
747         if ((pElement != null) && (textSize > 0.0f))
748         {
749                 pElement->textSize = textSize;
750
751                 return true;
752         }
753
754         return false;
755 }
756
757 bool
758 _ListViewItem::SetTextColor(int elementId, Color textColor, ListViewItemDrawingStatus status)
759 {
760         _ListViewItemElementText* pElement = GetElementText(elementId);
761
762         if (pElement == null)
763         {
764                 return false;
765         }
766
767         pElement->textColor[status] = textColor;
768
769         return true;
770 }
771
772 bool
773 _ListViewItem::GetTextColor(int elementId, Color& textColor, ListViewItemDrawingStatus status) const
774 {
775         _ListViewItemElementText* pElement = GetElementText(elementId);
776
777         if (pElement == null)
778         {
779                 return false;
780         }
781
782         textColor = pElement->textColor[status];
783
784         return true;
785 }
786
787 void
788 _ListViewItem::AdjustProgressBounds(void)
789 {
790         if (__pProgress != null)
791         {
792                 FloatRectangle progressRect = GetBoundsF();
793                 float progressHeight = 0.0f;
794                 float bottomMargin = 0.0f;
795
796                 // Calculate progress position
797                 GET_SHAPE_CONFIG(SLIDER::BAR_HEIGHT, _CONTROL_ORIENTATION_PORTRAIT, progressHeight);
798                 GET_SHAPE_CONFIG(SLIDER::BAR_TOP_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, bottomMargin);
799
800                 progressHeight = progressHeight + (bottomMargin * 2.0f);
801                 progressRect.x = __progressLeftMargin;
802                 progressRect.y = progressRect.height - progressHeight;
803                 progressRect.height = progressHeight;
804                 progressRect.width = progressRect.width -  __progressLeftMargin - __progressRightMargin;
805
806                 progressRect.y -= ((__descriptionTextShowState) ? GetDescriptionTextHeight() : 0.0f);
807
808                 __pProgress->SetBounds(progressRect);
809         }
810 }
811
812 bool
813 _ListViewItem::SetDescriptionText(const String& text)
814 {
815         if (text.IsEmpty())
816         {
817                 if (__pDescriptionText != null)
818                 {
819                         DetachChild(*__pDescriptionText);
820
821                         delete __pDescriptionText;
822                         __pDescriptionText = null;
823                 }
824
825                 return true;
826         }
827         else
828         {
829                 if (__pDescriptionText == null)
830                 {
831                         __pDescriptionText = _Label::CreateLabelN();
832                         result r = GetLastResult();
833                         SysTryReturn(NID_UI_CTRL, (__pDescriptionText != null), r, r, "[%s] Propagating.", GetErrorMessage(r));
834
835                         __pDescriptionText->SetVisibleState(false);
836                         __pDescriptionText->SetMargin(0.0f, 0.0f, 0.0f, 0.0f);
837                         __pDescriptionText->SetTextHorizontalAlignment(ALIGNMENT_LEFT);
838
839                         AttachChild(*__pDescriptionText);
840                 }
841
842                 FloatRectangle bounds = GetBoundsF();
843                 FloatRectangle textBounds;
844                 float textSize = 0.0f;
845                 bool ret = true;
846
847                 GET_SHAPE_CONFIG(LISTVIEW::ITEM_DESCRIPTION_TEXT_LEFT_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, textBounds.x);
848                 GET_SHAPE_CONFIG(LISTVIEW::ITEM_DESCRIPTION_TEXT_TOP_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, textBounds.y);
849                 GET_SHAPE_CONFIG(LISTVIEW::ITEM_DESCRIPTION_TEXT_FONT_SIZE, _CONTROL_ORIENTATION_PORTRAIT, textSize);
850
851                 textBounds.width = bounds.width - (textBounds.x * 2.0f);
852
853                 TextObject* pText = new (std::nothrow) TextObject();
854                 SysTryReturn(NID_UI_CTRL, (pText != null), false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
855
856                 pText->Construct();
857
858                 TextSimple* pSimpleText = new (std::nothrow) TextSimple((const_cast<wchar_t*>(text.GetPointer())), text.GetLength());
859                 SysTryCatch(NID_UI_CTRL, (pSimpleText != null), (ret = false), E_OUT_OF_MEMORY, "[%s] Propagating.", GetErrorMessage(GetLastResult()));
860
861                 pText->AppendElement(*pSimpleText);
862                 pText->SetAlignment(TEXT_OBJECT_ALIGNMENT_LEFT | TEXT_OBJECT_ALIGNMENT_TOP);
863                 pText->SetWrap(TEXT_OBJECT_WRAP_TYPE_WORD);
864                 pText->SetFont(GetFont(FONT_STYLE_PLAIN, textSize), 0, pText->GetTextLength());
865                 pText->SetBounds(FloatRectangle(0.0f, 0.0f, textBounds.width, 1.0f));
866                 pText->Compose();
867
868                 textBounds.height = pText->GetTotalHeight();
869
870                 __pDescriptionText->SetBounds(FloatRectangle(textBounds.x, bounds.height + textBounds.y, textBounds.width, textBounds.height));
871                 __pDescriptionText->SetBackgroundColor(Color(0, 0, 0, 0));
872                 __pDescriptionText->SetTextColor(__descriptionTextColor);
873                 __pDescriptionText->SetTextConfig(textSize, LABEL_TEXT_STYLE_NORMAL);
874                 __pDescriptionText->SetText(text);
875
876 CATCH:
877                 delete pText;
878
879                 return ret;
880         }
881 }
882
883 void
884 _ListViewItem::SetDescriptionTextColor(const Color& color)
885 {
886         __descriptionTextColor = color;
887 }
888
889 float
890 _ListViewItem::GetDescriptionTextHeight(void)
891 {
892         if (__pDescriptionText != null)
893         {
894                 float margin = 0.0f;
895                 GET_SHAPE_CONFIG(LISTVIEW::ITEM_DESCRIPTION_TEXT_TOP_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, margin);
896
897                 return ((margin * 2.0f) + __pDescriptionText->GetBoundsF().height);
898         }
899
900         return 0.0f;
901 }
902
903 void
904 _ListViewItem::SetDescriptionTextShowState(bool show)
905 {
906         if (__descriptionTextShowState != show)
907         {
908                 __descriptionTextShowState = show;
909
910                 if (__pDescriptionText != null)
911                 {
912                         __pDescriptionText->SetVisibleState(__descriptionTextShowState);
913
914                         FloatDimension itemDimension = GetSizeF();
915                         float descriptionTextHeight = GetDescriptionTextHeight();
916
917                         itemDimension.height += ((__descriptionTextShowState) ? (descriptionTextHeight) : (-descriptionTextHeight));
918
919                         // Set position & item height
920                         SetItemCustomHeight((__descriptionTextShowState ? (itemDimension.height - descriptionTextHeight) : 0.0f));
921                         SetItemHeight(itemDimension.height);
922
923                         SetSize(itemDimension);
924
925                         _AccessibilityContainer* pContainer = GetAccessibilityContainer();
926
927                         if ((__pAccessibilityElement != null) && (pContainer != null))
928                         {
929                                 SetAccessibilityElement();
930
931                                 _AccessibilityManager::GetInstance()->RequestToDrawFocusUi();
932                         }
933                 }
934         }
935 }
936
937 void
938 _ListViewItem::SetContextItemEventListener(_IActionEventListener& listener)
939 {
940         __pContextItemEventListener = &listener;
941 }
942
943 void
944 _ListViewItem::SetContextItemActivationState(bool activate)
945 {
946         _ListViewContextItem* pContextItem = static_cast<_ListViewContextItem*>(GetContextItem());
947
948         if ((pContextItem != null) && (__pContextItemEventListener != null))
949         {
950                 if (activate)
951                 {
952                         pContextItem->AddContextItemEventListener(*__pContextItemEventListener);
953                 }
954                 else
955                 {
956                         pContextItem->RemoveContextItemEventListener(*__pContextItemEventListener);
957                 }
958         }
959 }
960
961 bool
962 _ListViewItem::OnTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
963 {
964         if ((&source != this) && (source.GetParent() != this))
965         {
966                 return false;
967         }
968
969         ClearLastStateChangedInfo();
970         StopTextSlideTimer();
971
972         FloatPoint pos = touchinfo.GetCurrentPosition();
973         __prevTouchPos.SetPosition(pos.x, pos.y);
974
975         __selectedElementId = GetElementIdFromPosition(pos);
976
977         _ListViewItemElement* pElement = GetElement(__selectedElementId);
978
979         if (pElement != null)
980         {
981                 if ((pElement->actionElement) && (pElement->selectionEnabled))
982                 {
983                         __selectionEabledBgColor = GetItemBackgroundColor(LIST_ITEM_STATE_PRESSED);
984                         SetItemBackgroundColor(LIST_ITEM_STATE_PRESSED, GetItemBackgroundColor(LIST_ITEM_STATE_NORMAL));
985
986                         __selectionEabled = true;
987                 }
988
989                 if (pElement->elementType == LISTVIEW_ITEM_ELEMENT_TEXT)
990                 {
991                         SetCutlinkTextFocus(pos);
992
993                         if (pElement->pTextElement->textSlidingEnabled)
994                         {
995                                 pElement->pTextElement->pTextObject->SetAction(TEXT_OBJECT_ACTION_TYPE_SLIDE_LEFT);
996                                 pElement->pTextElement->pTextObject->Compose();
997
998                                 if (pElement->pTextElement->pTextObject->IsActionOn())
999                                 {
1000                                         StartTextSlideTimer();
1001                                 }
1002                         }
1003                 }
1004         }
1005
1006         __touchPressed = true;
1007
1008         SetLastStateChangedInfo();
1009
1010         _TableViewItem::OnTouchPressed(source, touchinfo);
1011
1012         return false;
1013 }
1014
1015 bool
1016 _ListViewItem::OnTouchReleased(const _Control& source, const _TouchInfo& touchinfo)
1017 {
1018         if ((&source != this) && (source.GetParent() != this))
1019         {
1020                 return false;
1021         }
1022
1023         ResetTextSlide();
1024         ResetCutlinkFocus();
1025
1026         if (__selectionEabled)
1027         {
1028                 SetItemBackgroundColor(LIST_ITEM_STATE_PRESSED, __selectionEabledBgColor);
1029                 __selectionEabled = false;
1030         }
1031
1032         __selectedElementId = -1;
1033         __touchPressed = false;
1034
1035         _TableViewItem::OnTouchReleased(source, touchinfo);
1036
1037         return false;
1038 }
1039
1040 bool
1041 _ListViewItem::OnTouchMoved(const _Control& source, const _TouchInfo& touchinfo)
1042 {
1043         if (__touchPressed)
1044         {
1045                 ClearLastStateChangedInfo();
1046         }
1047
1048         ResetTextSlide();
1049
1050         __selectedElementId = -1;
1051         __touchPressed = false;
1052
1053         _TableViewItem::OnTouchMoved(source, touchinfo);
1054
1055         return false;
1056 }
1057
1058 bool
1059 _ListViewItem::OnTouchCanceled(const _Control& source, const _TouchInfo& touchinfo)
1060 {
1061         ResetTextSlide();
1062
1063         if (__selectionEabled)
1064         {
1065                 SetItemBackgroundColor(LIST_ITEM_STATE_PRESSED, __selectionEabledBgColor);
1066                 __selectionEabled = false;
1067         }
1068
1069         _TableViewItem::OnTouchCanceled(source, touchinfo);
1070
1071         return false;
1072 }
1073
1074 void
1075 _ListViewItem::OnDraw(void)
1076 {
1077         _TableViewItem::OnDraw();
1078
1079         DrawElements();
1080         DrawDivider();
1081 }
1082
1083 result
1084 _ListViewItem::OnBoundsChanging(const FloatRectangle& bounds)
1085 {
1086         FloatDimension currentSize = GetSizeF();
1087
1088         if (!_FloatCompare(currentSize.width, bounds.width) || !_FloatCompare(currentSize.height, bounds.height))
1089         {
1090                 __needAlignContextItem = true;
1091         }
1092
1093         return E_SUCCESS;
1094 }
1095
1096 void
1097 _ListViewItem::OnBoundsChanged(void)
1098 {
1099         _TableViewItem::OnBoundsChanged();
1100
1101         if (__needAlignContextItem)
1102         {
1103                 _ListViewContextItem* pContextItem = static_cast<_ListViewContextItem*>(GetContextItem());
1104
1105                 if (pContextItem != null)
1106                 {
1107                         FloatRectangle bounds = GetBoundsF();
1108                         pContextItem->AdjustItemBounds(bounds);
1109
1110                         __needAlignContextItem = false;
1111                 }
1112         }
1113 }
1114
1115 ListViewItemDrawingStatus
1116 _ListViewItem::GetItemDrawingStatus(void)
1117 {
1118         TableViewItemDrawingStatus parentStatus = GetDrawingStatus();
1119         ListViewItemDrawingStatus status;
1120
1121         switch (parentStatus)
1122         {
1123         case TABLE_VIEW_ITEM_DRAWING_STATUS_PRESSED:
1124                 status = LISTVIEW_ITEM_STATUS_PRESSED;
1125                 break;
1126
1127         case TABLE_VIEW_ITEM_DRAWING_STATUS_HIGHLIGHTED:
1128                 status = LISTVIEW_ITEM_STATUS_HIGHLIGHTED;
1129                 break;
1130
1131         default:
1132                 status = LISTVIEW_ITEM_STATUS_NORMAL;
1133                 break;
1134         }
1135
1136         return status;
1137 }
1138
1139 void
1140 _ListViewItem::DrawElement(_ListViewItemElement* pElement)
1141 {
1142         // Get Current TableViewItem drawing status
1143         ListViewItemDrawingStatus status = GetItemDrawingStatus();
1144         FloatRectangle elementRect;
1145
1146         // Check element selection enabled
1147         if (status != LISTVIEW_ITEM_STATUS_NORMAL)
1148         {
1149                 if (__selectedElementId == -1)
1150                 {
1151                         if ((pElement->actionElement) && (pElement->selectionEnabled))
1152                         {
1153                                 status = LISTVIEW_ITEM_STATUS_NORMAL;
1154                         }
1155                 }
1156                 else if (__selectedElementId != pElement->elementId)
1157                 {
1158                         bool enabled = false;
1159                         if (GetElementSelectionEnabled(__selectedElementId, enabled) && enabled)
1160                         {
1161                                 status = LISTVIEW_ITEM_STATUS_NORMAL;
1162                         }
1163                         else if ((pElement->actionElement) && (pElement->selectionEnabled))
1164                         {
1165                                 status = LISTVIEW_ITEM_STATUS_NORMAL;
1166                         }
1167                 }
1168         }
1169
1170         Canvas* pCanvas = null;
1171
1172         switch (pElement->elementType)
1173         {
1174         case LISTVIEW_ITEM_ELEMENT_TEXT:
1175                 DrawText(pElement->bounds, status, pElement->pTextElement);
1176                 break;
1177
1178         case LISTVIEW_ITEM_ELEMENT_BITMAP:
1179                 DrawBitmap(pElement->bounds, status, pElement->pBitmapElement);
1180                 break;
1181
1182         case LISTVIEW_ITEM_ELEMENT_OBJ:
1183                 pCanvas = pElement->pCustomElement->pVE->GetCanvasN();
1184
1185                 if (pCanvas != null)
1186                 {
1187                         pCanvas->SetBackgroundColor(Color(0, 0, 0, 0));
1188                         pCanvas->Clear();
1189                         elementRect.SetBounds(0.0f, 0.0f, pElement->bounds.width, pElement->bounds.height);
1190
1191                         pElement->pCustomElement->pCustom->DrawElement(pCanvas, elementRect, status);
1192                 }
1193                 break;
1194
1195         default:
1196                 break;
1197         }
1198
1199         delete pCanvas;
1200 }
1201
1202 void
1203 _ListViewItem::DrawElements(void)
1204 {
1205         _LinkedList <_ListViewItemElement>::_Iterator iter;
1206
1207         for (iter = __elements.begin(); iter != __elements.end(); iter++)
1208         {
1209                 DrawElement(&(*iter));
1210         }
1211 }
1212
1213 bool
1214 _ListViewItem::DrawText(FloatRectangle& rect, ListViewItemDrawingStatus status, _ListViewItemElementText* pText)
1215 {
1216         SysTryReturn(NID_UI_CTRL, (pText != null), false, E_INVALID_ARG, "[E_INVALID_ARG] This Text element is null.");
1217
1218         FloatRectangle bounds(rect.x, rect.y, rect.width, rect.height);
1219
1220         if (pText->pVE->GetParent() == null)
1221         {
1222                 GetVisualElement()->AttachChild(*(pText->pVE));
1223                 pText->pVE->SetShowState(true);
1224         }
1225
1226         if (pText->textSize > 0)
1227         {
1228                 pText->pTextObject->SetFont(GetFont(FONT_STYLE_PLAIN, pText->textSize), 0, pText->pTextObject->GetTextLength());
1229         }
1230
1231         // Calculate Text element bounds
1232         if (pText->pEnrichedText == null)
1233         {
1234                 FloatDimension textDimension = pText->pTextObject->GetTextExtentF(0, pText->pTextObject->GetTextLength());
1235                 TextObjectAlignment textAlign = pText->pTextObject->GetAlignment();
1236
1237                 if (__itemType == LISTVIEW_ITEM_TYPE_CUSTOM)
1238                 {
1239                         if (textDimension.width < bounds.width)
1240                         {
1241                                 bounds.width = textDimension.width;
1242
1243                                 if ((0x0007 & textAlign) == TEXT_OBJECT_ALIGNMENT_CENTER)
1244                                 {
1245                                         bounds.x = rect.x + ((rect.width - bounds.width) / 2.0f);
1246                                 }
1247                                 else if ((0x0007 & textAlign) == TEXT_OBJECT_ALIGNMENT_RIGHT)
1248                                 {
1249                                         bounds.x = rect.x + (rect.width - bounds.width);
1250                                 }
1251                         }
1252                         if (textDimension.height < bounds.height)
1253                         {
1254                                 bounds.height = textDimension.height;
1255
1256                                 if ((0x0700 & textAlign) == TEXT_OBJECT_ALIGNMENT_MIDDLE)
1257                                 {
1258                                         bounds.y = rect.y + ((rect.height - bounds.height) / 2.0f);
1259                                 }
1260                                 else if ((0x0700 & textAlign) == TEXT_OBJECT_ALIGNMENT_BOTTOM)
1261                                 {
1262                                         bounds.y = rect.y + (rect.height - bounds.height);
1263                                 }
1264                         }
1265                 }
1266                 else
1267                 {
1268                         if ((!_FloatCompare(bounds.width, textDimension.width)) || (!_FloatCompare(bounds.height, textDimension.height)))
1269                         {
1270                                 bounds.x = rect.x;
1271                                 bounds.y = rect.y + ((rect.height - textDimension.height) / 2.0f);
1272                                 bounds.width = (bounds.width > textDimension.width) ? textDimension.width : bounds.width;
1273                                 bounds.height = textDimension.height;
1274
1275                                 rect = bounds;
1276                         }
1277                 }
1278         }
1279
1280         pText->pVE->SetBounds(bounds);
1281
1282         // Check to EnrichedText contains Cutlink
1283         if ((pText->pEnrichedText != null) && (pText->cutlinkViewModeEnabled) && (pText->cutlinkParseEnabled)
1284                         && (pText->pTextObject->GetTotalCutLinkElementCount() <= 0))
1285         {
1286                 if (ParseCutlinkText(pText))
1287                 {
1288                         pText->pTextObject->SetCutLinkViewMode(true);
1289                 }
1290         }
1291         else
1292         {
1293                 if (IsItemEnabled())
1294                 {
1295                         pText->pTextObject->SetForegroundColor(pText->textColor[status], 0, pText->pTextObject->GetTextLength());
1296                 }
1297                 else
1298                 {
1299                         Color disableTextColor;
1300                         GET_COLOR_CONFIG(TABLEVIEW::ITEM_TEXT_DISABLED, disableTextColor);
1301
1302                         pText->pTextObject->SetForegroundColor(disableTextColor, 0, pText->pTextObject->GetTextLength());
1303                 }
1304         }
1305
1306         pText->pTextObject->SetAction(TEXT_OBJECT_ACTION_TYPE_ABBREV);
1307         pText->pTextObject->SetBounds(FloatRectangle(0.0f, 0.0f, bounds.width, bounds.height));
1308
1309         Canvas* pCanvas = pText->pVE->GetCanvasN();
1310         SysTryReturn(NID_UI_CTRL, (pCanvas != null), false, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1311
1312         pCanvas->SetBackgroundColor(Color(0, 0, 0, 0));
1313         pCanvas->Clear();
1314
1315         pText->pTextObject->Draw(*_CanvasImpl::GetInstance(*pCanvas));
1316
1317         delete pCanvas;
1318
1319         return true;
1320 }
1321
1322 bool
1323 _ListViewItem::DrawBitmap(FloatRectangle& rect, ListViewItemDrawingStatus status, _ListViewItemElementBitmap* pBitmap)
1324 {
1325         SysTryReturn(NID_UI_CTRL, (pBitmap != null), false, E_INVALID_ARG, "[E_INVALID_ARG] This Bitmap element is null.");
1326
1327         Bitmap* pDrawBitmap = pBitmap->pBitmap[status];
1328         if ((pDrawBitmap == null) && (status != LISTVIEW_ITEM_STATUS_NORMAL))
1329         {
1330                 pDrawBitmap = pBitmap->pBitmap[LISTVIEW_ITEM_STATUS_NORMAL];
1331         }
1332
1333         SysTryReturn(NID_UI_CTRL, (pDrawBitmap != null), false, E_INVALID_ARG, "[E_INVALID_ARG] This Bitmap element is null.");
1334
1335         if (pBitmap->pVE->GetParent() == null)
1336         {
1337                 GetVisualElement()->AttachChild(*(pBitmap->pVE));
1338                 pBitmap->pVE->SetShowState(true);
1339         }
1340
1341         pBitmap->pVE->SetBounds(rect);
1342
1343         Canvas* pCanvas = pBitmap->pVE->GetCanvasN();
1344         SysTryReturn(NID_UI_CTRL, (pCanvas != null), false, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1345
1346         pCanvas->SetBackgroundColor(Color(0, 0, 0, 0));
1347         pCanvas->Clear();
1348
1349         if (pDrawBitmap->IsNinePatchedBitmap())
1350         {
1351                 pCanvas->DrawNinePatchedBitmap(FloatRectangle(0.0f, 0.0f, rect.width, rect.height), *pDrawBitmap);
1352         }
1353         else
1354         {
1355                 pCanvas->DrawBitmap(FloatRectangle(0.0f, 0.0f, rect.width, rect.height), *pDrawBitmap);
1356         }
1357
1358         delete pCanvas;
1359
1360         return true;
1361 }
1362
1363 void
1364 _ListViewItem::DrawDivider(void)
1365 {
1366         if ((__itemType == LISTVIEW_ITEM_TYPE_GROUP) && (GetItemBackgroundBitmap(LIST_ITEM_STATE_NORMAL) == null))
1367         {
1368                 float lineHeight = 0.0f;
1369                 float lineLeftMargin = 0.0f;
1370                 float lineBottomMargin = 0.0f;
1371                 float lineTopMargin = 0.0f;
1372                 GET_SHAPE_CONFIG(LISTVIEW::GROUPITEM_DIVIDER_HEIGHT, _CONTROL_ORIENTATION_PORTRAIT, lineHeight);
1373                 GET_SHAPE_CONFIG(LISTVIEW::GROUPITEM_DIVIDER_LEFT_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, lineLeftMargin);
1374                 GET_SHAPE_CONFIG(LISTVIEW::GROUPITEM_DIVIDER_BOTTOM_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, lineBottomMargin);
1375
1376                 FloatRectangle textBounds;
1377                 FloatRectangle bitmapBounds;
1378                 _ListViewItemElementText* pElementText = GetElementText(LIST_ITEM_RESERVED_ID_3);
1379                 _ListViewItemElementBitmap* pElementBitmap = GetElementBitmap(LIST_ITEM_RESERVED_ID_2);
1380
1381                 if ((pElementText != null) && (pElementText->pVE != null))
1382                 {
1383                         textBounds = pElementText->pVE->GetBounds();
1384                 }
1385
1386                 if ((pElementBitmap != null) && (pElementBitmap->pVE != null))
1387                 {
1388                         bitmapBounds = pElementBitmap->pVE->GetBounds();
1389                 }
1390
1391                 float textBottomPos = textBounds.y + textBounds.height;
1392                 float bitmapBottomPos = bitmapBounds.y + bitmapBounds.height;
1393
1394                 lineTopMargin = (textBottomPos > bitmapBottomPos) ? textBottomPos : bitmapBottomPos;
1395
1396                 FloatRectangle bounds = GetBoundsF();
1397                 float defaultMargin = bounds.height - lineBottomMargin;
1398                 lineTopMargin = (lineTopMargin > defaultMargin) ? lineTopMargin : defaultMargin;
1399
1400                 if (bounds.height <= lineTopMargin)
1401                 {
1402                         return;
1403                 }
1404
1405                 if (__pDivider == null)
1406                 {
1407                         __pDivider = _Label::CreateLabelN();
1408                         SysTryReturnVoidResult(NID_UI_CTRL, __pDivider != null, E_OUT_OF_MEMORY, "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1409
1410                         AttachSystemChild(*__pDivider);
1411
1412                         _AccessibilityContainer* pContainer = __pDivider->GetAccessibilityContainer();
1413                         if (pContainer != null)
1414                         {
1415                                 pContainer->Activate(false);
1416                         }
1417                 }
1418
1419                 Color underLineColor;
1420                 GET_COLOR_CONFIG(TABLEVIEW::GROUPITEM_INDEX_BAR_NORMAL, underLineColor);
1421
1422                 __pDivider->SetBounds(FloatRectangle(lineLeftMargin, lineTopMargin, bounds.width - lineLeftMargin * 2.0f, lineHeight));
1423                 __pDivider->SetBackgroundColor(underLineColor);
1424                 __pDivider->Invalidate();
1425         }
1426 }
1427
1428 void
1429 _ListViewItem::StartTextSlideTimer(void)
1430 {
1431         result r = E_SUCCESS;
1432
1433         if (__pTextSlideTimer == null)
1434         {
1435                 __pTextSlideTimer = new (std::nothrow) Timer();
1436
1437                 r = __pTextSlideTimer->Construct(*this);
1438                 SysTryCatch(NID_UI, (r == E_SUCCESS), ,E_SYSTEM, ("[E_SYSTEM] Timer cannot construct."));
1439         }
1440         else
1441         {
1442                 __pTextSlideTimer->Cancel();
1443         }
1444
1445         r = __pTextSlideTimer->Start(TEXT_SLIDING_TIMER_DURATION);
1446         SysTryCatch(NID_UI, (r == E_SUCCESS), , E_SYSTEM, ("[E_SYSTEM] Timer Start failed."));
1447
1448         return;
1449
1450 CATCH:
1451         StopTextSlideTimer();
1452 }
1453
1454 void
1455 _ListViewItem::StopTextSlideTimer(void)
1456 {
1457         delete __pTextSlideTimer;
1458         __pTextSlideTimer = null;
1459 }
1460
1461 bool
1462 _ListViewItem::IsTextSlideTimerRunning(void)
1463 {
1464         return (__pTextSlideTimer != null);
1465 }
1466
1467 void
1468 _ListViewItem::OnTextSlideTimerExpired(void)
1469 {
1470         if (__selectedElementId != -1)
1471         {
1472                 _ListViewItemElement* pElement = GetElement(__selectedElementId);
1473
1474                 if ((pElement != null) && (pElement->pTextElement->pTextObject != null))
1475                 {
1476                         TextObject* pTextObject = pElement->pTextElement->pTextObject;
1477
1478                         Canvas* pCanvas = (pElement->pTextElement->pVE)->GetCanvasN();
1479                         SysTryReturnVoidResult(NID_UI_CTRL, (pCanvas != null), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1480
1481                         pCanvas->SetBackgroundColor(Color(0, 0, 0, 0));
1482                         pCanvas->Clear();
1483
1484                         pTextObject->SetForegroundColor(pElement->pTextElement->textColor[LISTVIEW_ITEM_STATUS_PRESSED], 0, pTextObject->GetTextLength());
1485                         pTextObject->SetAction(TEXT_OBJECT_ACTION_TYPE_SLIDE_LEFT);
1486                         pTextObject->Compose();
1487                         pTextObject->DrawWithOffset(*_CanvasImpl::GetInstance(*pCanvas));
1488
1489                         pCanvas->Show(_CoordinateSystemUtils::ConvertToInteger(pElement->bounds));
1490                         StartTextSlideTimer();
1491
1492                         delete pCanvas;
1493                         pCanvas = null;
1494                 }
1495         }
1496 }
1497
1498 void
1499 _ListViewItem::ResetTextSlide(void)
1500 {
1501         if (IsTextSlideTimerRunning())
1502         {
1503                 StopTextSlideTimer();
1504
1505                 _ListViewItemElement* pElement = GetElement(__selectedElementId);
1506
1507                 if ((pElement != null) && (pElement->pTextElement->pTextObject != null))
1508                 {
1509                         pElement->pTextElement->pTextObject->SetAction(TEXT_OBJECT_ACTION_TYPE_ABBREV);
1510                         pElement->pTextElement->pTextObject->SetForegroundColor(pElement->pTextElement->textColor[LISTVIEW_ITEM_STATUS_NORMAL],
1511                                         0, pElement->pTextElement->pTextObject->GetTextLength());
1512                 }
1513         }
1514 }
1515
1516 void
1517 _ListViewItem::OnTimerExpired(Timer& timer)
1518 {
1519         _TableViewItem::OnTimerExpired(timer);
1520
1521         if (&timer == __pTextSlideTimer)
1522         {
1523                 OnTextSlideTimerExpired();
1524         }
1525 }
1526
1527 bool
1528 _ListViewItem::ParseCutlinkText(_ListViewItemElementText* pElementText)
1529 {
1530         if ((pElementText == null) || (pElementText->pEnrichedText == null))
1531         {
1532                 return false;
1533         }
1534
1535         TextObject* pTextObject = pElementText->pTextObject;
1536         unsigned long cutlinkMaskType = pElementText->cutlinkMaskType;
1537         TextLinkInfo* pTextLinkInfo = null;
1538         TextLinkInfo* pNextLinkInfo = null;
1539         int currentOffset = 0;
1540         bool isChangingCutlink = false;
1541         wchar_t* pCutlinkString = null;
1542         bool ret = true;
1543
1544         int strLength = pTextObject->GetTextLength();
1545         wchar_t* pStr = new (std::nothrow) wchar_t[strLength + 1];
1546         SysTryReturn(NID_UI, (pStr != null), false, E_OUT_OF_MEMORY, ("[E_OUT_OF_MEMORY] The memory is insufficient."));
1547
1548         pTextObject->GetText(pStr, strLength);
1549
1550         TextCutLinkParser* pParser = new (std::nothrow) TextCutLinkParser();
1551         SysTryCatch(NID_UI, (pParser != null), (ret = false), E_OUT_OF_MEMORY, ("[E_OUT_OF_MEMORY] The memory is insufficient."));
1552
1553         pParser->SetCutLinkMask(cutlinkMaskType);
1554
1555         pTextLinkInfo = pParser->Parse(pStr, strLength, 0);
1556         SysTryCatch(NID_UI, (pTextLinkInfo != null), (ret = false), E_SYSTEM, ("[E_SYSTEM] TextLinkInfo is not valid."));
1557
1558         // remove all text element in _EnrichedTextImpl
1559         pElementText->pEnrichedText->RemoveAllTextElements(true);
1560
1561         while (pTextLinkInfo != null)
1562         {
1563                 isChangingCutlink = false;
1564
1565                 switch (pTextLinkInfo->linkType)
1566                 {
1567                 case LINK_TYPE_URL:
1568                         if (cutlinkMaskType & LINK_TYPE_URL)
1569                         {
1570                                 isChangingCutlink = true;
1571                         }
1572                         break;
1573
1574                 case LINK_TYPE_EMAIL:
1575                         if (cutlinkMaskType & LINK_TYPE_EMAIL)
1576                         {
1577                                 isChangingCutlink = true;
1578                         }
1579                         break;
1580
1581                 case LINK_TYPE_TEL_NUM:
1582                         if (cutlinkMaskType & LINK_TYPE_TEL_NUM)
1583                         {
1584                                 isChangingCutlink = true;
1585                         }
1586                         break;
1587
1588                 case LINK_TYPE_APPCONTROL:
1589                         if (cutlinkMaskType & LINK_TYPE_APPCONTROL)
1590                         {
1591                                 isChangingCutlink = true;
1592                         }
1593                         break;
1594
1595                 case LINK_TYPE_MIME:
1596                         if (cutlinkMaskType & LINK_TYPE_MIME)
1597                         {
1598                                 isChangingCutlink = true;
1599                         }
1600                         break;
1601
1602                 default:
1603                         break;
1604                 }
1605
1606                 pCutlinkString = new (std::nothrow) wchar_t[pTextLinkInfo->length + 1];
1607
1608                 if (pCutlinkString == null)
1609                 {
1610                         while (pTextLinkInfo != null)
1611                         {
1612                                 pNextLinkInfo = pTextLinkInfo->pNextLinkInfo;
1613                                 delete pTextLinkInfo;
1614                                 pTextLinkInfo = pNextLinkInfo;
1615                         }
1616                         SysTryCatch(NID_UI, (pTextLinkInfo != null), (ret = false), E_SYSTEM, ("[E_SYSTEM] TextLinkInfo is not valid."));
1617                 }
1618
1619                 for (int i = 0; i < pTextLinkInfo->length; i++)
1620                 {
1621                         pCutlinkString[i] = pStr[pTextLinkInfo->srcOffset + i];
1622                 }
1623
1624                 pCutlinkString[pTextLinkInfo->length] = null;
1625
1626                 if (currentOffset < pTextLinkInfo->srcOffset)
1627                 {
1628                         TextSimple* pSimpleText = new (std::nothrow) TextSimple(pStr + currentOffset, pTextLinkInfo->srcOffset - currentOffset);
1629                         pTextObject->AppendElement(*pSimpleText);
1630                 }
1631
1632                 if (isChangingCutlink == true)
1633                 {
1634                         TextCutLink* pTextElement = new (std::nothrow) TextCutLink(false, pTextLinkInfo->linkType, pStr + pTextLinkInfo->srcOffset,
1635                                                                                                                                            pTextLinkInfo->length);
1636                         pTextElement->SetEditModeEnable(true);
1637                         pTextObject->AppendElement(*pTextElement);
1638                 }
1639                 else
1640                 {
1641                         TextSimple* pSimpleText = new (std::nothrow) TextSimple(pCutlinkString, pTextLinkInfo->length);
1642                         pTextObject->AppendElement(*pSimpleText);
1643                 }
1644
1645                 currentOffset = pTextLinkInfo->srcOffset + pTextLinkInfo->length;
1646
1647                 pNextLinkInfo = pTextLinkInfo->pNextLinkInfo;
1648                 delete pTextLinkInfo;
1649                 pTextLinkInfo = pNextLinkInfo;
1650
1651                 delete[] pCutlinkString;
1652                 pCutlinkString = null;
1653         }
1654
1655         if (strLength != currentOffset)
1656         {
1657                 TextSimple* pSimpleText = new (std::nothrow) TextSimple(pStr + currentOffset, strLength - currentOffset);
1658                 pTextObject->AppendElement(*pSimpleText);
1659         }
1660
1661         //pTextObject->SetRange(0, pTextObject->GetLength());
1662         //pTextObject->NotifyTextChanged(0, pTextObject->GetLength());
1663         pTextObject->Compose();
1664
1665 CATCH:
1666         delete pParser;
1667         pParser = null;
1668
1669         if (pStr != null)
1670         {
1671                 delete[] pStr;
1672                 pStr = null;
1673         }
1674
1675         return ret;
1676 }
1677
1678 bool
1679 _ListViewItem::IsCutlinkTextSelected(const FloatPoint& position, int* index, _ListViewItemUiLinkInfo** ppInfo) const
1680 {
1681         int elementId = GetElementIdFromPosition(position);
1682         _ListViewItemElementText* pElement = GetElementText(elementId);
1683
1684         if ((pElement != null) && (pElement->pTextObject) && (pElement->cutlinkViewModeEnabled))
1685         {
1686                 TextObject* pTextObject = pElement->pTextObject;
1687                 FloatRectangle displayRect = pTextObject->GetBoundsF();
1688                 int selectedIndex = pTextObject->GetCutLinkIndexFromPositionData(position.x - displayRect.x, position.y - displayRect.y);
1689
1690                 if (selectedIndex >= 0)
1691                 {
1692                         *index = selectedIndex;
1693                         TextCutLink* pCutLinkObject = dynamic_cast<TextCutLink*>(pTextObject->GetCutLinkElementAtCutLinkElementIndex(selectedIndex));
1694                         if (pCutLinkObject == null)
1695                         {
1696                                 return false;
1697                         }
1698
1699                         String cutLinkString(pCutLinkObject->GetText());
1700                         LinkType baseLinkType = pCutLinkObject->GetCutLinkType();
1701
1702                         if (baseLinkType & pElement->cutlinkMaskType)
1703                         {
1704                                 _ListViewItemUiLinkInfo* pUiLinkInfo = new (std::nothrow) _ListViewItemUiLinkInfo();
1705
1706                                 pUiLinkInfo->textInfo = cutLinkString;
1707                                 pUiLinkInfo->linkType = baseLinkType;
1708                                 pUiLinkInfo->linkInfo = cutLinkString;
1709
1710                                 *ppInfo = pUiLinkInfo;
1711                         }
1712                 }
1713
1714                 return true;
1715         }
1716
1717         return false;
1718 }
1719
1720 bool
1721 _ListViewItem::SetCutlinkTextFocus(const FloatPoint& position)
1722 {
1723         int elementId = GetElementIdFromPosition(position);
1724         _ListViewItemElementText* pElement = GetElementText(elementId);
1725
1726         if ((pElement != null) && (pElement->pTextObject != null) && (pElement->cutlinkViewModeEnabled))
1727         {
1728                 TextObject* pTextObject = pElement->pTextObject;
1729                 FloatRectangle displayRect = pTextObject->GetBoundsF();
1730
1731                 int index = pTextObject->GetCutLinkIndexFromPositionData(position.x - displayRect.x, position.y - displayRect.y);
1732
1733                 if (index >= 0)
1734                 {
1735                         pTextObject->ChangeCutLinkState(index, true);
1736                         return true;
1737                 }
1738         }
1739
1740         return false;
1741 }
1742
1743 bool
1744 _ListViewItem::ResetCutlinkFocus(void)
1745 {
1746         _LinkedList <_ListViewItemElement>::_Iterator iter;
1747
1748         for (iter = __elements.begin(); iter != __elements.end(); iter++)
1749         {
1750                 if ((iter->elementType == LISTVIEW_ITEM_ELEMENT_TEXT) && (iter->pTextElement->pTextObject))
1751                 {
1752                         iter->pTextElement->pTextObject->ResetAllCutLinkElementsState();
1753                 }
1754         }
1755
1756         return true;
1757 }
1758
1759 Font*
1760 _ListViewItem::GetFont(unsigned long fontStyle, float fontSize)
1761 {
1762         __fontStyle = fontStyle;
1763         __fontSize = fontSize;
1764
1765         return GetFallbackFont();
1766 }
1767
1768 void
1769 _ListViewItem::OnFontChanged(Font* pFont)
1770 {
1771         __fontName = _Control::GetFont();
1772
1773         if (__pDescriptionText != null)
1774         {
1775                 __pDescriptionText->SetFont(__fontName);
1776         }
1777
1778         if (GetContextItem() != null)
1779         {
1780                 GetContextItem()->SetFont(__fontName);
1781         }
1782 }
1783
1784 void
1785 _ListViewItem::OnFontInfoRequested(unsigned long& style, int& size)
1786 {
1787         style = __fontStyle;
1788         size = _CoordinateSystemUtils::ConvertToInteger(__fontSize);
1789 }
1790
1791 void
1792 _ListViewItem::OnFontInfoRequested(unsigned long& style, float& size)
1793 {
1794         style = __fontStyle;
1795         size =  __fontSize;
1796 }
1797 void
1798 _ListViewItem::OnAncestorEnableStateChanged(const _Control& control)
1799 {
1800         _LinkedList <_ListViewItemElement>::_Iterator iter;
1801
1802         for (iter = __elements.begin(); iter != __elements.end(); iter++)
1803         {
1804                 if (iter->elementType == LISTVIEW_ITEM_ELEMENT_TEXT)
1805                 {
1806                         DrawText(iter->bounds, GetItemDrawingStatus(), iter->pTextElement);
1807                 }
1808         }
1809 }
1810
1811 bool
1812 CompareAccessibilityElement(_ListViewItemElement* a, _ListViewItemElement* b)
1813 {
1814         if (_FloatCompare(a->bounds.y, b->bounds.y))
1815         {
1816                 return (a->bounds.x < b->bounds.x);
1817         }
1818
1819         return (a->bounds.y < b->bounds.y);
1820 }
1821
1822 void
1823 _ListViewItem::SetAccessibilityElement(void)
1824 {
1825         if (!_AccessibilityManager::IsActivated())
1826         {
1827                 return;
1828         }
1829
1830         _AccessibilityContainer* pContainer = GetAccessibilityContainer();
1831
1832         if (pContainer != null)
1833         {
1834                 if (__pAccessibilityElement == null)
1835                 {
1836                         _LinkedList <_ListViewItemElement*> accessibilityElementList;
1837                         _LinkedList <_ListViewItemElement>::_Iterator iter;
1838
1839                         for (iter = __elements.begin(); iter != __elements.end(); iter++)
1840                         {
1841                                 if (iter->elementType == LISTVIEW_ITEM_ELEMENT_TEXT)
1842                                 {
1843                                         accessibilityElementList.push_back(&(*iter));
1844                                 }
1845                         }
1846
1847                         accessibilityElementList.sort(CompareAccessibilityElement);
1848
1849                         _LinkedList <_ListViewItemElement*>::_Iterator accessibilityIter;
1850                         _ListViewItemElement* pElement = null;
1851                         String accessibilityLable;
1852
1853                         for (accessibilityIter = accessibilityElementList.begin(); accessibilityIter != accessibilityElementList.end(); accessibilityIter++)
1854                         {
1855                                 pElement = *accessibilityIter;
1856
1857                                 int textLength = pElement->pTextElement->pTextObject->GetTextLength();
1858
1859                                 if (textLength > 0)
1860                                 {
1861                                         wchar_t* pAccessibilityText = new (std::nothrow) wchar_t[textLength + 1];
1862                                         SysTryReturnVoidResult(NID_UI_CTRL, (pAccessibilityText != null), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
1863
1864                                         pElement->pTextElement->pTextObject->GetText(pAccessibilityText, textLength);
1865
1866                                         accessibilityLable += String(pAccessibilityText);
1867
1868                                         delete[] pAccessibilityText;
1869                                 }
1870                         }
1871
1872                         accessibilityElementList.clear();
1873
1874                         __pAccessibilityElement = new (std::nothrow) _AccessibilityElement(true);
1875                         SysTryReturnVoidResult(NID_UI_CTRL, (__pAccessibilityElement != null), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
1876
1877                         __pAccessibilityElement->SetBounds(Rectangle(0, 0, _CoordinateSystemUtils::ConvertToInteger(GetBoundsF().width), _CoordinateSystemUtils::ConvertToInteger(GetBoundsF().height)));
1878                         __pAccessibilityElement->SetTrait(ACCESSIBILITY_TRAITS_NONE);
1879                         __pAccessibilityElement->SetName(L"ListViewItem");
1880
1881                         if (accessibilityLable.IsEmpty())
1882                         {
1883                                 accessibilityLable = L"ListViewItem";
1884                         }
1885
1886                         __pAccessibilityElement->SetLabel(accessibilityLable);
1887
1888                         pContainer->AddElement(*__pAccessibilityElement);
1889                 }
1890                 else
1891                 {
1892                         __pAccessibilityElement->SetBounds(Rectangle(0, 0, _CoordinateSystemUtils::ConvertToInteger(GetBoundsF().width), _CoordinateSystemUtils::ConvertToInteger(GetBoundsF().height)));
1893                 }
1894         }
1895 }
1896
1897 void
1898 _ListViewItem::SetAccessibilityElementLabel(void)
1899 {
1900         // nothing
1901 }
1902
1903 _ListViewItemHitTestVEDelegator::_ListViewItemHitTestVEDelegator(void)
1904 {
1905 }
1906
1907 _ListViewItemHitTestVEDelegator::~_ListViewItemHitTestVEDelegator(void)
1908 {
1909 }
1910
1911 HitTestResult
1912 _ListViewItemHitTestVEDelegator::HitTest(VisualElement& target, const FloatPoint& point)
1913 {
1914         return HIT_TEST_NOWHERE;
1915 }
1916
1917 }}} // Tizen::Ui::Controls