TizenRefApp-8430 [Call UI] Add MainPage sceleton 96/126996/3
authorIgor Olshevskyi <i.olshevskyi@samsung.com>
Tue, 25 Apr 2017 11:29:09 +0000 (14:29 +0300)
committerIgor Olshevskyi <i.olshevskyi@samsung.com>
Mon, 15 May 2017 05:43:42 +0000 (08:43 +0300)
Change-Id: I6c315a21f41af1c3382ebf54d558380f2344d254

15 files changed:
inc/model/types.h
inc/presenters/Instance.h
inc/presenters/MainPage.h [new file with mode: 0644]
inc/presenters/Page.h [new file with mode: 0644]
inc/presenters/Page.hpp [new file with mode: 0644]
inc/presenters/types.h [new file with mode: 0644]
inc/resources.h [new file with mode: 0644]
inc/view/helpers.h [new file with mode: 0644]
res/edje/theme.edc [new file with mode: 0644]
src/presenters/Instance.cpp
src/presenters/MainPage.cpp [new file with mode: 0644]
src/presenters/Page.cpp [new file with mode: 0644]
src/presenters/common.h [new file with mode: 0644]
src/view/common.h [new file with mode: 0644]
src/view/helpers.cpp [new file with mode: 0644]

index c3dd7d28ef6508ba1f47360a14be71106880e3af..d4f9f694ac35239c4d93c8487b8c423ce985e5c7 100644 (file)
@@ -166,4 +166,4 @@ namespace callui {
        using RejectMsgList = std::vector<IRejectMsgSRef>;
 }
 
-#endif // __GALLERY_MODEL_TYPES_H__
+#endif // __CALLUI_MODEL_TYPES_H__
index b1e316f1cadb66564a5f7c2b78e756a702cb542e..4060d48c55d4e6e637971cec9200f3f2b71ea515 100644 (file)
 #ifndef __CALLUI_PRESENTERS_INSTANCE_H__
 #define __CALLUI_PRESENTERS_INSTANCE_H__
 
-#include "types.h"
-
 #include "ucl/appfw/IInstance.h"
 #include "ucl/appfw/IInstanceAppControlExt.h"
 
-#include "ucl/appfw/SysEventProvider.h"
+#include "ucl/gui/Theme.h"
+#include "ucl/gui/Naviframe.h"
 
-#include "model/ICall.h"
+#include "types.h"
 
 namespace callui {
 
@@ -33,11 +32,7 @@ namespace callui {
                        public ucl::IInstanceAppControlExt {
        public:
                Instance(ucl::SysEventProvider &sysEventProvider);
-
-               // For testing
-               ucl::WindowWRef getWindow();
-               ucl::IInstanceContext *getContext();
-               ICallWRef getCall();
+               virtual ~Instance();
 
                // IInstance //
 
@@ -51,14 +46,22 @@ namespace callui {
                virtual void onAppControl(app_control_h appControl) final override;
 
        private:
-               void onBack(Evas_Object *obj, void *event_info);
+               ucl::Result setupTheme();
+
                void onSysEvent(const ucl::SysEvent sysEvent);
+               void onPageExitRequest(Page &page);
 
        private:
                ucl::SysEventProvider &m_sysEventProvider;
                ucl::IInstanceContext *m_context;
-               ucl::WindowSRef m_win;
+
                ICallSRef m_call;
+
+               ucl::WindowSRef m_win;
+               ucl::NaviframeSRef m_navi;
+               ucl::Theme m_theme;
+
+               PageWRef m_page;
        };
 }
 
diff --git a/inc/presenters/MainPage.h b/inc/presenters/MainPage.h
new file mode 100644 (file)
index 0000000..fb16036
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CALLUI_PRESENTERS_MAIN_PAGE_H__
+#define __CALLUI_PRESENTERS_MAIN_PAGE_H__
+
+#include "Page.h"
+#include "model/ICallListener.h"
+
+#include "types.h"
+
+namespace callui {
+
+       class MainPage final :
+                       public Page,
+                       public ICallListener {
+       public:
+               class Builder {
+               public:
+                       Builder();
+                       ~Builder();
+                       Builder &setNaviframe(const ucl::NaviframeSRef &navi);
+                       Builder &setCall(const ICallSRef &call);
+                       MainPageSRef build(ExitRequestHandler onExitRequest) const;
+               private:
+                       ucl::NaviframeSRef m_navi;
+                       ICallSRef m_call;
+               };
+
+       private:
+               friend class ucl::RefCountObj<MainPage>;
+               MainPage(ucl::RefCountObjBase &rc, const ucl::NaviframeSRef &navi,
+                               ExitRequestHandler onExitRequest, const ICallSRef &call);
+               virtual ~MainPage();
+
+               ucl::Result prepare();
+
+               // Page
+
+               virtual void onBackKey() final override;
+
+               // ICallListener
+
+               virtual void onCallEvent(CallEventType type) final override;
+               virtual void onError(CallErr err) final override;
+
+       private:
+               ICallSRef m_call;
+       };
+}
+
+#endif // __CALLUI_PRESENTERS_MAIN_PAGE_H__
diff --git a/inc/presenters/Page.h b/inc/presenters/Page.h
new file mode 100644 (file)
index 0000000..bfe3ac2
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CALLUI_PRESENTERS_PAGE_H__
+#define __CALLUI_PRESENTERS_PAGE_H__
+
+#include "ucl/gui/Naviframe.h"
+
+#include "types.h"
+
+namespace callui {
+
+       class Page : public ucl::RefCountAware {
+       public:
+               using ExitRequestHandler = ucl::Delegate<void(Page &page)>;
+
+       public:
+               ucl::Naviframe &getNaviframe();
+
+               bool isActive() const;
+
+               bool isAtTop() const;
+               bool isAtBottom() const;
+
+               void exit();
+               void exitNoTransition();
+
+               void popTo();
+               void deleteTo();
+               void promote();
+
+               template <class ...ARGS>
+               ucl::NaviItem insertAfter(ARGS &&...args);
+
+               template <class ...ARGS>
+               ucl::NaviItem insertBefore(ARGS &&...args);
+
+       protected:
+               Page(ucl::RefCountObjBase &rc, const ucl::NaviframeSRef &navi,
+                               ExitRequestHandler onExitRequest);
+               virtual ~Page();
+
+               template <class ITEM_FACTORY>
+               ucl::Result prepare(ITEM_FACTORY &&makeItem);
+
+               ucl::NaviItem getItem();
+
+               void requestExit();
+
+               virtual void onActivate();
+               virtual void onDeactivate();
+               virtual void onBackKey();
+
+       private:
+               ucl::Result preparePart2();
+
+               void dispatchTopPageChanged();
+
+               void activate();
+               void deactivate();
+               void updateActiveState();
+
+               void onTransitionStarted(ucl::Widget &widget, void *eventInfo);
+               void onTransitionFinished(ucl::Widget &widget, void *eventInfo);
+               void onTopPageChanged(ucl::Widget &widget, void *eventInfo);
+
+               void onHWBackKey(Evas_Object *obj, void *eventInfo);
+               void onItemDel(Evas_Object *obj, void *eventInfo);
+
+       private:
+               const ucl::NaviframeSRef m_navi;
+               const ExitRequestHandler m_onExitRequest;
+               ucl::NaviItem m_item;
+               bool m_isActive;
+       };
+
+       // Non-member functions
+
+       bool isLast(const Page &page);
+}
+
+#include "Page.hpp"
+
+#endif // __CALLUI_PRESENTERS_PAGE_H__
diff --git a/inc/presenters/Page.hpp b/inc/presenters/Page.hpp
new file mode 100644 (file)
index 0000000..58e11c5
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ucl/util/logging.h"
+
+namespace callui {
+
+       template <class ITEM_FACTORY>
+       inline ucl::Result Page::prepare(ITEM_FACTORY &&makeItem)
+       {
+               m_item = makeItem();
+               if (!m_item) {
+                       UCL_LOG_RETURN(ucl::RES_FAIL, "m_item is NULL");
+               }
+               return preparePart2();
+       }
+
+       template <class ...ARGS>
+       inline ucl::NaviItem Page::insertAfter(ARGS &&...args)
+       {
+               return m_navi->insertAfter(m_item, std::forward<ARGS>(args)...);
+       }
+
+       template <class ...ARGS>
+       inline ucl::NaviItem Page::insertBefore(ARGS &&...args)
+       {
+               return m_navi->insertBefore(m_item, std::forward<ARGS>(args)...);
+       }
+
+       inline ucl::Naviframe &Page::getNaviframe()
+       {
+               UCL_ASSERT(m_navi, "m_navi is NULL");
+               return *m_navi;
+       }
+
+       inline bool Page::isActive() const
+       {
+               return m_isActive;
+       }
+
+       inline bool Page::isAtTop() const
+       {
+               return (m_navi->getTopItem() == m_item);
+       }
+
+       inline bool Page::isAtBottom() const
+       {
+               return (m_navi->getBottomItem() == m_item);
+       }
+
+       // Non-member functions
+
+       inline bool isLast(const Page &page)
+       {
+               return (page.isAtBottom() && page.isAtTop());
+       }
+}
diff --git a/inc/presenters/types.h b/inc/presenters/types.h
new file mode 100644 (file)
index 0000000..c7d19e3
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CALLUI_PRESENTERS_TYPES_H__
+#define __CALLUI_PRESENTERS_TYPES_H__
+
+#include "../types.h"
+
+#include "model/types.h"
+
+namespace callui {
+
+       UCL_DECLARE_REF_ALIASES(Page);
+
+       UCL_DECLARE_REF_ALIASES(MainPage);
+}
+
+#endif // __CALLUI_PRESENTERS_TYPES_H__
diff --git a/inc/resources.h b/inc/resources.h
new file mode 100644 (file)
index 0000000..b75cd57
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CALLUI_RESOURCES_H__
+#define __CALLUI_RESOURCES_H__
+
+#include "ucl/misc/TString.h"
+
+#include "config.h"
+
+namespace callui {
+
+       constexpr auto THEME_EDJE_PATH = "edje/theme.edj";
+}
+
+#endif // __CALLUI_RESOURCES_H__
diff --git a/inc/view/helpers.h b/inc/view/helpers.h
new file mode 100644 (file)
index 0000000..75ab4c8
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CALLUI_VIEW_HELPERS_H__
+#define __CALLUI_VIEW_HELPERS_H__
+
+#include <efl_extension.h>
+
+#include "types.h"
+
+namespace ucl {
+
+       class ElmWidget;
+       class Naviframe;
+}
+
+namespace callui {
+
+       ucl::Result createCircleSurface(ucl::Naviframe &navi);
+
+       Eext_Circle_Surface *getCircleSurface(const ucl::ElmWidget &widget);
+
+}
+
+#endif // __CALLUI_VIEW_HELPERS_H__
diff --git a/res/edje/theme.edc b/res/edje/theme.edc
new file mode 100644 (file)
index 0000000..84af942
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+collections {
+   base_scale: 1.3;
+
+   plugins {
+      plugin {
+         name: "touch_sound";
+         source: "feedback";
+         param: "FEEDBACK_TYPE_SOUND FEEDBACK_PATTERN_TAP";
+      }
+   }
+
+}
index 26a9ed0f3589846404c7af8bd962ba9b9018042e..4e3caaeb9d1bcdb80f4eef005bde1b20aad49386 100644 (file)
 #include "presenters/Instance.h"
 
 #include "ucl/util/memory.h"
+#include "ucl/appfw/SysEventProvider.h"
+#include "ucl/appfw/helpers.h"
 
 #include <system_settings.h>
-#include <efl_extension.h>
 
 #include "model/CallBuilder.h"
+#include "model/ICall.h"
 #include "model/ICallManager.h"
-#include "model/IIncomingCall.h"
-#include "model/IActiveCall.h"
-#include "model/IHeldCall.h"
-#include "model/IEndCall.h"
-#include "model/ICallInfo.h"
-#include "model/ICallListener.h"
+#include "presenters/MainPage.h"
 
-#include "../common.h"
+#include "resources.h"
+#include "common.h"
 
 namespace callui {
 
        using namespace ucl;
 
-       // For testing
-       UCL_DECLARE_REF_ALIASES(CallListener);
-       class CallListener : public ICallListener {
-       public:
-               static CallListenerSRef newInstance(Instance &instance)
-               {
-                       return makeShared<CallListener>(instance);
-               }
-
-               virtual void onCallEvent(CallEventType type) override final
-               {
-                       WindowWRef win = m_instance.getWindow();
-                       ICallWRef call = m_instance.getCall();
-                       ICallManagerSRef callMng = {};
-                       if (call) {
-                               callMng = call->getCallManager();
-                       }
-
-                       if (win && !win->isVisible()) {
-                               show(*win);
-                       }
-
-                       IIncomingCallWRef incom = callMng->getIncomingCall();
-                       IActiveCallWRef active = callMng->getActiveCall();
-                       IHeldCallWRef held = callMng->getHeldCall();
-                       IEndCallWRef end = callMng->getEndCall();
-
-                       ILOG(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
-                       if (incom) {
-                               ILOG("Incoming call available");
-                               logCallInfo(incom->getInfo());
-                       } else {
-                               ILOG("No incoming call");
-                       }
-
-                       if (active) {
-                               ILOG("Active call available");
-                               logCallInfo(active->getInfo());
-                       } else {
-                               ILOG("No active call");
-                       }
-
-                       if (held) {
-                               ILOG("Held call available");
-                               logCallInfo(held->getInfo());
-                       } else {
-                               ILOG("No held call");
-                       }
-
-                       if (end) {
-                               ILOG("End call available");
-                               logCallInfo(end->getInfo());
-                       } else {
-                               ILOG("No end call");
-                       }
-                       ILOG("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
-
-                       if (type == CallEventType::END) {
-                               if (!callMng->getIncomingCall()
-                                               && !callMng->getActiveCall()
-                                               && !callMng->getHeldCall()) {
-                                       IInstanceContext *ctx = m_instance.getContext();
-                                       if (ctx) {
-                                               ctx->exitApp();
-                                       }
-                               }
-                       }
-               }
-
-               virtual void onError(CallErr err) override final
-               {
-                       ILOG();
-               }
-
-       private:
-               friend class ucl::RefCountObj<CallListener>;
-               CallListener(Instance &instance):
-                       m_instance(instance)
-               {
-                       ILOG();
-               }
-
-               void logCallInfo(ICallInfoSCRef info)
-               {
-                       ILOG("* call id [%d]", info->getCallId());
-                       ILOG("* phone number [%s]", info->getPhoneNumber().c_str());
-                       ILOG("* conference member count [%d]", info->getConferenceMemberCount());
-               }
-
-       private:
-               Instance &m_instance;
-       };
-
        Instance::Instance(SysEventProvider &sysEventProvider) :
                m_sysEventProvider(sysEventProvider),
                m_context(nullptr)
        {
        }
 
+       Instance::~Instance()
+       {
+               if (m_page) {
+                       m_page->exitNoTransition();
+               }
+       }
+
        Result Instance::onCreate(IInstanceContext *const context)
        {
                m_context = context;
 
                m_win = m_context->getWindow();
 
-               m_sysEventProvider.addEventHandler(
-                               DELEGATE(Instance::onSysEvent, this));
-
-               eext_object_event_callback_add(*m_win, EEXT_CALLBACK_BACK,
-                               CALLBACK_A(Instance::onBack), this);
+               FAIL_RETURN(setupTheme(), "setupTheme() failed!");
 
-               // For testing
                m_call = CallBuilder().build();
                if (!m_call) {
                        LOG_RETURN(RES_FAIL, "m_call is NULL");
                }
 
-               static CallListenerSRef callListener =
-                               CallListener::newInstance(*this);
-               m_call->setListener(callListener);
+               m_navi = Naviframe::Builder().
+                               build(m_win->getConformant());
+               if (!m_navi) {
+                       LOG_RETURN(RES_FAIL, "Naviframe::build() failed!");
+               }
+
+               m_win->getConformant().setContent(*m_navi);
+
+               FAIL_RETURN(createCircleSurface(*m_navi),
+                               "createCircleSurface() failed!");
+
+               m_sysEventProvider.addEventHandler(
+                               DELEGATE(Instance::onSysEvent, this));
 
                return RES_OK;
        }
@@ -172,12 +89,19 @@ namespace callui {
 
        void Instance::onAppControl(app_control_h appControl)
        {
-               char *op = {};
-               app_control_get_operation(appControl, &op);
-               ILOG("operation: %s", op);
-               free(op);
+               if (!m_page) {
+                       auto page = MainPage::Builder().
+                                       setNaviframe(m_navi).
+                                       setCall(m_call).
+                                       build(DELEGATE(Instance::onPageExitRequest, this));
+                       if (!page) {
+                               ELOG("Create page failed! Exit application");
+                               m_context->exitApp();
+                       }
+                       m_call->setListener(page);
+                       m_page = page;
+               }
 
-               // For testing
                Result res = m_call->processAppControl(appControl);
                if (res != RES_OK) {
                        ELOG("processAppControl() failed!");
@@ -189,9 +113,22 @@ namespace callui {
                }
        }
 
-       void Instance::onBack(Evas_Object *obj, void *event_info)
+       Result Instance::setupTheme()
+       {
+               m_theme = Theme::create();
+               if (isNotValid(m_theme)) {
+                       LOG_RETURN(RES_FAIL, "Theme::create() failed!");
+               }
+
+               m_theme.addExtension(getResPath(THEME_EDJE_PATH));
+
+               m_win->setTheme(m_theme);
+
+               return RES_OK;
+       }
+
+       void Instance::onPageExitRequest(Page &page)
        {
-               ILOG("Exiting the application...");
                m_context->exitApp();
        }
 
@@ -214,19 +151,4 @@ namespace callui {
                }
        }
 
-       WindowWRef Instance::getWindow()
-       {
-               return m_win;
-       }
-
-       IInstanceContext *Instance::getContext()
-       {
-               return m_context;
-       }
-
-       ICallWRef Instance::getCall()
-       {
-               return m_call;
-       }
-
 }
diff --git a/src/presenters/MainPage.cpp b/src/presenters/MainPage.cpp
new file mode 100644 (file)
index 0000000..b904204
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ucl/gui/Window.h"
+#include "ucl/gui/Layout.h"
+
+#include "presenters/MainPage.h"
+
+#include "model/ICall.h"
+#include "model/ICallManager.h"
+#include "model/IIncomingCall.h"
+#include "model/IActiveCall.h"
+#include "model/IHeldCall.h"
+#include "model/IEndCall.h"
+
+#include "common.h"
+
+namespace callui {
+
+       using namespace ucl;
+
+       // MainPage::Builder
+
+       MainPage::Builder::Builder()
+       {
+       }
+
+       MainPage::Builder::~Builder()
+       {
+       }
+
+       MainPage::Builder &MainPage::Builder::setNaviframe(
+                       const NaviframeSRef &navi)
+       {
+               m_navi = navi;
+               return *this;
+       }
+
+       MainPage::Builder &MainPage::Builder::setCall(
+                       const ICallSRef &call)
+       {
+               m_call = call;
+               return *this;
+       }
+
+       MainPageSRef MainPage::Builder::build(
+                       const ExitRequestHandler onExitRequest) const
+       {
+               if (!onExitRequest) {
+                       LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {},
+                                       "onExitRequest is NULL");
+               }
+               if (!m_navi) {
+                       LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {},
+                                       "m_navi is NULL");
+               }
+               if (!m_call) {
+                       LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {},
+                                       "m_call is NULL");
+               }
+
+               auto result = makeShared<MainPage>(
+                               m_navi, onExitRequest, m_call);
+
+               FAIL_RETURN_VALUE(result->prepare(), {},
+                               "result->prepare() failed!");
+
+               return result;
+       }
+
+       // MainPage
+
+       MainPage::MainPage(RefCountObjBase &rc,
+                       const NaviframeSRef &navi,
+                       const ExitRequestHandler onExitRequest,
+                       const ICallSRef &call) :
+               Page(rc, navi, onExitRequest),
+               m_call(call)
+       {
+       }
+
+       MainPage::~MainPage()
+       {
+       }
+
+       Result MainPage::prepare()
+       {
+               // TODO: Temporary. Need to implement with real layout
+               return Page::prepare([this]() {
+                       return getNaviframe().
+                                       push(*Layout::Builder().
+                                                       build(getNaviframe()));
+               });
+       }
+
+       void MainPage::onBackKey()
+       {
+               if (m_call->getCallManager()->getAvailableCalls()
+                               == CALL_FLAG_END) {
+                       requestExit();
+               }
+       }
+
+       void MainPage::onCallEvent(CallEventType type)
+       {
+               auto win = getNaviframe().getWindow();
+               if (!win) {
+                       LOG_RETURN_VOID(RES_FAIL, "win is NULL");
+               }
+
+               if ((type == CallEventType::DIALING
+                               || type == CallEventType::INCOMING)
+                               && !win->isVisible()) {
+                       show(*win);
+               }
+
+               if (type == CallEventType::END) {
+                       if (m_call->getCallManager()->getAvailableCalls()
+                                       == CALL_FLAG_END) {
+                               requestExit();
+                       }
+               }
+       }
+
+       void MainPage::onError(CallErr err)
+       {
+               if (!m_call->getCallManager()->getAvailableCalls()) {
+                       requestExit();
+               }
+       }
+
+}
diff --git a/src/presenters/Page.cpp b/src/presenters/Page.cpp
new file mode 100644 (file)
index 0000000..19e8a9f
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "presenters/Page.h"
+
+#include "common.h"
+
+namespace callui { namespace { namespace impl {
+
+       using namespace ucl;
+
+       constexpr SmartEvent TOP_PAGE_CHANGED {"ucl,top,page,changed"};
+}}}
+
+namespace callui {
+
+       using namespace ucl;
+
+       Page::Page(RefCountObjBase &rc, const NaviframeSRef &navi,
+                       const ExitRequestHandler onExitRequest) :
+               RefCountAware(&rc),
+               m_navi(navi),
+               m_onExitRequest(onExitRequest),
+               m_isActive(false)
+       {
+               UCL_ASSERT(navi, "navi is NULL!");
+               UCL_ASSERT(onExitRequest, "onExitRequest is NULL!");
+       }
+
+       Page::~Page()
+       {
+       }
+
+       Result Page::preparePart2()
+       {
+               Evas_Object *content = m_item.getContent();
+               if (!content) {
+                       LOG_RETURN(RES_FAIL, "content is NULL");
+               }
+
+               m_navi->addEventHandler(NAVI_TRANSITION_STARTED,
+                               WEAK_DELEGATE(Page::onTransitionStarted, asWeak(*this)));
+
+               m_navi->addEventHandler(NAVI_TRANSITION_FINISHED,
+                               WEAK_DELEGATE(Page::onTransitionFinished, asWeak(*this)));
+
+               m_navi->addEventHandler(impl::TOP_PAGE_CHANGED,
+                               WEAK_DELEGATE(Page::onTopPageChanged, asWeak(*this)));
+
+               eext_object_event_callback_add(content, EEXT_CALLBACK_BACK,
+                               CALLBACK_A(Page::onHWBackKey), this);
+
+               m_item.setData(this);
+               m_item.setDelCallback(CALLBACK_A(Page::onItemDel));
+
+               m_rc->ref();
+
+               if (!m_navi->isInTransition() && isAtTop()) {
+                       dispatchTopPageChanged();
+               }
+
+               return RES_OK;
+       }
+
+       void Page::dispatchTopPageChanged()
+       {
+               m_navi->callEvent(impl::TOP_PAGE_CHANGED, nullptr);
+       }
+
+       void Page::onItemDel(Evas_Object *obj, void *eventInfo)
+       {
+               m_item = nullptr;
+               m_rc->unref();
+       }
+
+       void Page::exit()
+       {
+               if (isAtTop() && !isAtBottom()) {
+                       m_navi->pop();
+                       m_item = nullptr;
+               } else {
+                       exitNoTransition();
+               }
+       }
+
+       void Page::exitNoTransition()
+       {
+               if (isAtTop()) {
+                       m_item.del();
+                       dispatchTopPageChanged();
+               } else if (m_item) {
+                       m_item.del();
+               }
+       }
+
+       void Page::popTo()
+       {
+               if (m_item && !isAtTop()) {
+                       m_item.popTo();
+               }
+       }
+
+       void Page::deleteTo()
+       {
+               if (m_item && !isAtTop()) {
+                       while (!isAtTop()) {
+                               m_navi->getTopItem().del();
+                       }
+                       dispatchTopPageChanged();
+               }
+       }
+
+       void Page::promote()
+       {
+               if (m_item && !isAtTop()) {
+                       m_item.promote();
+               }
+       }
+
+       NaviItem Page::getItem()
+       {
+               return m_item;
+       }
+
+       void Page::requestExit()
+       {
+               m_onExitRequest(*this);
+       }
+
+       void Page::activate()
+       {
+               if (!m_isActive) {
+                       m_isActive = true;
+                       onActivate();
+               }
+       }
+
+       void Page::deactivate()
+       {
+               if (m_isActive) {
+                       m_isActive = false;
+                       onDeactivate();
+               }
+       }
+
+       void Page::updateActiveState()
+       {
+               if (isAtTop()) {
+                       activate();
+               } else {
+                       deactivate();
+               }
+       }
+
+       void Page::onTransitionStarted(Widget &widget, void *eventInfo)
+       {
+               deactivate();
+       }
+
+       void Page::onTransitionFinished(Widget &widget, void *eventInfo)
+       {
+               updateActiveState();
+       }
+
+       void Page::onTopPageChanged(Widget &widget, void *eventInfo)
+       {
+               updateActiveState();
+       }
+
+       void Page::onHWBackKey(Evas_Object *obj, void *eventInfo)
+       {
+               if (m_isActive) {
+                       onBackKey();
+               }
+       }
+
+       void Page::onActivate()
+       {
+       }
+
+       void Page::onDeactivate()
+       {
+       }
+
+       void Page::onBackKey()
+       {
+               requestExit();
+       }
+}
diff --git a/src/presenters/common.h b/src/presenters/common.h
new file mode 100644 (file)
index 0000000..2a17171
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CALLUI_PRESENTERS_COMMON_H__
+#define __CALLUI_PRESENTERS_COMMON_H__
+
+#include "ucl/gui/stdTheme.h"
+
+#include "view/helpers.h"
+
+#include "../common.h"
+
+#endif // __CALLUI_PRESENTERS_COMMON_H__
diff --git a/src/view/common.h b/src/view/common.h
new file mode 100644 (file)
index 0000000..50d4f33
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CALLUI_VIEW_COMMON_H__
+#define __CALLUI_VIEW_COMMON_H__
+
+#include "ucl/gui/stdTheme.h"
+#include "ucl/gui/helpers.h"
+
+#include "view/helpers.h"
+
+#include "../common.h"
+
+#endif // __CALLUI_VIEW_COMMON_H__
diff --git a/src/view/helpers.cpp b/src/view/helpers.cpp
new file mode 100644 (file)
index 0000000..9d1e0f7
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "view/helpers.h"
+
+#include "ucl/gui/Window.h"
+#include "ucl/gui/Naviframe.h"
+
+#include "common.h"
+
+namespace callui { namespace { namespace impl {
+
+       using namespace ucl;
+
+       constexpr EoDataKey CIRCLE_SURFACE {"callui,eext,circle,surface"};
+}}}
+
+namespace callui {
+
+       using namespace ucl;
+
+       Result createCircleSurface(Naviframe &navi)
+       {
+               const auto win = navi.getWindow();
+               if (!win) {
+                       LOG_RETURN(RES_FAIL, "Failed to get Window from Naviframe!");
+               }
+
+               if (win->getData(impl::CIRCLE_SURFACE)) {
+                       LOG_RETURN(RES_ILLEGAL_STATE, "Circle Surface data already set!");
+               }
+
+               const auto sfc = eext_circle_surface_naviframe_add(navi);
+               if (!sfc) {
+                       LOG_RETURN(RES_FAIL,
+                                       "eext_circle_surface_conformant_add() failed!");
+               }
+
+               win->setData(impl::CIRCLE_SURFACE, sfc);
+
+               return RES_OK;
+       }
+
+       Eext_Circle_Surface *getCircleSurface(const ElmWidget &widget)
+       {
+               const auto win = widget.getWindow();
+               if (!win) {
+                       LOG_RETURN_VALUE(RES_FAIL, nullptr,
+                                       "Failed to get Window from widget!");
+               }
+
+               const auto sfc = static_cast<Eext_Circle_Surface *>(
+                               win->getData(impl::CIRCLE_SURFACE));
+               if (!sfc) {
+                       LOG_RETURN_VALUE(RES_FAIL, nullptr,
+                                       "Failed to get Eext_Circle_Surface from window!");
+               }
+
+               return sfc;
+       }
+
+}
+