Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / FUi_LayoutImpl.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_LayoutImpl.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 <FUiLayout.h>
25 #include <FUiRelativeLayout.h>
26 #include <FUiGridLayout.h>
27 #include <FUiVerticalBoxLayout.h>
28 #include <FUiHorizontalBoxLayout.h>
29 #include <FUiCardLayout.h>
30 #include "FUi_LayoutImpl.h"
31
32 using namespace Tizen::Base;
33
34 namespace Tizen { namespace Ui
35 {
36
37 namespace
38 {
39 static const int CONVERT_ERROR_CODE = -1;
40
41 _Layout::HorizontalAlign
42 ConvertEnum(const LayoutHorizontalAlignment val)
43 {
44         switch (val)
45         {
46         case LAYOUT_HORIZONTAL_ALIGN_LEFT:
47                 return _Layout::ITEM_HORIZONTAL_ALIGN_LEFT;
48
49         case LAYOUT_HORIZONTAL_ALIGN_RIGHT:
50                 return _Layout::ITEM_HORIZONTAL_ALIGN_RIGHT;
51
52         case LAYOUT_HORIZONTAL_ALIGN_CENTER:
53                 return _Layout::ITEM_HORIZONTAL_ALIGN_CENTER;
54
55         default:
56                 return static_cast <_Layout::HorizontalAlign>(CONVERT_ERROR_CODE);
57         }
58 }
59
60 LayoutHorizontalAlignment
61 ConvertEnum(const _Layout::HorizontalAlign val)
62 {
63         switch (val)
64         {
65         case _Layout::ITEM_HORIZONTAL_ALIGN_LEFT:
66                 return LAYOUT_HORIZONTAL_ALIGN_LEFT;
67
68         case _Layout::ITEM_HORIZONTAL_ALIGN_RIGHT:
69                 return LAYOUT_HORIZONTAL_ALIGN_RIGHT;
70
71         case _Layout::ITEM_HORIZONTAL_ALIGN_CENTER:
72                 return LAYOUT_HORIZONTAL_ALIGN_CENTER;
73
74         default:
75                 return static_cast <LayoutHorizontalAlignment>(CONVERT_ERROR_CODE);
76         }
77 }
78
79 _Layout::VerticalAlign
80 ConvertEnum(const LayoutVerticalAlignment val)
81 {
82         switch (val)
83         {
84         case LAYOUT_VERTICAL_ALIGN_TOP:
85                 return _Layout::ITEM_VERTICAL_ALIGN_TOP;
86
87         case LAYOUT_VERTICAL_ALIGN_BOTTOM:
88                 return _Layout::ITEM_VERTICAL_ALIGN_BOTTOM;
89
90         case LAYOUT_VERTICAL_ALIGN_MIDDLE:
91                 return _Layout::ITEM_VERTICAL_ALIGN_MIDDLE;
92
93         default:
94                 return static_cast <_Layout::VerticalAlign>(CONVERT_ERROR_CODE);
95         }
96 }
97
98 LayoutVerticalAlignment
99 ConvertEnum(const _Layout::VerticalAlign val)
100 {
101         switch (val)
102         {
103         case _Layout::ITEM_VERTICAL_ALIGN_TOP:
104                 return LAYOUT_VERTICAL_ALIGN_TOP;
105
106         case _Layout::ITEM_VERTICAL_ALIGN_BOTTOM:
107                 return LAYOUT_VERTICAL_ALIGN_BOTTOM;
108
109         case _Layout::ITEM_VERTICAL_ALIGN_MIDDLE:
110                 return LAYOUT_VERTICAL_ALIGN_MIDDLE;
111
112         default:
113                 return static_cast <LayoutVerticalAlignment>(CONVERT_ERROR_CODE);
114         }
115 }
116
117 _Layout::LayoutMatchMode
118 ConvertEnum(FitPolicy val)
119 {
120         switch (val)
121         {
122         case FIT_POLICY_FIXED:
123                 return _Layout::NONE_MODE;
124
125         case FIT_POLICY_CONTENT:
126                 return _Layout::WRAP_CONTENT;
127
128         case FIT_POLICY_PARENT:
129                 return _Layout::MATCH_PARENT;
130
131         default:
132                 return static_cast <_Layout::LayoutMatchMode>(CONVERT_ERROR_CODE);
133         }
134 }
135
136 FitPolicy
137 ConvertEnum(_Layout::LayoutMatchMode val)
138 {
139         switch (val)
140         {
141         case _Layout::NONE_MODE:
142                 return FIT_POLICY_FIXED;
143
144         case _Layout::WRAP_CONTENT:
145                 return FIT_POLICY_CONTENT;
146
147         case _Layout::MATCH_PARENT:
148                 return FIT_POLICY_PARENT;
149
150         default:
151                 return static_cast <FitPolicy>(CONVERT_ERROR_CODE);
152         }
153 }
154 }
155
156 // _LayoutImpl implementation
157 _LayoutImpl::_LayoutImpl(Layout* pPublicLayout, _Layout::Layout* pCoreLayout)
158         : _pPublicLayout(pPublicLayout)
159         , _pCoreLayout(pCoreLayout)
160 {
161 }
162
163 _LayoutImpl::~_LayoutImpl()
164 {
165         delete _pCoreLayout;
166 }
167
168 result
169 _LayoutImpl::CheckConstruction(_Layout::Layout* pCoreLayout, _LayoutImpl* pImplLayout)
170 {
171         if (pImplLayout == null)
172         {
173                 delete pCoreLayout;
174                 SysLogException(NID_UI, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
175                 return E_OUT_OF_MEMORY;
176         }
177
178         result r = GetLastResult();
179
180         if (IsFailed(r))
181         {
182                 delete pImplLayout;
183                 pImplLayout = null;
184
185                 SysLogException(NID_UI, r, "[%s] Propagating.", GetErrorMessage(r));
186                 return r;
187         }
188
189         return E_SUCCESS;
190 }
191
192 _SharedPtr <_LayoutImpl>
193 _LayoutImpl::GetLayoutImpl(Layout* pPublicLayout)
194 {
195         LayoutImplHolder* pHolder = static_cast <LayoutImplHolder*>(pPublicLayout->_pImpl);
196         SysAssert(pHolder != null);
197
198         return pHolder->layoutImpl;
199 }
200
201 void
202 _LayoutImpl::SetLayoutImpl(Layout* pPublicLayout, _LayoutImpl* pImplLayout)
203 {
204         LayoutImplHolder* pHolder = static_cast <LayoutImplHolder*>(pPublicLayout->_pImpl);
205         SysAssert(pHolder != null);
206
207         pHolder->layoutImpl.SetNull();
208         pHolder->layoutImpl.Bind(pImplLayout);
209 }
210
211 const char*
212 _LayoutImpl::GetPublicClassName(void) const
213 {
214         return "Tizen::Ui::Layout";
215 }
216
217 const Layout&
218 _LayoutImpl::GetPublic(void) const
219 {
220         return *_pPublicLayout;
221 }
222
223 Layout&
224 _LayoutImpl::GetPublic(void)
225 {
226         return *_pPublicLayout;
227 }
228
229 const _Layout::Layout&
230 _LayoutImpl::GetCore(void) const
231 {
232         return *_pCoreLayout;
233 }
234
235 _Layout::Layout&
236 _LayoutImpl::GetCore(void)
237 {
238         return *_pCoreLayout;
239 }
240
241 const _LayoutImpl*
242 _LayoutImpl::GetInstance(const Layout& layout)
243 {
244         LayoutImplHolder* pHolder = static_cast <LayoutImplHolder*>(layout._pImpl);
245         SysAssert(pHolder != null);
246
247         const _LayoutImpl* pImpl = pHolder->layoutImpl.Get();
248
249         return pImpl;
250 }
251
252 _LayoutImpl*
253 _LayoutImpl::GetInstance(Layout& layout)
254 {
255         LayoutImplHolder* pHolder = static_cast <LayoutImplHolder*>(layout._pImpl);
256         SysAssert(pHolder != null);
257
258         _LayoutImpl* pImpl = pHolder->layoutImpl.Get();
259
260         return pImpl;
261 }
262
263 result
264 _LayoutImpl::SetAlignment(const _ControlImpl& item, const LayoutHorizontalAlignment horizontalAlign, const LayoutVerticalAlignment verticalAlign)
265 {
266         ClearLastResult();
267
268         _Layout::LayoutItem& layoutItem = item.GetLayoutContainer();
269
270         _Layout::ItemAlign itemAlign;
271         itemAlign.HAlign = ConvertEnum(horizontalAlign);
272         SysTryReturn(NID_UI, itemAlign.HAlign != (_Layout::HorizontalAlign) CONVERT_ERROR_CODE,
273                                 E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The given parameter is invalid.");
274
275         itemAlign.VAlign = ConvertEnum(verticalAlign);
276         SysTryReturn(NID_UI, itemAlign.VAlign != (_Layout::VerticalAlign) CONVERT_ERROR_CODE,
277                                 E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The given parameter is invalid.");
278
279         return _pCoreLayout->SetItemAlignment(layoutItem, itemAlign);
280 }
281
282 result
283 _LayoutImpl::GetAlignment(const _ControlImpl& item, LayoutHorizontalAlignment& horizontalAlign, LayoutVerticalAlignment& verticalAlign) const
284 {
285         _Layout::LayoutItem& layoutItem = item.GetLayoutContainer();
286
287         result r = E_SUCCESS;
288         _Layout::ItemAlign itemAlign;
289
290         r = _pCoreLayout->GetItemAlignment(layoutItem, itemAlign);
291         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
292
293         horizontalAlign = ConvertEnum(itemAlign.HAlign);
294         verticalAlign = ConvertEnum(itemAlign.VAlign);
295
296         return E_SUCCESS;
297 }
298
299 result
300 _LayoutImpl::SetMargin(const _ControlImpl& item, int left, int right, int top, int bottom)
301 {
302         SysTryReturn(NID_UI, left >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The left margin is negative.");
303         SysTryReturn(NID_UI, right >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The right margin is negative.");
304         SysTryReturn(NID_UI, top >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The top margin is negative.");
305         SysTryReturn(NID_UI, bottom >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The bottom margin is negative.");
306
307         _Layout::LayoutItem& layoutItem = item.GetLayoutContainer();
308
309         _Layout::ItemMargin itemMargin;
310
311         itemMargin.left = left;
312         itemMargin.right = right;
313         itemMargin.top = top;
314         itemMargin.bottom = bottom;
315
316         result r = _pCoreLayout->SetItemMargin(layoutItem, itemMargin);
317
318         return r;
319 }
320
321 result
322 _LayoutImpl::GetMargin(const _ControlImpl& item, int& left, int& right, int& top, int& bottom) const
323 {
324         _Layout::LayoutItem& layoutItem = item.GetLayoutContainer();
325
326         _Layout::ItemMargin itemMargin;
327
328         result r = _pCoreLayout->GetItemMargin(layoutItem, itemMargin);
329         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
330
331         left = itemMargin.left;
332         right = itemMargin.right;
333         top = itemMargin.top;
334         bottom = itemMargin.bottom;
335
336         return r;
337 }
338
339 result
340 _LayoutImpl::SetHorizontalFitPolicy(const _ControlImpl& item, const FitPolicy policy)
341 {
342         _Layout::LayoutItem& layoutItem = item.GetLayoutContainer();
343
344         _Layout::LayoutMatchMode matchMode;
345
346         matchMode = ConvertEnum(policy);
347
348         SysTryReturn(NID_UI, matchMode != (_Layout::LayoutMatchMode) CONVERT_ERROR_CODE,
349                                 E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The given parameter is invalid.");
350
351         result r = _pCoreLayout->SetItemWidthMatchMode(layoutItem, matchMode);
352
353         return r;
354 }
355
356 result
357 _LayoutImpl::GetHorizontalFitPolicy(const _ControlImpl& item, FitPolicy& policy) const
358 {
359         _Layout::LayoutItem& layoutItem = item.GetLayoutContainer();
360
361         _Layout::LayoutMatchMode matchMode;
362
363         result r = _pCoreLayout->GetItemWidthMatchMode(layoutItem, matchMode);
364         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
365
366         policy = ConvertEnum(matchMode);
367
368         return r;
369 }
370
371 result
372 _LayoutImpl::SetVerticalFitPolicy(const _ControlImpl& item, const FitPolicy matchMode)
373 {
374         _Layout::LayoutItem& layoutItem = item.GetLayoutContainer();
375
376         _Layout::LayoutMatchMode layoutMatchMode;
377
378         layoutMatchMode = ConvertEnum(matchMode);
379
380         SysTryReturn(NID_UI, layoutMatchMode != (_Layout::LayoutMatchMode) CONVERT_ERROR_CODE,
381                                 E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The given parameter is invalid.");
382
383         result r = _pCoreLayout->SetItemHeightMatchMode(layoutItem, layoutMatchMode);
384
385         return r;
386 }
387
388 result
389 _LayoutImpl::GetVerticalFitPolicy(const _ControlImpl& item, FitPolicy& policy) const
390 {
391         _Layout::LayoutItem& layoutItem = item.GetLayoutContainer();
392
393         _Layout::LayoutMatchMode matchMode;
394
395         result r = _pCoreLayout->GetItemHeightMatchMode(layoutItem, matchMode);
396         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
397
398         policy = ConvertEnum(matchMode);
399
400         return r;
401 }
402
403 result
404 _LayoutImpl::UpdateLayout(void)
405 {
406         result r = _pCoreLayout->UpdateLayout();
407
408         return r;
409 }
410
411 result
412 _LayoutImpl::AddItem(_ControlImpl& addItem)
413 {
414         _Layout::LayoutItem& layoutItem = addItem.GetLayoutContainer();
415
416         result r = _pCoreLayout->AddItem(layoutItem);
417
418         return r;
419 }
420
421 result
422 _LayoutImpl::RemoveItem(const _ControlImpl& removeItem)
423 {
424         _Layout::LayoutItem& layoutItem = removeItem.GetLayoutContainer();
425
426         result r = _pCoreLayout->RemoveItem(layoutItem);
427
428         return r;
429 }
430
431 result
432 _LayoutImpl::OnChangeViewPos(int viewPosX, int viewPosY)
433 {
434         result r = _pCoreLayout->OnChangeViewPosition(viewPosX, viewPosY);
435
436         return r;
437 }
438
439 result
440 _LayoutImpl::SetItemBaseRect(const _ControlImpl& item, const _Layout::LayoutRect baseRect)
441 {
442         SysTryReturn(NID_UI, baseRect.x >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] X position is negative.");
443         SysTryReturn(NID_UI, baseRect.y >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Y position is negative.");
444         SysTryReturn(NID_UI, baseRect.w >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Width is negative.");
445         SysTryReturn(NID_UI, baseRect.h >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Height is negative.");
446
447         _Layout::LayoutItem& layoutItem = item.GetLayoutContainer();
448
449         result r = _pCoreLayout->SetItemBaseRect(layoutItem, baseRect);
450
451         return r;
452 }
453
454 result
455 _LayoutImpl::GetItemBaseRect(const _ControlImpl& item, _Layout::LayoutRect& baseRect) const
456 {
457         _Layout::LayoutItem& layoutItem = item.GetLayoutContainer();
458
459         result r = _pCoreLayout->GetItemBaseRect(layoutItem, baseRect);
460
461         return r;
462 }
463
464 void
465 _LayoutImpl::AllocateLayoutImpl(Layout* pPublicLayout, _SharedPtr <Tizen::Ui::_LayoutImpl> layoutImpl)
466 {
467         LayoutImplHolder* pHolder = static_cast <LayoutImplHolder*>(pPublicLayout->_pImpl);
468         SysAssert(pHolder != null);
469
470         pHolder->layoutImpl = layoutImpl;
471 }
472
473 Layout*
474 _LayoutImpl::CreatePublicLayoutN(_SharedPtr <Tizen::Ui::_LayoutImpl> layoutImpl)
475 {
476         _LayoutImpl* pLayoutImpl = layoutImpl.Get();
477         if (pLayoutImpl == null)
478         {
479                 return null;
480         }
481
482         switch (pLayoutImpl->GetLayoutType())
483         {
484         case LAYOUT_RELATIVE:
485         {
486                 RelativeLayout* pPublicLayout = new (std::nothrow) RelativeLayout;
487                 SysTryReturn(NID_UI, pPublicLayout != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
488
489                 _LayoutImpl::AllocateLayoutImpl(pPublicLayout, layoutImpl);
490
491                 return pPublicLayout;
492         }
493
494         case LAYOUT_VERTICAL_BOX:
495         {
496                 VerticalBoxLayout* pPublicLayout = new (std::nothrow) VerticalBoxLayout;
497                 SysTryReturn(NID_UI, pPublicLayout != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
498
499                 _LayoutImpl::AllocateLayoutImpl(pPublicLayout, layoutImpl);
500
501                 return pPublicLayout;
502         }
503
504         case LAYOUT_HORIZONTAL_BOX:
505         {
506                 HorizontalBoxLayout* pPublicLayout = new (std::nothrow) HorizontalBoxLayout;
507                 SysTryReturn(NID_UI, pPublicLayout != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
508
509                 _LayoutImpl::AllocateLayoutImpl(pPublicLayout, layoutImpl);
510
511                 return pPublicLayout;
512         }
513
514         case LAYOUT_GRID:
515         {
516                 GridLayout* pPublicLayout = new (std::nothrow) GridLayout;
517                 SysTryReturn(NID_UI, pPublicLayout != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
518
519                 _LayoutImpl::AllocateLayoutImpl(pPublicLayout, layoutImpl);
520
521                 return pPublicLayout;
522         }
523
524         case LAYOUT_CARD:
525         {
526                 CardLayout* pPublicLayout = new (std::nothrow) CardLayout;
527                 SysTryReturn(NID_UI, pPublicLayout != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
528
529                 _LayoutImpl::AllocateLayoutImpl(pPublicLayout, layoutImpl);
530
531                 return pPublicLayout;
532         }
533
534         default:
535                 SysAssert(false);
536                 return null;
537         }
538         return null;
539 }
540
541 }} // Tizen::Ui