+ basic view transition bahavior. 69/61969/3
authorHermet Park <hermet@hermet.pe.kr>
Fri, 11 Mar 2016 14:08:01 +0000 (23:08 +0900)
committerHermet Park <chuneon.park@samsung.com>
Fri, 11 Mar 2016 14:10:45 +0000 (06:10 -0800)
Change-Id: I8a1a320a1f78be5b12934754af78bce66ad2c60a

data/edc/ui-viewmgr.edc
src/include/efl/ui_viewmgr.h
src/include/interface/ui_iface_view.h
src/lib/efl/mobile/ui_basic_view.cpp
src/lib/efl/ui_viewmgr.cpp
src/lib/interface/ui_iface_view.cpp
src/lib/interface/ui_iface_viewmgr.cpp

index 793e2c6..64dd08b 100644 (file)
@@ -23,6 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 #define TIZEN_VIEW_BG_PORTRAIT_HEIGHT_INC 1280
 #define TIZEN_VIEW_BG_LANDSPACPE_HEIGHT_INC 720
 #define TIZEN_VIEW_TITLE_HEIGHT_INC 110
@@ -49,6 +50,7 @@
 #define TIZEN_VIEW_TOOLBAR_TITLE_CLIPPER_HEIGHT_INC 80
 #define TIZEN_VIEW_TOOLBAR_LIGHT_VIEW_HEIGHT_INC 86
 #define TIZEN_VIEW_TOOLBAR_TOP_DIVIDER_HEIGHT_INC 0
+#define TRANSITION_TIME 0.25
 
 collections {
    base_scale: 2.6;
@@ -69,7 +71,7 @@ collections {
          tag:  "tab" "\t";
       }
    }
-   group { "elm/layout/tizen_view/default";
+   group { "tizen_view/default";
       images {
          image: "images/core_theme_bg_01.png" COMP;
          image: "images/core_icon_badge_container.#.png" COMP;
@@ -1086,4 +1088,84 @@ collections {
          }
       }
    }
+   /* Sliding Effect */
+   group { "transition/default";
+      alias: "transition/slide";
+      parts {
+         swallow { "pcontent";
+            desc { "default";
+            }
+            desc {"pushed";
+               rel1.relative: -1.0 0.0;
+               rel2.relative: 0.0 1.0;
+            }
+            desc {"popped";
+               rel1.relative: 1.0 0.0;
+               rel2.relative: 2.0 1.0;
+            }
+         }
+         swallow { "content";
+            desc { "default";
+            }
+            desc { "push_ready";
+               rel1.relative: 1.0 0.0;
+               rel2.relative: 2.0 1.0;
+            }
+            desc { "pop_ready";
+               rel1.relative: -1.0 0.0;
+               rel2.relative: 0.0 1.0;
+            }
+         }
+      }
+      programs {
+         program { "push_finished";
+            action: SIGNAL_EMIT "push,finished" "viewmgr";
+         }
+         program { "push_pcontent";
+            action: STATE_SET "pushed";
+            target: "pcontent";
+            transition: DECELERATE TRANSITION_TIME;
+            after: "push_finished";
+         }
+         program { "push_content";
+            action: STATE_SET "default";
+            target: "content";
+            transition: DECELERATE TRANSITION_TIME;
+         }
+         program { "push";
+            signal: "view,push";
+            source: "viewmgr";
+            script {
+               set_state(PART:"pcontent", "default", 0.0);
+               set_state(PART:"content", "push_ready", 0.0);
+               run_program(PROGRAM:"push_pcontent");
+               run_program(PROGRAM:"push_content");
+            }
+         }
+         program { "pop_finished";
+            action: SIGNAL_EMIT "pop,finished" "viewmgr";
+         }
+         program { "pop_pcontent";
+            action: STATE_SET "popped";
+            target: "pcontent";
+            transition: DECELERATE TRANSITION_TIME;
+            after: "pop_finished";
+         }
+         program { "pop_content";
+            action: STATE_SET "default";
+            target: "content";
+            transition: DECELERATE TRANSITION_TIME;
+         }
+         program { "pop";
+            signal: "view,pop";
+            source: "viewmgr";
+            script {
+               set_state(PART:"pcontent", "default", 0.0);
+               set_state(PART:"content", "pop_ready", 0.0);
+               run_program(PROGRAM:"pop_pcontent");
+               run_program(PROGRAM:"pop_content");
+            }
+         }
+      }
+   }
 }
index 9477f92..6ade0d2 100644 (file)
@@ -47,6 +47,9 @@ private:
        Evas_Object *layout;             //Viewmgr's base layout.
        ui_key_listener *key_listener;   //HW Key Handler such as "BACK" key...
        ui_view_indicator indicator;     //Mode of indicator.
+       string transition_style;         //Current transiton effect style name
+
+       Evas_Object *set_transition_layout(string transition_style);
 
        /**
         *  @brief Create a conformant.
@@ -169,6 +172,22 @@ public:
        /** @brief Get a last view of current view stack.
         */
        ui_view *get_last_view();
+
+       /**
+        *  @brief Return a view which is matched with the index @p idx.
+        *
+        *  @param idx A index of the view which you are looking for.
+        *
+        *  @return The view which index is matched with @p idx.
+        *          If there were no views with index @p idx, @c NULL will be returned.
+        *
+        *  @note You could use the index as the page numbers of the views.
+        *  @warning the index number of views are variable since the view list is variable.
+        *
+        *  @see get_view_index()
+        *  @see get_view_count()
+        */
+       ui_view *get_view(unsigned int idx);
 };
 }
 
index 597ce37..62f5b92 100644 (file)
@@ -59,10 +59,10 @@ private:
        };
 
        T content;                              ///< A content instance for a screen as a view.
-       ui_iface_controller *controller;    ///< View life-cycle controller interface.
+       ui_iface_controller *controller;        ///< View life-cycle controller interface.
        string name;                            ///< View name.
-       string style;                           ///< View style name.
-       ui_iface_viewmgr *viewmgr;          ///< Viewmgr which this view belongs to.
+       string transition_style;                ///< View transition style name.
+       ui_iface_viewmgr *viewmgr;              ///< Viewmgr which this view belongs to.
        ui_view_state state;                    ///< View state.
        ui_view_indicator indicator;            ///< View indicator mode.
        bool event_block;                       ///< State of event block.
@@ -205,19 +205,20 @@ public:
         */
        T set_content(T content);
 
-       /** @brief set style of the view.
+       /** @brief set transition style of a view.
         *
-        *  @note style is reserved for supporting various kinds of view as well as it's transition effects.
-        *        The actual behaviors with this style is up to your frameworks. Default value of the style is NULL.
+        *  @note @p style is reserved for supporting various kinds of view transition effects.
+        *        The actual behaviors with this transition style is up to your frameworks. Default value of the style is NULL.
+        *        and "none" represents none transition. If you don't like give any transition effects to this view, you can pass "none" as @p style.
         *
-        *  @param style a new style name.
+        *  @param style a transition style name.
         *
         *  @return true if the given @c style is available, otherwise false.
         *
         *  @warning When you override this member function, you should implement the logic to check the given style name is available or not.
         *           If your framework doesn't support any styles then just allow a @c NULL argument and return true. Otherwise return false.
         */
-       bool set_style(const char *style);
+       bool set_transition_style(const char *style);
 
        /** @brief set name of the view.
         *
@@ -249,9 +250,9 @@ public:
         *
         *  @return style name of view.
         */
-       const char *get_style()
+       const char *get_transition_style()
        {
-               return this->style.c_str();
+               return this->transition_style.c_str();
        }
 
        /** @brief Return a name of this view.
@@ -281,7 +282,6 @@ public:
                return this->state;
        }
 
-
        /** @brief Return a state of removeable content.
         *
         *  @return true if the view's content is removable, otherwise false.
index f7f68d0..3d8f93b 100644 (file)
 #include "../../../include/efl/mobile/ui_viewmanager_mobile.h"
 
 //FIXME: is it correct to define here?
-//#define EDJ_PATH "/opt/usr/apps/org.tizen.ui-viewmgr/res/ui-viewmgr.edj"
 #define EDJ_PATH "/usr/share/edje/ui-viewmgr/ui-viewmgr.edj"
-#define GROUP "elm/layout/tizen_view/default"
-#define TOOLBAR "elm/layout/tizen_view/toolbar"
+#define GROUP "tizen_view/default"
 
 using namespace efl_viewmgr;
 using namespace viewmgr;
@@ -228,7 +226,6 @@ bool ui_basic_view::set_toolbar(Evas_Object *toolbar)
 
        if (layout)
        {
-
                if ((!strcmp(elm_object_style_get(toolbar), "toolbar_with_title")) &&
                    ((elm_toolbar_shrink_mode_get(toolbar) != ELM_TOOLBAR_SHRINK_EXPAND)))
                {
index 3667607..53a61ff 100644 (file)
 using namespace efl_viewmgr;
 using namespace viewmgr;
 
+//FIXME: is it correct to define here?
+#define EDJ_PATH "/usr/share/edje/ui-viewmgr/ui-viewmgr.edj"
+
+Evas_Object *ui_viewmgr::set_transition_layout(string transition_style)
+{
+       elm_object_part_content_unset(this->get_base(), "pcontent");
+       elm_object_part_content_unset(this->get_base(), "content");
+
+       if (transition_style == this->transition_style) return this->layout;
+
+       //FIXME: 1. Find current style effect layout
+       Evas_Object *effect = this->get_base();
+
+       //2. Switch effect layout to base layout
+       elm_object_part_content_unset(this->get_conformant(), "elm.swallow.content");
+       elm_object_part_content_set(this->get_conformant(), "elm.swallow.content", effect);
+
+       this->layout = effect;
+       this->transition_style = transition_style;
+
+       return this->layout;
+}
+
 void ui_viewmgr::active_top_view()
 {
-       elm_object_part_content_unset(this->get_base(), "elm.swallow.content");
+       elm_object_part_content_unset(this->get_base(), "content");
 
-       ui_view *view = dynamic_cast<ui_view *>(this->get_last_view());
+       ui_view *view = this->get_last_view();
 
-       //TODO: get parent?
-       Evas_Object *content = view->get_base();
-       if (content == this->get_base())
+       //In case of ui_view, it doesn't have any base form. It uses viewmgr base instead.
+       Evas_Object *content;
+       if (view->get_base() == this->get_base())
        {
-               elm_object_part_content_set(this->get_base(), "elm.swallow.content", CONVERT_TO_EO(view->get_content()));
+               content = CONVERT_TO_EO(view->get_content());
        }
        else
        {
-               elm_object_part_content_set(this->get_base(), "elm.swallow.content", CONVERT_TO_EO(view->get_base()));
+               content = CONVERT_TO_EO(view->get_base());
        }
 
+       elm_object_part_content_set(this->get_base(), "content", content);
+
        this->set_indicator(view->get_indicator());
 }
 
@@ -93,16 +118,41 @@ bool ui_viewmgr::create_base_layout(Evas_Object *conform)
        Evas_Object *layout = elm_layout_add(conform);
        if (!layout) return false;
 
-       elm_layout_theme_set(layout, "layout", "application", "default");
+       //default transition layout
+       elm_layout_file_set(layout, EDJ_PATH, "transition/default");
        elm_object_content_set(conform, layout);
 
+       //Push Finished Event
+       elm_layout_signal_callback_add(layout, "push,finished", "viewmgr",
+                       [](void *data, Evas_Object *obj, const char *emission, const char *source) -> void
+                       {
+                               ui_viewmgr *viewmgr = static_cast<ui_viewmgr *>(data);
+                               ui_view *pview = viewmgr->get_view(viewmgr->get_view_count() - 2);
+                               ui_view *view = viewmgr->get_last_view();
+                               if (pview) viewmgr->push_view_finished(pview);
+                               if (view) viewmgr->push_view_finished(view);
+                       },
+                       this);
+
+       //Pop Finished Event
+       elm_layout_signal_callback_add(layout, "pop,finished", "viewmgr",
+                       [](void *data, Evas_Object *obj, const char *emission, const char *source) -> void
+                       {
+                               ui_viewmgr *viewmgr = static_cast<ui_viewmgr *>(data);
+                               ui_view *pview = viewmgr->get_view(viewmgr->get_view_count() - 2);
+                               ui_view *view = viewmgr->get_last_view();
+                               if (pview) viewmgr->pop_view_finished(pview);
+                               if (view) viewmgr->pop_view_finished(view);
+                       },
+                       this);
+
        this->layout = layout;
 
        return true;
 }
 
 ui_viewmgr::ui_viewmgr(const char *pkg, ui_key_listener *key_listener)
-               : ui_iface_viewmgr(), key_listener(key_listener)
+               : ui_iface_viewmgr(), key_listener(key_listener), transition_style("")
 {
        if (!pkg)
        {
@@ -177,7 +227,7 @@ bool ui_viewmgr::activate()
        this->active_top_view();
 
        //FIXME: Necessary??
-       ui_view *view = dynamic_cast<ui_view *>(this->get_last_view());
+       ui_view *view = this->get_last_view();
        view->active();
 
        evas_object_show(this->win);
@@ -187,12 +237,12 @@ bool ui_viewmgr::activate()
 
 bool ui_viewmgr::deactivate()
 {
-       ui_iface_viewmgr::deactivate();
+       if (!ui_iface_viewmgr::deactivate()) return false;
 
        //FIXME: based on the profile, we should app to go behind or terminate.
        if (true)
        {
-               ui_view *view = dynamic_cast<ui_view *>(this->get_last_view());
+               ui_view *view = this->get_last_view();
                if (view) view->inactive();
                evas_object_lower(this->win);
        }
@@ -207,23 +257,49 @@ bool ui_viewmgr::deactivate()
 
 bool ui_viewmgr::pop_view()
 {
-       if (this->get_view_count() == 1) this->deactivate();
-       else if(!ui_iface_viewmgr::pop_view()) return false;
-
-       ui_view *view = dynamic_cast<ui_view *>(this->get_last_view());
+       if (this->get_view_count() == 1)
+       {
+               this->deactivate();
+               return true;
+       }
 
-       //TODO: get parent?
-       Evas_Object *content = view->get_base();
-       if (content == this->get_base())
+       if(!ui_iface_viewmgr::pop_view())
        {
-               elm_object_part_content_set(this->get_base(), "elm.swallow.content", CONVERT_TO_EO(view->get_content()));
+               return false;
        }
-       else
+
+       ui_view *pview = this->get_view(this->get_view_count() - 2);
+       ui_view *view = this->get_last_view();
+
+       //In case, if view doesn't have transition effect
+       if (!strcmp(view->get_transition_style(), "none"))
        {
-               elm_object_part_content_set(this->get_base(), "elm.swallow.content", CONVERT_TO_EO(view->get_base()));
+               this->pop_view_finished(pview);
+               this->pop_view_finished(view);
+               this->active_top_view();
+               return true;
        }
 
-       this->set_indicator(view->get_indicator());
+       //Choose an effect layout.
+       Evas_Object *effect = this->set_transition_layout(view->get_transition_style());
+       if (!effect) {
+               LOGE("invalid effect transition style?! = %s", view->get_transition_style());
+               this->pop_view_finished(pview);
+               this->pop_view_finished(view);
+               this->active_top_view();
+               return true;
+       }
+
+       //Trigger Effects.
+       Evas_Object *prv = CONVERT_TO_EO(this->get_base() == pview->get_base() ? pview->get_content() : pview->get_base());
+       elm_layout_content_set(effect, "content", prv);
+
+       Evas_Object *cur = CONVERT_TO_EO(this->get_base() == view->get_base() ? view->get_content() : view->get_base());
+       elm_layout_content_set(effect, "pcontent", cur);
+
+       elm_layout_signal_emit(effect, "view,pop", "viewmgr");
+
+       this->set_indicator(pview->get_indicator());
 
        return true;
 }
@@ -234,12 +310,53 @@ ui_view * ui_viewmgr::push_view(ui_view *view)
 
        if (!this->is_activated()) return view;
 
-       this->active_top_view();
+       //In case, if viewmgr has one view, we skip effect.
+       if (this->get_view_count() == 1) {
+               this->active_top_view();
+               this->push_view_finished(view);
+               return view;
+       }
+
+       ui_view *pview = this->get_view(this->get_view_count() - 2);
+
+       //In case, if view doesn't have transition effect
+       if (!strcmp(view->get_transition_style(), "none")) {
+               this->active_top_view();
+               this->push_view_finished(pview);
+               this->push_view_finished(view);
+               return view;
+       }
+
+       //Choose an effect layout.
+       Evas_Object *effect = this->set_transition_layout(view->get_transition_style());
+       if (!effect) {
+               LOGE("invalid effect transition style?! = %s", view->get_transition_style());
+               this->active_top_view();
+               this->push_view_finished(pview);
+               this->push_view_finished(view);
+               return view;
+       }
+
+       //Trigger Effects.
+       Evas_Object *prv = CONVERT_TO_EO(this->get_base() == pview->get_base() ? pview->get_content() : pview->get_base());
+       elm_layout_content_set(effect, "pcontent", prv);
+
+       Evas_Object *cur = CONVERT_TO_EO(this->get_base() == view->get_base() ? view->get_content() : view->get_base());
+       elm_layout_content_set(effect, "content", cur);
+
+       elm_layout_signal_emit(effect, "view,push", "viewmgr");
+
+       this->set_indicator(view->get_indicator());
 
        return view;
 }
 
+ui_view *ui_viewmgr::get_view(unsigned int idx)
+{
+       return dynamic_cast<ui_view *>(ui_iface_viewmgr::get_view(idx));
+}
+
 ui_view *ui_viewmgr::get_last_view()
 {
-   return dynamic_cast<ui_view *>(ui_iface_viewmgr::get_last_view());
+       return dynamic_cast<ui_view *>(ui_iface_viewmgr::get_last_view());
 }
index ca9b444..39a3dad 100644 (file)
@@ -83,7 +83,7 @@ void ui_iface_view::destroy()
 }
 
 ui_iface_view::ui_iface_view(ui_iface_controller *controller, const char *name)
-               : content(NULL), controller(controller), name(string(name ? name : "")), style(string("")), viewmgr(NULL), state(UI_VIEW_STATE_LOAD),
+               : content(NULL), controller(controller), name(string(name ? name : "")), transition_style(string("")), viewmgr(NULL), state(UI_VIEW_STATE_LOAD),
                  indicator(UI_VIEW_INDICATOR_DEFAULT), event_block(false), removable_content(true)
 {
        this->state = UI_VIEW_STATE_UNLOAD;
@@ -118,9 +118,9 @@ T ui_iface_view::set_content(T content)
        return prev;
 }
 
-bool ui_iface_view::set_style(const char *style)
+bool ui_iface_view::set_transition_style(const char *style)
 {
-       this->style.assign(style);
+       this->transition_style.assign(style);
        return true;
 }
 
index 5f19c90..3cdfd77 100644 (file)
@@ -70,7 +70,7 @@ bool ui_iface_viewmgr::push_view_finished(ui_iface_view *view)
 
        //A new view has been pushed. This should be active.
        view->active();
-       this->set_event_block(view, true);
+       this->set_event_block(view, false);
 
        return true;
 }
@@ -90,7 +90,7 @@ bool ui_iface_viewmgr::pop_view_finished(ui_iface_view *view)
 
        //The previous view has been popped. It should become active.
        view->active();
-       this->set_event_block(view, true);
+       this->set_event_block(view, false);
 
        return true;
 }
@@ -134,14 +134,11 @@ ui_iface_viewmgr::push_view(ui_iface_view *view)
        ui_iface_view *pview;
 
        //Previous view
-       if (this->view_list.size())
+       if (this->view_list.size() > 0)
        {
                pview = this->view_list.back();
                pview->inactive();
                this->set_event_block(pview, true);
-
-               //FIXME: Since we have no transition
-               pview->unload();
        }
 
        view_list.push_back(view);
@@ -159,13 +156,14 @@ ui_iface_viewmgr::push_view(ui_iface_view *view)
 
 bool ui_iface_viewmgr::pop_view()
 {
-       //No more view? destroy viewmgr?
+       //FIXME: No more view?
        if (this->get_view_count() == 0)
        {
+               LOGE("No Views. Can't pop anymore!");
                return false;
        }
 
-       //This is the last page. destroy viewmgr?
+       //This is the last page.
        if (this->get_view_count() == 1)
        {
                //destroy viewmgr?
@@ -175,7 +173,7 @@ bool ui_iface_viewmgr::pop_view()
                view->destroy();
                delete(view);
 
-               return false;
+               return true;
        }
 
        //last page to be popped.
@@ -192,13 +190,6 @@ bool ui_iface_viewmgr::pop_view()
        pview->inactive();
        this->set_event_block(pview, true);
 
-       //FIXME: since we have no transition effect
-       pview->active();
-       view->inactive();
-       view->unload();
-       view->destroy();
-       delete (view);
-
        return true;
 }