Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / layout / FUi_LayoutLayout.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 /**
18  * @file                FUi_LayoutLayout.cpp
19  * @brief       This is the implementation file for Layout class.
20  *
21  * This file contains the implementation of Layout class.
22  */
23
24 #include <FBaseSysLog.h>
25 #include "FUi_LayoutLayout.h"
26 #include "FUi_LayoutLayoutItemProxy.h"
27 #include "FUi_LayoutProxyList.h"
28 #include "FUi_LayoutLayoutItemInfo.h"
29 #include "FUi_LayoutLayoutList.h"
30
31 namespace Tizen { namespace Ui { namespace _Layout
32 {
33
34 Layout::Layout(void)
35         : __pProxyList(null)
36         , __x(0)
37         , __y(0)
38         , __width(0)
39         , __height(0)
40         , __pContainerProxy(null)
41         , __rootLayout(false)
42         , __updateState(true)
43         , __partialUpdateState(false)
44         , __determineState(false)
45 {
46 }
47
48 Layout::~Layout(void)
49 {
50         LayoutItemProxy* pContainerProxy = GetContainerProxy();
51         if (pContainerProxy != null)
52         {
53                 LayoutContainer* pContainer = dynamic_cast <LayoutContainer*>(pContainerProxy->GetItem());
54                 if (pContainer)
55                 {
56                         pContainer->OnDestroyLayout(*this);
57                 }
58         }
59
60         if (__rootLayout)
61         {
62                 delete __pContainerProxy;
63         }
64
65         delete __pProxyList;
66 }
67
68 LayoutItemProxy*
69 Layout::GetContainerProxy(void)
70 {
71         if (__pContainerProxy == null)
72         {
73                 return null;
74         }
75
76         if (__rootLayout == false)
77         {
78                 LayoutContainer* pContainer = dynamic_cast <LayoutContainer*>(__pContainerProxy->GetItem());
79                 if (pContainer == null)
80                 {
81                         SysLog(NID_UI, "Container is null.");
82                         return null;
83                 }
84
85                 LayoutContainer* pParentContainer = pContainer->GetParentContainer();
86                 if (pParentContainer == null)
87                 {
88                         SysLog(NID_UI, "Parent of container is null.");
89                         return null;
90                 }
91
92                 Layout* pParentLayout = __pContainerProxy->GetParentLayout();
93                 if (pParentLayout == null)
94                 {
95                         SysLog(NID_UI, "Parent layout of container is null.");
96                         return null;
97                 }
98
99                 if (pParentLayout != pParentContainer->__pCurrentLayout)
100                 {
101                         ProxyListNode* pNode = pParentContainer->__pCurrentLayout->__pProxyList->GetFirstNode();
102                         while (pNode != null)
103                         {
104                                 LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
105                                 LayoutContainer* pResultContainer = dynamic_cast <LayoutContainer*>(pItemProxy->GetItem());
106                                 if (pContainer == pResultContainer)
107                                 {
108                                         __pContainerProxy = pItemProxy;
109                                         break;
110                                 }
111                                 pNode = __pProxyList->GetNextNode(*pNode);
112                         }
113                 }
114         }
115
116         return __pContainerProxy;
117 }
118
119 void
120 Layout::SetLayoutRect(const LayoutRect layoutRect)
121 {
122         __x = layoutRect.x;
123         __y = layoutRect.y;
124         __width = layoutRect.w;
125         __height = layoutRect.h;
126 }
127
128 LayoutRect
129 Layout::GetLayoutRect(void) const
130 {
131         LayoutRect layoutRect = {__x, __y, __width, __height};
132
133         return layoutRect;
134 }
135
136 result
137 Layout::SetItemAlignment(const LayoutItem& item, const ItemAlign align)
138 {
139         ClearLastResult();
140
141         if (align.HAlign < ITEM_HORIZONTAL_ALIGN_LEFT || align.HAlign > ITEM_HORIZONTAL_ALIGN_LEFT_RIGHT ||
142                 align.VAlign < ITEM_VERTICAL_ALIGN_TOP || align.VAlign > ITEM_VERTICAL_ALIGN_TOP_BOTTOM)
143         {
144                 SysTryReturn(NID_UI, false, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The alignment parameter is invalid parameter.");
145         }
146
147         LayoutItemProxy* pItemProxy = __pProxyList->GetItemProxy(item);
148         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
149
150         pItemProxy->SetItemAlignment(align);
151
152         SetUpdateState(true);
153         return E_SUCCESS;
154 }
155
156 result
157 Layout::GetItemAlignment(const LayoutItem& item, ItemAlign& align) const
158 {
159         ClearLastResult();
160
161         LayoutItemProxy* pItemProxy = __pProxyList->GetItemProxy(item);
162         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
163
164         align = pItemProxy->GetItemAlignment();
165
166         return E_SUCCESS;
167 }
168
169 result
170 Layout::SetItemMargin(const LayoutItem& item, const ItemMargin margin)
171 {
172         ClearLastResult();
173
174         LayoutItemProxy* pItemProxy = __pProxyList->GetItemProxy(item);
175         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
176
177         pItemProxy->SetItemMargin(margin);
178
179         SetUpdateState(true);
180         return E_SUCCESS;
181 }
182
183 result
184 Layout::GetItemMargin(const LayoutItem& item, ItemMargin& margin) const
185 {
186         ClearLastResult();
187
188         LayoutItemProxy* pItemProxy = __pProxyList->GetItemProxy(item);
189         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
190
191         margin = pItemProxy->GetItemMargin();
192
193         return E_SUCCESS;
194 }
195
196 result
197 Layout::SetItemWidthMatchMode(const LayoutItem& item, const LayoutMatchMode matchMode)
198 {
199         ClearLastResult();
200
201         LayoutItemProxy* pItemProxy = __pProxyList->GetItemProxy(item);
202         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
203
204         pItemProxy->SetItemWidthMatchMode(matchMode);
205
206         SetUpdateState(true);
207         return E_SUCCESS;
208 }
209
210 result
211 Layout::GetItemWidthMatchMode(const LayoutItem& item, LayoutMatchMode& matchMode) const
212 {
213         ClearLastResult();
214
215         LayoutItemProxy* pItemProxy = __pProxyList->GetItemProxy(item);
216         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
217
218         matchMode = pItemProxy->GetItemWidthMatchMode();
219
220         return E_SUCCESS;
221 }
222
223 result
224 Layout::SetItemHeightMatchMode(const LayoutItem& item, const LayoutMatchMode matchMode)
225 {
226         ClearLastResult();
227
228         LayoutItemProxy* pItemProxy = __pProxyList->GetItemProxy(item);
229         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
230
231         pItemProxy->SetItemHeightMatchMode(matchMode);
232
233         return E_SUCCESS;
234 }
235
236 result
237 Layout::GetItemHeightMatchMode(const LayoutItem& item, LayoutMatchMode& matchMode) const
238 {
239         ClearLastResult();
240
241         LayoutItemProxy* pItemProxy = __pProxyList->GetItemProxy(item);
242         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
243
244         matchMode = pItemProxy->GetItemHeightMatchMode();
245
246         return E_SUCCESS;
247 }
248
249 result
250 Layout::SetItemBaseRect(const LayoutItem& item, const LayoutRect baseRect)
251 {
252         ClearLastResult();
253
254         LayoutItemProxy* pItemProxy = __pProxyList->GetItemProxy(item);
255         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
256
257         pItemProxy->SetItemBaseRect(baseRect);
258
259         SetUpdateState(true);
260         return E_SUCCESS;
261 }
262
263 result
264 Layout::GetItemBaseRect(const LayoutItem& item, LayoutRect& baseRect) const
265 {
266         ClearLastResult();
267
268         LayoutItemProxy* pItemProxy = __pProxyList->GetItemProxy(item);
269         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
270
271         baseRect = pItemProxy->GetItemBaseRect();
272
273         return E_SUCCESS;
274 }
275
276 bool
277 Layout::ItemExists(LayoutItem& item)
278 {
279         if (__pProxyList->GetItemProxy(item) != null)
280         {
281                 return true;
282         }
283         return false;
284 }
285
286 LayoutUpdateFlag
287 Layout::CheckParentFlag(void)
288 {
289         ClearLastResult();
290
291         if (__rootLayout)
292         {
293                 return UPDATEFLAG_NO_FLAG;
294         }
295
296         LayoutItemProxy* pContainerProxy = GetContainerProxy();
297         SysTryReturn(NID_UI, pContainerProxy != null, UPDATEFLAG_ERROR, E_INVALID_STATE, "[E_INVALID_STATE] Did not set the container.");
298
299         Layout* pParentLayout = pContainerProxy->GetParentLayout();
300         SysTryReturn(NID_UI, pParentLayout != null, UPDATEFLAG_ERROR, E_INVALID_STATE, "[E_INVALID_STATE] Layout does not exist.");
301
302         LayoutItemProxy* pParentContainerProxy = pParentLayout->GetContainerProxy();
303         SysTryReturn(NID_UI, pContainerProxy != null, UPDATEFLAG_ERROR, E_INVALID_STATE, "[E_INVALID_STATE] Did not set the parent container.");
304
305         return CheckFlagInternal(*pParentContainerProxy);
306 }
307
308 LayoutUpdateFlag
309 Layout::CheckCurrentFlag(void)
310 {
311         ClearLastResult();
312
313         if (__rootLayout)
314         {
315                 return UPDATEFLAG_NO_FLAG;
316         }
317
318         LayoutItemProxy* pContainerProxy = GetContainerProxy();
319         SysTryReturn(NID_UI, pContainerProxy != null, UPDATEFLAG_ERROR, E_INVALID_STATE, "[E_INVALID_STATE] Did not set the container.");
320
321         return  CheckFlagInternal(*pContainerProxy);
322 }
323
324 LayoutUpdateFlag
325 Layout::CheckFlagInternal(LayoutItemProxy& containerProxy)
326 {
327         int updateFlag = 0;
328
329         LayoutMatchMode widthMode = containerProxy.GetItemWidthMatchMode();
330         LayoutMatchMode heightMode = containerProxy.GetItemHeightMatchMode();
331         ItemAlign align = containerProxy.GetItemAlignment();
332
333         if (widthMode == NONE_MODE && heightMode == NONE_MODE)
334         {
335                 updateFlag |= UPDATEFLAG_NONE_MODE;
336         }
337
338         if (widthMode == MATCH_PARENT || heightMode == MATCH_PARENT)
339         {
340                 updateFlag |= UPDATEFLAG_MATCH_PARENT;
341         }
342
343         if (widthMode == WRAP_CONTENT || heightMode == WRAP_CONTENT)
344         {
345                 updateFlag |= UPDATEFLAG_WRAPCONTENT;
346         }
347
348         if (align.HAlign != ITEM_HORIZONTAL_ALIGN_LEFT || align.VAlign != ITEM_VERTICAL_ALIGN_TOP)
349         {
350                 updateFlag |= UPDATEFLAG_ALIGNMENT;
351         }
352
353         return static_cast <LayoutUpdateFlag>(updateFlag);
354
355 }
356
357 result
358 Layout::UpdateLayout(void)
359 {
360         result r = UpdateLayoutInternal(UPDATEFLAG_NO_FLAG);
361         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Failed to UpdateLayout.", GetErrorMessage(r));
362         r = DetermineWindowRectToAllItem();
363         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Failed to DetermineWindowRectToAllItem.", GetErrorMessage(r));
364
365         return r;
366 }
367
368 result
369 Layout::DetermineWindowRectToAllItem(void)
370 {
371         ClearLastResult();
372
373         LayoutItemProxy* pContainerProxy = GetContainerProxy();
374         SysTryReturn(NID_UI, pContainerProxy != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Did not set the container.");
375
376         if (__rootLayout)
377         {
378                 if (__determineState)
379                 {
380                         OnDetermine();
381                         __determineState = false;
382                 }
383         }
384         else
385         {
386                 Layout* pParentLayout = pContainerProxy->GetParentLayout();
387                 SysTryReturn(NID_UI, pParentLayout != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Layout does not exist.");
388                 return pParentLayout->DetermineWindowRectToAllItem();
389         }
390
391         return E_SUCCESS;
392 }
393
394 result
395 Layout::OnDetermine(void)
396 {
397         ProxyList* pProxyList = GetProxyList();
398         SysAssertf(pProxyList != null, "ProxyList is invalid");
399
400         LayoutItemProxy* pContainerProxy = GetContainerProxy();
401         SysTryReturn(NID_UI, pContainerProxy != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Did not set the container.");
402
403         LayoutRect itemRect;
404         pContainerProxy->GetItemWindowRect(itemRect);
405         pContainerProxy->SetItemWindowRect(itemRect, false);
406
407         ProxyListNode* pCurNode = pProxyList->GetFirstNode();
408         while (pCurNode != null)
409         {
410                 LayoutItemProxy* pItemProxy = pCurNode->GetItemProxy();
411                 LayoutContainer* pCurContainer = dynamic_cast<LayoutContainer*>(pItemProxy->GetItem());
412                 SysTryReturn(NID_UI, pCurContainer != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] This item is not container.");
413
414                 pCurContainer->GetLayout()->OnDetermine();
415
416                 pCurNode = pProxyList->GetNextNode(*pCurNode);
417         }
418
419         return E_SUCCESS;
420 }
421
422
423 void
424 Layout::SetUpdateState(bool state)
425 {
426         ClearLastResult();
427
428         LayoutItemProxy* pContainerProxy = GetContainerProxy();
429
430         SysTryReturnVoidResult(NID_UI, pContainerProxy != null, E_INVALID_STATE, "[E_INVALID_STATE] Did not set the container.");
431
432         if (__rootLayout)
433         {
434                 __updateState = state;
435         }
436         else
437         {
438                 Layout* pParentLayout = pContainerProxy->GetParentLayout();
439                 SysTryReturnVoidResult(NID_UI, pParentLayout != null, E_INVALID_STATE, "[E_INVALID_STATE] Layout does not exist.");
440                 return pParentLayout->SetUpdateState(state);
441         }
442 }
443
444 result
445 Layout::PartialUpdateLayout(void)
446 {
447         ClearLastResult();
448
449         LayoutUpdateFlag flag = CheckCurrentFlag();
450         SysTryReturn(NID_UI, flag != UPDATEFLAG_ERROR, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] CheckCurrentFlag is failed.");
451
452         return UpdateLayoutInternal(flag);
453
454 }
455
456 result
457 Layout::OnLayoutTrigger(Layout& layout, bool layoutUpdating)
458 {
459         ClearLastResult();
460
461         LayoutItemProxy* pContainerProxy = layout.GetContainerProxy();
462
463         SysTryReturn(NID_UI, pContainerProxy != null, E_INVALID_STATE, E_INVALID_STATE,
464                                 "[E_INVALID_STATE] Did not set the container.");
465
466         LayoutRect containerRect;
467         pContainerProxy->GetItemWindowRect(containerRect);
468         LayoutContainer* pContainer = dynamic_cast <LayoutContainer*>(pContainerProxy->GetItem());
469         SysTryReturn(NID_UI, pContainer != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Did not set the container.");
470         pContainer->ConvertWindowToClientBounds(containerRect, containerRect);
471
472         LayoutSize containerSize;
473         containerSize.w = containerRect.w;
474         containerSize.h = containerRect.h;
475         pContainer->SetIntendedWindowSize(containerSize);
476
477         return layout.OnLayout(containerRect.w, containerRect.h, layoutUpdating);
478 }
479
480 result
481 Layout::UpdateLayoutInternal(LayoutUpdateFlag updateFlag)
482 {
483         ClearLastResult();
484
485         LayoutItemProxy* pContainerProxy = GetContainerProxy();
486
487         SysTryReturn(NID_UI, pContainerProxy != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Did not set the container.");
488
489         if (__rootLayout)
490         {
491                 if (__updateState)
492                 {
493                         if (updateFlag == UPDATEFLAG_NO_FLAG)
494                         {
495                                 __updateState = false;
496                         }
497                         __determineState = true;
498                         return OnLayoutTrigger(*this, true);
499                 }
500                 else
501                 {
502                         return E_SUCCESS;
503                 }
504         }
505         else
506         {
507                 Layout* pParentLayout = pContainerProxy->GetParentLayout();
508                 SysTryReturn(NID_UI, pParentLayout != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Layout does not exist.");
509
510                 if (updateFlag != UPDATEFLAG_NO_FLAG)
511                 {
512                         if (updateFlag & UPDATEFLAG_MATCH_PARENT || updateFlag & UPDATEFLAG_ALIGNMENT || pParentLayout->__partialUpdateState)
513                         {
514                                 LayoutUpdateFlag parentflag = CheckParentFlag();
515                                 SysTryReturn(NID_UI, parentflag != UPDATEFLAG_ERROR, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] CheckParentFlag is failed.");
516
517                                 if (parentflag & UPDATEFLAG_MATCH_PARENT || parentflag & UPDATEFLAG_ALIGNMENT || pParentLayout->__partialUpdateState)
518                                 {
519                                         return pParentLayout->UpdateLayoutInternal(parentflag);
520                                 }
521                                 else
522                                 {
523                                         return OnLayoutTrigger(*pParentLayout, true);
524                                 }
525                         }
526                         else
527                         {
528                                 return OnLayoutTrigger(*this, true);
529                         }
530                 }
531
532                 return pParentLayout->UpdateLayoutInternal(UPDATEFLAG_NO_FLAG);
533         }
534 }
535
536 result
537 Layout::AddItem(LayoutItem& addItem)
538 {
539         //ClearLastResult();
540         result r = CheckItem(addItem);
541         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
542
543         LayoutItemProxy* pItemProxy = CreateProxy(addItem);
544         SysTryReturn(NID_UI, pItemProxy != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to create proxy of layout item.");
545
546         LayoutContainer* pContainer = dynamic_cast <LayoutContainer*>(&addItem);
547         if (pContainer != null)
548         {
549                 LayoutListNode* pCurNode = pContainer->GetLayoutList()->GetFirstNode();
550
551                 while (pCurNode)
552                 {
553                         Layout* pLayout = pCurNode->GetLayout();
554                         if (pLayout != null)
555                         {
556                                 if (pLayout->__rootLayout == true)
557                                 {
558                                         delete pLayout->__pContainerProxy;
559                                         pLayout->__pContainerProxy = pItemProxy;
560                                         pLayout->__rootLayout = false;
561                                 }
562                         }
563                         pCurNode = pContainer->GetLayoutList()->GetNextNode(*pCurNode);
564                 }
565         }
566
567         if (__pProxyList->AddNode(*pItemProxy) == null)
568         {
569                 pItemProxy->Destroy();
570                 r = GetLastResult();
571                 SysTryReturn(NID_UI, false, r, r, "[%s] Failed to add layout item.", GetErrorMessage(r));
572         }
573
574         pItemProxy->SetParentLayout(this);
575         pItemProxy->SetParentContainer(static_cast <LayoutContainer*>(__pContainerProxy->GetItem()));
576
577         LayoutRect itemRect;
578         pItemProxy->GetItemWindowRect(itemRect);
579
580         pItemProxy->SetItemBaseRect(itemRect);
581
582         SetUpdateState(true);
583         return E_SUCCESS;
584 }
585
586 result
587 Layout::RemoveItem(const LayoutItem& removeItem)
588 {
589         ClearLastResult();
590
591         LayoutItemProxy* pItemProxy = __pProxyList->GetItemProxy(removeItem);
592         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_STATE, E_INVALID_STATE,
593                                 "[E_INVALID_STATE] Control dose not belong to layout.");
594
595         result r = __pProxyList->RemoveNode(*pItemProxy);
596         if (r != E_SUCCESS)
597         {
598                 SysLog(NID_UI, "Failed to RemoveNode()");
599                 SysTryReturn(NID_UI, r, r, r, "[E_INVALID_STATE] Failed to remove layout item.");
600         }
601
602         pItemProxy->SetParentLayout(null);
603         pItemProxy->SetParentContainer(null);
604         pItemProxy->Destroy();
605
606         return E_SUCCESS;
607 }
608
609 result
610 Layout::OnChangeViewPosition(int viewPosX, int viewPosY)
611 {
612         ClearLastResult();
613
614         if (viewPosX != 0 || viewPosY != 0)
615         {
616                 ProxyListNode* pNode = __pProxyList->GetFirstNode();
617                 while (pNode != null)
618                 {
619                         LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
620                         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_STATE, E_INVALID_STATE,
621                                                 "[E_INVALID_STATE] Layout proxy list error.");
622
623                         LayoutRect itemRect;
624                         pItemProxy->GetItemWindowRect(itemRect);
625                         itemRect.x += viewPosX;
626                         itemRect.y += viewPosY;
627                         result r = pItemProxy->SetItemWindowRect(itemRect);
628                         if (r != E_SUCCESS)
629                         {
630                                 return r;
631                         }
632
633                         pNode = __pProxyList->GetNextNode(*pNode);
634                 }
635
636                 __x += viewPosX;
637                 __y += viewPosY;
638         }
639
640         return E_SUCCESS;
641 }
642
643 result
644 Layout::CalculateAlignment(const LayoutAlignMode alignMode)
645 {
646         ClearLastResult();
647
648         result r = E_SUCCESS;
649         bool needMeasure = false;
650
651         SysAssertf(__pProxyList != null, "ProxyList is invalid.");
652
653         ProxyListNode* pNode = __pProxyList->GetFirstNode();
654         while (pNode != null)
655         {
656                 LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
657                 SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Layout proxy list error.");
658
659                 ItemAlign align = pItemProxy->GetItemAlignment();
660                 ItemMargin margin = pItemProxy->GetItemMargin();
661                 LayoutRect itemRect;
662                 pItemProxy->GetItemWindowRect(itemRect);
663
664                 if (alignMode == BOTH || alignMode == HORIZONTALONLY)
665                 {
666                         switch (align.HAlign)
667                         {
668                         case ITEM_HORIZONTAL_ALIGN_LEFT:
669                         {
670                                 itemRect.x = __x + margin.left;
671                                 break;
672                         }
673
674                         case ITEM_HORIZONTAL_ALIGN_CENTER:
675                         {
676                                 itemRect.x = (__x + (__width / 2)) - (itemRect.w / 2);
677                                 break;
678                         }
679
680                         case ITEM_HORIZONTAL_ALIGN_RIGHT:
681                         {
682                                 itemRect.x = (__x + __width) - (itemRect.w + margin.right);
683                                 break;
684                         }
685
686                         case ITEM_HORIZONTAL_ALIGN_LEFT_RIGHT:
687                         {
688                                 itemRect.x = __x + margin.left;
689                                 itemRect.w = __width - (margin.left + margin.right);
690                                 needMeasure = true;
691                                 break;
692                         }
693                         }
694 #ifdef NOT_SUPPORT_NEGATIVE_SIZE
695                         if (itemRect.w < 0)
696                         {
697                                 itemRect.w = 0;
698                         }
699 #endif
700                 }
701
702                 if (alignMode == BOTH || alignMode == VERTICALONLY)
703                 {
704                         switch (align.VAlign)
705                         {
706                         case ITEM_VERTICAL_ALIGN_TOP:
707                         {
708                                 itemRect.y = __y + margin.top;
709                                 break;
710                         }
711
712                         case ITEM_VERTICAL_ALIGN_MIDDLE:
713                         {
714                                 itemRect.y = (__y + (__height / 2)) - (itemRect.h / 2);
715                                 break;
716                         }
717
718                         case ITEM_VERTICAL_ALIGN_BOTTOM:
719                         {
720                                 itemRect.y = (__y + __height) - (itemRect.h + margin.bottom);
721                                 break;
722                         }
723
724                         case ITEM_VERTICAL_ALIGN_TOP_BOTTOM:
725                         {
726                                 itemRect.y = __y + margin.top;
727                                 itemRect.h = __height - (margin.top + margin.bottom);
728                                 needMeasure = true;
729                                 break;
730                         }
731                         }
732 #ifdef NOT_SUPPORT_NEGATIVE_SIZE
733                         if (itemRect.h < 0)
734                         {
735                                 itemRect.h = 0;
736                         }
737 #endif
738                 }
739
740                 if (needMeasure)
741                 {
742                         r = pItemProxy->Measure(itemRect.w, itemRect.h);
743                         if (r != E_SUCCESS)
744                         {
745                                 return r;
746                         }
747                         pItemProxy->GetMeasuredSize(itemRect.w, itemRect.h);
748                 }
749                 r = pItemProxy->SetItemWindowRect(itemRect);
750                 if (r != E_SUCCESS)
751                 {
752                         return r;
753                 }
754
755                 pNode = __pProxyList->GetNextNode(*pNode);
756         }
757
758         return E_SUCCESS;
759 }
760
761 result
762 Layout::SetContainer(LayoutContainer* pContainer)
763 {
764         ClearLastResult();
765
766         if (pContainer == null)
767         {
768                 ProxyListNode* pNode = __pProxyList->GetFirstNode();
769                 while (pNode != null)
770                 {
771                         LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
772                         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_STATE, E_INVALID_STATE,
773                                                 "[E_INVALID_STATE] Layout proxy list error.");
774
775                         pItemProxy->SetParentContainer(null);
776
777                         pNode = __pProxyList->GetNextNode(*pNode);
778                 }
779
780                 if (__pContainerProxy)
781                 {
782                         if (__rootLayout)
783                         {
784                                 //__pContainerProxy->Destroy();
785                                 delete __pContainerProxy;
786                                 __rootLayout = false;
787                         }
788                         __pContainerProxy = null;
789                 }
790
791                 return E_SUCCESS;
792         }
793
794         LayoutContainer* pParentContainer = pContainer->GetParentContainer();
795         if (pParentContainer == null)
796         {
797                 if (__rootLayout && __pContainerProxy != null)
798                 {
799                         delete __pContainerProxy;
800                 }
801
802                 __pContainerProxy = CreateProxy(*pContainer);
803                 SysTryReturn(NID_UI, __pContainerProxy != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to create proxy of layout item.");
804
805                 __rootLayout = true;
806         }
807         else
808         {
809                 Layout* pParentLayout = pParentContainer->GetLayout();
810                 SysTryReturn(NID_UI, pParentLayout, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Did not set a layout.");
811
812                 ProxyListNode* pNode = pParentLayout->__pProxyList->GetFirstNode();
813                 while (pNode != null)
814                 {
815                         LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
816                         if (pItemProxy == null)
817                         {
818                                 return E_INVALID_STATE;
819                         }
820                         LayoutContainer* pResultContainer = dynamic_cast <LayoutContainer*>(pItemProxy->GetItem());
821                         if (pContainer == pResultContainer)
822                         {
823                                 if (__rootLayout && __pContainerProxy != null)
824                                 {
825                                         delete __pContainerProxy;
826                                         __rootLayout = false;
827                                 }
828                                 __pContainerProxy = pItemProxy;
829                                 break;
830                         }
831                         pNode = __pProxyList->GetNextNode(*pNode);
832                 }
833         }
834
835         return E_SUCCESS;
836 }
837
838 LayoutItemProxy*
839 Layout::CreateProxy(LayoutItem& item)
840 {
841         return LayoutItemProxy::Create(*this, item);
842 }
843
844 void
845 Layout::SetRootLayout(bool rootCheck)
846 {
847         __rootLayout = rootCheck;
848 }
849
850 result
851 Layout::CheckItem(const LayoutItem& checkItem)
852 {
853         ClearLastResult();
854
855         ProxyListNode* pNode = __pProxyList->GetFirstNode();
856         while (pNode != null)
857         {
858                 LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
859                 SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Invalid proxy list node.");
860
861                 LayoutItem* pItem = pItemProxy->GetItem();
862                 SysTryReturn(NID_UI, pItem != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Invalid layout item.");
863
864                 SysTryReturn(NID_UI, &checkItem != pItem, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Control belong to layout.");
865
866                 pNode = __pProxyList->GetNextNode(*pNode);
867         }
868
869         return E_SUCCESS;
870 }
871
872 bool
873 Layout::HasLayoutContainer(void)
874 {
875         return __pContainerProxy != null;
876 }
877
878 void
879 Layout::SetPartialUpdateFlag(bool flag)
880 {
881         __partialUpdateState = flag;
882 }
883
884 void
885 Layout::SetItemList(ProxyList* pItemList)
886 {
887         __pProxyList = pItemList;
888 }
889
890 ProxyList*
891 Layout::GetProxyList(void) const
892 {
893         return __pProxyList;
894 }
895
896 }}} // Tizen::Ui::_Layout