Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / controls / FUiCtrl_PopupPresenter.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_PopupPresenter.cpp
20  * @brief       This is the implementation file for the _PopupPresenter class.
21  */
22
23
24 #include <FBaseErrorDefine.h>
25 #include <FBaseSysLog.h>
26 #include <FGrp_BitmapImpl.h>
27 #include <FGrp_CanvasImpl.h>
28 #include <FGrp_FontImpl.h>
29 #include <FGrp_TextTextSimple.h>
30 #include "FUi_ControlManager.h"
31 #include "FUi_ModalLoopManager.h"
32 #include "FUi_ResourceManager.h"
33 #include "FUi_UiTouchEvent.h"
34 #include "FUiAnim_RootVisualElement.h"
35 #include "FUiCtrl_Label.h"
36 #include "FUiCtrl_PopupPresenter.h"
37 #include "FUiCtrl_Popup.h"
38
39
40 using namespace Tizen::Base;
41 using namespace Tizen::Graphics;
42 using namespace Tizen::Graphics::_Text;
43 using namespace Tizen::Ui;
44 using namespace Tizen::Ui::Animations;
45
46
47 namespace Tizen { namespace Ui { namespace Controls
48 {
49
50
51 _PopupPresenter::_PopupPresenter(void)
52         : _pFont(null)
53         , __pPopup(null)
54         , __pPopupVE(null)
55         , __pBackgroundVE(null)
56         , __pTextObject(null)
57         , __pLabelCore(null)
58         , __titleBounds(0, 0, 0, 0)
59 {
60         //empty statement
61 }
62
63 _PopupPresenter::~_PopupPresenter(void)
64 {
65         if (__pTextObject != null)
66         {
67                 delete __pTextObject;
68                 __pTextObject = null;
69         }
70
71         delete __pLabelCore;
72         __pLabelCore = null;
73
74         if (__pBackgroundVE != null)
75         {
76                 __pBackgroundVE->Destroy();
77                 __pBackgroundVE = null;
78         }
79 }
80
81 void
82 _PopupPresenter::UpdateEffectBounds(void)
83 {
84         Dimension screenRect;
85         Rectangle bounds;
86
87         int bgOutlineEffectTopMargin = 0;
88         int bgOutlineEffectBottomMargin = 0;
89         int bgOutlineEffectLeftMargin = 0;
90         int bgOutlineEffectRightMargin = 0;
91         int temp = 0;
92
93         GET_SHAPE_CONFIG(POPUP::BG_OUTLINE_EFFECT_TOP_MARGIN, __pPopup->GetOrientation(), bgOutlineEffectTopMargin);
94         GET_SHAPE_CONFIG(POPUP::BG_OUTLINE_EFFECT_BOTTOM_MARGIN, __pPopup->GetOrientation(), bgOutlineEffectBottomMargin);
95         GET_SHAPE_CONFIG(POPUP::BG_OUTLINE_EFFECT_LEFT_MARGIN, __pPopup->GetOrientation(), bgOutlineEffectLeftMargin);
96         GET_SHAPE_CONFIG(POPUP::BG_OUTLINE_EFFECT_RIGHT_MARGIN, __pPopup->GetOrientation(), bgOutlineEffectRightMargin);
97
98         bounds = __pPopup->GetBounds();
99
100         screenRect = _ControlManager::GetInstance()->GetScreenSize();
101         if (__pPopup->GetOrientation() == _CONTROL_ORIENTATION_LANDSCAPE)
102         {
103                 temp = screenRect.width;
104                 screenRect.width = screenRect.height;
105                 screenRect.height = temp;
106         }
107
108         bounds.x = (screenRect.width - (bounds.width)) / 2 - bgOutlineEffectLeftMargin;
109         bounds.y = (screenRect.height - (bounds.height)) / 2 - bgOutlineEffectTopMargin;
110
111         __pBackgroundVE->SetBounds(FloatRectangle((float)bounds.x,
112                                                                                         (float)bounds.y,
113                                                                                         (float)(bounds.width + bgOutlineEffectLeftMargin + bgOutlineEffectRightMargin),
114                                                                                         (float)(bounds.height + bgOutlineEffectTopMargin + bgOutlineEffectBottomMargin)));
115 }
116
117 void
118 _PopupPresenter::Initialize(_Popup& popup)
119 {
120         result r = E_SUCCESS;
121
122         Dimension screenRect;
123         Rectangle bounds;
124         int temp = 0;
125
126         int transTopMargin = 0;
127         int transBottomMargin = 0;
128         int transLeftMargin = 0;
129         int transRightMargin = 0;
130
131         int bgOutlineEffectTopMargin = 0;
132         int bgOutlineEffectBottomMargin = 0;
133         int bgOutlineEffectLeftMargin = 0;
134         int bgOutlineEffectRightMargin = 0;
135
136         __pPopup = &popup;
137
138         GET_SHAPE_CONFIG(POPUP::BG_IMAGE_TRANSPARENT_TOP_MARGIN, __pPopup->GetOrientation(), transTopMargin);
139         GET_SHAPE_CONFIG(POPUP::BG_IMAGE_TRANSPARENT_BOTTOM_MARGIN, __pPopup->GetOrientation(), transBottomMargin);
140         GET_SHAPE_CONFIG(POPUP::BG_IMAGE_TRANSPARENT_LEFT_MARGIN, __pPopup->GetOrientation(), transLeftMargin);
141         GET_SHAPE_CONFIG(POPUP::BG_IMAGE_TRANSPARENT_RIGHT_MARGIN, __pPopup->GetOrientation(), transRightMargin);
142
143         GET_SHAPE_CONFIG(POPUP::BG_OUTLINE_EFFECT_TOP_MARGIN, __pPopup->GetOrientation(), bgOutlineEffectTopMargin);
144         GET_SHAPE_CONFIG(POPUP::BG_OUTLINE_EFFECT_BOTTOM_MARGIN, __pPopup->GetOrientation(), bgOutlineEffectBottomMargin);
145         GET_SHAPE_CONFIG(POPUP::BG_OUTLINE_EFFECT_LEFT_MARGIN, __pPopup->GetOrientation(), bgOutlineEffectLeftMargin);
146         GET_SHAPE_CONFIG(POPUP::BG_OUTLINE_EFFECT_RIGHT_MARGIN, __pPopup->GetOrientation(), bgOutlineEffectRightMargin);
147
148         // system label to cover non-client area
149         __pLabelCore = _Label::CreateLabelN();
150         r = GetLastResult();
151         SysTryReturnVoidResult(NID_UI_CTRL, __pLabelCore != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
152         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
153
154         __pLabelCore->SetBackgroundColor(Color(0, 0 ,0, 0));
155
156         r = __pPopup->AttachSystemChild(*__pLabelCore);
157         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
158
159         __pBackgroundVE = new (std::nothrow) _VisualElement();
160         SysTryReturnVoidResult(NID_UI_CTRL, __pBackgroundVE != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
161
162         r = __pBackgroundVE->Construct();
163         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
164
165         bounds = __pPopup->GetBounds();
166
167         screenRect = _ControlManager::GetInstance()->GetScreenSize();
168         if (__pPopup->GetOrientation() == _CONTROL_ORIENTATION_LANDSCAPE)
169         {
170                 temp = screenRect.width;
171                 screenRect.width = screenRect.height;
172                 screenRect.height = temp;
173         }
174
175         bounds.x = (screenRect.width - (bounds.width)) / 2 - bgOutlineEffectLeftMargin;
176         bounds.y = (screenRect.height - (bounds.height)) / 2 - bgOutlineEffectTopMargin;
177
178         __pBackgroundVE->SetBounds(FloatRectangle((float)bounds.x,
179                                                                                         (float)bounds.y,
180                                                                                         (float)(bounds.width + bgOutlineEffectLeftMargin + bgOutlineEffectRightMargin),
181                                                                                         (float)(bounds.height + bgOutlineEffectTopMargin + bgOutlineEffectBottomMargin)));
182
183         r = __pBackgroundVE->SetSurfaceOpaque(false);
184         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
185
186         __pBackgroundVE->SetShowState(true);
187
188         __pPopupVE = __pPopup->GetVisualElement();
189         SysTryCatch(NID_UI_CTRL, (__pPopupVE != null), r = E_SYSTEM, E_SYSTEM,
190                                                            "[E_SYSTEM] A system error has occurred. Failed to get the Popup visual element.");
191
192         return;
193
194 CATCH:
195         delete __pLabelCore;
196         __pLabelCore = null;
197
198         __pBackgroundVE->Destroy();
199         __pBackgroundVE = null;
200
201         return;
202 }
203
204 _Label*
205 _PopupPresenter::GetSystemLabel(void) const
206 {
207         return __pLabelCore;
208 }
209
210 void
211 _PopupPresenter::OnFontChanged(Font* pFont)
212 {
213         _pFont = pFont;
214 }
215
216 void
217 _PopupPresenter::OnFontInfoRequested(unsigned long& style, int& size)
218 {
219         int textSize = 0;
220         GET_SHAPE_CONFIG(POPUP::TITLE_TEXT_SIZE, __pPopup->GetOrientation(), textSize);
221
222         style = FONT_STYLE_PLAIN;
223         size = textSize;
224 }
225
226 result
227 _PopupPresenter::SetTitleTextObject(const String &title)
228 {
229         result r = E_SUCCESS;
230         TextSimple* pSimpleText = null;
231
232         int textSize = 0;
233         int titleHeight = 0;
234         int titleTopMargin = 0;
235         int titleLeftMargin = 0;
236         int titleRightMargin = 0;
237         int transTopMargin = 0;
238         int transLeftMargin = 0;
239         int transRightMargin = 0;
240
241         GET_SHAPE_CONFIG(POPUP::TITLE_TEXT_SIZE, __pPopup->GetOrientation(), textSize);
242         GET_SHAPE_CONFIG(POPUP::TITLE_HEIGHT, __pPopup->GetOrientation(), titleHeight);
243
244         GET_SHAPE_CONFIG(POPUP::TITLE_TEXT_TOP_MARGIN, __pPopup->GetOrientation(), titleTopMargin);
245         GET_SHAPE_CONFIG(POPUP::TITLE_TEXT_LEFT_MARGIN, __pPopup->GetOrientation(), titleLeftMargin);
246         GET_SHAPE_CONFIG(POPUP::TITLE_TEXT_RIGHT_MARGIN, __pPopup->GetOrientation(), titleRightMargin);
247
248         GET_SHAPE_CONFIG(POPUP::BG_IMAGE_TRANSPARENT_TOP_MARGIN, __pPopup->GetOrientation(), transTopMargin);
249         GET_SHAPE_CONFIG(POPUP::BG_IMAGE_TRANSPARENT_LEFT_MARGIN, __pPopup->GetOrientation(), transLeftMargin);
250         GET_SHAPE_CONFIG(POPUP::BG_IMAGE_TRANSPARENT_RIGHT_MARGIN, __pPopup->GetOrientation(), transRightMargin);
251
252         // Title font
253         _pFont = __pPopup->GetFallbackFont();
254         SysTryReturn(NID_UI_CTRL, _pFont != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
255
256         if (__pTextObject != null)
257         {
258                 delete __pTextObject;
259         }
260
261         // Title text
262         __pTextObject = new (std::nothrow) TextObject();
263         SysTryReturn(NID_UI_CTRL, __pTextObject != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
264
265         __pTextObject->Construct();
266
267         pSimpleText = new (std::nothrow) TextSimple(const_cast <wchar_t*>(title.GetPointer()),
268                                                                                                                                 title.GetLength(),
269                                                                                                                                 TEXT_ELEMENT_SOURCE_TYPE_EXTERNAL);
270         SysTryCatch(NID_UI_CTRL, pSimpleText != null , r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
271
272         __pTextObject->AppendElement(*pSimpleText);
273         __pTextObject->SetForegroundColor(__pPopup->GetTitleTextColor(), 0, __pTextObject->GetTextLength());
274         __pTextObject->SetWrap(TEXT_OBJECT_WRAP_TYPE_NONE);
275         __pTextObject->SetAction(TEXT_OBJECT_ACTION_TYPE_ABBREV);
276         __pTextObject->SetTextObjectEllipsisType(TEXT_OBJECT_ELLIPSIS_TYPE_TAIL);
277
278         __pTextObject->SetFont(_pFont, 0, __pTextObject->GetTextLength());
279         __pTextObject->SetAlignment(TEXT_OBJECT_ALIGNMENT_LEFT);
280
281         __pTextObject->SetBounds(Rectangle(titleLeftMargin + transLeftMargin,
282                                         titleTopMargin,
283                                         __pPopup->GetBounds().width - (titleLeftMargin + titleRightMargin + transLeftMargin + transRightMargin),
284                                         titleHeight - titleTopMargin));
285         __pTextObject->Compose();
286
287         // After TextObject::Compose(), we can get text-object's height.
288         __titleBounds.SetBounds(titleLeftMargin + transLeftMargin,
289                                                         titleTopMargin,
290                                                         __pPopup->GetBounds().width - (titleLeftMargin + titleRightMargin + transLeftMargin + transRightMargin),
291                                                         __pTextObject->GetTotalHeight());
292
293         __pTextObject->SetBounds(__titleBounds);
294
295         return r;
296
297 CATCH:
298         delete __pTextObject;
299         __pTextObject = null;
300
301         return r;
302 }
303
304 void
305 _PopupPresenter::OnDraw(void)
306 {
307         DrawSystemLabel();
308         Draw();
309 }
310
311 Rectangle
312 _PopupPresenter::GetTitleTextBounds(void) const
313 {
314         return __titleBounds;
315 }
316
317 void
318 _PopupPresenter::DrawSystemLabel(void)
319 {
320         result r = E_SUCCESS;
321
322         int titleHeight = 0;
323         int transTopMargin = 0;
324         int transBottomMargin = 0;
325
326         GET_SHAPE_CONFIG(POPUP::TITLE_HEIGHT, __pPopup->GetOrientation(), titleHeight);
327         GET_SHAPE_CONFIG(POPUP::BG_IMAGE_TRANSPARENT_TOP_MARGIN, __pPopup->GetOrientation(), transTopMargin);
328         GET_SHAPE_CONFIG(POPUP::BG_IMAGE_TRANSPARENT_BOTTOM_MARGIN, __pPopup->GetOrientation(), transBottomMargin);
329
330         Rectangle systemBounds;
331         Rectangle clientBounds = __pPopup->GetPopupClientArea();
332         Rectangle bounds = __pPopup->GetBounds();
333
334         systemBounds.x = clientBounds.x + clientBounds.width;
335
336         if (__pPopup->HasTitle() == false)
337         {
338                 titleHeight = 0;
339         }
340         systemBounds.y = clientBounds.y + POPUP_LABEL_GAP;
341
342         systemBounds.width = (bounds.width - systemBounds.x) - POPUP_LABEL_GAP / 2;
343         systemBounds.height = clientBounds.height -POPUP_LABEL_GAP * 2;
344
345         r = __pLabelCore->SetBounds(systemBounds);
346         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
347
348         __pLabelCore->SetBackgroundColor(__pPopup->GetColor());
349
350         __pLabelCore->Draw();
351
352         return;
353
354 CATCH:
355         delete __pLabelCore;
356         __pLabelCore = null;
357
358         return;
359 }
360
361 void
362 _PopupPresenter::Draw(void)
363 {
364         result r = E_SUCCESS;
365
366         int transTopMargin = 0;
367         int transBottomMargin = 0;
368         int transLeftMargin = 0;
369         int transRightMargin = 0;
370
371         int bgOutlineEffectTopMargin = 0;
372         int bgOutlineEffectBottomMargin = 0;
373         int bgOutlineEffectLeftMargin = 0;
374         int bgOutlineEffectRightMargin = 0;
375
376         GET_SHAPE_CONFIG(POPUP::BG_IMAGE_TRANSPARENT_TOP_MARGIN, __pPopup->GetOrientation(), transTopMargin);
377         GET_SHAPE_CONFIG(POPUP::BG_IMAGE_TRANSPARENT_BOTTOM_MARGIN, __pPopup->GetOrientation(), transBottomMargin);
378         GET_SHAPE_CONFIG(POPUP::BG_IMAGE_TRANSPARENT_LEFT_MARGIN, __pPopup->GetOrientation(), transLeftMargin);
379         GET_SHAPE_CONFIG(POPUP::BG_IMAGE_TRANSPARENT_RIGHT_MARGIN, __pPopup->GetOrientation(), transRightMargin);
380
381         GET_SHAPE_CONFIG(POPUP::BG_OUTLINE_EFFECT_TOP_MARGIN, __pPopup->GetOrientation(), bgOutlineEffectTopMargin);
382         GET_SHAPE_CONFIG(POPUP::BG_OUTLINE_EFFECT_BOTTOM_MARGIN, __pPopup->GetOrientation(), bgOutlineEffectBottomMargin);
383         GET_SHAPE_CONFIG(POPUP::BG_OUTLINE_EFFECT_LEFT_MARGIN, __pPopup->GetOrientation(), bgOutlineEffectLeftMargin);
384         GET_SHAPE_CONFIG(POPUP::BG_OUTLINE_EFFECT_RIGHT_MARGIN, __pPopup->GetOrientation(), bgOutlineEffectRightMargin);
385
386         // Get canvas
387         Canvas* pCanvas = __pPopup->GetCanvasN();
388         SysTryReturnVoidResult(NID_UI_CTRL, pCanvas != null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
389
390         pCanvas->SetBackgroundColor(Color(0, 0, 0, 0));
391         pCanvas->Clear();
392
393         Canvas* pBackgroundCanvas = __pBackgroundVE->GetCanvasN();
394         SysTryCatch(NID_UI_CTRL, pBackgroundCanvas != null, , GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
395
396         pBackgroundCanvas->SetBackgroundColor(Color(0, 0, 0, 0));
397         pBackgroundCanvas->Clear();
398
399         // Draw BG
400         if (__pPopup->GetBackgroundBitmap() != null)
401         {
402                 Rectangle bounds(-transLeftMargin,
403                                                 -transTopMargin,
404                                                 __pPopup->GetBounds().width + transLeftMargin + transRightMargin,
405                                                 __pPopup->GetBounds().height + transTopMargin + transBottomMargin);
406
407                 const Bitmap* pBackgroundBitmap = __pPopup->GetBackgroundBitmap();
408                 if (pBackgroundBitmap->IsNinePatchedBitmap() == true)
409                 {
410                         pCanvas->DrawNinePatchedBitmap(bounds, *pBackgroundBitmap);
411                 }
412                 else
413                 {
414                         pCanvas->DrawBitmap(bounds, *pBackgroundBitmap);
415                 }
416         }
417
418         // Draw Title
419         if (__pPopup->HasTitle())
420         {
421                 if (__pTextObject != null)
422                 {
423                         _pFont = __pPopup->GetFallbackFont();
424                         r = GetLastResult();
425                         SysTryCatch(NID_UI_CTRL, _pFont != null, , r, "[%s] Propagating.", GetErrorMessage(r));
426
427                         __pTextObject->SetFont(_pFont, 0, __pTextObject->GetTextLength());
428                         __pTextObject->SetBounds(__titleBounds);
429                         __pTextObject->SetForegroundColor(__pPopup->GetTitleTextColor(), 0, __pTextObject->GetTextLength());
430
431                         __pTextObject->Draw(*_CanvasImpl::GetInstance(*pCanvas));
432                 }
433         }
434
435
436         // Draw Outline
437         if (__pPopup->GetOutlineBitmap() != null)
438         {
439                 Rectangle bounds(0,
440                                                  0,
441                                                 __pPopup->GetBounds().width + bgOutlineEffectLeftMargin + bgOutlineEffectRightMargin,
442                                                 __pPopup->GetBounds().height + bgOutlineEffectTopMargin + bgOutlineEffectBottomMargin);
443
444                 const Bitmap* pOutlineBitmap = __pPopup->GetOutlineBitmap();
445
446                 if (pOutlineBitmap->IsNinePatchedBitmap() == true)
447                 {
448                         pBackgroundCanvas->DrawNinePatchedBitmap(bounds, *pOutlineBitmap);
449                 }
450                 else
451                 {
452                         pBackgroundCanvas->DrawBitmap(bounds, *pOutlineBitmap);
453                 }
454         }
455
456         //fall thtrough
457 CATCH:
458         delete pCanvas;
459         delete pBackgroundCanvas;
460
461         return;
462 }
463
464 void
465 _PopupPresenter::OnActivated(void)
466 {
467         result r = E_SUCCESS;
468
469 #if !defined(MULTI_WINDOW)
470                 VisualElement* pParent = __pPopupVE->GetParent();
471 #else
472                 _Window* pWindow = __pPopup->GetRootWindow();
473                 _RootVisualElement* pParent = pWindow->GetRootVisualElement();
474 #endif
475
476         if (pParent)
477         {
478                 r = pParent->InsertChild(*__pBackgroundVE, __pPopupVE, false);
479                 SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
480         }
481
482         return;
483 }
484
485 result
486 _PopupPresenter::DoModal(int& modalResult)
487 {
488         result r = E_SUCCESS;
489
490         r = __pPopup->Open();
491         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
492
493         ProcessEvent();
494
495         __pPopup->Close();
496
497         modalResult = __pPopup->GetPopupReturnValue();
498
499         return r;
500 }
501
502 void
503 _PopupPresenter::ProcessEvent(void)
504 {
505         _ModalLoopManager::GetInstance()->BeginMainLoop();
506
507         int exitCode = _ModalLoopManager::GetInstance()->GetLastExitCode();
508         switch (exitCode)
509         {
510         case _ModalLoopManager::MODAL_LOOP_EXIT_CODE_APP_TERMINATION:
511         case _ModalLoopManager::MODAL_LOOP_EXIT_CODE_CONTINUOUS_TERMINATION:
512                 _ModalLoopManager::GetInstance()->EndMainLoop(exitCode, false);
513                 break;
514         default:
515                 break;
516         }
517 }
518
519 bool
520 _PopupPresenter::OnTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
521 {
522         Point point = touchinfo.GetCurrentPosition();
523
524         return true;
525 }
526
527 bool
528 _PopupPresenter::OnTouchReleased(const _Control& source, const _TouchInfo& touchinfo)
529 {
530         Point point = touchinfo.GetCurrentPosition();
531
532         return true;
533 }
534
535
536 }}} // Tizen::Ui::Controls
537
538