Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / controls / FUiCtrl_PopupImpl.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 /**
19  * @file                FUiCtrl_PopupImpl.cpp
20  * @brief       This is the implementation file for the _PopupImpl class.
21  */
22
23
24 #include <FUiLayout.h>
25 #include <FBaseSysLog.h>
26 #include "FUi_UiBuilder.h"
27 #include "FUi_DataBindingContextImpl.h"
28 #include "FUi_ResourceSizeInfo.h"
29 #include "FUi_ResourceManager.h"
30 #include "FUi_ControlImplManager.h"
31 #include "FUi_LayoutImpl.h"
32 #include "FUiCtrl_FrameImpl.h"
33 #include "FUiCtrl_PopupImpl.h"
34 #include "FUiCtrl_Popup.h"
35 #include "FUiCtrl_Form.h"
36
37
38 using namespace Tizen::Ui::Animations;
39 using namespace Tizen::Graphics;
40 using namespace Tizen::Ui;
41
42
43 namespace Tizen { namespace Ui { namespace Controls
44 {
45
46
47 Dimension
48 _PopupImpl::PopupSizeInfo::GetDefaultMinimumSize(_ControlOrientation orientation) const
49 {
50         result r = E_SUCCESS;
51         Dimension dimension(0, 0);
52
53         r = GET_DIMENSION_CONFIG(POPUP::MIN_SIZE, orientation, dimension);
54         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, dimension, r, "[%s] A system error occurred.", GetErrorMessage(r));
55         SetLastResult(r);
56
57         return dimension;
58 }
59
60 Dimension
61 _PopupImpl::PopupSizeInfo::GetDefaultMaximumSize(_ControlOrientation orientation) const
62 {
63         result r = E_SUCCESS;
64         Dimension dimension(0, 0);
65
66         r = GET_DIMENSION_CONFIG(POPUP::MAX_SIZE, orientation, dimension);
67         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, dimension, r, "[%s] A system error occurred.", GetErrorMessage(r));
68
69         SetLastResult(r);
70
71         return dimension;
72 }
73
74 _PopupImpl*
75 _PopupImpl::GetInstance(Popup& pPopup)
76 {
77         return static_cast <_PopupImpl*>(pPopup._pControlImpl);
78 }
79
80 const _PopupImpl*
81 _PopupImpl::GetInstance(const Popup& pPopup)
82 {
83         return static_cast <const _PopupImpl*>(pPopup._pControlImpl);
84 }
85
86 _PopupImpl::_PopupImpl(Popup* pPublic, _Popup* pCore, Layout* pPublicPortraitLayout, Layout* pPublicLandscapeLayout)
87         : _WindowImpl(pPublic, pCore, pPublicPortraitLayout, pPublicLandscapeLayout)
88         , _isModal(false)
89         , __init(false)
90         , __centerAlign(false)
91         , __callBoundsChange(false)
92 {
93         //empty statement
94 }
95
96 _PopupImpl::~_PopupImpl(void)
97 {
98         //empty statement
99 }
100
101 _PopupImpl*
102 _PopupImpl::CreatePopupImplN(Popup* pControl, const Tizen::Graphics::Dimension& dim, Layout* pPublicPortraitLayout, Layout* pPublicLandscapeLayout)
103 {
104         result r = E_SUCCESS;
105
106         r = GET_SIZE_INFO(Popup).CheckInitialSizeValid(dim, _ControlManager::GetInstance()->GetOrientation());
107         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, E_INVALID_ARG, "[E_INVALID_ARG] The given size is not valid.");
108
109         _PopupImpl* pImpl = null;
110         _Popup* pCore = null;
111
112         pCore = _Popup::CreatePopupN();
113         SysTryReturn(NID_UI_CTRL, pCore, null, E_SYSTEM, "[%s] Propagating.", GetErrorMessage(GetLastResult()));
114
115         pImpl = new (std::nothrow) _PopupImpl(pControl, pCore, pPublicPortraitLayout, pPublicLandscapeLayout);
116         r = CheckConstruction(pCore, pImpl);
117         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
118
119         r = pImpl->InitializeBoundsProperties(GET_SIZE_INFO(Popup), dim, _ControlManager::GetInstance()->GetOrientation());
120         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
121
122         ClearLastResult();
123
124         return pImpl;
125
126 CATCH:
127         delete pImpl;   //This deletes pCore as well
128
129         return null;
130 }
131
132 result
133 _PopupImpl::Initialize(bool hasTitle, const Tizen::Graphics::Dimension& dim)
134 {
135         result r = E_SUCCESS;
136
137         if (hasTitle)
138         {
139                 Dimension minSize(0, 0);
140
141                 r = GET_DIMENSION_CONFIG(POPUP::MIN_SIZE_WITH_TITLE, _ControlManager::GetInstance()->GetOrientation(), minSize);
142
143                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] A system error occurred.", GetErrorMessage(r));
144
145                 SysTryReturn(NID_UI_CTRL,
146                 (minSize.width <= dim.width && minSize.height <= dim.height), E_INVALID_ARG,
147                 E_INVALID_ARG, "[E_INVALID_ARG] The size is out of minium size(%d, %d)",
148                 minSize.width, minSize.width);
149
150                 r = GetCore().SetMinimumSize(minSize);
151
152                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] SetMinimumSize is failed.", GetErrorMessage(r));
153         }
154
155         Rectangle bounds = GetCenterAlignedRect(dim.width, dim.height);
156         __init = true;
157         __centerAlign = true;
158
159         r = SetBounds(bounds);
160         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
161
162         return GetCore().Initialize(hasTitle, bounds);
163 }
164
165 const char*
166 _PopupImpl::GetPublicClassName(void) const
167 {
168         return "Tizen::Ui::Controls::Popup";
169 }
170
171 const Popup&
172 _PopupImpl::GetPublic(void) const
173 {
174         return static_cast <const Popup&>(_ControlImpl::GetPublic());
175 }
176
177 Popup&
178 _PopupImpl::GetPublic(void)
179 {
180         return static_cast <Popup&>(_ControlImpl::GetPublic());
181 }
182
183 const _Popup&
184 _PopupImpl::GetCore(void) const
185 {
186         return static_cast <const _Popup&>(_ControlImpl::GetCore());
187 }
188
189 _Popup&
190 _PopupImpl::GetCore(void)
191 {
192         return static_cast <_Popup&>(_ControlImpl::GetCore());
193 }
194
195 Rectangle
196 _PopupImpl::GetCenterAlignedRect(int width, int height) const
197 {
198         int x = 0;
199         int y = 0;
200
201         Dimension screenRect = _ControlManager::GetInstance()->GetScreenSize();
202
203         if (GetCore().GetOrientation() == _CONTROL_ORIENTATION_LANDSCAPE)
204         {
205                 int temp = screenRect.width;
206                 screenRect.width = screenRect.height;
207                 screenRect.height = temp;
208         }
209
210         x = (screenRect.width - width) / 2;
211         y = (screenRect.height - height) / 2;
212
213         return Rectangle(x, y, width, height);
214 }
215
216 Rectangle
217 _PopupImpl::GetClientAreaBounds(void) const
218 {
219         return _ControlImpl::GetClientBounds();
220 }
221
222 Canvas*
223 _PopupImpl::GetClientAreaCanvasN(void) const
224 {
225         return GetCore().GetClientAreaCanvasN();
226 }
227
228 Point
229 _PopupImpl::TranslateFromClientAreaPosition(const Point& clientPosition) const
230 {
231         return GetCore().TranslateFromClientAreaPosition(clientPosition);
232 }
233
234 Point
235 _PopupImpl::TranslateToClientAreaPosition(const Point& position) const
236 {
237         return GetCore().TranslateToClientAreaPosition(position);
238 }
239
240 result
241 _PopupImpl::DoModal(int& modalResult)
242 {
243         SysTryReturn(NID_UI_CTRL, GetVisibleState() != false, E_INVALID_STATE,
244                                         E_INVALID_STATE, "[E_INVALID_STATE] The Popup is not visible");
245
246         _isModal = true;
247
248         return GetCore().DoModal(modalResult);
249 }
250
251 result
252 _PopupImpl::EndModal(int modalResult)
253 {
254         SysTryReturn(NID_UI_CTRL, _isModal == true, E_INVALID_STATE, E_INVALID_STATE,
255                                 "[E_INVALID_STATE] The method is not supported because this popup isn't running as a modal window.");
256
257         return GetCore().EndModal(modalResult);
258 }
259
260 result
261 _PopupImpl::SetColor(const Color& color)
262 {
263         GetCore().SetColor(color);
264
265         return E_SUCCESS;
266 }
267
268 Color
269 _PopupImpl::GetColor(void) const
270 {
271         return GetCore().GetColor();
272 }
273
274 result
275 _PopupImpl::SetTitleText(const Tizen::Base::String& title)
276 {
277         return GetCore().SetTitleText(title);
278 }
279
280 Tizen::Base::String
281 _PopupImpl::GetTitleText(void) const
282 {
283         return GetCore().GetTitleText();
284 }
285
286 result
287 _PopupImpl::SetTitleTextColor(const Color& color)
288 {
289         GetCore().SetTitleTextColor(color);
290
291         return E_SUCCESS;
292 }
293
294 Color
295 _PopupImpl::GetTitleTextColor() const
296 {
297         return GetCore().GetTitleTextColor();
298 }
299
300 int
301 _PopupImpl::GetMinWidth(void) const
302 {
303         Dimension dimMin(0, 0);
304
305         GET_DIMENSION_CONFIG(POPUP::MIN_SIZE, GetCore().GetOrientation(), dimMin);
306
307         return dimMin.width;
308 }
309
310 int
311 _PopupImpl::GetMinHeight(void) const
312 {
313         Dimension dimMin(0, 0);
314
315         GET_DIMENSION_CONFIG(POPUP::MIN_SIZE, GetCore().GetOrientation(), dimMin);
316
317         return dimMin.height;
318 }
319
320 int
321 _PopupImpl::GetMaxWidth(void) const
322 {
323         Dimension dimMax(0, 0);
324
325         GET_DIMENSION_CONFIG(POPUP::MAX_SIZE, GetCore().GetOrientation(), dimMax);
326
327         return dimMax.width;
328 }
329
330 int
331 _PopupImpl::GetMaxHeight(void) const
332 {
333         Dimension dimMax(0, 0);
334
335         GET_DIMENSION_CONFIG(POPUP::MAX_SIZE, GetCore().GetOrientation(), dimMax);
336
337         return dimMax.height;
338 }
339
340 DataBindingContext*
341 _PopupImpl::GetDataBindingContextN(void) const
342 {
343         return Tizen::Ui::_DataBindingContextImpl::GetDataBindingContextN(*this);
344 }
345
346 void
347 _PopupImpl::OnChangeLayout(_ControlOrientation orientation)
348 {
349         result r = E_SUCCESS;
350
351         Dimension newMaxSize(0, 0);
352         Dimension maxSize = GetCore().GetMaximumSize();
353
354         r = GET_DIMENSION_CONFIG(POPUP::MAX_SIZE, orientation, newMaxSize);
355         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] A system error occurred.", GetErrorMessage(r));
356
357         if (maxSize.width == newMaxSize.height && maxSize.height == newMaxSize.width)
358         {
359                 r = GetCore().SetMaximumSize(newMaxSize);
360                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] SetMinimumSize is failed.", GetErrorMessage(r));
361         }
362
363         if (!__callBoundsChange)
364         {
365                 Rectangle bounds = GetCenterAlignedRect(GetBounds().width, GetBounds().height);
366                 __centerAlign = true;
367
368                 r = SetBounds(bounds);
369                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
370
371         }
372
373         return GetCore().OnChangeLayout(orientation);
374 }
375
376 void
377 _PopupImpl::OnBoundsChanged(void)
378 {
379         Rectangle rect = GetBounds();
380
381         if (__init)
382         {
383                 if (__centerAlign)
384                 {
385                         rect = GetCenterAlignedRect(GetSize().width, GetSize().height);
386                         __centerAlign = false;
387                 }
388                 else
389                 {
390                         __callBoundsChange = true;
391                 }
392         }
393
394 #if !defined(MULTI_WINDOW)
395         result r = SetBounds(rect, false);
396 #else
397         result r = SetBounds(rect, true);
398 #endif
399
400         if (IsFailed(r))
401         {
402                 // Error propagation fall through
403                 ClearLastResult();
404         }
405
406         _ControlImpl::OnBoundsChanged();
407 }
408
409
410 class _PopupMaker
411         : public _UiBuilderControlMaker
412 {
413 public:
414         _PopupMaker(_UiBuilder* uibuilder)
415                 : _UiBuilderControlMaker(uibuilder){};
416         virtual ~_PopupMaker(){};
417
418         static _UiBuilderControlMaker* GetInstance(_UiBuilder* uibuilder)
419         {
420                 _PopupMaker* pPopupMaker = new (std::nothrow) _PopupMaker(uibuilder);
421
422                 return static_cast<_UiBuilderControlMaker*>(pPopupMaker);
423         };
424
425 protected:
426         virtual Tizen::Ui::Control* Make(_UiBuilderControl* pControl)
427         {
428                 bool hasTitle = false;
429                 result r = E_SYSTEM;
430                 _UiBuilderControlLayout* pControlProperty = null;
431                 Tizen::Base::String elementString;
432                 Color color;
433                 Tizen::Graphics::Dimension dim;
434                 Tizen::Graphics::Rectangle rect;
435
436                 Popup* pPopup = dynamic_cast <Popup*>(GetContainer());
437                 SysTryReturn(NID_UI_CTRL, pPopup != null, null, E_SYSTEM, "[E_SYSTEM] This instance is not constructed.");
438
439                 SetUiBuilderRotateState(UIBUIDER_SCREEN_VERTICAL);
440                 GetProperty(pControl, &pControlProperty);
441
442                 if (pControlProperty == null)
443                 {
444                         return null;
445                 }
446
447                 if (pControl->GetElement("titleText", elementString))
448                 {
449                         hasTitle = true;
450                 }
451                 else
452                 {
453                         hasTitle = false;
454                 }
455
456                 //pPopup = new (std::nothrow) Popup();
457                 rect = pControlProperty->GetRect();
458
459                 dim.width = rect.width;
460                 dim.height = rect.height;
461
462 //              int sideMargin = 0;
463 //              GET_SHAPE_CONFIG(POPUP::TITLE_TEXT_SIDE_MARGIN,  _ControlManager::GetInstance()->GetOrientation(), sideMargin);
464 //
465 //              // To consider client's area
466 //              dim.width += sideMargin * 2;
467 //
468 //              if (hasTitle == true)
469 //              {
470 //                      int titleHeight = 0;
471 //                      GET_SHAPE_CONFIG(POPUP::TITLE_HEIGHT,  _ControlManager::GetInstance()->GetOrientation(), titleHeight);
472 //
473 //                      dim.height += titleHeight;
474 //              }
475
476                 _UiBuilderLayoutType layoutType = UIBUILDER_LAYOUT_NONE;
477                 GetLayoutType(pControlProperty, layoutType);
478
479                 if (layoutType == UIBUILDER_LAYOUT_NONE)
480                 {
481                         r = pPopup->Construct(hasTitle, dim);
482                 }
483                 else
484                 {
485                         Layout* pPortraitLayout = null;
486                         Layout* pLandscapeLayout = null;
487                         result tempResult = E_SUCCESS;
488
489                         tempResult = GetLayoutN(pControl, pPortraitLayout, pLandscapeLayout);
490
491                         if (E_SUCCESS == tempResult)
492                         {
493                                 r = pPopup->Construct(*pPortraitLayout, *pLandscapeLayout, hasTitle, dim);
494                         }
495                         else
496                         {
497                                 r = tempResult;
498                         }
499
500                         _UiBuilderLayoutType layoutType = UIBUILDER_LAYOUT_NONE;
501
502                         if (GetLayoutType(pControlProperty, layoutType) == false)
503                         {
504                                 return null;
505                         }
506
507                         if ( layoutType == UIBUILDER_LAYOUT_GRID)
508                         {
509                                 for (int i = 0; i < UIBUILDER_ATTRIBUTE_NUM; i++)
510                                 {
511                                         GridLayout* pGridLayout = null;
512                                         pControlProperty = pControl->GetAttribute(i);
513
514                                         if ( i == UIBUILDER_ATTRIBUTE_PORTRAIT)
515                                         {
516                                                 pGridLayout = dynamic_cast<GridLayout*>(pPortraitLayout);
517                                         }
518                                         else
519                                         {
520                                                 pGridLayout = dynamic_cast<GridLayout*>(pLandscapeLayout);
521                                         }
522                                         SetGridLayoutContainerProperty(pGridLayout, pControlProperty);
523                                 }
524                         }
525
526                         delete pPortraitLayout;
527
528                         if (pPortraitLayout != pLandscapeLayout)
529                         {
530                                 delete pLandscapeLayout;
531                         }
532                 //      CONSTRUCT_WITH_LAYOUT_ARG2(pPopup, hasTitle, dim);
533                 }
534
535                 if (r != E_SUCCESS)
536                 {
537                         SysLog(NID_UI_CTRL, "Failed to create Popup.");
538                         return null;
539                 }
540
541                 if (hasTitle == true)
542                 {
543                         pPopup->SetTitleText(elementString);
544                 }
545
546                 //set property
547                 if (pControl->GetElement("color", elementString))
548                 {
549                         ConvertStringToColor(elementString, color);
550                         pPopup->SetColor(color);
551                 }
552
553                 if (pControl->GetElement("titleTextColor", elementString))
554                 {
555                         ConvertStringToColor(elementString, color);
556                         pPopup->SetTitleTextColor(color);
557                 }
558
559                 //-------safety for Minimum size-------------------
560 //        rect = (pControl->GetAttribute(UIBUILDER_ATTRIBUTE_PORTRAIT))->GetRect();
561 //        if (rect.width < __BaseProperty(PROPERTY_POPUP_MIN_WIDTH))
562 //        {
563 //            rect.width = __BaseProperty(PROPERTY_POPUP_MIN_WIDTH);
564 //        }
565 //        if (rect.height < __BaseProperty(PROPERTY_POPUP_MIN_HEIGHT))
566 //        {
567 //            rect.height = __BaseProperty(PROPERTY_POPUP_MIN_HEIGHT);
568 //        }
569 //        (pControl->GetAttribute(UIBUILDER_ATTRIBUTE_PORTRAIT))->SetRect(rect.x,rect.y,rect.width,rect.height);
570 //
571 //        rect = (pControl->GetAttribute(UIBUILDER_ATTRIBUTE_LANDSCAPE))->GetRect();
572 //        if (rect.width < __BaseProperty(PROPERTY_POPUP_MIN_WIDTH))
573 //        {
574 //            rect.width = __BaseProperty(PROPERTY_POPUP_MIN_WIDTH);
575 //        }
576 //        if (rect.height < __BaseProperty(PROPERTY_POPUP_MIN_HEIGHT))
577 //        {
578 //            rect.height = __BaseProperty(PROPERTY_POPUP_MIN_HEIGHT);
579 //        }
580 //        (pControl->GetAttribute(UIBUILDER_ATTRIBUTE_LANDSCAPE))->SetRect(rect.x,rect.y,rect.width,rect.height);
581                 //---------end safety code------------------------
582
583                 return pPopup;
584         }
585
586 private:
587
588 };      // _PopupMaker
589
590 _PopupRegister::_PopupRegister()
591 {
592         _UiBuilderControlTableManager* pUiBuilderControlTableManager = _UiBuilderControlTableManager::GetInstance();
593         pUiBuilderControlTableManager->RegisterControl(L"Popup", _PopupMaker::GetInstance);
594 }
595
596 _PopupRegister::~_PopupRegister()
597 {
598         _UiBuilderControlTableManager* pUiBuilderControlTableManager = _UiBuilderControlTableManager::GetInstance();
599         pUiBuilderControlTableManager->UnregisterControl(L"Popup");
600 }
601 static _PopupRegister PopupRegisterToUiBuilder;
602
603 }}} // Tizen::Ui::Controls