2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
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
9 // http://floralicense.org/license/
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.
19 #include <unique_ptr.h>
20 #include <FAppUiApp.h>
21 #include <FAppIAppFrame.h>
23 #include <FUiControl.h>
24 #include <FUiCtrlFrame.h>
25 #include <FUiCtrlForm.h>
26 #include <FUiCtrlPanel.h>
27 #include <FUiAnimFrameAnimator.h>
28 #include <FUiAnimControlAnimator.h>
29 #include <FUiAnimAnimationTransaction.h>
30 #include <FUiScenesSceneManager.h>
31 #include <FUiScenesScene.h>
32 #include <FUiScenesISceneEventListener.h>
33 #include <FUiScenesISceneManagerEventListener.h>
34 #include <FUiScenesISceneTransitionPolicyProvider.h>
35 #include <FUiScenesIFormFactory.h>
36 #include <FUiScenesIPanelFactory.h>
37 #include <FUiScenesForwardSceneTransition.h>
38 #include <FUiScenesBackwardSceneTransition.h>
39 #include <FBaseSysLog.h>
40 #include "FUiScenes_SceneImpl.h"
41 #include "FUiScenes_SceneManagerImpl.h"
42 #include "FUiScenes_SceneTransitionImpl.h"
43 #include "FUiAnim_FrameAnimatorImpl.h"
44 #include "FUi_Control.h"
45 #include "FUi_ControlManager.h"
46 #include "FUi_ContainerImpl.h"
49 using namespace Tizen::Base;
50 using namespace Tizen::Base::Collection;
51 using namespace Tizen::App;
52 using namespace Tizen::Io;
53 using namespace Tizen::Ui;
54 using namespace Tizen::Ui::Controls;
55 using namespace Tizen::Ui::Animations;
56 using namespace Tizen::Graphics;
59 namespace Tizen { namespace Ui { namespace Scenes
62 // HashMapT assist template
64 class _StringHashCodeProvider
65 : public IHashCodeProviderT <T>
69 GetHashCode(const T& obj) const
71 String& objString = static_cast <String&>(const_cast <T&>(obj));
72 return objString.GetHashCode();
77 : public IComparerT <T>
81 Compare(const T& obj1, const T& obj2, int& cmp) const
83 String& objString1 = static_cast <String&>(const_cast <T&>(obj1));
84 String& objString2 = static_cast <String&>(const_cast <T&>(obj2));
85 cmp = objString1.CompareTo(objString2);
91 _SceneManagerImpl::_SceneDescription::_SceneDescription(const String& descriptionFormId, const String& descriptionPanelId)
92 : formId(descriptionFormId)
93 , panelId(descriptionPanelId)
98 _SceneManagerImpl::_SceneManagerImpl(void)
99 : __currentSceneId(L"")
100 , __pCurrentScene(null)
101 , __pFormFactory(null)
102 , __pPanelFactory(null)
103 , __pPolicyProvider(null)
104 , __destroyReservedScene(L"")
105 , __pCorrespondFrame(null)
106 , __correspondFrameControlHandle()
108 for (int i = 0; i < FRAME_ANIMATOR_FORM_TRANSITION_ANIMATION_MAX; i++)
110 static const long ANIMATION_DURATION = 250L;
111 __animationDescriptions[i].animationType = FrameAnimatorFormTransitionAnimation(i);
112 __animationDescriptions[i].duration = ANIMATION_DURATION;
113 __animationDescriptions[i].interpolatorType = ANIMATION_INTERPOLATOR_LINEAR;
117 _SceneManagerImpl::~_SceneManagerImpl(void)
119 std::unique_ptr<IMapEnumeratorT<String, _SceneDescription*> > pMapEnum(__sceneMap.GetMapEnumeratorN());
122 while (pMapEnum->MoveNext() == E_SUCCESS)
124 _SceneDescription* pValue = null;
125 pMapEnum->GetValue(pValue);
131 SysLogException(NID_UI_SCENES, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
134 std::unique_ptr<IMapEnumeratorT<String, SceneTransition*> > pTransitionMapEnum(__transitionMap.GetMapEnumeratorN());
135 if (pTransitionMapEnum)
137 while (pTransitionMapEnum->MoveNext() == E_SUCCESS)
139 SceneTransition* pValue = null;
140 pTransitionMapEnum->GetValue(pValue);
146 SysLogException(NID_UI_SCENES, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
151 _SceneManagerImpl::Construct(void)
153 result r = E_SUCCESS;
154 static _StringHashCodeProvider <String> sceneHashCodeProvider;
155 static _StringComparer <String> strComparer;
157 r = __sceneContainer.Construct(0, 0, sceneHashCodeProvider, strComparer);
158 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
159 r = __formContainer.Construct(0, 0, sceneHashCodeProvider, strComparer);
160 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
161 r = __formToPanelMultiMap.Construct(0, 0, sceneHashCodeProvider, strComparer);
162 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
163 r = __sceneMap.Construct(0, 0, sceneHashCodeProvider, strComparer);
164 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
165 r = __transitionMap.Construct(0, 0, sceneHashCodeProvider, strComparer);
166 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
168 r = __sceneControlEvent.Construct();
169 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
170 r = __sceneControlEvent.AddListener(dynamic_cast<_ISceneControlEventListener&>(*this));
171 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
173 UiApp* pUiApp = UiApp::GetInstance();
174 SysTryReturn(NID_UI_SCENES, pUiApp != null, null, E_SYSTEM,
175 "[%s] A system error has been occurred. UiApp::GetInstance failed.", GetErrorMessage(E_SYSTEM));
176 Frame* pFrame = pUiApp->GetFrameAt(0);
177 SysTryReturn(NID_UI_SCENES, pFrame != null, null, E_SYSTEM,
178 "[%s] A system error has been occurred. pUiApp->GetFrameAt(0) return null.", GetErrorMessage(E_SYSTEM));
179 __pCorrespondFrame = pFrame;
180 _ContainerImpl* pFrameWindowImpl = _ContainerImpl::GetInstance(*__pCorrespondFrame);
181 SysTryReturn(NID_UI_SCENES, pFrameWindowImpl != null, null, E_SYSTEM,
182 "[%s] A system error has been occurred. _ContainerImpl::GetInstance failed.", GetErrorMessage(E_SYSTEM));
183 __correspondFrameControlHandle = pFrameWindowImpl->GetCore().GetHandle();
189 _SceneManagerImpl::RegisterFormFactory(const IFormFactory& formFactory)
191 __pFormFactory = const_cast <IFormFactory*>(&formFactory);
197 _SceneManagerImpl::RegisterPanelFactory(const IPanelFactory& panelFactory)
199 __pPanelFactory = const_cast <IPanelFactory*>(&panelFactory);
205 _SceneManagerImpl::RegisterScene(const SceneId& sceneId, const String& formId, const String& panelId)
207 result r = E_SUCCESS;
208 _SceneDescription* pSceneDescription = null;
209 bool isContains = false;
211 SysTryReturnResult(NID_UI_SCENES, !(sceneId.IsEmpty() || formId.IsEmpty()), E_INVALID_ARG,
212 "Invalid argument is used. String length of sceneId=%d, formId=%d",
213 sceneId.GetLength(), formId.GetLength());
215 r = __sceneMap.ContainsKey(sceneId, isContains);
216 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
217 SysTryReturnResult(NID_UI_SCENES, !isContains, E_OBJ_ALREADY_EXIST, "Specified sceneId already exist.");
219 pSceneDescription = new (std::nothrow) _SceneDescription(formId, panelId);
220 SysTryReturnResult(NID_UI_SCENES, pSceneDescription != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
222 r = __sceneMap.Add(sceneId, pSceneDescription);
223 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
227 delete pSceneDescription;
232 _SceneManagerImpl::RegisterScene(const String& resourceId)
234 static const wchar_t RESOUCE_FILE_PATH[] = L"res/";
235 static const wchar_t RESOUCE_FILE_EXT[] = L".xml";
236 static const wchar_t RESOUCE_FILE_NORMAL[] = L"screen-size-normal/";
237 static const xmlChar* pElementWorkflow = reinterpret_cast<const xmlChar*>("Workflow");
238 static const xmlChar* pElementScene = reinterpret_cast<const xmlChar*>("Scene");
239 static const xmlChar* pElementSceneTransition = reinterpret_cast<const xmlChar*>("SceneTransition");
240 result r = E_SUCCESS;
242 _ControlManager* pControlManager = _ControlManager::GetInstance();
243 SysTryReturnResult(NID_UI_SCENES, pControlManager != null, E_SYSTEM,
244 "A system error has been occurred. Unable to get the control manager.");
245 Dimension screenSize = pControlManager->GetScreenSize();
247 const String appRootPath = Tizen::App::App::GetInstance()->GetAppRootPath();
249 // Formating path for current resolution: [AppRootPath/][res/][width]x[height]/[resourceId][.xml]
250 r = filePath.Format(FILENAME_MAX, L"%ls%ls%dx%d/%ls%ls",
251 appRootPath.GetPointer(), RESOUCE_FILE_PATH, screenSize.width, screenSize.height,
252 resourceId.GetPointer(), RESOUCE_FILE_EXT);
253 SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM, "A system error has been occurred. File path formatting failed.");
254 SysLog(NID_UI_SCENES, "RegisterScene: res path: %ls", filePath.GetPointer());
256 if (!File::IsFileExist(filePath))
257 { // File not exist on specific resolution then try again: [AppRootPath/][res/][screen-size-normal/][resourceId][.xml]
258 filePath.Format(FILENAME_MAX, L"%ls%ls%ls%ls%ls",
259 appRootPath.GetPointer(), RESOUCE_FILE_PATH, RESOUCE_FILE_NORMAL,
260 resourceId.GetPointer(), RESOUCE_FILE_EXT);
261 SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM, "A system error has been occurred. File path formatting failed.");
262 SysLog(NID_UI_SCENES, "RegisterScene: 2nd try - res path: %ls", filePath.GetPointer());
263 if (!pControlManager->IsCoordinateSystemLogical() || !File::IsFileExist(filePath))
265 SysLogException(NID_UI_SCENES, E_FILE_NOT_FOUND, "[%s] File could not be found. File path=%ls",
266 GetErrorMessage(E_FILE_NOT_FOUND), filePath.GetPointer());
267 return E_FILE_NOT_FOUND;
271 std::unique_ptr<ByteBuffer> pfilePathBuffer(Tizen::Base::Utility::StringUtil::StringToUtf8N(filePath));
272 SysTryReturnResult(NID_UI_SCENES, pfilePathBuffer != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
274 xmlDocPtr docPtr = xmlParseFile(reinterpret_cast<const char*>(pfilePathBuffer->GetPointer()));
275 SysTryReturnResult(NID_UI_SCENES, docPtr != null, E_SYSTEM,
276 "A system error has been occurred. Can not parse xml file: %ls", filePath.GetPointer());
278 xmlNodePtr rootNodePtr = xmlDocGetRootElement(docPtr);
279 SysTryReturnResult(NID_UI_SCENES, rootNodePtr != null, E_SYSTEM,
280 "A system error has been occurred. Can not find root node");
283 for (xmlNodePtr nodePtr = rootNodePtr; nodePtr != null; nodePtr = nodePtr->next) // Visit sibling node
284 { // Get element 'Workflow'
285 if ((nodePtr->type == XML_ELEMENT_NODE) && (xmlStrcmp(nodePtr->name, pElementWorkflow) == 0))
286 { // and Get child - 'Scene's and 'SceneTransition's
287 for (xmlNodePtr childNodePtr = nodePtr->children; childNodePtr != null; childNodePtr = childNodePtr->next) // Visit sibling
288 { // Get element 'Scene's and 'SceneTransition's
289 if (childNodePtr->type == XML_ELEMENT_NODE)
290 { // Check E_OBJ_ALREADY_EXIST(continue) and E_OUT_OF_MEMORY(break) for all case.
291 if (xmlStrcmp(childNodePtr->name, pElementScene) == 0)
293 result regResult = RegisterScene(childNodePtr);
294 if (IsFailed(regResult))
296 SysTryCatch(NID_UI_SCENES, regResult != E_OUT_OF_MEMORY, r = regResult, regResult,
297 "[%s] Propagating.", GetErrorMessage(regResult));
298 if (regResult == E_OBJ_ALREADY_EXIST)
305 if (xmlStrcmp(childNodePtr->name, pElementSceneTransition) == 0)
307 result regResult = RegisterSceneTransition(childNodePtr);
308 if (IsFailed(regResult))
310 SysTryCatch(NID_UI_SCENES, regResult != E_OUT_OF_MEMORY, r = regResult, regResult,
311 "[%s] Propagating.", GetErrorMessage(regResult));
312 if (regResult == E_OBJ_ALREADY_EXIST)
318 } // 'Scene' and 'SceneTransition'
319 } // Children of 'Workflow'
320 } // Element 'Workflow'
321 }// Root node sibling
332 _SceneManagerImpl::UnregisterScene(const SceneId& sceneId)
334 result r = E_SUCCESS;
335 _SceneDescription* pSceneDescription = null;
337 SysTryReturnResult(NID_UI_SCENES, !sceneId.IsEmpty(), E_INVALID_ARG, "Invalid argument is used. sceneId is empty.");
339 r = __sceneMap.GetValue(sceneId, pSceneDescription);
340 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
342 r = __sceneMap.Remove(sceneId);
343 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
345 delete pSceneDescription;
350 _SceneManagerImpl::AddSceneManagerEventListener(ISceneManagerEventListener& sceneManagerEventListener)
352 result r = E_SUCCESS;
353 ISceneManagerEventListener* pListener = &sceneManagerEventListener;
354 bool alreadyExist = __sceneManagerEventListenerList.Contains(pListener);
355 SysTryReturnResult(NID_UI_SCENES, !alreadyExist, E_OBJ_ALREADY_EXIST, "The event listener already exist.");
356 r = __sceneManagerEventListenerList.Add(pListener);
357 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
363 _SceneManagerImpl::RemoveSceneManagerEventListener(ISceneManagerEventListener& sceneManagerEventListener)
365 result r = E_SUCCESS;
366 ISceneManagerEventListener* pListener = &sceneManagerEventListener;
367 r = __sceneManagerEventListenerList.Remove(pListener);
368 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
374 _SceneManagerImpl::AddSceneEventListener(const SceneId& sceneId, ISceneEventListener& sceneEventListener)
376 result r = E_SUCCESS;
377 Scene* pScene = null;
378 _SceneImpl* pSceneImpl = null;
380 pScene = GetSceneFromContainer(sceneId);
381 SysTryReturnResult(NID_UI_SCENES, pScene != null, E_INVALID_ARG, "Invalid argument is used. The sceneId is not valid.");
382 pSceneImpl = _SceneImpl::GetInstance(*pScene);
383 SysTryReturnResult(NID_UI_SCENES, pSceneImpl != null, E_INVALID_ARG, "Invalid argument is used. The sceneId is not valid.");
384 r = pSceneImpl->AddSceneEventListener(sceneEventListener);
385 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
391 _SceneManagerImpl::RemoveSceneEventListener(const SceneId& sceneId, ISceneEventListener& sceneEventListener)
393 result r = E_SUCCESS;
394 Scene* pScene = null;
395 _SceneImpl* pSceneImpl = null;
397 pScene = GetSceneFromContainer(sceneId);
398 SysTryReturnResult(NID_UI_SCENES, pScene != null, E_INVALID_ARG, "Invalid argument is used. The sceneId is not valid.");
399 pSceneImpl = _SceneImpl::GetInstance(*pScene);
400 SysTryReturnResult(NID_UI_SCENES, pSceneImpl != null, E_INVALID_ARG, "Invalid argument is used. The sceneId is not valid.");
401 r = pSceneImpl->RemoveSceneEventListener(sceneEventListener);
402 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
408 _SceneManagerImpl::SetSceneAnimationProvider(const SceneId& sceneId, ISceneAnimationProvider* pSceneAnimationProvider)
410 result r = E_SUCCESS;
411 Scene* pScene = null;
412 _SceneImpl* pSceneImpl = null;
414 pScene = GetSceneFromContainer(sceneId);
415 SysTryReturnResult(NID_UI_SCENES, pScene != null, E_INVALID_ARG, "Invalid argument is used. The sceneId is not valid.");
416 pSceneImpl = _SceneImpl::GetInstance(*pScene);
417 SysTryReturnResult(NID_UI_SCENES, pSceneImpl != null, E_INVALID_ARG, "Invalid argument is used. The sceneId is not valid.");
418 r = pSceneImpl->SetSceneAnimationProvider(pSceneAnimationProvider);
419 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
425 _SceneManagerImpl::SetSceneTransitionPolicyProvider(ISceneTransitionPolicyProvider* pSceneTransitionPolicyProvider)
427 __pPolicyProvider = pSceneTransitionPolicyProvider;
433 _SceneManagerImpl::SetFormTransitionAnimationDefaultValues(SceneTransitionAnimationType animationType, long duration,
434 AnimationInterpolatorType interpolatorType)
436 static const long DURATION_MIN = 0;
437 static const long DURATION_MAX = 1000;
439 SysTryReturnResult(NID_UI_SCENES, (SCENE_TRANSITION_ANIMATION_TYPE_LEFT <= animationType &&
440 animationType <= SCENE_TRANSITION_ANIMATION_TYPE_DEPTH_OUT), E_INVALID_ARG,
441 "Invalid argument is used. animationType=%d", animationType);
442 SysTryReturnResult(NID_UI_SCENES, (DURATION_MIN <= duration && duration <= DURATION_MAX), E_INVALID_ARG,
443 "Invalid argument is used. duration=%d", duration);
444 __animationDescriptions[animationType - SCENE_TRANSITION_ANIMATION_TYPE_LEFT].duration = duration;
445 __animationDescriptions[animationType - SCENE_TRANSITION_ANIMATION_TYPE_LEFT].interpolatorType = interpolatorType;
451 _SceneManagerImpl::GoForward(const ForwardSceneTransition& sceneTransition, const Tizen::Base::Collection::IList* pArgs)
453 SysTryReturnResult(NID_UI_SCENES, IsAnimationCompleted() == true, E_IN_PROGRESS, "Previous operation in progressing");
454 result r = E_SUCCESS;
456 const _SceneTransitionImpl& forwardSceneTransition
457 = *_SceneTransitionImpl::GetInstance(static_cast<const SceneTransition&>(sceneTransition));
458 SysTryReturnResult(NID_UI_SCENES, forwardSceneTransition.GetDirection() == SCENE_TRANSITION_DIRECTION_FORWARD, E_INVALID_ARG,
459 "Invalid argument is used. sceneTransition's direction is not SCENE_TRANSITION_DIRECTION_FORWARD.");
461 SceneId sceneId = forwardSceneTransition.GetDestinationSceneId();
462 if (sceneId.GetLength() > 0)
463 { // Goto the specified scene
464 r = GotoScene(true, sceneId, forwardSceneTransition.GetAnimationType(),
465 forwardSceneTransition.GetHistoryOption(), forwardSceneTransition.GetDestroyOption(), pArgs);
466 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
469 { // Transition via PolicyProvider
470 SysTryReturnResult(NID_UI_SCENES, __pPolicyProvider != null, E_INVALID_STATE,
471 "SceneManager is in an invalid state. Policy provider not registered.");
473 String nextSceneId = __pPolicyProvider->GetNextScene(__currentSceneId, pArgs);
474 SysTryReturnResult(NID_UI_SCENES, !nextSceneId.IsEmpty(), E_INVALID_STATE,
475 "SceneManager is in an invalid state. Policy provider does not know next scene.");
477 r = GotoScene(true, nextSceneId, forwardSceneTransition.GetAnimationType(),
478 forwardSceneTransition.GetHistoryOption(), forwardSceneTransition.GetDestroyOption(), pArgs);
479 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
486 _SceneManagerImpl::GoForward(const SceneTransitionId& transitionId, const Tizen::Base::Collection::IList* pArgs)
488 ForwardSceneTransition forwardTransition;
490 result r = GetSceneTransition(transitionId, forwardTransition);
491 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
493 return GoForward(forwardTransition, pArgs);
497 _SceneManagerImpl::GoBackward(const BackwardSceneTransition& sceneTransition, const Tizen::Base::Collection::IList* pArgs)
499 SysTryReturnResult(NID_UI_SCENES, IsAnimationCompleted() == true, E_IN_PROGRESS, "Previous operation in progressing");
500 result r = E_SUCCESS;
502 const int historyCount = __sceneHistory.GetCount();
503 SysTryReturnResult(NID_UI_SCENES, historyCount != 0, E_UNDERFLOW, "The Scene history is empty.");
505 const _SceneTransitionImpl& backwardSceneTransition = *_SceneTransitionImpl::GetInstance(sceneTransition);
506 SysTryReturnResult(NID_UI_SCENES, backwardSceneTransition.GetDirection() == SCENE_TRANSITION_DIRECTION_BACKWARD,
508 "Invalid argument is used. sceneTransition's direction is not SCENE_TRANSITION_DIRECTION_BACKWARD!");
509 SysTryReturnResult(NID_UI_SCENES, backwardSceneTransition.GetHistoryOption() == SCENE_HISTORY_OPTION_NO_HISTORY,
511 "Invalid argument is used. sceneTransition's history option is not SCENE_HISTORY_OPTION_NO_HISTORY!");
513 SceneId sceneId = backwardSceneTransition.GetDestinationSceneId();
514 if (sceneId.GetLength() > 0)
515 { // Back to specific scene and clean up history between destination and last point.
516 int historyIndex = -1;
517 SceneId destinationSceneId;
519 // 1. Back tracking and pick a first matching sceneId
520 r = __sceneHistory.LastIndexOf(sceneId, historyIndex);
521 SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_OBJ_NOT_FOUND,
522 "The given sceneId was not found in the registered scenes.");
523 r = __sceneHistory.GetAt(historyIndex, destinationSceneId);
524 SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM, "A system error has been occurred.");
526 // 2. if destoryOption == SCENE_DESTROY_OPTION_DESTROY then destroy all scenes except matching scene.
527 if (backwardSceneTransition.GetDestroyOption() == SCENE_DESTROY_OPTION_DESTROY)
529 for (int i = historyIndex+1; i < historyCount; i++)
531 SceneId destroyTargetSceneId;
532 __sceneHistory.GetAt(i, destroyTargetSceneId);
533 // Scene instance is not always valid.
534 Scene* pScene = GetSceneFromContainer(destroyTargetSceneId);
537 // If Panel Scene then destroy sibling Panel Scene(s).
538 if (pScene->GetPanel())
540 DestroySiblingPanelScene(destroyTargetSceneId);
542 DestroyScene(destroyTargetSceneId);
547 // 3. Remove all scenes on history between latest scene to matching scene.
548 r = __sceneHistory.RemoveItems(historyIndex, historyCount-historyIndex);
549 SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM, "A system error has been occurred.");
552 r = GotoScene(false, destinationSceneId, backwardSceneTransition.GetAnimationType(),
553 SCENE_HISTORY_OPTION_NO_HISTORY, backwardSceneTransition.GetDestroyOption(), pArgs);
554 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
557 { // Adjacent backward transition
558 SceneId previousSceneId;
560 r = __sceneHistory.GetAt(historyCount-1, previousSceneId);
561 SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_OBJ_NOT_FOUND,
562 "The given sceneId was not found in the registered scenes.");
563 r = __sceneHistory.RemoveAt(historyCount-1);
564 SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM, "A system error has been occurred.");
566 r = GotoScene(false, previousSceneId, backwardSceneTransition.GetAnimationType(),
567 SCENE_HISTORY_OPTION_NO_HISTORY, backwardSceneTransition.GetDestroyOption(), pArgs);
568 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
575 _SceneManagerImpl::GoBackward(const SceneTransitionId& transitionId, const Tizen::Base::Collection::IList* pArgs)
577 BackwardSceneTransition backwardTransition;
579 result r = GetSceneTransition(transitionId, backwardTransition);
580 SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_INVALID_ARG, "Cannot get transition from Id.");
582 return GoBackward(backwardTransition, pArgs);
586 _SceneManagerImpl::GetCurrentScene(void) const
588 return __pCurrentScene;
592 _SceneManagerImpl::GetCurrentSceneId(void) const
594 return __currentSceneId;
598 _SceneManagerImpl::IsSceneAlive(const SceneId& sceneId) const
600 return (GetSceneFromContainer(sceneId)) ? true : false;
604 _SceneManagerImpl::DestroyScene(const SceneId& sceneId)
606 result r = E_SUCCESS;
607 Scene* pScene = null;
608 bool isFormScene = false;
609 bool isLastPanel = false;
612 SysTryReturnResult(NID_UI_SCENES, __currentSceneId != sceneId, E_INVALID_ARG,
613 "Invalid argument is used. The current Scene can not be destroy.");
614 pScene = GetSceneFromContainer(sceneId);
615 SysTryReturnResult(NID_UI_SCENES, pScene != null, E_OBJ_NOT_FOUND, "Specified sceneId does not exist.");
617 // Ok now destroy associated Ui controls
618 // Form scene: Destroy Form - that's all.
619 // Panel scene: Normal case - destroy Panel only but the current scene is the last panel then destroy Form.
620 // Correspondent internal data item should be destroy.
621 if (!pScene->GetPanel())
627 r = __formToPanelMultiMap.GetCount(pScene->GetFormId(), panelCount);
628 SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM,
629 "A system error has been occurred. Form(SceneId:%ls) is not valid.", sceneId.GetPointer());
637 { // 1. Remove Form control(Associated on Scene) from Frame
638 RemoveControlFromFrame(*pScene->GetForm());
639 // 2. Remove Form from Form container
640 RemoveFormFromFormContainer(pScene->GetFormId());
644 { // 1. Remove Panel from Panel container.
645 RemovePanelFromPanelContainer(pScene);
646 // 2. Remove Form control from Frame. (Associated Panel automatically removed by Ui)
647 RemoveControlFromFrame(*pScene->GetForm());
648 // 3. Remove Form from Form container.
649 RemoveFormFromFormContainer(pScene->GetFormId());
652 { // 1. Remove Panel from Panel container.
653 RemovePanelFromPanelContainer(pScene);
654 // 2. Remove Panel control from base Form
655 bool panelFromFormResouce = false;
656 _SceneImpl* pSceneImpl = _SceneImpl::GetInstance(*pScene);
659 panelFromFormResouce = pSceneImpl->IsPanelCreatedFromFormResource();
661 if (!panelFromFormResouce)
663 RemoveControlFromForm(*pScene->GetForm(), *pScene->GetPanel());
667 // Finally remove Scene
668 RemoveSceneFromContainer(sceneId);
675 _SceneManagerImpl::BringCurrentSceneToTop(void)
678 Scene* pCurrentScene = GetCurrentScene();
680 SysTryReturnResult(NID_UI_SCENES, pCurrentScene != null, E_OPERATION_FAILED, "The current Scene is not valid.");
681 pForm = pCurrentScene->GetForm();
682 SysTryReturnResult(NID_UI_SCENES, pForm != null, E_SYSTEM, "A system error has been occurred. The Form is not valid.");
683 result r = SetCurrentForm(*pForm);
684 SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM, "A system error has been occurred.");
690 _SceneManagerImpl::ClearSceneHistory(void)
692 __sceneHistory.RemoveAll();
698 _SceneManagerImpl::AddToSceneHistory(const SceneId& sceneId)
700 result r = E_SUCCESS;
701 bool isContains = false;
703 SysTryReturnResult(NID_UI_SCENES, !sceneId.IsEmpty(), E_INVALID_ARG, "Invalid argument is used. sceneId length is 0.");
704 r = __sceneMap.ContainsKey(sceneId, isContains);
705 SysTryReturnResult(NID_UI_SCENES, isContains, E_OBJ_NOT_FOUND, "The sceneId is not registered.");
706 r = AddHistory(sceneId);
707 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
713 _SceneManagerImpl::GetSceneHistoryN(void) const
715 IListT<String>* pSceneList = null;
716 pSceneList = new (std::nothrow) ArrayListT<String>;
717 SysTryReturn(NID_UI_SCENES, pSceneList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
718 GetErrorMessage(E_OUT_OF_MEMORY));
720 pSceneList->AddItems(__sceneHistory);
725 _SceneManagerImpl::GetInstance(SceneManager& pSceneManager)
727 return pSceneManager.__pSceneManagerImpl;
730 const _SceneManagerImpl*
731 _SceneManagerImpl::GetInstance(const SceneManager& pSceneManager)
733 return pSceneManager.__pSceneManagerImpl;
736 // Event handelers to asynchronous destroy the Scene.
738 _SceneManagerImpl::OnFormTransitionAnimationFinished(FrameAnimator& source, Frame& frame, Form& form1, Form& form2)
740 source.RemoveFrameAnimatorEventListener(*this);
741 DestroyReservedScene();
745 _SceneManagerImpl::OnFormTransitionAnimationStarted(FrameAnimator& source, Frame& frame, Form& form1, Form& form2)
751 _SceneManagerImpl::OnFormTransitionAnimationStopped(FrameAnimator& source, Frame& frame, Form& form1, Form& form2)
753 source.RemoveFrameAnimatorEventListener(*this);
754 DestroyReservedScene();
758 _SceneManagerImpl::OnControlAnimationFinished(ControlAnimator& source, Control& control)
760 source.RemoveControlAnimatorEventListener(*this);
761 DestroyReservedScene();
765 _SceneManagerImpl::OnControlAnimationStarted(ControlAnimator& source, Control& control)
771 _SceneManagerImpl::OnControlAnimationStopped(ControlAnimator& source, Control& control)
773 source.RemoveControlAnimatorEventListener(*this);
774 DestroyReservedScene();
778 _SceneManagerImpl::OnSceneControlEventReceived(_SceneControlEventArg::SceneControlEventType eventType, const SceneId& sceneId)
780 SysLog(NID_UI_SCENES, "Received type= 0x%x, sceneId=%ls", eventType, &sceneId);
784 case _SceneControlEventArg::SCENE_CONTROL_EVENT_TYPE_DESTROY:
785 DestroyScene(sceneId);
789 SysLog(NID_UI_SCENES, "Invalid SceneControlEventType x0%x", eventType);
794 // Internal operations
796 _SceneManagerImpl::GetScene(SceneId& sceneId)
798 return GetSceneFromContainer(sceneId);
802 _SceneManagerImpl::GetLiveSceneN(void) const
804 std::unique_ptr<ArrayListT<Scene*> > pSceneList(new (std::nothrow) ArrayListT<Scene*>);
805 SysTryReturn(NID_UI_SCENES, pSceneList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
806 GetErrorMessage(E_OUT_OF_MEMORY));
808 std::unique_ptr<IMapEnumeratorT<SceneId, Scene*> > pMapEnum(__sceneContainer.GetMapEnumeratorN());
809 SysTryReturn(NID_UI_SCENES, pMapEnum != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
810 GetErrorMessage(E_OUT_OF_MEMORY));
812 while (pMapEnum->MoveNext() == E_SUCCESS)
814 Scene* pScene = null;
815 pMapEnum->GetValue(pScene);
816 pSceneList->Add(pScene);
818 return pSceneList.release();
823 _SceneManagerImpl::GotoScene(bool forward, const SceneId& sceneId, SceneTransitionAnimationType animationType,
824 SceneHistoryOption historyOption, SceneDestroyOption destroyOption, const IList* pArgs)
826 // 1. Initialize for Scene transition.
827 result r = E_SUCCESS;
828 bool sceneAlreadyCreated = false;
829 bool formAlreadyCreated = false;
830 bool panelAlreadyCreated = false;
831 bool doAnimation = false;
832 bool formTransition = false;
833 Scene* pScene = null;
835 Panel* pPanel = null;
836 SceneId previousSceneId = __currentSceneId; // Save for later
837 String previousFormId = (__pCurrentScene) ? __pCurrentScene->GetFormId() : L"";
838 bool previousIsPanelScene = (__pCurrentScene) ? (__pCurrentScene->GetPanel()) : false;
839 Frame* pFrame = null;
840 FrameAnimator* pFrameAnimator = null;
841 // Exception handling hintings
842 bool onExceptionDeletepScene = false;
843 bool onExceptionRemovesceneIdFromSceneContainer = false;
844 bool onExceptionDeletepForm = false;
845 bool onExceptionRemoveFormIdFromFormContainer = false;
846 bool onExceptionRemovepPanel = false;
848 // Prevent self forward
849 SysTryCatch(NID_UI_SCENES, __currentSceneId != sceneId, r = E_INVALID_ARG, E_INVALID_ARG,
850 "[%s] Invalid argument is used. Can't forward to current Scene.", GetErrorMessage(E_INVALID_ARG));
851 CallListenerOnSceneTransitionStarted(__currentSceneId, sceneId); // Call listener - ISceneManagerEventListener's
853 { // Call listener - ISceneEventListener's
854 CallListenerOnSceneDeactivated(*__pCurrentScene, sceneId, __pCurrentScene->GetSceneId());
857 // 2. Find the Scene on SceneContainer - Scene and correspond UI control has same life time.
858 pScene = GetSceneFromContainer(sceneId);
859 if (pScene) // Activate pScene: Scene already existing then Re-activate associated a Form and a Panel.
861 sceneAlreadyCreated = true;
862 pForm = GetFormFromContainer(pScene->GetFormId());
863 SysTryCatch(NID_UI_SCENES, pForm == pScene->GetForm(), r = E_SYSTEM, E_SYSTEM,
864 "[%s] A system error has been occurred. FormId mismatch with associated From instance.",
865 GetErrorMessage(E_SYSTEM));
866 formAlreadyCreated = true;
867 pPanel = pScene->GetPanel();
870 panelAlreadyCreated = true;
874 { // 3. Scene not found- Create new Scene
875 _SceneDescription* pSceneValue = null;
876 __sceneMap.GetValue(sceneId, pSceneValue);
877 SysTryCatch(NID_UI_SCENES, pSceneValue != null, r = E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND,
878 "[%s] The given sceneId was not found in the registered scenes.", GetErrorMessage(E_OBJ_NOT_FOUND));
879 // 4. Setup the new Scene
880 pScene = _SceneImpl::CreateSceneN(sceneId, pSceneValue->formId, pSceneValue->panelId);
881 SysTryCatch(NID_UI_SCENES, pScene != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
882 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
883 onExceptionDeletepScene = true; // On the CATCH [delete pScene]
884 _SceneImpl* pSceneImpl = _SceneImpl::GetInstance(*pScene);
885 SysTryCatch(NID_UI_SCENES, pSceneImpl != null, r = E_SYSTEM, E_SYSTEM,
886 "[%s] A system error has been occurred. pSceneImpl not valid", GetErrorMessage(E_SYSTEM));
888 AddSceneToContainer(sceneId, pScene);
889 onExceptionRemovesceneIdFromSceneContainer = true; // On the CATCH [remove 'sceneId' from SceneContainer]
890 // 6. Find the Form on FormContainer
891 pForm = GetFormFromContainer(pScene->GetFormId());
892 if (pForm) // Form existing: just call SetCurrentForm
893 { // If the Scene is panel scene then add new panel to pForm or change showState.
894 formAlreadyCreated = true;
895 pSceneImpl->SetForm(pForm); // Panel Scene share same Form intance
897 else// 7. Form not found- Create new Form
898 { // 8. Get the new Form from the FormFactory
899 SysTryCatch(NID_UI_SCENES, __pFormFactory != null, r = E_INVALID_STATE, E_INVALID_STATE,
900 "[%s] SceneManager is in an invalid state. Form factory is not registered.",
901 GetErrorMessage(E_INVALID_STATE));
902 String formId(pScene->GetFormId());
903 pForm = __pFormFactory->CreateFormN(formId, sceneId); // On the CATCH [delete pForm]
904 SysTryCatch(NID_UI_SCENES, pForm != null, r = E_SYSTEM, E_SYSTEM,
905 "[%s] A system error has been occurred. Form(Id=%ls) creation failed on form factroy.",
906 GetErrorMessage(E_SYSTEM), formId.GetPointer());
907 onExceptionDeletepForm = true; // On the CATCH [remove pForm from FormContainer]
909 AddFormToContainer(pScene->GetFormId(), pForm);
910 pSceneImpl->SetForm(pForm);
911 onExceptionRemoveFormIdFromFormContainer = true;
913 // 10. Create panel for Panel Scene
914 // * One Panel instance for each Panel-Scene so no need to check duplicated panel instance for same panel Id.
915 if (!pScene->GetPanelId().IsEmpty())
917 String panelId(pScene->GetPanelId());
918 // First of all, get the Panel from the based Form.
919 // Because, base Form loaded from the resources, the child Panel also loaded and created.
920 // So, do not create a new Panel instance but get from base Form with panelId as resouce Id.
921 pPanel = dynamic_cast<Panel*>(pForm->GetControl(panelId));
924 pSceneImpl->SetPanelCreatedFromFormResource(true); // Prevent RemoveControl - It's not creatable via Panel factory.
928 SysTryCatch(NID_UI_SCENES, __pPanelFactory != null, r = E_INVALID_STATE, E_INVALID_STATE,
929 "[%s] SceneManager is in an invalid state. Panel factory is not registered.",
930 GetErrorMessage(E_INVALID_STATE));
931 pPanel = __pPanelFactory->CreatePanelN(panelId, sceneId); // On the CATCH [delete pPanel]
932 SysTryCatch(NID_UI_SCENES, pPanel != null, r = E_SYSTEM, E_SYSTEM,
933 "[%s] A system error has been occurred. Panel(Id=%ls) creation failed on PanelFactory.",
934 GetErrorMessage(E_SYSTEM), panelId.GetPointer());
935 onExceptionRemovepPanel = true; // On the CATCH [remove pPanel from __formToPanelMultiMap]
937 AddPanelToPanelContainer(pScene);
938 pSceneImpl->SetPanel(pPanel);
942 // For animation logic should be divide Animator section and normal section for proper operations.
943 // If (showAnimation && forwardAnimation is Not NONE) then doing animator related logic /
944 // Setup default animation setting / Add listener to get animation stop/finishing
945 formTransition = (previousFormId != pScene->GetFormId()) ? true : false;
946 doAnimation = (animationType > SCENE_TRANSITION_ANIMATION_TYPE_NONE) ? true : false;
947 if (doAnimation && (animationType != SCENE_TRANSITION_ANIMATION_TYPE_CUSTOM && !formTransition))
951 if (doAnimation && (GetCurrentForm() == null))
958 // Initialize Frame animator
960 SysTryCatch(NID_UI_SCENES, pFrame != null, r = E_SYSTEM, E_SYSTEM,
961 "[%s] A system error has been occurred. Cannot get Frame.", GetErrorMessage(E_SYSTEM));
962 pFrameAnimator = pFrame->GetFrameAnimator();
963 SysTryCatch(NID_UI_SCENES, pFrameAnimator != null, r = E_SYSTEM, E_SYSTEM,
964 "[%s] A system error has been occurred. Cannot get FrameAnimator.", GetErrorMessage(E_SYSTEM));
965 pFrameAnimator->StopAllAnimations();
967 // Initialize Control animator if needed.
968 if (!formTransition && pPanel)
970 ControlAnimator* pControlAnimator = pPanel->GetControlAnimator();
971 SysTryCatch(NID_UI_SCENES, pControlAnimator != null, r = E_SYSTEM, E_SYSTEM,
972 "[%s] A system error has been occurred. Cannot get ControlAnimator.", GetErrorMessage(E_SYSTEM));
973 pControlAnimator->StopAllAnimations();
976 // Set default value for formTransition
977 if (formTransition && (animationType >= SCENE_TRANSITION_ANIMATION_TYPE_LEFT) &&
978 (pFrameAnimator->GetStatus() == ANIMATOR_STATUS_STOPPED))
980 pFrameAnimator->SetFormTransitionAnimation(
981 __animationDescriptions[animationType-SCENE_TRANSITION_ANIMATION_TYPE_LEFT].animationType,
982 __animationDescriptions[animationType-SCENE_TRANSITION_ANIMATION_TYPE_LEFT].duration,
983 __animationDescriptions[animationType-SCENE_TRANSITION_ANIMATION_TYPE_LEFT].interpolatorType);
987 // Prepare animation for customization.
988 CallListenerPrepareAnimation(*pScene, sceneId, const_cast<IList*>(pArgs), animationType, formTransition );
989 // Setup Ui controls to show the result.
990 if (sceneAlreadyCreated)
996 SwitchToPanel(pScene->GetFormId(), pPanel);
998 r = SetCurrentForm(*pForm, doAnimation); // FrameAnimator
999 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1003 r = SetCurrentForm(*pForm);
1004 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1007 SwitchToPanel(pScene->GetFormId(), pPanel, doAnimation); // ControlAnimator
1011 else // Scene newly created
1013 if (formAlreadyCreated) // Panel scene created but base form already created - reuse base form.
1019 if (!panelAlreadyCreated) // If a new panel created then Add Panel to Form
1021 AddControlToForm(*pForm, *pPanel);
1023 SwitchToPanel(pScene->GetFormId(), pPanel);
1025 r = SetCurrentForm(*pForm, (doAnimation)); // FrameAnimator
1026 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1030 r = SetCurrentForm(*pForm);
1031 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1034 if (!panelAlreadyCreated)
1036 AddControlToForm(*pForm, *pPanel);
1038 SwitchToPanel(pScene->GetFormId(), pPanel, doAnimation); // ControlAnimator
1042 else // New Form created!
1047 AddControlToForm(*pForm, *pPanel);
1048 SwitchToPanel(pScene->GetFormId(), pPanel);
1050 AddControlToFrame(*pForm, doAnimation); // Form add to frame
1053 SetCurrentForm(*pForm);
1058 UpdateCurrentScene(pScene);
1059 if ((historyOption == SCENE_HISTORY_OPTION_ADD_HISTORY) && (!previousSceneId.IsEmpty()))
1061 r = AddHistory(previousSceneId);
1062 // Too late revert to previous scene, so just return the error code but not revert to previous state.
1063 SysTryLog(NID_UI_SCENES, !IsFailed(r), "[%s] History adding failed.", GetErrorMessage(r));
1066 CallListenerOnSceneActivatedN(*pScene, previousSceneId, sceneId, const_cast<IList*>(pArgs));
1067 CallListenerOnSceneTransitionCompleted(previousSceneId, __currentSceneId);
1069 if (destroyOption == SCENE_DESTROY_OPTION_DESTROY )
1071 if (previousIsPanelScene)
1073 DestroySiblingPanelScene(previousSceneId); // Destroy sibling Panel Scene
1077 ReserveDestroyingScene(previousSceneId); // Destroy the Scene after animator finished(stopped).
1081 DestroySceneAsync(previousSceneId);
1085 DrawForm(*pScene->GetForm());
1090 // Check all exception case for proper delete the instances: Scene, Form, Panel and item corresponding container.
1091 if (onExceptionRemovepPanel)
1093 RemovePanelFromPanelContainer(pScene);
1094 delete pPanel; // Also needed it.
1097 if (onExceptionRemoveFormIdFromFormContainer)
1099 RemoveFormFromFormContainer(pScene->GetFormId());
1101 if (onExceptionDeletepForm)
1106 if (onExceptionRemovesceneIdFromSceneContainer)
1108 RemoveSceneFromContainer(sceneId);
1110 if (onExceptionDeletepScene)
1119 _SceneManagerImpl::GetSceneFromContainer(const SceneId& sceneId) const
1121 Scene* pScene = null;
1122 __sceneContainer.GetValue(sceneId, pScene);
1127 _SceneManagerImpl::GetFormFromContainer(const String& formId)
1130 __formContainer.GetValue(formId, pForm);
1135 _SceneManagerImpl::AddSceneToContainer(const SceneId& sceneId, Scene* pScene)
1137 __sceneContainer.Add(sceneId, pScene);
1141 _SceneManagerImpl::RemoveSceneFromContainer(const SceneId& sceneId)
1143 __sceneContainer.Remove(sceneId);
1147 _SceneManagerImpl::AddFormToContainer(const String& formId, Form* pForm)
1149 __formContainer.Add(formId, pForm);
1153 _SceneManagerImpl::RemoveFormFromFormContainer(const String& formId)
1155 __formContainer.Remove(formId);
1159 _SceneManagerImpl::AddPanelToPanelContainer(Scene* pScene)
1161 __formToPanelMultiMap.Add(pScene->GetFormId(), pScene);
1165 _SceneManagerImpl::RemovePanelFromPanelContainer(Scene* pScene)
1167 __formToPanelMultiMap.Remove(pScene->GetFormId(), pScene);
1171 _SceneManagerImpl::UpdateCurrentScene(Scene* pScene)
1173 __pCurrentScene = pScene;
1174 __currentSceneId = pScene->GetSceneId();
1178 _SceneManagerImpl::AddHistory(const SceneId& sceneId)
1180 return __sceneHistory.Add(sceneId);
1184 _SceneManagerImpl::SwitchToPanel(const String& formId, Panel* pPanel, bool useAnimator)
1186 Panel* pShowPanel = null;
1188 std::unique_ptr<IEnumeratorT<Scene*> > pSceneEnum(__formToPanelMultiMap.GetValuesN(formId));
1189 SysTryReturnVoidResult(NID_UI_SCENES, pSceneEnum != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
1190 GetErrorMessage(E_OUT_OF_MEMORY));
1191 while (pSceneEnum->MoveNext() == E_SUCCESS)
1193 Scene* pCurrentScene = null;
1194 pSceneEnum->GetCurrent(pCurrentScene);
1195 SysTryReturnVoidResult(NID_UI_SCENES, pCurrentScene != null, E_SYSTEM, "[%s] Memory allocation failed.",
1196 GetErrorMessage(E_OUT_OF_MEMORY));
1197 if (pCurrentScene->GetPanel() != pPanel)
1199 if (pCurrentScene->GetPanel()->GetShowState())
1201 pShowPanel = pCurrentScene->GetPanel();
1206 if (useAnimator && pShowPanel && pPanel)
1208 int transactionId = 0;
1209 AnimationTransaction::Begin(transactionId);
1216 ControlAnimator* pControlAnimator = pShowPanel->GetControlAnimator();
1217 if (pControlAnimator)
1219 pControlAnimator->AddControlAnimatorEventListener(*this);
1220 pControlAnimator->SetShowState(false);
1225 pShowPanel->SetShowState(false);
1232 ControlAnimator* pControlAnimator = pPanel->GetControlAnimator();
1233 if (pControlAnimator)
1235 pControlAnimator->SetShowState(true);
1240 pPanel->SetShowState(true);
1244 if (useAnimator && pShowPanel && pPanel)
1246 result r = AnimationTransaction::Commit();
1249 SysLog(NID_UI_SCENES, "Animation Commit() failed");
1255 _SceneManagerImpl::AddControlToFrame(Form& form, bool useAnimator)
1257 Frame* pFrame = GetFrame();
1262 FrameAnimator* pFrameAnimator = pFrame->GetFrameAnimator();
1265 // Add animator listener to asynchronous scene destroy for safe deletion.
1266 pFrameAnimator->AddFrameAnimatorEventListener(*this);
1267 _FrameAnimatorImpl* pFrameAnimatorImpl = _FrameAnimatorImpl::GetInstance(*pFrameAnimator);
1268 if (pFrameAnimatorImpl)
1270 pFrameAnimatorImpl->AddControl(form);
1274 SysLog(NID_UI_SCENES, "pFrameAnimator or pFrameAnimatorImpl is not valid.");
1276 pFrame->AddControl(form);
1281 _SceneManagerImpl::RemoveControlFromFrame(Form& form)
1283 Frame* pFrame = GetFrame();
1286 // Control validation check for safe operation on termination(Ui destroy before asynchronous scene destroy process).
1287 _ControlManager* pControlManager = _ControlManager::GetInstance();
1288 if (pControlManager)
1290 _Control* pControl = pControlManager->GetObject(__correspondFrameControlHandle);
1293 pFrame->RemoveControl(form);
1298 SysLog(NID_UI_SCENES, "FrameWindow already destroyed. Skip remove control to form.");
1303 SysLog(NID_UI_SCENES, "Window system already shutdown.");
1309 _SceneManagerImpl::SetCurrentForm(Form& form, bool useAnimator)
1311 result r = E_SUCCESS;
1312 Frame* pFrame = GetFrame();
1314 SysTryReturnResult(NID_UI_SCENES, pFrame != null, E_SYSTEM,
1315 "A system error has been occurred. Can not get the Frame window.");
1318 FrameAnimator* pFrameAnimator = pFrame->GetFrameAnimator();
1321 // Add animator listener to asynchronous scene destroy for safe deletion.
1322 pFrameAnimator->AddFrameAnimatorEventListener(*this);
1323 r = pFrameAnimator->SetCurrentForm(form);
1329 SysLog(NID_UI_SCENES, "Safety operation ongoing. Animation may not working, Please check the problems!");
1332 r = pFrame->SetCurrentForm(form);
1333 SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM, "A system error has been occurred. Can not set current form.");
1338 _SceneManagerImpl::GetCurrentForm(void)
1340 Frame* pFrame = GetFrame();
1343 return pFrame->GetCurrentForm();
1349 _SceneManagerImpl::AddControlToForm(Form& baseForm, const Panel& panel)
1351 baseForm.AddControl(panel);
1355 _SceneManagerImpl::RemoveControlFromForm(Form& baseForm, const Panel& panel)
1357 baseForm.RemoveControl(panel);
1361 _SceneManagerImpl::SetShowState(Panel& targetPanel, bool state)
1363 targetPanel.SetShowState(state);
1367 _SceneManagerImpl::DrawForm(Form& form)
1369 form.Invalidate(true);
1373 _SceneManagerImpl::CallListenerOnSceneTransitionStarted(const SceneId& currentSceneId, const SceneId& nextSceneId)
1375 std::unique_ptr<IEnumeratorT<ISceneManagerEventListener*> > pEnum(__sceneManagerEventListenerList.GetEnumeratorN());
1381 while (pEnum->MoveNext() == E_SUCCESS)
1383 ISceneManagerEventListener* pListener = null;
1384 pEnum->GetCurrent(pListener);
1387 pListener->OnSceneTransitionStarted(currentSceneId, nextSceneId);
1394 _SceneManagerImpl::CallListenerOnSceneTransitionCompleted(const SceneId& previousSceneId, const SceneId& currentSceneId)
1396 std::unique_ptr<IEnumeratorT<ISceneManagerEventListener*> > pEnum(__sceneManagerEventListenerList.GetEnumeratorN());
1402 while (pEnum->MoveNext() == E_SUCCESS)
1404 ISceneManagerEventListener* pListener = null;
1405 pEnum->GetCurrent(pListener);
1408 pListener->OnSceneTransitionCompleted(previousSceneId, currentSceneId);
1415 _SceneManagerImpl::CallListenerPrepareAnimation(Scene& scene, const SceneId& sceneId, IList* pArgs,
1416 SceneTransitionAnimationType type, bool formTransition)
1418 _SceneImpl* pSceneImpl = _SceneImpl::GetInstance(scene);
1419 SysTryReturn(NID_UI_SCENES, pSceneImpl, false, E_INVALID_STATE,
1420 "[%s] SceneManager is in an invalid state. scene is not valid.",
1421 GetErrorMessage(E_INVALID_STATE));
1423 return pSceneImpl->PrepareAnimation(sceneId, pArgs, type, formTransition);
1427 _SceneManagerImpl::CallListenerOnSceneActivatedN(Scene& scene, const SceneId& previousSceneId, const SceneId& currentSceneId,
1430 _SceneImpl* pSceneImpl = _SceneImpl::GetInstance(scene);
1431 SysTryReturn(NID_UI_SCENES, pSceneImpl, false, E_INVALID_STATE,
1432 "[%s] SceneManager is in an invalid state. scene is not valid.",
1433 GetErrorMessage(E_INVALID_STATE));
1435 return pSceneImpl->OnSceneActivatedN(previousSceneId, currentSceneId, pArgs);
1439 _SceneManagerImpl::CallListenerOnSceneDeactivated(Scene& scene, const SceneId& currentSceneId, const SceneId& nextSceneId)
1441 _SceneImpl* pSceneImpl = _SceneImpl::GetInstance(scene);
1442 SysTryReturn(NID_UI_SCENES, pSceneImpl, false, E_INVALID_STATE,
1443 "[%s] SceneManager is in an invalid state. scene is not valid.",
1444 GetErrorMessage(E_INVALID_STATE));
1446 return pSceneImpl->OnSceneDeactivated(currentSceneId, nextSceneId);
1450 _SceneManagerImpl::CallStretegyGetNextScene(const SceneId& currentSceneId, const IList* pArgs)
1452 SceneId nextScene(L"");
1453 if (__pPolicyProvider)
1455 nextScene = __pPolicyProvider->GetNextScene(currentSceneId, pArgs);
1461 _SceneManagerImpl::DestroySceneAsync(const SceneId& sceneId)
1463 _SceneControlEventArg* pArg = new (std::nothrow) _SceneControlEventArg(
1464 _SceneControlEventArg::SCENE_CONTROL_EVENT_TYPE_DESTROY, sceneId);
1465 SysTryReturnVoidResult(NID_UI_SCENES, pArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
1466 GetErrorMessage(E_OUT_OF_MEMORY));
1467 __sceneControlEvent.FireAsync(*pArg);
1471 _SceneManagerImpl::ReserveDestroyingScene(const SceneId& sceneId)
1473 if (!__destroyReservedScene.IsEmpty())
1475 SysLog(NID_UI_SCENES, "Previous reserved sceneId=%ls", __destroyReservedScene.GetPointer());
1477 __destroyReservedScene = sceneId;
1481 _SceneManagerImpl::DestroyReservedScene(void)
1483 if (!__destroyReservedScene.IsEmpty())
1485 DestroySceneAsync(__destroyReservedScene);
1486 __destroyReservedScene.Clear();
1491 _SceneManagerImpl::DestroySiblingPanelScene(const SceneId& sceneId)
1493 Scene* pScene = null;
1494 pScene = GetSceneFromContainer(sceneId);
1495 SysTryReturnVoidResult(NID_UI_SCENES, pScene != null, E_OBJ_NOT_FOUND, "[%s] Specified sceneId does not exist.",
1496 GetErrorMessage(E_OBJ_NOT_FOUND));
1498 Panel* pPanel = pScene->GetPanel();
1502 result r = __formToPanelMultiMap.GetCount(pScene->GetFormId(), panelCount);
1503 SysTryReturnVoidResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM,
1504 "[%s] A system error has been occurred. Form(SceneId:%ls) not valid.",
1505 GetErrorMessage(E_SYSTEM), sceneId.GetPointer());
1506 if (panelCount <= 1)
1511 ArrayListT<Scene*> destroyList;
1512 std::unique_ptr<IEnumeratorT<Scene*> > pSceneEnum(__formToPanelMultiMap.GetValuesN(pScene->GetFormId()));
1513 SysTryReturnVoidResult(NID_UI_SCENES, pSceneEnum != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
1514 GetErrorMessage(E_OUT_OF_MEMORY));
1515 while (pSceneEnum->MoveNext() == E_SUCCESS)
1517 Scene* pCurrentScene = null;
1518 pSceneEnum->GetCurrent(pCurrentScene);
1519 SysTryReturnVoidResult(NID_UI_SCENES, pCurrentScene != null, E_SYSTEM,
1520 "[%s] A system error has been occurred. Current scene is not valid.",
1521 GetErrorMessage(E_SYSTEM));
1522 if (pCurrentScene->GetPanel() != pPanel)
1524 destroyList.Add(pCurrentScene); // DestroyScene modify __formToPanelMultiMap so can't destroy here.
1528 for (int i = 0; i < destroyList.GetCount(); i++)
1530 Scene* pCurrentScene = null;
1531 destroyList.GetAt(i, pCurrentScene);
1534 DestroyScene(pCurrentScene->GetSceneId());
1541 _SceneManagerImpl::GetFrame(void)
1543 if (__pCorrespondFrame == null)
1545 SysLog(NID_UI_SCENES, "WARNING! - Initialize error!. First GetInstance must call after set a FrameWindow.");
1546 UiApp* pUiApp = UiApp::GetInstance();
1547 SysTryReturn(NID_UI_SCENES, pUiApp != null, null, E_SYSTEM,
1548 "[%s] A system error has been occurred. UiApp::GetInstance failed.", GetErrorMessage(E_SYSTEM));
1549 Frame* pFrame = pUiApp->GetFrameAt(0);
1550 SysTryReturn(NID_UI_SCENES, pFrame != null, null, E_SYSTEM,
1551 "[%s] A system error has been occurred. pUiApp->GetFrameAt(0) return null.", GetErrorMessage(E_SYSTEM));
1552 __pCorrespondFrame = pFrame;
1553 _ContainerImpl* pFrameWindowImpl = _ContainerImpl::GetInstance(*__pCorrespondFrame);
1554 if (pFrameWindowImpl)
1556 __correspondFrameControlHandle = pFrameWindowImpl->GetCore().GetHandle();
1559 return __pCorrespondFrame;
1563 _SceneManagerImpl::IsAnimationCompleted(void)
1565 Frame* pFrame = GetFrame();
1566 SysTryReturn(NID_UI_SCENES, pFrame != null, false, E_SYSTEM, "[%s] A system error has been occurred. Cannot get Frame.",
1567 GetErrorMessage(E_SYSTEM));
1568 FrameAnimator* pFrameAnimator = pFrame->GetFrameAnimator();
1572 bool completed = (pFrameAnimator->GetStatus() == ANIMATOR_STATUS_STOPPED) ? true : false;
1579 _SceneManagerImpl::GetSceneTransition(const SceneTransitionId& transitionId, SceneTransition& sceneTransition) const
1581 result r = E_SUCCESS;
1582 SysTryReturnResult(NID_UI_SCENES, !transitionId.IsEmpty(), E_INVALID_ARG,
1583 "Invalid argument is used. The transitionId is empty.");
1585 SceneTransition* pSceneTransition = null;
1586 r = __transitionMap.GetValue(transitionId, pSceneTransition);
1587 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
1588 sceneTransition = *pSceneTransition;
1594 _SceneManagerImpl::RegisterScene(xmlNodePtr pNode)
1596 static const char* pPropId = "Id";
1597 static const char* pPropFormId = "Form";
1598 static const char* pPropPanelId = "Panel";
1599 result r = E_SUCCESS;
1600 _SceneDescription* pSceneDescription = null;
1602 SysTryReturn(NID_UI_SCENES, pNode != null, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. pNode is null.",
1603 GetErrorMessage(E_INVALID_ARG));
1605 xmlChar* pSceneId = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropId));
1608 String strSceneId(reinterpret_cast<char*>(pSceneId));
1611 xmlChar* pFormId = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropFormId));
1614 String strFormId(reinterpret_cast<char*>(pFormId));
1618 xmlChar* pPanelId = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropPanelId));
1621 strPanelId = reinterpret_cast<char*>(pPanelId);
1625 // Register a Scene item
1626 bool isContains = false;
1627 r = __sceneMap.ContainsKey(strSceneId, isContains);
1628 SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
1629 SysTryReturnResult(NID_UI_SCENES, !isContains, E_OBJ_ALREADY_EXIST, "Specified sceneId already exist.");
1631 pSceneDescription = new (std::nothrow) _SceneDescription(strFormId, strPanelId);
1632 SysTryReturnResult(NID_UI_SCENES, pSceneDescription != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1634 r = __sceneMap.Add(strSceneId, pSceneDescription);
1635 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1641 delete pSceneDescription;
1646 _SceneManagerImpl::RegisterSceneTransition(xmlNodePtr pNode)
1648 static const xmlChar* pPropId = reinterpret_cast<const xmlChar*>("Id");
1649 static const char* pPropDestinationSceneId = "TargetId";
1650 static const char* pPropDirectionType = "DirectionType";
1651 static const char* pPropAnimationType = "AnimationType";
1652 static const char* pPropHistoryOption = "HistoryOption";
1653 static const char* pPropDestroyOption = "DestroyOption";
1655 static const String strValueDirectionForward(L"forward");
1656 static const String strValueDirectionBackward(L"backward");
1657 static const String strValueDirectionAdjacentBackward(L"adjacentBackward");
1658 static const String strValueAnimationType[] = {L"none", L"custom", L"left", L"right", L"fade_in_out",
1659 L"zoom_in", L"zoom_out", L"depth_in", "depth_out"};
1660 static const String strValueHistoryOptionNoHistory(L"no");
1661 static const String strValueDestroyOptionKeep(L"keep");
1662 static const String strValueDestroyOptionDestroy(L"destroy");
1664 static const SceneTransitionAnimationType valueAnimation[] = {
1665 SCENE_TRANSITION_ANIMATION_TYPE_NONE, SCENE_TRANSITION_ANIMATION_TYPE_CUSTOM,
1666 SCENE_TRANSITION_ANIMATION_TYPE_LEFT, SCENE_TRANSITION_ANIMATION_TYPE_RIGHT,
1667 SCENE_TRANSITION_ANIMATION_TYPE_FADE_IN_OUT, SCENE_TRANSITION_ANIMATION_TYPE_ZOOM_IN,
1668 SCENE_TRANSITION_ANIMATION_TYPE_ZOOM_OUT, SCENE_TRANSITION_ANIMATION_TYPE_DEPTH_IN,
1669 SCENE_TRANSITION_ANIMATION_TYPE_DEPTH_OUT };
1671 SceneTransition* pSceneTransition = null;
1672 result r = E_SUCCESS;
1673 SysTryReturn(NID_UI_SCENES, pNode != null, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. pNode is null.",
1674 GetErrorMessage(E_INVALID_ARG));
1676 xmlChar* pTransitionId = xmlGetProp(pNode, pPropId);
1679 String strTransitionId(reinterpret_cast<char*>(pTransitionId));
1680 xmlFree(pTransitionId);
1681 if (strTransitionId.GetLength() > 0)
1683 xmlChar* pDirectionType = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropDirectionType));
1686 String strDirectionType(reinterpret_cast<char*>(pDirectionType));
1687 xmlFree(pDirectionType);
1689 // Mandatory item: transitionId, direction
1690 // forward: destinationSceneId(mandatory), animationType, historyOption, destroyOption
1691 // backward: destinationSceneId(mandatory), animationType, destroyOption [ Don't care: historyOption ]
1692 // adjacentBackward: animationType, destroyOption [ Don't care: destinationSceneId, historyOption]
1693 String strDestinationSceneId;
1694 String strAnimationType;
1695 String strHistoryOption;
1696 String strDestroyOption;
1697 SceneTransitionAnimationType animationType = SCENE_TRANSITION_ANIMATION_TYPE_NONE;
1699 // Get animationType and destroyOption (common property)
1700 xmlChar* pAnimationType = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropAnimationType));
1703 strAnimationType = reinterpret_cast<char*>(pAnimationType);
1704 xmlFree(pAnimationType);
1705 if (strAnimationType.GetLength() > 0)
1707 for (unsigned int i = 0; i < sizeof(valueAnimation)/sizeof(valueAnimation[0]); i++)
1708 { // Consider to use map collection.
1709 if (strAnimationType == strValueAnimationType[i])
1711 animationType = valueAnimation[i];
1718 xmlChar* pDestroyOption = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropDestroyOption));
1721 strDestroyOption = reinterpret_cast<char*>(pDestroyOption);
1722 xmlFree(pDestroyOption);
1725 // Compose SceneTransition
1726 if (strDirectionType == strValueDirectionAdjacentBackward) // Adjacent backward
1728 SceneDestroyOption destroyOption = SCENE_DESTROY_OPTION_DESTROY; // Default is destroy
1729 if ((strDestroyOption.GetLength() > 0) && (strDestroyOption == strValueDestroyOptionKeep))
1731 destroyOption = SCENE_DESTROY_OPTION_KEEP;
1734 pSceneTransition = new (std::nothrow) BackwardSceneTransition(animationType, destroyOption);
1735 SysTryReturnResult(NID_UI_SCENES, pSceneTransition != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1736 r = __transitionMap.Add(strTransitionId, pSceneTransition);
1737 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1741 // Get destinationSceneId
1742 xmlChar* pDestinationSceneId = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropDestinationSceneId));
1743 if (pDestinationSceneId)
1745 strDestinationSceneId = reinterpret_cast<char*>(pDestinationSceneId);
1746 xmlFree(pDestinationSceneId);
1748 SysTryReturn(NID_UI_SCENES, strDestinationSceneId.GetLength() > 0, E_INVALID_ARG, E_INVALID_ARG,
1749 "[%s] Invalid argument is used. strDestinationSceneId is empty.", GetErrorMessage(E_INVALID_ARG));
1751 if (strDirectionType == strValueDirectionBackward) // Backward
1753 SceneDestroyOption destroyOption = SCENE_DESTROY_OPTION_DESTROY; // Default is destroy
1754 if ((strDestroyOption.GetLength() > 0) && (strDestroyOption == strValueDestroyOptionKeep))
1756 destroyOption = SCENE_DESTROY_OPTION_KEEP;
1760 new (std::nothrow) BackwardSceneTransition(strDestinationSceneId, animationType, destroyOption);
1761 SysTryReturnResult(NID_UI_SCENES, pSceneTransition != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1762 r = __transitionMap.Add(strTransitionId, pSceneTransition);
1763 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1767 if (strDirectionType == strValueDirectionForward) // Forward
1769 SceneDestroyOption destroyOption = SCENE_DESTROY_OPTION_KEEP; // Default is keep
1770 if ((strDestroyOption.GetLength() > 0) && (strDestroyOption == strValueDestroyOptionDestroy))
1772 destroyOption = SCENE_DESTROY_OPTION_DESTROY;
1775 xmlChar* pHistoryOption = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropHistoryOption));
1778 strHistoryOption = reinterpret_cast<char*>(pHistoryOption);
1779 xmlFree(pHistoryOption);
1781 SceneHistoryOption historyOption = SCENE_HISTORY_OPTION_ADD_HISTORY; // Default is add to history
1782 if ((strHistoryOption.GetLength() > 0) && (strHistoryOption == strValueHistoryOptionNoHistory))
1784 historyOption = SCENE_HISTORY_OPTION_NO_HISTORY;
1787 pSceneTransition = new (std::nothrow) ForwardSceneTransition(strDestinationSceneId, animationType,
1788 historyOption, destroyOption);
1789 SysTryReturnResult(NID_UI_SCENES, pSceneTransition != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1790 r = __transitionMap.Add(strTransitionId, pSceneTransition);
1791 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1796 SysLog(NID_UI_SCENES, "Unknown direction type!");
1804 delete pSceneTransition;
1808 } } } // Tizen::Ui::Scenes