Refactored NavigatorPage lifetime. 85/61985/2
authorEugene Kurzberg <i.kurtsberg@samsung.com>
Fri, 11 Mar 2016 15:21:07 +0000 (17:21 +0200)
committerEugene Kurzberg <i.kurtsberg@samsung.com>
Mon, 14 Mar 2016 07:33:23 +0000 (09:33 +0200)
Implemented and integrated a more appropriate way to close the view.

Change-Id: Ic5d4f457aa131cb1ae5473a2afa0d2dc011276ea
Signed-off-by: Eugene Kurzberg <i.kurtsberg@samsung.com>
21 files changed:
lib-apps-common/inc/Ui/Naviframe.h
lib-apps-common/inc/Ui/NaviframePage.h
lib-apps-common/inc/Ui/Navigator.h
lib-apps-common/inc/Ui/NavigatorPage.h
lib-apps-common/inc/Ui/TabPage.h
lib-apps-common/inc/Ui/TabView.h
lib-apps-common/inc/Ui/View.h
lib-apps-common/src/Ui/Naviframe.cpp
lib-apps-common/src/Ui/NaviframePage.cpp
lib-apps-common/src/Ui/Navigator.cpp
lib-apps-common/src/Ui/NavigatorPage.cpp
lib-apps-common/src/Ui/TabPage.cpp
lib-apps-common/src/Ui/TabView.cpp
lib-apps-common/src/Ui/View.cpp
lib-common/src/Contacts/SelectView.cpp
lib-contact/inc/Contacts/Details/BasicInfoItem.h
lib-contact/src/Contacts/Common/Chooser.cpp
lib-contact/src/Contacts/Details/BasicInfoItem.cpp
lib-contact/src/Contacts/Details/DetailsView.cpp
lib-contact/src/Contacts/Input/InputView.cpp
lib-logs/src/Logs/Details/DetailsView.cpp

index 1618c9d..a452827 100644 (file)
@@ -40,6 +40,7 @@ namespace Ui
                virtual Evas_Object *onCreate(Evas_Object *parent) override;
                virtual NaviframePage *attachView(View *view) override;
                virtual void navigateToPage(NavigatorPage *page) override;
+               virtual void navigateFromPage(NavigatorPage *page) override;
 
                Eina_Bool onItemPop(Elm_Object_Item *item);
                void onTransition(Evas_Object *obj, void *eventInfo);
index 5217d0b..1c54f0b 100644 (file)
@@ -26,7 +26,6 @@ namespace Ui
        {
        public:
                NaviframePage(Elm_Object_Item *naviItem);
-               virtual ~NaviframePage() override;
 
                /**
                 * @see NavigatorPage::setTitle()
@@ -46,6 +45,8 @@ namespace Ui
        private:
                friend class Naviframe;
 
+               void onDestroy(Evas_Object *obj, void *eventInfo);
+
                Elm_Object_Item *m_NaviItem;
        };
 }
index 19d0517..905a326 100644 (file)
@@ -19,6 +19,7 @@
 #define UI_NAVIGATOR_H
 
 #include "Ui/View.h"
+#include <functional>
 
 namespace Ui
 {
@@ -46,6 +47,13 @@ namespace Ui
                 */
                void navigateTo(View *view);
 
+               /**
+                * @brief Navigate away from the view and destroy it.
+                * @param[in]   view    View to navigate from
+                * @return Whether navigation occurred.
+                */
+               bool navigateFrom(View *view);
+
        protected:
                Navigator(NavigatorType type);
 
@@ -70,6 +78,12 @@ namespace Ui
                virtual void navigateToPage(NavigatorPage *page) = 0;
 
                /**
+                * @brief Called after navigateFrom() is called
+                * @param[in]   page    Page to navigate from
+                */
+               virtual void navigateFromPage(NavigatorPage *page) = 0;
+
+               /**
                 * @see View::onNavigation()
                 */
                virtual void onNavigation(bool isCurrent) override;
index eb19b5f..48ddf5a 100644 (file)
@@ -63,6 +63,11 @@ namespace Ui
                 */
                virtual void setContent(const char *part, Evas_Object *content) = 0;
 
+               /**
+                * @brief Close the page and destroy its content.
+                */
+               void close();
+
        private:
                friend class Navigator;
                void onNavigatorAttached(Navigator *navigator, View *view);
index aa226d5..80f392e 100644 (file)
@@ -48,6 +48,7 @@ namespace Ui
                friend class TabView;
                virtual Evas_Object *onCreate(Evas_Object *parent) override;
                void onTabAttached(Elm_Object_Item *tabItem);
+               void onTabDestroy(Evas_Object *obj, void *eventInfo);
 
                size_t m_Index;
                Elm_Object_Item *m_TabItem;
index 006add2..bd82347 100644 (file)
@@ -43,9 +43,9 @@ namespace Ui
 
                virtual TabPage *attachView(View *view) override;
                virtual void navigateToPage(NavigatorPage *page) override;
+               virtual void navigateFromPage(NavigatorPage *page) override;
 
        private:
-               static void onTabDestroy(void *data, Evas_Object *obj, void *tabItem);
                void onTabSelected(Evas_Object *obj, Elm_Object_Item *selectedItem);
                void onPageChanged(Evas_Object *obj, void *eventInfo);
                void onResize(Evas *e, Evas_Object *obj, void *eventInfo);
index 48fa25b..14dcef8 100644 (file)
@@ -42,7 +42,6 @@ namespace Ui
        {
        public:
                View();
-               virtual ~View() override;
 
                /**
                 * @brief Get parent Navigator
index 69b25f7..15a4de0 100644 (file)
@@ -62,6 +62,15 @@ void Naviframe::navigateToPage(NavigatorPage *page)
                elm_naviframe_item_pop_to(naviItem);
        }
 }
+void Naviframe::navigateFromPage(NavigatorPage *page)
+{
+       Elm_Object_Item *naviItem = static_cast<NaviframePage *>(page)->m_NaviItem;
+       if (naviItem == elm_naviframe_top_item_get(getEvasObject())) {
+               elm_naviframe_item_pop(getEvasObject());
+       } else {
+               elm_object_item_del(naviItem);
+       }
+}
 
 Eina_Bool Naviframe::onItemPop(Elm_Object_Item *item)
 {
@@ -81,9 +90,8 @@ bool Naviframe::onBackPressed()
                return false;
        }
 
-       if (elm_naviframe_top_item_get(getEvasObject())
-                       != elm_naviframe_bottom_item_get(getEvasObject())) {
-               elm_naviframe_item_pop(getEvasObject());
+       NaviframePage *page = getCurrentPage();
+       if (page && navigateFrom(page->getView())) {
                return false;
        }
 
index 6840795..18e4b8d 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include "Ui/NaviframePage.h"
+#include "Utils/Callback.h"
 
 using namespace Ui;
 
@@ -23,17 +24,7 @@ NaviframePage::NaviframePage(Elm_Object_Item *naviItem)
        : m_NaviItem(naviItem)
 {
        elm_object_item_data_set(m_NaviItem, this);
-}
-
-NaviframePage::~NaviframePage()
-{
-       elm_object_item_part_content_unset(m_NaviItem, "elm.swallow.content");
-       Evas_Object *navi = elm_object_item_widget_get(m_NaviItem);
-       if (m_NaviItem == elm_naviframe_top_item_get(navi)) {
-               elm_naviframe_item_pop(navi);
-       } else {
-               elm_object_item_del(m_NaviItem);
-       }
+       elm_object_item_del_cb_set(m_NaviItem, makeCallback(&NaviframePage::onDestroy));
 }
 
 void NaviframePage::setTitle(const char *title)
@@ -52,3 +43,8 @@ void NaviframePage::setContent(const char *part, Evas_Object *content)
 {
        elm_object_item_part_content_set(m_NaviItem, part, content);
 }
+
+void NaviframePage::onDestroy(Evas_Object *obj, void *eventInfo)
+{
+       delete this;
+}
index 1a3452a..38d43e6 100644 (file)
@@ -60,6 +60,26 @@ void Navigator::navigateTo(View *view)
        navigateToPage(page);
 }
 
+bool Navigator::navigateFrom(View *view)
+{
+       if (!view || view->getNavigator(m_Type) != this) {
+               return false;
+       }
+
+       if (getPageCount() == 1) {
+               NavigatorPage *page = getPage();
+               if (page) {
+                       page->close();
+                       return true;
+               }
+
+               return false;
+       }
+
+       navigateFromPage(view->getPage());
+       return true;
+}
+
 void Navigator::notifyNavigation(NavigatorPage *page, bool isCurrent)
 {
        if (page) {
index d8ff1ba..4423b93 100644 (file)
@@ -42,6 +42,11 @@ View *NavigatorPage::getView() const
        return m_View;
 }
 
+void NavigatorPage::close()
+{
+       m_Navigator->navigateFrom(m_View);
+}
+
 void NavigatorPage::onNavigatorAttached(Navigator *navigator, View *view)
 {
        m_Navigator = navigator;
index 40e9389..4a06e83 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include "Ui/TabPage.h"
+#include "Utils/Callback.h"
 
 #define BUFFER_SIZE 64
 
@@ -28,7 +29,6 @@ TabPage::TabPage(size_t index)
 
 TabPage::~TabPage()
 {
-       elm_object_part_content_unset(m_Page, "elm.swallow.content");
        elm_object_item_del(m_TabItem);
 }
 
@@ -73,4 +73,10 @@ void TabPage::setContent(const char *part, Evas_Object *content)
 void TabPage::onTabAttached(Elm_Object_Item *tabItem)
 {
        m_TabItem = tabItem;
+       elm_object_item_del_cb_set(m_TabItem, makeCallback(&TabPage::onTabDestroy));
+}
+
+void TabPage::onTabDestroy(Evas_Object *obj, void *eventInfo)
+{
+       m_TabItem = nullptr;
 }
index 4c071a8..83f8610 100644 (file)
@@ -61,7 +61,6 @@ void TabView::onPageAttached(NavigatorPage *page)
        elm_toolbar_shrink_mode_set(m_Tabbar, ELM_TOOLBAR_SHRINK_EXPAND);
        elm_toolbar_select_mode_set(m_Tabbar, ELM_OBJECT_SELECT_MODE_ALWAYS);
        elm_toolbar_transverse_expanded_set(m_Tabbar, EINA_TRUE);
-       evas_object_smart_data_set(m_Tabbar, this);
        evas_object_smart_callback_add(m_Tabbar, "selected",
                        (Evas_Smart_Cb) makeCallback(&TabView::onTabSelected), this);
 
@@ -75,7 +74,6 @@ TabPage *TabView::attachView(View *view)
        m_Pages.push_back(page);
 
        Elm_Object_Item *item = elm_toolbar_item_append(m_Tabbar, nullptr, nullptr, nullptr, page);
-       elm_object_item_del_cb_set(item, &TabView::onTabDestroy);
        page->onTabAttached(item);
 
        Evas_Object *layout = page->create(getEvasObject());
@@ -101,17 +99,16 @@ void TabView::navigateToPage(NavigatorPage *page)
        notifyNavigation(tabPage, true);
 }
 
-void TabView::onTabDestroy(void *data, Evas_Object *obj, void *tabItem)
+void TabView::navigateFromPage(NavigatorPage *page)
 {
-       TabView *tabView = (TabView *) evas_object_smart_data_get(obj);
-       TabPage *page = (TabPage *) data;
+       size_t index = static_cast<TabPage *>(page)->m_Index;
+       m_Pages.erase(m_Pages.begin() + index);
 
-       size_t index = page->m_Index;
-       tabView->m_Pages.erase(tabView->m_Pages.begin() + index);
-
-       for (; index < tabView->m_Pages.size(); ++index) {
-               --(tabView->m_Pages[index]->m_Index);
+       for (; index < m_Pages.size(); ++index) {
+               --(m_Pages[index]->m_Index);
        }
+
+       delete page;
 }
 
 void TabView::onTabSelected(Evas_Object *obj, Elm_Object_Item *selectedItem)
index 6f70160..9b16ece 100644 (file)
@@ -24,11 +24,6 @@ View::View()
 {
 }
 
-View::~View()
-{
-       delete m_Page;
-}
-
 Navigator *View::getNavigator(NavigatorType type) const
 {
        return type == StackNavigator ? m_StackNavi : m_TabNavi;
@@ -44,10 +39,10 @@ void View::onNavigatorAttached(Navigator *stackNavi, Navigator *tabNavi, Navigat
        m_StackNavi = stackNavi;
        m_TabNavi = tabNavi;
 
-       if (page != m_Page) {
-               delete m_Page;
-               m_Page = page;
+       if (m_Page) {
+               m_Page->close();
        }
 
+       m_Page = page;
        onPageAttached(m_Page);
 }
index 13cc9f2..92b5301 100644 (file)
@@ -275,7 +275,7 @@ void SelectView::onItemSelected(SelectItem *item)
                {
                        SelectResult result = item->getSelectResult();
                        if (m_OnSelected && m_OnSelected({ &result, 1 })) {
-                               delete this;
+                               getPage()->close();
                        }
                }
                        break;
@@ -319,11 +319,11 @@ void SelectView::onDonePressed(Evas_Object *button, void *eventInfo)
        }
 
        if (m_OnSelected && m_OnSelected({ results.data(), results.size()})) {
-               delete this;
+               getPage()->close();
        }
 }
 
 void SelectView::onCancelPressed(Evas_Object *button, void *eventInfo)
 {
-       delete this;
+       getPage()->close();
 }
index e198195..bd3c821 100644 (file)
@@ -46,6 +46,11 @@ namespace Contacts
                {
                public:
                        /**
+                        * @brief Back button pressed callback
+                        */
+                       typedef std::function<void()> BackCallback;
+
+                       /**
                         * @brief Create basic info item.
                         * @param[in]   contact    Contact to display
                         */
@@ -57,6 +62,12 @@ namespace Contacts
                         */
                        void setSelectMode(SelectMode mode);
 
+                       /**
+                        * @brief Set "back" button callback.
+                        * @param[in]   callback    "back" button callback
+                        */
+                       void setBackCallback(BackCallback callback);
+
                protected:
                        /**
                         * @see GenlistItem::getItemClass()
@@ -101,6 +112,7 @@ namespace Contacts
                        Model::ContactTextField &m_JobTitle;
 
                        SelectMode m_SelectMode;
+                       BackCallback m_OnBackPressed;
                };
        }
 }
index 136629b..319d752 100644 (file)
@@ -110,7 +110,7 @@ bool Chooser::onMultiPersonSelected(SelectResults personResults)
 bool Chooser::onSelected(SelectResults results)
 {
        if (!m_OnSelected || m_OnSelected(results)) {
-               delete this;
+               getPage()->close();
        }
 
        return false;
index 1357056..f3120d1 100644 (file)
@@ -57,6 +57,11 @@ void BasicInfoItem::setSelectMode(SelectMode mode)
        elm_genlist_item_fields_update(getObjectItem(), PART_FAV_BTN, ELM_GENLIST_ITEM_FIELD_CONTENT);
 }
 
+void BasicInfoItem::setBackCallback(BackCallback callback)
+{
+       m_OnBackPressed = std::move(callback);
+}
+
 Elm_Genlist_Item_Class *BasicInfoItem::getItemClass() const
 {
        static Elm_Genlist_Item_Class itc = createItemClass(CONTACTS_DETAILS_ITEM_STYLE);
@@ -147,8 +152,9 @@ Evas_Object *BasicInfoItem::createFavButton(Evas_Object *parent)
 
 void BasicInfoItem::onBackPressed(Evas_Object *button, void *eventInfo)
 {
-       /* FIXME: Add possibility to get View or Navigator from child control */
-       delete getParent();
+       if (m_OnBackPressed) {
+               m_OnBackPressed();
+       }
 }
 
 void BasicInfoItem::onFavChanged(Evas_Object *check, void *eventInfo)
@@ -160,7 +166,10 @@ void BasicInfoItem::onFavChanged(Evas_Object *check, void *eventInfo)
 void BasicInfoItem::onFieldUpdated(ContactField &field, contacts_changed_e change)
 {
        if (&field == &m_Contact && change == CONTACTS_CHANGE_DELETED) {
-               delete getParent();
+               /* FIXME: Add possibility to get View from child control */
+               if (m_OnBackPressed) {
+                       m_OnBackPressed();
+               }
                return;
        }
 
index 067b177..5592dae 100644 (file)
@@ -86,6 +86,9 @@ void DetailsView::onCreated()
 
        m_BasicInfoItem = new BasicInfoItem(m_Contact);
        m_BasicInfoItem->setSelectMode(getSelectMode());
+       m_BasicInfoItem->setBackCallback([this] {
+               getPage()->close();
+       });
        m_Genlist->insert(m_BasicInfoItem);
 
        for (auto &&field : m_Contact) {
@@ -138,7 +141,7 @@ void DetailsView::onMenuPressed()
                popup->addButton("IDS_PB_BUTTON_CANCEL");
                popup->addButton("IDS_PB_BUTTON_DELETE_ABB4", [this] {
                        m_Contact.remove();
-                       delete this;
+                       getPage()->close();
                        return true;
                });
        });
index 9593f66..81387c7 100644 (file)
@@ -296,13 +296,13 @@ void InputView::onDonePressed(Evas_Object *button, void *eventInfo)
                m_OnResult(id);
        }
 
-       delete this;
+       getPage()->close();
 }
 
 void InputView::onCancelPressed(Evas_Object *button, void *eventInfo)
 {
        if (onCancel()) {
-               delete this;
+               getPage()->close();
        }
 }
 
@@ -319,7 +319,7 @@ bool InputView::onCancel()
 
        popup->addButton("IDS_PB_BUTTON_CANCEL");
        popup->addButton("IDS_PB_BUTTON_DISCARD_ABB", [this] {
-               delete this;
+               getPage()->close();
                return true;
        });
 
index 9f90566..a2030d6 100644 (file)
@@ -103,7 +103,7 @@ void DetailsView::insertBasicInfoItem()
 {
        m_BasicInfoItem = new BasicInfoItem(m_Group);
        m_BasicInfoItem->setBackCallback([this] {
-               delete this;
+               getPage()->close();
        });
        m_Genlist->insert(m_BasicInfoItem, nullptr, nullptr, Ui::Genlist::After);
 }