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