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_LayoutLinearLayout.cpp
19 * @brief This is the implementation file for LinearLayout class.
21 * This file contains the implementation of LinearLayout class.
25 #include <FBaseResult.h>
27 #include "FUi_LayoutLinearLayout.h"
28 #include "FUi_LayoutLayoutItemProxy.h"
29 #include "FUi_LayoutProxyList.h"
30 #include "FUi_LayoutLayoutItemInfo.h"
32 namespace Tizen { namespace Ui { namespace _Layout
35 LinearLayout::LinearLayout(void)
36 : __orientation(LINEAR_NONE_ORIENTATION)
37 , __direction(LINEAR_NONE_DIRECTION)
40 LinearProxyList* pLinearProxyList = new (std::nothrow) LinearProxyList();
41 SysTryReturnVoidResult(NID_UI, pLinearProxyList, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
42 SetItemList(pLinearProxyList);
45 LinearLayout::~LinearLayout(void)
50 LinearLayout::CreateLinearLayoutN(void)
52 LinearLayout* pLayout = new (std::nothrow) LinearLayout();
53 SysTryReturn(NID_UI, pLayout != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Linear layout core allocation failure.");
54 if (GetLastResult() != E_SUCCESS)
64 LinearLayout::Initialize(const LinearLayoutOrientation orientation, const LinearLayoutDirection direction)
66 if (orientation == LINEAR_NONE_ORIENTATION || direction == LINEAR_NONE_DIRECTION)
71 __orientation = orientation;
73 if (orientation == LINEAR_HORIZONTAL)
75 if (direction != LINEAR_LEFT_TO_RIGHT && direction != LINEAR_RIGHT_TO_LEFT)
82 if (direction != LINEAR_TOP_TO_BOTTOM && direction != LINEAR_BOTTOM_TO_TOP)
88 __direction = direction;
90 SetPartialUpdateFlag(true);
96 LinearLayout::AddItemToIndex(LayoutItem& addItem, int index)
98 result r = Layout::AddItem(addItem);
104 return MoveItem(addItem, index);
108 LinearLayout::MoveItem(LayoutItem& item, int index)
110 ProxyList* pProxyList = GetProxyList();
111 SysAssertf(pProxyList != null, "ProxyList is invalid.");
113 if (index < 0 || pProxyList->GetNodeCount() <= index)
115 return E_INVALID_ARG;
118 ProxyListNode* pItemNode = pProxyList->GetNode(item);
119 SysTryReturn(NID_UI, pItemNode != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
122 int targetIndex = -1;
124 ProxyListNode* pTargetNode = null;
125 ProxyListNode* pNode = pProxyList->GetFirstNode();
126 while (pNode != null)
129 if (indexCount == index)
131 targetIndex = indexCount;
134 if (pItemNode == pNode)
136 itemIndex = indexCount;
139 pNode = pProxyList->GetNextNode(*pNode);
142 if (targetIndex == -1 || itemIndex == -1)
144 return E_INVALID_STATE;
147 if (targetIndex == itemIndex)
152 result r = pProxyList->DetachNode(*pItemNode);
158 if (targetIndex < itemIndex)
160 r = pProxyList->InsertIntoLeft(*pTargetNode, *pItemNode);
161 pProxyList->RefreshIndex();
167 r = pProxyList->InsertIntoRight(*pTargetNode, *pItemNode);
168 pProxyList->RefreshIndex();
175 LinearLayout::SwapItem(LayoutItem& targetItem, LayoutItem& destItem)
177 result r = E_SUCCESS;
179 ProxyList* pProxyList = GetProxyList();
180 SysAssertf(pProxyList != null, "ProxyList is invalid.");
182 ProxyListNode* pTargetNode = pProxyList->GetNode(targetItem);
183 SysTryReturn(NID_UI, pTargetNode != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
185 ProxyListNode* pDestNode = pProxyList->GetNode(destItem);
186 SysTryReturn(NID_UI, pDestNode != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
188 r = pProxyList->SwapNode(*pTargetNode, *pDestNode);
189 pProxyList->RefreshIndex();
191 SetUpdateState(true);
196 LinearLayout::GetItemCount(void) const
198 ProxyList* pProxyList = GetProxyList();
199 SysAssertf(pProxyList != null, "ProxyList is invalid.");
201 return pProxyList->GetNodeCount();
205 LinearLayout::GetItemIndex(LayoutItem& item, int& index) const
207 ProxyList* pProxyList = GetProxyList();
208 SysAssertf(pProxyList != null, "ProxyList is invalid.");
210 ProxyListNode* pTargetNode = pProxyList->GetNode(item);
211 SysTryReturn(NID_UI, pTargetNode != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
213 index = pProxyList->GetIndex(*pTargetNode);
219 LinearLayout::SetOrientation(const LinearLayoutOrientation orientation)
221 if (orientation == LINEAR_NONE_ORIENTATION)
223 return E_INVALID_ARG;
226 if (__orientation != orientation)
228 if (orientation == LINEAR_HORIZONTAL)
230 __direction = LINEAR_LEFT_TO_RIGHT;
234 __direction = LINEAR_TOP_TO_BOTTOM;
238 __orientation = orientation;
240 SetUpdateState(true);
245 LinearLayout::GetOrientation(LinearLayoutOrientation& orientation) const
247 if (__orientation == LINEAR_NONE_ORIENTATION)
249 return E_INVALID_STATE;
252 orientation = __orientation;
258 LinearLayout::SetDirection(const LinearLayoutDirection direction)
260 if (direction == LINEAR_NONE_DIRECTION)
262 return E_INVALID_ARG;
265 if (__orientation == LINEAR_HORIZONTAL &&
266 (direction == LINEAR_TOP_TO_BOTTOM || direction == LINEAR_BOTTOM_TO_TOP))
268 return E_INVALID_ARG;
271 if (__orientation == LINEAR_VERTICAL &&
272 (direction == LINEAR_LEFT_TO_RIGHT || direction == LINEAR_RIGHT_TO_LEFT))
274 return E_INVALID_ARG;
277 __direction = direction;
279 SetUpdateState(true);
284 LinearLayout::GetDirection(LinearLayoutDirection& direction) const
286 if (__direction == LINEAR_NONE_DIRECTION)
288 return E_INVALID_STATE;
291 direction = __direction;
297 LinearLayout::SetItemWeight(LayoutItem& item, const float weight)
299 SysTryReturn(NID_UI, weight >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The weight value is negative.");
301 ProxyList* pProxyList = GetProxyList();
302 SysAssertf(pProxyList != null, "ProxyList is invalid.");
304 ProxyListNode* pNode = pProxyList->GetNode(item);
305 SysTryReturn(NID_UI, pNode != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
307 LinearItemInfo* pItemInfo = dynamic_cast <LinearItemInfo*>(pNode->GetItemInfo());
308 if (pItemInfo == null)
310 return E_INVALID_STATE;
313 __weightSum -= pItemInfo->__weight;
314 pItemInfo->__weight = weight;
315 __weightSum += pItemInfo->__weight;
317 SetUpdateState(true);
322 LinearLayout::GetItemWeight(const LayoutItem& item, float& weight) const
324 ProxyList* pProxyList = GetProxyList();
325 SysAssertf(pProxyList != null, "ProxyList is invalid.");
327 ProxyListNode* pNode = pProxyList->GetNode(item);
328 SysTryReturn(NID_UI, pNode != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
330 LinearItemInfo* pItemInfo = dynamic_cast <LinearItemInfo*>(pNode->GetItemInfo());
331 if (pItemInfo == null)
333 return E_INVALID_STATE;
336 weight = pItemInfo->__weight;
342 LinearLayout::SetItemSpacing(LayoutItem& item, int spacing)
344 ProxyList* pProxyList = GetProxyList();
345 SysAssertf(pProxyList != null, "ProxyList is invalid.");
347 ProxyListNode* pNode = pProxyList->GetNode(item);
348 SysTryReturn(NID_UI, pNode != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
350 LinearItemInfo* pItemInfo = dynamic_cast <LinearItemInfo*>(pNode->GetItemInfo());
351 if (pItemInfo == null)
353 return E_INVALID_STATE;
356 pItemInfo->__spacing = spacing;
358 SetUpdateState(true);
363 LinearLayout::GetItemSpacing(const LayoutItem& item, int& spacing) const
365 ProxyList* pProxyList = GetProxyList();
366 SysAssertf(pProxyList != null, "ProxyList is invalid.");
368 ProxyListNode* pNode = pProxyList->GetNode(item);
369 SysTryReturn(NID_UI, pNode != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
371 LinearItemInfo* pItemInfo = dynamic_cast <LinearItemInfo*>(pNode->GetItemInfo());
372 if (pItemInfo == null)
374 return E_INVALID_STATE;
377 spacing = pItemInfo->__spacing;
383 LinearLayout::OnLayout(int width, int height, bool layoutUpdating)
385 result r = E_SUCCESS;
387 ProxyList* pProxyList = GetProxyList();
388 SysAssertf(pProxyList != null, "ProxyList is invalid.");
390 if (__orientation == LINEAR_NONE_ORIENTATION || __direction == LINEAR_NONE_DIRECTION)
392 return E_INVALID_STATE;
395 LayoutItemProxy* pContainerProxy = GetContainerProxy();
396 if (pContainerProxy == null)
398 return E_INVALID_STATE;
401 LayoutRect intendedRect = {0, 0, width, height};
402 pContainerProxy->ConvertWindowToClientBounds(intendedRect, intendedRect);
404 LayoutRect layoutRect = GetLayoutRect();
405 layoutRect.w = intendedRect.w;
406 layoutRect.h = intendedRect.h;
407 SetLayoutRect(layoutRect);
411 r = CalculatePositionSize(rightBound, bottomBound);
417 if (_FloatHardCompare(__weightSum, 0.0f) == false)
419 r = CalculateWeight(rightBound, bottomBound);
426 r = CalculateWrapContent(*pContainerProxy, rightBound, bottomBound, layoutUpdating);
432 if (__orientation == LINEAR_HORIZONTAL)
434 r = CalculateAlignment(VERTICALONLY);
438 r = CalculateAlignment(HORIZONTALONLY);
445 r = CalculateCorrectedAlignment();
451 r = CalculateMatchParent();
457 ProxyListNode* pNode = pProxyList->GetFirstNode();
458 while (pNode != null)
460 LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
461 LinearItemInfo* pItemInfo = dynamic_cast <LinearItemInfo*>(pNode->GetItemInfo());
462 if (pItemProxy == null || pItemInfo == null)
464 return E_INVALID_STATE;
467 r = pItemProxy->SetItemWindowRect(pItemInfo->__itemRect);
473 pNode = pProxyList->GetNextNode(*pNode);
480 LinearLayout::CalculatePositionSize(int& rightBound, int& bottomBound)
482 ProxyList* pProxyList = GetProxyList();
483 SysAssertf(pProxyList != null, "ProxyList is invalid.");
485 if (pProxyList->GetNodeCount() == 0)
490 if (__orientation == LINEAR_HORIZONTAL)
492 return CalculateHorizontalPositionSize(rightBound, bottomBound);
496 return CalculateVerticalPositonSize(rightBound, bottomBound);
501 LinearLayout::CalculateHorizontalPositionSize(int& rightBound, int& bottomBound)
503 ProxyList* pProxyList = GetProxyList();
504 SysAssertf(pProxyList != null, "ProxyList is invalid.");
506 LayoutRect layoutRect = GetLayoutRect();
507 int x = layoutRect.x;
508 if (__direction == LINEAR_RIGHT_TO_LEFT)
513 ProxyListNode* pNode = pProxyList->GetFirstNode();
514 ProxyListNode* pFirstNode = pNode;
515 while (pNode != null)
517 LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
518 LinearItemInfo* pItemInfo = dynamic_cast <LinearItemInfo*>(pNode->GetItemInfo());
519 if (pItemProxy == null || pItemInfo == null)
521 return E_INVALID_STATE;
524 bool changedProperty = false;
525 if (pItemProxy->GetItemWidthMatchMode() == MATCH_PARENT)
527 pItemProxy->SetItemWidthMatchMode(NONE_MODE);
528 changedProperty = true;
531 LayoutRect itemRect = pItemProxy->GetItemBaseRect();
532 result r = pItemProxy->Measure(itemRect.w, itemRect.h);
537 pItemProxy->GetMeasuredSize(itemRect.w, itemRect.h);
538 if (__direction == LINEAR_LEFT_TO_RIGHT)
541 if (pNode != pFirstNode)
543 itemRect.x += pItemInfo->__spacing;
545 x = itemRect.x + itemRect.w;
550 if (pNode != pFirstNode)
552 x -= pItemInfo->__spacing;
556 itemRect.y = layoutRect.y;
557 pItemInfo->__itemRect = itemRect;
559 if (__direction == LINEAR_LEFT_TO_RIGHT)
565 rightBound = layoutRect.x + layoutRect.w;
568 ItemAlign align = pItemProxy->GetItemAlignment();
569 ItemMargin margin = pItemProxy->GetItemMargin();
570 if (pItemProxy->GetItemHeightMatchMode() != MATCH_PARENT)
572 int itemBottomPosition = 0;
573 if (align.VAlign == ITEM_VERTICAL_ALIGN_TOP)
575 itemBottomPosition = margin.top + itemRect.h;
577 else if (align.VAlign == ITEM_VERTICAL_ALIGN_BOTTOM)
579 itemBottomPosition = margin.bottom + itemRect.h;
581 else if (align.VAlign == ITEM_VERTICAL_ALIGN_TOP_BOTTOM)
583 itemBottomPosition = margin.top + itemRect.h + margin.bottom;
587 itemBottomPosition = itemRect.h;
590 if (itemBottomPosition > bottomBound)
592 bottomBound = itemBottomPosition;
598 pItemProxy->SetItemWidthMatchMode(MATCH_PARENT);
601 pNode = pProxyList->GetNextNode(*pNode);
608 LinearLayout::CalculateVerticalPositonSize(int& rightBound, int& bottomBound)
610 ProxyList* pProxyList = GetProxyList();
611 SysAssertf(pProxyList != null, "ProxyList is invalid.");
613 LayoutRect layoutRect = GetLayoutRect();
614 int y = layoutRect.y;
615 if (__direction == LINEAR_BOTTOM_TO_TOP)
620 ProxyListNode* pNode = pProxyList->GetFirstNode();
621 ProxyListNode* pFirstNode = pNode;
622 while (pNode != null)
624 LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
625 LinearItemInfo* pItemInfo = dynamic_cast <LinearItemInfo*>(pNode->GetItemInfo());
626 if (pItemProxy == null || pItemInfo == null)
628 return E_INVALID_STATE;
631 bool changedProperty = false;
632 if (pItemProxy->GetItemHeightMatchMode() == MATCH_PARENT)
634 pItemProxy->SetItemHeightMatchMode(NONE_MODE);
635 changedProperty = true;
638 LayoutRect itemRect = pItemProxy->GetItemBaseRect();
639 result r = pItemProxy->Measure(itemRect.w, itemRect.h);
644 pItemProxy->GetMeasuredSize(itemRect.w, itemRect.h);
645 if (__direction == LINEAR_TOP_TO_BOTTOM)
648 if (pNode != pFirstNode)
650 itemRect.y += pItemInfo->__spacing;
652 y = itemRect.y + itemRect.h;
657 if (pNode != pFirstNode)
659 y -= pItemInfo->__spacing;
663 itemRect.x = layoutRect.x;
664 pItemInfo->__itemRect = itemRect;
666 if (__direction == LINEAR_TOP_TO_BOTTOM)
672 bottomBound = layoutRect.y + layoutRect.h;
675 ItemAlign align = pItemProxy->GetItemAlignment();
676 ItemMargin margin = pItemProxy->GetItemMargin();
677 if (pItemProxy->GetItemWidthMatchMode() != MATCH_PARENT)
679 int itemRightPosition = 0;
680 if (align.HAlign == ITEM_HORIZONTAL_ALIGN_LEFT)
682 itemRightPosition = margin.left + itemRect.w;
684 else if (align.HAlign == ITEM_HORIZONTAL_ALIGN_RIGHT)
686 itemRightPosition = margin.right + itemRect.w;
688 else if (align.HAlign == ITEM_HORIZONTAL_ALIGN_LEFT_RIGHT)
690 itemRightPosition = margin.left + itemRect.w + margin.right;
694 itemRightPosition = itemRect.w;
697 if (itemRightPosition > rightBound)
699 rightBound = itemRightPosition;
705 pItemProxy->SetItemHeightMatchMode(MATCH_PARENT);
708 pNode = pProxyList->GetNextNode(*pNode);
715 LinearLayout::CalculateWeight(int& rightBound, int& bottomBound)
717 float originalWeightSum = __weightSum;
718 LayoutRect layoutRect = GetLayoutRect();
720 result r = E_SUCCESS;
722 ProxyList* pProxyList = GetProxyList();
723 SysAssertf(pProxyList != null, "ProxyList is invalid.");
725 if (__orientation == LINEAR_HORIZONTAL)
727 if (__direction == LINEAR_LEFT_TO_RIGHT)
729 emptySpace = (layoutRect.x + layoutRect.w) - rightBound;
733 ProxyListNode* pNode = pProxyList->GetLastNode();
736 return E_INVALID_STATE;
738 LinearItemInfo* pItemInfo = dynamic_cast <LinearItemInfo*>(pNode->GetItemInfo());
739 if (pItemInfo == null)
741 return E_INVALID_STATE;
744 emptySpace = pItemInfo->__itemRect.x - layoutRect.x;
747 while (emptySpace != 0)
749 r = CalculateHorizontalWeight(emptySpace);
756 ProxyListNode* pBoundNode = null;
757 if (__direction == LINEAR_TOP_TO_BOTTOM)
759 pBoundNode = pProxyList->GetLastNode();
763 pBoundNode = pProxyList->GetFirstNode();
765 if (pBoundNode == null)
767 return E_INVALID_STATE;
769 LinearItemInfo* pBoundInfo = dynamic_cast <LinearItemInfo*>(pBoundNode->GetItemInfo());
770 if (pBoundInfo == null)
772 return E_INVALID_STATE;
774 rightBound = pBoundInfo->__itemRect.x + pBoundInfo->__itemRect.w;
778 if (__direction == LINEAR_TOP_TO_BOTTOM)
780 emptySpace = (layoutRect.y + layoutRect.h) - bottomBound;
784 ProxyListNode* pNode = pProxyList->GetLastNode();
787 return E_INVALID_STATE;
789 LinearItemInfo* pItemInfo = dynamic_cast <LinearItemInfo*>(pNode->GetItemInfo());
790 if (pItemInfo == null)
792 return E_INVALID_STATE;
795 emptySpace = pItemInfo->__itemRect.y - layoutRect.y;
798 while (emptySpace != 0)
800 r = CalculateVerticalWeight(emptySpace);
807 ProxyListNode* pBoundNode = null;
808 if (__direction == LINEAR_TOP_TO_BOTTOM)
810 pBoundNode = pProxyList->GetLastNode();
814 pBoundNode = pProxyList->GetFirstNode();
816 if (pBoundNode == null)
818 return E_INVALID_STATE;
820 LinearItemInfo* pBoundInfo = dynamic_cast <LinearItemInfo*>(pBoundNode->GetItemInfo());
821 if (pBoundInfo == null)
823 return E_INVALID_STATE;
825 bottomBound = pBoundInfo->__itemRect.y + pBoundInfo->__itemRect.h;
828 ProxyListNode* pNode = pProxyList->GetFirstNode();
829 while (pNode != null)
831 LinearItemInfo* pItemInfo = dynamic_cast <LinearItemInfo*>(pNode->GetItemInfo());
832 if (pItemInfo == null)
834 return E_INVALID_STATE;
836 pItemInfo->__fixedSize = false;
838 pNode = pProxyList->GetNextNode(*pNode);
841 __weightSum = originalWeightSum;
847 LinearLayout::CalculateHorizontalWeight(int& emptySpace)
849 ProxyList* pProxyList = GetProxyList();
850 SysAssertf(pProxyList != null, "ProxyList is invalid.");
852 if (_FloatHardCompare(__weightSum, 0.0f) == true)
858 result r = E_SUCCESS;
860 int measuredWidth = 0;
861 int usedEmptySpace = emptySpace;
862 int itemCount = pProxyList->GetNodeCount();
864 if (usedEmptySpace <= itemCount && usedEmptySpace >= -itemCount)
866 ProxyListNode* pNode = pProxyList->GetFirstNode();
867 while (pNode != null)
869 LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
870 LinearItemInfo* pItemInfo = dynamic_cast <LinearItemInfo*>(pNode->GetItemInfo());
871 if (pItemProxy == null || pItemInfo == null)
873 return E_INVALID_STATE;
875 LayoutRect itemRect = pItemInfo->__itemRect;
877 if (pItemInfo->__fixedSize == false && usedEmptySpace != 0)
879 if (usedEmptySpace > 0)
883 r = pItemProxy->Measure(itemRect.w, itemRect.h);
889 pItemProxy->GetMeasuredSize(measuredWidth, itemRect.h);
890 if (measuredWidth == itemRect.w)
893 if (__direction == LINEAR_LEFT_TO_RIGHT)
905 itemRect.w = measuredWidth;
906 __weightSum -= pItemInfo->__weight;
907 pItemInfo->__fixedSize = true;
913 #ifdef NOT_SUPPORT_NEGATIVE_SIZE
919 r = pItemProxy->Measure(itemRect.w, itemRect.h);
925 pItemProxy->GetMeasuredSize(measuredWidth, itemRect.h);
926 if (measuredWidth == itemRect.w)
929 if (__direction == LINEAR_LEFT_TO_RIGHT)
941 itemRect.w = measuredWidth;
942 __weightSum -= pItemInfo->__weight;
943 pItemInfo->__fixedSize = true;
947 pItemInfo->__itemRect = itemRect;
949 pNode = pProxyList->GetNextNode(*pNode);
951 emptySpace = usedEmptySpace;
956 float unitSize = emptySpace / __weightSum;
957 int correctionValue = emptySpace - (int) (unitSize * 100.0) * (int) (__weightSum) / 100;
958 if (correctionValue < 0)
960 correctionValue = -correctionValue;
963 ProxyListNode* pNode = pProxyList->GetFirstNode();
964 while (pNode != null)
966 LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
967 LinearItemInfo* pItemInfo = dynamic_cast <LinearItemInfo*>(pNode->GetItemInfo());
968 if (pItemProxy == null || pItemInfo == null)
970 return E_INVALID_STATE;
972 LayoutRect itemRect = pItemInfo->__itemRect;
973 int correctionSize = (int) (unitSize * pItemInfo->__weight);
976 if (correctionSize < 0)
987 if (__direction == LINEAR_LEFT_TO_RIGHT)
992 if (pItemInfo->__fixedSize == false)
994 itemRect.w += correctionSize;
996 usedEmptySpace -= correctionSize;
999 if (__direction == LINEAR_RIGHT_TO_LEFT)
1004 r = pItemProxy->Measure(itemRect.w, itemRect.h);
1009 pItemProxy->GetMeasuredSize(measuredWidth, itemRect.h);
1010 if (measuredWidth != itemRect.w)
1012 usedEmptySpace = usedEmptySpace - (measuredWidth - itemRect.w);
1013 x = x + (measuredWidth - itemRect.w);
1014 itemRect.w = measuredWidth;
1015 __weightSum -= pItemInfo->__weight;
1016 pItemInfo->__fixedSize = true;
1018 #ifdef NOT_SUPPORT_NEGATIVE_SIZE
1024 pItemInfo->__itemRect = itemRect;
1026 pNode = pProxyList->GetNextNode(*pNode);
1028 emptySpace = usedEmptySpace;
1034 LinearLayout::CalculateVerticalWeight(int& emptySpace)
1036 if (_FloatHardCompare(__weightSum, 0.0f))
1042 ProxyList* pProxyList = GetProxyList();
1043 SysAssertf(pProxyList != null, "ProxyList is invalid.");
1045 result r = E_SUCCESS;
1047 int measuredHeight = 0;
1048 int usedEmptySpace = emptySpace;
1049 int itemCount = pProxyList->GetNodeCount();
1051 if (usedEmptySpace <= itemCount && usedEmptySpace >= -itemCount)
1053 ProxyListNode* pNode = pProxyList->GetFirstNode();
1054 while (pNode != null)
1056 LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
1057 LinearItemInfo* pItemInfo = dynamic_cast <LinearItemInfo*>(pNode->GetItemInfo());
1058 if (pItemProxy == null || pItemInfo == null)
1060 return E_INVALID_STATE;
1062 LayoutRect itemRect = pItemInfo->__itemRect;
1064 if (pItemInfo->__fixedSize == false && usedEmptySpace != 0)
1066 if (usedEmptySpace > 0)
1070 r = pItemProxy->Measure(itemRect.w, itemRect.h);
1076 pItemProxy->GetMeasuredSize(itemRect.w, measuredHeight);
1077 if (measuredHeight == itemRect.h)
1080 if (__direction == LINEAR_TOP_TO_BOTTOM)
1092 itemRect.h = measuredHeight;
1093 __weightSum -= pItemInfo->__weight;
1094 pItemInfo->__fixedSize = true;
1100 #ifdef NOT_SUPPORT_NEGATIVE_SIZE
1106 r = pItemProxy->Measure(itemRect.w, itemRect.h);
1112 pItemProxy->GetMeasuredSize(itemRect.w, measuredHeight);
1113 if (measuredHeight == itemRect.h)
1116 if (__direction == LINEAR_TOP_TO_BOTTOM)
1128 itemRect.h = measuredHeight;
1129 __weightSum -= pItemInfo->__weight;
1130 pItemInfo->__fixedSize = true;
1134 pItemInfo->__itemRect = itemRect;
1136 pNode = pProxyList->GetNextNode(*pNode);
1138 emptySpace = usedEmptySpace;
1143 float unitSize = emptySpace / __weightSum;
1144 int correctionValue = emptySpace - (int) (unitSize * 100.0) * (int) (__weightSum) / 100;
1145 if (correctionValue < 0)
1147 correctionValue = -correctionValue;
1150 ProxyListNode* pNode = pProxyList->GetFirstNode();
1151 while (pNode != null)
1153 LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
1154 LinearItemInfo* pItemInfo = dynamic_cast <LinearItemInfo*>(pNode->GetItemInfo());
1155 if (pItemProxy == null || pItemInfo == null)
1157 return E_INVALID_STATE;
1159 LayoutRect itemRect = pItemInfo->__itemRect;
1160 int correctionSize = (int) (unitSize * pItemInfo->__weight);
1161 if (correctionValue)
1163 if (correctionSize < 0)
1174 if (__direction == LINEAR_TOP_TO_BOTTOM)
1179 if (pItemInfo->__fixedSize == false)
1181 itemRect.h += correctionSize;
1182 y += correctionSize;
1183 usedEmptySpace -= correctionSize;
1186 if (__direction == LINEAR_BOTTOM_TO_TOP)
1191 r = pItemProxy->Measure(itemRect.w, itemRect.h);
1196 pItemProxy->GetMeasuredSize(itemRect.w, measuredHeight);
1197 if (measuredHeight != itemRect.h)
1199 usedEmptySpace = usedEmptySpace - (measuredHeight - itemRect.h);
1200 y = y + (measuredHeight - itemRect.h);
1201 itemRect.h = measuredHeight;
1202 __weightSum -= pItemInfo->__weight;
1203 pItemInfo->__fixedSize = true;
1205 #ifdef NOT_SUPPORT_NEGATIVE_SIZE
1211 pItemInfo->__itemRect = itemRect;
1213 pNode = pProxyList->GetNextNode(*pNode);
1215 emptySpace = usedEmptySpace;
1221 LinearLayout::CalculateWrapContent(LayoutItemProxy& containerProxy, int rightBound, int bottomBound, bool layoutUpdating)
1223 LayoutMatchMode widthMatchMode = containerProxy.GetItemWidthMatchMode();
1224 LayoutMatchMode heightMatchMode = containerProxy.GetItemHeightMatchMode();
1226 if (widthMatchMode != WRAP_CONTENT && heightMatchMode != WRAP_CONTENT)
1231 LayoutRect containerRect;
1232 LayoutRect clientRect;
1233 containerProxy.GetItemWindowRect(containerRect);
1234 containerProxy.ConvertWindowToClientBounds(containerRect, clientRect);
1236 int correctionWidth = containerRect.w - clientRect.w;
1237 int correctionHeight = containerRect.h - clientRect.h;
1240 containerProxy.GetMinSize(minSize);
1241 containerProxy.GetMaxSize(maxSize);
1242 LayoutRect layoutRect = GetLayoutRect();
1244 if (widthMatchMode == WRAP_CONTENT)
1246 layoutRect.w = rightBound - layoutRect.x;
1247 if (layoutRect.w < 0)
1251 containerRect.w = layoutRect.w + (containerRect.w - clientRect.w);
1252 containerRect.w = layoutRect.w + correctionWidth;
1253 #ifdef NOT_SUPPORT_NEGATIVE_SIZE
1254 if (containerRect.w < 0)
1256 containerRect.w = 0;
1259 if (containerRect.w < minSize.w)
1261 containerRect.w = minSize.w;
1263 if (containerRect.w > maxSize.w)
1265 containerRect.w = maxSize.w;
1267 layoutRect.w = containerRect.w - correctionWidth;
1269 if (heightMatchMode == WRAP_CONTENT)
1271 layoutRect.h = bottomBound - layoutRect.y;
1272 if (layoutRect.h < 0)
1276 containerRect.h = layoutRect.h + (containerRect.h - clientRect.h);
1277 containerRect.h = layoutRect.h + correctionHeight;
1278 #ifdef NOT_SUPPORT_NEGATIVE_SIZE
1279 if (containerRect.h < 0)
1281 containerRect.h = 0;
1284 if (containerRect.h < minSize.h)
1286 containerRect.h = minSize.h;
1288 if (containerRect.h > maxSize.h)
1290 containerRect.h = maxSize.h;
1292 layoutRect.h = containerRect.h - correctionHeight;
1294 SetLayoutRect(layoutRect);
1297 result r = containerProxy.SetItemWindowRect(containerRect);
1308 LinearLayout::CalculateMatchParent(void)
1310 ProxyList* pProxyList = GetProxyList();
1311 SysAssertf(pProxyList != null, "ProxyList is invalid.");
1313 LayoutRect layoutRect = GetLayoutRect();
1315 ProxyListNode* pNode = pProxyList->GetFirstNode();
1316 while (pNode != null)
1318 LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
1319 LinearItemInfo* pItemInfo = dynamic_cast <LinearItemInfo*>(pNode->GetItemInfo());
1320 if (pItemProxy == null || pItemInfo == null)
1322 return E_INVALID_STATE;
1325 bool changedProperty = false;
1326 if (pItemProxy->GetItemHeightMatchMode() == MATCH_PARENT && __orientation == LINEAR_HORIZONTAL)
1328 if (pItemProxy->GetItemWidthMatchMode() == MATCH_PARENT)
1330 pItemProxy->SetItemWidthMatchMode(NONE_MODE);
1331 changedProperty = true;
1333 LayoutRect itemRect = pItemInfo->__itemRect;
1334 result r = pItemProxy->Measure(itemRect.w, itemRect.h);
1339 pItemProxy->GetMeasuredSize(itemRect.w, itemRect.h);
1340 itemRect.y = layoutRect.y;
1341 pItemInfo->__itemRect = itemRect;
1343 if (changedProperty == true)
1345 pItemProxy->SetItemWidthMatchMode(MATCH_PARENT);
1348 if (pItemProxy->GetItemWidthMatchMode() == MATCH_PARENT && __orientation == LINEAR_VERTICAL)
1350 if (pItemProxy->GetItemHeightMatchMode() == MATCH_PARENT)
1352 pItemProxy->SetItemHeightMatchMode(NONE_MODE);
1353 changedProperty = true;
1355 LayoutRect itemRect = pItemInfo->__itemRect;
1356 result r = pItemProxy->Measure(itemRect.w, itemRect.h);
1361 pItemProxy->GetMeasuredSize(itemRect.w, itemRect.h);
1362 itemRect.x = layoutRect.x;
1363 pItemInfo->__itemRect = itemRect;
1365 if (changedProperty == true)
1367 pItemProxy->SetItemHeightMatchMode(MATCH_PARENT);
1371 pNode = pProxyList->GetNextNode(*pNode);
1378 LinearLayout::CalculateCorrectedAlignment(void)
1380 ProxyList* pProxyList = GetProxyList();
1381 SysAssertf(pProxyList != null, "ProxyList is invalid.");
1383 ProxyListNode* pNode = pProxyList->GetFirstNode();
1384 while (pNode != null)
1386 LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
1387 LinearItemInfo* pItemInfo = dynamic_cast <LinearItemInfo*>(pNode->GetItemInfo());
1388 if (pItemProxy == null || pItemInfo == null)
1390 return E_INVALID_STATE;
1392 ItemAlign align = pItemProxy->GetItemAlignment();
1393 LayoutRect itemWindowRect;
1394 pItemProxy->GetItemWindowRect(itemWindowRect);
1396 if (__orientation == LINEAR_HORIZONTAL)
1398 pItemInfo->__itemRect.y = itemWindowRect.y;
1399 if (align.VAlign == ITEM_VERTICAL_ALIGN_TOP_BOTTOM)
1401 pItemInfo->__itemRect.h = itemWindowRect.h;
1406 pItemInfo->__itemRect.x = itemWindowRect.x;
1407 if (align.HAlign == ITEM_HORIZONTAL_ALIGN_LEFT_RIGHT)
1409 pItemInfo->__itemRect.w = itemWindowRect.w;
1413 pNode = pProxyList->GetNextNode(*pNode);
1419 }}} // Tizen::Ui::_Layout