fixed bug (TapGesture improvement)
[platform/framework/native/uifw.git] / src / ui / layout / FUi_LayoutTableLayout.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an ”AS IS” BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 /**
18  * @file                FUi_LayoutTableLayout.cpp
19  * @brief       This is the implementation file for TableLayout class.
20  *
21  * This file contains the implementation of TableLayout class.
22  */
23
24 #include <new>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <FBaseResult.h>
28 #include <FBaseInteger.h>
29 #include "FUi_Math.h"
30 #include "FUi_LayoutTableLayout.h"
31 #include "FUi_LayoutLayoutItemProxy.h"
32 #include "FUi_LayoutProxyList.h"
33 #include "FUi_LayoutLayoutItemInfo.h"
34
35 using namespace Tizen::Base;
36
37 namespace Tizen { namespace Ui { namespace _Layout
38 {
39
40 TableLayout::TableLayout(void)
41         : Layout()
42         , __row(0)
43         , __column(0)
44         , __maxRow(0)
45         , __maxColumn(0)
46         , __shrinkRowCount(0)
47         , __shrinkColumnCount(0)
48         , __stretchRowCount(0)
49         , __stretchColumnCount(0)
50         , __rowShrinkable(false)
51         , __columnShrinkable(false)
52         , __rowStretchable(false)
53         , __columnStretchable(false)
54         , __pRowInfo(null)
55         , __pColInfo(null)
56 {
57         TableProxyList* pTableProxyList = new (std::nothrow) TableProxyList();
58         SysTryReturnVoidResult(NID_UI, pTableProxyList, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
59         SetItemList(pTableProxyList);
60 }
61
62 TableLayout::~TableLayout(void)
63 {
64         __mergedCellList.RemoveAll(true);
65
66         delete[] __pRowInfo;
67         delete[] __pColInfo;
68 }
69
70 TableLayout*
71 TableLayout::CreateTableLayoutN(void)
72 {
73         TableLayout* pLayout = new (std::nothrow) TableLayout();
74         SysTryReturn(NID_UI, pLayout != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Table layout core allocation failure.");
75         if (GetLastResult() != E_SUCCESS)
76         {
77                 delete pLayout;
78                 return null;
79         }
80
81         return pLayout;
82 }
83
84 result
85 TableLayout::CreateTable(int row, int column, float spacing)
86 {
87         if (row < 1 || column < 1)
88         {
89                 SysTryReturn(NID_UI, false, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Negative argument : row(%d), column(%d)", row,
90                                         column);
91         }
92
93         __row = row;
94         __column = column;
95         __maxRow = row;
96         __maxColumn = column;
97
98         __pColInfo = new (std::nothrow) ColumnInfo[__column];
99         SysTryReturn(NID_UI, __pColInfo != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
100
101         memset(__pColInfo, 0, sizeof(ColumnInfo) * __column);
102
103         for (int i = 0; i < __column; i++)
104         {
105                 __pColInfo[i].widthSpacing = spacing;
106         }
107
108         __pRowInfo = new (std::nothrow) RowInfo[__row];
109         SysTryReturn(NID_UI, __pRowInfo != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
110
111         memset(__pRowInfo, 0, sizeof(RowInfo) * __row);
112
113         for (int i = 0; i < __row; i++)
114         {
115                 __pRowInfo[i].heightSpacing = spacing;
116         }
117
118         return E_SUCCESS;
119 }
120
121 result
122 TableLayout::CalculateSize()
123 {
124         if (__row < 1 || __column < 1)
125         {
126                 return E_SUCCESS;
127         }
128
129         float nextPosX = 0.0f;
130         float nextPosY = 0.0f;
131
132         __shrinkRowCount = 0;
133         __shrinkColumnCount = 0;
134         __stretchRowCount = 0;
135         __stretchColumnCount = 0;
136
137         for (int j = 0; j < __column; j++)
138         {
139                 __pColInfo[j].x = 0.0f;
140                 __pColInfo[j].width = 0.0f;
141                 __pColInfo[j].maxWidth = 0.0f;
142                 __pColInfo[j].mergedWidth = 0.0f;
143         }
144
145         ProxyListNode* pCurNode = null;
146         TableItemInfo* pItemInfo = null;
147         LayoutItemProxy* pItemProxy = null;
148
149         for (int i = 0; i < __row; i++)
150         {
151                 __pRowInfo[i].y = 0.0f;
152                 __pRowInfo[i].height = 0.0f;
153                 __pRowInfo[i].maxHeight = 0.0f;
154                 __pRowInfo[i].mergedHeight = 0.0f;
155
156                 for (int j = 0; j < __column; j++)
157                 {
158                         pCurNode = GetNode(i, j);
159                         if (pCurNode != null)
160                         {
161                                 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
162
163                                 pItemProxy = pCurNode->GetItemProxy();
164                                 if (pItemInfo == null || pItemProxy == null)
165                                 {
166                                         return E_INVALID_STATE;
167                                 }
168
169                                 if (pItemInfo->__enable)
170                                 {
171                                         pItemProxy->GetMinSize(pItemInfo->__minSize);
172                                         pItemProxy->GetMaxSize(pItemInfo->__maxSize);
173                                 }
174
175                                 LayoutRect rect = pItemProxy->GetItemBaseRect();
176
177                                 result r = pItemProxy->Measure(rect.w, rect.h);
178                                 if (r != E_SUCCESS)
179                                 {
180                                         return r;
181                                 }
182                                 pItemProxy->GetMeasuredSize(rect.w, rect.h);
183
184                                 ItemMargin margin = pItemProxy->GetItemMargin();
185                                 ItemAlign itemAlign = pItemProxy->GetItemAlignment();
186                                 if (itemAlign.HAlign == ITEM_HORIZONTAL_ALIGN_LEFT || itemAlign.HAlign == ITEM_HORIZONTAL_ALIGN_LEFT_RIGHT)
187                                 {
188                                         rect.w += margin.left;
189                                 }
190                                 if (itemAlign.HAlign == ITEM_HORIZONTAL_ALIGN_RIGHT || itemAlign.HAlign == ITEM_HORIZONTAL_ALIGN_LEFT_RIGHT)
191                                 {
192                                         rect.w += margin.right;
193                                 }
194                                 if (itemAlign.VAlign == ITEM_VERTICAL_ALIGN_TOP || itemAlign.VAlign == ITEM_VERTICAL_ALIGN_TOP_BOTTOM)
195                                 {
196                                         rect.h += margin.top;
197                                 }
198                                 if (itemAlign.VAlign == ITEM_VERTICAL_ALIGN_BOTTOM || itemAlign.VAlign == ITEM_VERTICAL_ALIGN_TOP_BOTTOM)
199                                 {
200                                         rect.h += margin.bottom;
201                                 }
202
203                                 if (!pItemInfo->__merged)
204                                 {
205                                         if (__pColInfo[j].maxWidth < rect.w && !__pRowInfo[i].rowCollapsed)
206                                         {
207                                                 __pColInfo[j].maxWidth = rect.w;
208                                         }
209
210                                         if (__pRowInfo[i].maxHeight < rect.h && !__pColInfo[j].columnCollapsed)
211                                         {
212                                                 __pRowInfo[i].maxHeight = rect.h;
213                                         }
214                                 }
215                                 else
216                                 {
217                                         if (__pColInfo[j].mergedWidth < rect.w)
218                                         {
219                                                 __pColInfo[j].mergedWidth = rect.w;
220                                         }
221                                         if (__pRowInfo[i].mergedHeight < rect.h)
222                                         {
223                                                 __pRowInfo[i].mergedHeight = rect.h;
224                                         }
225                                 }
226                         }
227                 }
228
229                 if (!__pRowInfo[i].rowCollapsed)
230                 {
231                         if (__pRowInfo[i].heightStretchable)
232                         {
233                                 __stretchRowCount++;
234                         }
235                         if (__pRowInfo[i].heightShrinkable)
236                         {
237                                 __shrinkRowCount++;
238                         }
239
240                         if (!_FloatHardCompare(__pRowInfo[i].maxHeight, 0.0f))
241                         {
242                                 __pRowInfo[i].height = __pRowInfo[i].maxHeight;
243                         }
244                 }
245         }
246
247         for (int j = 0; j < __column; j++)
248         {
249                 if (!__pColInfo[j].columnCollapsed)
250                 {
251                         if (__pColInfo[j].widthStretchable)
252                         {
253                                 __stretchColumnCount++;
254                         }
255                         if (__pColInfo[j].widthShrinkable)
256                         {
257                                 __shrinkColumnCount++;
258                         }
259
260                         if (!_FloatHardCompare(__pColInfo[j].maxWidth, 0.0f))
261                         {
262                                 __pColInfo[j].width = __pColInfo[j].maxWidth;
263                         }
264                 }
265         }
266
267         pCurNode = null;
268         pItemInfo = null;
269         pItemProxy = null;
270
271         float mergedHeight = 0.0f;
272         float mergedWidth = 0.0f;
273         for (int i = __row - 1; i >= 0; i--)
274         {
275                 if (!__pRowInfo[i].rowCollapsed)
276                 {
277                         for (int j = __column - 1; j >= 0; j--)
278                         {
279                                 if (!__pColInfo[j].columnCollapsed)
280                                 {
281                                         pCurNode = GetNode(i, j);
282                                         if (pCurNode != null)
283                                         {
284                                                 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
285                                                 if (pItemInfo == null)
286                                                 {
287                                                         return E_INVALID_STATE;
288                                                 }
289                                                 pItemProxy = pCurNode->GetItemProxy();
290                                                 if (pItemInfo->__mergeEndPoint.x != NOT_MERGED)
291                                                 {
292                                                         int startRow = i;
293                                                         int startColumn = j;
294                                                         int endRow = pItemInfo->__mergeEndPoint.x;
295                                                         int endColumn = pItemInfo->__mergeEndPoint.y;
296
297                                                         pItemProxy->GetMeasuredSize(mergedWidth, mergedHeight);
298
299                                                         float rowHeightSum = 0.0f;
300                                                         if (startRow == 0)
301                                                         {
302                                                                 rowHeightSum -= __pRowInfo[startRow].heightSpacing;
303                                                         }
304                                                         for (int k = startRow; k <= endRow; k++)
305                                                         {
306                                                                 rowHeightSum += __pRowInfo[k].height + __pRowInfo[k].heightSpacing;
307                                                         }
308                                                         if (mergedHeight > rowHeightSum)
309                                                         {
310                                                                 __pRowInfo[startRow].height += mergedHeight - rowHeightSum;
311                                                         }
312
313                                                         float colWidthSum = 0.0f;
314                                                         if (startColumn == 0)
315                                                         {
316                                                                 colWidthSum -= __pColInfo[startColumn].widthSpacing;
317                                                         }
318                                                         for (int k = startColumn; k <= endColumn; k++)
319                                                         {
320                                                                 colWidthSum += __pColInfo[k].width + __pColInfo[k].widthSpacing;
321                                                         }
322                                                         if (mergedWidth > colWidthSum)
323                                                         {
324                                                                 __pColInfo[startColumn].width += mergedWidth - colWidthSum;
325                                                         }
326                                                 }
327                                         }
328                                 }
329                         }
330                 }
331         }
332
333         LayoutRect layoutRect = GetLayoutRect();
334         nextPosY = -__pRowInfo[0].heightSpacing + layoutRect.y;
335         for (int i = 0; i < __row; i++)
336         {
337                 nextPosX = -__pColInfo[0].widthSpacing + layoutRect.x;
338                 if (!__pRowInfo[i].rowCollapsed)
339                 {
340                         for (int j = 0; j < __column; j++)
341                         {
342                                 if (!__pColInfo[j].columnCollapsed)
343                                 {
344                                         __pColInfo[j].x = nextPosX + __pColInfo[j].widthSpacing;
345                                         nextPosX = __pColInfo[j].x + __pColInfo[j].width;
346                                 }
347                         }
348                         __pRowInfo[i].y = nextPosY + __pRowInfo[i].heightSpacing;
349                         nextPosY = __pRowInfo[i].y + __pRowInfo[i].height;
350                 }
351         }
352
353         layoutRect.w = nextPosX;
354         layoutRect.h = nextPosY;
355         SetLayoutRect(layoutRect);
356
357         return E_SUCCESS;
358 }
359
360 result
361 TableLayout::CalculateShrinkCell(const LayoutRect windowRect)
362 {
363         __rowShrinkable = false;
364         __columnShrinkable = false;
365
366         LayoutItemProxy* pContainerProxy = GetContainerProxy();
367         if (pContainerProxy == null)
368         {
369                 return E_INVALID_STATE;
370         }
371
372         LayoutRect containerRect;
373         pContainerProxy->ConvertWindowToClientBounds(windowRect, containerRect);
374
375         LayoutRect layoutRect = GetLayoutRect();
376
377         float shrinkTotalWidth = layoutRect.w - containerRect.w;
378         float shrinkTotalHeight = layoutRect.h - containerRect.h;
379
380         int shrinkColumnCount = __shrinkColumnCount;
381         int shrinkRowCount = __shrinkRowCount;
382
383         int* pShrinkedColumns = null;
384         int* pShrinkedRows = null;
385
386         int lastShrinkRow = 0;
387         int lastShrinkColumn = 0;
388
389         ProxyListNode* pCurNode = null;
390         TableItemInfo* pItemInfo = null;
391
392         if (shrinkTotalWidth > 0 && __shrinkColumnCount > 0)
393         {
394                 if (pContainerProxy->GetItemWidthMatchMode() == WRAP_CONTENT)
395                 {
396                         return E_SUCCESS;
397                 }
398
399                 __columnShrinkable = true;
400
401                 pShrinkedColumns = new (std::nothrow) int[__shrinkColumnCount];
402                 SysTryReturn(NID_UI, pShrinkedColumns != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
403
404                 memset(pShrinkedColumns, 0x00, sizeof(int) * __shrinkColumnCount);
405
406                 int shrinkedColumnCount = 0;
407                 bool shrinkedItem = true;
408
409                 while (shrinkedItem && shrinkColumnCount != 0)
410                 {
411                         shrinkedItem = false;
412
413                         for (int j = 0; j < __column; j++)
414                         {
415                                 int shrinkWidth = shrinkTotalWidth / shrinkColumnCount;
416                                 float shrinkedColWidth = __pColInfo[j].width;
417
418                                 if (__pColInfo[j].widthShrinkable && !__pColInfo[j].columnCollapsed)
419                                 {
420                                         shrinkedColWidth -= shrinkWidth;
421
422                                         if (shrinkedColWidth < 0.0f)
423                                         {
424                                                 shrinkWidth += shrinkedColWidth;
425
426                                                 __pColInfo[j].width = 0.0f;
427                                                 shrinkedColWidth = 0.0f;
428                                                 __pColInfo[j].widthShrinkable = false;
429
430                                         }
431
432                                         for (int i = 0; i < __row; i++)
433                                         {
434                                                 pCurNode = GetNode(i, j);
435                                                 pItemInfo = null;
436                                                 if (pCurNode != null)
437                                                 {
438                                                         pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
439                                                 }
440                                                 if (pItemInfo != null && shrinkedColWidth < pItemInfo->__minSize.w)
441                                                 {
442                                                         shrinkWidth -= pItemInfo->__minSize.w - shrinkedColWidth;
443                                                         __pColInfo[j].width = pItemInfo->__minSize.w;
444                                                         __pColInfo[j].widthShrinkable = false;
445                                                 }
446                                         }
447
448                                         if (__pColInfo[j].widthShrinkable == false)
449                                         {
450                                                 shrinkTotalWidth -= shrinkWidth;
451                                                 layoutRect.w -= shrinkWidth;
452                                                 shrinkColumnCount--;
453
454                                                 pShrinkedColumns[shrinkedColumnCount++] = j;
455                                                 shrinkedItem = true;
456
457                                                 break;
458                                         }
459                                 }
460                         }
461                 }
462
463                 float nextPosX = -__pColInfo[0].widthSpacing + layoutRect.x;
464
465                 for (int j = 0; j < __column; j++)
466                 {
467                         __pColInfo[j].x = nextPosX + __pColInfo[j].widthSpacing;
468
469                         if (!__pColInfo[j].columnCollapsed)
470                         {
471                                 if (shrinkColumnCount != 0)
472                                 {
473                                         int shrinkWidth = shrinkTotalWidth / shrinkColumnCount;
474
475                                         if (__pColInfo[j].widthShrinkable)
476                                         {
477                                                 __pColInfo[j].width -= shrinkWidth;
478                                                 lastShrinkColumn = j;
479                                                 layoutRect.w -= shrinkWidth;
480                                         }
481                                 }
482                                 nextPosX = __pColInfo[j].width + __pColInfo[j].x;
483                         }
484                 }
485
486                 nextPosX = -__pColInfo[0].widthSpacing + layoutRect.x;
487                 float shrinkWidth = 0.0f;
488                 if (!_FloatCompare(shrinkTotalWidth, 0.0f) && shrinkColumnCount != 0)
489                 {
490                         shrinkWidth = (int)shrinkTotalWidth % shrinkColumnCount;
491                 }
492                 bool shrinkableColumn = true;
493
494                 while (shrinkWidth > 0 && shrinkableColumn)
495                 {
496                         shrinkableColumn = false;
497                         for (int j = 0; j < __column; j++)
498                         {
499                                 __pColInfo[j].x = nextPosX + __pColInfo[j].widthSpacing;
500
501                                 if (!__pColInfo[j].columnCollapsed)
502                                 {
503                                         if (shrinkColumnCount != 0)
504                                         {
505                                                 if (__pColInfo[j].widthShrinkable)
506                                                 {
507                                                         for (int i = 0; i < __row; i++)
508                                                         {
509                                                                 pCurNode = GetNode(i, j);
510                                                                 pItemInfo = null;
511                                                                 if (pCurNode != null)
512                                                                 {
513                                                                         pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
514                                                                 }
515                                                                 if ((pItemInfo != null && ((__pColInfo[j].width - 1.0f) < pItemInfo->__minSize.w)) || (__pColInfo[j].width - 1.0f) < 0.0f)
516                                                                 {
517                                                                         pShrinkedColumns[shrinkedColumnCount++] = j;
518                                                                         __pColInfo[j].widthShrinkable = false;
519                                                                         shrinkColumnCount--;
520                                                                         break;
521                                                                 }
522                                                         }
523
524                                                         if (__pColInfo[j].widthShrinkable && shrinkWidth > 0.0f)
525                                                         {
526                                                                 if (shrinkWidth < 1.0f)
527                                                                 {
528                                                                         __pColInfo[j].width -= shrinkWidth;
529                                                                         layoutRect.w -= shrinkWidth;
530                                                                         shrinkWidth = 0.0f;
531                                                                         shrinkableColumn = true;
532                                                                 }
533                                                                 else
534                                                                 {
535                                                                         __pColInfo[j].width--;
536                                                                         layoutRect.w--;
537                                                                         shrinkWidth--;
538                                                                         shrinkableColumn = true;
539                                                                 }
540                                                         }
541                                                 }
542                                         }
543                                         nextPosX = __pColInfo[j].width + __pColInfo[j].x;
544                                 }
545                         }
546                 }
547
548                 for (int j = 0; j < shrinkedColumnCount; j++)
549                 {
550                         __pColInfo[pShrinkedColumns[j]].widthShrinkable = true;
551                 }
552
553                 delete[] pShrinkedColumns;
554         }
555
556         if (shrinkTotalHeight > 0.0f && __shrinkRowCount > 0)
557         {
558                 if (pContainerProxy->GetItemHeightMatchMode() == WRAP_CONTENT)
559                 {
560                         return E_SUCCESS;
561                 }
562
563                 __rowShrinkable = true;
564
565                 pShrinkedRows = new (std::nothrow) int[__shrinkRowCount];
566                 SysTryReturn(NID_UI, pShrinkedRows != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
567
568                 memset(pShrinkedRows, 0x00, sizeof(int) * __shrinkRowCount);
569                 int shrinkedRowCount = 0;
570                 bool shrinkedItem = true;
571
572                 while (shrinkedItem && shrinkRowCount != 0)
573                 {
574                         shrinkedItem = false;
575
576                         for (int i = 0; i < __row; i++)
577                         {
578                                 int shrinkHeight = shrinkTotalHeight / shrinkRowCount;
579                                 float shrinkedRowHeight = __pRowInfo[i].height;
580
581                                 if (__pRowInfo[i].heightShrinkable && !__pRowInfo[i].rowCollapsed)
582                                 {
583                                         shrinkedRowHeight -= shrinkHeight;
584
585                                         if (shrinkedRowHeight < 0.0f)
586                                         {
587                                                 shrinkHeight += shrinkedRowHeight;
588
589                                                 __pRowInfo[i].height = 0.0f;
590                                                 shrinkedRowHeight = 0.0f;
591                                                 __pRowInfo[i].heightShrinkable = false;
592
593                                         }
594
595                                         for (int j = 0; j < __column; j++)
596                                         {
597                                                 pCurNode = GetNode(i, j);
598                                                 pItemInfo = null;
599                                                 if (pCurNode != null)
600                                                 {
601                                                         pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
602                                                 }
603                                                 if (pItemInfo != null && shrinkedRowHeight < pItemInfo->__minSize.h)
604                                                 {
605                                                         shrinkHeight -= pItemInfo->__minSize.h - shrinkedRowHeight;
606                                                         __pRowInfo[i].height = pItemInfo->__minSize.h;
607                                                         __pRowInfo[i].heightShrinkable = false;
608                                                 }
609                                         }
610
611                                         if (__pRowInfo[i].heightShrinkable == false)
612                                         {
613                                                 shrinkTotalHeight -= shrinkHeight;
614                                                 layoutRect.h -= shrinkHeight;
615                                                 shrinkRowCount--;
616
617                                                 pShrinkedRows[shrinkedRowCount++] = i;
618                                                 shrinkedItem = true;
619
620                                                 break;
621                                         }
622                                 }
623                         }
624                 }
625
626                 float nextPosY = -__pRowInfo[0].heightSpacing + layoutRect.y;
627
628                 for (int i = 0; i < __row; i++)
629                 {
630                         if (!__pRowInfo[i].rowCollapsed)
631                         {
632                                 if (shrinkRowCount != 0)
633                                 {
634                                         int shrinkHeight = shrinkTotalHeight / shrinkRowCount;
635
636                                         if (__pRowInfo[i].heightShrinkable)
637                                         {
638                                                 __pRowInfo[i].height -= shrinkHeight;
639                                                 lastShrinkRow = i;
640                                                 layoutRect.h -= shrinkHeight;
641                                         }
642                                 }
643                                 __pRowInfo[i].y = nextPosY + __pRowInfo[i].heightSpacing;
644                                 nextPosY = __pRowInfo[i].height + __pRowInfo[i].y;
645                         }
646                 }
647
648                 nextPosY = -__pRowInfo[0].heightSpacing + layoutRect.y;
649                 float shrinkHeight = 0.0f;
650                 if (!_FloatHardCompare(shrinkTotalHeight, 0.0f) && shrinkRowCount != 0)
651                 {
652                         shrinkHeight = (int)shrinkTotalHeight % shrinkRowCount;
653                 }
654                 bool shrinkableRow = true;
655
656                 while (shrinkHeight > 0 && shrinkableRow)
657                 {
658                         shrinkableRow = false;
659                         for (int i = 0; i < __row; i++)
660                         {
661                                 if (!__pRowInfo[i].rowCollapsed)
662                                 {
663                                         if (shrinkRowCount != 0)
664                                         {
665                                                 if (__pRowInfo[i].heightShrinkable)
666                                                 {
667                                                         for (int j = 0; j < __column; j++)
668                                                         {
669                                                                 pCurNode = GetNode(i, j);
670                                                                 pItemInfo = null;
671                                                                 if (pCurNode != null)
672                                                                 {
673                                                                         pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
674                                                                 }
675                                                                 if ((pItemInfo != null && ((__pRowInfo[i].height - 1.0f) < pItemInfo->__minSize.h)) || (__pRowInfo[i].height - 1.0f) < 0.0f)
676                                                                 {
677                                                                         pShrinkedRows[shrinkedRowCount++] = i;
678                                                                         __pRowInfo[i].heightShrinkable = false;
679                                                                         shrinkRowCount--;
680                                                                         break;
681                                                                 }
682                                                         }
683
684                                                         if (__pRowInfo[i].heightShrinkable && shrinkHeight > 0)
685                                                         {
686                                                                 if (shrinkHeight < 1.0f)
687                                                                 {
688                                                                         __pRowInfo[i].height -= shrinkHeight;
689                                                                         layoutRect.h -= shrinkHeight;
690                                                                         shrinkHeight = 0.0f;
691                                                                         shrinkableRow = true;
692                                                                 }
693                                                                 else
694                                                                 {
695                                                                         __pRowInfo[i].height--;
696                                                                         layoutRect.h--;
697                                                                         shrinkHeight--;
698                                                                         shrinkableRow = true;
699                                                                 }
700                                                         }
701                                                 }
702                                         }
703                                         __pRowInfo[i].y = nextPosY + __pRowInfo[i].heightSpacing;
704                                         nextPosY = __pRowInfo[i].height + __pRowInfo[i].y;
705                                 }
706                         }
707                 }
708
709                 for (int i = 0; i < shrinkedRowCount; i++)
710                 {
711                         __pRowInfo[pShrinkedRows[i]].heightShrinkable = true;
712                 }
713
714                 delete[] pShrinkedRows;
715         }
716         SetLayoutRect(layoutRect);
717         return E_SUCCESS;
718 }
719
720 result
721 TableLayout::CalculateStretchCell(const LayoutRect windowRect)
722 {
723         __rowStretchable = false;
724         __columnStretchable = false;
725
726         LayoutItemProxy* pContainerProxy = GetContainerProxy();
727         if (pContainerProxy == null)
728         {
729                 return E_INVALID_STATE;
730         }
731
732         LayoutRect containerRect;
733         pContainerProxy->ConvertWindowToClientBounds(windowRect, containerRect);
734
735         LayoutRect layoutRect = GetLayoutRect();
736
737         float stretchTotalWidth = containerRect.w - layoutRect.w;
738         float stretchTotalHeight = containerRect.h - layoutRect.h;
739
740         int stretchColumnCount = __stretchColumnCount;
741         int stretchRowCount = __stretchRowCount;
742
743         int lastStretchRow = 0;
744         int lastStretchColumn = 0;
745
746         int* pStretchedColumns = null;
747         int* pStretchedRows = null;
748
749         ProxyListNode* pCurNode = null;
750         TableItemInfo* pItemInfo = null;
751
752         if (stretchTotalWidth > 0 && __stretchColumnCount > 0)
753         {
754                 if (pContainerProxy->GetItemWidthMatchMode() == WRAP_CONTENT)
755                 {
756                         return E_SUCCESS;
757                 }
758
759                 __columnStretchable = true;
760
761                 pStretchedColumns = new (std::nothrow) int[__stretchColumnCount];
762                 SysTryReturn(NID_UI, pStretchedColumns != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
763
764                 memset(pStretchedColumns, 0x00, sizeof(int) * __stretchColumnCount);
765                 int stretchedColumnCount = 0;
766                 bool stretchedItem = true;
767
768                 while (stretchedItem && stretchColumnCount != 0)
769                 {
770                         stretchedItem = false;
771                         int stretchWidth = stretchTotalWidth / stretchColumnCount;
772
773                         for (int j = 0; j < __column; j++)
774                         {
775                                 if (__pColInfo[j].widthStretchable && !__pColInfo[j].columnCollapsed)
776                                 {
777                                         float maxWidth = 0.0f;
778                                         float stretchedColWidth = __pColInfo[j].width;
779                                         stretchedColWidth += stretchWidth;
780                                         for (int i = 0; i < __row; i++)
781                                         {
782                                                 pCurNode = GetNode(i, j);
783                                                 pItemInfo = null;
784                                                 if (pCurNode != null)
785                                                 {
786                                                         pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
787                                                 }
788                                                 if (pItemInfo != null && maxWidth < pItemInfo->__maxSize.w)
789                                                 {
790                                                         maxWidth = pItemInfo->__maxSize.w;
791                                                 }
792                                         }
793
794                                         if (maxWidth < stretchedColWidth)
795                                         {
796                                                 stretchWidth -= stretchedColWidth - maxWidth;
797                                                 __pColInfo[j].width += stretchWidth;
798                                                 stretchTotalWidth -= stretchWidth;
799                                                 layoutRect.w += stretchWidth;
800                                                 stretchColumnCount--;
801                                                 __pColInfo[j].widthStretchable = false;
802
803                                                 pStretchedColumns[stretchedColumnCount++] = j;
804                                                 stretchedItem = true;
805                                                 break;
806                                         }
807                                 }
808                         }
809                 }
810
811                 int nextPosX = -__pColInfo[0].widthSpacing + layoutRect.x;
812
813                 for (int j = 0; j < __column; j++)
814                 {
815                         if (!__pColInfo[j].columnCollapsed)
816                         {
817                                 if (__pColInfo[j].widthStretchable && stretchColumnCount != 0)
818                                 {
819                                         int stretchWidth = stretchTotalWidth / stretchColumnCount;
820                                         __pColInfo[j].width += stretchWidth;
821                                         layoutRect.w += stretchWidth;
822                                         lastStretchColumn = j;
823                                 }
824                                 __pColInfo[j].x = nextPosX + __pColInfo[j].widthSpacing;
825                                 nextPosX = __pColInfo[j].x + __pColInfo[j].width;
826                         }
827                 }
828                 nextPosX = -__pColInfo[0].widthSpacing + layoutRect.x;
829                 float stretchWidth = 0.0f;
830                 if (!_FloatHardCompare(stretchTotalWidth, 0.0f) && stretchColumnCount)
831                 {
832                         stretchWidth = (int)stretchTotalWidth % stretchColumnCount;
833                 }
834                 bool stretchableColumn = true;
835
836                 while (stretchWidth > 0 && stretchableColumn)
837                 {
838                         stretchableColumn = false;
839                         for (int j = 0; j < __column; j++)
840                         {
841                                 if (!__pColInfo[j].columnCollapsed)
842                                 {
843                                         if (stretchColumnCount != 0)
844                                         {
845                                                 if (__pColInfo[j].widthStretchable)
846                                                 {
847                                                         for (int i = 0; i < __row; i++)
848                                                         {
849                                                                 pCurNode = GetNode(i, j);
850                                                                 pItemInfo = null;
851                                                                 if (pCurNode != null)
852                                                                 {
853                                                                         pItemInfo = (TableItemInfo*) pCurNode->GetItemInfo();
854                                                                 }
855                                                                 if (pItemInfo != null && ((__pColInfo[j].width + 1) > pItemInfo->__maxSize.w)  && !pItemInfo->__merged)
856                                                                 {
857                                                                         pStretchedColumns[stretchedColumnCount++] = j;
858                                                                         __pColInfo[j].widthStretchable = false;
859                                                                         stretchColumnCount--;
860                                                                         break;
861                                                                 }
862                                                         }
863
864                                                         if (__pColInfo[j].widthStretchable && stretchWidth > 0)
865                                                         {
866                                                                 if (stretchWidth < 1.0f)
867                                                                 {
868                                                                         __pColInfo[j].width += stretchWidth;
869                                                                         layoutRect.w += stretchWidth;
870                                                                         stretchWidth = 0.0f;
871                                                                         stretchableColumn = true;
872                                                                 }
873                                                                 else
874                                                                 {
875                                                                         __pColInfo[j].width++;
876                                                                         layoutRect.w++;
877                                                                         stretchWidth--;
878                                                                         stretchableColumn = true;
879                                                                 }
880                                                         }
881                                                 }
882                                         }
883                                         __pColInfo[j].x = nextPosX + __pColInfo[j].widthSpacing;
884                                         nextPosX = __pColInfo[j].x + __pColInfo[j].width;
885                                 }
886                         }
887                 }
888
889                 for (int j = 0; j < stretchedColumnCount; j++)
890                 {
891                         __pColInfo[pStretchedColumns[j]].widthStretchable = true;
892                 }
893
894                 delete[] pStretchedColumns;
895         }
896
897         if (stretchTotalHeight > 0 && __stretchRowCount > 0)
898         {
899                 if (pContainerProxy->GetItemHeightMatchMode() == WRAP_CONTENT)
900                 {
901                         return E_SUCCESS;
902                 }
903
904                 __rowStretchable = true;
905
906                 pStretchedRows = new (std::nothrow) int[__stretchRowCount];
907                 SysTryReturn(NID_UI, pStretchedRows != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
908
909                 memset(pStretchedRows, 0x00, sizeof(int) * __stretchRowCount);
910                 int stretchedRowCount = 0;
911                 bool stretchedItem = true;
912
913                 while (stretchedItem && stretchRowCount != 0)
914                 {
915                         stretchedItem = false;
916                         int stretchHeight = stretchTotalHeight / stretchRowCount;
917
918                         for (int i = 0; i < __row; i++)
919                         {
920                                 if (__pRowInfo[i].heightStretchable && !__pRowInfo[i].rowCollapsed)
921                                 {
922                                         float maxHeight = 0.0f;
923                                         float stretchedRowHeight = __pRowInfo[i].height;
924                                         stretchedRowHeight += stretchHeight;
925
926                                         for (int j = 0; j < __column; j++)
927                                         {
928                                                 pCurNode = GetNode(i, j);
929                                                 pItemInfo = null;
930                                                 if (pCurNode != null)
931                                                 {
932                                                         pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
933                                                 }
934                                                 if (pItemInfo != null && maxHeight < pItemInfo->__maxSize.h)
935                                                 {
936                                                         maxHeight = pItemInfo->__maxSize.h;
937                                                 }
938                                         }
939
940                                         if (maxHeight < stretchedRowHeight)
941                                         {
942                                                 stretchHeight -= stretchedRowHeight - maxHeight;
943                                                 __pRowInfo[i].height += stretchHeight;
944                                                 stretchTotalHeight -= stretchHeight;
945                                                 layoutRect.h += stretchHeight;
946                                                 stretchRowCount--;
947                                                 __pRowInfo[i].heightStretchable = false;
948
949                                                 pStretchedRows[stretchedRowCount++] = i;
950                                                 stretchedItem = true;
951                                                 break;
952                                         }
953                                 }
954                         }
955                 }
956
957                 float nextPosY = -__pRowInfo[0].heightSpacing + layoutRect.y;
958                 for (int i = 0; i < __row; i++)
959                 {
960                         if (!__pRowInfo[i].rowCollapsed)
961                         {
962                                 if (__pRowInfo[i].heightStretchable && stretchRowCount != 0)
963                                 {
964                                         int stretchHeight = stretchTotalHeight / stretchRowCount;
965                                         __pRowInfo[i].height += stretchHeight;
966                                         layoutRect.h += stretchHeight;
967                                         lastStretchRow = i;
968                                 }
969                                 __pRowInfo[i].y = nextPosY + __pRowInfo[i].heightSpacing;
970                                 nextPosY = __pRowInfo[i].y + __pRowInfo[i].height;
971                         }
972                 }
973
974                 nextPosY = -__pRowInfo[0].heightSpacing + layoutRect.y;
975                 float stretchHeight = 0.0f;
976                 if (!_FloatHardCompare(stretchTotalHeight, 0.0f) && stretchRowCount != 0)
977                 {
978                         stretchHeight = (int)stretchTotalHeight % stretchRowCount;
979                 }
980                 bool stretchableRow = true;
981
982                 while (stretchHeight > 0 && stretchableRow)
983                 {
984                         stretchableRow = false;
985                         for (int i = 0; i < __row; i++)
986                         {
987                                 if (!__pRowInfo[i].rowCollapsed)
988                                 {
989                                         if (stretchRowCount != 0)
990                                         {
991                                                 if (__pRowInfo[i].heightStretchable)
992                                                 {
993                                                         for (int j = 0; j < __column; j++)
994                                                         {
995                                                                 pCurNode = GetNode(i, j);
996                                                                 pItemInfo = null;
997                                                                 if (pCurNode != null)
998                                                                 {
999                                                                         pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1000                                                                 }
1001                                                                 if (pItemInfo != null && ((__pRowInfo[i].height + 1) > pItemInfo->__maxSize.h)  && !pItemInfo->__merged)
1002                                                                 {
1003                                                                         pStretchedRows[stretchedRowCount++] = i;
1004                                                                         __pRowInfo[i].heightStretchable = false;
1005                                                                         stretchRowCount--;
1006                                                                         break;
1007                                                                 }
1008                                                         }
1009
1010                                                         if (__pRowInfo[i].heightStretchable && stretchHeight > 0.0f)
1011                                                         {
1012                                                                 if (stretchHeight < 1.0f)
1013                                                                 {
1014                                                                         __pRowInfo[i].height += stretchHeight;
1015                                                                         layoutRect.h += stretchHeight;
1016                                                                         stretchHeight = 0.0f;
1017                                                                         stretchableRow = true;
1018                                                                 }
1019                                                                 else
1020                                                                 {
1021                                                                         __pRowInfo[i].height++;
1022                                                                         layoutRect.h++;
1023                                                                         stretchHeight--;
1024                                                                         stretchableRow = true;
1025                                                                 }
1026                                                         }
1027                                                 }
1028                                         }
1029                                         __pRowInfo[i].y = nextPosY + __pRowInfo[i].heightSpacing;
1030                                         nextPosY = __pRowInfo[i].y + __pRowInfo[i].height;
1031                                 }
1032                         }
1033                 }
1034
1035                 for (int i = 0; i < stretchedRowCount; i++)
1036                 {
1037                         __pRowInfo[pStretchedRows[i]].heightStretchable = true;
1038                 }
1039
1040                 delete[] pStretchedRows;
1041         }
1042         SetLayoutRect(layoutRect);
1043         return E_SUCCESS;
1044 }
1045
1046 result
1047 TableLayout::Merge(int startRow, int startCol, int endRow, int endCol)
1048 {
1049         if (startRow < 0 || startRow >= __row || startCol < 0 || startCol >= __column
1050                 || endRow < 0 || endRow >= __row || endCol < 0 || endCol >= __column
1051                 || startRow > endRow || startCol > endCol)
1052         {
1053                 return E_INVALID_ARG;
1054         }
1055
1056         int realEndRow = endRow;
1057         int realEndColumn = endCol;
1058
1059         ProxyListNode* pCurNode = null;
1060         TableItemInfo* pItemInfo = null;
1061         for (int i = startRow; i <= realEndRow; i++)
1062         {
1063                 if (__pRowInfo[i].rowCollapsed)
1064                 {
1065                         realEndRow++;
1066                 }
1067
1068                 for (int j = startCol; j <= realEndColumn; j++)
1069                 {
1070                         int k = 0;
1071                         int mergedCellIndex = MakeCellID(i, j);
1072
1073                         for (k = 0; k < __mergedCellList.GetCount(); k++)
1074                         {
1075                                 Integer* cellID = static_cast <Integer*>(__mergedCellList.GetAt(k));
1076                                 if (cellID->ToInt() == mergedCellIndex)
1077                                 {
1078                                         return E_SYSTEM;
1079                                 }
1080                         }
1081
1082                         if (i != startRow || j != startCol)
1083                         {
1084                                 __mergedCellList.Add(*(new Integer(mergedCellIndex)));
1085                         }
1086
1087                         pCurNode = GetNode(i, j);
1088                         pItemInfo = null;
1089                         if (pCurNode != null)
1090                         {
1091                                 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1092                         }
1093                         if (pItemInfo == null)
1094                         {
1095                                 continue;
1096                         }
1097                         if (pItemInfo->__merged)
1098                         {
1099                                 return E_SYSTEM;
1100                         }
1101                         if (__pColInfo[j].columnCollapsed)
1102                         {
1103                                 realEndColumn++;
1104                         }
1105
1106                         if (i == startRow && j == startCol)
1107                         {
1108                                 pItemInfo->__merged = true;
1109                                 continue;
1110                         }
1111
1112                         pItemInfo->__enable = false;
1113                         pItemInfo->__merged = true;
1114                         if (pCurNode->GetItemProxy() != null)
1115                         {
1116                                 pCurNode->GetItemProxy()->Visible(false);
1117                         }
1118                 }
1119         }
1120
1121         pCurNode = GetNode(startRow, startCol);
1122         if (pCurNode != null)
1123         {
1124                 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1125                 if (pItemInfo == null)
1126                 {
1127                         return E_INVALID_STATE;
1128                 }
1129                 pItemInfo->__mergeEndPoint.x = realEndRow;
1130                 pItemInfo->__mergeEndPoint.y = realEndColumn;
1131         }
1132
1133         SetUpdateState(true);
1134         return E_SUCCESS;
1135 }
1136
1137 result
1138 TableLayout::OnLayout(float width, float height, bool updateLayouting)
1139 {
1140         LayoutRect layoutRect = GetLayoutRect();
1141         LayoutRect windowRect = {layoutRect.x, layoutRect.y, width, height};
1142
1143         result r = CalculateSize();
1144         if (r != E_SUCCESS)
1145         {
1146                 return r;
1147         }
1148
1149         r = CalculateShrinkCell(windowRect);
1150         if (r != E_SUCCESS)
1151         {
1152                 return r;
1153         }
1154
1155         r = CalculateStretchCell(windowRect);
1156         if (r != E_SUCCESS)
1157         {
1158                 return r;
1159         }
1160
1161         r = AdjustTableLayout(windowRect, updateLayouting);
1162         if (r != E_SUCCESS)
1163         {
1164                 return r;
1165         }
1166
1167         return E_SUCCESS;
1168 }
1169
1170 result
1171 TableLayout::AdjustTableLayout(const LayoutRect windowRect, bool updateLayouting)
1172 {
1173         LayoutItemProxy* pContainerProxy = GetContainerProxy();
1174         if (pContainerProxy == null)
1175         {
1176                 return E_INVALID_STATE;
1177         }
1178
1179         result r = E_SUCCESS;
1180         LayoutSize size = {0.0f, 0.0f};
1181         ProxyListNode* pCurNode = null;
1182         TableItemInfo* pItemInfo = null;
1183         LayoutItemProxy* pItemProxy = null;
1184         for (int i = 0; i < __row; i++)
1185         {
1186                 for (int j = 0; j < __column; j++)
1187                 {
1188                         pCurNode = GetNode(i, j);
1189                         pItemInfo = null;
1190                         if (pCurNode != null)
1191                         {
1192                                 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1193                                 pItemProxy = pCurNode->GetItemProxy();
1194                         }
1195                         if (pItemInfo != null && pItemInfo->__enable)
1196                         {
1197                                 size.w = __pColInfo[j].width;
1198                                 size.h = __pRowInfo[i].height;
1199                                 if (pItemInfo->__mergeEndPoint.x != NOT_MERGED || pItemInfo->__mergeEndPoint.y != NOT_MERGED)
1200                                 {
1201                                         result r = CalculateMergeCell(i, j, size);
1202                                         if (r != E_SUCCESS)
1203                                         {
1204                                                 SysLog(NID_UI, "CalculateMergeCell() is Failed.");
1205                                         }
1206                                 }
1207                                 if (pItemProxy != null)
1208                                 {
1209                                         LayoutRect rect = pItemProxy->GetItemBaseRect();
1210                                         rect.x = __pColInfo[j].x;
1211                                         rect.y = __pRowInfo[i].y;
1212
1213                                         LayoutRect cellRect;
1214                                         cellRect.x = __pColInfo[j].x;
1215                                         cellRect.y = __pRowInfo[i].y;
1216                                         cellRect.w = size.w;
1217                                         cellRect.h = size.h;
1218
1219                                         r = pItemProxy->Measure(rect.w, rect.h);
1220                                         if (r != E_SUCCESS)
1221                                         {
1222                                                 return r;
1223                                         }
1224                                         pItemProxy->GetMeasuredSize(rect.w, rect.h);
1225
1226                                         if ((__pRowInfo[i].heightShrinkable && __rowShrinkable) ||
1227                                                 (__pRowInfo[i].heightStretchable && __rowStretchable) ||
1228                                                 pItemInfo->__fillHeight)
1229                                         {
1230                                                 float height = 0.0f;
1231                                                 r = pItemProxy->Measure(rect.w, cellRect.h);
1232                                                 if (r != E_SUCCESS)
1233                                                 {
1234                                                         return r;
1235                                                 }
1236                                                 pItemProxy->GetMeasuredSize(rect.w, height);
1237
1238                                                 if ((__pRowInfo[i].heightShrinkable && __rowShrinkable) && rect.h > height)
1239                                                 {
1240                                                         rect.h = height;
1241                                                 }
1242                                                 else if ((__pRowInfo[i].heightStretchable && __rowStretchable) && rect.h < height)
1243                                                 {
1244                                                         rect.h = height;
1245                                                 }
1246                                                 else if (pItemInfo->__fillHeight)
1247                                                 {
1248                                                         rect.h = height;
1249                                                 }
1250                                         }
1251
1252                                         if ((__pColInfo[j].widthShrinkable && __columnShrinkable) ||
1253                                                 (__pColInfo[j].widthStretchable && __columnStretchable) ||
1254                                                 pItemInfo->__fillWidth)
1255                                         {
1256                                                 float width = 0.0f;
1257                                                 r = pItemProxy->Measure(cellRect.w, rect.h);
1258                                                 if (r != E_SUCCESS)
1259                                                 {
1260                                                         return r;
1261                                                 }
1262                                                 pItemProxy->GetMeasuredSize(width, rect.h);
1263
1264                                                 if ((__pColInfo[j].widthShrinkable && __columnShrinkable) && rect.w > width)
1265                                                 {
1266                                                         rect.w = width;
1267                                                 }
1268                                                 else if ((__pColInfo[j].widthStretchable && __columnStretchable) && rect.w < width)
1269                                                 {
1270                                                         rect.w = width;
1271                                                 }
1272                                                 else if (pItemInfo->__fillWidth)
1273                                                 {
1274                                                         rect.w = width;
1275                                                 }
1276                                         }
1277
1278                                         ItemAlign align = pItemProxy->GetItemAlignment();
1279                                         rect = CalculateAlign(*pItemProxy, cellRect, rect, align.HAlign, align.VAlign);
1280
1281                                         r = pItemProxy->Measure(rect.w, rect.h);
1282                                         if (r != E_SUCCESS)
1283                                         {
1284                                                 return r;
1285                                         }
1286                                         pItemProxy->GetMeasuredSize(rect.w, rect.h);
1287                                         pItemProxy->SetItemWindowRect(rect);
1288                                 }
1289                         }
1290                 }
1291         }
1292
1293         LayoutMatchMode widthMode = pContainerProxy->GetItemWidthMatchMode();
1294         LayoutMatchMode heightMode = pContainerProxy->GetItemHeightMatchMode();
1295         LayoutRect containerRect;
1296         pContainerProxy->ConvertWindowToClientBounds(windowRect, containerRect);
1297
1298         containerRect.x = windowRect.x;
1299         containerRect.y = windowRect.y;
1300
1301         float correctionWidth = windowRect.w - containerRect.w;
1302         float correctionHeight = windowRect.h - containerRect.h;
1303
1304         LayoutRect layoutRect = GetLayoutRect();
1305         if (widthMode == WRAP_CONTENT)
1306         {
1307                 containerRect.w = layoutRect.w + correctionWidth;
1308         }
1309         else
1310         {
1311                 containerRect.w += correctionWidth;
1312         }
1313
1314         if (heightMode == WRAP_CONTENT)
1315         {
1316                 containerRect.h = layoutRect.h + correctionHeight;
1317         }
1318         else
1319         {
1320                 containerRect.h += correctionHeight;
1321         }
1322
1323         SetLayoutRect(containerRect);
1324
1325         LayoutRect clientRect;
1326         pContainerProxy->GetItemWindowRect(clientRect);
1327         containerRect.x = clientRect.x;
1328         containerRect.y = clientRect.y;
1329         if (updateLayouting)
1330         {
1331                 pContainerProxy->SetItemWindowRect(containerRect);
1332         }
1333         return E_SUCCESS;
1334 }
1335
1336 result
1337 TableLayout::AddItem(LayoutItem& item)
1338 {
1339         ProxyListNode* pCurNode = null;
1340
1341         int cellIndex = INVALID_CELL_ID;
1342         for (int i = 0; i < __row; i++)
1343         {
1344                 for (int j = 0; j < __column; j++)
1345                 {
1346                         pCurNode = GetNode(i, j);
1347                         if (pCurNode == null)
1348                         {
1349                                 if (!__pRowInfo[i].rowCollapsed && !__pColInfo[j].columnCollapsed)
1350                                 {
1351                                         cellIndex = MakeCellID(i, j);
1352                                         for (int k = 0; k < __mergedCellList.GetCount(); k++)
1353                                         {
1354                                                 Integer* cellID = static_cast <Integer*>(__mergedCellList.GetAt(k));
1355                                                 if (cellID->ToInt() == cellIndex)
1356                                                 {
1357                                                         return AddItem(item, i, j, true);
1358                                                 }
1359                                         }
1360
1361                                         return AddItem(item, i, j);
1362                                 }
1363                         }
1364                 }
1365         }
1366
1367         return E_SYSTEM;
1368 }
1369
1370 result
1371 TableLayout::AddItem(LayoutItem& item, int row, int column, bool mergedState)
1372 {
1373         ProxyList* pProxyList = GetProxyList();
1374         SysAssertf(pProxyList != null, "ProxyList is invalid");
1375
1376         if (row < 0 || row >= __row || column < 0 || column >= __column)
1377         {
1378                 return E_INVALID_ARG;
1379         }
1380         ProxyListNode* pGetNode = GetNode(row, column);
1381         if (pGetNode != null)
1382         {
1383                 return E_INVALID_STATE;
1384         }
1385
1386         int cellIndex = MakeCellID(row, column);
1387
1388         if (!mergedState)
1389         {
1390                 for (int k = 0; k < __mergedCellList.GetCount(); k++)
1391                 {
1392                         Integer* cellID = static_cast <Integer*>(__mergedCellList.GetAt(k));
1393                         if (cellID->ToInt() == cellIndex)
1394                         {
1395                                 return E_SYSTEM;
1396                         }
1397                 }
1398         }
1399
1400         result r = Layout::AddItem(item);
1401         if (r != E_SUCCESS)
1402         {
1403                 return r;
1404         }
1405
1406         ProxyListNode* pAddNode = pProxyList->GetNode(item);
1407         if (pAddNode == null)
1408         {
1409                 return E_INVALID_STATE;
1410         }
1411         TableItemInfo* pAddItemInfo = static_cast <TableItemInfo*>(pAddNode->GetItemInfo());
1412         if (pAddItemInfo == null)
1413         {
1414                 return E_INVALID_STATE;
1415         }
1416
1417         cellIndex = MakeCellID(row, column);
1418         pAddItemInfo->__id = cellIndex;
1419
1420         if (mergedState)
1421         {
1422                 pAddItemInfo->__enable = false;
1423                 pAddItemInfo->__merged = true;
1424
1425                 if (pAddNode->GetItemProxy() != null)
1426                 {
1427                         pAddNode->GetItemProxy()->Visible(false);
1428                 }
1429         }
1430
1431         return E_SUCCESS;
1432 }
1433
1434 LayoutItem*
1435 TableLayout::GetItem(int row, int column) const
1436 {
1437         if (row < 0 || row >= __row)
1438         {
1439                 return null;
1440         }
1441
1442         if (column < 0 || column >= __column)
1443         {
1444                 return null;
1445         }
1446
1447         ProxyListNode* pCurNode = GetNode(row, column);
1448         if (pCurNode != null && pCurNode->GetItemProxy() != null)
1449         {
1450                 return pCurNode->GetItemProxy()->GetItem();
1451         }
1452         else
1453         {
1454                 return null;
1455         }
1456 }
1457
1458 result
1459 TableLayout::SetItemPosition(const LayoutItem& item, int row, int column)
1460 {
1461         SysTryReturn(NID_UI, row >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Negative input argument : row(%d)", row);
1462         SysTryReturn(NID_UI, row < __row, E_INVALID_ARG, E_INVALID_ARG,
1463                                 "[E_INVALID_ARG] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
1464         SysTryReturn(NID_UI, column >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Negative input argument : column(%d)", column);
1465         SysTryReturn(NID_UI, column < __column, E_INVALID_ARG, E_INVALID_ARG,
1466                                 "[E_INVALID_ARG] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
1467
1468         ProxyList* pProxyList = GetProxyList();
1469         SysAssertf(pProxyList != null, "ProxyList is invalid");
1470
1471         ProxyListNode* pTargetNode = GetNode(row, column);
1472         ProxyListNode* pCurNode = pProxyList->GetNode(item);
1473         SysTryReturn(NID_UI, (pCurNode != null), E_INVALID_ARG, E_INVALID_ARG,
1474                                 "[E_INVALID_ARG] Controls have not been added to the container.");
1475
1476         if (pTargetNode == pCurNode)
1477         {
1478                 return E_SUCCESS;
1479         }
1480
1481         SysTryReturn(NID_UI, (pTargetNode == null), E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The (%d, %d) cell is not available.", row, column);
1482
1483         int cellIndex = MakeCellID(row, column);
1484         TableItemInfo* pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1485         if (pItemInfo == null)
1486         {
1487                 return E_INVALID_STATE;
1488         }
1489
1490         if (pItemInfo->__merged || !pItemInfo->__enable)
1491         {
1492                 pItemInfo->__enable = true;
1493                 pItemInfo->__merged = false;
1494                 if (pCurNode->GetItemProxy() != null)
1495                 {
1496                         pCurNode->GetItemProxy()->Visible(true);
1497                 }
1498         }
1499
1500         pItemInfo->__id = cellIndex;
1501
1502         SetUpdateState(true);
1503         return E_SUCCESS;
1504 }
1505
1506 result
1507 TableLayout::GetItemPosition(const LayoutItem& item, int& row, int& column) const
1508 {
1509         ProxyList* pProxyList = GetProxyList();
1510         SysAssertf(pProxyList != null, "ProxyList is invalid");
1511
1512         ProxyListNode* pCurNode = pProxyList->GetNode(item);
1513         SysTryReturn(NID_UI, (pCurNode != null), E_INVALID_ARG, E_INVALID_ARG,
1514                                 "[E_INVALID_ARG] Controls have not been added to the container.");
1515
1516         TableItemInfo* pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1517         if (pItemInfo == null)
1518         {
1519                 return E_INVALID_STATE;
1520         }
1521         row = (GetRow(pItemInfo->__id));
1522         column = (GetColumn(pItemInfo->__id));
1523
1524         return E_SUCCESS;
1525 }
1526
1527 result
1528 TableLayout::AddRow(void)
1529 {
1530         if (__row == __maxRow)
1531         {
1532                 RowInfo* pRowInfo = new (std::nothrow) RowInfo[__maxRow + 1];
1533                 SysTryReturn(NID_UI, pRowInfo != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
1534
1535                 memset(pRowInfo, 0x0, sizeof(RowInfo) * (__maxRow + 1));
1536                 memcpy(pRowInfo, __pRowInfo, sizeof(RowInfo) * __maxRow);
1537                 delete[] __pRowInfo;
1538                 __pRowInfo = pRowInfo;
1539                 __maxRow++;
1540         }
1541         __row++;
1542         return E_SUCCESS;
1543 }
1544
1545 result
1546 TableLayout::AddColumn(void)
1547 {
1548         if (__column == __maxColumn)
1549         {
1550                 ColumnInfo* pColInfo = new (std::nothrow) ColumnInfo[__maxColumn + 1];
1551                 SysTryReturn(NID_UI, pColInfo != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
1552
1553                 memset(pColInfo, 0x0, sizeof(ColumnInfo) * (__maxColumn + 1));
1554                 memcpy(pColInfo, __pColInfo, sizeof(ColumnInfo) * __maxColumn);
1555                 delete[] __pColInfo;
1556                 __pColInfo = pColInfo;
1557                 __maxColumn++;
1558         }
1559         __column++;
1560         return E_SUCCESS;
1561 }
1562
1563 result
1564 TableLayout::DeleteRow(int row)
1565 {
1566         if (row < 0 || row >= __row)
1567         {
1568                 return E_INVALID_ARG;
1569         }
1570
1571         ProxyListNode* pCurNode = null;
1572         result r = E_SUCCESS;
1573         for (int j = 0; j < __column; j++)
1574         {
1575                 pCurNode = GetNode(row, j);
1576                 if (pCurNode != null)
1577                 {
1578                         r = RemoveItem(*(pCurNode->GetItemProxy()->GetItem()));
1579                         if (r != E_SUCCESS)
1580                         {
1581                                 return r;
1582                         }
1583                 }
1584         }
1585
1586         TableItemInfo* pItemInfo = null;
1587         for (int i = 0; i < __row; i++)
1588         {
1589                 for (int j = 0; j < __column; j++)
1590                 {
1591                         pCurNode = GetNode(i, j);
1592                         if (pCurNode != null)
1593                         {
1594                                 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1595                                 if (pItemInfo == null)
1596                                 {
1597                                         return E_INVALID_STATE;
1598                                 }
1599                                 if (i > row)
1600                                 {
1601                                         pItemInfo->__id = MakeCellID((i - 1), j);
1602                                 }
1603                                 if (pItemInfo->__mergeEndPoint.x != NOT_MERGED)
1604                                 {
1605                                         if (pItemInfo->__mergeEndPoint.x >= row)
1606                                         {
1607                                                 pItemInfo->__mergeEndPoint.x--;
1608                                         }
1609                                         if (pItemInfo->__mergeEndPoint.x == GetRow(pItemInfo->__id))
1610                                         {
1611                                                 r = Unmerge(GetRow(pItemInfo->__id), GetColumn(pItemInfo->__id));
1612                                                 if (r != E_SUCCESS)
1613                                                 {
1614                                                         return r;
1615                                                 }
1616                                         }
1617                                 }
1618                         }
1619                 }
1620         }
1621
1622         memcpy(&__pRowInfo[row], &__pRowInfo[row + 1], sizeof(RowInfo) * (__row - row - 1));
1623
1624         __row--;
1625
1626         return r;
1627 }
1628
1629 result
1630 TableLayout::DeleteColumn(int column)
1631 {
1632         if (column < 0 || column >= __column)
1633         {
1634                 return E_INVALID_ARG;
1635         }
1636
1637         ProxyListNode* pCurNode = null;
1638         TableItemInfo* pItemInfo = null;
1639         result r = E_SUCCESS;
1640         for (int i = 0; i < __row; i++)
1641         {
1642                 pCurNode = GetNode(i, column);
1643                 if (pCurNode != null)
1644                 {
1645                         r = RemoveItem(*(pCurNode->GetItemProxy()->GetItem()));
1646                         if (r != E_SUCCESS)
1647                         {
1648                                 return r;
1649                         }
1650                 }
1651
1652                 for (int j = 0; j < __column; j++)
1653                 {
1654                         pCurNode = GetNode(i, j);
1655                         if (pCurNode != null)
1656                         {
1657                                 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1658                                 if (pItemInfo == null)
1659                                 {
1660                                         return E_INVALID_STATE;
1661                                 }
1662                                 if (j > column)
1663                                 {
1664                                         pItemInfo->__id = MakeCellID(i, (j - 1));
1665                                 }
1666
1667                                 if (pItemInfo->__mergeEndPoint.y != NOT_MERGED)
1668                                 {
1669                                         if (pItemInfo->__mergeEndPoint.y >= column)
1670                                         {
1671                                                 pItemInfo->__mergeEndPoint.y--;
1672                                         }
1673                                         int mergeEndColumn = GetColumn(pItemInfo->__id);
1674                                         if (pItemInfo->__mergeEndPoint.y == mergeEndColumn)
1675                                         {
1676                                                 r = Unmerge(GetRow(pItemInfo->__id), GetColumn(pItemInfo->__id));
1677                                                 if (r != E_SUCCESS)
1678                                                 {
1679                                                         return r;
1680                                                 }
1681                                         }
1682                                 }
1683                         }
1684                 }
1685         }
1686
1687         memcpy(&__pColInfo[column], &__pColInfo[column + 1], sizeof(ColumnInfo) * (__column - column - 1));
1688
1689         __column--;
1690
1691         return E_SUCCESS;
1692 }
1693
1694 result
1695 TableLayout::CalculateMergeCell(int row, int column, LayoutSize& size)
1696 {
1697         if (row < 0 || row >= __row || column < 0 || column >= __column)
1698         {
1699                 return E_INVALID_ARG;
1700         }
1701
1702         ProxyListNode* pCurNode = GetNode(row, column);
1703         if (pCurNode == null)
1704         {
1705                 return E_INVALID_ARG;
1706         }
1707
1708         TableItemInfo* pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1709         if (pItemInfo == null)
1710         {
1711                 return E_INVALID_STATE;
1712         }
1713         if (pItemInfo->__mergeEndPoint.x > NOT_MERGED && !__pRowInfo[pItemInfo->__mergeEndPoint.x].rowCollapsed)
1714         {
1715                 int endRowPos = __pRowInfo[pItemInfo->__mergeEndPoint.x].y;
1716                 size.h = __pRowInfo[pItemInfo->__mergeEndPoint.x].height + endRowPos - __pRowInfo[row].y;
1717         }
1718         else
1719         {
1720                 size.h = __pRowInfo[row].height;
1721         }
1722
1723         if (pItemInfo->__mergeEndPoint.y > NOT_MERGED && !__pColInfo[pItemInfo->__mergeEndPoint.y].columnCollapsed)
1724         {
1725                 float endColPos = __pColInfo[pItemInfo->__mergeEndPoint.y].x;
1726                 size.w = __pColInfo[pItemInfo->__mergeEndPoint.y].width + endColPos - __pColInfo[column].x;
1727         }
1728         else
1729         {
1730                 size.w = __pColInfo[column].width;
1731         }
1732
1733         return E_SUCCESS;
1734 }
1735
1736 LayoutRect
1737 TableLayout::CalculateAlign(LayoutItemProxy& itemProxy, LayoutRect cellRect, LayoutRect itemRect, const HorizontalAlign horizonAlign, const VerticalAlign verticalAlign)
1738 {
1739         ItemMargin margin = itemProxy.GetItemMargin();
1740         itemRect.y = cellRect.y;
1741         itemRect.x = cellRect.x;
1742
1743         if (verticalAlign == ITEM_VERTICAL_ALIGN_TOP)
1744         {
1745                 if (itemRect.h > cellRect.h - margin.top - margin.bottom)
1746                 {
1747                         itemRect.h = cellRect.h - margin.top - margin.bottom;
1748                 }
1749                 itemRect.y = cellRect.y + margin.top;
1750         }
1751         else if (verticalAlign == ITEM_VERTICAL_ALIGN_BOTTOM)
1752         {
1753                 if (itemRect.h > cellRect.h - margin.top - margin.bottom)
1754                 {
1755                         itemRect.h = cellRect.h - margin.top - margin.bottom;
1756                 }
1757                 itemRect.y = cellRect.h + cellRect.y - itemRect.h - margin.bottom;
1758         }
1759         else if (verticalAlign == ITEM_VERTICAL_ALIGN_TOP_BOTTOM)
1760         {
1761                 itemRect.h = cellRect.h - margin.top - margin.bottom;
1762                 itemRect.y = cellRect.y + margin.top;
1763         }
1764         else if (verticalAlign == ITEM_VERTICAL_ALIGN_MIDDLE)
1765         {
1766                 if (cellRect.h > itemRect.h)
1767                 {
1768                         itemRect.y = cellRect.y + ((cellRect.h - itemRect.h) / 2);
1769                 }
1770                 else
1771                 {
1772                         itemRect.h = cellRect.h;
1773                 }
1774         }
1775         if (horizonAlign == ITEM_HORIZONTAL_ALIGN_RIGHT)
1776         {
1777                 if (itemRect.w > cellRect.w - margin.right - margin.left)
1778                 {
1779                         itemRect.w = cellRect.w - margin.right - margin.left;
1780                 }
1781                 itemRect.x = cellRect.w + cellRect.x - itemRect.w - margin.right;
1782         }
1783         else if (horizonAlign == ITEM_HORIZONTAL_ALIGN_LEFT)
1784         {
1785                 if (itemRect.w > cellRect.w - margin.left - margin.right)
1786                 {
1787                         itemRect.w = cellRect.w - margin.left - margin.right;
1788                 }
1789                 itemRect.x = cellRect.x + margin.left;
1790         }
1791         else if (horizonAlign == ITEM_HORIZONTAL_ALIGN_CENTER)
1792         {
1793                 if (cellRect.w > itemRect.w)
1794                 {
1795                         itemRect.x = cellRect.x + ((cellRect.w - itemRect.w) / 2);
1796                 }
1797                 else
1798                 {
1799                         itemRect.w = cellRect.w;
1800                 }
1801         }
1802         else if (horizonAlign == ITEM_HORIZONTAL_ALIGN_LEFT_RIGHT)
1803         {
1804                 itemRect.w = cellRect.w - margin.left - margin.right;
1805                 itemRect.x = cellRect.x + margin.left;
1806         }
1807
1808         return itemRect;
1809 }
1810
1811 result
1812 TableLayout::GetCellSize(int cellIndex, LayoutRect& rect)
1813 {
1814         if (cellIndex == INVALID_CELL_ID)
1815         {
1816                 return E_INVALID_ARG;
1817         }
1818
1819         int row = GetRow(cellIndex);
1820         if (row < 0 || row >= __row)
1821         {
1822                 return E_INVALID_ARG;
1823         }
1824
1825         int column = GetColumn(cellIndex);
1826         if (column < 0 || column >= __column)
1827         {
1828                 return E_INVALID_ARG;
1829         }
1830
1831         ProxyListNode* pCurNode = GetNode(row, column);
1832         if (pCurNode != null)
1833         {
1834                 TableItemInfo* pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1835                 if (pItemInfo == null)
1836                 {
1837                         return E_INVALID_STATE;
1838                 }
1839                 if (pItemInfo->__mergeEndPoint.x != NOT_MERGED || pItemInfo->__mergeEndPoint.y != NOT_MERGED)
1840                 {
1841                         LayoutSize size = {0.0f, 0.0f};
1842                         result r = CalculateMergeCell(row, column, size);
1843                         if (r != E_SUCCESS)
1844                         {
1845                                 rect.w = size.w;
1846                                 rect.h = size.h;
1847                         }
1848                 }
1849                 else
1850                 {
1851                         rect.h = __pRowInfo[row].height;
1852                         rect.w = __pColInfo[column].width;
1853                 }
1854         }
1855
1856         if (__pRowInfo[row].rowCollapsed)
1857         {
1858                 rect.h = 0.0f;
1859         }
1860
1861         if (__pColInfo[column].columnCollapsed)
1862         {
1863                 rect.w = 0.0f;
1864         }
1865
1866         return E_SUCCESS;
1867 }
1868
1869 result
1870 TableLayout::SetColumnCollapsed(int columnIndex, bool collapsed)
1871 {
1872         SysTryReturn(NID_UI, columnIndex >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1873                                 "[E_OUT_OF_RANGE] Negative input argument : column(%d)", columnIndex);
1874         SysTryReturn(NID_UI, columnIndex < __column, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1875                                 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", columnIndex, __column);
1876
1877         __pColInfo[columnIndex].columnCollapsed = collapsed;
1878
1879         ProxyListNode* pCurNode = null;
1880         TableItemInfo* pItemInfo = null;
1881         result r = E_SUCCESS;
1882         for (int i = 0; i < __row; i++)
1883         {
1884                 pCurNode = GetNode(i, columnIndex);
1885                 if (pCurNode != null)
1886                 {
1887                         pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1888                         if (pItemInfo == null)
1889                         {
1890                                 return E_INVALID_STATE;
1891                         }
1892                         if (pItemInfo->__merged == true)
1893                         {
1894                                 continue;
1895                         }
1896                         if (__pColInfo[columnIndex].columnCollapsed)
1897                         {
1898                                 pItemInfo->__enable = false;
1899                                 if (pCurNode->GetItemProxy() != null)
1900                                 {
1901                                         pCurNode->GetItemProxy()->Visible(false);
1902                                 }
1903                         }
1904                         else if (!__pRowInfo[i].rowCollapsed)
1905                         {
1906                                 pItemInfo->__enable = true;
1907                                 if (pCurNode->GetItemProxy() != null)
1908                                 {
1909                                         pCurNode->GetItemProxy()->Visible(true);
1910                                 }
1911                         }
1912                 }
1913         }
1914
1915         SetUpdateState(true);
1916         return r;
1917 }
1918
1919 bool
1920 TableLayout::GetColumnCollapsed(int columnIndex) const
1921 {
1922         if (columnIndex < 0 || columnIndex >= __column)
1923         {
1924                 return false;
1925         }
1926
1927         return __pColInfo[columnIndex].columnCollapsed;
1928 }
1929
1930 result
1931 TableLayout::SetRowCollapsed(int rowIndex, bool collapsed)
1932 {
1933         SysTryReturn(NID_UI, rowIndex >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1934                                 "[E_OUT_OF_RANGE] Negative input argument : row(%d)", rowIndex);
1935         SysTryReturn(NID_UI, rowIndex < __row, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1936                                 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", rowIndex, __row);
1937
1938         __pRowInfo[rowIndex].rowCollapsed = collapsed;
1939
1940         ProxyListNode* pCurNode = null;
1941         TableItemInfo* pItemInfo = null;
1942
1943         for (int i = 0; i < __column; i++)
1944         {
1945                 pCurNode = GetNode(rowIndex, i);
1946                 if (pCurNode != null)
1947                 {
1948                         pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1949                         if (pItemInfo == null)
1950                         {
1951                                 return E_INVALID_STATE;
1952                         }
1953                         if (pItemInfo->__merged == true)
1954                         {
1955                                 continue;
1956                         }
1957                         if (__pRowInfo[rowIndex].rowCollapsed)
1958                         {
1959                                 pItemInfo->__enable = false;
1960                                 if (pCurNode->GetItemProxy() != null)
1961                                 {
1962                                         pCurNode->GetItemProxy()->Visible(false);
1963                                 }
1964                         }
1965                         else if (!__pColInfo[i].columnCollapsed)
1966                         {
1967                                 pItemInfo->__enable = true;
1968                                 if (pCurNode->GetItemProxy() != null)
1969                                 {
1970                                         pCurNode->GetItemProxy()->Visible(true);
1971                                 }
1972                         }
1973                 }
1974         }
1975
1976         SetUpdateState(true);
1977         return E_SUCCESS;
1978 }
1979
1980 bool
1981 TableLayout::GetRowCollapsed(int rowIndex) const
1982 {
1983         if (rowIndex < 0 || rowIndex >= __row)
1984         {
1985                 return false;
1986         }
1987
1988         return __pRowInfo[rowIndex].rowCollapsed;
1989 }
1990
1991 result
1992 TableLayout::SetRowShrinkable(int row, bool shrinkable)
1993 {
1994         SysTryReturn(NID_UI, row >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1995                                 "[E_OUT_OF_RANGE] Negative input argument : row(%d)", row);
1996         SysTryReturn(NID_UI, row < __row, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1997                                 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
1998
1999         __pRowInfo[row].heightShrinkable = shrinkable;
2000
2001         SetUpdateState(true);
2002         SetPartialUpdateFlag(true);
2003         return E_SUCCESS;
2004 }
2005
2006 bool
2007 TableLayout::GetRowShrinkable(int row) const
2008 {
2009         SysTryReturn(NID_UI, row >= 0, false, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] Negative input argument : row(%d)", row);
2010         SysTryReturn(NID_UI, row < __row, false, E_OUT_OF_RANGE,
2011                                 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
2012
2013         return __pRowInfo[row].heightShrinkable;
2014 }
2015
2016 result
2017 TableLayout::SetColumnShrinkable(int column, bool shrinkable)
2018 {
2019         SysTryReturn(NID_UI, column >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2020                                 "[E_OUT_OF_RANGE] Negative input argument : column(%d)", column);
2021         SysTryReturn(NID_UI, column < __column, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2022                                 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2023
2024         __pColInfo[column].widthShrinkable = shrinkable;
2025
2026         SetUpdateState(true);
2027         SetPartialUpdateFlag(true);
2028         return E_SUCCESS;
2029 }
2030
2031 bool
2032 TableLayout::GetColumnShrinkable(int column) const
2033 {
2034         SysTryReturn(NID_UI, column >= 0, false, E_OUT_OF_RANGE,
2035                                 "[E_OUT_OF_RANGE] Negative input argument : column(%d)", column);
2036         SysTryReturn(NID_UI, column < __column, false, E_OUT_OF_RANGE,
2037                                 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2038
2039         return __pColInfo[column].widthShrinkable;
2040 }
2041
2042 result
2043 TableLayout::SetRowStretchable(int row, bool stretchable)
2044 {
2045         SysTryReturn(NID_UI, row >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2046                                 "[E_OUT_OF_RANGE] Negative input argument : row(%d)", row);
2047         SysTryReturn(NID_UI, row < __row, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2048                                 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
2049
2050         __pRowInfo[row].heightStretchable = stretchable;
2051
2052         SetUpdateState(true);
2053         SetPartialUpdateFlag(true);
2054         return E_SUCCESS;
2055 }
2056
2057 bool
2058 TableLayout::GetRowStretchable(int row) const
2059 {
2060         if (row < 0 || row >= __row)
2061         {
2062                 return false;
2063         }
2064
2065         return __pRowInfo[row].heightStretchable;
2066 }
2067
2068 result
2069 TableLayout::SetColumnStretchable(int column, bool stretchable)
2070 {
2071         SysTryReturn(NID_UI, column >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] Negative input argument : column(%d)",
2072                                 column);
2073         SysTryReturn(NID_UI, column < __column, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2074                                 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2075
2076         __pColInfo[column].widthStretchable = stretchable;
2077
2078         SetUpdateState(true);
2079         SetPartialUpdateFlag(true);
2080         return E_SUCCESS;
2081 }
2082
2083 bool
2084 TableLayout::GetColumnStretchable(int column) const
2085 {
2086         SysTryReturn(NID_UI, column >= 0, false, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] Negative input argument : column(%d)", column);
2087         SysTryReturn(NID_UI, column < __column, false, E_OUT_OF_RANGE,
2088                                 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2089
2090         return __pColInfo[column].widthStretchable;
2091 }
2092
2093 result
2094 TableLayout::SetRowSpacing(int row, float heightSpacing)
2095 {
2096         SysTryReturn(NID_UI, row >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2097                                 "[E_OUT_OF_RANGE] Negative input argument : row(%d)", row);
2098         SysTryReturn(NID_UI, row < __row, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2099                                 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
2100         SysTryReturn(NID_UI, heightSpacing >= 0.0f, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2101                                 "[E_OUT_OF_RANGE] Negative input argument : spacing(%d)", heightSpacing);
2102
2103         __pRowInfo[row].heightSpacing = heightSpacing;
2104
2105         SetUpdateState(true);
2106         return E_SUCCESS;
2107 }
2108
2109 result
2110 TableLayout::GetRowSpacing(int row, float& spacing) const
2111 {
2112         SysTryReturn(NID_UI, row >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2113                                 "[E_OUT_OF_RANGE] Negative input argument : row(%d)", row);
2114         SysTryReturn(NID_UI, row < __row, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2115                                 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
2116
2117         spacing = __pRowInfo[row].heightSpacing;
2118         return E_SUCCESS;
2119 }
2120
2121 result
2122 TableLayout::SetColumnSpacing(int column, float widthSpacing)
2123 {
2124         SysTryReturn(NID_UI, column >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2125                                 "[E_OUT_OF_RANGE] Negative input argument : column(%d)", column);
2126         SysTryReturn(NID_UI, column < __column, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2127                                 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2128         SysTryReturn(NID_UI, widthSpacing >= 0.0f, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2129                                 "[E_OUT_OF_RANGE] Negative input argument : spacing(%d)", widthSpacing);
2130
2131         __pColInfo[column].widthSpacing = widthSpacing;
2132
2133         SetUpdateState(true);
2134         return E_SUCCESS;
2135 }
2136
2137 result
2138 TableLayout::GetColumnSpacing(int column, float& spacing) const
2139 {
2140         SysTryReturn(NID_UI, column >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2141                                 "[E_OUT_OF_RANGE] Negative input argument : column(%d)", column);
2142         SysTryReturn(NID_UI, column < __column, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2143                                 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2144
2145         spacing = __pColInfo[column].widthSpacing;
2146
2147         return E_SUCCESS;
2148 }
2149
2150 result
2151 TableLayout::SetFillCell(int row, int column, bool fillWidth, bool fillHeight)
2152 {
2153         SysTryReturn(NID_UI, row >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2154                                 "[E_OUT_OF_RANGE] Negative input argument : row(%d)", row);
2155         SysTryReturn(NID_UI, row < __row, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2156                                 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
2157         SysTryReturn(NID_UI, column >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2158                                 "[E_OUT_OF_RANGE] Negative input argument : column(%d)", column);
2159         SysTryReturn(NID_UI, column < __column, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2160                                 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2161
2162         ProxyListNode* pNode = GetNode(row, column);
2163         if (pNode != null)
2164         {
2165                 TableItemInfo* pItemInfo = static_cast <TableItemInfo*>(pNode->GetItemInfo());
2166                 if (pItemInfo == null)
2167                 {
2168                         return E_INVALID_STATE;
2169                 }
2170                 pItemInfo->__fillWidth = fillWidth;
2171                 pItemInfo->__fillHeight = fillHeight;
2172                 return E_SUCCESS;
2173         }
2174         return E_SYSTEM;
2175 }
2176
2177 result
2178 TableLayout::GetFillCell(int row, int column, bool& fillWidth, bool& fillHeight) const
2179 {
2180         SysTryReturn(NID_UI, row >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2181                                 "[E_OUT_OF_RANGE] Negative input argument : row(%d)", row);
2182         SysTryReturn(NID_UI, row < __row, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2183                                 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
2184         SysTryReturn(NID_UI, column >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2185                                 "[E_OUT_OF_RANGE] Negative input argument : column(%d)", column);
2186         SysTryReturn(NID_UI, column < __column, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2187                                 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2188
2189         ProxyListNode* pNode = GetNode(row, column);
2190         if (pNode != null)
2191         {
2192                 TableItemInfo* pItemInfo = static_cast <TableItemInfo*>(pNode->GetItemInfo());
2193                 if (pItemInfo == null)
2194                 {
2195                         return E_INVALID_STATE;
2196                 }
2197                 fillWidth = pItemInfo->__fillWidth;
2198                 fillHeight = pItemInfo->__fillHeight;
2199                 return E_SUCCESS;
2200         }
2201         return E_SYSTEM;
2202 }
2203
2204 result
2205 TableLayout::SwapItemPosition(LayoutItem& item1, LayoutItem& item2)
2206 {
2207         ProxyList* pProxyList = GetProxyList();
2208         SysAssertf(pProxyList != null, "ProxyList is invalid");
2209
2210         ProxyListNode* pNode1 = pProxyList->GetNode(item1);
2211         ProxyListNode* pNode2 = pProxyList->GetNode(item2);
2212
2213         SysTryReturn(NID_UI, (pNode1 != null && pNode2 != null), E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.")
2214
2215         TableItemInfo* pItemInfo1 = static_cast <TableItemInfo*>(pNode1->GetItemInfo());
2216         TableItemInfo* pItemInfo2 = static_cast <TableItemInfo*>(pNode2->GetItemInfo());
2217         if (pItemInfo1 == null || pItemInfo2 == null)
2218         {
2219                 return E_INVALID_STATE;
2220         }
2221
2222         int cellIndex1 = pItemInfo1->__id;
2223         int cellIndex2 = pItemInfo2->__id;
2224         bool merged1 = pItemInfo1->__merged;
2225         bool merged2 = pItemInfo2->__merged;
2226         bool enable1 = pItemInfo1->__enable;
2227         bool enable2 = pItemInfo2->__enable;
2228
2229         pItemInfo1->__id = cellIndex2;
2230         pItemInfo2->__id = cellIndex1;
2231         pItemInfo1->__merged = merged2;
2232         pItemInfo2->__merged = merged1;
2233         pItemInfo1->__enable = enable2;
2234         pItemInfo2->__enable = enable1;
2235
2236         if (pNode1->GetItemProxy() != null)
2237         {
2238                 if (pItemInfo1->__merged || !pItemInfo1->__enable)
2239                 {
2240                         pNode1->GetItemProxy()->Visible(false);
2241                 }
2242                 else
2243                 {
2244                         pNode1->GetItemProxy()->Visible(true);
2245                 }
2246         }
2247
2248         if (pNode2->GetItemProxy() != null)
2249         {
2250                 if (pItemInfo2->__merged || !pItemInfo2->__enable)
2251                 {
2252                         pNode2->GetItemProxy()->Visible(false);
2253                 }
2254                 else
2255                 {
2256                         pNode2->GetItemProxy()->Visible(true);
2257                 }
2258         }
2259
2260         SetUpdateState(true);
2261         return E_SUCCESS;
2262 }
2263
2264 result
2265 TableLayout::Unmerge(int row, int column)
2266 {
2267         SysTryReturn(NID_UI, row >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Negative input argument : row(%d)", row);
2268         SysTryReturn(NID_UI, row < __row, E_INVALID_ARG, E_INVALID_ARG,
2269                                 "[E_INVALID_ARG] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
2270         SysTryReturn(NID_UI, column >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Negative input argument : column(%d)", column);
2271         SysTryReturn(NID_UI, column < __column, E_INVALID_ARG, E_INVALID_ARG,
2272                                 "[E_INVALID_ARG] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2273
2274         int endRow = 0;
2275         int endColumn = 0;
2276
2277         ProxyListNode* pCurNode = null;
2278         TableItemInfo* pItemInfo = null;
2279
2280         pCurNode = GetNode(row, column);
2281         SysTryReturn(NID_UI, pCurNode, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALIDE_ARG] (%d, %d) cell  is not merged.", row, column);
2282
2283         pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
2284         if (pItemInfo == null)
2285         {
2286                 return E_INVALID_STATE;
2287         }
2288         endRow = pItemInfo->__mergeEndPoint.x;
2289         endColumn = pItemInfo->__mergeEndPoint.y;
2290
2291         if (pItemInfo->__enable == false || pItemInfo->__merged == false
2292                 || endRow == NOT_MERGED || endColumn == NOT_MERGED)
2293         {
2294                 return E_INVALID_STATE;
2295         }
2296
2297         pItemInfo->__mergeEndPoint.x = NOT_MERGED;
2298         pItemInfo->__mergeEndPoint.y = NOT_MERGED;
2299
2300         for (int i = row; i <= endRow; i++)
2301         {
2302                 for (int j = column; j <= endColumn; j++)
2303                 {
2304                         pCurNode = GetNode(i, j);
2305                         if (pCurNode != null)
2306                         {
2307                                 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
2308                                 if (pItemInfo == null)
2309                                 {
2310                                         return E_INVALID_STATE;
2311                                 }
2312                                 pItemInfo->__enable = true;
2313                                 pItemInfo->__merged = false;
2314
2315                                 for (int k = 0; k < __mergedCellList.GetCount(); k++)
2316                                 {
2317                                         Integer* cellID = static_cast <Integer*>(__mergedCellList.GetAt(k));
2318                                         if (cellID->ToInt() == MakeCellID(i, j))
2319                                         {
2320                                                 __mergedCellList.RemoveAt(k, true);
2321                                                 break;
2322                                         }
2323                                 }
2324
2325                                 if (pCurNode->GetItemProxy() != null)
2326                                 {
2327                                         pCurNode->GetItemProxy()->Visible(true);
2328                                 }
2329                         }
2330                 }
2331         }
2332
2333         SetUpdateState(true);
2334         return E_SUCCESS;
2335 }
2336
2337 result
2338 TableLayout::GetMergeSize(int row, int column, int& rowSize, int& colSize) const
2339 {
2340         rowSize = 0;
2341         colSize = 0;
2342
2343         SysTryReturn(NID_UI, row >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2344                                 "[E_OUT_OF_RANGE] Negative input argument : row(%d)", row);
2345         SysTryReturn(NID_UI, row < __row, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2346                                 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
2347         SysTryReturn(NID_UI, column >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2348                                 "[E_OUT_OF_RANGE] Negative input argument : column(%d)", column);
2349         SysTryReturn(NID_UI, column < __column, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2350                                 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2351
2352         ProxyListNode* pNode = GetNode(row, column);
2353         if (pNode == null)
2354         {
2355                 rowSize = 1;
2356                 colSize = 1;
2357                 return E_SUCCESS;
2358         }
2359         TableItemInfo* pItemInfo = static_cast <TableItemInfo*>(pNode->GetItemInfo());
2360         if (pItemInfo == null || pItemInfo->__enable == false)
2361         {
2362                 return E_INVALID_STATE;
2363         }
2364
2365         if (pItemInfo->__merged == false)
2366         {
2367                 rowSize = 1;
2368                 colSize = 1;
2369         }
2370         else
2371         {
2372                 rowSize = pItemInfo->__mergeEndPoint.x - row + 1;
2373                 colSize = pItemInfo->__mergeEndPoint.y - column + 1;
2374         }
2375
2376         return E_SUCCESS;
2377 }
2378
2379 ProxyListNode*
2380 TableLayout::GetNode(int row, int column) const
2381 {
2382         ProxyList* pProxyList = GetProxyList();
2383         SysAssertf(pProxyList != null, "ProxyList is invalid");
2384
2385         ProxyListNode* pCurNode = pProxyList->GetFirstNode();
2386         TableItemInfo* pItemInfo = null;
2387         int rowIndex = 0;
2388         int columnIndex = 0;
2389         while (pCurNode)
2390         {
2391                 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
2392                 if (pItemInfo != null)
2393                 {
2394                         rowIndex = GetRow(pItemInfo->__id);
2395                         columnIndex = GetColumn(pItemInfo->__id);
2396                         if (row == rowIndex && column == columnIndex)
2397                         {
2398                                 return pCurNode;
2399                         }
2400                 }
2401                 pCurNode = pProxyList->GetNextNode(*pCurNode);
2402         }
2403         return null;
2404 }
2405
2406 int
2407 TableLayout::GetRow(int id) const
2408 {
2409         return id >> 16;
2410 }
2411
2412 int
2413 TableLayout::GetColumn(int id) const
2414 {
2415         return id & 0x0000FFFF;
2416 }
2417
2418 int
2419 TableLayout::MakeCellID(int row, int column) const
2420 {
2421         return (row << 16) | (column & 0x0000FFFF);
2422 }
2423
2424 } // Tizen::Ui::_Layout
2425 } // Tizen::Ui
2426 } // Osp