fixed bug (TapGesture improvement)
[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 "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.0f)
37         , __y(0.0f)
38         , __width(0.0f)
39         , __height(0.0f)
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 = static_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 = static_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 = static_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         SetUpdateState(true);
234         return E_SUCCESS;
235 }
236
237 result
238 Layout::GetItemHeightMatchMode(const LayoutItem& item, LayoutMatchMode& matchMode) const
239 {
240         ClearLastResult();
241
242         LayoutItemProxy* pItemProxy = __pProxyList->GetItemProxy(item);
243         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
244
245         matchMode = pItemProxy->GetItemHeightMatchMode();
246
247         return E_SUCCESS;
248 }
249
250 result
251 Layout::SetItemBaseRect(const LayoutItem& item, const LayoutRect baseRect)
252 {
253         ClearLastResult();
254
255         LayoutItemProxy* pItemProxy = __pProxyList->GetItemProxy(item);
256         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
257
258         pItemProxy->SetItemBaseRect(baseRect);
259
260         SetUpdateState(true);
261         return E_SUCCESS;
262 }
263
264 result
265 Layout::GetItemBaseRect(const LayoutItem& item, LayoutRect& baseRect) const
266 {
267         ClearLastResult();
268
269         LayoutItemProxy* pItemProxy = __pProxyList->GetItemProxy(item);
270         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Control dose not belong to layout.");
271
272         baseRect = pItemProxy->GetItemBaseRect();
273
274         return E_SUCCESS;
275 }
276
277 bool
278 Layout::ItemExists(LayoutItem& item)
279 {
280         if (__pProxyList->GetItemProxy(item) != null)
281         {
282                 return true;
283         }
284         return false;
285 }
286
287 LayoutUpdateFlag
288 Layout::CheckParentFlag(void)
289 {
290         ClearLastResult();
291
292         if (__rootLayout)
293         {
294                 return UPDATEFLAG_NO_FLAG;
295         }
296
297         LayoutItemProxy* pContainerProxy = GetContainerProxy();
298         SysTryReturn(NID_UI, pContainerProxy != null, UPDATEFLAG_ERROR, E_INVALID_STATE, "[E_INVALID_STATE] Did not set the container.");
299
300         Layout* pParentLayout = pContainerProxy->GetParentLayout();
301         SysTryReturn(NID_UI, pParentLayout != null, UPDATEFLAG_ERROR, E_INVALID_STATE, "[E_INVALID_STATE] Layout does not exist.");
302
303         LayoutItemProxy* pParentContainerProxy = pParentLayout->GetContainerProxy();
304         SysTryReturn(NID_UI, pContainerProxy != null, UPDATEFLAG_ERROR, E_INVALID_STATE, "[E_INVALID_STATE] Did not set the parent container.");
305
306         return CheckFlagInternal(*pParentContainerProxy);
307 }
308
309 LayoutUpdateFlag
310 Layout::CheckCurrentFlag(void)
311 {
312         ClearLastResult();
313
314         if (__rootLayout)
315         {
316                 return UPDATEFLAG_NO_FLAG;
317         }
318
319         LayoutItemProxy* pContainerProxy = GetContainerProxy();
320         SysTryReturn(NID_UI, pContainerProxy != null, UPDATEFLAG_ERROR, E_INVALID_STATE, "[E_INVALID_STATE] Did not set the container.");
321
322         return  CheckFlagInternal(*pContainerProxy);
323 }
324
325 LayoutUpdateFlag
326 Layout::CheckFlagInternal(LayoutItemProxy& containerProxy)
327 {
328         int updateFlag = 0;
329
330         LayoutMatchMode widthMode = containerProxy.GetItemWidthMatchMode();
331         LayoutMatchMode heightMode = containerProxy.GetItemHeightMatchMode();
332         ItemAlign align = containerProxy.GetItemAlignment();
333
334         if (widthMode == NONE_MODE && heightMode == NONE_MODE)
335         {
336                 updateFlag |= UPDATEFLAG_NONE_MODE;
337         }
338
339         if (widthMode == MATCH_PARENT || heightMode == MATCH_PARENT)
340         {
341                 updateFlag |= UPDATEFLAG_MATCH_PARENT;
342         }
343
344         if (widthMode == WRAP_CONTENT || heightMode == WRAP_CONTENT)
345         {
346                 updateFlag |= UPDATEFLAG_WRAPCONTENT;
347         }
348
349         if (align.HAlign != ITEM_HORIZONTAL_ALIGN_LEFT || align.VAlign != ITEM_VERTICAL_ALIGN_TOP)
350         {
351                 updateFlag |= UPDATEFLAG_ALIGNMENT;
352         }
353
354         return static_cast <LayoutUpdateFlag>(updateFlag);
355
356 }
357
358 result
359 Layout::UpdateLayout(void)
360 {
361         result r = UpdateLayoutInternal(UPDATEFLAG_NO_FLAG);
362         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Failed to UpdateLayout.", GetErrorMessage(r));
363         r = DetermineWindowRectToAllItem();
364         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Failed to DetermineWindowRectToAllItem.", GetErrorMessage(r));
365
366         return r;
367 }
368
369 result
370 Layout::DetermineWindowRectToAllItem(void)
371 {
372         ClearLastResult();
373
374         LayoutItemProxy* pContainerProxy = GetContainerProxy();
375         SysTryReturn(NID_UI, pContainerProxy != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Did not set the container.");
376
377         if (__rootLayout)
378         {
379                 if (__determineState)
380                 {
381                         OnDetermine();
382                         __determineState = false;
383                 }
384         }
385         else
386         {
387                 Layout* pParentLayout = pContainerProxy->GetParentLayout();
388                 SysTryReturn(NID_UI, pParentLayout != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Layout does not exist.");
389                 return pParentLayout->DetermineWindowRectToAllItem();
390         }
391
392         return E_SUCCESS;
393 }
394
395 result
396 Layout::OnDetermine(void)
397 {
398         ProxyList* pProxyList = GetProxyList();
399         SysAssertf(pProxyList != null, "ProxyList is invalid");
400
401         LayoutItemProxy* pContainerProxy = GetContainerProxy();
402         SysTryReturn(NID_UI, pContainerProxy != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Did not set the container.");
403
404         LayoutRect itemRect;
405         pContainerProxy->GetItemWindowRect(itemRect);
406         pContainerProxy->SetItemWindowRect(itemRect, false);
407
408         itemRect.x = 0.0f;
409         itemRect.y = 0.0f;
410         itemRect.w = 0.0f;
411         itemRect.h = 0.0f;
412         pContainerProxy->SetItemWindowRect(itemRect, true);
413
414         ProxyListNode* pCurNode = pProxyList->GetFirstNode();
415         while (pCurNode != null)
416         {
417                 LayoutItemProxy* pItemProxy = pCurNode->GetItemProxy();
418                 LayoutContainer* pCurContainer = static_cast<LayoutContainer*>(pItemProxy->GetItem());
419                 SysTryReturn(NID_UI, pCurContainer != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] This item is not container.");
420
421                 pCurContainer->GetLayout()->OnDetermine();
422
423                 pCurNode = pProxyList->GetNextNode(*pCurNode);
424         }
425
426         return E_SUCCESS;
427 }
428
429
430 void
431 Layout::SetUpdateState(bool state)
432 {
433         ClearLastResult();
434
435         LayoutItemProxy* pContainerProxy = GetContainerProxy();
436
437         SysTryReturnVoidResult(NID_UI, pContainerProxy != null, E_INVALID_STATE, "[E_INVALID_STATE] Did not set the container.");
438
439         if (__rootLayout)
440         {
441                 __updateState = state;
442         }
443         else
444         {
445                 Layout* pParentLayout = pContainerProxy->GetParentLayout();
446                 SysTryReturnVoidResult(NID_UI, pParentLayout != null, E_INVALID_STATE, "[E_INVALID_STATE] Layout does not exist.");
447                 return pParentLayout->SetUpdateState(state);
448         }
449 }
450
451 result
452 Layout::PartialUpdateLayout(void)
453 {
454         ClearLastResult();
455
456         LayoutUpdateFlag flag = CheckCurrentFlag();
457         SysTryReturn(NID_UI, flag != UPDATEFLAG_ERROR, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] CheckCurrentFlag is failed.");
458
459         result r = UpdateLayoutInternal(flag);
460         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Failed to UpdateLayout.", GetErrorMessage(r));
461         r = OnDetermine();
462         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Failed to OnDetermine.", GetErrorMessage(r));
463
464         return r;
465
466 }
467
468 result
469 Layout::OnLayoutTrigger(Layout& layout, bool layoutUpdating)
470 {
471         ClearLastResult();
472
473         LayoutItemProxy* pContainerProxy = layout.GetContainerProxy();
474
475         SysTryReturn(NID_UI, pContainerProxy != null, E_INVALID_STATE, E_INVALID_STATE,
476                                 "[E_INVALID_STATE] Did not set the container.");
477
478         LayoutRect containerRect;
479         pContainerProxy->GetItemWindowRect(containerRect);
480         LayoutContainer* pContainer = static_cast <LayoutContainer*>(pContainerProxy->GetItem());
481         SysTryReturn(NID_UI, pContainer != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Did not set the container.");
482
483         LayoutRect containerClientRect = {0.0f, 0.0f, containerRect.w, containerRect.h};
484         pContainer->ConvertWindowToClientBounds(containerClientRect, containerClientRect);
485
486         LayoutSize containerSize = {containerClientRect.w, containerClientRect.h};
487
488         pContainer->SetIntendedWindowSize(containerSize);
489         return layout.OnLayout(containerRect.w, containerRect.h, layoutUpdating);
490 }
491
492 result
493 Layout::UpdateLayoutInternal(LayoutUpdateFlag updateFlag)
494 {
495         ClearLastResult();
496
497         LayoutItemProxy* pContainerProxy = GetContainerProxy();
498
499         SysTryReturn(NID_UI, pContainerProxy != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Did not set the container.");
500
501         if (__rootLayout)
502         {
503                 if (__updateState)
504                 {
505                         if (updateFlag == UPDATEFLAG_NO_FLAG)
506                         {
507                                 __updateState = false;
508                         }
509                         __determineState = true;
510                         return OnLayoutTrigger(*this, true);
511                 }
512                 else
513                 {
514                         return E_SUCCESS;
515                 }
516         }
517         else
518         {
519                 Layout* pParentLayout = pContainerProxy->GetParentLayout();
520                 SysTryReturn(NID_UI, pParentLayout != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Layout does not exist.");
521
522                 if (updateFlag != UPDATEFLAG_NO_FLAG)
523                 {
524                         if (updateFlag & UPDATEFLAG_MATCH_PARENT || updateFlag & UPDATEFLAG_ALIGNMENT || pParentLayout->__partialUpdateState)
525                         {
526                                 LayoutUpdateFlag parentflag = CheckParentFlag();
527                                 SysTryReturn(NID_UI, parentflag != UPDATEFLAG_ERROR, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] CheckParentFlag is failed.");
528
529                                 if (parentflag & UPDATEFLAG_MATCH_PARENT || parentflag & UPDATEFLAG_ALIGNMENT || pParentLayout->__partialUpdateState)
530                                 {
531                                         return pParentLayout->UpdateLayoutInternal(parentflag);
532                                 }
533                                 else
534                                 {
535                                         return OnLayoutTrigger(*pParentLayout, true);
536                                 }
537                         }
538                         else
539                         {
540                                 return OnLayoutTrigger(*this, true);
541                         }
542                 }
543
544                 return pParentLayout->UpdateLayoutInternal(UPDATEFLAG_NO_FLAG);
545         }
546 }
547
548 result
549 Layout::AddItem(LayoutItem& addItem)
550 {
551         LayoutItemProxy* pItemProxy = CreateProxy(addItem);
552         SysTryReturn(NID_UI, pItemProxy != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to create proxy of layout item.");
553
554         LayoutContainer* pContainer = static_cast <LayoutContainer*>(&addItem);
555         if (pContainer != null)
556         {
557                 LayoutListNode* pCurNode = pContainer->GetLayoutList()->GetFirstNode();
558
559                 while (pCurNode)
560                 {
561                         Layout* pLayout = pCurNode->GetLayout();
562                         if (pLayout != null)
563                         {
564                                 if (pLayout->__rootLayout == true)
565                                 {
566                                         delete pLayout->__pContainerProxy;
567                                         pLayout->__pContainerProxy = pItemProxy;
568                                         pLayout->__rootLayout = false;
569                                 }
570                         }
571                         pCurNode = pContainer->GetLayoutList()->GetNextNode(*pCurNode);
572                 }
573         }
574
575         if (__pProxyList->AddNode(*pItemProxy) == null)
576         {
577                 pItemProxy->Destroy();
578                 result r = GetLastResult();
579                 SysTryReturn(NID_UI, false, r, r, "[%s] Failed to add layout item.", GetErrorMessage(r));
580         }
581
582         pItemProxy->SetParentLayout(this);
583         pItemProxy->SetParentContainer(static_cast <LayoutContainer*>(__pContainerProxy->GetItem()));
584
585         LayoutRect itemRect;
586         pItemProxy->GetItemWindowRect(itemRect);
587
588         pItemProxy->SetItemBaseRect(itemRect);
589
590         SetUpdateState(true);
591         return E_SUCCESS;
592 }
593
594 result
595 Layout::RemoveItem(const LayoutItem& removeItem)
596 {
597         ClearLastResult();
598
599         LayoutItemProxy* pItemProxy = __pProxyList->GetItemProxy(removeItem);
600         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_STATE, E_INVALID_STATE,
601                                 "[E_INVALID_STATE] Control dose not belong to layout.");
602
603         result r = __pProxyList->RemoveNode(*pItemProxy);
604         if (r != E_SUCCESS)
605         {
606                 SysLog(NID_UI, "Failed to RemoveNode()");
607                 SysTryReturn(NID_UI, r, r, r, "[E_INVALID_STATE] Failed to remove layout item.");
608         }
609
610         pItemProxy->SetParentLayout(null);
611         pItemProxy->SetParentContainer(null);
612         pItemProxy->Destroy();
613
614         return E_SUCCESS;
615 }
616
617 result
618 Layout::OnChangeViewPosition(int viewPosX, int viewPosY)
619 {
620         ClearLastResult();
621
622         if (viewPosX != 0 || viewPosY != 0)
623         {
624                 ProxyListNode* pNode = __pProxyList->GetFirstNode();
625                 while (pNode != null)
626                 {
627                         LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
628                         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_STATE, E_INVALID_STATE,
629                                                 "[E_INVALID_STATE] Layout proxy list error.");
630
631                         LayoutRect itemRect;
632                         pItemProxy->GetItemWindowRect(itemRect);
633                         itemRect.x += viewPosX;
634                         itemRect.y += viewPosY;
635                         result r = pItemProxy->SetItemWindowRect(itemRect);
636                         if (r != E_SUCCESS)
637                         {
638                                 return r;
639                         }
640
641                         pNode = __pProxyList->GetNextNode(*pNode);
642                 }
643
644                 __x += viewPosX;
645                 __y += viewPosY;
646         }
647
648         return E_SUCCESS;
649 }
650
651 result
652 Layout::CalculateAlignment(const LayoutAlignMode alignMode)
653 {
654         ClearLastResult();
655
656         result r = E_SUCCESS;
657         bool needMeasure = false;
658
659         SysAssertf(__pProxyList != null, "ProxyList is invalid.");
660
661         ProxyListNode* pNode = __pProxyList->GetFirstNode();
662         while (pNode != null)
663         {
664                 LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
665                 SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Layout proxy list error.");
666
667                 ItemAlign align = pItemProxy->GetItemAlignment();
668                 ItemMargin margin = pItemProxy->GetItemMargin();
669                 LayoutRect itemRect;
670                 pItemProxy->GetItemWindowRect(itemRect);
671
672                 if (alignMode == BOTH || alignMode == HORIZONTALONLY)
673                 {
674                         switch (align.HAlign)
675                         {
676                         case ITEM_HORIZONTAL_ALIGN_LEFT:
677                         {
678                                 itemRect.x = __x + margin.left;
679                                 break;
680                         }
681
682                         case ITEM_HORIZONTAL_ALIGN_CENTER:
683                         {
684                                 itemRect.x = (__x + (__width / 2)) - (itemRect.w / 2);
685                                 break;
686                         }
687
688                         case ITEM_HORIZONTAL_ALIGN_RIGHT:
689                         {
690                                 itemRect.x = (__x + __width) - (itemRect.w + margin.right);
691                                 break;
692                         }
693
694                         case ITEM_HORIZONTAL_ALIGN_LEFT_RIGHT:
695                         {
696                                 itemRect.x = __x + margin.left;
697                                 itemRect.w = __width - (margin.left + margin.right);
698                                 needMeasure = true;
699                                 break;
700                         }
701                         }
702 #ifdef NOT_SUPPORT_NEGATIVE_SIZE
703                         if (itemRect.w < 0)
704                         {
705                                 itemRect.w = 0.0f;
706                         }
707 #endif
708                 }
709
710                 if (alignMode == BOTH || alignMode == VERTICALONLY)
711                 {
712                         switch (align.VAlign)
713                         {
714                         case ITEM_VERTICAL_ALIGN_TOP:
715                         {
716                                 itemRect.y = __y + margin.top;
717                                 break;
718                         }
719
720                         case ITEM_VERTICAL_ALIGN_MIDDLE:
721                         {
722                                 itemRect.y = (__y + (__height / 2)) - (itemRect.h / 2);
723                                 break;
724                         }
725
726                         case ITEM_VERTICAL_ALIGN_BOTTOM:
727                         {
728                                 itemRect.y = (__y + __height) - (itemRect.h + margin.bottom);
729                                 break;
730                         }
731
732                         case ITEM_VERTICAL_ALIGN_TOP_BOTTOM:
733                         {
734                                 itemRect.y = __y + margin.top;
735                                 itemRect.h = __height - (margin.top + margin.bottom);
736                                 needMeasure = true;
737                                 break;
738                         }
739                         }
740 #ifdef NOT_SUPPORT_NEGATIVE_SIZE
741                         if (itemRect.h < 0)
742                         {
743                                 itemRect.h = 0.0f;
744                         }
745 #endif
746                 }
747
748                 if (needMeasure)
749                 {
750                         r = pItemProxy->Measure(itemRect.w, itemRect.h);
751                         if (r != E_SUCCESS)
752                         {
753                                 return r;
754                         }
755                         pItemProxy->GetMeasuredSize(itemRect.w, itemRect.h);
756                 }
757                 r = pItemProxy->SetItemWindowRect(itemRect);
758                 if (r != E_SUCCESS)
759                 {
760                         return r;
761                 }
762
763                 pNode = __pProxyList->GetNextNode(*pNode);
764         }
765
766         return E_SUCCESS;
767 }
768
769 result
770 Layout::SetContainer(LayoutContainer* pContainer)
771 {
772         ClearLastResult();
773
774         if (pContainer == null)
775         {
776                 ProxyListNode* pNode = __pProxyList->GetFirstNode();
777                 while (pNode != null)
778                 {
779                         LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
780                         SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_STATE, E_INVALID_STATE,
781                                                 "[E_INVALID_STATE] Layout proxy list error.");
782
783                         pItemProxy->SetParentContainer(null);
784
785                         pNode = __pProxyList->GetNextNode(*pNode);
786                 }
787
788                 if (__pContainerProxy)
789                 {
790                         if (__rootLayout)
791                         {
792                                 //__pContainerProxy->Destroy();
793                                 delete __pContainerProxy;
794                                 __rootLayout = false;
795                         }
796                         __pContainerProxy = null;
797                 }
798
799                 return E_SUCCESS;
800         }
801
802         LayoutContainer* pParentContainer = pContainer->GetParentContainer();
803         if (pParentContainer == null)
804         {
805                 if (__rootLayout && __pContainerProxy != null)
806                 {
807                         delete __pContainerProxy;
808                 }
809
810                 __pContainerProxy = CreateProxy(*pContainer);
811                 SysTryReturn(NID_UI, __pContainerProxy != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to create proxy of layout item.");
812
813                 __rootLayout = true;
814         }
815         else
816         {
817                 Layout* pParentLayout = pParentContainer->GetLayout();
818                 SysTryReturn(NID_UI, pParentLayout, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Did not set a layout.");
819
820                 ProxyListNode* pNode = pParentLayout->__pProxyList->GetFirstNode();
821                 while (pNode != null)
822                 {
823                         LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
824                         if (pItemProxy == null)
825                         {
826                                 return E_INVALID_STATE;
827                         }
828                         LayoutContainer* pResultContainer = static_cast <LayoutContainer*>(pItemProxy->GetItem());
829                         if (pContainer == pResultContainer)
830                         {
831                                 if (__rootLayout && __pContainerProxy != null)
832                                 {
833                                         delete __pContainerProxy;
834                                         __rootLayout = false;
835                                 }
836                                 __pContainerProxy = pItemProxy;
837                                 break;
838                         }
839                         pNode = __pProxyList->GetNextNode(*pNode);
840                 }
841         }
842
843         return E_SUCCESS;
844 }
845
846 LayoutItemProxy*
847 Layout::CreateProxy(LayoutItem& item)
848 {
849         return LayoutItemProxy::Create(*this, item);
850 }
851
852 void
853 Layout::SetRootLayout(bool rootCheck)
854 {
855         __rootLayout = rootCheck;
856 }
857
858 result
859 Layout::CheckItem(const LayoutItem& checkItem)
860 {
861         ClearLastResult();
862
863         ProxyListNode* pNode = __pProxyList->GetFirstNode();
864         while (pNode != null)
865         {
866                 LayoutItemProxy* pItemProxy = pNode->GetItemProxy();
867                 SysTryReturn(NID_UI, pItemProxy != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Invalid proxy list node.");
868
869                 LayoutItem* pItem = pItemProxy->GetItem();
870                 SysTryReturn(NID_UI, pItem != null, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Invalid layout item.");
871
872                 SysTryReturn(NID_UI, &checkItem != pItem, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Control belong to layout.");
873
874                 pNode = __pProxyList->GetNextNode(*pNode);
875         }
876
877         return E_SUCCESS;
878 }
879
880 bool
881 Layout::HasLayoutContainer(void)
882 {
883         return __pContainerProxy != null;
884 }
885
886 void
887 Layout::SetPartialUpdateFlag(bool flag)
888 {
889         __partialUpdateState = flag;
890 }
891
892 void
893 Layout::SetItemList(ProxyList* pItemList)
894 {
895         __pProxyList = pItemList;
896 }
897
898 ProxyList*
899 Layout::GetProxyList(void) const
900 {
901         return __pProxyList;
902 }
903
904 }}} // Tizen::Ui::_Layout