https://review.tizen.org/git/platform/core/uifw/ui-viewmgr refs/
1. Overview of Tizen View Manager
1.1 Tizen View
Conceptually, there are 2 types of views in Tizen. One is window view and the other is logical view.
Other than EFL, other UIFW in Tizen doesn’t have any view managing concept so far. Generally, one Tizen UI applications are being consisted views with Logic Views. One UI application has one basic Window view and it contains multiple logical views for navigating scenes. However, some applications occasionally use multiple windows for switching scenes. In this case, it could contain below scenarios.
Figure 1: Current Tizen view system
1.2 Naviframe
Figure 2: Naviframe View navigation between Page 1 and Page 2
1.2.1 Naviframe module (Elementary) in Tizen 2.4
Figure 3 shows you where Naviframe (Elementary) package is located in Tizen building blocks.
Figure 3: Naviframe (Elementary) in Tizen 2.4
1.2.2 Naviframe Basic API Usage
static void
create_base_gui(appdata_s *ad)
{
//…
//Create a Naviframe
Evas_Object *nf = elm_naviframe_add(win);
/* Push a previous button to naviframe item automatically */
elm_naviframe_prev_btn_auto_pushed_set(nf, EINA_TRUE);
/* Set naviframe as a main layout content */
elm_object_part_content_set(layout, “elm.swallow.content”, nf);
/* Add Callbacks for Back, More key events */
eext_object_event_callback_add(nf, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
eext_object_event_callback_add(nf, EEXT_CALLBACK_MORE, eext_naviframe_more_cb, NULL);
//Create a view content. create_main_content() is an utility function that application defined.
Evas_Object *content = create_main_content(nf, “Naviframe Demo<br/>Page 2”);
//Create a view
Elm_Object_Item *it = elm_naviframe_item_push(nf, "Title Buttons", NULL, NULL, content, NULL);
//Set a view title cancel button
Evas_Object *cancel_btn = elm_button_add(nf);
elm_object_text_set(cancel_btn, "CANCEL");
evas_object_show(cancel_btn);
elm_object_item_part_content_set(it, “prev_btn”, cancel_btn);
//Set a view title done button
Evas_Object *done_btn = elm_button_add(nf);
elm_object_text_set(done_btn, "DONE”);
evas_object_show(done_btn);
elm_object_item_part_content_set(it, “next_btn”, done_btn);
//…
}
1.2.3 Naviframe API list
//Create a Naviframe
Elm_Naviframe *elm_naviframe_add(Elm_Naviframe *parent);
//Create a Naviframe View
Elm_Naviframe_Item *elm_naviframe_item_push(Elm_Naviframe *nf, const char *title_label, Evas_Object *prev_btn, Evas_Object *next_btn, Evas_Object *content, const char *item_style);
//Insert a Naviframe View
Elm_Naviframe_Item *elm_naviframe_item_insert_after(Elm_Naviframe *nf, Elm_Naviframe_Item *after, const char *title_label, Evas_Object *prev_btn, Evas_Object *next_btn, Evas_Object *content, const char *item_style);
//Insert a Naviframe View
Elm_Naviframe_Item *elm_naviframe_item_insert_before(Elm_Naviframe *nf, Elm_Naviframe_Item *before, const char *title_label, Evas_Object *prev_btn, Evas_Object *next_btn, Evas_Object *content, const char *item_style);
//Destroy a Naviframe View
Evas_Object *elm_naviframe_item_pop(Elm_Naviframe *nf);
//Enable/Disable touch event on Naviframe View transition
void elm_naviframe_event_enabled_set(Elm_Naviframe *nf, Eina_Bool enabled);
//Preserve the content objects when Views are popped
void elm_naviframe_content_preserve_on_pop_set(Elm_Naviframe *nf, Eina_Bool preserve);
//Control if creating prev button automatically or not
void elm_naviframe_prev_btn_auto_pushed_set(Elm_Naviframe *nf, Eina_Bool auto_pushed);
//Return a handle of the top view
Elm_Naviframe_Item *elm_naviframe_top_item_get(const Elm_Naviframe *nf);
//Return a handle of the bottom view
Elm_Naviframe_Item *elm_naviframe_bottom_item_get(const Elm_Naviframe *nf);
//Return the list of the views
Eina_List *elm_naviframe_items_get(const Elm_Naviframe *nf);
//Set style of the view (“default”, “tabbar/icon/notitle”, “tabbar”, “empty”)
void elm_naviframe_item_style_set(Elm_Naviframe_Item *item, const char *style);
//Return the style of a Naviframe View
const char *elm_naviframe_item_style_get(const Elm_Navifrmae_Item *nf);
//Enable/Disable Title area of Naviframe
void elm_naviframe_item_title_enabled_set(Elm_Naviframe_Item *item, Eina_Bool enable, Eina_Bool transition);
//Promote an item already in the Naviframe stack to the top of the stack.
void elm_naviframe_item_promote(Elm_Naviframe_Item *item);
//Pop the top item and delete the items between the top and the above one on the given item.
void elm_naviframe_item_pop_to(Elm_Naviframe_Item *item);
//Set a function to be called when an item of the Naviframe is going to be popped.
void elm_naviframe_item_pop_cb_set(Elm_Naviframe_Item *item, Elm_Naviframe_Item_Pop_Cb func, void *data);
1.3 Tizen 2.4 View manager work flow
Figure 5: Tizen 2.4 View manager work flow
Basically, an application creates one default window that is a output of application display and fill inside it with views. Mostly, applications create views using any kind of container widgets like Elementary Layout, also control those views using Naviframe. Naviframe provides convenient functions via view push/pop mechanism. Additionally, it constructs basic view templates – Title and content parts and their look and feel styles - for views. Also, Naviframe implements view transition effects on the theme.
In a certain situation, application may require another view that is suggested by other application package. For instance, your application could request camera view from camera app package for your application scenario. In that case, you cannot push the camera view into your Naviframe, instead you could launch the camera application window which contains the camera view using App Control. App Control is a way of sharing an application’s functionality like this situation. Once you launched the other application using App Control, it would be possible that one more windows for your applications could be constructed. However, window behaviors were controlled by Window manager under the Tizen window managing policy. Now, if you want to switch the views over the windows, in this case, then Window manager will perform the view switching immediately.
Lastly, when the user pressed the Menu or Back key, the key generates a signal with its key property. EFL library receives the signal then propagates it to application layers as an event. The EFL extension library consumes the events and handles the views of the application according to key properties. Otherwise, EFL extension manages the rotary events, which are generated from rotary components in wearable devices and delivered to application layers by defining an event callback or a handler function, and registering it.
1.4 Problems (Improvement Points)
Since first generation of Tizen, we’ve found a few weak points and here list tells you the improvement point proposal for the next Tizen platform.
2. New Tizen View Manager
2.1 Considerations
But the point is, whatever its substance is, if it provides an abstracted interface for the views, it will decrease conceptual complexity in point of user programming view. Also theoretically, it’s possible to achieve a management system for separated views from different UI systems such as EFL, Dali and Volt.
One of downside of Tizen is, it has multiple UI systems. These UI systems have totally different development concepts, even different programming languages. Currently, EFL is based on the C language but Dali is based on C++ on the other hands. If we design the common Tizen View manager interfaces and it comes out with the specification for the UI application view managing, then users would understand the view manager concept quickly and easier through the different UI systems. Also, those UI systems could utilize the common View manager implementation body.
The conclusion is, Tizen View Manager needs an enhanced clean and easy interface set out of Elementary Naviframe. It should be extendable by 2nd, 3rd parties, also its framework interface should be well-organized with Tizen application life-cycle and Tizen system. If the concept is closed to more Tizen family wise, it would be satisfied with any concepts of Tizen UX.
2.2 UI View Manager Common Classes
2.2.1 Class Description
Next common interface classes are designed for Tizen View manager basic behaviors. Some of the methods are implemented with basic behaviors but some of them don’t because some parts of body are independent with UI systems but some parts must depend on UI systems. So you must inherit them definitely to implement the specific behaviors for current UI system.
Figure 6: UiIfaceViewmgr class diagram
Figure 7: UiIfaceView class diagram
Figure 8: UiIfaceRotatable class diagram
Figure 9: UiIfaceOverlay class diagram
Figure 10: UiIfaceApp class diagram
2.2.2 Design Diagrams
A View manager designed on a certain UI system could be built on the base common interfaces. Applications may access that view manager to achieve view managing functions. Next figure 9, 10 shows you this design abstraction diagrams.
Figure 11: Abstract View Manager Design Diagram
Figure 12: UI system specified View Manager Design Diagram
Figure 13: EFL View manager Design Diagram
2.3 EFL View Manager Classes
2.3.1 EFL Base Classes
EFL base classes are designed for supporting view manager basics under profiles. Each view manager in various profiles could extend these base classes for their own specific policy and behaviors of profile. These bases implements common behaviors for EFL.
Figure 14: UiBaseViewmgr class diagram
Figure 15: UiBaseView class diagram
Figure 16: UiBaseOverlay class diagram
Figure 17: UiBaseKeyListener class diagram
2.3.2 Mobile profile EFL View manager classes
Figure 18: UiViewmgr class diagram
Figure 19: UiView class diagram
Figure 20: UiStandardView class diagram
Figure 21: UiMenu class diagram
Figure 22: UiPopup class diagram
Figure 23: UiKeyListener class diagram
Figure 24: UiApp class diagram
Figure 25 shows you an entire class hierarchy for EFL Mobile profile.
Figure 25: Class hierarchy for EFL Mobile Profile
2.4 New Block Diagram
Figure 26: UiViewmgr in Tizen 3.0
2.5 New View Manager work flow
Figure 27: UI View Manager work flow
Compared to the previous architecture, new view manager in Tizen 3.0 is wholly replaced to UiViewmgr from Elementary Naviframe. This new UiViewmgr will work on a UI system, hiding detailed view managing mechanism with regard to UI system. Main functionality of view managing is similar with functionality of Naviframe. However, UiViewmgr takes cover not only view managing but HW key propagation and popup context management also.
UiView is a more abstracted handle for a view that provides much more convenient functions and simpler interfaces. Not like Elm_Object_Item, which is a view interface of Naviframe, UiView works on the view manager which is running with Tizen application process. UiView notifies users to handle some pre-conditioned various states on time. For instance, after registering a view, user could get a notification about load, unload, pause, resume, activate, deactivate. This state based view managing methods reduces the complexity of view context, also improves the application infrastructure design cohesion.
Next figure shows you a life-cycle of a view on a certain scenario.
Figure 28: View life cycle
A view works on state based, it must have only one certain state by scenario. The next describes those states of a view.
3. Sample Code (C++)
class SampleApp: public UiApp
{
public:
SampleApp() : UiApp(PACKAGE, LOCALE_DIR) {}
~SampleApp() {}
bool onCreate()
{
if (!UiApp::onCreate()) return false;
/* Create a first view content here… */
UI_VIEWMGR->pushView(new page());
return true;
}
};
int main(int argc, char *argv[])
{
SampleApp app;
return app.run(argc, argv);
}
class page: public UiStandardView
{
/* on_load() will be called when this page is requested to be shown. */
void onLoad()
{
UiStandardView::onLoad();
/* create content */
…
this->setContent(content, “title”);
}
};
class page: public UiStandardView
{
void onLoad()
{
…
/* create a back button */
Elm_Button *btn= elm_button_add(this->getBase());
evas_object_smart_callback_add(btn, “clicked”,
[](void *data, Evas_Object *obj, void *event_info) -> void
{
UI_VIEWMGR->popView();
}, this);
/* create content */
…
this->setContent(content, “title”, NULL, btn, NULL);
}
};
class page: public UiStandardView { void onLoad() { /* create content */ … this->setContent(content, “title”); /* Sub title */ this->setSubtitle(“subtitle”); /* Title Left Button */ Elm_Button *leftBtn= elm_button_add(this->getBase()); this->setTitleLeftBtn(leftBtn); /* Title Right Button */ Elm_Button *rightBtn= elm_button_add(this->getBase()); this->setTitleRightBtn(rightBtn); /* or you could use this, this->setContent(content, “title”, “subtitle”, leftBtn, rightBtn); */ } };
class page1: public UiStandardView { void onLoad() { … this->setIndicator(UI_VIEW_INDICATOR_DEFAULT); /* You could use one of below items. UI_VIEW_INDICATOR_DEFAULT, UI_VIEW_INDICATOR_OPTIMAL, UI_VIEW_INDICATOR_OVERLAP, UI_VIEW_INDICATOR_HIDE, UI_VIEW_INDICATOR_SHOW, */ } }; class page2: public UiStandardView { void onLload() { … this->setIndicator(UI_VIEW_INDICATOR_OVERLAP); } }; //UI View Manager will recover the indicator status when it goes back to page 1 from page 2
class page: public UiStandardView { void onLoad() { … this->setTransitionStyle(“fade”); } };
class page: public UiStandardView { void onMenu(UiMenu *menu) { UiStandardView::onMenu(menu); Elm_Ctxpopup *ctxpopup = elm_ctxpopup_add(menu->get_base()); elm_ctxpopup_item_append(ctxpopup, "Phone calls", NULL, ctxpopup_item_select_cb, this); elm_ctxpopup_item_append(ctxpopup, "Favorites", NULL, ctxpopup_item_select_cb, this); elm_ctxpopup_item_append(ctxpopup, "Search", NULL, ctxpopup_item_select_cb, this); elm_ctxpopup_item_append(ctxpopup, "Dialer", NULL, ctxpopup_item_select_cb, this); menu->setContent(ctxpopup); } };
void createPopup(page *view) { UiPopup *popup = new UiPopup(view); Elm_Popup *obj = elm_popup_add(popup->getBase()); elm_object_text_set(obj, "This popup has only text which is set via desc set function, (This popup gets hidden when user clicks outside) here timeout of 3 sec is set."); popup->setContent(obj); popup->activate(); } class page: public UiStandardView { void onBack() { /* Do something */ UiStandardView::onBack(); } };
class page: public UiStandardView { void onBack() { /* Do something */ UiStandardView::onBack(); } };