Revert " modify license, permission and remove ^M char"
[framework/osp/uifw.git] / src / ui / controls / FUiCtrl_FastScrollPresenter.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_FastScrollPresenter.cpp
20  * @brief               This is the implementation file for the _FastScrollPresenter class.
21  */
22 #include <wchar.h>
23 #include <FBaseErrors.h>
24 #include <FBaseString.h>
25
26 #include <FGrpColor.h>
27 #include <FGrpRectangle.h>
28 #include <FGrpCanvas.h>
29 #include <FGrpBitmap.h>
30 #include <FUiAnimVisualElementAnimation.h>
31 #include <FUiAnimVisualElementAnimationProvider.h>
32 #include <FUiAnimIVisualElementAnimationStatusEventListener.h>
33 #include <FUiAnimVisualElementContentProvider.h>
34 #include <FUiAnimIVisualElementContentProvider.h>
35 #include <FUiAnimVisualElement.h>
36 #include <FBaseSysLog.h>
37 #include <FGrp_BitmapImpl.h>
38 #include "FGrp_TextTextObject.h"
39 #include <FGrp_TextTextSimple.h>
40 #include "FUiAnim_VisualElement.h"
41 #include "FUi_Control.h"
42 #include "FUi_UiTouchEvent.h"
43 #include "FUi_ResourceManager.h"
44 #include "FUi_CoordinateSystemUtils.h"
45 #include "FUi_Math.h"
46 #include "FUiCtrl_IFastScrollListener.h"
47 #include "FUiCtrl_UiFastScrollEvent.h"
48 #include "FUiCtrl_UiFastScrollEventArg.h"
49 #include "FUiCtrl_FastScroll.h"
50 #include "FUiCtrl_FastScrollPresenter.h"
51 #include "FUiCtrl_FastScrollModel.h"
52 #include "FUiCtrl_FastScrollIndex.h"
53
54 #include "FUiAnim_MatrixUtil.h"
55
56 using namespace Tizen::Base;
57 using namespace Tizen::Graphics;
58 using namespace Tizen::Ui;
59 using namespace Tizen::Ui::Animations;
60 using namespace Tizen::Graphics::_Text;
61
62 namespace
63 {
64 const float FASTSCROLL_OPACITY_ON = 1.0f;
65 const float FASTSCROLL_OPACITY_SELECTEDBG_DIM = 0.5f;
66 const float FASTSCROLL_OPACITY_LIGHT_DIM = 0.3f;
67 const float FASTSCROLL_OPACITY_OFF = 0.0f;
68 const int FASTSCROLL_POPUPINDEX_COUNT = 3;
69 }
70
71 namespace Tizen { namespace Ui { namespace Controls
72 {
73
74 _FastScrollViewConfig::_FastScrollViewConfig(void)
75         : __indexBgColor(Color::GetColor(COLOR_ID_BLACK))
76         , __indexHighlightColor(Color::GetColor(COLOR_ID_BLACK))
77         , __indexSelectedLineColor(Color::GetColor(COLOR_ID_BLACK))
78         , __indexTextColor(Color::GetColor(COLOR_ID_BLACK))
79         , __indexDividerColor(Color::GetColor(COLOR_ID_BLACK))
80         , __selectedIndexBgColor(Color::GetColor(COLOR_ID_BLACK))
81         , __selectedIndexTextColor(Color::GetColor(COLOR_ID_BLACK))
82         , __popupBgColor(Color::GetColor(COLOR_ID_BLACK))
83         , __popupTextColor(Color::GetColor(COLOR_ID_BLACK))
84         , __indexSizeMin(0.0f, 0.0f)
85         , __popupSize(0.0f, 0.0f)
86         , __indexMarginTop(0.0f)
87         , __indexGap(0.0f)
88         , __indexLeftLineThickness(0.0f)
89         , __indexTextSize(0.0f)
90         , __indexSeparatorThickness(0.0f)
91         , __selectedIndexMarginRight(0.0f)
92         , __selectedIndexHeight(0.0f)
93         , __popupWidthIncrement(0.0f)
94         , __popupTextSize(0.0f)
95         , __popupShadowRight(0.0f)
96         , __popupShadowBottom(0.0f)
97         , __pIndexBgBitmap(null)
98         , __pSelectedIndexBgBitmap(null)
99         , __pSelectedIndexlineBitmap(null)
100         , __pPopupBgBitmap(null)
101         , __pPopupBgEffectBitmap(null)
102         , __pFont(null)
103 {
104 }
105
106 _FastScrollViewConfig::~_FastScrollViewConfig(void)
107 {
108         ReleaseResources();
109 }
110
111 _FastScrollViewConfig*
112 _FastScrollViewConfig::CreateFastScrollViewConfigN(_ControlOrientation orientation)
113 {
114         _FastScrollViewConfig* pConfig = new (std::nothrow) _FastScrollViewConfig();
115         SysTryReturn(NID_UI_CTRL, pConfig, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
116
117         result r = pConfig->Construct(orientation);
118         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
119
120         SetLastResult(E_SUCCESS);
121         return pConfig;
122
123 CATCH:
124         delete pConfig;
125
126         return null;
127 }
128
129 result
130 _FastScrollViewConfig::ReloadConfig(_ControlOrientation orientation)
131 {
132         result r = E_SUCCESS;
133
134         // release allocated resources.
135         ReleaseResources();
136
137         // load bitmap resources
138         r = GET_BITMAP_CONFIG_N(FASTSCROLL::INDEX_BG_NORMAL, BITMAP_PIXEL_FORMAT_ARGB8888, __pIndexBgBitmap);
139         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to load image.");
140
141         r = GET_BITMAP_CONFIG_N(FASTSCROLL::INDEX_BG_PRESSED, BITMAP_PIXEL_FORMAT_ARGB8888, __pSelectedIndexBgBitmap);
142         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to load image.");
143
144         r = GET_BITMAP_CONFIG_N(FASTSCROLL::INDEX_LINE_PRESSED, BITMAP_PIXEL_FORMAT_ARGB8888, __pSelectedIndexlineBitmap);
145         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to load image.");
146
147         r = GET_BITMAP_CONFIG_N(FASTSCROLL::POPUP_BG_NORMAL, BITMAP_PIXEL_FORMAT_ARGB8888, __pPopupBgBitmap);
148         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to load image.");
149
150         r = GET_BITMAP_CONFIG_N(FASTSCROLL::POPUP_BG_EFFECT, BITMAP_PIXEL_FORMAT_ARGB8888, __pPopupBgEffectBitmap);
151         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to load image.");
152
153
154         // load shape configuration
155         r = GET_SHAPE_CONFIG(FASTSCROLL::INDEX_WIDTH, _CONTROL_ORIENTATION_PORTRAIT, __indexSizeMin.width);
156         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
157
158         r = GET_SHAPE_CONFIG(FASTSCROLL::INDEX_HEIGHT, _CONTROL_ORIENTATION_PORTRAIT, __indexSizeMin.height);
159         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
160
161         r = GET_SHAPE_CONFIG(FASTSCROLL::INDEX_TOP_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, __indexMarginTop);
162         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
163
164         r = GET_SHAPE_CONFIG(FASTSCROLL::INDEX_LEFT_LINE_THICKNESS, _CONTROL_ORIENTATION_PORTRAIT, __indexLeftLineThickness);
165         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
166
167         r = GET_SHAPE_CONFIG(FASTSCROLL::INDEX_TEXT_SIZE, _CONTROL_ORIENTATION_PORTRAIT, __indexTextSize);
168         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
169
170         r = GET_FIXED_VALUE_CONFIG(FASTSCROLL::INDEX_SEPARATOR_THICKNESS, _CONTROL_ORIENTATION_PORTRAIT, __indexSeparatorThickness);
171         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
172
173         r = GET_SHAPE_CONFIG(FASTSCROLL::SELECTED_INDEX_RIGHT_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, __selectedIndexMarginRight);
174         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
175
176         r = GET_SHAPE_CONFIG(FASTSCROLL::SELECTED_INDEX_HEIGHT, _CONTROL_ORIENTATION_PORTRAIT, __selectedIndexHeight);
177         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
178
179         r = GET_SHAPE_CONFIG(FASTSCROLL::POPUP_WIDTH, _CONTROL_ORIENTATION_PORTRAIT, __popupSize.width);
180         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
181
182         r = GET_SHAPE_CONFIG(FASTSCROLL::POPUP_HEIGHT, _CONTROL_ORIENTATION_PORTRAIT, __popupSize.height);
183         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
184
185         r = GET_SHAPE_CONFIG(FASTSCROLL::POPUP_WIDTH_INCREMENT, _CONTROL_ORIENTATION_PORTRAIT, __popupWidthIncrement);
186         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
187
188         r = GET_SHAPE_CONFIG(FASTSCROLL::POPUP_TEXT_SIZE, _CONTROL_ORIENTATION_PORTRAIT, __popupTextSize);
189         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
190
191         r = GET_SHAPE_CONFIG(FASTSCROLL::POPUP_RIGHT_SHADOW, _CONTROL_ORIENTATION_PORTRAIT, __popupShadowRight);
192         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
193
194         r = GET_SHAPE_CONFIG(FASTSCROLL::POPUP_BOTTOM_SHADOW, _CONTROL_ORIENTATION_PORTRAIT, __popupShadowBottom);
195         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
196
197
198         // load color configuration
199         r = GET_COLOR_CONFIG(FASTSCROLL::INDEX_BG_NORMAL, __indexBgColor);
200         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
201
202         r = GET_COLOR_CONFIG(FASTSCROLL::INDEX_LINE_PRESSED, __indexSelectedLineColor);
203         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
204
205         r = GET_COLOR_CONFIG(FASTSCROLL::INDEX_TEXT_NORMAL, __indexTextColor);
206         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
207
208         r = GET_COLOR_CONFIG(FASTSCROLL::INDEX_DIVIDER_NORMAL, __indexDividerColor);
209         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
210
211         r = GET_COLOR_CONFIG(FASTSCROLL::INDEX_BG_PRESSED, __selectedIndexBgColor);
212         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
213
214         r = GET_COLOR_CONFIG(FASTSCROLL::INDEX_TEXT_PRESSED, __selectedIndexTextColor);
215         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
216
217         r = GET_COLOR_CONFIG(FASTSCROLL::POPUP_BG_NORMAL, __popupBgColor);
218         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
219
220         r = GET_COLOR_CONFIG(FASTSCROLL::POPUP_TEXT_NORMAL, __popupTextColor);
221         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Failed to get resource.");
222
223         return E_SUCCESS;
224
225 CATCH:
226         __indexBgColor = Color::GetColor(COLOR_ID_BLACK);
227         __indexHighlightColor = Color::GetColor(COLOR_ID_BLACK);
228         __indexSelectedLineColor= Color::GetColor(COLOR_ID_BLACK);
229         __indexTextColor = Color::GetColor(COLOR_ID_BLACK);
230         __indexDividerColor= Color::GetColor(COLOR_ID_BLACK);
231         __selectedIndexBgColor = Color::GetColor(COLOR_ID_BLACK);
232         __selectedIndexTextColor = Color::GetColor(COLOR_ID_BLACK);
233         __popupBgColor = Color::GetColor(COLOR_ID_BLACK);
234         __popupTextColor = Color::GetColor(COLOR_ID_BLACK);
235
236         __indexSizeMin.SetSize(0.0f, 0.0f);
237         __popupSize.SetSize(0.0f, 0.0f);
238
239         __indexMarginTop = 0.0f;
240         __indexGap = 0.0f;
241         __indexLeftLineThickness = 0.0f;
242         __indexTextSize = 0.0f;
243         __indexSeparatorThickness = 0.0f;
244         __selectedIndexMarginRight = 0.0f;
245         __selectedIndexHeight = 0.0f;
246         __popupWidthIncrement = 0.0f;
247         __popupTextSize = 0.0f;
248         __popupShadowRight = 0.0f;
249         __popupShadowBottom = 0.0f;
250
251         ReleaseResources();
252
253         return E_SYSTEM;
254 }
255
256 void
257 _FastScrollViewConfig::ReleaseResources(void)
258 {
259         delete __pIndexBgBitmap;
260         delete __pSelectedIndexBgBitmap;
261         delete __pSelectedIndexlineBitmap;
262         delete __pPopupBgBitmap;
263         delete __pPopupBgEffectBitmap;
264
265         __pIndexBgBitmap = null;
266         __pSelectedIndexBgBitmap = null;
267         __pSelectedIndexlineBitmap = null;
268         __pPopupBgBitmap = null;
269         __pPopupBgEffectBitmap = null;
270 }
271
272 result
273 _FastScrollViewConfig::Construct(_ControlOrientation orientation)
274 {
275         return ReloadConfig(orientation);
276 }
277
278
279 _FastScrollIndexView::_FastScrollIndexView(_VisualElement& parentVe, _FastScrollViewConfig& viewConfig)
280         : __parentVe(parentVe)
281         , __viewConfig(viewConfig)
282         , __pBaseIndex(null)
283         , __pSelectedIndex(null)
284         , __pSelectedIndexInOmittedIndex(null)
285         , __pFormerIndex(null)
286         , __pBaseIndexVe(null)
287         , __pSelectedBgVe(null)
288         , __pSelectedIndexVe(null)
289         , __needUpdateBaseIndex(false)
290         , __needUpdateSelectedIndex(false)
291         , __needDestroySelf(false)
292 {
293 }
294
295 _FastScrollIndexView::~_FastScrollIndexView(void)
296 {
297         if (__pSelectedIndexVe)
298         {
299                 __pSelectedIndexVe->RemoveAllAnimations();
300                 __pSelectedIndexVe->SetAnimationProvider(null);
301
302                 __pSelectedIndexVe->Destroy();
303                 __pSelectedIndexVe = null;
304         }
305
306         if (__pSelectedBgVe)
307         {
308                 __pSelectedBgVe->RemoveAllAnimations();
309                 __pSelectedBgVe->SetAnimationProvider(null);
310
311                 __pSelectedBgVe->Destroy();
312                 __pSelectedBgVe = null;
313         }
314
315         if (__pBaseIndexVe)
316         {
317                 __pBaseIndexVe->RemoveAllAnimations();
318                 __pBaseIndexVe->SetAnimationProvider(null);
319
320                 __pBaseIndexVe->Destroy();
321                 __pBaseIndexVe = null;
322         }
323 }
324
325 _FastScrollIndexView*
326 _FastScrollIndexView::CreateFastScrollIndexViewN(_VisualElement& parentVe, _FastScrollViewConfig& viewConfig)
327 {
328         _FastScrollIndexView* pIndexView = new (std::nothrow) _FastScrollIndexView(parentVe, viewConfig);
329         SysTryReturn(NID_UI_CTRL, pIndexView, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
330
331         result r = pIndexView->Construct();
332         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
333
334         SetLastResult(E_SUCCESS);
335         return pIndexView;
336
337 CATCH:
338         delete pIndexView;
339
340         return null;
341 }
342
343 result
344 _FastScrollIndexView::FadeOutAndDestroy(void)
345 {
346         __needDestroySelf = true;
347         if (__pSelectedIndexVe)
348         {
349                 __pSelectedIndexVe->RemoveAllAnimations();
350         }
351
352         if (__pSelectedBgVe)
353         {
354                 __pSelectedBgVe->RemoveAllAnimations();
355         }
356
357         return SetIndexVisibility(false);
358 }
359
360 result
361 _FastScrollIndexView::SetBaseIndex(_FastScrollIndex* pIndex)
362 {
363         __pBaseIndex = pIndex;
364
365         result r = UpdateIndex(false);
366         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to update the index view.");
367
368         return E_SUCCESS;
369 }
370
371 _FastScrollIndex*
372 _FastScrollIndexView::GetBaseIndex(void) const
373 {
374         return __pBaseIndex;
375 }
376
377 result
378 _FastScrollIndexView::SetIndexBounds(const FloatRectangle& indexBounds)
379 {
380         SysTryReturnResult(NID_UI_CTRL, __pSelectedIndexVe, E_INVALID_STATE, "__pSelectedIndexVe must not be null.");
381
382         FloatRectangle veBounds(indexBounds.x, indexBounds.y, indexBounds.width, indexBounds.height);
383         __pBaseIndexVe->SetBounds(veBounds);
384
385         __needUpdateBaseIndex = true;
386
387         veBounds.x = 0.0f;
388         veBounds.y = 0.0f;
389         __pSelectedIndexVe->SetBounds(veBounds);
390
391         __needUpdateSelectedIndex = true;
392
393         return E_SUCCESS;
394 }
395
396 Rectangle
397 _FastScrollIndexView::GetIndexBounds(void) const
398 {
399         FloatRectangle veBounds = __pBaseIndexVe->GetBounds();
400         return Rectangle(veBounds.x, veBounds.y, veBounds.width, veBounds.height);
401 }
402
403 FloatRectangle
404 _FastScrollIndexView::GetIndexBoundsF(void) const
405 {
406         return __pBaseIndexVe->GetBounds();
407 }
408
409 _FastScrollIndex*
410 _FastScrollIndexView::GetIndexAtPoint(const FloatPoint& point) const
411 {
412         SysTryReturn(NID_UI_CTRL, __pBaseIndex, null, E_INVALID_STATE, "[E_INVALID_STATE] __pBaseIndex must not be null.");
413
414         int childCount = __pBaseIndex->GetChildCount(__pBaseIndex->GetIndexType());
415         SysTryReturn(NID_UI_CTRL, childCount > 0, null, E_INVALID_STATE, "[E_INVALID_STATE] The index have no children.");
416
417         _FastScrollIndex* pChildIndex = null;
418
419         FloatRectangle bounds = __pBaseIndexVe->GetBounds();
420         if (bounds.Contains(point) == true)
421         {
422                 float touchY = point.y - bounds.y - __viewConfig.__indexMarginTop;
423                 float indexHeight = GetIndexHeight();
424                 int indexOrder = 0;
425
426                 if (!(_FloatCompare(touchY, 0.0f) || _FloatCompare(indexHeight, 0.0f)))
427                 {
428                         indexOrder = _CoordinateSystemUtils::ConvertToInteger(touchY / indexHeight);
429                 }
430
431                 pChildIndex = __pBaseIndex->GetChildIndex(indexOrder, true);
432                 SysTryReturn(NID_UI_CTRL, pChildIndex, null, GetLastResult(), "[%s] Failed to get the child index.",
433                                 GetErrorMessage(GetLastResult()));
434         }
435
436         SetLastResult(E_SUCCESS);
437         return pChildIndex;
438 }
439
440 _FastScrollIndex*
441 _FastScrollIndexView::GetOmissionIndexAtPoint(_FastScrollIndex* pIndex, const FloatPoint& point) const
442 {
443         FloatRectangle bounds = __pBaseIndexVe->GetBounds();
444         float touchY = point.y - bounds.y - __viewConfig.__indexMarginTop - (pIndex->GetIndexOrder(true) * GetIndexHeight());
445         float indexHeight = GetIndexHeight() / pIndex->GetChildCount();
446         int omissionIndexOrder = 0;
447
448         if (!(_FloatCompare(touchY, 0.0f) || _FloatCompare(indexHeight, 0.0f)))
449         {
450                 omissionIndexOrder = _CoordinateSystemUtils::ConvertToInteger(touchY / indexHeight);
451         }
452
453         _FastScrollIndex* pChildIndex = pIndex->GetChildIndex(omissionIndexOrder);
454         SysTryReturn(NID_UI_CTRL, pChildIndex, null, GetLastResult(), "[%s] Failed to get the child index.",
455                                 GetErrorMessage(GetLastResult()));
456
457         SetLastResult(E_SUCCESS);
458         return pChildIndex;
459 }
460
461 float
462 _FastScrollIndexView::GetIndexHeight(void) const
463 {
464         FloatRectangle bounds = __pBaseIndexVe->GetBounds();
465         float indexHeight = __viewConfig.__indexSizeMin.height;
466
467         if (__pBaseIndex->GetParentIndex() == null)
468         {
469                 float indexHeightPerChild = (bounds.height - __viewConfig.__indexMarginTop * 2.0f) / (__pBaseIndex->GetChildCount(__pBaseIndex->GetIndexType()));
470                 if (indexHeight < indexHeightPerChild)
471                 {
472                         indexHeight = indexHeightPerChild;
473                 }
474         }
475
476         return indexHeight;
477 }
478
479 result
480 _FastScrollIndexView::SelectIndex(int indexOrder)
481 {
482         result r = E_SUCCESS;
483
484         SysTryReturnResult(NID_UI_CTRL, __pBaseIndex, E_INVALID_STATE, "__pBaseIndex must not be null.");
485
486         _FastScrollIndex* pIndex = __pBaseIndex->GetChildIndex(indexOrder, true);
487         SysTryReturnResult(NID_UI_CTRL, pIndex, GetLastResult(), "Failed to get the child index.");
488
489         r = SelectIndex(pIndex, false);
490         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to select the index.");
491
492         return E_SUCCESS;
493 }
494
495 result
496 _FastScrollIndexView::SelectIndex(_FastScrollIndex* pIndex, bool animation)
497 {
498         result r = E_SUCCESS;
499
500         if (__pSelectedIndex == pIndex)
501         {
502                 return E_SUCCESS;
503         }
504
505         __pSelectedIndex = pIndex;
506
507         if (__pSelectedIndex)
508         {
509                 __pSelectedBgVe->SetBounds(CalculateSelectedBg());
510                 if (GetSelectedIndexVisibility() == false)
511                 {
512                         r = SetSelectedIndexVisibility(true, animation);
513                         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to set visibility of the Selected Bg ve.");
514                 }
515         }
516         else
517         {
518                 if (GetSelectedIndexVisibility() == true)
519                 {
520                         r = SetSelectedIndexVisibility(false, animation);
521                         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to set visibility of the Selected Bg ve.");
522                 }
523                 SetSelectedIndexInOmittedIndex(null);
524                 __pFormerIndex = null;
525         }
526
527         r = UpdateIndex(false);
528         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to update the index view.");
529
530         return E_SUCCESS;
531 }
532
533 int
534 _FastScrollIndexView::GetSelectedIndexOrder(void) const
535 {
536         SysTryReturn(NID_UI_CTRL, __pBaseIndex, -1, E_INVALID_STATE, "[E_INVALID_STATE] __pBaseIndex must not be null.");
537         SysTryReturn(NID_UI_CTRL, __pSelectedIndex, -1, E_INVALID_STATE, "[E_INVALID_STATE] __pSelectedIndex must not be null.");
538
539         return __pBaseIndex->GetChildOrder(__pSelectedIndex, true);
540 }
541
542 void
543 _FastScrollIndexView::SetSelectedIndex(_FastScrollIndex* pIndex)
544 {
545         __pSelectedIndex = pIndex;
546 }
547
548 _FastScrollIndex*
549 _FastScrollIndexView::GetSelectedIndex(void) const
550 {
551         return __pSelectedIndex;
552 }
553
554 void
555 _FastScrollIndexView::SetSelectedIndexInOmittedIndex(_FastScrollIndex* pIndex)
556 {
557         __pFormerIndex = __pSelectedIndexInOmittedIndex;
558         __pSelectedIndexInOmittedIndex = pIndex;
559 }
560
561 _FastScrollIndex*
562 _FastScrollIndexView::GetSelectedIndexInOmittedIndex(void) const
563 {
564         return __pSelectedIndexInOmittedIndex;
565 }
566
567 _FastScrollIndex*
568 _FastScrollIndexView::GetFormerIndex(void) const
569 {
570         return __pFormerIndex;
571 }
572
573 bool
574 _FastScrollIndexView::IsOnAnimation(void) const
575 {
576         return false;
577 }
578
579 void
580 _FastScrollIndexView::RemoveAllAnimations(void)
581 {
582         __pBaseIndexVe->RemoveAllAnimations();
583 }
584
585 result
586 _FastScrollIndexView::SetIndexVisibility(bool visibility)
587 {
588         result r = E_SUCCESS;
589
590         __pBaseIndexVe->SetImplicitAnimationEnabled(true);
591
592                 if (visibility)
593                 {
594                         __pBaseIndexVe->SetOpacity(FASTSCROLL_OPACITY_ON);
595                 }
596                 else
597                 {
598                         __pBaseIndexVe->SetOpacity(FASTSCROLL_OPACITY_OFF);
599                 }
600                 // else keep up current visibility.
601
602         __pBaseIndexVe->SetImplicitAnimationEnabled(false);
603
604         return r;
605 }
606
607 bool
608 _FastScrollIndexView::GetIndexVisibility(void) const
609 {
610         float opacity = __pBaseIndexVe->GetOpacity();
611         if (opacity > FASTSCROLL_OPACITY_OFF)
612         {
613                 return true;
614         }
615         else
616         {
617                 return false;
618         }
619 }
620
621 result
622 _FastScrollIndexView::SetSelectedIndexVisibility(bool visibility, bool animation)
623 {
624         SysTryReturnResult(NID_UI_CTRL, __pSelectedIndexVe, E_INVALID_STATE, "__pSelectedIndexVe must not be null.");
625         SysTryReturnResult(NID_UI_CTRL, __pSelectedBgVe, E_INVALID_STATE, "__pSelectedBgVe must not be null.");
626
627         if (animation)
628         {
629                 __pSelectedIndexVe->SetImplicitAnimationEnabled(true);
630                 __pSelectedBgVe->SetImplicitAnimationEnabled(true);
631         }
632
633         if (visibility)
634         {
635                 __pSelectedIndexVe->SetOpacity(FASTSCROLL_OPACITY_ON);
636                 __pSelectedBgVe->SetOpacity(FASTSCROLL_OPACITY_SELECTEDBG_DIM);
637         }
638         else
639         {
640                 __pSelectedIndexVe->SetOpacity(FASTSCROLL_OPACITY_OFF);
641                 __pSelectedBgVe->SetOpacity(FASTSCROLL_OPACITY_OFF);
642         }
643         // else keep up current visibility.
644
645         __pSelectedIndexVe->SetImplicitAnimationEnabled(false);
646         __pSelectedBgVe->SetImplicitAnimationEnabled(false);
647
648         return E_SUCCESS;
649 }
650
651 bool
652 _FastScrollIndexView::GetSelectedIndexVisibility(void) const
653 {
654         SysTryReturn(NID_UI_CTRL, __pSelectedIndexVe, false, E_INVALID_STATE, "[E_INVALID_STATE] __pSelectedIndexVe must not be null.");
655
656         float opacity = __pSelectedIndexVe->GetOpacity();
657         if (opacity > FASTSCROLL_OPACITY_OFF)
658         {
659                 return true;
660         }
661
662         return false;
663 }
664
665
666 result
667 _FastScrollIndexView::UpdateIndex(bool bNeedUpdateBaseIndex)
668 {
669         result r = E_SUCCESS;
670
671         r = __parentVe.InvalidateRectangle(null);
672         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to invalidate the index Ve.");
673
674         if (__pSelectedIndex)
675         {
676                 __needUpdateSelectedIndex = true;
677         }
678
679         if (bNeedUpdateBaseIndex)
680         {
681                 __needUpdateBaseIndex = true;
682         }
683
684         return E_SUCCESS;
685 }
686
687 void
688 _FastScrollIndexView::OnDraw(void)
689 {
690         DrawBaseIndex();
691         if (__pSelectedIndex)
692         {
693                 DrawSelectedBg();
694                 DrawSelectedIndex();
695         }
696 }
697
698 VisualElementAnimation*
699 _FastScrollIndexView::CreateAnimationForProperty(VisualElement& target, const String& property)
700 {
701         VisualElementAnimation* pAnimation = VisualElementAnimationProvider::CreateAnimationForProperty(target, property);
702
703         if (pAnimation)
704         {
705                 const IVisualElementAnimationTimingFunction* pTimingFunction = VisualElementAnimation::GetTimingFunctionByName("EaseInOut");
706                 if (pTimingFunction)
707                 {
708                         pAnimation->SetTimingFunction(pTimingFunction);
709                 }
710                 pAnimation->SetVisualElementAnimationStatusEventListener(this);
711         }
712         return pAnimation;
713 }
714
715 void
716 _FastScrollIndexView::OnVisualElementAnimationStarted(const VisualElementAnimation& animation, const String& keyName, VisualElement& target)
717 {
718 }
719
720 void
721 _FastScrollIndexView::OnVisualElementAnimationRepeated(const VisualElementAnimation& animation, const String& keyName, VisualElement& target, long currentRepeatCount)
722 {
723 }
724
725 void
726 _FastScrollIndexView::OnVisualElementAnimationFinished(const VisualElementAnimation& animation, const String& keyName, VisualElement& target, bool completedNormally)
727 {
728         if (__pBaseIndexVe == (static_cast <_VisualElement*>(&target)))
729         {
730                 if (__needDestroySelf && completedNormally)
731                 {
732                         if (__pSelectedIndexVe)
733                         {
734                                 __pSelectedIndexVe->RemoveAllAnimations();
735                                 __pSelectedIndexVe->SetAnimationProvider(null);
736                         }
737
738                         if (__pSelectedBgVe)
739                         {
740                                 __pSelectedBgVe->RemoveAllAnimations();
741                                 __pSelectedBgVe->SetAnimationProvider(null);
742                         }
743
744                         __pBaseIndexVe->RemoveAllAnimations();
745                         __pBaseIndexVe->SetAnimationProvider(null);
746
747                         delete this;
748                 }
749         }
750 }
751
752 FloatRectangle
753 _FastScrollIndexView::CalculateSelectedBg(void)
754 {
755         SysTryReturn(NID_UI_CTRL, __pBaseIndex, FloatRectangle(0.0f, 0.0f, 0.0f, 0.0f), E_INVALID_STATE,
756                         "[E_INVALID_STATE] __pBaseIndex must not be     null.");
757         SysTryReturn(NID_UI_CTRL, __pSelectedIndexVe, FloatRectangle(0.0f, 0.0f, 0.0f, 0.0f), E_INVALID_STATE,
758                         "[E_INVALID_STATE] __pSelectedIndexVe must not be null.");
759         SysTryReturn(NID_UI_CTRL, __pSelectedIndex, FloatRectangle(0.0f, 0.0f, 0.0f, 0.0f), E_INVALID_STATE,
760                         "[E_INVALID_STATE] __pSelectedIndex must not be null.");
761
762         int childCount = __pBaseIndex->GetChildCount(__pBaseIndex->GetIndexType());
763         SysTryReturn(NID_UI_CTRL, childCount > 0, FloatRectangle(0.0f, 0.0f, 0.0f, 0.0f), E_INVALID_STATE, "[E_INVALID_STATE] The index have no children.");
764
765         FloatRectangle bounds = __pBaseIndexVe->GetBounds();
766         float indexHeight = GetIndexHeight();
767         int selectedIndexOrder = GetSelectedIndexOrder();
768         FloatRectangle selectedRect(0.0f, 0.0f, (bounds.width - __viewConfig.__selectedIndexMarginRight), __viewConfig.__selectedIndexHeight);
769
770         if (_FloatCompare(bounds.height, __viewConfig.__selectedIndexHeight) || (bounds.height < __viewConfig.__selectedIndexHeight))
771         {
772                 selectedRect.height = bounds.height;
773         }
774         else
775         {
776                 if (selectedIndexOrder == 0)
777                 {
778                         selectedRect.y = 0.0f;
779                         selectedRect.height = indexHeight + __viewConfig.__indexMarginTop;
780                 }
781                 else if (selectedIndexOrder == childCount - 1)
782                 {
783                         selectedRect.y = ((selectedIndexOrder * indexHeight) + __viewConfig.__indexMarginTop);
784                         selectedRect.height = bounds.height - selectedRect.y;
785                 }
786                 else
787                 {
788                         selectedRect.y = ((selectedIndexOrder * indexHeight) + __viewConfig.__indexMarginTop);
789                         if (indexHeight < __viewConfig.__selectedIndexHeight)
790                         {
791                                 selectedRect.y -= ((__viewConfig.__selectedIndexHeight - indexHeight) / 2.0f);
792                         }
793                         else
794                         {
795                                 selectedRect.height = indexHeight;
796                         }
797
798                         if (selectedRect.y < 0.0f)
799                         {
800                                 selectedRect.y = 0.0f;
801                         }
802                 }
803         }
804
805         return selectedRect;
806 }
807
808 void
809 _FastScrollIndexView::DrawBaseIndex()
810 {
811         if (!__needUpdateBaseIndex)
812         {
813                 return;
814         }
815         SysTryReturnVoidResult(NID_UI_CTRL, __pBaseIndex, E_INVALID_STATE, "[E_INVALID_STATE] __pBaseIndex must not be null.");
816
817         result r = E_SUCCESS;
818         int childCount = __pBaseIndex->GetChildCount(__pBaseIndex->GetIndexType());
819         SysTryReturnVoidResult(NID_UI_CTRL, childCount > 0, E_INVALID_STATE, "[E_INVALID_STATE] The index have no children.");
820
821         Canvas* pCanvas = __pBaseIndexVe->GetCanvasN();
822         SysTryReturnVoidResult(NID_UI_CTRL, pCanvas, GetLastResult(), "[%s] Failed to get the canvas of the index ve.",
823                         GetErrorMessage(GetLastResult()));
824
825         pCanvas->SetBackgroundColor(Color(0, 0, 0, 0));
826         pCanvas->Clear();
827
828         pCanvas->SetLineWidth(__viewConfig.__indexSeparatorThickness);
829
830         FloatRectangle bounds = __pBaseIndexVe->GetBounds();
831         float indexHeight = GetIndexHeight();
832
833         FloatRectangle bgBounds(0.0f, 0.0f, bounds.width, bounds.height);
834         if (__viewConfig.__pIndexBgBitmap)
835         {
836                 Bitmap* pReplacementColorBackgroundBitmap =
837                                 _BitmapImpl::GetColorReplacedBitmapN(*__viewConfig.__pIndexBgBitmap,
838                                                                 Color::GetColor(COLOR_ID_MAGENTA), __viewConfig.__indexBgColor);
839                 DrawBitmap(*pCanvas, bgBounds, *pReplacementColorBackgroundBitmap);
840
841                 delete pReplacementColorBackgroundBitmap;
842         }
843
844         FloatRectangle indexRect(0.0f, __viewConfig.__indexMarginTop, bounds.width, indexHeight);
845         Bitmap* pReplacementColorBitmap = null;
846
847         TextObject* pTextObject = new (std::nothrow) TextObject();
848         SysTryCatch(NID_UI_CTRL, pTextObject, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
849
850         pTextObject->Construct();
851
852         for (int i = 0; i < childCount; i++)
853         {
854                 TextSimple* pSimpleText = null;
855
856                 _FastScrollIndex* pChildIndex = __pBaseIndex->GetChildIndex(i, true);
857                 SysTryCatch(NID_UI_CTRL, pChildIndex, , GetLastResult(), "[%s] Failed to get the child index.",
858                                 GetErrorMessage(GetLastResult()));
859
860                 Bitmap* pChildIndexImage = pChildIndex->GetIndexImage();
861                 if (pChildIndexImage)
862                 {
863                         FloatRectangle imageRect = indexRect;
864                         float scaleFactor = indexRect.width / pChildIndexImage->GetWidthF();
865                         float heightScaleFactor = indexRect.height / pChildIndexImage->GetHeightF();
866                         if (scaleFactor > heightScaleFactor)
867                         {
868                                 scaleFactor = heightScaleFactor;
869                         }
870
871                         imageRect.width = pChildIndexImage->GetWidthF() * scaleFactor + FASTSCROLL_OPACITY_SELECTEDBG_DIM;
872                         imageRect.height = pChildIndexImage->GetHeightF() * scaleFactor + FASTSCROLL_OPACITY_SELECTEDBG_DIM;
873
874                         if (indexRect.width - imageRect.width > 0.0f)
875                         {
876                                 imageRect.x = indexRect.x + (indexRect.width - imageRect.width) / 2.0f;
877                         }
878
879                         if (indexRect.height - imageRect.height > 0.0f)
880                         {
881                                 imageRect.y = indexRect.y + (indexRect.height - imageRect.height) / 2.0f;
882                         }
883
884                         pReplacementColorBitmap =
885                                 _BitmapImpl::GetColorReplacedBitmapN(*pChildIndexImage,
886                                                                 Color::GetColor(COLOR_ID_MAGENTA), __viewConfig.__indexTextColor);
887                         r = DrawBitmap(*pCanvas, imageRect, *pReplacementColorBitmap,
888                                         FloatRectangle(0.0f, 0.0f, pChildIndexImage->GetWidthF(), pChildIndexImage->GetHeightF()));
889                         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to draw a bitmap.", GetErrorMessage(r));
890
891                         delete pReplacementColorBitmap;
892                         pReplacementColorBitmap = null;
893                 }
894                 else
895                 {
896                         String* pChildIndexText = pChildIndex->GetIndexText();
897                         SysTryCatch(NID_UI_CTRL, pChildIndexText, , E_INVALID_STATE, "pChildIndexText must not be null.");
898
899                         pTextObject->RemoveAll();
900
901                         pSimpleText = new (std::nothrow)TextSimple(const_cast<wchar_t*>(pChildIndexText->GetPointer()), pChildIndexText->GetLength(), TEXT_ELEMENT_SOURCE_TYPE_EXTERNAL);
902                         SysTryCatch(NID_UI_CTRL, pSimpleText, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed");
903
904                         r = pTextObject->AppendElement(*pSimpleText);
905                         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to append simple text.", GetErrorMessage(r));
906
907                         r = pTextObject->SetWrap(TEXT_OBJECT_WRAP_TYPE_WORD);
908                         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set wrap.", GetErrorMessage(r));
909
910                         r = pTextObject->SetFont(__viewConfig.__pFont, 0, pTextObject->GetTextLength());
911                         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set font.", GetErrorMessage(r));
912
913                         r = pTextObject->SetAlignment(TEXT_OBJECT_ALIGNMENT_CENTER | TEXT_OBJECT_ALIGNMENT_MIDDLE);
914                         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set alignment.", GetErrorMessage(r));
915
916                         r = pTextObject->SetBounds(indexRect);
917                         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set bounds of pTextObject.", GetErrorMessage(r));
918
919                         r = pTextObject->SetForegroundColor(__viewConfig.__indexTextColor, 0, pTextObject->GetTextLength());
920                         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set foreground color.", GetErrorMessage(r));
921
922                         r = pTextObject->Draw(*_CanvasImpl::GetInstance(*pCanvas));
923                         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to draw text.", GetErrorMessage(r));
924
925                 }
926
927                 indexRect.y += indexHeight;
928                 if (i != (childCount - 1))
929                 {
930                         pCanvas->SetForegroundColor(__viewConfig.__indexDividerColor);
931                         pCanvas->DrawLine(FloatPoint(indexRect.x, indexRect.y + __viewConfig.__indexSeparatorThickness),
932                                                         FloatPoint(indexRect.x + indexRect.width, indexRect.y + __viewConfig.__indexSeparatorThickness));
933                 }
934         }
935
936         __needUpdateBaseIndex = false;
937         //fall through
938 CATCH:
939         delete pTextObject;
940         delete pCanvas;
941         delete pReplacementColorBitmap;
942 }
943
944 void
945 _FastScrollIndexView::DrawSelectedBg()
946 {
947         if (!__needUpdateSelectedIndex)
948         {
949                 return;
950         }
951
952         SysTryReturnVoidResult(NID_UI_CTRL, __pSelectedIndex, E_INVALID_STATE,
953                         "[E_INVALID_STATE] __pSelectedIndex must not be null.");
954
955         Canvas* pCanvas = __pSelectedBgVe->GetCanvasN();
956         SysTryReturnVoidResult(NID_UI_CTRL, pCanvas, GetLastResult(), "[%s] Failed to get the canvas of the Selected Bg ve.",
957                         GetErrorMessage(GetLastResult()));
958
959         pCanvas->SetBackgroundColor(Color(0, 0, 0, 0));
960         pCanvas->Clear();
961
962         FloatRectangle bounds = __pSelectedBgVe->GetBounds();
963         bounds.y = 0.0f;
964
965         if (__viewConfig.__pSelectedIndexBgBitmap)
966         {
967                 Bitmap* pReplacementColorBackgroundBitmap = null;
968                 pReplacementColorBackgroundBitmap =
969                                 _BitmapImpl::GetColorReplacedBitmapN(*__viewConfig.__pSelectedIndexBgBitmap,
970                                                                 Color::GetColor(COLOR_ID_MAGENTA), __viewConfig.__selectedIndexBgColor);
971                 DrawBitmap(*pCanvas, bounds, *pReplacementColorBackgroundBitmap);
972
973                 delete pReplacementColorBackgroundBitmap;
974         }
975
976         delete pCanvas;
977 }
978
979 void
980 _FastScrollIndexView::DrawSelectedIndex()
981 {
982         if (!__needUpdateSelectedIndex)
983         {
984                 return;
985         }
986
987         SysTryReturnVoidResult(NID_UI_CTRL, __pSelectedIndex, E_INVALID_STATE, "[E_INVALID_STATE] __pSelectedIndex must not be null.");
988
989         Canvas* pCanvas = __pSelectedIndexVe->GetCanvasN();
990         SysTryReturnVoidResult(NID_UI_CTRL, pCanvas, GetLastResult(), "[%s] Failed to get the canvas of the selected index ve.",
991                         GetErrorMessage(GetLastResult()));
992
993         result r = E_SUCCESS;
994         pCanvas->SetBackgroundColor(Color(0, 0, 0, 0));
995         pCanvas->Clear();
996         FloatRectangle bounds = __pSelectedIndexVe->GetBounds();
997         FloatRectangle outlineBounds = __pSelectedBgVe->GetBounds();
998
999         int childCount = __pBaseIndex->GetChildCount(__pBaseIndex->GetIndexType());
1000         int selectedIndexOrder = GetSelectedIndexOrder();
1001
1002         pCanvas->SetLineWidth(__viewConfig.__indexLeftLineThickness);
1003         pCanvas->SetForegroundColor(__viewConfig.__indexSelectedLineColor);
1004
1005         if (selectedIndexOrder == 0)
1006         {
1007                 pCanvas->DrawLine(FloatPoint(0.0f, outlineBounds.height), FloatPoint(outlineBounds.width, outlineBounds.height));
1008                 pCanvas->DrawLine(FloatPoint(outlineBounds.width, outlineBounds.y), FloatPoint(outlineBounds.width, outlineBounds.height));
1009
1010                 pCanvas->DrawLine(FloatPoint(1.0f, outlineBounds.height), FloatPoint(1.0f, bounds.height));
1011         }
1012         else if (selectedIndexOrder == childCount - 1)
1013         {
1014                 pCanvas->DrawLine(FloatPoint(0.0f, outlineBounds.y), FloatPoint(outlineBounds.width, outlineBounds.y));
1015                 pCanvas->DrawLine(FloatPoint(outlineBounds.width, outlineBounds.y), FloatPoint(outlineBounds.width, bounds.height));
1016
1017                 pCanvas->DrawLine(FloatPoint(1.0f, 0.0f), FloatPoint(1.0f, outlineBounds.y));
1018         }
1019         else if (__viewConfig.__pSelectedIndexlineBitmap)
1020         {
1021                 Bitmap* pReplacementColorBackgroundBitmap = null;
1022                 pReplacementColorBackgroundBitmap =
1023                                 _BitmapImpl::GetColorReplacedBitmapN(*__viewConfig.__pSelectedIndexlineBitmap,
1024                                                                 Color::GetColor(COLOR_ID_MAGENTA), __viewConfig.__indexSelectedLineColor);
1025                 DrawBitmap(*pCanvas, outlineBounds, *pReplacementColorBackgroundBitmap);
1026
1027                 delete pReplacementColorBackgroundBitmap;
1028
1029                 pCanvas->DrawLine(FloatPoint(1.0f, 0.0f), FloatPoint(1.0f, outlineBounds.y));
1030                 pCanvas->DrawLine(FloatPoint(1.0f, (outlineBounds.y + outlineBounds.height)), FloatPoint(1.0f, bounds.height));
1031         }
1032
1033         //draw text
1034         TextObject* pTextObject = null;
1035         TextSimple* pSimpleText = null;
1036
1037         float indexHeight = GetIndexHeight();
1038         FloatRectangle indexRect(0.0f, ((GetSelectedIndexOrder() * indexHeight) + __viewConfig.__indexMarginTop),
1039                         bounds.width, indexHeight);
1040
1041         Bitmap* pChildIndexImage = __pSelectedIndex->GetIndexImage();
1042         Bitmap* pReplacementColorBitmap = null;
1043         if (pChildIndexImage)
1044         {
1045                 FloatRectangle imageRect = indexRect;
1046                 float scaleFactor = indexRect.width / pChildIndexImage->GetWidthF();
1047                 float heightScaleFactor = indexRect.height / pChildIndexImage->GetHeightF();
1048                 if (scaleFactor > heightScaleFactor)
1049                 {
1050                         scaleFactor = heightScaleFactor;
1051                 }
1052
1053                 imageRect.width = pChildIndexImage->GetWidthF() * scaleFactor + FASTSCROLL_OPACITY_SELECTEDBG_DIM;
1054                 imageRect.height = pChildIndexImage->GetHeightF() * scaleFactor + FASTSCROLL_OPACITY_SELECTEDBG_DIM;
1055
1056                 if (indexRect.width - imageRect.width > 0.0f)
1057                 {
1058                         imageRect.x = indexRect.x + (indexRect.width - imageRect.width) / 2.0f;
1059                 }
1060
1061                 if (indexRect.height - imageRect.height > 0.0f)
1062                 {
1063                         imageRect.y = indexRect.y + (indexRect.height - imageRect.height) / 2.0f;
1064                 }
1065
1066                 pReplacementColorBitmap =
1067                         _BitmapImpl::GetColorReplacedBitmapN(*pChildIndexImage,
1068                                                         Color::GetColor(COLOR_ID_MAGENTA), __viewConfig.__selectedIndexTextColor);
1069                 r = DrawBitmap(*pCanvas, imageRect, *pReplacementColorBitmap,
1070                                 FloatRectangle(0.0f, 0.0f, pChildIndexImage->GetWidthF(), pChildIndexImage->GetHeightF()));
1071                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to draw a bitmap.", GetErrorMessage(r));
1072
1073                 delete pReplacementColorBitmap;
1074                 pReplacementColorBitmap = null;
1075         }
1076         else
1077         {
1078                 String* pChildIndexText = __pSelectedIndex->GetIndexText();
1079                 SysTryCatch(NID_UI_CTRL, pChildIndexText, , E_INVALID_STATE, "[E_INVALID_STATE] pChildIndexText must not be null.");
1080
1081                 pTextObject = new (std::nothrow) TextObject();
1082                 SysTryCatch(NID_UI_CTRL, pTextObject, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1083
1084                 pTextObject->Construct();
1085
1086                 pSimpleText = new (std::nothrow)TextSimple(const_cast<wchar_t*>(pChildIndexText->GetPointer()), pChildIndexText->GetLength(), TEXT_ELEMENT_SOURCE_TYPE_EXTERNAL);
1087                 SysTryCatch(NID_UI_CTRL, pSimpleText, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1088
1089                 r = pTextObject->AppendElement(*pSimpleText);
1090                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to append simpletext.", GetErrorMessage(r));
1091
1092                 r = pTextObject->SetWrap(TEXT_OBJECT_WRAP_TYPE_WORD);
1093                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set wrap.", GetErrorMessage(r));
1094
1095                 r = pTextObject->SetFont(__viewConfig.__pFont, 0, pTextObject->GetTextLength());
1096                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set font.", GetErrorMessage(r));
1097
1098                 r = pTextObject->SetAlignment(TEXT_OBJECT_ALIGNMENT_CENTER | TEXT_OBJECT_ALIGNMENT_MIDDLE);
1099                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set alignment.", GetErrorMessage(r));
1100
1101                 r = pTextObject->SetBounds(indexRect);
1102                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set bounds of pTextObject.", GetErrorMessage(r));
1103
1104                 r = pTextObject->SetForegroundColor(__viewConfig.__selectedIndexTextColor, 0, pTextObject->GetTextLength());
1105                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set foreground color.", GetErrorMessage(r));
1106
1107                 r = pTextObject->Draw(*_CanvasImpl::GetInstance(*pCanvas));
1108                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to draw text.", GetErrorMessage(r));
1109
1110         }
1111         __needUpdateSelectedIndex = false;
1112
1113         //fall through
1114 CATCH:
1115         delete pTextObject;
1116         delete pCanvas;
1117         delete pReplacementColorBitmap;
1118 }
1119
1120 result
1121 _FastScrollIndexView::DrawBitmap(Canvas& canvas, const FloatRectangle& bounds, const Bitmap& bitmap)
1122 {
1123         result r = E_SUCCESS;
1124         if (_BitmapImpl::CheckNinePatchedBitmapStrictly(bitmap))
1125         {
1126                 r = canvas.DrawNinePatchedBitmap(bounds, bitmap);
1127                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to draw ninepathced bitmap");
1128         }
1129         else
1130         {
1131                 r = canvas.DrawBitmap(bounds, bitmap);
1132                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to draw bitmap");
1133         }
1134
1135         return E_SUCCESS;
1136 }
1137
1138 result
1139 _FastScrollIndexView::DrawBitmap(Canvas& canvas, const FloatRectangle& srcRect, const Bitmap& bitmap, const FloatRectangle& dstRect)
1140 {
1141         result r = E_SUCCESS;
1142         if (_BitmapImpl::CheckNinePatchedBitmapStrictly(bitmap))
1143         {
1144                 r = canvas.DrawNinePatchedBitmap(srcRect, bitmap);
1145                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to draw ninepathced bitmap");
1146         }
1147         else
1148         {
1149                 r = canvas.DrawBitmap(srcRect, bitmap, dstRect);
1150                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to draw bitmap");
1151         }
1152
1153         return E_SUCCESS;
1154 }
1155
1156 result
1157 _FastScrollIndexView::Construct(void)
1158 {
1159         result r = E_SUCCESS;
1160
1161         // FormattedText for Title text
1162         __pBaseIndexVe = new (std::nothrow) _VisualElement();
1163         SysTryCatch(NID_UI_CTRL, __pBaseIndexVe, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1164
1165         r = __pBaseIndexVe->Construct();
1166         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to construct the index Ve.", GetErrorMessage(r));
1167
1168         __pBaseIndexVe->SetAnimationProvider(this);
1169
1170         r = __pBaseIndexVe->SetSurfaceOpaque(false);
1171         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set the opaque of the base index ve.", GetErrorMessage(r));
1172
1173         __pBaseIndexVe->SetImplicitAnimationEnabled(false);
1174
1175         r = __parentVe.AttachChild(*__pBaseIndexVe);
1176         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to attach the base index ve to the parent.", GetErrorMessage(r));
1177
1178         __pBaseIndexVe->SetShowState(true);
1179
1180         //__pSelectedBgVe
1181         __pSelectedBgVe = new (std::nothrow) _VisualElement();
1182         SysTryCatch(NID_UI_CTRL, __pSelectedBgVe, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1183
1184         r = __pSelectedBgVe->Construct();
1185         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to construct the selected Bg ve.", GetErrorMessage(r));
1186
1187         __pSelectedBgVe->SetAnimationProvider(this);
1188
1189         r = __pSelectedBgVe->SetSurfaceOpaque(false);
1190         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set the opaque of the selected Bg ve.", GetErrorMessage(r));
1191
1192         __pSelectedBgVe->SetImplicitAnimationEnabled(false);
1193
1194         r = __pBaseIndexVe->AttachChild(*__pSelectedBgVe);
1195         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to attach the selected Bg ve to the parent.", GetErrorMessage(r));
1196
1197         __pSelectedBgVe->SetOpacity(FASTSCROLL_OPACITY_SELECTEDBG_DIM);
1198
1199         __pSelectedBgVe->SetShowState(true);
1200
1201         //__pSelectedIndexVe
1202         __pSelectedIndexVe = new (std::nothrow) _VisualElement();
1203         SysTryCatch(NID_UI_CTRL, __pSelectedIndexVe, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1204
1205         r = __pSelectedIndexVe->Construct();
1206         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to construct the selected index ve.", GetErrorMessage(r));
1207
1208         __pSelectedIndexVe->SetAnimationProvider(this);
1209
1210         r = __pSelectedIndexVe->SetSurfaceOpaque(false);
1211         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set the opaque of the selected index ve.", GetErrorMessage(r));
1212
1213         __pSelectedIndexVe->SetImplicitAnimationEnabled(false);
1214
1215         r = __pBaseIndexVe->AttachChild(*__pSelectedIndexVe);
1216         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to attach the selected index ve to the parent.", GetErrorMessage(r));
1217
1218         __pSelectedIndexVe->SetShowState(true);
1219
1220         return E_SUCCESS;
1221
1222 CATCH:
1223         if (__pSelectedIndexVe)
1224         {
1225                 __pSelectedIndexVe->Destroy();
1226                 __pSelectedIndexVe = null;
1227         }
1228
1229         if (__pSelectedBgVe)
1230         {
1231                 __pSelectedBgVe->Destroy();
1232                 __pSelectedBgVe = null;
1233         }
1234
1235         if (__pBaseIndexVe)
1236         {
1237                 __pBaseIndexVe->Destroy();
1238                 __pBaseIndexVe = null;
1239         }
1240
1241         return r;
1242 }
1243
1244 _FastScrollPopupView::_FastScrollPopupView(_VisualElement& parentVe, _FastScrollViewConfig& viewConfig)
1245         : __parentVe(parentVe)
1246         , __viewConfig(viewConfig)
1247         , __pPopupVe(null)
1248         , __needUpdatePopupVe(false)
1249         , __needUpdatePopupIndexVe(false)
1250         , __needDestroySelf(false)
1251 {
1252 }
1253
1254 _FastScrollPopupView::~_FastScrollPopupView(void)
1255 {
1256         for (int i = 0; i < GetIndexVeCount(); i++)
1257         {
1258                 _VisualElement* pIndexVe = GetIndexVe(i);
1259
1260                 if (pIndexVe)
1261                 {
1262                         pIndexVe->RemoveAllAnimations();
1263                         pIndexVe->SetAnimationProvider(null);
1264                         pIndexVe->Destroy();
1265                 }
1266         }
1267         __indexViews.RemoveAll(false);
1268
1269         if (__pPopupVe)
1270         {
1271                 __pPopupVe->RemoveAllAnimations();
1272                 __pPopupVe->SetAnimationProvider(null);
1273
1274                 __pPopupVe->Destroy();
1275                 __pPopupVe = null;
1276         }
1277 }
1278
1279 _FastScrollPopupView*
1280 _FastScrollPopupView::CreateFastScrollPopupViewN(_VisualElement& parentVe, _FastScrollViewConfig& viewConfig)
1281 {
1282         _FastScrollPopupView* pPopupView = new (std::nothrow) _FastScrollPopupView(parentVe, viewConfig);
1283         SysTryReturn(NID_UI_CTRL, pPopupView, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1284
1285         result r = pPopupView->Construct();
1286         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
1287
1288         SetLastResult(E_SUCCESS);
1289         return pPopupView;
1290
1291 CATCH:
1292         delete pPopupView;
1293
1294         return null;
1295 }
1296
1297 result
1298 _FastScrollPopupView::FadeOutAndDestroy(void)
1299 {
1300         __needDestroySelf = true;
1301
1302         for (int i = 0; i < GetIndexVeCount(); i++)
1303         {
1304                 _VisualElement* pIndexVe = GetIndexVe(i);
1305                 SysTryReturnResult(NID_UI_CTRL, pIndexVe, GetLastResult(), "Failed to get the popup index view.");
1306
1307                 pIndexVe->RemoveAllAnimations();
1308         }
1309
1310         return SetPopupVisibility(false);
1311 }
1312
1313 result
1314 _FastScrollPopupView::SelectIndex(int indexLevel, _FastScrollIndex* pIndex, _FastScrollIndex* pFormerIndex)
1315 {
1316         _VisualElement* pIndexVe = GetIndexVe(indexLevel);
1317         SysTryReturnResult(NID_UI_CTRL, pIndexVe, GetLastResult(), "Failed to get the popup index view.");
1318
1319         if (pIndex)
1320         {
1321                 pIndexVe->SetOpacity(FASTSCROLL_OPACITY_ON);
1322                 FloatRectangle popupVeBounds = __pPopupVe->GetBounds();
1323                 FloatMatrix4 popupVeMatrix;
1324                 popupVeMatrix.SetAsIdentity();
1325
1326                 if (pFormerIndex && (pFormerIndex != pIndex))
1327                 {
1328                         FloatRectangle popupIndexVeBounds = pIndexVe->GetBounds();
1329
1330                         int selectedOrder = pIndex->GetIndexOrder(false);
1331                         int oldOrder = pFormerIndex->GetIndexOrder(false);
1332
1333                         if (selectedOrder > oldOrder)
1334                         {
1335                                 _MatrixUtilTranslate(popupVeMatrix, 0.0f, 0.0f, 0.0f);
1336                         }
1337                         else
1338                         {
1339                                 _MatrixUtilTranslate(popupVeMatrix, 0.0f, -(popupVeBounds.height * (FASTSCROLL_POPUPINDEX_COUNT - 1)), 0.0f);
1340                         }
1341                         pIndexVe->SetTransformMatrix(popupVeMatrix);
1342                         pIndexVe->SetImplicitAnimationEnabled(true);
1343
1344                         popupVeMatrix.SetAsIdentity();
1345                         _MatrixUtilTranslate(popupVeMatrix, 0.0f, -popupVeBounds.height, 0.0f);
1346                         pIndexVe->SetTransformMatrix(popupVeMatrix);
1347
1348                         pIndexVe->SetImplicitAnimationEnabled(false);
1349                 }
1350                 else
1351                 {
1352                         _MatrixUtilTranslate(popupVeMatrix, 0.0f, -popupVeBounds.height, 0.0f);
1353                         pIndexVe->SetTransformMatrix(popupVeMatrix);
1354                 }
1355         }
1356         else
1357         {
1358                 pIndexVe->SetOpacity(FASTSCROLL_OPACITY_LIGHT_DIM);
1359         }
1360
1361         return E_SUCCESS;
1362 }
1363
1364 result
1365 _FastScrollPopupView::AddPopupIndexVe(int indexLevel)
1366 {
1367         result r = E_SUCCESS;
1368         _VisualElement* pPopupIndexVe = new (std::nothrow) _VisualElement();
1369         SysTryCatch(NID_UI_CTRL, pPopupIndexVe, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1370
1371         r = pPopupIndexVe->Construct();
1372         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to construct the popup index ve.", GetErrorMessage(r));
1373
1374         pPopupIndexVe->SetAnimationProvider(this);
1375
1376         r = pPopupIndexVe->SetSurfaceOpaque(false);
1377         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set the opaque of the popup index ve.", GetErrorMessage(r));
1378
1379         pPopupIndexVe->SetImplicitAnimationEnabled(false);
1380
1381         r = __pPopupVe->AttachChild(*pPopupIndexVe);
1382         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to attach the popup index ve to the popup ve.", GetErrorMessage(r));
1383
1384         pPopupIndexVe->SetShowState(true);
1385
1386         r = __indexViews.InsertAt(*pPopupIndexVe, indexLevel);
1387         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to change the last index view.", GetErrorMessage(r));
1388
1389         return E_SUCCESS;
1390
1391 CATCH:
1392         if (pPopupIndexVe)
1393         {
1394                 pPopupIndexVe->RemoveAllAnimations();
1395                 pPopupIndexVe->SetAnimationProvider(null);
1396
1397                 pPopupIndexVe->Destroy();
1398         }
1399
1400         return r;
1401 }
1402
1403 result
1404 _FastScrollPopupView::RemovePopupIndexVe(int indexLevel)
1405 {
1406         result r = E_SUCCESS;
1407
1408         if (indexLevel < GetIndexVeCount())
1409         {
1410                 _VisualElement* pIndexVe = GetIndexVe(indexLevel);
1411                 SysTryReturnResult(NID_UI_CTRL, pIndexVe, GetLastResult(), "Failed to get the popup index ve.");
1412
1413                 r = __indexViews.Remove(*pIndexVe, false);
1414                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to remove the popup index ve.");
1415
1416                 pIndexVe->RemoveAllAnimations();
1417                 pIndexVe->SetAnimationProvider(null);
1418                 pIndexVe->Destroy();
1419         }
1420
1421         return E_SUCCESS;
1422 }
1423
1424 result
1425 _FastScrollPopupView::SetPopupBounds(const FloatRectangle& indexBounds)
1426 {
1427         SysTryReturnResult(NID_UI_CTRL, __pPopupVe, E_INVALID_STATE, "__pPopupVe must not be null.");
1428
1429         __pPopupVe->SetBounds(indexBounds);
1430
1431         return E_SUCCESS;
1432 }
1433
1434 result
1435 _FastScrollPopupView::SetPopupIndexBounds(int indexLevel, const _FastScrollIndex* pBaseIndex)
1436 {
1437         FloatRectangle veBounds = __pPopupVe->GetBounds();
1438         _VisualElement* pIndexVe = GetIndexVe(indexLevel);
1439         SysTryReturnResult(NID_UI_CTRL, pIndexVe, GetLastResult(), "Failed to get the popup index view.");
1440
1441         if (pBaseIndex)
1442         {
1443                 veBounds.x = 0.0f;
1444                 veBounds.y = 0.0f;
1445                 veBounds.height = veBounds.height * FASTSCROLL_POPUPINDEX_COUNT;
1446         }
1447
1448         int indexVeCount = GetIndexVeCount();
1449         float indexWidth = veBounds.width;
1450         if (indexVeCount > 0)
1451         {
1452                 indexWidth /= indexVeCount;
1453         }
1454
1455         veBounds.width = indexWidth;
1456         veBounds.x = veBounds.width * indexLevel;
1457
1458         pIndexVe->SetBounds(veBounds);
1459
1460         return E_SUCCESS;
1461 }
1462
1463 _VisualElement*
1464 _FastScrollPopupView::GetIndexVe(int indexLevel) const
1465 {
1466         Object* pObj = const_cast<Object*>(__indexViews.GetAt(indexLevel));
1467         SysTryReturn(NID_UI_CTRL, pObj, null, GetLastResult(), "[%s] Failed to get the popup index ve.",
1468                         GetErrorMessage(GetLastResult()));
1469
1470         return dynamic_cast<_VisualElement*>(pObj);
1471 }
1472
1473 int
1474 _FastScrollPopupView::GetIndexVeCount(void) const
1475 {
1476         return __indexViews.GetCount();
1477 }
1478
1479 bool
1480 _FastScrollPopupView::IsOnAnimation(void) const
1481 {
1482         return false;
1483 }
1484
1485 void
1486 _FastScrollPopupView::RemoveAllAnimations(void)
1487 {
1488         SysTryReturnVoidResult(NID_UI_CTRL, __pPopupVe, E_INVALID_STATE, "[E_INVALID_STATE] __pPopupVe must not be null.");
1489         __pPopupVe->RemoveAllAnimations();
1490 }
1491
1492 result
1493 _FastScrollPopupView::SetPopupVisibility(bool visibility)
1494 {
1495         SysTryReturnResult(NID_UI_CTRL, __pPopupVe, E_INVALID_STATE, "__pPopupVe must not be null.");
1496
1497         if (visibility)
1498         {
1499                 __pPopupVe->SetTransformMatrix(__matrixFadeInStart);
1500                 __pPopupVe->SetImplicitAnimationEnabled(true);
1501                 __pPopupVe->SetOpacity(FASTSCROLL_OPACITY_ON);
1502                 __pPopupVe->SetTransformMatrix(__matrixOrigin);
1503                 __pPopupVe->SetImplicitAnimationEnabled(false);
1504         }
1505         else
1506         {
1507                 __pPopupVe->SetImplicitAnimationEnabled(true);
1508                 __pPopupVe->SetOpacity(FASTSCROLL_OPACITY_OFF);
1509                 __pPopupVe->SetTransformMatrix(__matrixFadeOutEnd);
1510                 __pPopupVe->SetImplicitAnimationEnabled(false);
1511         }
1512         // else keep up current visibility.
1513
1514         return E_SUCCESS;
1515 }
1516
1517 bool
1518 _FastScrollPopupView::GetPopupVisibility(void) const
1519 {
1520         SysTryReturn(NID_UI_CTRL, __pPopupVe, false, E_INVALID_STATE, "[E_INVALID_STATE] __pPopupVe must not be null.");
1521
1522         float opacity = __pPopupVe->GetOpacity();
1523         if (opacity > FASTSCROLL_OPACITY_OFF)
1524         {
1525                 return true;
1526         }
1527
1528         return false;
1529 }
1530
1531 void
1532 _FastScrollPopupView::SetPopupVeUpdateNeeded(bool needUpdate)
1533 {
1534         __needUpdatePopupIndexVe = needUpdate;
1535 }
1536
1537 result
1538 _FastScrollPopupView::UpdateIndex(void)
1539 {
1540         SysTryReturnResult(NID_UI_CTRL, __pPopupVe, E_INVALID_STATE, "__pPopupVe must not be null.");
1541
1542         result r = E_SUCCESS;
1543
1544         r = __parentVe.InvalidateRectangle(null);
1545         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to invalidate the popup Ve.");
1546
1547         __needUpdatePopupIndexVe = true;
1548
1549         return E_SUCCESS;
1550 }
1551
1552 void
1553 _FastScrollPopupView::OnDraw(int indexLevel, const _FastScrollIndex* pBaseIndex, const _FastScrollIndex* pSelectedIndex)
1554 {
1555         DrawPopupVe();
1556         DrawPopupIndexVe(indexLevel, pBaseIndex, pSelectedIndex);
1557 }
1558
1559 VisualElementAnimation*
1560 _FastScrollPopupView::CreateAnimationForProperty(VisualElement& target, const String& property)
1561 {
1562         VisualElementAnimation* pAnimation = VisualElementAnimationProvider::CreateAnimationForProperty(target, property);
1563
1564         if (pAnimation)
1565         {
1566                 const IVisualElementAnimationTimingFunction* pTimingFunction = VisualElementAnimation::GetTimingFunctionByName("EaseInOut");
1567                 if (pTimingFunction)
1568                 {
1569                         pAnimation->SetTimingFunction(pTimingFunction);
1570                 }
1571                 pAnimation->SetVisualElementAnimationStatusEventListener(this);
1572         }
1573         return pAnimation;
1574 }
1575
1576 void
1577 _FastScrollPopupView::OnVisualElementAnimationStarted(const VisualElementAnimation& animation, const String& keyName, VisualElement& target)
1578 {
1579 }
1580
1581 void
1582 _FastScrollPopupView::OnVisualElementAnimationRepeated(const VisualElementAnimation& animation, const String& keyName, VisualElement& target, long currentRepeatCount)
1583 {
1584 }
1585
1586 void
1587 _FastScrollPopupView::OnVisualElementAnimationFinished(const VisualElementAnimation& animation, const String& keyName, VisualElement& target, bool completedNormally)
1588 {
1589         SysTryReturnVoidResult(NID_UI_CTRL, __pPopupVe, E_INVALID_STATE, "[E_INVALID_STATE] The popup Ve must not be null.");
1590         if (__pPopupVe == (static_cast <_VisualElement*>(&target)))
1591         {
1592                 if (__needDestroySelf && completedNormally)
1593                 {
1594                         for (int i = 0; i < GetIndexVeCount(); i++)
1595                         {
1596                                 _VisualElement* pIndexVe = GetIndexVe(i);
1597                                 if (pIndexVe)
1598                                 {
1599                                         pIndexVe->RemoveAllAnimations();
1600                                         pIndexVe->SetAnimationProvider(null);
1601                                 }
1602                         }
1603
1604                         __pPopupVe->RemoveAllAnimations();
1605                         __pPopupVe->SetAnimationProvider(null);
1606
1607                         delete this;
1608                 }
1609         }
1610 }
1611
1612 void
1613 _FastScrollPopupView::DrawPopupVe(void)
1614 {
1615         if (!__needUpdatePopupVe)
1616         {
1617                 return;
1618         }
1619
1620         SysTryReturnVoidResult(NID_UI_CTRL, __pPopupVe, E_INVALID_STATE, "[E_INVALID_STATE] __pPopupVe must not be null.");
1621
1622         Canvas* pCanvas = __pPopupVe->GetCanvasN();
1623         SysTryReturnVoidResult(NID_UI_CTRL, pCanvas, GetLastResult(), "[%s] Failed to get the canvas of the popup ve.",
1624                         GetErrorMessage(GetLastResult()));
1625
1626         FloatRectangle bounds = __pPopupVe->GetBounds();
1627         bounds.SetPosition(0.0f, 0.0f);
1628
1629         pCanvas->SetBackgroundColor(Color(0, 0, 0, 0));
1630         pCanvas->Clear();
1631         bool isCustomBitmap = IS_CUSTOM_BITMAP(FASTSCROLL::POPUP_BG_NORMAL);
1632
1633         if (__viewConfig.__pPopupBgEffectBitmap && isCustomBitmap == false)
1634         {
1635                 DrawBitmap(*pCanvas, bounds, *__viewConfig.__pPopupBgEffectBitmap);
1636         }
1637
1638         if (__viewConfig.__pPopupBgBitmap)
1639         {
1640                 Bitmap* pReplacementColorBackgroundBitmap = null;
1641                 pReplacementColorBackgroundBitmap =
1642                                 _BitmapImpl::GetColorReplacedBitmapN(*__viewConfig.__pPopupBgBitmap, Color::GetColor(COLOR_ID_MAGENTA), __viewConfig.__popupBgColor);
1643                 DrawBitmap(*pCanvas, bounds, *pReplacementColorBackgroundBitmap);
1644
1645                 delete pReplacementColorBackgroundBitmap;
1646         }
1647
1648         delete pCanvas;
1649
1650         __needUpdatePopupVe = false;
1651 }
1652
1653
1654 void
1655 _FastScrollPopupView::DrawPopupIndexVe(int indexLevel, const _FastScrollIndex* pBaseIndex, const _FastScrollIndex* pSelectedIndex)
1656 {
1657         if (__needUpdatePopupIndexVe != true)
1658         {
1659                 return;
1660         }
1661
1662         SysTryReturnVoidResult(NID_UI_CTRL, pBaseIndex, E_INVALID_STATE, "[E_INVALID_STATE] pBaseIndex must not be null.");
1663         SysTryReturnVoidResult(NID_UI_CTRL, pSelectedIndex, E_INVALID_STATE, "[E_INVALID_STATE] pBaseIndex must not be null.");
1664
1665         result r = E_SUCCESS;
1666
1667         int childCount = pBaseIndex->GetChildCount();
1668         SysTryReturnVoidResult(NID_UI_CTRL, childCount > 0, E_INVALID_STATE, "[E_INVALID_STATE] The index have no children.");
1669
1670         _VisualElement* pIndexVe = GetIndexVe(indexLevel);
1671         SysTryReturnVoidResult(NID_UI_CTRL, pIndexVe, GetLastResult(), "[%s] Failed to get the popup index ve.",
1672                                 GetErrorMessage(GetLastResult()));
1673
1674         Canvas* pCanvas = pIndexVe->GetCanvasN();
1675         SysTryReturnVoidResult(NID_UI_CTRL, pCanvas, GetLastResult(), "[%s] Failed to get the canvas of the popup index ve.",
1676                         GetErrorMessage(GetLastResult()));
1677
1678         pCanvas->SetBackgroundColor(Color(0, 0, 0, 0));
1679         pCanvas->Clear();
1680
1681         FloatRectangle veBounds = pIndexVe->GetBounds();
1682         FloatRectangle bounds(veBounds.x, veBounds.y, veBounds.width, veBounds.height);
1683
1684         float indexHeight = bounds.height / FASTSCROLL_POPUPINDEX_COUNT;
1685         if (indexHeight < __viewConfig.__popupTextSize)
1686         {
1687                 indexHeight = __viewConfig.__popupTextSize;
1688         }
1689
1690         FloatRectangle indexRect(0.0f, 0.0f, bounds.width, indexHeight);
1691         int selectedOrder = pSelectedIndex->GetIndexOrder(false);
1692         Bitmap* pReplacementColorBitmap = null;
1693
1694         TextObject* pTextObject = new (std::nothrow) TextObject();
1695         SysTryCatch(NID_UI_CTRL, pTextObject, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1696
1697         pTextObject->Construct();
1698
1699         for (int i = -1; i < 2; i++)
1700         {
1701                 TextSimple* pSimpleText = null;
1702
1703                 _FastScrollIndex* pChildIndex = pBaseIndex->GetChildIndex(selectedOrder + i);
1704                 if (pChildIndex)
1705                 {
1706                         Bitmap* pChildIndexImage = pChildIndex->GetIndexImage();
1707                         if (pChildIndexImage)
1708                         {
1709                                 FloatRectangle imageRect = indexRect;
1710                                 float scaleFactor = indexRect.width / pChildIndexImage->GetWidthF();
1711                                 float heightScale = indexRect.height / pChildIndexImage->GetHeightF();
1712                                 float rectHeight = indexRect.height;
1713                                 if (rectHeight > __viewConfig.__popupTextSize)
1714                                 {
1715                                         rectHeight = __viewConfig.__popupTextSize;
1716                                 }
1717
1718                                 if (scaleFactor > heightScale)
1719                                 {
1720                                         scaleFactor = heightScale;
1721                                 }
1722                                 imageRect.width = pChildIndexImage->GetWidthF() * scaleFactor;
1723                                 imageRect.height = pChildIndexImage->GetHeightF() * scaleFactor;
1724
1725                                 if (indexRect.width - imageRect.width > 0.0f)
1726                                 {
1727                                         imageRect.x = indexRect.x + (indexRect.width - imageRect.width) / 2.0f;
1728                                 }
1729
1730                                 if (indexRect.height - imageRect.height > 0.0f)
1731                                 {
1732                                         imageRect.y = indexRect.y + (indexRect.height - imageRect.height) / 2.0f;
1733                                 }
1734
1735                                 pReplacementColorBitmap =
1736                                         _BitmapImpl::GetColorReplacedBitmapN(*pChildIndexImage,
1737                                                         Color::GetColor(COLOR_ID_MAGENTA), __viewConfig.__popupTextColor);
1738                                 r = DrawBitmap(*pCanvas, imageRect, *pReplacementColorBitmap,
1739                                                 FloatRectangle(0.0f, 0.0f, pChildIndexImage->GetWidthF(), pChildIndexImage->GetHeightF()));
1740                                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to draw a bitmap.", GetErrorMessage(r));
1741
1742                                 delete pReplacementColorBitmap;
1743                                 pReplacementColorBitmap = null;
1744                         }
1745                         else
1746                         {
1747                                 String* pChildIndexText = pChildIndex->GetIndexText();
1748                                 SysTryCatch(NID_UI_CTRL, pChildIndexText, , E_INVALID_STATE, "[E_INVALID_STATE] pChildIndexText must not be null.");
1749
1750                                 pTextObject->RemoveAll();
1751
1752                                 pSimpleText = new (std::nothrow)TextSimple(const_cast<wchar_t*>(pChildIndexText->GetPointer()), pChildIndexText->GetLength(), TEXT_ELEMENT_SOURCE_TYPE_EXTERNAL);
1753                                 SysTryCatch(NID_UI_CTRL, pSimpleText, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1754
1755                                 r = pTextObject->AppendElement(*pSimpleText);
1756                                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to append simple text.", GetErrorMessage(r));
1757
1758                                 r = pTextObject->SetWrap(TEXT_OBJECT_WRAP_TYPE_WORD);
1759                                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set wrap.", GetErrorMessage(r));
1760
1761                                 r = pTextObject->SetFont(__viewConfig.__pFont, 0, pTextObject->GetTextLength());
1762                                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set font.", GetErrorMessage(r));
1763
1764                                 r = pTextObject->SetForegroundColor(__viewConfig.__popupTextColor, 0, pTextObject->GetTextLength());
1765                                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set foreground color.", GetErrorMessage(r));
1766
1767                                 r = pTextObject->SetAlignment(TEXT_OBJECT_ALIGNMENT_CENTER | TEXT_OBJECT_ALIGNMENT_MIDDLE);
1768                                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set alignment.", GetErrorMessage(r));
1769
1770                                 r = pTextObject->SetBounds(indexRect);
1771                                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set bounds of pTextObject.", GetErrorMessage(r));
1772
1773                                 r = pTextObject->Draw(*_CanvasImpl::GetInstance(*pCanvas));
1774                                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to draw text.", GetErrorMessage(r));
1775                         }
1776                 }
1777
1778                 indexRect.y += indexHeight;
1779         }
1780
1781         //fall through
1782 CATCH:
1783         delete pTextObject;
1784         delete pCanvas;
1785         delete pReplacementColorBitmap;
1786 }
1787
1788 result
1789 _FastScrollPopupView::DrawBitmap(Canvas& canvas, const FloatRectangle& bounds, const Bitmap& bitmap)
1790 {
1791         result r = E_SUCCESS;
1792         if (_BitmapImpl::CheckNinePatchedBitmapStrictly(bitmap))
1793         {
1794                 r = canvas.DrawNinePatchedBitmap(bounds, bitmap);
1795                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to draw ninepathced bitmap");
1796         }
1797         else
1798         {
1799                 r = canvas.DrawBitmap(bounds, bitmap);
1800                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to draw bitmap");
1801         }
1802
1803         return E_SUCCESS;
1804 }
1805
1806 result
1807 _FastScrollPopupView::DrawBitmap(Canvas& canvas, const FloatRectangle& srcRect, const Bitmap& bitmap, const FloatRectangle& dstRect)
1808 {
1809         result r = E_SUCCESS;
1810         if (_BitmapImpl::CheckNinePatchedBitmapStrictly(bitmap))
1811         {
1812                 r = canvas.DrawNinePatchedBitmap(srcRect, bitmap);
1813                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to draw ninepathced bitmap");
1814         }
1815         else
1816         {
1817                 r = canvas.DrawBitmap(srcRect, bitmap, dstRect);
1818                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to draw bitmap");
1819         }
1820
1821         return E_SUCCESS;
1822 }
1823
1824 result
1825 _FastScrollPopupView::Construct(void)
1826 {
1827         result r = E_SUCCESS;
1828
1829         __pPopupVe = new (std::nothrow) _VisualElement();
1830         SysTryCatch(NID_UI_CTRL, __pPopupVe, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1831
1832         r = __pPopupVe->Construct();
1833         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to construct the popup ve.", GetErrorMessage(r));
1834
1835         __pPopupVe->SetAnimationProvider(this);
1836
1837         r = __pPopupVe->SetSurfaceOpaque(false);
1838         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set the opaque of the popup ve.", GetErrorMessage(r));
1839
1840         __pPopupVe->SetImplicitAnimationEnabled(false);
1841
1842         r = __parentVe.AttachChild(*__pPopupVe);
1843         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to attach the popup ve to the parent.", GetErrorMessage(r));
1844
1845         __pPopupVe->SetShowState(true);
1846         __pPopupVe->SetClipChildrenEnabled(true);
1847         __pPopupVe->SetOpacity(FASTSCROLL_OPACITY_OFF);
1848
1849         __needUpdatePopupVe = true;
1850
1851         __matrixOrigin.SetAsIdentity();
1852         __matrixFadeInStart.SetAsIdentity();
1853         __matrixFadeOutEnd.SetAsIdentity();
1854
1855         _MatrixUtilScale(__matrixFadeInStart, 0.8f, 0.8f, 1.0f);
1856         _MatrixUtilScale(__matrixFadeOutEnd, 0.1f, 0.1f, 1.0f);
1857
1858         return E_SUCCESS;
1859
1860 CATCH:
1861         if (__pPopupVe)
1862         {
1863                 __pPopupVe->Destroy();
1864                 __pPopupVe = null;
1865         }
1866
1867         return r;
1868 }
1869
1870 _FastScrollPresenter::_FastScrollPresenter(_Control& parentCtrl, _FastScroll& fastScroll, bool visibility)
1871         : __parentCtrl(parentCtrl)
1872         , __fastScroll(fastScroll)
1873         , __pCtrlVe(null)
1874         , __pViewConfig(null)
1875         , __pFastScrollEvent(null)
1876         , __pFastScrollModel(null)
1877         , __fontStyle(0)
1878         , __fontSize(0.0f)
1879         , __pPopupView(null)
1880         , __focusedIndexLevel(0)
1881         , __pSelectedIndex(null)
1882         , __enableFadeEffect(true)
1883         , __indexCountMax(0)
1884         , __fadeIn(false)
1885         , __fadeOut(false)
1886         , __scrollVisibility(visibility)
1887         , __fadeEffectDuration_ms(500)
1888 {
1889 }
1890
1891 _FastScrollPresenter::~_FastScrollPresenter(void)
1892 {
1893         delete __pFastScrollEvent;
1894         __pFastScrollEvent = null;
1895
1896         delete __pFastScrollModel;
1897         __pFastScrollModel = null;
1898
1899         delete __pPopupView;
1900         __pPopupView = null;
1901
1902         RemoveAllIndexViews(false);
1903
1904         delete __pViewConfig;
1905         __pViewConfig = null;
1906
1907         if (__pCtrlVe)
1908         {
1909                 __pCtrlVe->RemoveAllAnimations();
1910                 __pCtrlVe->SetAnimationProvider(null);
1911         }
1912 }
1913
1914 _FastScrollPresenter*
1915 _FastScrollPresenter::CreateFastScrollPresenterN(_Control& parentCtrl, _FastScroll& fastScroll, bool visibility)
1916 {
1917         _FastScrollPresenter* pPresenter = new (std::nothrow) _FastScrollPresenter(parentCtrl, fastScroll, visibility);
1918         SysTryReturn(NID_UI_CTRL, pPresenter, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1919
1920         result r = pPresenter->Construct();
1921         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
1922
1923         return pPresenter;
1924
1925 CATCH:
1926         delete pPresenter;
1927
1928         return null;
1929 }
1930
1931 result
1932 _FastScrollPresenter::SetRootIndex(_FastScrollIndex* pIndex)
1933 {
1934         result r = E_SUCCESS;
1935
1936         // initialize index views
1937         RemoveAllIndexViews(false);
1938
1939         // initialize the popup view
1940         if (__pPopupView)
1941         {
1942                 r = __pPopupView->SetPopupVisibility(false);
1943                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to clear visibility of the popup view.");
1944         }
1945
1946         r = SetFontInfo(FONT_STYLE_PLAIN, __pViewConfig->__indexTextSize);
1947         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to set font.");
1948
1949         // set the root index into _FastScrollModel
1950         r = __pFastScrollModel->SetRootIndex(pIndex);
1951         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to set the root index into _FastScrollModel");
1952
1953         // add new root index view.
1954         if (pIndex)
1955         {
1956                 r = AddIndexView(0, *pIndex);
1957                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to add the root index view.");
1958         }
1959
1960         return E_SUCCESS;
1961 }
1962
1963 _FastScrollIndex*
1964 _FastScrollPresenter::GetRootIndex(void) const
1965 {
1966         return __pFastScrollModel->GetRootIndex();
1967 }
1968
1969 result
1970 _FastScrollPresenter::UpdateIndex(void)
1971 {
1972         result r = E_SUCCESS;
1973
1974         // update the base index of index views
1975         int indexViewCount = GetIndexViewCount();
1976         for (int i = 0; i < indexViewCount; i++)
1977         {
1978                 _FastScrollIndexView* pIndexView = GetIndexView(i);
1979                 SysTryReturnResult(NID_UI_CTRL, pIndexView, GetLastResult(), "Failed to get the index view.");
1980
1981                 _FastScrollIndex* pIndex = pIndexView->GetBaseIndex();
1982
1983                 if ((pIndex->GetChildCount() > __indexCountMax) && (pIndex->GetIndexType() != FAST_SCROLL_INDEX_TYPE_OMISSION))
1984                 {
1985                         r = pIndex->SetOmissionIndex(__indexCountMax);
1986                         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to set omiited index.");
1987                 }
1988
1989                 r = pIndexView->UpdateIndex(true);
1990                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to update the index view.");
1991         }
1992
1993         // update the base index of the popup view
1994         if (__pPopupView)
1995         {
1996                 r = __pPopupView->UpdateIndex();
1997                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to update the popup view.");
1998         }
1999
2000         return E_SUCCESS;
2001 }
2002
2003 void
2004 _FastScrollPresenter::EnableFadeEffect(bool enable)
2005 {
2006         __enableFadeEffect = enable;
2007 }
2008
2009 bool
2010 _FastScrollPresenter::IsEnabledFadeEffect(void) const
2011 {
2012         return __enableFadeEffect;
2013 }
2014
2015 bool
2016 _FastScrollPresenter::IsOnFadeEffect(void) const
2017 {
2018         return (__fadeIn || __fadeOut);
2019 }
2020
2021 bool
2022 _FastScrollPresenter::IsScrollVisible(void) const
2023 {
2024         return (__fadeIn || __fadeOut || __scrollVisibility);
2025 }
2026
2027 result
2028 _FastScrollPresenter::SetScrollVisibility(bool visibility)
2029 {
2030         result r = E_SUCCESS;
2031
2032         if (GetScrollVisibility() == visibility)
2033         {
2034                 // keep up current visibility.
2035                 return E_SUCCESS;
2036         }
2037
2038         if (visibility == false && __pSelectedIndex != null)
2039         {
2040                 return E_SUCCESS;
2041         }
2042
2043         __pCtrlVe->RemoveAllAnimations();
2044         if (visibility)
2045         {
2046                 if (__enableFadeEffect)
2047                 {
2048                         __fadeIn = true;
2049                         __fadeOut = false;
2050
2051                         __pCtrlVe->SetImplicitAnimationEnabled(true);
2052                 }
2053
2054                 __pCtrlVe->SetOpacity(FASTSCROLL_OPACITY_ON);
2055
2056                 if (__enableFadeEffect)
2057                 {
2058                         __pCtrlVe->SetImplicitAnimationEnabled(false);
2059                 }
2060                 else
2061                 {
2062                         __fadeIn = false;
2063                         __fadeOut = false;
2064                 }
2065         }
2066         else
2067         {
2068                 if (__enableFadeEffect)
2069                 {
2070                         __fadeIn = false;
2071                         __fadeOut = true;
2072
2073                         __pCtrlVe->SetImplicitAnimationEnabled(true);
2074                 }
2075
2076                 __pCtrlVe->SetOpacity(FASTSCROLL_OPACITY_OFF);
2077
2078                 if (__enableFadeEffect)
2079                 {
2080                         __pCtrlVe->SetImplicitAnimationEnabled(false);
2081                 }
2082                 else
2083                 {
2084                         __fadeIn = false;
2085                         __fadeOut = false;
2086                 }
2087         }
2088
2089         __scrollVisibility = visibility;
2090
2091         return  r;
2092 }
2093
2094 bool
2095 _FastScrollPresenter::GetScrollVisibility(void) const
2096 {
2097         float opacity = __pCtrlVe->GetOpacity();
2098
2099         if (__enableFadeEffect)
2100         {
2101                 if (__scrollVisibility)
2102                 {
2103                         return true;
2104                 }
2105         }
2106         else if (opacity > FASTSCROLL_OPACITY_OFF)
2107         {
2108                 return true;
2109         }
2110
2111         return false;
2112 }
2113
2114 void
2115 _FastScrollPresenter::CancelFadeEffect(void)
2116 {
2117         if (__fadeIn)
2118         {
2119                 __fadeIn = false;
2120                 __scrollVisibility = false;
2121                 __pCtrlVe->SetOpacity(FASTSCROLL_OPACITY_OFF);
2122         }
2123         else if (__fadeOut)
2124         {
2125                 __fadeOut = false;
2126                 __scrollVisibility = true;
2127                 __pCtrlVe->SetOpacity(FASTSCROLL_OPACITY_ON);
2128         }
2129 }
2130
2131 void
2132 _FastScrollPresenter::AddFastScrollEventListener(const Controls::_IUiFastScrollListener& listener)
2133 {
2134         result r = E_SUCCESS;
2135
2136         if (__pFastScrollEvent == null)
2137         {
2138                 __pFastScrollEvent = new (std::nothrow) _UiFastScrollEvent();
2139                 SysTryReturnVoidResult(NID_UI_CTRL, __pFastScrollEvent, E_OUT_OF_MEMORY,
2140                                 "[E_OUT_OF_MEMORY] Memory allocation failed.");
2141
2142                 r = __pFastScrollEvent->Construct(__fastScroll);
2143                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
2144         }
2145
2146         r = __pFastScrollEvent->AddListener(listener);
2147         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
2148 }
2149
2150 void
2151 _FastScrollPresenter::RemoveFastScrollEventListener(const Controls::_IUiFastScrollListener& listener)
2152 {
2153         result r = E_SUCCESS;
2154
2155         SysTryReturnVoidResult(NID_UI_CTRL, __pFastScrollEvent, E_INVALID_STATE, "[E_INVALID_STATE] __pFastScrollEvent must not be null.");
2156
2157         r = __pFastScrollEvent->RemoveListener(listener);
2158         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
2159 }
2160
2161 void
2162 _FastScrollPresenter::OnParentBoundsChanged(void)
2163 {
2164         RelayoutFastScrollChildren();
2165 }
2166
2167 void
2168 _FastScrollPresenter::OnDraw(void)
2169 {
2170         // draw index views
2171         int indexViewCount = GetIndexViewCount();
2172         for (int i = 0; i < indexViewCount; i++)
2173         {
2174                 _FastScrollIndexView* pIndexView = GetIndexView(i);
2175                 SysTryReturnVoidResult(NID_UI_CTRL, pIndexView, GetLastResult(), "[%s] Failed to get the index view.",
2176                                 GetErrorMessage(GetLastResult()));
2177
2178                 result r = SetFontInfo(FONT_STYLE_PLAIN, __pViewConfig->__indexTextSize);
2179                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to set font.", GetErrorMessage(r));
2180                 pIndexView->OnDraw();
2181
2182                 // draw the popup view
2183                 if (__pPopupView && i <= __focusedIndexLevel)
2184                 {
2185                         r = SetFontInfo(FONT_STYLE_PLAIN, __pViewConfig->__popupTextSize);
2186                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to set font.", GetErrorMessage(r));
2187                         __pPopupView->OnDraw(i, pIndexView->GetBaseIndex(), pIndexView->GetSelectedIndexInOmittedIndex());
2188                 }
2189         }
2190
2191         if (__pPopupView)
2192         {
2193                 __pPopupView->SetPopupVeUpdateNeeded(false);
2194         }
2195 }
2196
2197 bool
2198 _FastScrollPresenter::OnTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
2199 {
2200         FloatPoint touchedPosition = touchinfo.GetCurrentPosition();
2201         return OnTouchPressedAndMoved(touchedPosition, true);
2202 }
2203
2204 bool
2205 _FastScrollPresenter::OnTouchReleased(const _Control& source, const _TouchInfo& touchinfo)
2206 {
2207         return OnTouchReleasedAndCanceled();
2208 }
2209
2210 bool
2211 _FastScrollPresenter::OnTouchMoved(const _Control& source, const _TouchInfo& touchinfo)
2212 {
2213         FloatPoint touchedPosition = touchinfo.GetCurrentPosition();
2214         return OnTouchPressedAndMoved(touchedPosition, false);
2215 }
2216
2217 bool
2218 _FastScrollPresenter::OnTouchCanceled(const _Control& source, const _TouchInfo& touchinfo)
2219 {
2220         return OnTouchReleasedAndCanceled();
2221 }
2222
2223 void
2224 _FastScrollPresenter::OnFontChanged(Font* pFont)
2225 {
2226         __pViewConfig->__pFont = pFont;
2227 }
2228
2229 void
2230 _FastScrollPresenter::OnFontInfoRequested(unsigned long& style, float& size)
2231 {
2232         style = __fontStyle;
2233         size = __fontSize;
2234 }
2235
2236 result
2237 _FastScrollPresenter::SetFontInfo(unsigned long style, float size)
2238 {
2239         __fontStyle = style;
2240         __fontSize = size;
2241
2242         __pViewConfig->__pFont = __fastScroll.GetFallbackFont();
2243         SysTryReturnResult(NID_UI_CTRL, __pViewConfig->__pFont, GetLastResult(), "Failed to get a font.");
2244
2245         return E_SUCCESS;
2246 }
2247
2248 VisualElementAnimation*
2249 _FastScrollPresenter::CreateAnimationForProperty(VisualElement& target, const String& property)
2250 {
2251         VisualElementAnimation* pAnimation = VisualElementAnimationProvider::CreateAnimationForProperty(target, property);
2252
2253         if (pAnimation)
2254         {
2255                 const IVisualElementAnimationTimingFunction* pTimingFunction = VisualElementAnimation::GetTimingFunctionByName("EaseInOut");
2256                 if (pTimingFunction)
2257                 {
2258                         pAnimation->SetTimingFunction(pTimingFunction);
2259                 }
2260                 pAnimation->SetVisualElementAnimationStatusEventListener(this);
2261         }
2262         return pAnimation;
2263 }
2264
2265 void
2266 _FastScrollPresenter::OnVisualElementAnimationStarted(const VisualElementAnimation& animation, const String& keyName, VisualElement& target)
2267 {
2268 }
2269
2270 void
2271 _FastScrollPresenter::OnVisualElementAnimationRepeated(const VisualElementAnimation& animation, const String& keyName, VisualElement& target, long currentRepeatCount)
2272 {
2273 }
2274
2275 void
2276 _FastScrollPresenter::OnVisualElementAnimationFinished(const VisualElementAnimation& animation, const String& keyName, VisualElement& target, bool completedNormally)
2277 {
2278         if (__pCtrlVe == (static_cast <_VisualElement*>(&target)))
2279         {
2280                 __fadeIn = false;
2281                 __fadeOut = false;
2282         }
2283 }
2284
2285 HitTestResult
2286 _FastScrollPresenter::HitTest(const Tizen::Graphics::FloatPoint& point)
2287 {
2288         if (IsScrollVisible() == false)
2289         {
2290                 return HIT_TEST_NOWHERE;
2291         }
2292
2293         int indexViewCount = GetIndexViewCount();
2294         for (int i = 0; i < indexViewCount; i++)
2295         {
2296                 _FastScrollIndexView* pIndexView = GetIndexView(i);
2297                 SysTryReturn(NID_UI_CTRL, pIndexView, HIT_TEST_NOWHERE, GetLastResult(), "[%s] Failed to get the index view.",
2298                                 GetErrorMessage(GetLastResult()));
2299
2300                 FloatRectangle indexBounds = pIndexView->GetIndexBoundsF();
2301                 if (indexBounds.Contains(point) == true)
2302                 {
2303                         return HIT_TEST_MATCH;
2304                 }
2305         }
2306
2307         return HIT_TEST_NOWHERE;
2308 }
2309
2310 void
2311 _FastScrollPresenter::OnIndexDataUpdated(_FastScrollIndex& updatedIndex)
2312 {
2313         result r = E_SUCCESS;
2314
2315         int indexViewCount = GetIndexViewCount();
2316         for (int i = 0; i < indexViewCount; i++)
2317         {
2318                 _FastScrollIndexView* pIndexView = GetIndexView(i);
2319                 SysTryReturnVoidResult(NID_UI_CTRL, pIndexView, GetLastResult(), "[%s] Failed to get the index view.",
2320                                 GetErrorMessage(GetLastResult()));
2321
2322                 if (pIndexView->GetBaseIndex() == &updatedIndex)
2323                 {
2324                         r = pIndexView->UpdateIndex(false);
2325                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to update index view.", GetErrorMessage(r));
2326
2327                         if (__pPopupView)
2328                         {
2329                                 r = __pPopupView->UpdateIndex();
2330                                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to update the popup view.", GetErrorMessage(r));
2331                         }
2332                         break;
2333                 }
2334         }
2335 }
2336
2337 void
2338 _FastScrollPresenter::OnIndexDeleted(_FastScrollIndex& deletedIndex)
2339 {
2340         result r = E_SUCCESS;
2341
2342         int indexViewCount = GetIndexViewCount();
2343         for (int i = 0; i < indexViewCount; i++)
2344         {
2345                 _FastScrollIndexView* pIndexView = GetIndexView(i);
2346                 SysTryReturnVoidResult(NID_UI_CTRL, pIndexView, GetLastResult(), "[%s] Failed to get the index view.",
2347                                 GetErrorMessage(GetLastResult()));
2348
2349                 if (pIndexView->GetBaseIndex() == &deletedIndex)
2350                 {
2351                         // first of all, update the base index view
2352                         if (i != 0)
2353                         {
2354                                 _FastScrollIndexView* pBaseIndexView = GetIndexView(i - 1);
2355                                 SysTryReturnVoidResult(NID_UI_CTRL, pBaseIndexView, GetLastResult(), "[%s] Failed to get the index view.",
2356                                                 GetErrorMessage(GetLastResult()));
2357
2358                                 r = pBaseIndexView->UpdateIndex(false);
2359                                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to update index view.", GetErrorMessage(r));
2360                         }
2361
2362                         // then remove the index view for detached index.
2363                         RemoveIndexView(i, true);
2364
2365                         delete __pPopupView;
2366                         __pPopupView = null;
2367
2368                         break;
2369                 }
2370                 else if (pIndexView->GetBaseIndex() == deletedIndex.GetParentIndex())
2371                 {
2372                         r = pIndexView->UpdateIndex(false);
2373                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to update index view.", GetErrorMessage(r));
2374
2375                         r = __pPopupView->UpdateIndex();
2376                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to update popup view.", GetErrorMessage(r));
2377                 }
2378         }
2379 }
2380
2381 void
2382 _FastScrollPresenter::OnChildIndexAttached(_FastScrollIndex& parentIndex, int attachedOrder, _FastScrollIndex& attachedIndex)
2383 {
2384         result r = E_SUCCESS;
2385
2386         int indexViewCount = GetIndexViewCount();
2387         for (int i = 0; i < indexViewCount; i++)
2388         {
2389                 _FastScrollIndexView* pIndexView = GetIndexView(i);
2390                 SysTryReturnVoidResult(NID_UI_CTRL, pIndexView, GetLastResult(), "[%s] Failed to get the index view.",
2391                                 GetErrorMessage(GetLastResult()));
2392
2393                 if (pIndexView->GetBaseIndex() == &parentIndex)
2394                 {
2395                         r = pIndexView->UpdateIndex(false);
2396                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to update index view.", GetErrorMessage(r));
2397
2398                         r = __pPopupView->UpdateIndex();
2399                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to update popup view.", GetErrorMessage(r));
2400                         break;
2401                 }
2402         }
2403 }
2404
2405 void
2406 _FastScrollPresenter::OnChildIndexDetached(_FastScrollIndex& parentIndex, int detachedOrder, _FastScrollIndex& detachedIndex)
2407 {
2408         result r = E_SUCCESS;
2409
2410         int indexViewCount = GetIndexViewCount();
2411         for (int i = 0; i < indexViewCount; i++)
2412         {
2413                 _FastScrollIndexView* pIndexView = GetIndexView(i);
2414                 SysTryReturnVoidResult(NID_UI_CTRL, pIndexView, GetLastResult(), "[%s] Failed to get the index view.",
2415                                 GetErrorMessage(GetLastResult()));
2416
2417                 if (pIndexView->GetBaseIndex() == &detachedIndex)
2418                 {
2419                         // first of all, update the base index view
2420                         if (i != 0)
2421                         {
2422                                 _FastScrollIndexView* pBaseIndexView = GetIndexView(i - 1);
2423                                 SysTryReturnVoidResult(NID_UI_CTRL, pBaseIndexView, GetLastResult(), "[%s] Failed to get the index view.",
2424                                                 GetErrorMessage(GetLastResult()));
2425
2426                                 r = pBaseIndexView->UpdateIndex(false);
2427                                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to update index view.", GetErrorMessage(r));
2428                         }
2429
2430                         // then remove the index view for detached index.
2431                         RemoveIndexView(i, true);
2432
2433                         delete __pPopupView;
2434                         __pPopupView = null;
2435                         break;
2436                 }
2437                 else if (pIndexView->GetBaseIndex() == &parentIndex)
2438                 {
2439                         r = pIndexView->UpdateIndex(false);
2440                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to update index view.", GetErrorMessage(r));
2441
2442                         r = __pPopupView->UpdateIndex();
2443                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to update popup view.", GetErrorMessage(r));
2444                 }
2445         }
2446 }
2447
2448
2449 result
2450 _FastScrollPresenter::Construct(void)
2451 {
2452         result r = E_SUCCESS;
2453
2454         // load color/shape configuration and bitmap resources
2455         __pViewConfig = _FastScrollViewConfig::CreateFastScrollViewConfigN(_CONTROL_ORIENTATION_PORTRAIT);
2456         SysTryReturnResult(NID_UI_CTRL, __pViewConfig, GetLastResult(), "Failed to create _FastScrollViewConfig.");
2457
2458         // create _FastScrollModel
2459         __pFastScrollModel = _FastScrollModel::CreateFastScrollModelN();
2460         SysTryCatch(NID_UI_CTRL, __pFastScrollModel, , GetLastResult(), "[%s] Failed to create _FastScrollModel.",
2461                         GetErrorMessage(GetLastResult()));
2462
2463         // initialize visual elements
2464         __pCtrlVe = __fastScroll.GetVisualElement();
2465         SysTryCatch(NID_UI_CTRL, __pCtrlVe, , GetLastResult(), "[%s] Failed to get VisualElement of the _FastScroll",
2466                         GetErrorMessage(GetLastResult()));
2467
2468         __pCtrlVe->SetAnimationProvider(this);
2469         __pCtrlVe->SetClipChildrenEnabled(false);
2470
2471         if (__scrollVisibility)
2472         {
2473                 __pCtrlVe->SetOpacity(FASTSCROLL_OPACITY_ON);
2474         }
2475         else
2476         {
2477                 __pCtrlVe->SetOpacity(FASTSCROLL_OPACITY_OFF);
2478         }
2479
2480         // initialize the fastscroll control
2481         r = __fastScroll.SetBounds(CalculateFastScrollBounds(0));
2482         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set the bounds of _FastScroll", GetErrorMessage(r));
2483
2484         __fastScroll.SetBackgroundColor(Tizen::Graphics::Color(0, 0, 0, 0));
2485
2486         __indexCountMax = _CoordinateSystemUtils::ConvertToInteger((__fastScroll.GetBoundsF().height -
2487                                 (__pViewConfig->__indexMarginTop * 2.0f)) /     __pViewConfig->__indexSizeMin.height);
2488
2489         return E_SUCCESS;
2490
2491 CATCH:
2492         delete __pFastScrollModel;
2493         __pFastScrollModel = null;
2494
2495         delete __pViewConfig;
2496         __pViewConfig = null;
2497
2498         return GetLastResult();
2499 }
2500
2501 FloatRectangle
2502 _FastScrollPresenter::CalculateFastScrollBounds(int indexCount)
2503 {
2504         FloatRectangle fastScrollBounds(0.0f, 0.0f, 0.0f, 0.0f);
2505         FloatRectangle parentBounds = __parentCtrl.GetBoundsF();
2506         fastScrollBounds.width = parentBounds.width;
2507         fastScrollBounds.height = parentBounds.height;
2508         return fastScrollBounds;
2509 }
2510
2511 FloatRectangle
2512 _FastScrollPresenter::CalculateIndexBounds(int indexLevel, _FastScrollIndex& pIndex)
2513 {
2514         FloatRectangle fastScrollBounds = __fastScroll.GetBoundsF();
2515         FloatRectangle indexBounds(0.0f, 0.0f, __pViewConfig->__indexSizeMin.width, fastScrollBounds.height);
2516
2517         indexBounds.x = fastScrollBounds.width - __pViewConfig->__indexSizeMin.width;
2518         for (int i = 1; i <= indexLevel; i++)
2519         {
2520                 indexBounds.x -= __pViewConfig->__indexGap + __pViewConfig->__indexSizeMin.width;
2521         }
2522
2523         if (indexBounds.x < 0.0f)
2524         {
2525                 indexBounds.x = 0.0f;
2526         }
2527
2528         if (indexLevel != 0)
2529         {
2530                 int childCount = pIndex.GetChildCount();
2531                 indexBounds.height = (childCount * __pViewConfig->__indexSizeMin.height) + (__pViewConfig->__indexMarginTop * 2.0f);
2532
2533                 if (indexBounds.height < fastScrollBounds.height)
2534                 {
2535                         _FastScrollIndexView* pParentIndexView = GetIndexView(indexLevel - 1);
2536                         if (pParentIndexView)
2537                         {
2538                                 FloatRectangle parentBounds = pParentIndexView->GetIndexBoundsF();
2539
2540                                 indexBounds.y = parentBounds.y + (pIndex.GetIndexOrder() * pParentIndexView->GetIndexHeight()) - __pViewConfig->__indexMarginTop;
2541                                 if (indexBounds.y < fastScrollBounds.y)
2542                                 {
2543                                         indexBounds.y = fastScrollBounds.y;
2544                                 }
2545
2546                                 float totalHeight = indexBounds.y + indexBounds.height;
2547                                 if (_FloatCompare(totalHeight, fastScrollBounds.height) || (totalHeight > fastScrollBounds.height))
2548                                 {
2549                                         indexBounds.y = fastScrollBounds.height - indexBounds.height;
2550                                 }
2551                         }
2552                 }
2553                 else
2554                 {
2555                         indexBounds.height = fastScrollBounds.height;
2556                 }
2557         }
2558
2559         return indexBounds;
2560 }
2561
2562 FloatRectangle
2563 _FastScrollPresenter::CalculatePopupBounds(void)
2564 {
2565         FloatRectangle popupBounds(0.0f, 0.0f, 0.0f, 0.0f);
2566         FloatRectangle parentBounds = __parentCtrl.GetBoundsF();
2567         FloatRectangle fastScrollBounds = __fastScroll.GetBoundsF();
2568
2569         popupBounds.width = __pViewConfig->__popupSize.width + (__pViewConfig->__popupWidthIncrement * __focusedIndexLevel);
2570         if (popupBounds.width > parentBounds.width)
2571         {
2572                 popupBounds.width = parentBounds.width;
2573         }
2574
2575         popupBounds.height = __pViewConfig->__popupSize.height;
2576         if (popupBounds.height > parentBounds.height)
2577         {
2578                 popupBounds.height = parentBounds.height;
2579         }
2580
2581         popupBounds.x = ((parentBounds.width - popupBounds.width) / 2.0f) - fastScrollBounds.x;
2582         if (popupBounds.x < 0.0f)
2583         {
2584                 popupBounds.x = 0.0f;
2585         }
2586
2587         popupBounds.y = ((parentBounds.height - popupBounds.height) / 2.0f) - fastScrollBounds.y;
2588         if (popupBounds.y < 0.0f)
2589         {
2590                 popupBounds.y = 0.0f;
2591         }
2592
2593         return popupBounds;
2594 }
2595
2596 void
2597 _FastScrollPresenter::RelayoutFastScrollChildren(void)
2598 {
2599         result r = E_SUCCESS;
2600
2601         int indexViewCount = GetIndexViewCount();
2602
2603         // initialize the fastscroll control
2604         r = __fastScroll.SetBounds(CalculateFastScrollBounds(indexViewCount));
2605         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to set the bounds of _FastScroll", GetErrorMessage(r));
2606
2607         __indexCountMax = _CoordinateSystemUtils::ConvertToInteger((__fastScroll.GetBoundsF().height -
2608                                 (__pViewConfig->__indexMarginTop * 2.0f)) /     __pViewConfig->__indexSizeMin.height);
2609
2610         for (int i = 0; i < indexViewCount; i++)
2611         {
2612                 _FastScrollIndexView* pIndexView = GetIndexView(i);
2613                 SysTryReturnVoidResult(NID_UI_CTRL, pIndexView, GetLastResult(), "[%s] Failed to get the index view.",
2614                                 GetErrorMessage(GetLastResult()));
2615
2616                 r = pIndexView->SetIndexBounds(CalculateIndexBounds(i, *(pIndexView->GetBaseIndex())));
2617                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to set bounds of the index.", GetErrorMessage(r));
2618
2619                 _FastScrollIndex* pIndex = pIndexView->GetBaseIndex();
2620                 if (pIndex->GetIndexType() == FAST_SCROLL_INDEX_TYPE_OMISSION)
2621                 {
2622                         _FastScrollIndex* pSelectedIndex = pIndexView->GetSelectedIndex();
2623                         if (pSelectedIndex && pSelectedIndex->GetOmitted())
2624                         {
2625                                 pIndexView->SetSelectedIndex(null);
2626                         }
2627                         r = pIndex->RemoveOmissionChildren(false);
2628                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to remove omission index view", GetErrorMessage(r));
2629                 }
2630
2631                 if (pIndex->GetChildCount() > __indexCountMax)
2632                 {
2633                         r = pIndex->SetOmissionIndex(__indexCountMax);
2634                         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to set omission index.", GetErrorMessage(r));
2635                 }
2636
2637                 r = pIndexView->UpdateIndex(false);
2638                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to update index view.", GetErrorMessage(r));
2639         }
2640
2641         if (__pPopupView)
2642         {
2643                 r = __pPopupView->SetPopupBounds(CalculatePopupBounds());
2644                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Failed to set bounds of the popup view.", GetErrorMessage(r));
2645         }
2646 }
2647
2648 _FastScrollIndex*
2649 _FastScrollPresenter::SelectOnIndexViews(const FloatPoint& point, bool animation)
2650 {
2651         result r = E_SUCCESS;
2652
2653         _FastScrollIndex* pSelectedIndex = null;
2654         int selectedIndexLevel = 0;
2655         int indexViewCount = GetIndexViewCount();
2656         SysTryReturn(NID_UI_CTRL, indexViewCount > 0, null, E_INVALID_STATE, "[E_INVALID_STATE] The root index view is invalid state.");
2657
2658         // search the hit index on index views, then fade out other index views
2659         for (int i = 0; i < indexViewCount; i++)
2660         {
2661                 _FastScrollIndexView* pIndexView = GetIndexView(i);
2662                 SysTryReturn(NID_UI_CTRL, pIndexView, null, GetLastResult(), "[%s] Failed to get the index view.",
2663                                 GetErrorMessage(GetLastResult()));
2664
2665                 _FastScrollIndex* pIndex = pIndexView->GetIndexAtPoint(point);
2666                 if (pIndex)
2667                 {
2668                         // select the index of the index view.
2669                         r = pIndexView->SelectIndex(pIndex, animation);
2670                         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Failed to select the index.", GetErrorMessage(r));
2671                         pSelectedIndex = pIndex;
2672                         if (pIndex->GetOmitted() == true)
2673                         {
2674                                 pSelectedIndex = pIndexView->GetOmissionIndexAtPoint(pIndex, point);
2675                         }
2676                         pIndexView->SetSelectedIndexInOmittedIndex(pSelectedIndex);
2677
2678                         selectedIndexLevel = i;
2679                         break;
2680                 }
2681         }
2682
2683         // if can no find the index on views, select index of the last index view
2684         if ((pSelectedIndex == null) && (__focusedIndexLevel != -1))
2685         {
2686                 _FastScrollIndexView* pFocusedIndexView = GetIndexView(__focusedIndexLevel);
2687                 SysTryReturn(NID_UI_CTRL, pFocusedIndexView, null, GetLastResult(), "[%s] Failed to get the index view.",
2688                                 GetErrorMessage(GetLastResult()));
2689
2690                 _FastScrollIndex* pIndex = pFocusedIndexView->GetIndexAtPoint(FloatPoint(pFocusedIndexView->GetIndexBoundsF().x, point.y));
2691                 if (pIndex)
2692                 {
2693                         // select the index of the focused index view.
2694                         r = pFocusedIndexView->SelectIndex(pIndex, animation);
2695                         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Failed to select the index.", GetErrorMessage(r));
2696                         pSelectedIndex = pIndex;
2697
2698                         if (pIndex->GetOmitted() == true)
2699                         {
2700                                 pSelectedIndex = pFocusedIndexView->GetOmissionIndexAtPoint(pIndex,
2701                                                                                 FloatPoint(pFocusedIndexView->GetIndexBoundsF().x, point.y));
2702                         }
2703                         pFocusedIndexView->SetSelectedIndexInOmittedIndex(pSelectedIndex);
2704
2705                         selectedIndexLevel = __focusedIndexLevel;
2706                 }
2707                 else
2708                 {
2709                         pSelectedIndex = pFocusedIndexView->GetSelectedIndex();
2710                         selectedIndexLevel = __focusedIndexLevel;
2711                 }
2712         }
2713
2714         if (pSelectedIndex)
2715         {
2716                 int childCount = pSelectedIndex->GetChildCount();
2717                 if (childCount > 0)
2718                 {
2719                         _FastScrollIndexView* pSelectedIndexView = GetIndexView(selectedIndexLevel + 1);
2720                         if (pSelectedIndexView)
2721                         {
2722                                 r = pSelectedIndexView->SelectIndex((_FastScrollIndex*)null, false);
2723                                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Failed to select the index.", GetErrorMessage(r));
2724
2725                                 r = pSelectedIndexView->SetBaseIndex(pSelectedIndex);
2726                                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Failed to set the base index of the index view.", GetErrorMessage(r));
2727
2728                                 r = pSelectedIndexView->SetIndexBounds(CalculateIndexBounds(selectedIndexLevel + 1, *pSelectedIndex));
2729                                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Failed to set bounds of the index.", GetErrorMessage(r));
2730
2731                                 r = pSelectedIndexView->SetIndexVisibility(true);
2732                                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Failed to set the visibility of the index view.", GetErrorMessage(r));
2733
2734                                 indexViewCount = GetIndexViewCount();
2735                                 while (indexViewCount > selectedIndexLevel + 2)
2736                                 {
2737                                         r = RemoveIndexView(indexViewCount - 1, true);
2738                                         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Failed to remove the index view.", GetErrorMessage(r));
2739                                         indexViewCount = GetIndexViewCount();
2740                                 }
2741                         }
2742                         else
2743                         {
2744                                 r = AddIndexView(*pSelectedIndex);
2745                                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Failed to add new child index.", GetErrorMessage(r));
2746                         }
2747
2748                         if ((childCount > __indexCountMax) && (pSelectedIndex->GetIndexType() != FAST_SCROLL_INDEX_TYPE_OMISSION))
2749                         {
2750                                 r = pSelectedIndex->SetOmissionIndex(__indexCountMax);
2751                                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Failed to set omission index.", GetErrorMessage(r));
2752                         }
2753                 }
2754                 else
2755                 {
2756                         indexViewCount = GetIndexViewCount();
2757                         while (indexViewCount > selectedIndexLevel + 1)
2758                         {
2759                                 r = RemoveIndexView(indexViewCount - 1, true);
2760                                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Failed to remove the index view.", GetErrorMessage(r));
2761                                 indexViewCount = GetIndexViewCount();
2762                         }
2763                 }
2764         }
2765         else
2766         {
2767                 indexViewCount = GetIndexViewCount();
2768                 while (indexViewCount > 1)
2769                 {
2770                         r = RemoveIndexView(indexViewCount - 1, true);
2771                         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Failed to remove the index view.", GetErrorMessage(r));
2772                         indexViewCount = GetIndexViewCount();
2773                 }
2774         }
2775
2776         __focusedIndexLevel = selectedIndexLevel;
2777         return pSelectedIndex;
2778 }
2779
2780 result
2781 _FastScrollPresenter::DeselectIndexViews(void)
2782 {
2783         result r = E_SUCCESS;
2784
2785         while (GetIndexViewCount() > 1)
2786         {
2787                 RemoveIndexView(GetIndexViewCount() - 1, true);
2788         }
2789
2790         _FastScrollIndexView* pIndexView = GetIndexView(0);
2791         SysTryReturnResult(NID_UI_CTRL, pIndexView, GetLastResult(), "Failed to get the index view.");
2792
2793         r = pIndexView->SelectIndex((_FastScrollIndex*)null, true);
2794         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to clear the index selection.");
2795         pIndexView->SetSelectedIndexInOmittedIndex(null);
2796
2797         __fastScroll.Invalidate();
2798
2799         return E_SUCCESS;
2800 }
2801
2802 result
2803 _FastScrollPresenter::SetPopupIndex(_FastScrollIndex& popupIndex, const FloatPoint& point)
2804 {
2805         result r = E_SUCCESS;
2806
2807         // set the selected node into the popup views.
2808         if (__pPopupView == null)
2809         {
2810                 __pPopupView = _FastScrollPopupView::CreateFastScrollPopupViewN(*__pCtrlVe, *__pViewConfig);
2811                 SysTryReturnResult(NID_UI_CTRL, __pPopupView, GetLastResult(), "Propagating.");
2812
2813                 r = __pPopupView->SetPopupBounds(CalculatePopupBounds());
2814                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to set bounds of the popup view.");
2815
2816                 r = __pPopupView->SetPopupVisibility(true);
2817                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to set visibility of the popup view.");
2818         }
2819
2820         int indexViewCount = __focusedIndexLevel + 1;
2821         int popupIndexViewCount = __pPopupView->GetIndexVeCount();
2822
2823         if (indexViewCount != popupIndexViewCount)
2824         {
2825                 r = __pPopupView->SetPopupBounds(CalculatePopupBounds());
2826                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to set bounds of the popup view.");
2827
2828                 if (indexViewCount > popupIndexViewCount)
2829                 {
2830                         for (int i = popupIndexViewCount; i < indexViewCount; i++)
2831                         {
2832                                 r = __pPopupView->AddPopupIndexVe(i);
2833                                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to add popup index ve.");
2834                         }
2835                 }
2836                 else if (indexViewCount < popupIndexViewCount)
2837                 {
2838                         for (int i = indexViewCount; i < popupIndexViewCount; i++)
2839                         {
2840                                 r = __pPopupView->RemovePopupIndexVe(i);
2841                                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to remove popup index ve.");
2842                         }
2843                 }
2844         }
2845
2846         r = __pPopupView->UpdateIndex();
2847         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to update the popup view.");
2848
2849         for (int i = 0; i < indexViewCount; i++)
2850         {
2851                 _FastScrollIndexView* pIndexView = GetIndexView(i);
2852                 SysTryReturnResult(NID_UI_CTRL, pIndexView, r, "Failed to index view.");
2853
2854                 r = __pPopupView->SetPopupIndexBounds(i, pIndexView->GetBaseIndex());
2855                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to set bounds of the popup index ve.");
2856
2857                 _FastScrollIndex* pFormerIndex = null;
2858                 if ( i == __focusedIndexLevel )
2859                 {
2860                         pFormerIndex = pIndexView->GetFormerIndex();
2861                         r = __pPopupView->SelectIndex(i, &popupIndex, pFormerIndex);
2862                         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to select the popup index.");
2863                 }
2864                 else
2865                 {
2866                         r = __pPopupView->SelectIndex(i, null, null);
2867                         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to select the popup index.");
2868                 }
2869         }
2870
2871         return E_SUCCESS;
2872 }
2873
2874 result
2875 _FastScrollPresenter::ClearPopupIndex(void)
2876 {
2877         result r = E_SUCCESS;
2878
2879         // clear the node data of the popup view
2880         if (__pPopupView)
2881         {
2882                 r = __pPopupView->FadeOutAndDestroy();
2883                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to clear visibility of the popup view.");
2884
2885                 __pPopupView = null;
2886         }
2887
2888         return E_SUCCESS;
2889 }
2890
2891 result
2892 _FastScrollPresenter::FireFastScrollEvent(_FastScrollIndex& selectedIndex)
2893 {
2894         // fire the fast scroll event
2895         if (__pFastScrollEvent)
2896         {
2897                 String* pIndexNodeText = selectedIndex.GetIndexText();
2898                 if (pIndexNodeText)
2899                 {
2900                         _UiFastScrollEventArg* pEventArg = new (std::nothrow) _UiFastScrollEventArg(*__pFastScrollEvent->GetSource(), selectedIndex);
2901                         SysTryReturnResult(NID_UI_CTRL, pEventArg, E_OUT_OF_MEMORY,     "Memory allocation failed.");
2902
2903                         __pFastScrollEvent->Fire(*pEventArg);
2904                 }
2905         }
2906
2907         return E_SUCCESS;
2908 }
2909
2910 bool
2911 _FastScrollPresenter::OnTouchPressedAndMoved(const FloatPoint& point, bool animation)
2912 {
2913         result r = E_SUCCESS;
2914         if (__scrollVisibility == false)
2915         {
2916                 r = SetScrollVisibility(true);
2917                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, true, r, "[%s] Failed to fade out fastscroll.", GetErrorMessage(r));
2918         }
2919
2920         _FastScrollIndex* pSelectedIndex = SelectOnIndexViews(point, animation);
2921         if (pSelectedIndex && (__pSelectedIndex != pSelectedIndex))
2922         {
2923                 PLAY_FEEDBACK(_RESOURCE_FEEDBACK_PATTERN_TAP);
2924                 r = SetPopupIndex(*pSelectedIndex, point);
2925                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, true, r, "[%s] Failed to set the poup index.", GetErrorMessage(r));
2926
2927                 r = FireFastScrollEvent(*pSelectedIndex);
2928                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, true, r, "[%s] Failed to send the fast scroll event.", GetErrorMessage(r));
2929         }
2930
2931         __pSelectedIndex = pSelectedIndex;
2932
2933         return true;
2934 }
2935
2936 bool
2937 _FastScrollPresenter::OnTouchReleasedAndCanceled(void)
2938 {
2939         result r = E_SUCCESS;
2940
2941         r = DeselectIndexViews();
2942         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, true, r, "[%s] Failed to deselect index views.", GetErrorMessage(r));
2943
2944         r = ClearPopupIndex();
2945         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, true, r, "[%s] Failed to clear the popup index.", GetErrorMessage(r));
2946
2947         __pSelectedIndex = null;
2948         if (__scrollVisibility == true)
2949         {
2950                 r = SetScrollVisibility(false);
2951                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, true, r, "[%s] Failed to fade out fastscroll.", GetErrorMessage(r));
2952         }
2953
2954         return true;
2955 }
2956
2957 result
2958 _FastScrollPresenter::AddIndexView(_FastScrollIndex& baseIndex)
2959 {
2960         return AddIndexView(GetIndexViewCount(), baseIndex);
2961 }
2962
2963 result
2964 _FastScrollPresenter::AddIndexView(int indexLevel, _FastScrollIndex& baseIndex)
2965 {
2966         result r = E_SUCCESS;
2967
2968         _FastScrollIndexView* pNewIndexView = _FastScrollIndexView::CreateFastScrollIndexViewN( *__pCtrlVe, *__pViewConfig);
2969         SysTryReturnResult(NID_UI_CTRL, pNewIndexView, GetLastResult(), "Propagating.");
2970
2971         r = __fastScroll.SetBounds(CalculateFastScrollBounds(GetIndexViewCount() + 1));
2972         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to set the bounds of _FastScroll.");
2973
2974         r = pNewIndexView->SetIndexBounds(CalculateIndexBounds(indexLevel, baseIndex));
2975         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to set bounds of the index view.");
2976
2977         r = pNewIndexView->SetBaseIndex(&baseIndex);
2978         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to set the index data for the index view.");
2979
2980         r = pNewIndexView->SetIndexVisibility(true);
2981         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to set visibility of the index view.");
2982
2983         r = __indexViews.InsertAt(*pNewIndexView, indexLevel);
2984         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to change the last index view.");
2985
2986         return E_SUCCESS;
2987 }
2988
2989 result
2990 _FastScrollPresenter::RemoveIndexView(int indexLevel, bool fadeout)
2991 {
2992         result r = E_SUCCESS;
2993
2994         int indexViewCount = GetIndexViewCount();
2995         if (indexLevel < indexViewCount)
2996         {
2997                 _FastScrollIndexView* pIndexView = GetIndexView(indexLevel);
2998                 SysTryReturnResult(NID_UI_CTRL, pIndexView, GetLastResult(), "Failed to get the index view.");
2999
3000                 if (fadeout)
3001                 {
3002                         r = pIndexView->FadeOutAndDestroy();
3003                         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to request to fade out of the index view.");
3004                 }
3005
3006                 r = __indexViews.Remove(*pIndexView, false);
3007                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to remove the index views.");
3008
3009                 // initialize the fastscroll control
3010                 r = __fastScroll.SetBounds(CalculateFastScrollBounds(GetIndexViewCount()));
3011                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to set the bounds of _FastScroll");
3012         }
3013
3014         return E_SUCCESS;
3015 }
3016
3017 result
3018 _FastScrollPresenter::RemoveAllIndexViews(bool fadeout)
3019 {
3020         result r = E_SUCCESS;
3021
3022         if (fadeout)
3023         {
3024                 int indexViewCount = GetIndexViewCount();
3025                 for (int i = 0; i < indexViewCount; i++)
3026                 {
3027                         _FastScrollIndexView* pIndexView = GetIndexView(i);
3028                         SysTryReturnResult(NID_UI_CTRL, pIndexView, GetLastResult(), "Failed to get the index view.");
3029
3030                         r = pIndexView->FadeOutAndDestroy();
3031                         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to request to fade out of the index view.");
3032                 }
3033         }
3034
3035         __indexViews.RemoveAll(true);
3036
3037         // initialize the fastscroll control
3038         r = __fastScroll.SetBounds(CalculateFastScrollBounds(0));
3039         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to set the bounds of _FastScroll.");
3040
3041         return E_SUCCESS;
3042 }
3043
3044 _FastScrollIndexView*
3045 _FastScrollPresenter::GetIndexView(int indexLevel) const
3046 {
3047         Object* pIndexView = const_cast<Object*>(__indexViews.GetAt(indexLevel));
3048         SysTryReturn(NID_UI_CTRL, pIndexView, null, GetLastResult(), "[%s] Failed to get the index view.",
3049                         GetErrorMessage(GetLastResult()));
3050
3051         return dynamic_cast<_FastScrollIndexView*>(pIndexView);
3052 }
3053
3054 int
3055 _FastScrollPresenter::GetIndexViewCount(void) const
3056 {
3057         return __indexViews.GetCount();
3058 }
3059
3060 } } } // Tizen::Ui::Controls