Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / controls / FUiCtrl_FastScrollIndex.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_FastScrollIndex.cpp
20  * @brief               This is the implementation file for the _FastScrollIndex class.
21  */
22
23 #include <wchar.h>
24 #include <FBaseSysLog.h>
25 #include "FUiCtrl_FastScrollIndex.h"
26 #include "FGrp_BitmapImpl.h"
27
28 namespace Tizen { namespace Ui { namespace Controls
29 {
30
31 _FastScrollIndex::_FastScrollIndex(void)
32         : __pImage(null)
33         , __pText(null)
34         , __pParentIndex(null)
35         , __pIndexObserver(null)
36         , __omitted(false)
37         , __indexType(FAST_SCROLL_INDEX_TYPE_NORMAL)
38 {
39 }
40
41 _FastScrollIndex::~_FastScrollIndex(void)
42 {
43         if (__pIndexObserver)
44         {
45                 __pIndexObserver->OnIndexDeleted(*this);
46         }
47
48         if (__pParentIndex)
49         {
50                 __pParentIndex->RemoveChildIndex(this, false);
51                 __pParentIndex = null;
52         }
53
54         RemoveChildren(true);
55
56         delete __pImage;
57         __pImage = null;
58
59         delete __pText;
60         __pText = null;
61 }
62
63
64 _FastScrollIndex*
65 _FastScrollIndex::CreateFastScrollIndexN(void)
66 {
67         _FastScrollIndex* pIndex = new (std::nothrow) _FastScrollIndex();
68         SysTryReturn(NID_UI_CTRL, pIndex, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
69
70         result r = pIndex->Construct();
71         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
72
73         SetLastResult(E_SUCCESS);
74         return pIndex;
75
76 CATCH:
77         delete pIndex;
78
79         return null;
80 }
81
82 result
83 _FastScrollIndex::SetIndexText(Tizen::Base::String* pText)
84 {
85         delete __pText;
86         __pText = null;
87
88         if (pText)
89         {
90                 __pText = new (std::nothrow) Tizen::Base::String(*pText);
91                 SysTryReturnResult(NID_UI_CTRL, __pText, E_OUT_OF_MEMORY, "Memory allocation failed.");
92         }
93
94         // send the action to _IFastScrollIndexObserver
95         if (__pIndexObserver)
96         {
97                 __pIndexObserver->OnIndexDataUpdated(*this);
98         }
99
100         return E_SUCCESS;
101 }
102
103 Tizen::Base::String*
104 _FastScrollIndex::GetIndexText(void) const
105 {
106         return __pText;
107 }
108
109 result
110 _FastScrollIndex::SetIndexImage(Tizen::Graphics::Bitmap* pImage)
111 {
112         delete __pImage;
113         __pImage = null;
114
115         if (pImage)
116         {
117                 __pImage = Tizen::Graphics::_BitmapImpl::CloneN(*pImage);
118         }
119
120         // send the action to _IFastScrollIndexObserver
121         if (__pIndexObserver)
122         {
123                 __pIndexObserver->OnIndexDataUpdated(*this);
124         }
125
126         return E_SUCCESS;
127 }
128
129 Tizen::Graphics::Bitmap*
130 _FastScrollIndex::GetIndexImage(void) const
131 {
132         return __pImage;
133 }
134
135 void
136 _FastScrollIndex::SetIndexObserver(_IFastScrollIndexObserver* pIndexListener)
137 {
138         __pIndexObserver = pIndexListener;
139 }
140
141 _IFastScrollIndexObserver*
142 _FastScrollIndex::GetIndexObserver(void) const
143 {
144         return __pIndexObserver;
145 }
146
147 result
148 _FastScrollIndex::SetOmissionIndex(int indexCountMax)
149 {
150         int childCount = GetChildCount();
151         int maxOmissionSlot = (indexCountMax - 1) / 2;
152         int omissionCount = childCount - indexCountMax;
153         int omittedNum = (omissionCount / maxOmissionSlot) + 1;
154
155         int additionalOmittedNum = (omissionCount % maxOmissionSlot);
156         int additionalOmissionStartIndex = ((maxOmissionSlot - additionalOmittedNum) / 2);
157         int i = 0;
158         int j = 0;
159         result r = E_SUCCESS;
160
161         Tizen::Base::String omissionText(L".");
162
163         if ((indexCountMax % 2) == 0)
164         {
165                 r = AddChildIndex(GetChildIndex(i), true);
166                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to add child index.");
167                 i++;
168                 j++;
169         }
170
171         while (i < childCount)
172         {
173                 r = AddChildIndex(GetChildIndex(i), true);
174                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to add child index.");
175
176                 i++;
177                 j++;
178
179                 if (i >= childCount)
180                 {
181                         break;
182                 }
183
184                 int omittedCount = omittedNum;
185                 if ((additionalOmissionStartIndex < 0) && (additionalOmittedNum > 0))
186                 {
187                         omittedCount += 1;
188                         additionalOmittedNum--;
189                 }
190
191                 if (omittedCount < 2)
192                 {
193                         if ((i % 2) > 0)
194                         {
195                                 additionalOmissionStartIndex--;
196                         }
197                         continue;
198                 }
199
200                 r = AddChildIndex(&omissionText, null, true);
201                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to add child index.");
202
203                 _FastScrollIndex* pOmissionBaseIndex = GetChildIndex(j, true);
204                 SysTryReturnResult(NID_UI_CTRL, pOmissionBaseIndex, GetLastResult(), "Failed to get the child index.");
205                 pOmissionBaseIndex->SetOmitted(true);
206                 j++;
207                 additionalOmissionStartIndex--;
208
209                 for (int k = 0; k < omittedCount; k++)
210                 {
211                         pOmissionBaseIndex->AddOmissionChildIndex(GetChildIndex(i + k));
212                 }
213                 i += omittedCount;
214         }
215         SetIndexType(FAST_SCROLL_INDEX_TYPE_OMISSION);
216
217         return r;
218 }
219
220 result
221 _FastScrollIndex::AddChildIndex(Tizen::Base::String* pText, Tizen::Graphics::Bitmap* pImage, bool omitted)
222 {
223         _FastScrollIndex* pNewIndex = _FastScrollIndex::CreateFastScrollIndexN();
224         SysTryReturnResult(NID_UI_CTRL, pNewIndex, GetLastResult(), "Failed to create _FastScrollIndex.");
225
226         result r = pNewIndex->SetIndexText(pText);
227         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set text.", GetErrorMessage(r));
228
229         pNewIndex->SetIndexImage(pImage);
230
231         return AddChildIndex(pNewIndex, omitted);
232
233 CATCH:
234         delete pNewIndex;
235
236         return r;
237 }
238
239 result
240 _FastScrollIndex::AddChildIndex(_FastScrollIndex* pChildIndex, bool omitted)
241 {
242         return AddChildIndex(GetChildCount(omitted), pChildIndex, omitted);
243 }
244
245 result
246 _FastScrollIndex::AddChildIndex(int childOrder, Tizen::Base::String* pText, Tizen::Graphics::Bitmap* pImage, bool omitted)
247 {
248         _FastScrollIndex* pNewIndex = _FastScrollIndex::CreateFastScrollIndexN();
249         SysTryReturnResult(NID_UI_CTRL, pNewIndex, GetLastResult(), "Failed to create _FastScrollIndex.");
250
251         result r = pNewIndex->SetIndexText(pText);
252         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to set text.", GetErrorMessage(r));
253
254         pNewIndex->SetIndexImage(pImage);
255
256         return AddChildIndex(childOrder, pNewIndex, omitted);
257
258 CATCH:
259         delete pNewIndex;
260
261         return r;
262 }
263
264 result
265 _FastScrollIndex::AddChildIndex(int childOrder, _FastScrollIndex* pChildIndex, bool omitted)
266 {
267         SysTryReturnResult(NID_UI_CTRL, pChildIndex, E_INVALID_ARG, "Invalid argument is used. pChildIndex is null.");
268
269         Tizen::Base::Collection::ArrayList* pList = &__childIndexList;
270         if (omitted)
271         {
272                 pList = &__childOmittedIndexList;
273         }
274
275         if (pList->GetCount() <= childOrder)
276         {
277                 childOrder = GetChildCount(omitted);
278         }
279
280         pList->InsertAt(*pChildIndex, childOrder);
281         pChildIndex->SetParentIndex(this);
282
283         if (__pIndexObserver)
284         {
285                 __pIndexObserver->OnChildIndexAttached(*this, childOrder, *pChildIndex);
286         }
287
288         return E_SUCCESS;
289 }
290
291 void
292 _FastScrollIndex::AddOmissionChildIndex(_FastScrollIndex* pChildIndex)
293 {
294         if (GetOmitted() == false)
295         {
296                 return;
297         }
298
299         SysTryReturnVoidResult(NID_UI_CTRL, pChildIndex, E_INVALID_ARG,
300                         "[E_INVALID_ARG] Invalid argument is used. pChildIndex is null.");
301
302         __childIndexList.InsertAt(*pChildIndex, GetChildCount());
303 }
304
305 result
306 _FastScrollIndex::AddChildTextIndexArray(int childOrder, const wchar_t* pTextIndexArray, int textLenth, int indexCount)
307 {
308         result r = E_SUCCESS;
309
310         Tizen::Base::String* indexText = null;
311
312         wchar_t* pTempChar = new (std::nothrow) wchar_t[textLenth+1];
313         SysTryReturnResult(NID_UI_CTRL, pTempChar, E_OUT_OF_MEMORY, "Memory allocation failed.");
314
315         int i = 0;
316         int j = 0;
317         for (i = 0; i < indexCount; i++)
318         {
319                 for (j = 0; j < textLenth; j++)
320                 {
321                         pTempChar[j] = pTextIndexArray[(i*textLenth)+j];
322                 }
323                 pTempChar[j] = 0;
324
325                 indexText = new (std::nothrow) Tizen::Base::String(pTempChar);
326                 SysTryCatch(NID_UI_CTRL, indexText, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
327
328                 r = AddChildIndex(childOrder+i, indexText, null);
329                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to add child index.", GetErrorMessage(r));
330
331                 delete indexText;
332                 indexText = null;
333         }
334
335         delete[] pTempChar;
336         return E_SUCCESS;
337
338 CATCH:
339         delete indexText;
340         delete[] pTempChar;
341
342         return r;
343 }
344
345
346 result
347 _FastScrollIndex::RemoveChildIndex(int childOrder, bool destroy)
348 {
349         _FastScrollIndex* pIndex = GetChildIndex(childOrder);
350         SysTryReturnResult(NID_UI_CTRL, pIndex, GetLastResult(), "Failed to get the child index.");
351
352         return RemoveChildIndex(pIndex, destroy);
353 }
354
355 result
356 _FastScrollIndex::RemoveChildIndex(_FastScrollIndex* pChildIndex, bool destroy)
357 {
358         int detachedOrder = 0;
359
360         __childIndexList.IndexOf(*pChildIndex, detachedOrder);
361
362         if (destroy == true)
363         {
364                 __childIndexList.Remove(*pChildIndex, true);
365         }
366         else
367         {
368                 __childIndexList.Remove(*pChildIndex, false);
369                 pChildIndex->SetParentIndex(null);
370         }
371
372         if (__pIndexObserver)
373         {
374                 __pIndexObserver->OnChildIndexDetached(*this, detachedOrder, *pChildIndex);
375         }
376
377         return E_SUCCESS;
378 }
379
380 void
381 _FastScrollIndex::RemoveChildren(bool destroy)
382 {
383         RemoveOmissionChildren(destroy);
384
385         int childrenCount = __childIndexList.GetCount();
386         for (int i = childrenCount-1; i >= 0; i--)
387         {
388                 __childIndexList.RemoveAt(i, destroy);
389         }
390 }
391
392 result
393 _FastScrollIndex::RemoveOmissionChildren(bool destroy)
394 {
395         int childrenCount = __childOmittedIndexList.GetCount();
396
397         if (childrenCount <= 0)
398         {
399                 return E_SUCCESS;
400         }
401
402         for (int i = childrenCount-1; i >= 0; i--)
403         {
404                 _FastScrollIndex* pIndex = GetChildIndex(i, true);
405                 SysTryReturnResult(NID_UI_CTRL, pIndex, GetLastResult(), "Failed to get the child index.");
406
407                 if (pIndex->GetOmitted())
408                 {
409                         pIndex->RemoveChildren(false);
410
411                         __childOmittedIndexList.RemoveAt(i, true);
412                 }
413                 else
414                 {
415                         __childOmittedIndexList.RemoveAt(i, false);
416                 }
417         }
418         SetIndexType(FAST_SCROLL_INDEX_TYPE_NORMAL);
419
420         return E_SUCCESS;
421 }
422
423 _FastScrollIndex*
424 _FastScrollIndex::GetChildIndex(int childOrder, bool omitted) const
425 {
426         if (omitted && __childOmittedIndexList.GetCount() > 0)
427         {
428                 Object* pOmittedChildIndex = const_cast <Object*>(__childOmittedIndexList.GetAt(childOrder));
429                 SysTryReturn(NID_UI_CTRL, pOmittedChildIndex, null, GetLastResult(), "[%s] Failed to get the child index.",
430                                 GetErrorMessage(GetLastResult()));
431
432                 return dynamic_cast <_FastScrollIndex*>(pOmittedChildIndex);
433         }
434
435         Object* pChildIndex = const_cast <Object*>(__childIndexList.GetAt(childOrder));
436         SysTryReturn(NID_UI_CTRL, pChildIndex, null, GetLastResult(), "[%s] Failed to get the child index.",
437                         GetErrorMessage(GetLastResult()));
438
439         return dynamic_cast <_FastScrollIndex*>(pChildIndex);
440 }
441
442 int
443 _FastScrollIndex::GetChildOrder(const _FastScrollIndex* pChildIndex, bool omitted) const
444 {
445         int childIndex = -1;
446         if (omitted && __childOmittedIndexList.GetCount() > 0)
447         {
448                 __childOmittedIndexList.IndexOf(*pChildIndex, childIndex);
449         }
450         else
451         {
452                 __childIndexList.IndexOf(*pChildIndex, childIndex);
453         }
454         return childIndex;
455 }
456
457 int
458 _FastScrollIndex::GetChildCount(bool omitted) const
459 {
460         if (omitted)
461         {
462                 return __childOmittedIndexList.GetCount();
463         }
464
465         return __childIndexList.GetCount();
466 }
467
468 void
469 _FastScrollIndex::SetParentIndex(_FastScrollIndex* pParent)
470 {
471         __pParentIndex = pParent;
472 }
473
474 _FastScrollIndex*
475 _FastScrollIndex::GetParentIndex(void) const
476 {
477         return __pParentIndex;
478 }
479
480 int
481 _FastScrollIndex::GetIndexOrder(bool omitted) const
482 {
483         if (__pParentIndex)
484         {
485                 return __pParentIndex->GetChildOrder(this, omitted);
486         }
487         else
488         {
489                 return -1;
490         }
491 }
492
493 void
494 _FastScrollIndex::SetIndexType(_FastScrollIndexType type)
495 {
496         __indexType = type;
497 }
498
499 _FastScrollIndexType
500 _FastScrollIndex::GetIndexType(void) const
501 {
502         return __indexType;
503 }
504
505 void
506 _FastScrollIndex::SetOmitted(bool omitted)
507 {
508         __omitted = omitted;
509 }
510
511 bool
512 _FastScrollIndex::GetOmitted(void) const
513 {
514         return __omitted;
515 }
516
517 result
518 _FastScrollIndex::Construct(void)
519 {
520         return E_SUCCESS;
521 }
522
523 } } } // Tizen::Ui::Controls