2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0/
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.
18 * @file FUi_LayoutTableLayout.cpp
19 * @brief This is the implementation file for TableLayout class.
21 * This file contains the implementation of TableLayout class.
27 #include <FBaseResult.h>
28 #include <FBaseInteger.h>
30 #include "FUi_LayoutTableLayout.h"
31 #include "FUi_LayoutLayoutItemProxy.h"
32 #include "FUi_LayoutProxyList.h"
33 #include "FUi_LayoutLayoutItemInfo.h"
35 using namespace Tizen::Base;
37 namespace Tizen { namespace Ui { namespace _Layout
40 TableLayout::TableLayout(void)
47 , __shrinkColumnCount(0)
48 , __stretchRowCount(0)
49 , __stretchColumnCount(0)
50 , __rowShrinkable(false)
51 , __columnShrinkable(false)
52 , __rowStretchable(false)
53 , __columnStretchable(false)
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);
62 TableLayout::~TableLayout(void)
64 __mergedCellList.RemoveAll(true);
71 TableLayout::CreateTableLayoutN(void)
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)
85 TableLayout::CreateTable(int row, int column, float spacing)
87 if (row < 1 || column < 1)
89 SysTryReturn(NID_UI, false, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Negative argument : row(%d), column(%d)", row,
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.");
101 memset(__pColInfo, 0, sizeof(ColumnInfo) * __column);
103 for (int i = 0; i < __column; i++)
105 __pColInfo[i].widthSpacing = spacing;
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.");
111 memset(__pRowInfo, 0, sizeof(RowInfo) * __row);
113 for (int i = 0; i < __row; i++)
115 __pRowInfo[i].heightSpacing = spacing;
122 TableLayout::CalculateSize()
124 if (__row < 1 || __column < 1)
129 float nextPosX = 0.0f;
130 float nextPosY = 0.0f;
132 __shrinkRowCount = 0;
133 __shrinkColumnCount = 0;
134 __stretchRowCount = 0;
135 __stretchColumnCount = 0;
137 for (int j = 0; j < __column; j++)
139 __pColInfo[j].x = 0.0f;
140 __pColInfo[j].width = 0.0f;
141 __pColInfo[j].maxWidth = 0.0f;
142 __pColInfo[j].mergedWidth = 0.0f;
145 ProxyListNode* pCurNode = null;
146 TableItemInfo* pItemInfo = null;
147 LayoutItemProxy* pItemProxy = null;
149 for (int i = 0; i < __row; i++)
151 __pRowInfo[i].y = 0.0f;
152 __pRowInfo[i].height = 0.0f;
153 __pRowInfo[i].maxHeight = 0.0f;
154 __pRowInfo[i].mergedHeight = 0.0f;
156 for (int j = 0; j < __column; j++)
158 pCurNode = GetNode(i, j);
159 if (pCurNode != null)
161 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
163 pItemProxy = pCurNode->GetItemProxy();
164 if (pItemInfo == null || pItemProxy == null)
166 return E_INVALID_STATE;
169 if (pItemInfo->__enable)
171 pItemProxy->GetMinSize(pItemInfo->__minSize);
172 pItemProxy->GetMaxSize(pItemInfo->__maxSize);
175 LayoutRect rect = pItemProxy->GetItemBaseRect();
177 result r = pItemProxy->Measure(rect.w, rect.h);
182 pItemProxy->GetMeasuredSize(rect.w, rect.h);
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)
188 rect.w += margin.left;
190 if (itemAlign.HAlign == ITEM_HORIZONTAL_ALIGN_RIGHT || itemAlign.HAlign == ITEM_HORIZONTAL_ALIGN_LEFT_RIGHT)
192 rect.w += margin.right;
194 if (itemAlign.VAlign == ITEM_VERTICAL_ALIGN_TOP || itemAlign.VAlign == ITEM_VERTICAL_ALIGN_TOP_BOTTOM)
196 rect.h += margin.top;
198 if (itemAlign.VAlign == ITEM_VERTICAL_ALIGN_BOTTOM || itemAlign.VAlign == ITEM_VERTICAL_ALIGN_TOP_BOTTOM)
200 rect.h += margin.bottom;
203 if (!pItemInfo->__merged)
205 if (__pColInfo[j].maxWidth < rect.w && !__pRowInfo[i].rowCollapsed)
207 __pColInfo[j].maxWidth = rect.w;
210 if (__pRowInfo[i].maxHeight < rect.h && !__pColInfo[j].columnCollapsed)
212 __pRowInfo[i].maxHeight = rect.h;
217 if (__pColInfo[j].mergedWidth < rect.w)
219 __pColInfo[j].mergedWidth = rect.w;
221 if (__pRowInfo[i].mergedHeight < rect.h)
223 __pRowInfo[i].mergedHeight = rect.h;
229 if (!__pRowInfo[i].rowCollapsed)
231 if (__pRowInfo[i].heightStretchable)
235 if (__pRowInfo[i].heightShrinkable)
240 if (!_FloatHardCompare(__pRowInfo[i].maxHeight, 0.0f))
242 __pRowInfo[i].height = __pRowInfo[i].maxHeight;
247 for (int j = 0; j < __column; j++)
249 if (!__pColInfo[j].columnCollapsed)
251 if (__pColInfo[j].widthStretchable)
253 __stretchColumnCount++;
255 if (__pColInfo[j].widthShrinkable)
257 __shrinkColumnCount++;
260 if (!_FloatHardCompare(__pColInfo[j].maxWidth, 0.0f))
262 __pColInfo[j].width = __pColInfo[j].maxWidth;
271 float mergedHeight = 0.0f;
272 float mergedWidth = 0.0f;
273 for (int i = __row - 1; i >= 0; i--)
275 if (!__pRowInfo[i].rowCollapsed)
277 for (int j = __column - 1; j >= 0; j--)
279 if (!__pColInfo[j].columnCollapsed)
281 pCurNode = GetNode(i, j);
282 if (pCurNode != null)
284 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
285 if (pItemInfo == null)
287 return E_INVALID_STATE;
289 pItemProxy = pCurNode->GetItemProxy();
290 if (pItemInfo->__mergeEndPoint.x != NOT_MERGED)
294 int endRow = pItemInfo->__mergeEndPoint.x;
295 int endColumn = pItemInfo->__mergeEndPoint.y;
297 pItemProxy->GetMeasuredSize(mergedWidth, mergedHeight);
299 float rowHeightSum = 0.0f;
302 rowHeightSum -= __pRowInfo[startRow].heightSpacing;
304 for (int k = startRow; k <= endRow; k++)
306 rowHeightSum += __pRowInfo[k].height + __pRowInfo[k].heightSpacing;
308 if (mergedHeight > rowHeightSum)
310 __pRowInfo[startRow].height += mergedHeight - rowHeightSum;
313 float colWidthSum = 0.0f;
314 if (startColumn == 0)
316 colWidthSum -= __pColInfo[startColumn].widthSpacing;
318 for (int k = startColumn; k <= endColumn; k++)
320 colWidthSum += __pColInfo[k].width + __pColInfo[k].widthSpacing;
322 if (mergedWidth > colWidthSum)
324 __pColInfo[startColumn].width += mergedWidth - colWidthSum;
333 LayoutRect layoutRect = GetLayoutRect();
334 nextPosY = -__pRowInfo[0].heightSpacing + layoutRect.y;
335 for (int i = 0; i < __row; i++)
337 nextPosX = -__pColInfo[0].widthSpacing + layoutRect.x;
338 if (!__pRowInfo[i].rowCollapsed)
340 for (int j = 0; j < __column; j++)
342 if (!__pColInfo[j].columnCollapsed)
344 __pColInfo[j].x = nextPosX + __pColInfo[j].widthSpacing;
345 nextPosX = __pColInfo[j].x + __pColInfo[j].width;
348 __pRowInfo[i].y = nextPosY + __pRowInfo[i].heightSpacing;
349 nextPosY = __pRowInfo[i].y + __pRowInfo[i].height;
353 layoutRect.w = nextPosX;
354 layoutRect.h = nextPosY;
355 SetLayoutRect(layoutRect);
361 TableLayout::CalculateShrinkCell(const LayoutRect windowRect)
363 __rowShrinkable = false;
364 __columnShrinkable = false;
366 LayoutItemProxy* pContainerProxy = GetContainerProxy();
367 if (pContainerProxy == null)
369 return E_INVALID_STATE;
372 LayoutRect containerRect;
373 pContainerProxy->ConvertWindowToClientBounds(windowRect, containerRect);
375 LayoutRect layoutRect = GetLayoutRect();
377 float shrinkTotalWidth = layoutRect.w - containerRect.w;
378 float shrinkTotalHeight = layoutRect.h - containerRect.h;
380 int shrinkColumnCount = __shrinkColumnCount;
381 int shrinkRowCount = __shrinkRowCount;
383 int* pShrinkedColumns = null;
384 int* pShrinkedRows = null;
386 int lastShrinkRow = 0;
387 int lastShrinkColumn = 0;
389 ProxyListNode* pCurNode = null;
390 TableItemInfo* pItemInfo = null;
392 if (shrinkTotalWidth > 0 && __shrinkColumnCount > 0)
394 if (pContainerProxy->GetItemWidthMatchMode() == WRAP_CONTENT)
399 __columnShrinkable = true;
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.");
404 memset(pShrinkedColumns, 0x00, sizeof(int) * __shrinkColumnCount);
406 int shrinkedColumnCount = 0;
407 bool shrinkedItem = true;
409 while (shrinkedItem && shrinkColumnCount != 0)
411 shrinkedItem = false;
413 for (int j = 0; j < __column; j++)
415 int shrinkWidth = shrinkTotalWidth / shrinkColumnCount;
416 float shrinkedColWidth = __pColInfo[j].width;
418 if (__pColInfo[j].widthShrinkable && !__pColInfo[j].columnCollapsed)
420 shrinkedColWidth -= shrinkWidth;
422 if (shrinkedColWidth < 0.0f)
424 shrinkWidth += shrinkedColWidth;
426 __pColInfo[j].width = 0.0f;
427 shrinkedColWidth = 0.0f;
428 __pColInfo[j].widthShrinkable = false;
432 for (int i = 0; i < __row; i++)
434 pCurNode = GetNode(i, j);
436 if (pCurNode != null)
438 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
440 if (pItemInfo != null && shrinkedColWidth < pItemInfo->__minSize.w)
442 shrinkWidth -= pItemInfo->__minSize.w - shrinkedColWidth;
443 __pColInfo[j].width = pItemInfo->__minSize.w;
444 __pColInfo[j].widthShrinkable = false;
448 if (__pColInfo[j].widthShrinkable == false)
450 shrinkTotalWidth -= shrinkWidth;
451 layoutRect.w -= shrinkWidth;
454 pShrinkedColumns[shrinkedColumnCount++] = j;
463 float nextPosX = -__pColInfo[0].widthSpacing + layoutRect.x;
465 for (int j = 0; j < __column; j++)
467 __pColInfo[j].x = nextPosX + __pColInfo[j].widthSpacing;
469 if (!__pColInfo[j].columnCollapsed)
471 if (shrinkColumnCount != 0)
473 int shrinkWidth = shrinkTotalWidth / shrinkColumnCount;
475 if (__pColInfo[j].widthShrinkable)
477 __pColInfo[j].width -= shrinkWidth;
478 lastShrinkColumn = j;
479 layoutRect.w -= shrinkWidth;
482 nextPosX = __pColInfo[j].width + __pColInfo[j].x;
486 nextPosX = -__pColInfo[0].widthSpacing + layoutRect.x;
487 float shrinkWidth = 0.0f;
488 if (!_FloatCompare(shrinkTotalWidth, 0.0f) && shrinkColumnCount != 0)
490 shrinkWidth = (int)shrinkTotalWidth % shrinkColumnCount;
492 bool shrinkableColumn = true;
494 while (shrinkWidth > 0 && shrinkableColumn)
496 shrinkableColumn = false;
497 for (int j = 0; j < __column; j++)
499 __pColInfo[j].x = nextPosX + __pColInfo[j].widthSpacing;
501 if (!__pColInfo[j].columnCollapsed)
503 if (shrinkColumnCount != 0)
505 if (__pColInfo[j].widthShrinkable)
507 for (int i = 0; i < __row; i++)
509 pCurNode = GetNode(i, j);
511 if (pCurNode != null)
513 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
515 if ((pItemInfo != null && ((__pColInfo[j].width - 1.0f) < pItemInfo->__minSize.w)) || (__pColInfo[j].width - 1.0f) < 0.0f)
517 pShrinkedColumns[shrinkedColumnCount++] = j;
518 __pColInfo[j].widthShrinkable = false;
524 if (__pColInfo[j].widthShrinkable && shrinkWidth > 0.0f)
526 if (shrinkWidth < 1.0f)
528 __pColInfo[j].width -= shrinkWidth;
529 layoutRect.w -= shrinkWidth;
531 shrinkableColumn = true;
535 __pColInfo[j].width--;
538 shrinkableColumn = true;
543 nextPosX = __pColInfo[j].width + __pColInfo[j].x;
548 for (int j = 0; j < shrinkedColumnCount; j++)
550 __pColInfo[pShrinkedColumns[j]].widthShrinkable = true;
553 delete[] pShrinkedColumns;
556 if (shrinkTotalHeight > 0.0f && __shrinkRowCount > 0)
558 if (pContainerProxy->GetItemHeightMatchMode() == WRAP_CONTENT)
563 __rowShrinkable = true;
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.");
568 memset(pShrinkedRows, 0x00, sizeof(int) * __shrinkRowCount);
569 int shrinkedRowCount = 0;
570 bool shrinkedItem = true;
572 while (shrinkedItem && shrinkRowCount != 0)
574 shrinkedItem = false;
576 for (int i = 0; i < __row; i++)
578 int shrinkHeight = shrinkTotalHeight / shrinkRowCount;
579 float shrinkedRowHeight = __pRowInfo[i].height;
581 if (__pRowInfo[i].heightShrinkable && !__pRowInfo[i].rowCollapsed)
583 shrinkedRowHeight -= shrinkHeight;
585 if (shrinkedRowHeight < 0.0f)
587 shrinkHeight += shrinkedRowHeight;
589 __pRowInfo[i].height = 0.0f;
590 shrinkedRowHeight = 0.0f;
591 __pRowInfo[i].heightShrinkable = false;
595 for (int j = 0; j < __column; j++)
597 pCurNode = GetNode(i, j);
599 if (pCurNode != null)
601 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
603 if (pItemInfo != null && shrinkedRowHeight < pItemInfo->__minSize.h)
605 shrinkHeight -= pItemInfo->__minSize.h - shrinkedRowHeight;
606 __pRowInfo[i].height = pItemInfo->__minSize.h;
607 __pRowInfo[i].heightShrinkable = false;
611 if (__pRowInfo[i].heightShrinkable == false)
613 shrinkTotalHeight -= shrinkHeight;
614 layoutRect.h -= shrinkHeight;
617 pShrinkedRows[shrinkedRowCount++] = i;
626 float nextPosY = -__pRowInfo[0].heightSpacing + layoutRect.y;
628 for (int i = 0; i < __row; i++)
630 if (!__pRowInfo[i].rowCollapsed)
632 if (shrinkRowCount != 0)
634 int shrinkHeight = shrinkTotalHeight / shrinkRowCount;
636 if (__pRowInfo[i].heightShrinkable)
638 __pRowInfo[i].height -= shrinkHeight;
640 layoutRect.h -= shrinkHeight;
643 __pRowInfo[i].y = nextPosY + __pRowInfo[i].heightSpacing;
644 nextPosY = __pRowInfo[i].height + __pRowInfo[i].y;
648 nextPosY = -__pRowInfo[0].heightSpacing + layoutRect.y;
649 float shrinkHeight = 0.0f;
650 if (!_FloatHardCompare(shrinkTotalHeight, 0.0f) && shrinkRowCount != 0)
652 shrinkHeight = (int)shrinkTotalHeight % shrinkRowCount;
654 bool shrinkableRow = true;
656 while (shrinkHeight > 0 && shrinkableRow)
658 shrinkableRow = false;
659 for (int i = 0; i < __row; i++)
661 if (!__pRowInfo[i].rowCollapsed)
663 if (shrinkRowCount != 0)
665 if (__pRowInfo[i].heightShrinkable)
667 for (int j = 0; j < __column; j++)
669 pCurNode = GetNode(i, j);
671 if (pCurNode != null)
673 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
675 if ((pItemInfo != null && ((__pRowInfo[i].height - 1.0f) < pItemInfo->__minSize.h)) || (__pRowInfo[i].height - 1.0f) < 0.0f)
677 pShrinkedRows[shrinkedRowCount++] = i;
678 __pRowInfo[i].heightShrinkable = false;
684 if (__pRowInfo[i].heightShrinkable && shrinkHeight > 0)
686 if (shrinkHeight < 1.0f)
688 __pRowInfo[i].height -= shrinkHeight;
689 layoutRect.h -= shrinkHeight;
691 shrinkableRow = true;
695 __pRowInfo[i].height--;
698 shrinkableRow = true;
703 __pRowInfo[i].y = nextPosY + __pRowInfo[i].heightSpacing;
704 nextPosY = __pRowInfo[i].height + __pRowInfo[i].y;
709 for (int i = 0; i < shrinkedRowCount; i++)
711 __pRowInfo[pShrinkedRows[i]].heightShrinkable = true;
714 delete[] pShrinkedRows;
716 SetLayoutRect(layoutRect);
721 TableLayout::CalculateStretchCell(const LayoutRect windowRect)
723 __rowStretchable = false;
724 __columnStretchable = false;
726 LayoutItemProxy* pContainerProxy = GetContainerProxy();
727 if (pContainerProxy == null)
729 return E_INVALID_STATE;
732 LayoutRect containerRect;
733 pContainerProxy->ConvertWindowToClientBounds(windowRect, containerRect);
735 LayoutRect layoutRect = GetLayoutRect();
737 float stretchTotalWidth = containerRect.w - layoutRect.w;
738 float stretchTotalHeight = containerRect.h - layoutRect.h;
740 int stretchColumnCount = __stretchColumnCount;
741 int stretchRowCount = __stretchRowCount;
743 int lastStretchRow = 0;
744 int lastStretchColumn = 0;
746 int* pStretchedColumns = null;
747 int* pStretchedRows = null;
749 ProxyListNode* pCurNode = null;
750 TableItemInfo* pItemInfo = null;
752 if (stretchTotalWidth > 0 && __stretchColumnCount > 0)
754 if (pContainerProxy->GetItemWidthMatchMode() == WRAP_CONTENT)
759 __columnStretchable = true;
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.");
764 memset(pStretchedColumns, 0x00, sizeof(int) * __stretchColumnCount);
765 int stretchedColumnCount = 0;
766 bool stretchedItem = true;
768 while (stretchedItem && stretchColumnCount != 0)
770 stretchedItem = false;
771 int stretchWidth = stretchTotalWidth / stretchColumnCount;
773 for (int j = 0; j < __column; j++)
775 if (__pColInfo[j].widthStretchable && !__pColInfo[j].columnCollapsed)
777 float maxWidth = 0.0f;
778 float stretchedColWidth = __pColInfo[j].width;
779 stretchedColWidth += stretchWidth;
780 for (int i = 0; i < __row; i++)
782 pCurNode = GetNode(i, j);
784 if (pCurNode != null)
786 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
788 if (pItemInfo != null && maxWidth < pItemInfo->__maxSize.w)
790 maxWidth = pItemInfo->__maxSize.w;
794 if (maxWidth < stretchedColWidth)
796 stretchWidth -= stretchedColWidth - maxWidth;
797 __pColInfo[j].width += stretchWidth;
798 stretchTotalWidth -= stretchWidth;
799 layoutRect.w += stretchWidth;
800 stretchColumnCount--;
801 __pColInfo[j].widthStretchable = false;
803 pStretchedColumns[stretchedColumnCount++] = j;
804 stretchedItem = true;
811 int nextPosX = -__pColInfo[0].widthSpacing + layoutRect.x;
813 for (int j = 0; j < __column; j++)
815 if (!__pColInfo[j].columnCollapsed)
817 if (__pColInfo[j].widthStretchable && stretchColumnCount != 0)
819 int stretchWidth = stretchTotalWidth / stretchColumnCount;
820 __pColInfo[j].width += stretchWidth;
821 layoutRect.w += stretchWidth;
822 lastStretchColumn = j;
824 __pColInfo[j].x = nextPosX + __pColInfo[j].widthSpacing;
825 nextPosX = __pColInfo[j].x + __pColInfo[j].width;
828 nextPosX = -__pColInfo[0].widthSpacing + layoutRect.x;
829 float stretchWidth = 0.0f;
830 if (!_FloatHardCompare(stretchTotalWidth, 0.0f) && stretchColumnCount)
832 stretchWidth = (int)stretchTotalWidth % stretchColumnCount;
834 bool stretchableColumn = true;
836 while (stretchWidth > 0 && stretchableColumn)
838 stretchableColumn = false;
839 for (int j = 0; j < __column; j++)
841 if (!__pColInfo[j].columnCollapsed)
843 if (stretchColumnCount != 0)
845 if (__pColInfo[j].widthStretchable)
847 for (int i = 0; i < __row; i++)
849 pCurNode = GetNode(i, j);
851 if (pCurNode != null)
853 pItemInfo = (TableItemInfo*) pCurNode->GetItemInfo();
855 if (pItemInfo != null && ((__pColInfo[j].width + 1) > pItemInfo->__maxSize.w) && !pItemInfo->__merged)
857 pStretchedColumns[stretchedColumnCount++] = j;
858 __pColInfo[j].widthStretchable = false;
859 stretchColumnCount--;
864 if (__pColInfo[j].widthStretchable && stretchWidth > 0)
866 if (stretchWidth < 1.0f)
868 __pColInfo[j].width += stretchWidth;
869 layoutRect.w += stretchWidth;
871 stretchableColumn = true;
875 __pColInfo[j].width++;
878 stretchableColumn = true;
883 __pColInfo[j].x = nextPosX + __pColInfo[j].widthSpacing;
884 nextPosX = __pColInfo[j].x + __pColInfo[j].width;
889 for (int j = 0; j < stretchedColumnCount; j++)
891 __pColInfo[pStretchedColumns[j]].widthStretchable = true;
894 delete[] pStretchedColumns;
897 if (stretchTotalHeight > 0 && __stretchRowCount > 0)
899 if (pContainerProxy->GetItemHeightMatchMode() == WRAP_CONTENT)
904 __rowStretchable = true;
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.");
909 memset(pStretchedRows, 0x00, sizeof(int) * __stretchRowCount);
910 int stretchedRowCount = 0;
911 bool stretchedItem = true;
913 while (stretchedItem && stretchRowCount != 0)
915 stretchedItem = false;
916 int stretchHeight = stretchTotalHeight / stretchRowCount;
918 for (int i = 0; i < __row; i++)
920 if (__pRowInfo[i].heightStretchable && !__pRowInfo[i].rowCollapsed)
922 float maxHeight = 0.0f;
923 float stretchedRowHeight = __pRowInfo[i].height;
924 stretchedRowHeight += stretchHeight;
926 for (int j = 0; j < __column; j++)
928 pCurNode = GetNode(i, j);
930 if (pCurNode != null)
932 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
934 if (pItemInfo != null && maxHeight < pItemInfo->__maxSize.h)
936 maxHeight = pItemInfo->__maxSize.h;
940 if (maxHeight < stretchedRowHeight)
942 stretchHeight -= stretchedRowHeight - maxHeight;
943 __pRowInfo[i].height += stretchHeight;
944 stretchTotalHeight -= stretchHeight;
945 layoutRect.h += stretchHeight;
947 __pRowInfo[i].heightStretchable = false;
949 pStretchedRows[stretchedRowCount++] = i;
950 stretchedItem = true;
957 float nextPosY = -__pRowInfo[0].heightSpacing + layoutRect.y;
958 for (int i = 0; i < __row; i++)
960 if (!__pRowInfo[i].rowCollapsed)
962 if (__pRowInfo[i].heightStretchable && stretchRowCount != 0)
964 int stretchHeight = stretchTotalHeight / stretchRowCount;
965 __pRowInfo[i].height += stretchHeight;
966 layoutRect.h += stretchHeight;
969 __pRowInfo[i].y = nextPosY + __pRowInfo[i].heightSpacing;
970 nextPosY = __pRowInfo[i].y + __pRowInfo[i].height;
974 nextPosY = -__pRowInfo[0].heightSpacing + layoutRect.y;
975 float stretchHeight = 0.0f;
976 if (!_FloatHardCompare(stretchTotalHeight, 0.0f) && stretchRowCount != 0)
978 stretchHeight = (int)stretchTotalHeight % stretchRowCount;
980 bool stretchableRow = true;
982 while (stretchHeight > 0 && stretchableRow)
984 stretchableRow = false;
985 for (int i = 0; i < __row; i++)
987 if (!__pRowInfo[i].rowCollapsed)
989 if (stretchRowCount != 0)
991 if (__pRowInfo[i].heightStretchable)
993 for (int j = 0; j < __column; j++)
995 pCurNode = GetNode(i, j);
997 if (pCurNode != null)
999 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1001 if (pItemInfo != null && ((__pRowInfo[i].height + 1) > pItemInfo->__maxSize.h) && !pItemInfo->__merged)
1003 pStretchedRows[stretchedRowCount++] = i;
1004 __pRowInfo[i].heightStretchable = false;
1010 if (__pRowInfo[i].heightStretchable && stretchHeight > 0.0f)
1012 if (stretchHeight < 1.0f)
1014 __pRowInfo[i].height += stretchHeight;
1015 layoutRect.h += stretchHeight;
1016 stretchHeight = 0.0f;
1017 stretchableRow = true;
1021 __pRowInfo[i].height++;
1024 stretchableRow = true;
1029 __pRowInfo[i].y = nextPosY + __pRowInfo[i].heightSpacing;
1030 nextPosY = __pRowInfo[i].y + __pRowInfo[i].height;
1035 for (int i = 0; i < stretchedRowCount; i++)
1037 __pRowInfo[pStretchedRows[i]].heightStretchable = true;
1040 delete[] pStretchedRows;
1042 SetLayoutRect(layoutRect);
1047 TableLayout::Merge(int startRow, int startCol, int endRow, int endCol)
1049 if (startRow < 0 || startRow >= __row || startCol < 0 || startCol >= __column
1050 || endRow < 0 || endRow >= __row || endCol < 0 || endCol >= __column
1051 || startRow > endRow || startCol > endCol)
1053 return E_INVALID_ARG;
1056 int realEndRow = endRow;
1057 int realEndColumn = endCol;
1059 ProxyListNode* pCurNode = null;
1060 TableItemInfo* pItemInfo = null;
1061 for (int i = startRow; i <= realEndRow; i++)
1063 if (__pRowInfo[i].rowCollapsed)
1068 for (int j = startCol; j <= realEndColumn; j++)
1071 int mergedCellIndex = MakeCellID(i, j);
1073 for (k = 0; k < __mergedCellList.GetCount(); k++)
1075 Integer* cellID = static_cast <Integer*>(__mergedCellList.GetAt(k));
1076 if (cellID->ToInt() == mergedCellIndex)
1082 if (i != startRow || j != startCol)
1084 __mergedCellList.Add(*(new Integer(mergedCellIndex)));
1087 pCurNode = GetNode(i, j);
1089 if (pCurNode != null)
1091 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1093 if (pItemInfo == null)
1097 if (pItemInfo->__merged)
1101 if (__pColInfo[j].columnCollapsed)
1106 if (i == startRow && j == startCol)
1108 pItemInfo->__merged = true;
1112 pItemInfo->__enable = false;
1113 pItemInfo->__merged = true;
1114 if (pCurNode->GetItemProxy() != null)
1116 pCurNode->GetItemProxy()->Visible(false);
1121 pCurNode = GetNode(startRow, startCol);
1122 if (pCurNode != null)
1124 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1125 if (pItemInfo == null)
1127 return E_INVALID_STATE;
1129 pItemInfo->__mergeEndPoint.x = realEndRow;
1130 pItemInfo->__mergeEndPoint.y = realEndColumn;
1133 SetUpdateState(true);
1138 TableLayout::OnLayout(float width, float height, bool updateLayouting)
1140 LayoutRect layoutRect = GetLayoutRect();
1141 LayoutRect windowRect = {layoutRect.x, layoutRect.y, width, height};
1143 result r = CalculateSize();
1149 r = CalculateShrinkCell(windowRect);
1155 r = CalculateStretchCell(windowRect);
1161 r = AdjustTableLayout(windowRect, updateLayouting);
1171 TableLayout::AdjustTableLayout(const LayoutRect windowRect, bool updateLayouting)
1173 LayoutItemProxy* pContainerProxy = GetContainerProxy();
1174 if (pContainerProxy == null)
1176 return E_INVALID_STATE;
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++)
1186 for (int j = 0; j < __column; j++)
1188 pCurNode = GetNode(i, j);
1190 if (pCurNode != null)
1192 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1193 pItemProxy = pCurNode->GetItemProxy();
1195 if (pItemInfo != null && pItemInfo->__enable)
1197 size.w = __pColInfo[j].width;
1198 size.h = __pRowInfo[i].height;
1199 if (pItemInfo->__mergeEndPoint.x != NOT_MERGED || pItemInfo->__mergeEndPoint.y != NOT_MERGED)
1201 result r = CalculateMergeCell(i, j, size);
1204 SysLog(NID_UI, "CalculateMergeCell() is Failed.");
1207 if (pItemProxy != null)
1209 LayoutRect rect = pItemProxy->GetItemBaseRect();
1210 rect.x = __pColInfo[j].x;
1211 rect.y = __pRowInfo[i].y;
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;
1219 r = pItemProxy->Measure(rect.w, rect.h);
1224 pItemProxy->GetMeasuredSize(rect.w, rect.h);
1226 if ((__pRowInfo[i].heightShrinkable && __rowShrinkable) ||
1227 (__pRowInfo[i].heightStretchable && __rowStretchable) ||
1228 pItemInfo->__fillHeight)
1230 float height = 0.0f;
1231 r = pItemProxy->Measure(rect.w, cellRect.h);
1236 pItemProxy->GetMeasuredSize(rect.w, height);
1238 if ((__pRowInfo[i].heightShrinkable && __rowShrinkable) && rect.h > height)
1242 else if ((__pRowInfo[i].heightStretchable && __rowStretchable) && rect.h < height)
1246 else if (pItemInfo->__fillHeight)
1252 if ((__pColInfo[j].widthShrinkable && __columnShrinkable) ||
1253 (__pColInfo[j].widthStretchable && __columnStretchable) ||
1254 pItemInfo->__fillWidth)
1257 r = pItemProxy->Measure(cellRect.w, rect.h);
1262 pItemProxy->GetMeasuredSize(width, rect.h);
1264 if ((__pColInfo[j].widthShrinkable && __columnShrinkable) && rect.w > width)
1268 else if ((__pColInfo[j].widthStretchable && __columnStretchable) && rect.w < width)
1272 else if (pItemInfo->__fillWidth)
1278 ItemAlign align = pItemProxy->GetItemAlignment();
1279 rect = CalculateAlign(*pItemProxy, cellRect, rect, align.HAlign, align.VAlign);
1281 r = pItemProxy->Measure(rect.w, rect.h);
1286 pItemProxy->GetMeasuredSize(rect.w, rect.h);
1287 pItemProxy->SetItemWindowRect(rect);
1293 LayoutMatchMode widthMode = pContainerProxy->GetItemWidthMatchMode();
1294 LayoutMatchMode heightMode = pContainerProxy->GetItemHeightMatchMode();
1295 LayoutRect containerRect;
1296 pContainerProxy->ConvertWindowToClientBounds(windowRect, containerRect);
1298 containerRect.x = windowRect.x;
1299 containerRect.y = windowRect.y;
1301 float correctionWidth = windowRect.w - containerRect.w;
1302 float correctionHeight = windowRect.h - containerRect.h;
1304 LayoutRect layoutRect = GetLayoutRect();
1305 if (widthMode == WRAP_CONTENT)
1307 containerRect.w = layoutRect.w + correctionWidth;
1311 containerRect.w += correctionWidth;
1314 if (heightMode == WRAP_CONTENT)
1316 containerRect.h = layoutRect.h + correctionHeight;
1320 containerRect.h += correctionHeight;
1323 SetLayoutRect(containerRect);
1325 LayoutRect clientRect;
1326 pContainerProxy->GetItemWindowRect(clientRect);
1327 containerRect.x = clientRect.x;
1328 containerRect.y = clientRect.y;
1329 if (updateLayouting)
1331 pContainerProxy->SetItemWindowRect(containerRect);
1337 TableLayout::AddItem(LayoutItem& item)
1339 ProxyListNode* pCurNode = null;
1341 int cellIndex = INVALID_CELL_ID;
1342 for (int i = 0; i < __row; i++)
1344 for (int j = 0; j < __column; j++)
1346 pCurNode = GetNode(i, j);
1347 if (pCurNode == null)
1349 if (!__pRowInfo[i].rowCollapsed && !__pColInfo[j].columnCollapsed)
1351 cellIndex = MakeCellID(i, j);
1352 for (int k = 0; k < __mergedCellList.GetCount(); k++)
1354 Integer* cellID = static_cast <Integer*>(__mergedCellList.GetAt(k));
1355 if (cellID->ToInt() == cellIndex)
1357 return AddItem(item, i, j, true);
1361 return AddItem(item, i, j);
1371 TableLayout::AddItem(LayoutItem& item, int row, int column, bool mergedState)
1373 ProxyList* pProxyList = GetProxyList();
1374 SysAssertf(pProxyList != null, "ProxyList is invalid");
1376 if (row < 0 || row >= __row || column < 0 || column >= __column)
1378 return E_INVALID_ARG;
1380 ProxyListNode* pGetNode = GetNode(row, column);
1381 if (pGetNode != null)
1383 return E_INVALID_STATE;
1386 int cellIndex = MakeCellID(row, column);
1390 for (int k = 0; k < __mergedCellList.GetCount(); k++)
1392 Integer* cellID = static_cast <Integer*>(__mergedCellList.GetAt(k));
1393 if (cellID->ToInt() == cellIndex)
1400 result r = Layout::AddItem(item);
1406 ProxyListNode* pAddNode = pProxyList->GetNode(item);
1407 if (pAddNode == null)
1409 return E_INVALID_STATE;
1411 TableItemInfo* pAddItemInfo = static_cast <TableItemInfo*>(pAddNode->GetItemInfo());
1412 if (pAddItemInfo == null)
1414 return E_INVALID_STATE;
1417 cellIndex = MakeCellID(row, column);
1418 pAddItemInfo->__id = cellIndex;
1422 pAddItemInfo->__enable = false;
1423 pAddItemInfo->__merged = true;
1425 if (pAddNode->GetItemProxy() != null)
1427 pAddNode->GetItemProxy()->Visible(false);
1435 TableLayout::GetItem(int row, int column) const
1437 if (row < 0 || row >= __row)
1442 if (column < 0 || column >= __column)
1447 ProxyListNode* pCurNode = GetNode(row, column);
1448 if (pCurNode != null && pCurNode->GetItemProxy() != null)
1450 return pCurNode->GetItemProxy()->GetItem();
1459 TableLayout::SetItemPosition(const LayoutItem& item, int row, int column)
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);
1468 ProxyList* pProxyList = GetProxyList();
1469 SysAssertf(pProxyList != null, "ProxyList is invalid");
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.");
1476 if (pTargetNode == pCurNode)
1481 SysTryReturn(NID_UI, (pTargetNode == null), E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The (%d, %d) cell is not available.", row, column);
1483 int cellIndex = MakeCellID(row, column);
1484 TableItemInfo* pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1485 if (pItemInfo == null)
1487 return E_INVALID_STATE;
1490 if (pItemInfo->__merged || !pItemInfo->__enable)
1492 pItemInfo->__enable = true;
1493 pItemInfo->__merged = false;
1494 if (pCurNode->GetItemProxy() != null)
1496 pCurNode->GetItemProxy()->Visible(true);
1500 pItemInfo->__id = cellIndex;
1502 SetUpdateState(true);
1507 TableLayout::GetItemPosition(const LayoutItem& item, int& row, int& column) const
1509 ProxyList* pProxyList = GetProxyList();
1510 SysAssertf(pProxyList != null, "ProxyList is invalid");
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.");
1516 TableItemInfo* pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1517 if (pItemInfo == null)
1519 return E_INVALID_STATE;
1521 row = (GetRow(pItemInfo->__id));
1522 column = (GetColumn(pItemInfo->__id));
1528 TableLayout::AddRow(void)
1530 if (__row == __maxRow)
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.");
1535 memset(pRowInfo, 0x0, sizeof(RowInfo) * (__maxRow + 1));
1536 memcpy(pRowInfo, __pRowInfo, sizeof(RowInfo) * __maxRow);
1537 delete[] __pRowInfo;
1538 __pRowInfo = pRowInfo;
1546 TableLayout::AddColumn(void)
1548 if (__column == __maxColumn)
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.");
1553 memset(pColInfo, 0x0, sizeof(ColumnInfo) * (__maxColumn + 1));
1554 memcpy(pColInfo, __pColInfo, sizeof(ColumnInfo) * __maxColumn);
1555 delete[] __pColInfo;
1556 __pColInfo = pColInfo;
1564 TableLayout::DeleteRow(int row)
1566 if (row < 0 || row >= __row)
1568 return E_INVALID_ARG;
1571 ProxyListNode* pCurNode = null;
1572 result r = E_SUCCESS;
1573 for (int j = 0; j < __column; j++)
1575 pCurNode = GetNode(row, j);
1576 if (pCurNode != null)
1578 r = RemoveItem(*(pCurNode->GetItemProxy()->GetItem()));
1586 TableItemInfo* pItemInfo = null;
1587 for (int i = 0; i < __row; i++)
1589 for (int j = 0; j < __column; j++)
1591 pCurNode = GetNode(i, j);
1592 if (pCurNode != null)
1594 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1595 if (pItemInfo == null)
1597 return E_INVALID_STATE;
1601 pItemInfo->__id = MakeCellID((i - 1), j);
1603 if (pItemInfo->__mergeEndPoint.x != NOT_MERGED)
1605 if (pItemInfo->__mergeEndPoint.x >= row)
1607 pItemInfo->__mergeEndPoint.x--;
1609 if (pItemInfo->__mergeEndPoint.x == GetRow(pItemInfo->__id))
1611 r = Unmerge(GetRow(pItemInfo->__id), GetColumn(pItemInfo->__id));
1622 memcpy(&__pRowInfo[row], &__pRowInfo[row + 1], sizeof(RowInfo) * (__row - row - 1));
1630 TableLayout::DeleteColumn(int column)
1632 if (column < 0 || column >= __column)
1634 return E_INVALID_ARG;
1637 ProxyListNode* pCurNode = null;
1638 TableItemInfo* pItemInfo = null;
1639 result r = E_SUCCESS;
1640 for (int i = 0; i < __row; i++)
1642 pCurNode = GetNode(i, column);
1643 if (pCurNode != null)
1645 r = RemoveItem(*(pCurNode->GetItemProxy()->GetItem()));
1652 for (int j = 0; j < __column; j++)
1654 pCurNode = GetNode(i, j);
1655 if (pCurNode != null)
1657 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1658 if (pItemInfo == null)
1660 return E_INVALID_STATE;
1664 pItemInfo->__id = MakeCellID(i, (j - 1));
1667 if (pItemInfo->__mergeEndPoint.y != NOT_MERGED)
1669 if (pItemInfo->__mergeEndPoint.y >= column)
1671 pItemInfo->__mergeEndPoint.y--;
1673 int mergeEndColumn = GetColumn(pItemInfo->__id);
1674 if (pItemInfo->__mergeEndPoint.y == mergeEndColumn)
1676 r = Unmerge(GetRow(pItemInfo->__id), GetColumn(pItemInfo->__id));
1687 memcpy(&__pColInfo[column], &__pColInfo[column + 1], sizeof(ColumnInfo) * (__column - column - 1));
1695 TableLayout::CalculateMergeCell(int row, int column, LayoutSize& size)
1697 if (row < 0 || row >= __row || column < 0 || column >= __column)
1699 return E_INVALID_ARG;
1702 ProxyListNode* pCurNode = GetNode(row, column);
1703 if (pCurNode == null)
1705 return E_INVALID_ARG;
1708 TableItemInfo* pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1709 if (pItemInfo == null)
1711 return E_INVALID_STATE;
1713 if (pItemInfo->__mergeEndPoint.x > NOT_MERGED && !__pRowInfo[pItemInfo->__mergeEndPoint.x].rowCollapsed)
1715 int endRowPos = __pRowInfo[pItemInfo->__mergeEndPoint.x].y;
1716 size.h = __pRowInfo[pItemInfo->__mergeEndPoint.x].height + endRowPos - __pRowInfo[row].y;
1720 size.h = __pRowInfo[row].height;
1723 if (pItemInfo->__mergeEndPoint.y > NOT_MERGED && !__pColInfo[pItemInfo->__mergeEndPoint.y].columnCollapsed)
1725 float endColPos = __pColInfo[pItemInfo->__mergeEndPoint.y].x;
1726 size.w = __pColInfo[pItemInfo->__mergeEndPoint.y].width + endColPos - __pColInfo[column].x;
1730 size.w = __pColInfo[column].width;
1737 TableLayout::CalculateAlign(LayoutItemProxy& itemProxy, LayoutRect cellRect, LayoutRect itemRect, const HorizontalAlign horizonAlign, const VerticalAlign verticalAlign)
1739 ItemMargin margin = itemProxy.GetItemMargin();
1740 itemRect.y = cellRect.y;
1741 itemRect.x = cellRect.x;
1743 if (verticalAlign == ITEM_VERTICAL_ALIGN_TOP)
1745 if (itemRect.h > cellRect.h - margin.top - margin.bottom)
1747 itemRect.h = cellRect.h - margin.top - margin.bottom;
1749 itemRect.y = cellRect.y + margin.top;
1751 else if (verticalAlign == ITEM_VERTICAL_ALIGN_BOTTOM)
1753 if (itemRect.h > cellRect.h - margin.top - margin.bottom)
1755 itemRect.h = cellRect.h - margin.top - margin.bottom;
1757 itemRect.y = cellRect.h + cellRect.y - itemRect.h - margin.bottom;
1759 else if (verticalAlign == ITEM_VERTICAL_ALIGN_TOP_BOTTOM)
1761 itemRect.h = cellRect.h - margin.top - margin.bottom;
1762 itemRect.y = cellRect.y + margin.top;
1764 else if (verticalAlign == ITEM_VERTICAL_ALIGN_MIDDLE)
1766 if (cellRect.h > itemRect.h)
1768 itemRect.y = cellRect.y + ((cellRect.h - itemRect.h) / 2);
1772 itemRect.h = cellRect.h;
1775 if (horizonAlign == ITEM_HORIZONTAL_ALIGN_RIGHT)
1777 if (itemRect.w > cellRect.w - margin.right - margin.left)
1779 itemRect.w = cellRect.w - margin.right - margin.left;
1781 itemRect.x = cellRect.w + cellRect.x - itemRect.w - margin.right;
1783 else if (horizonAlign == ITEM_HORIZONTAL_ALIGN_LEFT)
1785 if (itemRect.w > cellRect.w - margin.left - margin.right)
1787 itemRect.w = cellRect.w - margin.left - margin.right;
1789 itemRect.x = cellRect.x + margin.left;
1791 else if (horizonAlign == ITEM_HORIZONTAL_ALIGN_CENTER)
1793 if (cellRect.w > itemRect.w)
1795 itemRect.x = cellRect.x + ((cellRect.w - itemRect.w) / 2);
1799 itemRect.w = cellRect.w;
1802 else if (horizonAlign == ITEM_HORIZONTAL_ALIGN_LEFT_RIGHT)
1804 itemRect.w = cellRect.w - margin.left - margin.right;
1805 itemRect.x = cellRect.x + margin.left;
1812 TableLayout::GetCellSize(int cellIndex, LayoutRect& rect)
1814 if (cellIndex == INVALID_CELL_ID)
1816 return E_INVALID_ARG;
1819 int row = GetRow(cellIndex);
1820 if (row < 0 || row >= __row)
1822 return E_INVALID_ARG;
1825 int column = GetColumn(cellIndex);
1826 if (column < 0 || column >= __column)
1828 return E_INVALID_ARG;
1831 ProxyListNode* pCurNode = GetNode(row, column);
1832 if (pCurNode != null)
1834 TableItemInfo* pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1835 if (pItemInfo == null)
1837 return E_INVALID_STATE;
1839 if (pItemInfo->__mergeEndPoint.x != NOT_MERGED || pItemInfo->__mergeEndPoint.y != NOT_MERGED)
1841 LayoutSize size = {0.0f, 0.0f};
1842 result r = CalculateMergeCell(row, column, size);
1851 rect.h = __pRowInfo[row].height;
1852 rect.w = __pColInfo[column].width;
1856 if (__pRowInfo[row].rowCollapsed)
1861 if (__pColInfo[column].columnCollapsed)
1870 TableLayout::SetColumnCollapsed(int columnIndex, bool collapsed)
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);
1877 __pColInfo[columnIndex].columnCollapsed = collapsed;
1879 ProxyListNode* pCurNode = null;
1880 TableItemInfo* pItemInfo = null;
1881 result r = E_SUCCESS;
1882 for (int i = 0; i < __row; i++)
1884 pCurNode = GetNode(i, columnIndex);
1885 if (pCurNode != null)
1887 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1888 if (pItemInfo == null)
1890 return E_INVALID_STATE;
1892 if (pItemInfo->__merged == true)
1896 if (__pColInfo[columnIndex].columnCollapsed)
1898 pItemInfo->__enable = false;
1899 if (pCurNode->GetItemProxy() != null)
1901 pCurNode->GetItemProxy()->Visible(false);
1904 else if (!__pRowInfo[i].rowCollapsed)
1906 pItemInfo->__enable = true;
1907 if (pCurNode->GetItemProxy() != null)
1909 pCurNode->GetItemProxy()->Visible(true);
1915 SetUpdateState(true);
1920 TableLayout::GetColumnCollapsed(int columnIndex) const
1922 if (columnIndex < 0 || columnIndex >= __column)
1927 return __pColInfo[columnIndex].columnCollapsed;
1931 TableLayout::SetRowCollapsed(int rowIndex, bool collapsed)
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);
1938 __pRowInfo[rowIndex].rowCollapsed = collapsed;
1940 ProxyListNode* pCurNode = null;
1941 TableItemInfo* pItemInfo = null;
1943 for (int i = 0; i < __column; i++)
1945 pCurNode = GetNode(rowIndex, i);
1946 if (pCurNode != null)
1948 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1949 if (pItemInfo == null)
1951 return E_INVALID_STATE;
1953 if (pItemInfo->__merged == true)
1957 if (__pRowInfo[rowIndex].rowCollapsed)
1959 pItemInfo->__enable = false;
1960 if (pCurNode->GetItemProxy() != null)
1962 pCurNode->GetItemProxy()->Visible(false);
1965 else if (!__pColInfo[i].columnCollapsed)
1967 pItemInfo->__enable = true;
1968 if (pCurNode->GetItemProxy() != null)
1970 pCurNode->GetItemProxy()->Visible(true);
1976 SetUpdateState(true);
1981 TableLayout::GetRowCollapsed(int rowIndex) const
1983 if (rowIndex < 0 || rowIndex >= __row)
1988 return __pRowInfo[rowIndex].rowCollapsed;
1992 TableLayout::SetRowShrinkable(int row, bool shrinkable)
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);
1999 __pRowInfo[row].heightShrinkable = shrinkable;
2001 SetUpdateState(true);
2002 SetPartialUpdateFlag(true);
2007 TableLayout::GetRowShrinkable(int row) const
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);
2013 return __pRowInfo[row].heightShrinkable;
2017 TableLayout::SetColumnShrinkable(int column, bool shrinkable)
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);
2024 __pColInfo[column].widthShrinkable = shrinkable;
2026 SetUpdateState(true);
2027 SetPartialUpdateFlag(true);
2032 TableLayout::GetColumnShrinkable(int column) const
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);
2039 return __pColInfo[column].widthShrinkable;
2043 TableLayout::SetRowStretchable(int row, bool stretchable)
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);
2050 __pRowInfo[row].heightStretchable = stretchable;
2052 SetUpdateState(true);
2053 SetPartialUpdateFlag(true);
2058 TableLayout::GetRowStretchable(int row) const
2060 if (row < 0 || row >= __row)
2065 return __pRowInfo[row].heightStretchable;
2069 TableLayout::SetColumnStretchable(int column, bool stretchable)
2071 SysTryReturn(NID_UI, column >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] Negative input argument : column(%d)",
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);
2076 __pColInfo[column].widthStretchable = stretchable;
2078 SetUpdateState(true);
2079 SetPartialUpdateFlag(true);
2084 TableLayout::GetColumnStretchable(int column) const
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);
2090 return __pColInfo[column].widthStretchable;
2094 TableLayout::SetRowSpacing(int row, float heightSpacing)
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);
2103 __pRowInfo[row].heightSpacing = heightSpacing;
2105 SetUpdateState(true);
2110 TableLayout::GetRowSpacing(int row, float& spacing) const
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);
2117 spacing = __pRowInfo[row].heightSpacing;
2122 TableLayout::SetColumnSpacing(int column, float widthSpacing)
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);
2131 __pColInfo[column].widthSpacing = widthSpacing;
2133 SetUpdateState(true);
2138 TableLayout::GetColumnSpacing(int column, float& spacing) const
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);
2145 spacing = __pColInfo[column].widthSpacing;
2151 TableLayout::SetFillCell(int row, int column, bool fillWidth, bool fillHeight)
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);
2162 ProxyListNode* pNode = GetNode(row, column);
2165 TableItemInfo* pItemInfo = static_cast <TableItemInfo*>(pNode->GetItemInfo());
2166 if (pItemInfo == null)
2168 return E_INVALID_STATE;
2170 pItemInfo->__fillWidth = fillWidth;
2171 pItemInfo->__fillHeight = fillHeight;
2178 TableLayout::GetFillCell(int row, int column, bool& fillWidth, bool& fillHeight) const
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);
2189 ProxyListNode* pNode = GetNode(row, column);
2192 TableItemInfo* pItemInfo = static_cast <TableItemInfo*>(pNode->GetItemInfo());
2193 if (pItemInfo == null)
2195 return E_INVALID_STATE;
2197 fillWidth = pItemInfo->__fillWidth;
2198 fillHeight = pItemInfo->__fillHeight;
2205 TableLayout::SwapItemPosition(LayoutItem& item1, LayoutItem& item2)
2207 ProxyList* pProxyList = GetProxyList();
2208 SysAssertf(pProxyList != null, "ProxyList is invalid");
2210 ProxyListNode* pNode1 = pProxyList->GetNode(item1);
2211 ProxyListNode* pNode2 = pProxyList->GetNode(item2);
2213 SysTryReturn(NID_UI, (pNode1 != null && pNode2 != null), E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.")
2215 TableItemInfo* pItemInfo1 = static_cast <TableItemInfo*>(pNode1->GetItemInfo());
2216 TableItemInfo* pItemInfo2 = static_cast <TableItemInfo*>(pNode2->GetItemInfo());
2217 if (pItemInfo1 == null || pItemInfo2 == null)
2219 return E_INVALID_STATE;
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;
2229 pItemInfo1->__id = cellIndex2;
2230 pItemInfo2->__id = cellIndex1;
2231 pItemInfo1->__merged = merged2;
2232 pItemInfo2->__merged = merged1;
2233 pItemInfo1->__enable = enable2;
2234 pItemInfo2->__enable = enable1;
2236 if (pNode1->GetItemProxy() != null)
2238 if (pItemInfo1->__merged || !pItemInfo1->__enable)
2240 pNode1->GetItemProxy()->Visible(false);
2244 pNode1->GetItemProxy()->Visible(true);
2248 if (pNode2->GetItemProxy() != null)
2250 if (pItemInfo2->__merged || !pItemInfo2->__enable)
2252 pNode2->GetItemProxy()->Visible(false);
2256 pNode2->GetItemProxy()->Visible(true);
2260 SetUpdateState(true);
2265 TableLayout::Unmerge(int row, int column)
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);
2277 ProxyListNode* pCurNode = null;
2278 TableItemInfo* pItemInfo = null;
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);
2283 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
2284 if (pItemInfo == null)
2286 return E_INVALID_STATE;
2288 endRow = pItemInfo->__mergeEndPoint.x;
2289 endColumn = pItemInfo->__mergeEndPoint.y;
2291 if (pItemInfo->__enable == false || pItemInfo->__merged == false
2292 || endRow == NOT_MERGED || endColumn == NOT_MERGED)
2294 return E_INVALID_STATE;
2297 pItemInfo->__mergeEndPoint.x = NOT_MERGED;
2298 pItemInfo->__mergeEndPoint.y = NOT_MERGED;
2300 for (int i = row; i <= endRow; i++)
2302 for (int j = column; j <= endColumn; j++)
2304 pCurNode = GetNode(i, j);
2305 if (pCurNode != null)
2307 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
2308 if (pItemInfo == null)
2310 return E_INVALID_STATE;
2312 pItemInfo->__enable = true;
2313 pItemInfo->__merged = false;
2315 for (int k = 0; k < __mergedCellList.GetCount(); k++)
2317 Integer* cellID = static_cast <Integer*>(__mergedCellList.GetAt(k));
2318 if (cellID->ToInt() == MakeCellID(i, j))
2320 __mergedCellList.RemoveAt(k, true);
2325 if (pCurNode->GetItemProxy() != null)
2327 pCurNode->GetItemProxy()->Visible(true);
2333 SetUpdateState(true);
2338 TableLayout::GetMergeSize(int row, int column, int& rowSize, int& colSize) const
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);
2352 ProxyListNode* pNode = GetNode(row, column);
2359 TableItemInfo* pItemInfo = static_cast <TableItemInfo*>(pNode->GetItemInfo());
2360 if (pItemInfo == null || pItemInfo->__enable == false)
2362 return E_INVALID_STATE;
2365 if (pItemInfo->__merged == false)
2372 rowSize = pItemInfo->__mergeEndPoint.x - row + 1;
2373 colSize = pItemInfo->__mergeEndPoint.y - column + 1;
2380 TableLayout::GetNode(int row, int column) const
2382 ProxyList* pProxyList = GetProxyList();
2383 SysAssertf(pProxyList != null, "ProxyList is invalid");
2385 ProxyListNode* pCurNode = pProxyList->GetFirstNode();
2386 TableItemInfo* pItemInfo = null;
2388 int columnIndex = 0;
2391 pItemInfo = static_cast <TableItemInfo*>(pCurNode->GetItemInfo());
2392 if (pItemInfo != null)
2394 rowIndex = GetRow(pItemInfo->__id);
2395 columnIndex = GetColumn(pItemInfo->__id);
2396 if (row == rowIndex && column == columnIndex)
2401 pCurNode = pProxyList->GetNextNode(*pCurNode);
2407 TableLayout::GetRow(int id) const
2413 TableLayout::GetColumn(int id) const
2415 return id & 0x0000FFFF;
2419 TableLayout::MakeCellID(int row, int column) const
2421 return (row << 16) | (column & 0x0000FFFF);
2424 } // Tizen::Ui::_Layout