2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://floralicense.org/license/
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>
29 #include "FUi_LayoutTableLayout.h"
30 #include "FUi_LayoutLayoutItemProxy.h"
31 #include "FUi_LayoutProxyList.h"
32 #include "FUi_LayoutLayoutItemInfo.h"
34 using namespace Tizen::Base;
36 namespace Tizen { namespace Ui { namespace _Layout
39 TableLayout::TableLayout(void)
46 , __shrinkColumnCount(0)
47 , __stretchRowCount(0)
48 , __stretchColumnCount(0)
49 , __rowShrinkable(false)
50 , __columnShrinkable(false)
51 , __rowStretchable(false)
52 , __columnStretchable(false)
56 TableProxyList* pTableProxyList = new (std::nothrow) TableProxyList();
57 SysTryReturnVoidResult(NID_UI, pTableProxyList, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
58 SetItemList(pTableProxyList);
61 TableLayout::~TableLayout(void)
63 __mergedCellList.RemoveAll(true);
70 TableLayout::CreateTableLayoutN(void)
72 TableLayout* pLayout = new (std::nothrow) TableLayout();
73 SysTryReturn(NID_UI, pLayout != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Table layout core allocation failure.");
74 if (GetLastResult() != E_SUCCESS)
84 TableLayout::CreateTable(int row, int column, int spacing)
86 if (row < 1 || column < 1)
88 SysTryReturn(NID_UI, false, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Negative argument : row(%d), column(%d)", row,
97 __pColInfo = new (std::nothrow) ColumnInfo[__column];
98 SysTryReturn(NID_UI, __pColInfo != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
100 memset(__pColInfo, 0, sizeof(ColumnInfo) * __column);
102 for (int i = 0; i < __column; i++)
104 __pColInfo[i].widthSpacing = spacing;
107 __pRowInfo = new (std::nothrow) RowInfo[__row];
108 SysTryReturn(NID_UI, __pRowInfo != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
110 memset(__pRowInfo, 0, sizeof(RowInfo) * __row);
112 for (int i = 0; i < __row; i++)
114 __pRowInfo[i].heightSpacing = spacing;
121 TableLayout::CalculateSize()
123 if (__row < 1 || __column < 1)
128 int nextPosX = 0; //-__pColInfo[0].widthSpacing + m_nPosX;
129 int nextPosY = 0; //-__pRowInfo[0].heightSpacing + m_nPosY;
131 __shrinkRowCount = 0;
132 __shrinkColumnCount = 0;
133 __stretchRowCount = 0;
134 __stretchColumnCount = 0;
136 for (int j = 0; j < __column; j++)
139 __pColInfo[j].width = 0;
140 __pColInfo[j].maxWidth = 0;
141 __pColInfo[j].mergedWidth = 0;
144 ProxyListNode* pCurNode = null;
145 TableItemInfo* pItemInfo = null;
146 LayoutItemProxy* pItemProxy = null;
148 for (int i = 0; i < __row; i++)
151 __pRowInfo[i].height = 0;
152 __pRowInfo[i].maxHeight = 0;
153 __pRowInfo[i].mergedHeight = 0;
155 for (int j = 0; j < __column; j++)
157 pCurNode = GetNode(i, j);
158 if (pCurNode != null)
160 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
162 pItemProxy = pCurNode->GetItemProxy();
163 if (pItemInfo == null || pItemProxy == null)
165 return E_INVALID_STATE;
168 if (pItemInfo->__enable)
170 pItemProxy->GetMinSize(pItemInfo->__minSize);
171 pItemProxy->GetMaxSize(pItemInfo->__maxSize);
174 LayoutRect rect = pItemProxy->GetItemBaseRect();
176 result r = pItemProxy->Measure(rect.w, rect.h);
181 pItemProxy->GetMeasuredSize(rect.w, rect.h);
183 ItemMargin margin = pItemProxy->GetItemMargin();
184 ItemAlign itemAlign = pItemProxy->GetItemAlignment();
185 if (itemAlign.HAlign == ITEM_HORIZONTAL_ALIGN_LEFT || itemAlign.HAlign == ITEM_HORIZONTAL_ALIGN_LEFT_RIGHT)
187 rect.w += margin.left;
189 if (itemAlign.HAlign == ITEM_HORIZONTAL_ALIGN_RIGHT || itemAlign.HAlign == ITEM_HORIZONTAL_ALIGN_LEFT_RIGHT)
191 rect.w += margin.right;
193 if (itemAlign.VAlign == ITEM_VERTICAL_ALIGN_TOP || itemAlign.VAlign == ITEM_VERTICAL_ALIGN_TOP_BOTTOM)
195 rect.h += margin.top;
197 if (itemAlign.VAlign == ITEM_VERTICAL_ALIGN_BOTTOM || itemAlign.VAlign == ITEM_VERTICAL_ALIGN_TOP_BOTTOM)
199 rect.h += margin.bottom;
202 if (!pItemInfo->__merged)
204 if (__pColInfo[j].maxWidth < rect.w && !__pRowInfo[i].rowCollapsed)
206 __pColInfo[j].maxWidth = rect.w;
209 if (__pRowInfo[i].maxHeight < rect.h && !__pColInfo[j].columnCollapsed)
211 __pRowInfo[i].maxHeight = rect.h;
216 if (__pColInfo[j].mergedWidth < rect.w)
218 __pColInfo[j].mergedWidth = rect.w;
220 if (__pRowInfo[i].mergedHeight < rect.h)
222 __pRowInfo[i].mergedHeight = rect.h;
228 if (!__pRowInfo[i].rowCollapsed)
230 if (__pRowInfo[i].heightStretchable)
234 if (__pRowInfo[i].heightShrinkable)
239 if (__pRowInfo[i].maxHeight != 0)
241 __pRowInfo[i].height = __pRowInfo[i].maxHeight;
246 for (int j = 0; j < __column; j++)
248 if (!__pColInfo[j].columnCollapsed)
250 if (__pColInfo[j].widthStretchable)
252 __stretchColumnCount++;
254 if (__pColInfo[j].widthShrinkable)
256 __shrinkColumnCount++;
259 if (__pColInfo[j].maxWidth != 0)
261 __pColInfo[j].width = __pColInfo[j].maxWidth;
270 int mergedHeight = 0;
272 for (int i = __row - 1; i >= 0; i--)
274 if (!__pRowInfo[i].rowCollapsed)
276 for (int j = __column - 1; j >= 0; j--)
278 if (!__pColInfo[j].columnCollapsed)
280 pCurNode = GetNode(i, j);
281 if (pCurNode != null)
283 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
284 if (pItemInfo == null)
286 return E_INVALID_STATE;
288 pItemProxy = pCurNode->GetItemProxy();
289 if (pItemInfo->__mergeEndPoint.x != NOT_MERGED)
293 int endRow = pItemInfo->__mergeEndPoint.x;
294 int endColumn = pItemInfo->__mergeEndPoint.y;
296 pItemProxy->GetMeasuredSize(mergedWidth, mergedHeight);
298 int rowHeightSum = 0;
301 rowHeightSum -= __pRowInfo[startRow].heightSpacing;
303 for (int k = startRow; k <= endRow; k++)
305 rowHeightSum += __pRowInfo[k].height + __pRowInfo[k].heightSpacing;
307 if (mergedHeight > rowHeightSum)
309 __pRowInfo[startRow].height += mergedHeight - rowHeightSum;
313 if (startColumn == 0)
315 colWidthSum -= __pColInfo[startColumn].widthSpacing;
317 for (int k = startColumn; k <= endColumn; k++)
319 colWidthSum += __pColInfo[k].width + __pColInfo[k].widthSpacing;
321 if (mergedWidth > colWidthSum)
323 __pColInfo[startColumn].width += mergedWidth - colWidthSum;
332 LayoutRect layoutRect = GetLayoutRect();
333 nextPosY = -__pRowInfo[0].heightSpacing + layoutRect.y;
334 for (int i = 0; i < __row; i++)
336 nextPosX = -__pColInfo[0].widthSpacing + layoutRect.x;
337 if (!__pRowInfo[i].rowCollapsed)
339 for (int j = 0; j < __column; j++)
341 if (!__pColInfo[j].columnCollapsed)
343 __pColInfo[j].x = nextPosX + __pColInfo[j].widthSpacing;
344 nextPosX = __pColInfo[j].x + __pColInfo[j].width;
347 __pRowInfo[i].y = nextPosY + __pRowInfo[i].heightSpacing;
348 nextPosY = __pRowInfo[i].y + __pRowInfo[i].height;
352 layoutRect.w = nextPosX;
353 layoutRect.h = nextPosY;
354 SetLayoutRect(layoutRect);
360 TableLayout::CalculateShrinkCell(const LayoutRect windowRect)
362 __rowShrinkable = false;
363 __columnShrinkable = false;
365 LayoutItemProxy* pContainerProxy = GetContainerProxy();
366 if (pContainerProxy == null)
368 return E_INVALID_STATE;
371 LayoutRect containerRect;
372 pContainerProxy->ConvertWindowToClientBounds(windowRect, containerRect);
374 LayoutRect layoutRect = GetLayoutRect();
376 int shrinkTotalWidth = layoutRect.w - containerRect.w;
377 int shrinkTotalHeight = layoutRect.h - containerRect.h;
379 int shrinkColumnCount = __shrinkColumnCount;
380 int shrinkRowCount = __shrinkRowCount;
382 int* pShrinkedColumns = null;
383 int* pShrinkedRows = null;
385 int lastShrinkRow = 0;
386 int lastShrinkColumn = 0;
388 ProxyListNode* pCurNode = null;
389 TableItemInfo* pItemInfo = null;
391 if (shrinkTotalWidth > 0 && __shrinkColumnCount > 0)
393 if (pContainerProxy->GetItemWidthMatchMode() == WRAP_CONTENT)
398 __columnShrinkable = true;
400 pShrinkedColumns = new (std::nothrow) int[__shrinkColumnCount];
401 SysTryReturn(NID_UI, pShrinkedColumns != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
403 memset(pShrinkedColumns, 0x00, sizeof(int) * __shrinkColumnCount);
405 int shrinkedColumnCount = 0;
406 bool shrinkedItem = true;
408 while (shrinkedItem && shrinkColumnCount != 0)
410 shrinkedItem = false;
412 for (int j = 0; j < __column; j++)
414 int shrinkWidth = shrinkTotalWidth / shrinkColumnCount;
415 int shrinkedColWidth = __pColInfo[j].width;
417 if (__pColInfo[j].widthShrinkable && !__pColInfo[j].columnCollapsed)
419 shrinkedColWidth -= shrinkWidth;
421 if (shrinkedColWidth < 0)
423 shrinkWidth += shrinkedColWidth;
425 __pColInfo[j].width = 0;
426 shrinkedColWidth = 0;
427 __pColInfo[j].widthShrinkable = false;
431 for (int i = 0; i < __row; i++)
433 pCurNode = GetNode(i, j);
435 if (pCurNode != null)
437 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
439 if (pItemInfo != null && shrinkedColWidth < pItemInfo->__minSize.w)
441 shrinkWidth -= pItemInfo->__minSize.w - shrinkedColWidth;
442 __pColInfo[j].width = pItemInfo->__minSize.w;
443 __pColInfo[j].widthShrinkable = false;
447 if (__pColInfo[j].widthShrinkable == false)
449 shrinkTotalWidth -= shrinkWidth;
450 layoutRect.w -= shrinkWidth;
453 pShrinkedColumns[shrinkedColumnCount++] = j;
462 int nextPosX = -__pColInfo[0].widthSpacing + layoutRect.x;
464 for (int j = 0; j < __column; j++)
466 __pColInfo[j].x = nextPosX + __pColInfo[j].widthSpacing;
468 if (!__pColInfo[j].columnCollapsed)
470 if (shrinkColumnCount != 0)
472 int shrinkWidth = shrinkTotalWidth / shrinkColumnCount;
474 if (__pColInfo[j].widthShrinkable)
476 __pColInfo[j].width -= shrinkWidth;
477 lastShrinkColumn = j;
478 layoutRect.w -= shrinkWidth;
481 nextPosX = __pColInfo[j].width + __pColInfo[j].x;
485 nextPosX = -__pColInfo[0].widthSpacing + layoutRect.x;
487 if (shrinkTotalWidth != 0 && shrinkColumnCount != 0)
489 shrinkWidth = shrinkTotalWidth % shrinkColumnCount;
491 bool shrinkableColumn = true;
493 while (shrinkWidth > 0 && shrinkableColumn)
495 shrinkableColumn = false;
496 for (int j = 0; j < __column; j++)
498 __pColInfo[j].x = nextPosX + __pColInfo[j].widthSpacing;
500 if (!__pColInfo[j].columnCollapsed)
502 if (shrinkColumnCount != 0)
504 if (__pColInfo[j].widthShrinkable)
506 for (int i = 0; i < __row; i++)
508 pCurNode = GetNode(i, j);
510 if (pCurNode != null)
512 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
514 if ((pItemInfo != null && ((__pColInfo[j].width - 1) < pItemInfo->__minSize.w)) || (__pColInfo[j].width - 1) < 0)
516 pShrinkedColumns[shrinkedColumnCount++] = j;
517 __pColInfo[j].widthShrinkable = false;
523 if (__pColInfo[j].widthShrinkable && shrinkWidth > 0)
525 __pColInfo[j].width--;
528 shrinkableColumn = true;
532 nextPosX = __pColInfo[j].width + __pColInfo[j].x;
537 for (int j = 0; j < shrinkedColumnCount; j++)
539 __pColInfo[pShrinkedColumns[j]].widthShrinkable = true;
542 delete[] pShrinkedColumns;
545 if (shrinkTotalHeight > 0 && __shrinkRowCount > 0)
547 if (pContainerProxy->GetItemHeightMatchMode() == WRAP_CONTENT)
552 __rowShrinkable = true;
554 pShrinkedRows = new (std::nothrow) int[__shrinkRowCount];
555 SysTryReturn(NID_UI, pShrinkedRows != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
557 memset(pShrinkedRows, 0x00, sizeof(int) * __shrinkRowCount);
558 int shrinkedRowCount = 0;
559 bool shrinkedItem = true;
561 while (shrinkedItem && shrinkRowCount != 0)
563 shrinkedItem = false;
565 for (int i = 0; i < __row; i++)
567 int shrinkHeight = shrinkTotalHeight / shrinkRowCount;
568 int shrinkedRowHeight = __pRowInfo[i].height;
570 if (__pRowInfo[i].heightShrinkable && !__pRowInfo[i].rowCollapsed)
572 shrinkedRowHeight -= shrinkHeight;
574 if (shrinkedRowHeight < 0)
576 shrinkHeight += shrinkedRowHeight;
578 __pRowInfo[i].height = 0;
579 shrinkedRowHeight = 0;
580 __pRowInfo[i].heightShrinkable = false;
584 for (int j = 0; j < __column; j++)
586 pCurNode = GetNode(i, j);
588 if (pCurNode != null)
590 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
592 if (pItemInfo != null && shrinkedRowHeight < pItemInfo->__minSize.h)
594 shrinkHeight -= pItemInfo->__minSize.h - shrinkedRowHeight;
595 __pRowInfo[i].height = pItemInfo->__minSize.h;
596 __pRowInfo[i].heightShrinkable = false;
600 if (__pRowInfo[i].heightShrinkable == false)
602 shrinkTotalHeight -= shrinkHeight;
603 layoutRect.h -= shrinkHeight;
606 pShrinkedRows[shrinkedRowCount++] = i;
615 int nextPosY = -__pRowInfo[0].heightSpacing + layoutRect.y;
617 for (int i = 0; i < __row; i++)
619 if (!__pRowInfo[i].rowCollapsed)
621 if (shrinkRowCount != 0)
623 int shrinkHeight = shrinkTotalHeight / shrinkRowCount;
625 if (__pRowInfo[i].heightShrinkable)
627 __pRowInfo[i].height -= shrinkHeight;
629 layoutRect.h -= shrinkHeight;
632 __pRowInfo[i].y = nextPosY + __pRowInfo[i].heightSpacing;
633 nextPosY = __pRowInfo[i].height + __pRowInfo[i].y;
637 nextPosY = -__pRowInfo[0].heightSpacing + layoutRect.y;
638 int shrinkHeight = 0;
639 if (shrinkTotalHeight != 0 && shrinkRowCount != 0)
641 shrinkHeight = shrinkTotalHeight % shrinkRowCount;
643 bool shrinkableRow = true;
645 while (shrinkHeight > 0 && shrinkableRow)
647 shrinkableRow = false;
648 for (int i = 0; i < __row; i++)
650 if (!__pRowInfo[i].rowCollapsed)
652 if (shrinkRowCount != 0)
654 if (__pRowInfo[i].heightShrinkable)
656 for (int j = 0; j < __column; j++)
658 pCurNode = GetNode(i, j);
660 if (pCurNode != null)
662 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
664 if ((pItemInfo != null && ((__pRowInfo[i].height - 1) < pItemInfo->__minSize.h)) || (__pRowInfo[i].height - 1) < 0)
666 pShrinkedRows[shrinkedRowCount++] = i;
667 __pRowInfo[i].heightShrinkable = false;
673 if (__pRowInfo[i].heightShrinkable && shrinkHeight > 0)
675 __pRowInfo[i].height--;
678 shrinkableRow = true;
682 __pRowInfo[i].y = nextPosY + __pRowInfo[i].heightSpacing;
683 nextPosY = __pRowInfo[i].height + __pRowInfo[i].y;
688 for (int i = 0; i < shrinkedRowCount; i++)
690 __pRowInfo[pShrinkedRows[i]].heightShrinkable = true;
693 delete[] pShrinkedRows;
695 SetLayoutRect(layoutRect);
700 TableLayout::CalculateStretchCell(const LayoutRect windowRect)
702 __rowStretchable = false;
703 __columnStretchable = false;
705 LayoutItemProxy* pContainerProxy = GetContainerProxy();
706 if (pContainerProxy == null)
708 return E_INVALID_STATE;
711 LayoutRect containerRect;
712 pContainerProxy->ConvertWindowToClientBounds(windowRect, containerRect);
714 LayoutRect layoutRect = GetLayoutRect();
716 int stretchTotalWidth = containerRect.w - layoutRect.w;
717 int stretchTotalHeight = containerRect.h - layoutRect.h;
719 int stretchColumnCount = __stretchColumnCount;
720 int stretchRowCount = __stretchRowCount;
722 int lastStretchRow = 0;
723 int lastStretchColumn = 0;
725 int* pStretchedColumns = null;
726 int* pStretchedRows = null;
728 ProxyListNode* pCurNode = null;
729 TableItemInfo* pItemInfo = null;
731 if (stretchTotalWidth > 0 && __stretchColumnCount > 0)
733 if (pContainerProxy->GetItemWidthMatchMode() == WRAP_CONTENT)
738 __columnStretchable = true;
740 pStretchedColumns = new (std::nothrow) int[__stretchColumnCount];
741 SysTryReturn(NID_UI, pStretchedColumns != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
743 memset(pStretchedColumns, 0x00, sizeof(int) * __stretchColumnCount);
744 int stretchedColumnCount = 0;
745 bool stretchedItem = true;
747 while (stretchedItem && stretchColumnCount != 0)
749 stretchedItem = false;
750 int stretchWidth = stretchTotalWidth / stretchColumnCount;
752 for (int j = 0; j < __column; j++)
754 if (__pColInfo[j].widthStretchable && !__pColInfo[j].columnCollapsed)
757 int stretchedColWidth = __pColInfo[j].width;
758 stretchedColWidth += stretchWidth;
759 for (int i = 0; i < __row; i++)
761 pCurNode = GetNode(i, j);
763 if (pCurNode != null)
765 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
767 if (pItemInfo != null && maxWidth < pItemInfo->__maxSize.w)
769 maxWidth = pItemInfo->__maxSize.w;
773 if (maxWidth < stretchedColWidth)
775 stretchWidth -= stretchedColWidth - maxWidth;
776 __pColInfo[j].width += stretchWidth;
777 stretchTotalWidth -= stretchWidth;
778 layoutRect.w += stretchWidth;
779 stretchColumnCount--;
780 __pColInfo[j].widthStretchable = false;
782 pStretchedColumns[stretchedColumnCount++] = j;
783 stretchedItem = true;
790 int nextPosX = -__pColInfo[0].widthSpacing + layoutRect.x;
792 for (int j = 0; j < __column; j++)
794 if (!__pColInfo[j].columnCollapsed)
796 if (__pColInfo[j].widthStretchable && stretchColumnCount != 0)
798 int stretchWidth = stretchTotalWidth / stretchColumnCount;
799 __pColInfo[j].width += stretchWidth;
800 layoutRect.w += stretchWidth;
801 lastStretchColumn = j;
803 __pColInfo[j].x = nextPosX + __pColInfo[j].widthSpacing;
804 nextPosX = __pColInfo[j].x + __pColInfo[j].width;
807 nextPosX = -__pColInfo[0].widthSpacing + layoutRect.x;
808 int stretchWidth = 0;
809 if (stretchTotalWidth != 0 && stretchColumnCount != 0)
811 stretchWidth = stretchTotalWidth % stretchColumnCount;
813 bool stretchableColumn = true;
815 while (stretchWidth > 0 && stretchableColumn)
817 stretchableColumn = false;
818 for (int j = 0; j < __column; j++)
820 if (!__pColInfo[j].columnCollapsed)
822 if (stretchColumnCount != 0)
824 if (__pColInfo[j].widthStretchable)
826 for (int i = 0; i < __row; i++)
828 pCurNode = GetNode(i, j);
830 if (pCurNode != null)
832 pItemInfo = (TableItemInfo*) pCurNode->GetItemInfo();
834 if (pItemInfo != null && ((__pColInfo[j].width + 1) > pItemInfo->__maxSize.w) && !pItemInfo->__merged)
836 pStretchedColumns[stretchedColumnCount++] = j;
837 __pColInfo[j].widthStretchable = false;
838 stretchColumnCount--;
843 if (__pColInfo[j].widthStretchable && stretchWidth > 0)
845 __pColInfo[j].width++;
848 stretchableColumn = true;
852 __pColInfo[j].x = nextPosX + __pColInfo[j].widthSpacing;
853 nextPosX = __pColInfo[j].x + __pColInfo[j].width;
858 for (int j = 0; j < stretchedColumnCount; j++)
860 __pColInfo[pStretchedColumns[j]].widthStretchable = true;
863 delete[] pStretchedColumns;
866 if (stretchTotalHeight > 0 && __stretchRowCount > 0)
868 if (pContainerProxy->GetItemHeightMatchMode() == WRAP_CONTENT)
873 __rowStretchable = true;
875 pStretchedRows = new (std::nothrow) int[__stretchRowCount];
876 SysTryReturn(NID_UI, pStretchedRows != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
878 memset(pStretchedRows, 0x00, sizeof(int) * __stretchRowCount);
879 int stretchedRowCount = 0;
880 bool stretchedItem = true;
882 while (stretchedItem && stretchRowCount != 0)
884 stretchedItem = false;
885 int stretchHeight = stretchTotalHeight / stretchRowCount;
887 for (int i = 0; i < __row; i++)
889 if (__pRowInfo[i].heightStretchable && !__pRowInfo[i].rowCollapsed)
892 int stretchedRowHeight = __pRowInfo[i].height;
893 stretchedRowHeight += stretchHeight;
895 for (int j = 0; j < __column; j++)
897 pCurNode = GetNode(i, j);
899 if (pCurNode != null)
901 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
903 if (pItemInfo != null && maxHeight < pItemInfo->__maxSize.h)
905 maxHeight = pItemInfo->__maxSize.h;
909 if (maxHeight < stretchedRowHeight)
911 stretchHeight -= stretchedRowHeight - maxHeight;
912 __pRowInfo[i].height += stretchHeight;
913 stretchTotalHeight -= stretchHeight;
914 layoutRect.h += stretchHeight;
916 __pRowInfo[i].heightStretchable = false;
918 pStretchedRows[stretchedRowCount++] = i;
919 stretchedItem = true;
926 int nextPosY = -__pRowInfo[0].heightSpacing + layoutRect.y;
927 for (int i = 0; i < __row; i++)
929 if (!__pRowInfo[i].rowCollapsed)
931 if (__pRowInfo[i].heightStretchable && stretchRowCount != 0)
933 int stretchHeight = stretchTotalHeight / stretchRowCount;
934 __pRowInfo[i].height += stretchHeight;
935 layoutRect.h += stretchHeight;
938 __pRowInfo[i].y = nextPosY + __pRowInfo[i].heightSpacing;
939 nextPosY = __pRowInfo[i].y + __pRowInfo[i].height;
943 nextPosY = -__pRowInfo[0].heightSpacing + layoutRect.y;
944 int stretchHeight = 0;
945 if (stretchTotalHeight != 0 && stretchRowCount != 0)
947 stretchHeight = stretchTotalHeight % stretchRowCount;
949 bool stretchableRow = true;
951 while (stretchHeight > 0 && stretchableRow)
953 stretchableRow = false;
954 for (int i = 0; i < __row; i++)
956 if (!__pRowInfo[i].rowCollapsed)
958 if (stretchRowCount != 0)
960 if (__pRowInfo[i].heightStretchable)
962 for (int j = 0; j < __column; j++)
964 pCurNode = GetNode(i, j);
966 if (pCurNode != null)
968 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
970 if (pItemInfo != null && ((__pRowInfo[i].height + 1) > pItemInfo->__maxSize.h) && !pItemInfo->__merged)
972 pStretchedRows[stretchedRowCount++] = i;
973 __pRowInfo[i].heightStretchable = false;
979 if (__pRowInfo[i].heightStretchable && stretchHeight > 0)
981 __pRowInfo[i].height++;
984 stretchableRow = true;
988 __pRowInfo[i].y = nextPosY + __pRowInfo[i].heightSpacing;
989 nextPosY = __pRowInfo[i].y + __pRowInfo[i].height;
994 for (int i = 0; i < stretchedRowCount; i++)
996 __pRowInfo[pStretchedRows[i]].heightStretchable = true;
999 delete[] pStretchedRows;
1001 SetLayoutRect(layoutRect);
1006 TableLayout::Merge(int startRow, int startCol, int endRow, int endCol)
1008 if (startRow < 0 || startRow >= __row || startCol < 0 || startCol >= __column
1009 || endRow < 0 || endRow >= __row || endCol < 0 || endCol >= __column
1010 || startRow > endRow || startCol > endCol)
1012 return E_INVALID_ARG;
1015 int realEndRow = endRow;
1016 int realEndColumn = endCol;
1018 ProxyListNode* pCurNode = null;
1019 TableItemInfo* pItemInfo = null;
1020 for (int i = startRow; i <= realEndRow; i++)
1022 if (__pRowInfo[i].rowCollapsed)
1027 for (int j = startCol; j <= realEndColumn; j++)
1030 int mergedCellIndex = MakeCellID(i, j);
1032 for (k = 0; k < __mergedCellList.GetCount(); k++)
1034 Integer* cellID = static_cast <Integer*>(__mergedCellList.GetAt(k));
1035 if (cellID->ToInt() == mergedCellIndex)
1041 if (i != startRow || j != startCol)
1043 __mergedCellList.Add(*(new Integer(mergedCellIndex)));
1046 pCurNode = GetNode(i, j);
1048 if (pCurNode != null)
1050 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1052 if (pItemInfo == null)
1056 if (pItemInfo->__merged)
1060 if (__pColInfo[j].columnCollapsed)
1065 if (i == startRow && j == startCol)
1067 pItemInfo->__merged = true;
1071 pItemInfo->__enable = false;
1072 pItemInfo->__merged = true;
1073 if (pCurNode->GetItemProxy() != null)
1075 pCurNode->GetItemProxy()->Visible(false);
1080 pCurNode = GetNode(startRow, startCol);
1081 if (pCurNode != null)
1083 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1084 if (pItemInfo == null)
1086 return E_INVALID_STATE;
1088 pItemInfo->__mergeEndPoint.x = realEndRow;
1089 pItemInfo->__mergeEndPoint.y = realEndColumn;
1092 SetUpdateState(true);
1097 TableLayout::OnLayout(int width, int height, bool updateLayouting)
1099 LayoutRect layoutRect = GetLayoutRect();
1100 LayoutRect windowRect = {layoutRect.x, layoutRect.y, width, height};
1102 result r = CalculateSize();
1108 r = CalculateShrinkCell(windowRect);
1114 r = CalculateStretchCell(windowRect);
1120 r = AdjustTableLayout(windowRect, updateLayouting);
1130 TableLayout::AdjustTableLayout(const LayoutRect windowRect, bool updateLayouting)
1132 LayoutItemProxy* pContainerProxy = GetContainerProxy();
1133 if (pContainerProxy == null)
1135 return E_INVALID_STATE;
1138 result r = E_SUCCESS;
1139 LayoutSize size = {0, 0};
1140 ProxyListNode* pCurNode = null;
1141 TableItemInfo* pItemInfo = null;
1142 LayoutItemProxy* pItemProxy = null;
1143 for (int i = 0; i < __row; i++)
1145 for (int j = 0; j < __column; j++)
1147 pCurNode = GetNode(i, j);
1149 if (pCurNode != null)
1151 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1152 pItemProxy = pCurNode->GetItemProxy();
1154 if (pItemInfo != null && pItemInfo->__enable)
1156 size.w = __pColInfo[j].width;
1157 size.h = __pRowInfo[i].height;
1158 if (pItemInfo->__mergeEndPoint.x != NOT_MERGED || pItemInfo->__mergeEndPoint.y != NOT_MERGED)
1160 result r = CalculateMergeCell(i, j, size);
1163 SysLog(NID_UI, "CalculateMergeCell() is Failed.");
1166 if (pItemProxy != null)
1168 LayoutRect rect = pItemProxy->GetItemBaseRect();
1169 rect.x = __pColInfo[j].x;
1170 rect.y = __pRowInfo[i].y;
1172 LayoutRect cellRect;
1173 cellRect.x = __pColInfo[j].x;
1174 cellRect.y = __pRowInfo[i].y;
1175 cellRect.w = size.w;
1176 cellRect.h = size.h;
1178 r = pItemProxy->Measure(rect.w, rect.h);
1183 pItemProxy->GetMeasuredSize(rect.w, rect.h);
1185 if ((__pRowInfo[i].heightShrinkable && __rowShrinkable) ||
1186 (__pRowInfo[i].heightStretchable && __rowStretchable) ||
1187 pItemInfo->__fillHeight)
1190 r = pItemProxy->Measure(rect.w, cellRect.h);
1195 pItemProxy->GetMeasuredSize(rect.w, height);
1197 if ((__pRowInfo[i].heightShrinkable && __rowShrinkable) && rect.h > height)
1201 else if ((__pRowInfo[i].heightStretchable && __rowStretchable) && rect.h < height)
1205 else if (pItemInfo->__fillHeight)
1211 if ((__pColInfo[j].widthShrinkable && __columnShrinkable) ||
1212 (__pColInfo[j].widthStretchable && __columnStretchable) ||
1213 pItemInfo->__fillWidth)
1216 r = pItemProxy->Measure(cellRect.w, rect.h);
1221 pItemProxy->GetMeasuredSize(width, rect.h);
1223 if ((__pColInfo[j].widthShrinkable && __columnShrinkable) && rect.w > width)
1227 else if ((__pColInfo[j].widthStretchable && __columnStretchable) && rect.w < width)
1231 else if (pItemInfo->__fillWidth)
1237 ItemAlign align = pItemProxy->GetItemAlignment();
1238 rect = CalculateAlign(*pItemProxy, cellRect, rect, align.HAlign, align.VAlign);
1240 r = pItemProxy->Measure(rect.w, rect.h);
1245 pItemProxy->GetMeasuredSize(rect.w, rect.h);
1246 pItemProxy->SetItemWindowRect(rect);
1252 LayoutMatchMode widthMode = pContainerProxy->GetItemWidthMatchMode();
1253 LayoutMatchMode heightMode = pContainerProxy->GetItemHeightMatchMode();
1254 LayoutRect containerRect;
1255 pContainerProxy->ConvertWindowToClientBounds(windowRect, containerRect);
1257 containerRect.x = windowRect.x;
1258 containerRect.y = windowRect.y;
1260 int correctionWidth = windowRect.w - containerRect.w;
1261 int correctionHeight = windowRect.h - containerRect.h;
1263 LayoutRect layoutRect = GetLayoutRect();
1264 if (widthMode == WRAP_CONTENT)
1266 containerRect.w = layoutRect.w + correctionWidth;
1270 containerRect.w += correctionWidth;
1273 if (heightMode == WRAP_CONTENT)
1275 containerRect.h = layoutRect.h + correctionHeight;
1279 containerRect.h += correctionHeight;
1282 SetLayoutRect(containerRect);
1284 LayoutRect clientRect;
1285 pContainerProxy->GetItemWindowRect(clientRect);
1286 containerRect.x = clientRect.x;
1287 containerRect.y = clientRect.y;
1288 if (updateLayouting)
1290 pContainerProxy->SetItemWindowRect(containerRect);
1296 TableLayout::AddItem(LayoutItem& item)
1298 ProxyListNode* pCurNode = null;
1300 int cellIndex = INVALID_CELL_ID;
1301 for (int i = 0; i < __row; i++)
1303 for (int j = 0; j < __column; j++)
1305 pCurNode = GetNode(i, j);
1306 if (pCurNode == null)
1308 if (!__pRowInfo[i].rowCollapsed && !__pColInfo[j].columnCollapsed)
1310 cellIndex = MakeCellID(i, j);
1311 for (int k = 0; k < __mergedCellList.GetCount(); k++)
1313 Integer* cellID = static_cast <Integer*>(__mergedCellList.GetAt(k));
1314 if (cellID->ToInt() == cellIndex)
1316 return AddItem(item, i, j, true);
1320 return AddItem(item, i, j);
1330 TableLayout::AddItem(LayoutItem& item, int row, int column, bool mergedState)
1332 ProxyList* pProxyList = GetProxyList();
1333 SysAssertf(pProxyList != null, "ProxyList is invalid");
1335 if (row < 0 || row >= __row || column < 0 || column >= __column)
1337 return E_INVALID_ARG;
1339 ProxyListNode* pGetNode = GetNode(row, column);
1340 if (pGetNode != null)
1342 return E_INVALID_STATE;
1345 int cellIndex = MakeCellID(row, column);
1349 for (int k = 0; k < __mergedCellList.GetCount(); k++)
1351 Integer* cellID = static_cast <Integer*>(__mergedCellList.GetAt(k));
1352 if (cellID->ToInt() == cellIndex)
1359 result r = Layout::AddItem(item);
1365 ProxyListNode* pAddNode = pProxyList->GetNode(item);
1366 if (pAddNode == null)
1368 return E_INVALID_STATE;
1370 TableItemInfo* pAddItemInfo = dynamic_cast <TableItemInfo*>(pAddNode->GetItemInfo());
1371 if (pAddItemInfo == null)
1373 return E_INVALID_STATE;
1376 cellIndex = MakeCellID(row, column);
1377 pAddItemInfo->__id = cellIndex;
1381 pAddItemInfo->__enable = false;
1382 pAddItemInfo->__merged = true;
1384 if (pAddNode->GetItemProxy() != null)
1386 pAddNode->GetItemProxy()->Visible(false);
1394 TableLayout::GetItem(int row, int column) const
1396 if (row < 0 || row >= __row)
1401 if (column < 0 || column >= __column)
1406 ProxyListNode* pCurNode = GetNode(row, column);
1407 if (pCurNode != null && pCurNode->GetItemProxy() != null)
1409 return pCurNode->GetItemProxy()->GetItem();
1418 TableLayout::SetItemPosition(const LayoutItem& item, int row, int column)
1420 SysTryReturn(NID_UI, row >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Negative input argument : row(%d)", row);
1421 SysTryReturn(NID_UI, row < __row, E_INVALID_ARG, E_INVALID_ARG,
1422 "[E_INVALID_ARG] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
1423 SysTryReturn(NID_UI, column >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Negative input argument : column(%d)", column);
1424 SysTryReturn(NID_UI, column < __column, E_INVALID_ARG, E_INVALID_ARG,
1425 "[E_INVALID_ARG] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
1427 ProxyList* pProxyList = GetProxyList();
1428 SysAssertf(pProxyList != null, "ProxyList is invalid");
1430 ProxyListNode* pTargetNode = GetNode(row, column);
1431 ProxyListNode* pCurNode = pProxyList->GetNode(item);
1432 SysTryReturn(NID_UI, (pCurNode != null), E_INVALID_ARG, E_INVALID_ARG,
1433 "[E_INVALID_ARG] Controls have not been added to the container.");
1435 if (pTargetNode == pCurNode)
1440 SysTryReturn(NID_UI, (pTargetNode == null), E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The (%d, %d) cell is not available.", row, column);
1442 int cellIndex = MakeCellID(row, column);
1443 TableItemInfo* pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1444 if (pItemInfo == null)
1446 return E_INVALID_STATE;
1449 if (pItemInfo->__merged || !pItemInfo->__enable)
1451 pItemInfo->__enable = true;
1452 pItemInfo->__merged = false;
1453 if (pCurNode->GetItemProxy() != null)
1455 pCurNode->GetItemProxy()->Visible(true);
1459 pItemInfo->__id = cellIndex;
1461 SetUpdateState(true);
1466 TableLayout::GetItemPosition(const LayoutItem& item, int& row, int& column) const
1468 ProxyList* pProxyList = GetProxyList();
1469 SysAssertf(pProxyList != null, "ProxyList is invalid");
1471 ProxyListNode* pCurNode = pProxyList->GetNode(item);
1472 SysTryReturn(NID_UI, (pCurNode != null), E_INVALID_ARG, E_INVALID_ARG,
1473 "[E_INVALID_ARG] Controls have not been added to the container.");
1475 TableItemInfo* pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1476 if (pItemInfo == null)
1478 return E_INVALID_STATE;
1480 row = (GetRow(pItemInfo->__id));
1481 column = (GetColumn(pItemInfo->__id));
1487 TableLayout::AddRow(void)
1489 if (__row == __maxRow)
1491 RowInfo* pRowInfo = new (std::nothrow) RowInfo[__maxRow + 1];
1492 SysTryReturn(NID_UI, pRowInfo != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
1494 memset(pRowInfo, 0x0, sizeof(RowInfo) * (__maxRow + 1));
1495 memcpy(pRowInfo, __pRowInfo, sizeof(RowInfo) * __maxRow);
1496 delete[] __pRowInfo;
1497 __pRowInfo = pRowInfo;
1505 TableLayout::AddColumn(void)
1507 if (__column == __maxColumn)
1509 ColumnInfo* pColInfo = new (std::nothrow) ColumnInfo[__maxColumn + 1];
1510 SysTryReturn(NID_UI, pColInfo != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
1512 memset(pColInfo, 0x0, sizeof(ColumnInfo) * (__maxColumn + 1));
1513 memcpy(pColInfo, __pColInfo, sizeof(ColumnInfo) * __maxColumn);
1514 delete[] __pColInfo;
1515 __pColInfo = pColInfo;
1523 TableLayout::DeleteRow(int row)
1525 if (row < 0 || row >= __row)
1527 return E_INVALID_ARG;
1530 ProxyListNode* pCurNode = null;
1531 result r = E_SUCCESS;
1532 for (int j = 0; j < __column; j++)
1534 pCurNode = GetNode(row, j);
1535 if (pCurNode != null)
1537 r = RemoveItem(*(pCurNode->GetItemProxy()->GetItem()));
1545 TableItemInfo* pItemInfo = null;
1546 for (int i = 0; i < __row; i++)
1548 for (int j = 0; j < __column; j++)
1550 pCurNode = GetNode(i, j);
1551 if (pCurNode != null)
1553 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1554 if (pItemInfo == null)
1556 return E_INVALID_STATE;
1560 pItemInfo->__id = MakeCellID((i - 1), j);
1562 if (pItemInfo->__mergeEndPoint.x != NOT_MERGED)
1564 if (pItemInfo->__mergeEndPoint.x >= row)
1566 pItemInfo->__mergeEndPoint.x--;
1568 if (pItemInfo->__mergeEndPoint.x == GetRow(pItemInfo->__id))
1570 r = Unmerge(GetRow(pItemInfo->__id), GetColumn(pItemInfo->__id));
1581 memcpy(&__pRowInfo[row], &__pRowInfo[row + 1], sizeof(RowInfo) * (__row - row - 1));
1589 TableLayout::DeleteColumn(int column)
1591 if (column < 0 || column >= __column)
1593 return E_INVALID_ARG;
1596 ProxyListNode* pCurNode = null;
1597 TableItemInfo* pItemInfo = null;
1598 result r = E_SUCCESS;
1599 for (int i = 0; i < __row; i++)
1601 pCurNode = GetNode(i, column);
1602 if (pCurNode != null)
1604 r = RemoveItem(*(pCurNode->GetItemProxy()->GetItem()));
1611 for (int j = 0; j < __column; j++)
1613 pCurNode = GetNode(i, j);
1614 if (pCurNode != null)
1616 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1617 if (pItemInfo == null)
1619 return E_INVALID_STATE;
1623 pItemInfo->__id = MakeCellID(i, (j - 1));
1626 if (pItemInfo->__mergeEndPoint.y != NOT_MERGED)
1628 if (pItemInfo->__mergeEndPoint.y >= column)
1630 pItemInfo->__mergeEndPoint.y--;
1632 int mergeEndColumn = GetColumn(pItemInfo->__id);
1633 if (pItemInfo->__mergeEndPoint.y == mergeEndColumn)
1635 r = Unmerge(GetRow(pItemInfo->__id), GetColumn(pItemInfo->__id));
1646 memcpy(&__pColInfo[column], &__pColInfo[column + 1], sizeof(ColumnInfo) * (__column - column - 1));
1654 TableLayout::CalculateMergeCell(int row, int column, LayoutSize& size)
1656 if (row < 0 || row >= __row || column < 0 || column >= __column)
1658 return E_INVALID_ARG;
1661 ProxyListNode* pCurNode = GetNode(row, column);
1662 if (pCurNode == null)
1664 return E_INVALID_ARG;
1667 TableItemInfo* pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1668 if (pItemInfo == null)
1670 return E_INVALID_STATE;
1672 if (pItemInfo->__mergeEndPoint.x > NOT_MERGED && !__pRowInfo[pItemInfo->__mergeEndPoint.x].rowCollapsed)
1674 int endRowPos = __pRowInfo[pItemInfo->__mergeEndPoint.x].y;
1675 size.h = __pRowInfo[pItemInfo->__mergeEndPoint.x].height + endRowPos - __pRowInfo[row].y;
1679 size.h = __pRowInfo[row].height;
1682 if (pItemInfo->__mergeEndPoint.y > NOT_MERGED && !__pColInfo[pItemInfo->__mergeEndPoint.y].columnCollapsed)
1684 int endColPos = __pColInfo[pItemInfo->__mergeEndPoint.y].x;
1685 size.w = __pColInfo[pItemInfo->__mergeEndPoint.y].width + endColPos - __pColInfo[column].x;
1689 size.w = __pColInfo[column].width;
1696 TableLayout::CalculateAlign(LayoutItemProxy& itemProxy, LayoutRect cellRect, LayoutRect itemRect, const HorizontalAlign horizonAlign, const VerticalAlign verticalAlign)
1698 ItemMargin margin = itemProxy.GetItemMargin();
1699 itemRect.y = cellRect.y;
1700 itemRect.x = cellRect.x;
1702 if (verticalAlign == ITEM_VERTICAL_ALIGN_TOP)
1704 if (itemRect.h > cellRect.h - margin.top)
1706 itemRect.h = cellRect.h - margin.top;
1708 itemRect.y = cellRect.y + margin.top;
1710 else if (verticalAlign == ITEM_VERTICAL_ALIGN_BOTTOM)
1712 if (itemRect.h > cellRect.h - margin.bottom)
1714 itemRect.h = cellRect.h - margin.bottom;
1716 itemRect.y = cellRect.h + cellRect.y - itemRect.h - margin.bottom;
1718 else if (verticalAlign == ITEM_VERTICAL_ALIGN_TOP_BOTTOM)
1720 itemRect.h = cellRect.h - margin.top - margin.bottom;
1721 itemRect.y = cellRect.y + margin.top;
1723 else if (verticalAlign == ITEM_VERTICAL_ALIGN_MIDDLE)
1725 if (cellRect.h > itemRect.h)
1727 itemRect.y = cellRect.y + ((cellRect.h - itemRect.h) >> 1);
1731 itemRect.h = cellRect.h;
1734 if (horizonAlign == ITEM_HORIZONTAL_ALIGN_RIGHT)
1736 if (itemRect.w > cellRect.w - margin.right)
1738 itemRect.w = cellRect.w - margin.right;
1740 itemRect.x = cellRect.w + cellRect.x - itemRect.w - margin.right;
1742 else if (horizonAlign == ITEM_HORIZONTAL_ALIGN_LEFT)
1744 if (itemRect.w > cellRect.w - margin.left)
1746 itemRect.w = cellRect.w - margin.left;
1748 itemRect.x = cellRect.x + margin.left;
1750 else if (horizonAlign == ITEM_HORIZONTAL_ALIGN_CENTER)
1752 if (cellRect.w > itemRect.w)
1754 itemRect.x = cellRect.x + ((cellRect.w - itemRect.w) >> 1);
1758 itemRect.w = cellRect.w;
1761 else if (horizonAlign == ITEM_HORIZONTAL_ALIGN_LEFT_RIGHT)
1763 itemRect.w = cellRect.w - margin.left - margin.right;
1764 itemRect.x = cellRect.x + margin.left;
1771 TableLayout::GetCellSize(int cellIndex, LayoutRect& rect)
1773 if (cellIndex == INVALID_CELL_ID)
1775 return E_INVALID_ARG;
1778 int row = GetRow(cellIndex);
1779 if (row < 0 || row >= __row)
1781 return E_INVALID_ARG;
1784 int column = GetColumn(cellIndex);
1785 if (column < 0 || column >= __column)
1787 return E_INVALID_ARG;
1790 ProxyListNode* pCurNode = GetNode(row, column);
1791 if (pCurNode != null)
1793 TableItemInfo* pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1794 if (pItemInfo == null)
1796 return E_INVALID_STATE;
1798 if (pItemInfo->__mergeEndPoint.x != NOT_MERGED || pItemInfo->__mergeEndPoint.y != NOT_MERGED)
1800 LayoutSize size = {0, 0};
1801 result r = CalculateMergeCell(row, column, size);
1810 rect.h = __pRowInfo[row].height;
1811 rect.w = __pColInfo[column].width;
1815 if (__pRowInfo[row].rowCollapsed)
1820 if (__pColInfo[column].columnCollapsed)
1829 TableLayout::SetColumnCollapsed(int columnIndex, bool collapsed)
1831 SysTryReturn(NID_UI, columnIndex >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1832 "[E_OUT_OF_RANGE] Negative input argument : column(%d)", columnIndex);
1833 SysTryReturn(NID_UI, columnIndex < __column, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1834 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", columnIndex, __column);
1836 __pColInfo[columnIndex].columnCollapsed = collapsed;
1838 ProxyListNode* pCurNode = null;
1839 TableItemInfo* pItemInfo = null;
1840 result r = E_SUCCESS;
1841 for (int i = 0; i < __row; i++)
1843 pCurNode = GetNode(i, columnIndex);
1844 if (pCurNode != null)
1846 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1847 if (pItemInfo == null)
1849 return E_INVALID_STATE;
1851 if (pItemInfo->__merged == true)
1855 if (__pColInfo[columnIndex].columnCollapsed)
1857 pItemInfo->__enable = false;
1858 if (pCurNode->GetItemProxy() != null)
1860 pCurNode->GetItemProxy()->Visible(false);
1863 else if (!__pRowInfo[i].rowCollapsed)
1865 pItemInfo->__enable = true;
1866 if (pCurNode->GetItemProxy() != null)
1868 pCurNode->GetItemProxy()->Visible(true);
1874 SetUpdateState(true);
1879 TableLayout::GetColumnCollapsed(int columnIndex) const
1881 if (columnIndex < 0 || columnIndex >= __column)
1886 return __pColInfo[columnIndex].columnCollapsed;
1890 TableLayout::SetRowCollapsed(int rowIndex, bool collapsed)
1892 SysTryReturn(NID_UI, rowIndex >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1893 "[E_OUT_OF_RANGE] Negative input argument : row(%d)", rowIndex);
1894 SysTryReturn(NID_UI, rowIndex < __row, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1895 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", rowIndex, __row);
1897 __pRowInfo[rowIndex].rowCollapsed = collapsed;
1899 ProxyListNode* pCurNode = null;
1900 TableItemInfo* pItemInfo = null;
1902 for (int i = 0; i < __column; i++)
1904 pCurNode = GetNode(rowIndex, i);
1905 if (pCurNode != null)
1907 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
1908 if (pItemInfo == null)
1910 return E_INVALID_STATE;
1912 if (pItemInfo->__merged == true)
1916 if (__pRowInfo[rowIndex].rowCollapsed)
1918 pItemInfo->__enable = false;
1919 if (pCurNode->GetItemProxy() != null)
1921 pCurNode->GetItemProxy()->Visible(false);
1924 else if (!__pColInfo[i].columnCollapsed)
1926 pItemInfo->__enable = true;
1927 if (pCurNode->GetItemProxy() != null)
1929 pCurNode->GetItemProxy()->Visible(true);
1935 SetUpdateState(true);
1940 TableLayout::GetRowCollapsed(int rowIndex) const
1942 if (rowIndex < 0 || rowIndex >= __row)
1947 return __pRowInfo[rowIndex].rowCollapsed;
1951 TableLayout::SetRowShrinkable(int row, bool shrinkable)
1953 SysTryReturn(NID_UI, row >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1954 "[E_OUT_OF_RANGE] Negative input argument : row(%d)", row);
1955 SysTryReturn(NID_UI, row < __row, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1956 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
1958 __pRowInfo[row].heightShrinkable = shrinkable;
1960 SetUpdateState(true);
1961 SetPartialUpdateFlag(true);
1966 TableLayout::GetRowShrinkable(int row) const
1968 SysTryReturn(NID_UI, row >= 0, false, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] Negative input argument : row(%d)", row);
1969 SysTryReturn(NID_UI, row < __row, false, E_OUT_OF_RANGE,
1970 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
1972 return __pRowInfo[row].heightShrinkable;
1976 TableLayout::SetColumnShrinkable(int column, bool shrinkable)
1978 SysTryReturn(NID_UI, column >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1979 "[E_OUT_OF_RANGE] Negative input argument : column(%d)", column);
1980 SysTryReturn(NID_UI, column < __column, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
1981 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
1983 __pColInfo[column].widthShrinkable = shrinkable;
1985 SetUpdateState(true);
1986 SetPartialUpdateFlag(true);
1991 TableLayout::GetColumnShrinkable(int column) const
1993 SysTryReturn(NID_UI, column >= 0, false, E_OUT_OF_RANGE,
1994 "[E_OUT_OF_RANGE] Negative input argument : column(%d)", column);
1995 SysTryReturn(NID_UI, column < __column, false, E_OUT_OF_RANGE,
1996 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
1998 return __pColInfo[column].widthShrinkable;
2002 TableLayout::SetRowStretchable(int row, bool stretchable)
2004 SysTryReturn(NID_UI, row >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2005 "[E_OUT_OF_RANGE] Negative input argument : row(%d)", row);
2006 SysTryReturn(NID_UI, row < __row, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2007 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
2009 __pRowInfo[row].heightStretchable = stretchable;
2011 SetUpdateState(true);
2012 SetPartialUpdateFlag(true);
2017 TableLayout::GetRowStretchable(int row) const
2019 if (row < 0 || row >= __row)
2024 return __pRowInfo[row].heightStretchable;
2028 TableLayout::SetColumnStretchable(int column, bool stretchable)
2030 SysTryReturn(NID_UI, column >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] Negative input argument : column(%d)",
2032 SysTryReturn(NID_UI, column < __column, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2033 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2035 __pColInfo[column].widthStretchable = stretchable;
2037 SetUpdateState(true);
2038 SetPartialUpdateFlag(true);
2043 TableLayout::GetColumnStretchable(int column) const
2045 SysTryReturn(NID_UI, column >= 0, false, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] Negative input argument : column(%d)", column);
2046 SysTryReturn(NID_UI, column < __column, false, E_OUT_OF_RANGE,
2047 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2049 return __pColInfo[column].widthStretchable;
2053 TableLayout::SetRowSpacing(int row, int heightSpacing)
2055 SysTryReturn(NID_UI, row >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2056 "[E_OUT_OF_RANGE] Negative input argument : row(%d)", row);
2057 SysTryReturn(NID_UI, row < __row, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2058 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
2059 SysTryReturn(NID_UI, heightSpacing >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2060 "[E_OUT_OF_RANGE] Negative input argument : spacing(%d)", heightSpacing);
2062 __pRowInfo[row].heightSpacing = heightSpacing;
2064 SetUpdateState(true);
2069 TableLayout::GetRowSpacing(int row, int& spacing) const
2071 SysTryReturn(NID_UI, row >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2072 "[E_OUT_OF_RANGE] Negative input argument : row(%d)", row);
2073 SysTryReturn(NID_UI, row < __row, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2074 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
2076 spacing = __pRowInfo[row].heightSpacing;
2081 TableLayout::SetColumnSpacing(int column, int widthSpacing)
2083 SysTryReturn(NID_UI, column >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2084 "[E_OUT_OF_RANGE] Negative input argument : column(%d)", column);
2085 SysTryReturn(NID_UI, column < __column, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2086 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2087 SysTryReturn(NID_UI, widthSpacing >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2088 "[E_OUT_OF_RANGE] Negative input argument : spacing(%d)", widthSpacing);
2090 __pColInfo[column].widthSpacing = widthSpacing;
2092 SetUpdateState(true);
2097 TableLayout::GetColumnSpacing(int column, int& spacing) const
2099 SysTryReturn(NID_UI, column >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2100 "[E_OUT_OF_RANGE] Negative input argument : column(%d)", column);
2101 SysTryReturn(NID_UI, column < __column, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2102 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2104 spacing = __pColInfo[column].widthSpacing;
2110 TableLayout::SetFillCell(int row, int column, bool fillWidth, bool fillHeight)
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 SysTryReturn(NID_UI, column >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2117 "[E_OUT_OF_RANGE] Negative input argument : column(%d)", column);
2118 SysTryReturn(NID_UI, column < __column, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2119 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2121 ProxyListNode* pNode = GetNode(row, column);
2124 TableItemInfo* pItemInfo = dynamic_cast <TableItemInfo*>(pNode->GetItemInfo());
2125 if (pItemInfo == null)
2127 return E_INVALID_STATE;
2129 pItemInfo->__fillWidth = fillWidth;
2130 pItemInfo->__fillHeight = fillHeight;
2137 TableLayout::GetFillCell(int row, int column, bool& fillWidth, bool& fillHeight) const
2139 SysTryReturn(NID_UI, row >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2140 "[E_OUT_OF_RANGE] Negative input argument : row(%d)", row);
2141 SysTryReturn(NID_UI, row < __row, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2142 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
2143 SysTryReturn(NID_UI, column >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2144 "[E_OUT_OF_RANGE] Negative input argument : column(%d)", column);
2145 SysTryReturn(NID_UI, column < __column, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2146 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2148 ProxyListNode* pNode = GetNode(row, column);
2151 TableItemInfo* pItemInfo = dynamic_cast <TableItemInfo*>(pNode->GetItemInfo());
2152 if (pItemInfo == null)
2154 return E_INVALID_STATE;
2156 fillWidth = pItemInfo->__fillWidth;
2157 fillHeight = pItemInfo->__fillHeight;
2164 TableLayout::SwapItemPosition(LayoutItem& item1, LayoutItem& item2)
2166 ProxyList* pProxyList = GetProxyList();
2167 SysAssertf(pProxyList != null, "ProxyList is invalid");
2169 ProxyListNode* pNode1 = pProxyList->GetNode(item1);
2170 ProxyListNode* pNode2 = pProxyList->GetNode(item2);
2172 SysTryReturn(NID_UI, (pNode1 != null && pNode2 != null), E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.")
2174 TableItemInfo* pItemInfo1 = dynamic_cast <TableItemInfo*>(pNode1->GetItemInfo());
2175 TableItemInfo* pItemInfo2 = dynamic_cast <TableItemInfo*>(pNode2->GetItemInfo());
2176 if (pItemInfo1 == null || pItemInfo2 == null)
2178 return E_INVALID_STATE;
2181 int cellIndex1 = pItemInfo1->__id;
2182 int cellIndex2 = pItemInfo2->__id;
2183 bool merged1 = pItemInfo1->__merged;
2184 bool merged2 = pItemInfo2->__merged;
2185 bool enable1 = pItemInfo1->__enable;
2186 bool enable2 = pItemInfo2->__enable;
2188 pItemInfo1->__id = cellIndex2;
2189 pItemInfo2->__id = cellIndex1;
2190 pItemInfo1->__merged = merged2;
2191 pItemInfo2->__merged = merged1;
2192 pItemInfo1->__enable = enable2;
2193 pItemInfo2->__enable = enable1;
2195 if (pNode1->GetItemProxy() != null)
2197 if (pItemInfo1->__merged || !pItemInfo1->__enable)
2199 pNode1->GetItemProxy()->Visible(false);
2203 pNode1->GetItemProxy()->Visible(true);
2207 if (pNode2->GetItemProxy() != null)
2209 if (pItemInfo2->__merged || !pItemInfo2->__enable)
2211 pNode2->GetItemProxy()->Visible(false);
2215 pNode2->GetItemProxy()->Visible(true);
2219 SetUpdateState(true);
2224 TableLayout::Unmerge(int row, int column)
2226 SysTryReturn(NID_UI, row >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Negative input argument : row(%d)", row);
2227 SysTryReturn(NID_UI, row < __row, E_INVALID_ARG, E_INVALID_ARG,
2228 "[E_INVALID_ARG] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
2229 SysTryReturn(NID_UI, column >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Negative input argument : column(%d)", column);
2230 SysTryReturn(NID_UI, column < __column, E_INVALID_ARG, E_INVALID_ARG,
2231 "[E_INVALID_ARG] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2236 ProxyListNode* pCurNode = null;
2237 TableItemInfo* pItemInfo = null;
2239 pCurNode = GetNode(row, column);
2240 SysTryReturn(NID_UI, pCurNode, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALIDE_ARG] (%d, %d) cell is not merged.", row, column);
2242 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
2243 if (pItemInfo == null)
2245 return E_INVALID_STATE;
2247 endRow = pItemInfo->__mergeEndPoint.x;
2248 endColumn = pItemInfo->__mergeEndPoint.y;
2250 if (pItemInfo->__enable == false || pItemInfo->__merged == false
2251 || endRow == NOT_MERGED || endColumn == NOT_MERGED)
2253 return E_INVALID_STATE;
2256 pItemInfo->__mergeEndPoint.x = NOT_MERGED;
2257 pItemInfo->__mergeEndPoint.y = NOT_MERGED;
2259 for (int i = row; i <= endRow; i++)
2261 for (int j = column; j <= endColumn; j++)
2263 pCurNode = GetNode(i, j);
2264 if (pCurNode != null)
2266 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
2267 if (pItemInfo == null)
2269 return E_INVALID_STATE;
2271 pItemInfo->__enable = true;
2272 pItemInfo->__merged = false;
2274 for (int k = 0; k < __mergedCellList.GetCount(); k++)
2276 Integer* cellID = static_cast <Integer*>(__mergedCellList.GetAt(k));
2277 if (cellID->ToInt() == MakeCellID(i, j))
2279 __mergedCellList.RemoveAt(k, true);
2284 if (pCurNode->GetItemProxy() != null)
2286 pCurNode->GetItemProxy()->Visible(true);
2292 SetUpdateState(true);
2297 TableLayout::GetMergeSize(int row, int column, int& rowSize, int& colSize) const
2302 SysTryReturn(NID_UI, row >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2303 "[E_OUT_OF_RANGE] Negative input argument : row(%d)", row);
2304 SysTryReturn(NID_UI, row < __row, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2305 "[E_OUT_OF_RANGE] Input Argument row over the max row : row(%d), maxRow(%d)", row, __row);
2306 SysTryReturn(NID_UI, column >= 0, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2307 "[E_OUT_OF_RANGE] Negative input argument : column(%d)", column);
2308 SysTryReturn(NID_UI, column < __column, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
2309 "[E_OUT_OF_RANGE] Input Argument column over the max column : column(%d), maxColumn(%d)", column, __column);
2311 ProxyListNode* pNode = GetNode(row, column);
2318 TableItemInfo* pItemInfo = dynamic_cast <TableItemInfo*>(pNode->GetItemInfo());
2319 if (pItemInfo == null || pItemInfo->__enable == false)
2321 return E_INVALID_STATE;
2324 if (pItemInfo->__merged == false)
2331 rowSize = pItemInfo->__mergeEndPoint.x - row + 1;
2332 colSize = pItemInfo->__mergeEndPoint.y - column + 1;
2339 TableLayout::GetNode(int row, int column) const
2341 ProxyList* pProxyList = GetProxyList();
2342 SysAssertf(pProxyList != null, "ProxyList is invalid");
2344 ProxyListNode* pCurNode = pProxyList->GetFirstNode();
2345 TableItemInfo* pItemInfo = null;
2347 int columnIndex = 0;
2350 pItemInfo = dynamic_cast <TableItemInfo*>(pCurNode->GetItemInfo());
2351 if (pItemInfo != null)
2353 rowIndex = GetRow(pItemInfo->__id);
2354 columnIndex = GetColumn(pItemInfo->__id);
2355 if (row == rowIndex && column == columnIndex)
2360 pCurNode = pProxyList->GetNextNode(*pCurNode);
2366 TableLayout::GetRow(int id) const
2372 TableLayout::GetColumn(int id) const
2374 return id & 0x0000FFFF;
2378 TableLayout::MakeCellID(int row, int column) const
2380 return (row << 16) | (column & 0x0000FFFF);
2383 } // Tizen::Ui::_Layout