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