From 97c2d5db44852eac643d9079f030193b3ec0607f Mon Sep 17 00:00:00 2001 From: woochan lee Date: Tue, 2 Feb 2016 19:12:45 +0900 Subject: [PATCH] Introduce an initial Draft Signed-Off-By: Hermet Park Signed-Off-By: WooChan Lee Change-Id: I77bf628f44079bb117d2bb42a31735d29caa2e35 --- AUTHORS | 3 +- CMakeLists.txt | 100 ++++---- README | 7 + data/org.tizen.ui-viewmgr.png | Bin 0 -> 57662 bytes data/ui-viewmgr.uri | 2 + inc/main.h | 46 ++++ org.tizen.ui-viewmgr.manifest | 26 +++ org.tizen.ui-viewmgr.xml | 14 ++ packaging/ui-controls.spec | 47 ++++ packaging/ui-viewmgr.spec | 69 ------ {data/edc => res}/ui-viewmgr.edc | 0 src/CMakeLists.txt | 8 - src/app_controller.h | 269 ++++++++++++++++++++++ src/efl_viewmgr.h | 8 + src/examples/CMakeLists.txt | 16 -- src/examples/viewmgr_demo.c | 264 --------------------- src/include/CMakeLists.txt | 6 - src/include/ui_view.h | 117 ---------- src/include/ui_viewmgr.h | 100 -------- src/include/ui_viewmgr_private.h | 125 ---------- src/lib/CMakeLists.txt | 19 -- src/lib/ui_view.c | 122 ---------- src/lib/ui_viewmgr.c | 482 --------------------------------------- src/main.cpp | 148 ++++++++++++ src/ui_basic_view.cpp | 125 ++++++++++ src/ui_basic_view.h | 35 +++ src/ui_controller.cpp | 18 ++ src/ui_controller.h | 50 ++++ src/ui_controller_base.cpp | 13 ++ src/ui_controller_base.h | 106 +++++++++ src/ui_view.cpp | 37 +++ src/ui_view.h | 40 ++++ src/ui_view_base.cpp | 125 ++++++++++ src/ui_view_base.h | 222 ++++++++++++++++++ src/ui_viewmgr.cpp | 169 ++++++++++++++ src/ui_viewmgr.h | 232 +++++++++++++++++++ src/ui_viewmgr_base.cpp | 234 +++++++++++++++++++ src/ui_viewmgr_base.h | 220 ++++++++++++++++++ ui-viewmgr.manifest | 24 -- ui-viewmgr.pc.in | 11 - 40 files changed, 2253 insertions(+), 1406 deletions(-) create mode 100644 README create mode 100644 data/org.tizen.ui-viewmgr.png create mode 100644 data/ui-viewmgr.uri create mode 100644 inc/main.h create mode 100644 org.tizen.ui-viewmgr.manifest create mode 100644 org.tizen.ui-viewmgr.xml create mode 100644 packaging/ui-controls.spec delete mode 100644 packaging/ui-viewmgr.spec rename {data/edc => res}/ui-viewmgr.edc (100%) delete mode 100644 src/CMakeLists.txt create mode 100644 src/app_controller.h create mode 100644 src/efl_viewmgr.h delete mode 100644 src/examples/CMakeLists.txt delete mode 100644 src/examples/viewmgr_demo.c delete mode 100644 src/include/CMakeLists.txt delete mode 100644 src/include/ui_view.h delete mode 100644 src/include/ui_viewmgr.h delete mode 100644 src/include/ui_viewmgr_private.h delete mode 100644 src/lib/CMakeLists.txt delete mode 100644 src/lib/ui_view.c delete mode 100644 src/lib/ui_viewmgr.c create mode 100644 src/main.cpp create mode 100644 src/ui_basic_view.cpp create mode 100644 src/ui_basic_view.h create mode 100644 src/ui_controller.cpp create mode 100644 src/ui_controller.h create mode 100644 src/ui_controller_base.cpp create mode 100644 src/ui_controller_base.h create mode 100644 src/ui_view.cpp create mode 100644 src/ui_view.h create mode 100644 src/ui_view_base.cpp create mode 100644 src/ui_view_base.h create mode 100644 src/ui_viewmgr.cpp create mode 100644 src/ui_viewmgr.h create mode 100644 src/ui_viewmgr_base.cpp create mode 100644 src/ui_viewmgr_base.h delete mode 100644 ui-viewmgr.manifest delete mode 100644 ui-viewmgr.pc.in diff --git a/AUTHORS b/AUTHORS index 47a65d6..2bb03d8 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1,2 @@ -Subhransu Sekhar Mohanty +Chuneon Park +Woochan Lee diff --git a/CMakeLists.txt b/CMakeLists.txt index c46812f..985d7ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,56 +1,72 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(ui-viewmgr) +SET(PACKAGE org.tizen.ui-viewmgr) -SET(PREFIX ${CMAKE_INSTALL_PREFIX}) -SET(EXEC_DIR ${PREFIX}) -SET(BINDIR ${PREFIX}/bin) -SET(LIBDIR ${PREFIX}/lib) -SET(INCDIR ${PREFIX}/include) -SET(VERSION_MAJOR 0) -SET(VERSION ${VERSION_MAJOR}.1.0) -SET(VENDOR "samsung") -SET(PACKAGE ${PROJECT_NAME}) - -SET(CMAKE_SKIP_BUILD_RPATH TRUE) - -IF("${CMAKE_BUILD_TYPE}" STREQUAL "") - SET(CMAKE_BUILD_TYPE "Release") -ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "") -MESSAGE("Build type: ${CMAKE_BUILD_TYPE}") - -IF(NOT DBDIR) - SET(DBDIR "$ENV{HOME}") -ENDIF(NOT DBDIR) -ADD_DEFINITIONS("-DDBDIR=\"${DBDIR}\"") -ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") -ADD_DEFINITIONS("-DVERSION=\"${VERSION}\"") -ADD_DEFINITIONS("-DPACKAGE=\"${PACKAGE}\"") -ADD_DEFINITIONS("-DPLUGINDIR=\"${PLUGINDIR}\"") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -Wall") +SET(SRCS + src/ui_controller.cpp + src/ui_view.cpp + src/ui_viewmgr.cpp + src/ui_controller_base.cpp + src/ui_view_base.cpp + src/ui_viewmgr_base.cpp + src/ui_basic_view.cpp + src/main.cpp + ) -# Added for edc -SET(RESDIR "${PREFIX}/res") -SET(EDJ_PATH "${RESDIR}/edje") +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/inc) -#INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR}) +FIND_LIBRARY(LIB_M m) +#FIXME: pthread is added for preventing build error +SET(PKG_LDFLAGS "-pthread ${LIB_M} -pie") +SET(PKG_CFLAGS "-g -Wall -fPIE") INCLUDE(FindPkgConfig) +pkg_check_modules(BASE_PKG REQUIRED elementary efl-extension) +FOREACH(flag ${BASE_PKG_CFLAGS}) + SET(PKG_CFLAGS "${PKG_CFLAGS} ${flag}") +ENDFOREACH(flag) +FOREACH(flag ${BASE_PKG_LDFLAGS}) + SET(PKG_LDFLAGS "${PKG_LDFLAGS} ${flag}") +ENDFOREACH(flag) + +pkg_check_modules(TIZEN_PKG REQUIRED dlog capi-appfw-application capi-system-system-settings appcore-efl capi-appfw-app-manager) +FOREACH(flag ${TIZEN_PKG_CFLAGS}) + SET(PKG_CFLAGS "${PKG_CFLAGS} ${flag}") +ENDFOREACH(flag) +FOREACH(flag ${TIZEN_PKG_LDFLAGS}) + SET(PKG_LDFLAGS "${PKG_LDFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(GC_SECTIONS_FLAGS "-fdata-sections -ffunction-sections -Wl,--gc-sections") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PKG_CFLAGS}") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PKG_CFLAGS} -Wall -Werror -Wno-unused -Wno-format-extra-args -Wl,--no-undefined -fvisibility=hidden -fPIC -std=c++0x ${GC_SECTIONS_FLAGS}") -ADD_SUBDIRECTORY(src) +# install desktop file & icon +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(BINDIR "${PREFIX}/bin") +SET(RESDIR "${PREFIX}/res") +SET(DATADIR "${PREFIX}/data") +SET(LOCALEDIR "${RESDIR}/locale") +SET(IMGDIR "${RESDIR}/images") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror") -SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") -SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib") +ADD_DEFINITIONS("-DPACKAGE=\"${PACKAGE}\"") +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DRESDIR=\"${RESDIR}\"") +ADD_DEFINITIONS("-DDATADIR=\"${DATADIR}\"") +ADD_DEFINITIONS("-DLOCALE_DIR=\"${LOCALEDIR}\"") -CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION lib/pkgconfig) +ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${PKG_LDFLAGS}) ADD_CUSTOM_TARGET(${PROJECT_NAME}.edj - COMMAND edje_cc ${CMAKE_SOURCE_DIR}/data/edc/${PROJECT_NAME}.edc ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.edj - DEPENDS ${CMAKE_SOURCE_DIR}/data/edc/${PROJECT_NAME}.edc - ) + COMMAND edje_cc + ${CMAKE_SOURCE_DIR}/res/${PROJECT_NAME}.edc ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.edj + DEPENDS ${CMAKE_SOURCE_DIR}/res/${PROJECT_NAME}.edc + ) ADD_DEPENDENCIES(${PROJECT_NAME} ${PROJECT_NAME}.edj) -INSTALL(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.edj DESTINATION /usr/share/edje/${PROJECT_NAME}) - - +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR}) +# for workaround taskmanager behaviour +INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/${PACKAGE}.png DESTINATION /usr/share/icons/default/small/) +INSTALL(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.edj DESTINATION ${RESDIR}) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${PACKAGE}.xml DESTINATION /usr/share/packages/) diff --git a/README b/README new file mode 100644 index 0000000..8e123d2 --- /dev/null +++ b/README @@ -0,0 +1,7 @@ +Tizen View Manager 0.1.0 + +****************************************************************************** + + FOR ANY ISSUES PLEASE EMAIL: + +****************************************************************************** diff --git a/data/org.tizen.ui-viewmgr.png b/data/org.tizen.ui-viewmgr.png new file mode 100644 index 0000000000000000000000000000000000000000..9765b1bda7e5bddf0925555ab204b887a873bf24 GIT binary patch literal 57662 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 kZ}gYfNaCF}xV$|1>H6z0+kD +#include +#include +#include +#include "../src/efl_viewmgr.h" + +//uncomment if you want debug +#ifndef TIZEN_ENGINEER_MODE +#define TIZEN_ENGINEER_MODE +#endif + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "VIEWMGR" + + +#if !defined(PACKAGE) +#define PACKAGE "org.tizen.ui-viewmgr" +#endif + + +#define ELM_DEMO_EDJ "/opt/usr/apps/org.tizen.ui-viewmgr/res/ui-viewmgr.edj" + + +typedef struct appdata { + ui_viewmgr *viewmgr; +} appdata_s; + +void view_cb(void *data, Evas_Object *obj, void *event_info); diff --git a/org.tizen.ui-viewmgr.manifest b/org.tizen.ui-viewmgr.manifest new file mode 100644 index 0000000..d864c98 --- /dev/null +++ b/org.tizen.ui-viewmgr.manifest @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.tizen.ui-viewmgr.xml b/org.tizen.ui-viewmgr.xml new file mode 100644 index 0000000..113efba --- /dev/null +++ b/org.tizen.ui-viewmgr.xml @@ -0,0 +1,14 @@ + + + + + org.tizen.ui-viewmgr.png + + + + + + http://tizen.org/privilege/appmanager.launch + http://tizen.org/privilege/appmanager.kill.bgapp + + diff --git a/packaging/ui-controls.spec b/packaging/ui-controls.spec new file mode 100644 index 0000000..8ac34ee --- /dev/null +++ b/packaging/ui-controls.spec @@ -0,0 +1,47 @@ +Name: org.tizen.ui-viewmgr +Summary: UI Viewmgr (Elementary) +Version: 1.0.3 +Release: 1 +Group: TO_BE/FILLED_IN +License: Apache License, Version 2.0 +Source0: %{name}-%{version}.tar.gz +BuildRequires: pkgconfig(elementary) +BuildRequires: pkgconfig(capi-appfw-application) +BuildRequires: pkgconfig(capi-system-system-settings) +BuildRequires: pkgconfig(capi-appfw-app-manager) +BuildRequires: pkgconfig(dlog) +BuildRequires: app-core-efl-devel +BuildRequires: efl-extension-devel +BuildRequires: cmake +BuildRequires: edje-bin +BuildRequires: gettext-tools + +%description +UI Viewmgr (Elementary) + +%prep +%setup -q + +%define prefix "/opt/usr/apps/org.tizen.ui-viewmgr" + +%build +rm -rf CMakeFiles CMakeCache.txt && cmake . -DCMAKE_INSTALL_PREFIX=%{prefix} +make %{?jobs:-j%jobs} + +%install +%make_install + +mkdir -p %{buildroot}/%{_datadir}/packages/ +cp %{_builddir}/%{buildsubdir}/org.tizen.ui-viewmgr.xml %{buildroot}/%{_datadir}/packages/org.tizen.ui-viewmgr.xml + +mkdir -p %{buildroot}/%{_datadir}/license +cp %{_builddir}/%{buildsubdir}/LICENSE %{buildroot}/%{_datadir}/license/%{name} + +%files +%defattr(-,root,root,-) +/opt/usr/apps/org.tizen.ui-viewmgr/bin/* +/opt/usr/apps/org.tizen.ui-viewmgr/res/* +%{_datadir}/packages/org.tizen.ui-viewmgr.xml +%{_datadir}/icons/default/small/org.tizen.ui-viewmgr.png +%{_datadir}/license/%{name} +%manifest %{name}.manifest diff --git a/packaging/ui-viewmgr.spec b/packaging/ui-viewmgr.spec deleted file mode 100644 index c426034..0000000 --- a/packaging/ui-viewmgr.spec +++ /dev/null @@ -1,69 +0,0 @@ -Name: ui-viewmgr -Summary: UI VIEW MANAGER library -Version: 0.1.0 -Release: 1 -Group: System/Libraries -License: APLv2 -Source0: %{name}-%{version}.tar.gz -BuildRequires: edje-bin -BuildRequires: pkgconfig(elementary) -BuildRequires: pkgconfig(dlog) -BuildRequires: pkgconfig(utilX) -Requires(post): /sbin/ldconfig -Requires(postun): /sbin/ldconfig - - -%description -UI VIEW MANAGER library - - -%package devel -Summary: UI VIEW MANAGER library (devel) -Group: Development/Libraries -Requires: %{name} = %{version}-%{release} -Requires: capi-base-common-devel - - -%description devel -UI VIEW MANAGER library providing View management functionality(devel) - - -%prep -%setup -q - - -%build -export CFLAGS+=" -fvisibility=hidden" -export LDFLAGS+=" -fvisibility=hidden" -cmake . -DCMAKE_INSTALL_PREFIX=/usr - -make %{?jobs:-j%jobs} - - -%install -rm -rf %{buildroot} -%make_install -mkdir -p %{buildroot}/usr/share/license -cp %{_builddir}/%{buildsubdir}/LICENSE %{buildroot}/usr/share/license/%{name} - - -%post -p /sbin/ldconfig - - -%postun -p /sbin/ldconfig - -%files -%defattr(-,root,root,-) -%{_libdir}/libui-viewmgr.so.* -%manifest %{name}.manifest -/usr/share/license/%{name} -/usr/share/edje/ui-viewmgr/ui-viewmgr.edj -/opt/usr/apps/ui-viewmgr/bin/* - - -%files devel -%defattr(-,root,root,-) -%{_includedir}/ui-viewmgr/*.h -%{_libdir}/*.so -%{_libdir}/pkgconfig/ui-viewmgr.pc - diff --git a/data/edc/ui-viewmgr.edc b/res/ui-viewmgr.edc similarity index 100% rename from data/edc/ui-viewmgr.edc rename to res/ui-viewmgr.edc diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index d7cc3a1..0000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -SET(LIB_NAME ${PROJECT_NAME}) - -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) -LINK_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/lib) - -ADD_SUBDIRECTORY(include) -ADD_SUBDIRECTORY(lib) -ADD_SUBDIRECTORY(examples) diff --git a/src/app_controller.h b/src/app_controller.h new file mode 100644 index 0000000..8526c5a --- /dev/null +++ b/src/app_controller.h @@ -0,0 +1,269 @@ +#include "ui_controller.h" + + +static Evas_Object* +create_content(Evas_Object *parent, const char *text, Evas_Smart_Cb prev_btn_clicked_cb, Evas_Smart_Cb next_btn_clicked_cb, appdata_s *ad) +{ + Evas_Object *grid, *box, *layout, *scroller, *btn, *button_layout; + + /* Scroller */ + scroller = elm_scroller_add(parent); + elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE); + elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO); + + /* Grid */ + grid = elm_grid_add(scroller); + evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(grid, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(grid); + + /* NoContent Layout */ + layout = elm_layout_add(grid); + elm_layout_theme_set(layout, "layout", "nocontents", "default"); + elm_object_part_text_set(layout, "elm.text", text); + evas_object_show(layout); + elm_grid_pack(grid, layout, 0, 0, 100, 100); + + /* Previous Page Button */ + btn = elm_button_add(grid); + elm_object_text_set(btn, "Prev"); + evas_object_smart_callback_add(btn, "clicked", prev_btn_clicked_cb, ad); + evas_object_show(btn); + elm_grid_pack(grid, btn, 10, 90, 30, 8); + + /* Next Page Button */ + btn = elm_button_add(grid); + elm_object_text_set(btn, "Next"); + evas_object_smart_callback_add(btn, "clicked", next_btn_clicked_cb, ad); + evas_object_show(btn); + elm_grid_pack(grid, btn, 60, 90, 30, 8); + + elm_object_content_set(scroller, grid); + + return scroller; +} + + + + + +class app_controller4: public ui_controller +{ +private: + appdata_s *ad; + Evas_Object *content; + + static void page_clicked_cb(void *data, Evas_Object *obj, void *event_info) + { + + appdata_s *ad = static_cast(data); + + } + +public: + app_controller4(appdata_s *ad) : + ad(ad), content(NULL) + { + } + + ~app_controller4() + { + LOGE("controller 4"); + } + + void load() + { + LOGE("view 4 button create"); + ui_view *view = this->get_view(); + Evas_Object *btn = elm_button_add(view->get_base()); + elm_object_text_set(btn, "Page 4"); + view->set_content(btn); + + evas_object_smart_callback_add(btn, "clicked", page_clicked_cb, this->ad); + + this->content = btn; + } + + void unload() + { + LOGE("controller4"); + evas_object_del(this->content); + ui_view *view = this->get_view(); + view->set_content(NULL); + } + + void active() + { + LOGE("controller4"); + } + + void inactive() + { + LOGE("controller4"); + } + + void destroy() + { + LOGE("controller4"); + } +}; + +class app_controller3: public ui_controller +{ +private: + appdata_s *ad; + Evas_Object *content; + + static void page_clicked_cb(void *data, Evas_Object *obj, void *event_info) + { + + appdata_s *ad = static_cast(data); + + //View 4 + + app_controller4 *controller = new app_controller4(ad); + ad->viewmgr->push_view(new ui_basic_view(controller)); + + } + +public: + app_controller3(appdata_s *ad) : + ad(ad), content(NULL) + { + } + + ~app_controller3() + { + LOGE("controller 3"); + } + + void load() + { + ui_view *view = this->get_view(); + Evas_Object *btn = elm_button_add(view->get_base()); + elm_object_text_set(btn, "Page 3"); + view->set_content(btn); + + evas_object_smart_callback_add(btn, "clicked", page_clicked_cb, this->ad); + + this->content = btn; + } + + void unload() + { + LOGE("controller3"); + evas_object_del(this->content); + ui_view *view = this->get_view(); + view->set_content(NULL); + } + + void active() + { + LOGE("controller3"); + } + + void inactive() + { + LOGE("controller3"); + } + + void destroy() + { + LOGE("controller3"); + } +}; + +class app_controller2: public ui_controller +{ +private: + appdata_s *ad; + Evas_Object *content; + + static void next_clicked_cb(void *data, Evas_Object *obj, void *event_info) + { + appdata_s *ad = static_cast(data); + //View 2 + app_controller2 *controller = new app_controller2(ad); + ad->viewmgr->push_view(new ui_basic_view(controller)); + } + static void prev_clicked_cb(void *data, Evas_Object *obj, void *event_info) + { + appdata_s *ad = static_cast(data); + ad->viewmgr->deactivate(); + } + +public: + app_controller2(appdata_s *ad) : + ad(ad), content(NULL) + { + } + + ~app_controller2() + { + } + + void load() + { + ui_basic_view *view = dynamic_cast(ui_controller::get_view()); + Evas_Object *content = create_content(view->get_base(), "ViewMgr Demo
Page 2", prev_clicked_cb, next_clicked_cb, this->ad); + + Evas_Object *left_title_btn = elm_button_add(view->get_base()); + elm_object_text_set(left_title_btn, "Cancel"); + + Evas_Object *right_title_btn = elm_button_add(view->get_base()); + elm_object_text_set(right_title_btn, "Done"); + + view->set_content(content, "Title Buttons", NULL, left_title_btn, right_title_btn); + this->content = content; + } + + void unload() + { + evas_object_del(this->content); + ui_view *view = this->get_view(); + view->set_content(NULL); + } +}; + +class app_controller1: public ui_controller +{ +private: + appdata_s *ad; + + static void next_clicked_cb(void *data, Evas_Object *obj, void *event_info) + { + appdata_s *ad = static_cast(data); + //View 2 + app_controller2 *controller = new app_controller2(ad); + ad->viewmgr->push_view(new ui_basic_view(controller)); + } + static void prev_clicked_cb(void *data, Evas_Object *obj, void *event_info) + { + appdata_s *ad = static_cast(data); + ad->viewmgr->deactivate(); + } + +public: + app_controller1(appdata_s *ad) : + ad(ad) + { + } + + ~app_controller1() + { + } + + void load() + { + ui_basic_view *view = dynamic_cast(ui_controller::get_view()); + Evas_Object *content = create_content(view->get_base(), "ViewMgr Demo
Page 1", prev_clicked_cb, next_clicked_cb, this->ad); + view->set_content(content, "Title"); + } + + void unload() + { + ui_view *view = ui_controller::get_view(); + Evas_Object *btn = view->set_content(NULL); + evas_object_del(btn); + } +}; diff --git a/src/efl_viewmgr.h b/src/efl_viewmgr.h new file mode 100644 index 0000000..a426a2a --- /dev/null +++ b/src/efl_viewmgr.h @@ -0,0 +1,8 @@ +#include +#include "ui_viewmgr.h" +#include "ui_controller.h" +#include "ui_basic_view.h" +#include "ui_view.h" + + +using namespace efl; diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt deleted file mode 100644 index 2f33e9c..0000000 --- a/src/examples/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -SET(EXAM_NAME viewmgr_demo) -SET(EXAM_SRCS viewmgr_demo.c) - -ADD_EXECUTABLE(${EXAM_NAME} ${EXAM_SRCS}) - -PKG_CHECK_MODULES(EXAM_PKGS REQUIRED elementary) -FOREACH(flag ${EXAM_PKGS_CFLAGS}) - SET(EXAM_CFLAGS "${EXAM_CFLAGS} ${flag}") -ENDFOREACH(flag) - -SET_TARGET_PROPERTIES(${EXAM_NAME} PROPERTIES COMPILE_FLAGS "${EXAM_CFLAGS}") -TARGET_LINK_LIBRARIES(${EXAM_NAME} ${EXAM_PKGS_LDFLAGS} ${EXAM_TARGET_PKGS_LDFLAGS}) -TARGET_LINK_LIBRARIES(${EXAM_NAME} ${EXAM_PKGS_LDFLAGS} ${LIB_NAME}) - -INSTALL(TARGETS ${EXAM_NAME} DESTINATION /opt/usr/apps/ui-viewmgr/bin) - diff --git a/src/examples/viewmgr_demo.c b/src/examples/viewmgr_demo.c deleted file mode 100644 index 7c1a6c2..0000000 --- a/src/examples/viewmgr_demo.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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 -#include -#include -#include - -static Evas_Object *window; -static ui_viewmgr *view_mgr; -static ui_view *promote_view; - -Evas_Object* -create_btn(const char *title, Eina_Bool left, Eina_Bool popup_btn) -{ - Evas_Object *button = elm_button_add(window); - - if (popup_btn) - elm_object_style_set(button, "bottom"); - else - { - if (left) - elm_object_style_set(button, "naviframe/title_left"); - else - elm_object_style_set(button, "naviframe/title_right"); - } - - elm_object_text_set(button, title); - return button; -} - -Evas_Object* -create_content(const char *text) -{ - Evas_Object *nocontents; - - /* Create elm_layout and set its style as nocontents/text */ - nocontents = elm_layout_add(window); - elm_layout_theme_set(nocontents, "layout", "nocontents", "default"); - evas_object_size_hint_weight_set(nocontents, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(nocontents, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_object_part_text_set(nocontents, "elm.text", text); - elm_layout_signal_emit(nocontents, "align.center", "elm"); - - return nocontents; -} - -// Create Content using layout and elm_widgets -Evas_Object* -create_view(const char *title_label,Evas_Object *prev_btn,Evas_Object *next_btn,Evas_Object *content) -{ - Evas_Object *layout; - layout = elm_layout_add(window); - elm_layout_theme_set(layout, "layout", "application", "view"); - - // add next button if any - if(next_btn) { - elm_object_part_content_set(layout, "title_right_btn", next_btn); - } - // add prev_button if any - if(prev_btn) { - elm_object_part_content_set(layout, "title_left_btn", prev_btn); - } - if(content) { - elm_object_part_content_set(layout, "elm.swallow.content", content); - } - if(title_label) { - elm_object_part_text_set(layout, "elm.text.title", title_label); - } - return layout; -} - -// pop the top view from the view manager stack -void -_pop_view(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - ui_viewmgr_view_pop(view_mgr); -} - -// promote a view to top of the stack -void -_promote_view2(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - ui_viewmgr_view_promote(view_mgr, promote_view); -} - -// this is the callback handler for view_event -Eina_Bool -_view6(void *data EINA_UNUSED, ui_view *viewobj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Evas_Object *prev, *content, *next; - prev = create_btn("view 5", EINA_TRUE, EINA_FALSE); - next = create_btn("Promote View 2", EINA_FALSE, EINA_FALSE); - content = create_view("View 6",prev,next,create_content("View 6 Content")); - ui_view *view = ui_view_add(content); - ui_view_style_set(view, "slidein"); - ui_viewmgr_view_push(view_mgr, view); - evas_object_smart_callback_add(prev, "clicked", _pop_view, view_mgr); - evas_object_smart_callback_add(next, "clicked", _promote_view2, view_mgr); -} - -void -_popup_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - ui_view *view = data; - // add a callback when the view pop transition is finished. - ui_view_event_callback_add(view,"view,disappear,finish",_view6,data); - ui_viewmgr_view_pop(view_mgr); -} - -// A popup view which will overlay on top of the previous view -void -_view5(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Evas_Object *content, *next, *cancel, *popup; - - popup = elm_popup_add(window); - elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0); - evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - elm_object_text_set(popup, "This popup has content area and action area, action area has two buttons Next and Cancel."); - - ui_view *view = ui_view_add(popup); - - next = create_btn("Next", EINA_FALSE, EINA_TRUE); - cancel = create_btn("Cancel", EINA_FALSE, EINA_TRUE); - - elm_object_part_content_set(popup, "button1", next); - evas_object_smart_callback_add(next, "clicked", _popup_cb, view); - elm_object_part_content_set(popup, "button2", cancel); - evas_object_smart_callback_add(cancel, "clicked", _pop_view, view_mgr); - - ui_view_style_set(view, "popup"); - ui_viewmgr_view_push(view_mgr, view); - - evas_object_smart_callback_add(prev, "clicked", _pop_view, view_mgr); - evas_object_smart_callback_add(next, "clicked", _popup_cb, view); -} - -void -_view4(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Evas_Object *prev, *next, *content; - prev = create_btn("view3", EINA_TRUE, EINA_FALSE); - next = create_btn("Next", EINA_FALSE, EINA_FALSE); - content = create_view("View 4",prev,next,create_content("View 4 Content")); - ui_view *view = ui_view_add(content); - - // set a different style for the view transition - ui_view_style_set(view, "slidein"); - - ui_viewmgr_view_push(view_mgr, view); - evas_object_smart_callback_add(prev, "clicked", _pop_view, view_mgr); - evas_object_smart_callback_add(next, "clicked", _view5, view_mgr); - -} - -void -_view3(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Evas_Object *prev, *next, *content; - prev = create_btn("view2", EINA_TRUE, EINA_FALSE); - next = create_btn("Next", EINA_FALSE, EINA_FALSE); - content = create_view("View 3",prev,next,create_content("View 3 Content")); - ui_view *view = ui_view_add(content); - ui_view_style_set(view, "default"); - ui_viewmgr_view_push(view_mgr, view); - evas_object_smart_callback_add(prev, "clicked", _pop_view, view_mgr); - evas_object_smart_callback_add(next, "clicked", _view4, view_mgr); - -} - -// A callback handler to set the content of view2 -Eina_Bool _load_view2_cb(void *data EINA_UNUSED, ui_view *view , void *event_info EINA_UNUSED) -{ - Evas_Object *prev, *next, *content; - prev = create_btn("view1", EINA_TRUE, EINA_FALSE); - next = create_btn("Next", EINA_FALSE, EINA_FALSE); - content = create_view("View 2",prev,next,create_content("View 2 Content")); - evas_object_smart_callback_add(prev, "clicked", _pop_view, view_mgr); - evas_object_smart_callback_add(next, "clicked", _view3, view_mgr); - ui_view_content_set(view,content); -} - -// Lazy initialization of the content in a view -// if no style is set then default style will be used for view transition -void -_view2(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - ui_view *view = ui_view_add(NULL); - ui_viewmgr_view_push(view_mgr, view); - - // add a callback for the view,load notification - ui_view_event_callback_add(view,"view,load",_load_view2_cb,data); - promote_view = view; -} - -Eina_Bool _key_back_cb(void *data EINA_UNUSED, ui_view *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - // delete the window - // The view manager assosiated with this wind will get deleted automatically. - evas_object_del(window); - return EINA_TRUE; -} - -// The first view on the application -// if user don't want any view animation while app is lunching -// user can set the view style as "noanimation" -void -_view1(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Evas_Object *next, *content; - next = create_btn("Next", EINA_FALSE, EINA_FALSE); - content = create_view("View 1",NULL, next, create_content("View 1 Content")); - ui_view *view = ui_view_add(content); - ui_viewmgr_view_push(view_mgr, view); - - // if we don't want view swithcing animation - ui_view_style_set(view, "noanimation"); - - evas_object_smart_callback_add(next, "clicked", _view2, data); - - // Add a "key,back" callback to handle application close - ui_view_event_callback_add(view, "key,back",_key_back_cb,data); -} - -int -elm_main(int argc, char **argv) -{ - // create a window with background - //window = elm_win_util_standard_add("viewmanager", "ViewMannager"); - window = elm_win_add(NULL, "viewmanager", ELM_WIN_BASIC); - elm_win_autodel_set(window, EINA_TRUE); - - // Create View manager using window as a parent - view_mgr = ui_viewmgr_add(window); - - // add a view to vew manager. - _view1(view_mgr,NULL,NULL); - - evas_object_resize(window, 720, 1280); - elm_win_autodel_set(window, EINA_TRUE); - elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED); - evas_object_show(window); - - elm_run(); - elm_shutdown(); - return 0; -} -ELM_MAIN() diff --git a/src/include/CMakeLists.txt b/src/include/CMakeLists.txt deleted file mode 100644 index b9f586f..0000000 --- a/src/include/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -INSTALL( - DIRECTORY ./ DESTINATION include/${LIB_NAME} - FILES_MATCHING - PATTERN "*_private.h" EXCLUDE - PATTERN "*.h" - ) diff --git a/src/include/ui_view.h b/src/include/ui_view.h deleted file mode 100644 index c77364c..0000000 --- a/src/include/ui_view.h +++ /dev/null @@ -1,117 +0,0 @@ -/** -* @brief, A view is responsible for showing the content on the screen -* How it will be shown on the screen will be decided by the style set on the view. -* Its the view manager's resposibility to show -* the view on screen and to manage the owenership of the view. -* View manager emit the signals corresponding to the state change of the view. -* View takes the explicit ownersip of the content . -* If user wants to take the ownership back it has to do that with content_unset api. -* list of signal emmmited from view -* @li @c "view,load" - When View is about to be shown and the content is null -* -* @li @c "view,unload" - When View is about to destroy. -* -* @li @c "view,appear,start" - When View is about to show on screen, before show transition start. -* -* @li @c "view,appear,finish" - When View is fully shown on screen, after show transition finished. -* -* @li @c "view,disappear,start" - When View is about to disappear from screen, before hide transition start. -* -* @li @c "view,disappear,finish" - When View is fully hidden from screen, after hide transition finish. -* -* @li @c "key,back" - When back key is pressed . -* @li @c "key,more" - When more key is pressed. -* -* List of styel provided in the view , the behaviour will be decided by the ui-viewmgr layout file. -* @li @c "default" - The default transition for the system , and this will be applied if nothing is set. -* @li @c "noanimation" - If the user don't want any transition while showing a view. -* @li @c "slidein" - If the new view need to slidein to the screen when shown. -* @li @c "popup" - If the new view need to shown as a popup on the screen. -*/ - -#ifndef _UI_VIEW_H -#define _UI_VIEW_H - -#include - -typedef struct _ui_view ui_view; - -/** -#include - -typedef struct _ui_viewmgr ui_viewmgr; - -/** -* @brief Add a new view manager to window -* @param window , window object -* @return New ui_viewmgr object on success or @c NULL on failure. -*/ - -EAPI ui_viewmgr *ui_viewmgr_add(Evas_Object *window); - -/** -* @brief Delete the view manager -* ViewManager deletes itself when the associated window gets deleted. -*/ -EAPI void ui_viewmgr_del(ui_viewmgr *view_mgr); - -/** -* @brief Push a view into view manager's view stack -* View Push operation can be customised by setting the style on View. -* @param view_mgr , view maanger object -* @param view , view object to be pushed -* @return EINA_TRUE on sucsess else EINA_FALSE. -*/ -EAPI Eina_Bool ui_viewmgr_view_push(ui_viewmgr *view_mgr, ui_view *view); - -/** -* @brief Insert a view into view manager's view stack with relative to a view -* @param view_mgr , view maanger object -* @param view , view object to be pushed -* @param before , the view before which the new view will be placed in view stack. -* @return EINA_TRUE on sucsess else EINA_FALSE. -*/ -EAPI Eina_Bool ui_viewmgr_view_insert_before(ui_viewmgr *view_mgr, ui_view *before, ui_view *view); - -/** -* @brief Insert a view into view manager's view stack with relative to a view -* @param view_mgr , view maanger object -* @param view , view object to be pushed -* @param after , the relative view after which the new view will be placed in view stack. -* @return EINA_TRUE on sucsess else EINA_FALSE. -*/ -EAPI Eina_Bool ui_viewmgr_view_insert_after(ui_viewmgr *view_mgr, ui_view *after, ui_view *view); - -/** -* @brief Remove the top view from the stack. -* If there is more view on the stack it makes the below view as the top view of the stack -* @ret returns EINA_TRUE if the operation is a success , else EINA_FALSE -*/ - -EAPI Eina_Bool ui_viewmgr_view_pop(ui_viewmgr *view_mgr); - -/** -* @brief Pop to a view on the stack. -* On the process it removes all the view in beteen the top view and the view it pops to. -* It will only do the view transition effect between top view and the view it pops to. -* @param view , view object on the stack to be poped to -* @ret returns EINA_TRUE if the operation is a success , else EINA_FALSE -*/ -EAPI Eina_Bool ui_viewmgr_view_pop_to(ui_viewmgr *view_mgr, ui_view *to_view); - - -/** -* @brief Promote a view to the top of the stack. -* @param view , view object that needs to be brought on th top of the stack -* This operation will happen if the view is present on the stack and not on the top. -* @ret returns EINA_TRUE if the operation is a success , else EINA_FALSE -*/ -EAPI Eina_Bool ui_viewmgr_view_promote(ui_viewmgr *view_mgr, ui_view *view); - -/** -* @brief Get the top view from the view manager -* @ret returns the top view of the view stack , else returns NULL -*/ -EAPI ui_view *ui_viewmgr_top_view_get(const ui_viewmgr *view_mgr); - -/** -* @brief Get the conformant created by view manager -* @ret returns the conformant that internally created by view manager. -*/ -EAPI Evas_Object *ui_viewmgr_conformant_get(const ui_viewmgr *view_mgr); - -#endif //_UI_VIEWMGR_H diff --git a/src/include/ui_viewmgr_private.h b/src/include/ui_viewmgr_private.h deleted file mode 100644 index 7c5f865..0000000 --- a/src/include/ui_viewmgr_private.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef _UI_VIEWMGR_PRIVATE_H -#define _UI_VIEWMGR_PRIVATE_H - -#include -#include -#include "ui_view.h" -#include "ui_viewmgr.h" - -#define LOG_TAG "ui-viewmgr" - - -typedef struct _ui_view_event_callback ui_view_event_callback; - - -static const char SIG_VIEW_LOAD[] = "view,load"; -static const char SIG_VIEW_UNLOAD[] = "view,unload"; -static const char SIG_VIEW_APPEAR_START[] = "view,appear,start"; -static const char SIG_VIEW_APPEAR_FINISH[] = "view,appear,finish"; -static const char SIG_VIEW_DISAPPEAR_START[] = "view,disappear,start"; -static const char SIG_VIEW_DISAPPEAR_FINISH[] = "view,disappear,finish"; -static const char SIG_VIEW_KEY_BACK[] = "key,back"; -static const char SIG_VIEW_KEY_OPTION[] = "key,option"; - - -struct _ui_view_event_callback -{ - const char *event; - ui_view_event_cb func; - void *func_data; - char delete_me : 1; -}; - - -#define VIEW_MGR_CHECK(obj) \ - if (!obj) \ - return - -struct _ui_viewmgr -{ - Eina_List *view_stack; - Evas_Object *window; - Evas_Object *conformant; - Evas_Object *base_layout; - Ecore_Job *animation_job; - Evas_Object *key_grabber; - struct { - ui_view* view_this; - ui_view* view_other; - }anim; - - Eina_Bool animation_ongoing : 1; -}; - -typedef enum _ui_view_state_type -{ - VIEW_SHOWN = 0, - VIEW_HIDDEN, - VIEW_ABOUT_TO_DESTROY, - VIEW_ABOUT_TO_SHOW, - VIEW_ABOUT_TO_HIDE -} ui_view_state_type; - - -struct _ui_view -{ - Eina_List *callbacks; - Evas_Object *content; - const char *style; - - ui_view_state_type current_state; - ui_view_state_type previous_state; - -}; - - -#define VIEW_CHECK(obj) \ - if (!obj) \ - return - -static inline void -_ui_view_state_set(ui_view *view, ui_view_state_type state) -{ - VIEW_CHECK(view); - view->previous_state = view->current_state; - view->current_state = state; -} - -static inline ui_view_state_type -_ui_view_state_get(ui_view *view) -{ - VIEW_CHECK(view) VIEW_ABOUT_TO_DESTROY; - return view->current_state; -} - -static inline ui_view_state_type -_ui_view_prev_state_get(ui_view *view) -{ - VIEW_CHECK(view) VIEW_ABOUT_TO_DESTROY; - return view->previous_state; -} - -static inline Eina_Bool -_ui_view_event_callback_call(ui_view *view, const char *event, void *event_info) -{ - Eina_List *l; - ui_view_event_callback *cb; - const char *strshare; - - VIEW_CHECK(view) EINA_FALSE; - if (!event) return EINA_FALSE; - - strshare = eina_stringshare_add(event); - EINA_LIST_FOREACH(view->callbacks, l, cb) { - if (!cb->delete_me) { - if (cb->event == strshare) { - eina_stringshare_del(strshare); - return cb->func(cb->func_data, view, event_info); - } - } - } - eina_stringshare_del(strshare); - return EINA_FALSE; -} - -#endif //_UI_VIEWMGR_PRIVATE_H diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt deleted file mode 100644 index 2a04ae4..0000000 --- a/src/lib/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -SET(LIB_SRCS - ui_view.c - ui_viewmgr.c) - -ADD_LIBRARY(${LIB_NAME} SHARED ${LIB_SRCS}) - -ADD_DEFINITIONS("-DEXPORT_API=__attribute__((visibility(\"default\")))") -PKG_CHECK_MODULES(LIB_PKGS REQUIRED elementary edje dlog) - -FOREACH(flag ${LIB_PKGS_CFLAGS}) - SET(LIB_CFLAGS "${LIB_CFLAGS} ${flag}") -ENDFOREACH(flag) - -SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES COMPILE_FLAGS "${LIB_CFLAGS}") -SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES VERSION ${VERSION}) -SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR}) -TARGET_LINK_LIBRARIES(${LIB_NAME} ${LIB_PKGS_LDFLAGS} ${LIB_TARGET_PKGS_LDFLAGS}) - -INSTALL(TARGETS ${LIB_NAME} DESTINATION lib) diff --git a/src/lib/ui_view.c b/src/lib/ui_view.c deleted file mode 100644 index 0803184..0000000 --- a/src/lib/ui_view.c +++ /dev/null @@ -1,122 +0,0 @@ -#include "ui_viewmgr_private.h" -#include "ui_view.h" - -EAPI ui_view * -ui_view_add(Evas_Object *content) -{ - ui_view *view = calloc(1, sizeof(ui_view)); - if(!view) - return NULL; - - view->content = content; - view->style = eina_stringshare_add("default"); - view->current_state = VIEW_ABOUT_TO_SHOW; - view->previous_state = VIEW_ABOUT_TO_SHOW; - return view; -} - -EAPI void -ui_view_del(ui_view *view) -{ - VIEW_CHECK(view); - ui_view_event_callback *cb; - - if(view->content) - evas_object_del(view->content); - - EINA_LIST_FREE(view->callbacks,cb) { - eina_stringshare_del(cb->event); - free(cb); - } - - eina_stringshare_del(view->style); - - free(view); -} - -EAPI Eina_Bool -ui_view_content_set(ui_view *view, Evas_Object *content) -{ - VIEW_CHECK(view) EINA_FALSE; - // if same content - if(view->content == content) - return EINA_TRUE; - - // if already content exists delete it - if(view->content) - evas_object_del(view->content); - - // update the new content - view->content = content; - - return EINA_TRUE; -} - -EAPI Evas_Object * -ui_view_content_unset(ui_view *view) -{ - Evas_Object *content; - - VIEW_CHECK(view) NULL; - content = view->content; - view->content = NULL; - - return content; -} - -EAPI Evas_Object * -ui_view_content_get(ui_view *view) -{ - VIEW_CHECK(view) NULL; - return view->content; -} - -EAPI void -ui_view_style_set(ui_view* view, const char *style) -{ - VIEW_CHECK(view); - eina_stringshare_replace(&view->style,style); -} - -EAPI const char * -ui_view_style_get(ui_view* view) -{ - VIEW_CHECK(view) ""; - return view->style; -} - -EAPI void -ui_view_event_callback_add(ui_view *view, const char *event, ui_view_event_cb func, const void *data) -{ - ui_view_event_callback *cb; - VIEW_CHECK(view); - if (!event) return; - if (!func) return; - cb = calloc(1,sizeof(ui_view_event_callback)); - cb->event = eina_stringshare_add(event); - cb->func = func; - cb->func_data = (void *)data; - view->callbacks = eina_list_append(view->callbacks,cb); -} - -EAPI void * -ui_view_event_callback_del(ui_view *view, const char *event, ui_view_event_cb func) -{ - Eina_List *l; - ui_view_event_callback *cb; - - VIEW_CHECK(view) NULL; - if (!event) return NULL; - if (!func) return NULL; - - EINA_LIST_FOREACH(view->callbacks, l, cb) { - if ((!strcmp(cb->event, event)) && (cb->func == func)) { - void *data; - - data = cb->func_data; - cb->delete_me = 1; - return data; - } - } - return NULL; -} diff --git a/src/lib/ui_viewmgr.c b/src/lib/ui_viewmgr.c deleted file mode 100644 index b4d8b84..0000000 --- a/src/lib/ui_viewmgr.c +++ /dev/null @@ -1,482 +0,0 @@ -#include "ui_viewmgr.h" -#include "ui_view.h" -#include "ui_viewmgr_private.h" -#include "utilX.h" - -//@TODO, Currently the view manager can only show -// two overlay views visible on the screen . to show any number of overlay views -// simultaneously visible on the screen we need some kind of stack layout. -// elm_grid can be used to simulate a stack layout , but currently it has soem issue -// which prevents us to use it. So as a future work we need to integrate the elm_grid -// as a stack layout to show any number of overlay views simultaneously visible on the -// screen. - -static Evas_Object * -_create_conformant(Evas_Object *parent) -{ - Evas_Object *conform; - - if (parent == NULL) return NULL; - - conform = elm_conformant_add(parent); - evas_object_size_hint_weight_set(conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - elm_win_resize_object_add(parent, conform); - evas_object_show(conform); - - return conform; -} - -static Evas_Object * -_create_layout(Evas_Object *parent, const char *style) -{ - Evas_Object *layout; - char group[100] = {0}; - - // create a layout using given style - layout = elm_layout_add(parent); - snprintf(group, sizeof(group), "layout/viewmgr/%s", style); - elm_layout_file_set(layout, "/usr/share/edje/ui-viewmgr/ui-viewmgr.edj", group); - return layout; -} - -static void -_appear_finished_cb(void *data, Evas_Object *obj , const char *emission EINA_UNUSED, const char *source EINA_UNUSED) -{ - ui_viewmgr *view_mgr = data; - - _ui_view_state_set(view_mgr->anim.view_this, VIEW_SHOWN); - _ui_view_state_set(view_mgr->anim.view_other, VIEW_HIDDEN); - - _ui_view_event_callback_call(view_mgr->anim.view_this, SIG_VIEW_APPEAR_FINISH, ""); - _ui_view_event_callback_call(view_mgr->anim.view_other, SIG_VIEW_DISAPPEAR_FINISH, ""); - - elm_object_part_content_set(view_mgr->base_layout, "swallow.back", obj); - - evas_object_freeze_events_set(elm_object_part_content_get(obj, "swallow.view.this"), EINA_FALSE); - - view_mgr->anim.view_this = NULL; - view_mgr->anim.view_other = NULL; - view_mgr->animation_ongoing = EINA_FALSE; -} - -static void -_disappear_finished_cb(void *data, Evas_Object *obj, const char *emission EINA_UNUSED, const char *source EINA_UNUSED) -{ - ui_viewmgr *view_mgr = data; - - _ui_view_state_set(view_mgr->anim.view_this, VIEW_HIDDEN); - _ui_view_state_set(view_mgr->anim.view_other, VIEW_SHOWN); - - _ui_view_event_callback_call(view_mgr->anim.view_this, SIG_VIEW_DISAPPEAR_FINISH, ""); - _ui_view_event_callback_call(view_mgr->anim.view_other, SIG_VIEW_APPEAR_FINISH, ""); - - elm_object_part_content_set(view_mgr->base_layout, "swallow.back", obj); - - // notify the view deletion - _ui_view_event_callback_call(view_mgr->anim.view_this,SIG_VIEW_UNLOAD,""); - - evas_object_freeze_events_set(elm_object_part_content_get(obj, "swallow.view.this"), EINA_FALSE); - evas_object_freeze_events_set(elm_object_part_content_get(obj, "swallow.view.other"), EINA_FALSE); - - //destroy the view - // remove it from the view stack - view_mgr->view_stack = eina_list_remove(view_mgr->view_stack, view_mgr->anim.view_this); - elm_object_part_content_unset(obj,"swallow.view.this"); - ui_view_del(view_mgr->anim.view_this); - - view_mgr->anim.view_this = NULL; - view_mgr->anim.view_other = NULL; - view_mgr->animation_ongoing = EINA_FALSE; - -} - -static void -_delete_layout(Evas_Object* layout) -{ - Evas_Object *content; - if(layout) { - content = elm_object_part_content_unset(layout, "swallow.view.this"); - if(content) - evas_object_hide(content); - content = elm_object_part_content_unset(layout, "swallow.view.other"); - if(content) - evas_object_hide(content); - evas_object_del(layout); - } -} - -static void -_appear_effect(ui_viewmgr* view_mgr) -{ - Evas_Object *layout; - layout = _create_layout(view_mgr->base_layout, ui_view_style_get(view_mgr->anim.view_this)); - elm_object_part_content_set(view_mgr->base_layout, "swallow.front", layout); - evas_object_show(layout); - - // setup for view_this - if(!ui_view_content_get(view_mgr->anim.view_this) || (_ui_view_prev_state_get(view_mgr->anim.view_this) == VIEW_ABOUT_TO_SHOW)) { - _ui_view_event_callback_call(view_mgr->anim.view_this,SIG_VIEW_LOAD, ""); - } - - if(ui_view_content_get(view_mgr->anim.view_this)) { - evas_object_freeze_events_set(ui_view_content_get(view_mgr->anim.view_this), EINA_TRUE); - elm_object_part_content_set(layout,"swallow.view.this", ui_view_content_get(view_mgr->anim.view_this)); - } - _ui_view_event_callback_call(view_mgr->anim.view_this, SIG_VIEW_APPEAR_START,""); - - // setup for view_other - if(view_mgr->anim.view_other) { - if(ui_view_content_get(view_mgr->anim.view_other)) { - elm_object_part_content_set(layout, "swallow.view.other", ui_view_content_get(view_mgr->anim.view_other)); - evas_object_freeze_events_set(ui_view_content_get(view_mgr->anim.view_other), EINA_TRUE); - } - _ui_view_event_callback_call(view_mgr->anim.view_other, SIG_VIEW_DISAPPEAR_START, ""); - } - - // delete old layout if any - _delete_layout(elm_object_part_content_get(view_mgr->base_layout, "swallow.back")); - - // start the animation - elm_object_signal_emit(layout, "appear,effect", "elm"); - elm_object_signal_callback_add(layout, "appear,effect,finished", "*", _appear_finished_cb, view_mgr); -} - -static void -_disappear_effect(ui_viewmgr* view_mgr) -{ - Evas_Object *layout; - layout = _create_layout(view_mgr->base_layout, ui_view_style_get(view_mgr->anim.view_this)); - elm_object_part_content_set(view_mgr->base_layout, "swallow.front", layout); - evas_object_show(layout); - - // setup for view_this - elm_object_part_content_set(layout,"swallow.view.this", ui_view_content_get(view_mgr->anim.view_this)); - _ui_view_event_callback_call(view_mgr->anim.view_this, SIG_VIEW_DISAPPEAR_START, ""); - - // setup for view_other - elm_object_part_content_set(layout,"swallow.view.other", ui_view_content_get(view_mgr->anim.view_other)); - if((!ui_view_content_get(view_mgr->anim.view_other)) || (_ui_view_state_get(view_mgr->anim.view_other) == VIEW_ABOUT_TO_SHOW)) { - _ui_view_event_callback_call(view_mgr->anim.view_other, SIG_VIEW_LOAD, ""); - } - _ui_view_event_callback_call(view_mgr->anim.view_other, SIG_VIEW_APPEAR_START, ""); - - evas_object_freeze_events_set(ui_view_content_get(view_mgr->anim.view_this), EINA_TRUE); - evas_object_freeze_events_set(ui_view_content_get(view_mgr->anim.view_other), EINA_TRUE); - - // delete old layout if any - _delete_layout(elm_object_part_content_get(view_mgr->base_layout, "swallow.back")); - - // start the animation - elm_object_signal_emit(layout, "disappear,effect", "elm"); - elm_object_signal_callback_add(layout, "disappear,effect,finished", "*", _disappear_finished_cb, view_mgr); -} - -static void -_animation_cb(void *data) -{ - ui_view *view; - Eina_List *l; - ui_viewmgr *view_mgr = data; - view_mgr->animation_job = NULL; - - if(view_mgr->animation_ongoing) { - view_mgr->animation_job = ecore_job_add(_animation_cb, view_mgr); - return; - } else { - view_mgr->animation_ongoing = EINA_TRUE; - } - - view_mgr->anim.view_this = eina_list_data_get(eina_list_last(view_mgr->view_stack)); - - if(_ui_view_state_get(view_mgr->anim.view_this) == VIEW_ABOUT_TO_SHOW) { // Appear case - EINA_LIST_REVERSE_FOREACH(view_mgr->view_stack, l, view) { - if (_ui_view_state_get(view) == VIEW_SHOWN) { - // this is our other view - view_mgr->anim.view_other = view; - break; - } - } - _appear_effect(view_mgr); - } - - if(_ui_view_state_get(view_mgr->anim.view_this) == VIEW_ABOUT_TO_HIDE) { // Disappear case - EINA_LIST_REVERSE_FOREACH(view_mgr->view_stack, l, view) { - ui_view_state_type type = _ui_view_state_get(view); - if ( (type == VIEW_HIDDEN) || (type == VIEW_ABOUT_TO_SHOW)) { - // this is our other view - view_mgr->anim.view_other = view; - break; - } - } - if(view_mgr->anim.view_other) - _disappear_effect(view_mgr); - } -} - -static void -_key_grabber_key_up_cb(void *data, Evas *e, Evas_Object *obj, - void *event_info) -{ - Evas_Event_Key_Down *ev = event_info; - ui_viewmgr *view_mgr = data; - - if (!strcmp(ev->keyname, KEY_BACK)) { - // send the signal to current view - ui_view *top_view = ui_viewmgr_top_view_get(view_mgr); - if(top_view && (_ui_view_state_get(top_view) == VIEW_SHOWN)) { - Eina_Bool handled = _ui_view_event_callback_call(top_view, SIG_VIEW_KEY_BACK, ev->keyname); - if(!handled) { - ui_viewmgr_view_pop(view_mgr); - } - } - - } else if(!strcmp(ev->keyname, KEY_SEND)) { - // send the signal to current view - ui_view *top_view = ui_viewmgr_top_view_get(view_mgr); - if(top_view && (_ui_view_state_get(top_view) == VIEW_SHOWN)) - _ui_view_event_callback_call(top_view, SIG_VIEW_KEY_OPTION, ev->keyname); - } else { - return; - } -} - -static Eina_Bool -_init_key_grabber(ui_viewmgr *view_mgr) -{ - // initialize key grabber. - view_mgr->key_grabber = evas_object_rectangle_add(evas_object_evas_get(view_mgr->window)); - - evas_object_event_callback_add(view_mgr->key_grabber, EVAS_CALLBACK_KEY_UP, - _key_grabber_key_up_cb, view_mgr); - - if (!evas_object_key_grab(view_mgr->key_grabber, KEY_SEND, 0, 0, EINA_FALSE)) - return EINA_FALSE; - if(!evas_object_key_grab(view_mgr->key_grabber, KEY_BACK, 0, 0, EINA_FALSE)) - return EINA_FALSE; - - return EINA_TRUE; -} - -void -_window_delete_cb(void *data, Evas* e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - ui_viewmgr *viewmgr = data; - ui_viewmgr_del(viewmgr); -} - -void -ui_viewmgr_del(ui_viewmgr *view_mgr) -{ - ui_view *view; - VIEW_MGR_CHECK(view_mgr); - EINA_LIST_FREE(view_mgr->view_stack, view) - { - _ui_view_event_callback_call(view, SIG_VIEW_UNLOAD, ""); - ui_view_del(view); - } - -} - -EAPI ui_viewmgr * -ui_viewmgr_add(Evas_Object *window) -{ - if(!window) - return NULL; - if (!evas_object_smart_type_check(window, "elm_win")) - return NULL; - - // check wheather window has any view manager. - if(evas_object_data_get(window, "viewmgr")) - return NULL; - - ui_viewmgr *view_mgr = calloc(1, sizeof(ui_viewmgr)); - if(!view_mgr) - { - return NULL; - } - view_mgr->window = window; - // Add a callback for window deletion notification. - evas_object_event_callback_add(view_mgr->window, EVAS_CALLBACK_DEL, _window_delete_cb, view_mgr); - - //create conformant - //@TODO future work, create conformant based on configuration. - view_mgr->conformant = _create_conformant(window); - elm_win_indicator_mode_set(view_mgr->window, ELM_WIN_INDICATOR_SHOW); - - view_mgr->base_layout = _create_layout(view_mgr->conformant, "baselayout"); - evas_object_size_hint_weight_set(view_mgr->base_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - elm_object_part_content_set(view_mgr->conformant, "elm.swallow.content", view_mgr->base_layout); - - _init_key_grabber(view_mgr); - - // update the window regarding view manager - evas_object_data_set(window,"viewmgr", view_mgr); - - return view_mgr; -} - - -EAPI Eina_Bool -ui_viewmgr_view_push(ui_viewmgr *view_mgr, ui_view *view) -{ - - VIEW_MGR_CHECK(view_mgr) EINA_FALSE; - - if(!view) // check for invalid view - return EINA_FALSE; - - _ui_view_state_set(view, VIEW_ABOUT_TO_SHOW); - // append to the stack - view_mgr->view_stack = eina_list_append(view_mgr->view_stack, view); - - if(!view_mgr->animation_job) - view_mgr->animation_job = ecore_job_add(_animation_cb, view_mgr); - - return EINA_TRUE; - -} - -EAPI Eina_Bool -ui_viewmgr_view_promote(ui_viewmgr *view_mgr, ui_view *view) -{ - VIEW_MGR_CHECK(view_mgr) EINA_FALSE; - - if(!view) // check for invalid view - return EINA_FALSE; - if(!view_mgr->view_stack) - return EINA_FALSE; - if(eina_list_data_find(view_mgr->view_stack, view)) { // view is on the stack - if (ui_viewmgr_top_view_get(view_mgr) == view) // already on top - return EINA_TRUE; - // remove the view from the stack. - view_mgr->view_stack = eina_list_remove(view_mgr->view_stack, view); - - return ui_viewmgr_view_push(view_mgr, view); - } - - return EINA_FALSE; -} - -EAPI Eina_Bool -ui_viewmgr_view_insert_before(ui_viewmgr *view_mgr, ui_view *before, ui_view *view) -{ - VIEW_MGR_CHECK(view_mgr) EINA_FALSE; - - if(!view) // check for invalid view - return EINA_FALSE; - if(!before) - return EINA_FALSE; - - if(eina_list_data_find(view_mgr->view_stack, view)) { // view is already on stack - if(ui_viewmgr_top_view_get(view_mgr) == view) // if its the top view do nothing - return EINA_FALSE; - eina_list_remove(view_mgr->view_stack, view); - - } else { - _ui_view_state_set(view, VIEW_ABOUT_TO_SHOW); - } - view_mgr->view_stack = eina_list_prepend_relative(view_mgr->view_stack, view, before); - return EINA_TRUE; - -} - -EAPI Eina_Bool -ui_viewmgr_view_insert_after(ui_viewmgr *view_mgr, ui_view *after, ui_view *view) -{ - VIEW_MGR_CHECK(view_mgr) EINA_FALSE; - - if(!view) // check for invalid view - return EINA_FALSE; - if(!after) - return EINA_FALSE; - - if(eina_list_data_find(view_mgr->view_stack, view)) { // view is already on stack - if(ui_viewmgr_top_view_get(view_mgr) == view) // if its the top view do nothing - return EINA_FALSE; - eina_list_remove(view_mgr->view_stack, view); - - } else { - _ui_view_state_set(view, VIEW_ABOUT_TO_SHOW); - } - - if (ui_viewmgr_top_view_get(view_mgr) == after) - return ui_viewmgr_view_push(view_mgr, view); - - view_mgr->view_stack = eina_list_append_relative(view_mgr->view_stack, view, after); - return EINA_TRUE; - -} - -EAPI Eina_Bool -ui_viewmgr_view_pop(ui_viewmgr *view_mgr) -{ - ui_view *top_view; - - VIEW_MGR_CHECK(view_mgr) EINA_FALSE; - - // get the current view that is on top of the stack. - top_view = ui_viewmgr_top_view_get(view_mgr); - - if(!top_view || (eina_list_count(view_mgr->view_stack) == 1)) - return EINA_FALSE; - - _ui_view_state_set(top_view, VIEW_ABOUT_TO_HIDE); - - if(!view_mgr->animation_job) - view_mgr->animation_job = ecore_job_add(_animation_cb, view_mgr); - - return EINA_TRUE; - -} - -EAPI Eina_Bool -ui_viewmgr_view_pop_to(ui_viewmgr *view_mgr, ui_view *to_view) -{ - ui_view *top_view, *view = NULL; - Eina_List *sublist, *l, *l_next; - - VIEW_MGR_CHECK(view_mgr) EINA_FALSE; - if(!view_mgr->view_stack) return EINA_FALSE; - - top_view = ui_viewmgr_top_view_get(view_mgr); - if(!top_view) return EINA_FALSE; - - if(top_view == to_view) return EINA_FALSE; - - // check if the view is present in the stack - sublist = eina_list_data_find_list(view_mgr->view_stack, to_view); - if(!sublist) return EINA_FALSE; - sublist = eina_list_next(sublist); - if(!sublist) return EINA_FALSE; - - EINA_LIST_FOREACH_SAFE(sublist,l,l_next,view) { - if(view != top_view) { - _ui_view_event_callback_call(view_mgr->anim.view_this, SIG_VIEW_UNLOAD,""); - ui_view_del(view); - sublist = eina_list_remove_list(sublist, l); - } - } - - _ui_view_state_set(top_view,VIEW_ABOUT_TO_HIDE); - - if(!view_mgr->animation_job) - view_mgr->animation_job = ecore_job_add(_animation_cb, view_mgr); - - return EINA_TRUE; -} - -EAPI ui_view * -ui_viewmgr_top_view_get(const ui_viewmgr *view_mgr) -{ - VIEW_MGR_CHECK(view_mgr) NULL; - if (!view_mgr->view_stack) return NULL; - - return eina_list_data_get(eina_list_last(view_mgr->view_stack)); -} - -EAPI Evas_Object * -ui_viewmgr_conformant_get(const ui_viewmgr *view_mgr) -{ - VIEW_MGR_CHECK(view_mgr) NULL; - return view_mgr->conformant; -} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..fc398f5 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 "main.h" +#include "app_controller.h" + +static void create_base_gui(appdata_s *ad) +{ + ad->viewmgr = new ui_viewmgr(PACKAGE); + + //View 1 + { + app_controller1 *controller = new app_controller1(ad); + ad->viewmgr->push_view(new ui_basic_view(controller)); + } +/* + //View 2 + { + app_controller2 *controller = new app_controller2(ad); + ad->viewmgr->push_view(new ui_basic_view(controller)); + } + + //View 3 + { + app_controller3 *controller = new app_controller3(ad); + ad->viewmgr->push_view(new ui_view(controller)); + } + //View 4 + { + app_controller4 *controller = new app_controller4(); + ui_basic_view *view = ad->viewmgr->push_view(new ui_basic_view(controller)); + } +*/ + ad->viewmgr->activate(); +} + +static bool app_create(void *data) +{ + /* Hook to take necessary actions before main event loop starts + Initialize UI resources and application's data + If this function returns true, the main loop of application starts + If this function returns false, the application is terminated */ + appdata_s *ad = (appdata_s *) data; + + elm_app_base_scale_set(2.6); + + /* Bind package locale file */ + bindtextdomain(PACKAGE, LOCALE_DIR); + textdomain(PACKAGE); + + create_base_gui(ad); + + return true; +} + +static void app_control(app_control_h app_control, void *data) +{ + /* Handle the launch request. */ +} + +static void app_pause(void *data) +{ +} + +static void app_resume(void *data) +{ +} + +static void app_terminate(void *data) +{ +} + +static void ui_app_lang_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LANGUAGE_CHANGED*/ + char *locale = NULL; + system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &locale); + elm_language_set(locale); + free(locale); + return; +} + +static void ui_app_orient_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_DEVICE_ORIENTATION_CHANGED*/ + return; +} + +static void ui_app_region_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_REGION_FORMAT_CHANGED*/ +} + +static void ui_app_low_battery(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LOW_BATTERY*/ +} + +static void ui_app_low_memory(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LOW_MEMORY*/ +} + +int main(int argc, char *argv[]) +{ + appdata_s ad = { 0, }; + int ret = 0; + + ui_app_lifecycle_callback_s event_callback = { 0, }; + app_event_handler_h handlers[5] = { NULL, }; + + event_callback.create = app_create; + event_callback.terminate = app_terminate; + event_callback.pause = app_pause; + event_callback.resume = app_resume; + event_callback.app_control = app_control; + + ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, ui_app_low_battery, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, ui_app_low_memory, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, + ui_app_orient_changed, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, ui_app_lang_changed, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, + &ad); + ui_app_remove_event_handler(handlers[APP_EVENT_LOW_MEMORY]); + + ret = ui_app_main(argc, argv, &event_callback, &ad); + if (ret != APP_ERROR_NONE) + { + dlog_print(DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret); + } + + return ret; +} diff --git a/src/ui_basic_view.cpp b/src/ui_basic_view.cpp new file mode 100644 index 0000000..dbe09c5 --- /dev/null +++ b/src/ui_basic_view.cpp @@ -0,0 +1,125 @@ +#include +#include "ui_basic_view.h" +#include "ui_viewmgr.h" + +using namespace efl; + +bool ui_basic_view::destroy_layout() +{ + if (!this->layout) return false; + if (this->get_content()) + { + elm_object_part_content_unset(this->layout, "elm.swallow.content"); + } + evas_object_del(this->layout); + + return true; +} + +bool ui_basic_view::create_layout() +{ + ui_viewmgr *viewmgr = dynamic_cast(ui_view_base::get_viewmgr()); + Evas_Object *parent = viewmgr->get_window(); + + Evas_Object *layout = elm_layout_add(parent); + if (!layout) + { + LOGE("Failed to create a layout = ui_basic_view(%p)", this); + return false; + } + + if (!elm_layout_theme_set(layout, "layout", "tizen_view", "default")) + { + LOGE("Failed to set theme = ui_basic_view(%p)", this); + evas_object_del(layout); + return false; + } + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL); + + if (this->get_content()) + { + elm_object_part_content_set(layout, "elm.swallow.content", CONVERT_TO_EO(this->get_content())); + } + + this->layout = layout; + + return true; +} + +ui_basic_view::ui_basic_view(ui_controller *controller) : + ui_view(controller), layout(NULL) +{ +} + +ui_basic_view::~ui_basic_view() +{ + destroy_layout(); +} + +void ui_basic_view::load() +{ + this->create_layout(); + ui_view::load(); +} + +void ui_basic_view ::unload() +{ + this->destroy_layout(); + ui_view::unload(); +} + +Evas_Object * +ui_basic_view::set_content(Evas_Object *content) +{ + Evas_Object *pcontent = ui_view::set_content(content); + + if (this->layout) + { + elm_object_part_content_unset(this->layout, "elm.swallow.content"); + elm_object_part_content_set(this->layout, "elm.swallow.content", content); + } + else + { + LOGE("Layout is not exist!"); + } + + return pcontent; +} + + +Evas_Object * +ui_basic_view::set_content(Evas_Object *content, const char *title, const char *subtitle, Evas_Object *title_left_btn, Evas_Object *title_right_btn) +{ + + Evas_Object *pcontent = this->set_content(content); + + if (this->layout) + { + if (title) elm_object_part_text_set(this->layout, "elm.text.title", title); + if (subtitle) elm_object_part_text_set(this->layout, "elm.text.subtitle", subtitle); + if (title_left_btn) + { + elm_object_style_set(title_left_btn, "naviframe/title_left"); + //FIXME: + //elm_object_style_set(title_left_btn, "tizen_view/title_left"); + elm_object_part_content_set(this->layout, "title_left_btn", title_left_btn); + } + if (title_right_btn) + { + LOGE("AHHHHHHHHHHHHH"); + elm_object_style_set(title_right_btn, "naviframe/title_right"); + //FIXME: + //elm_object_style_set(title_left_btn, "tizen_view/title_right"); + elm_object_part_content_set(this->layout, "title_right_btn", title_right_btn); + } + } + else + { + LOGE("Layout is not exist!"); + } + + return pcontent; +} + + diff --git a/src/ui_basic_view.h b/src/ui_basic_view.h new file mode 100644 index 0000000..4f096fd --- /dev/null +++ b/src/ui_basic_view.h @@ -0,0 +1,35 @@ +#ifndef UI_BASIC_VIEW +#define UI_BASIC_VIEW + +#include "ui_view.h" + +namespace efl +{ + +class ui_basic_view: public ui_view +{ +private: + Evas_Object *layout; //Base layout for view + bool create_layout(); + bool destroy_layout(); + +protected: + void load(); + void unload(); + +public: + ui_basic_view(ui_controller *controller); + virtual ~ui_basic_view(); + + Evas_Object *get_base() + { + return this->layout; + } + + Evas_Object *set_content(Evas_Object *content); + Evas_Object *set_content(Evas_Object *content, const char *title, const char *subtitle = NULL, Evas_Object *title_left_btn = NULL, Evas_Object *title_right_btn = NULL); +}; + +} + +#endif /* UI_BASIC_VIEW */ diff --git a/src/ui_controller.cpp b/src/ui_controller.cpp new file mode 100644 index 0000000..035e38f --- /dev/null +++ b/src/ui_controller.cpp @@ -0,0 +1,18 @@ +#include +#include "ui_view.h" +#include "ui_controller.h" + +using namespace efl; + +ui_view * +ui_controller::get_view() +{ + ui_view_base *view = ui_controller_base::get_view(); + if (!view) + { + LOGI("view ahhhhh =%p", view); + return NULL; + } + LOGI("view =%p", view); + return dynamic_cast(view); +} diff --git a/src/ui_controller.h b/src/ui_controller.h new file mode 100644 index 0000000..ecc1324 --- /dev/null +++ b/src/ui_controller.h @@ -0,0 +1,50 @@ +#ifndef UI_CONTROLLER +#define UI_CONTROLLER + +#include +#include +#include "ui_controller_base.h" +#include "ui_view.h" + +namespace efl +{ +class ui_controller: public ui_controller_base +{ +public: + virtual ~ui_controller() + { + } + + virtual void load() + { + } + + virtual void unload() + { + } + + virtual void active() + { + } + + virtual void inactive() + { + } + + virtual void pause() + { + } + + virtual void resume() + { + } + + virtual void destroy() + { + } + + ui_view *get_view(); +}; +} + +#endif /* UI_CONTROLLER_H */ diff --git a/src/ui_controller_base.cpp b/src/ui_controller_base.cpp new file mode 100644 index 0000000..900510e --- /dev/null +++ b/src/ui_controller_base.cpp @@ -0,0 +1,13 @@ +#include +#include "ui_view_base.h" +#include "ui_controller_base.h" + +void ui_controller_base::set_view(ui_view_base *view) +{ + if (this->view) + { + //TODO: ? + } + LOGI("view =%p", view); + this->view = view; +} diff --git a/src/ui_controller_base.h b/src/ui_controller_base.h new file mode 100644 index 0000000..352dd31 --- /dev/null +++ b/src/ui_controller_base.h @@ -0,0 +1,106 @@ +/* + * ui_controller_base.h + * + * Created on: Jan 15, 2016 + * Author: Hermet Park + */ + +#ifndef UI_CONTROLLER_BASE_H_ +#define UI_CONTROLLER_BASE_H_ + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "VIEWMGR" + +class ui_view_base; + +/** + * @class ui_controller_base + * + * @ingroup ui_viewmgr + * + * @brief UI Controller Interface. This interface is designed for handling of life-cycle events from user side. + * + * @date 2016/01/15 + * @author Hermet Park + * + */ +class ui_controller_base +{ +private: + ui_view_base *view; + +public: + ui_controller_base() : + view(NULL) + { + } + virtual ~ui_controller_base() + { + } + + /** @brief load callback + * + * @note Now, this view is moving onto the screen. Get ready for this view. If this view content is alive, load callback won't be called. + * In the most cases, this callback will be triggered with this step load -> inactive -> active. + */ + virtual void load() = 0; + + /** @brief unload callback + * + * @note Remove resources with regards to this view for saving memory or keep the content for performance. It's up to your scenario. + * Unload will be called just right before when the view is going to be deleted by popping or it's piled under the more than one view. + * If the view content is not alive, the unload won't be called. + * In the most cases, this callback will be triggered with this step. inactive -> unload -> destroy + */ + virtual void unload() = 0; + + /** @brief active callback + * + * @note View is on active state after show transition is finished. + * From whatever the state, if the view is on the screen, the active callback will be called. + * In the most cases, this callback will be triggered with this step. load -> inactive -> active + */ + virtual void active() = 0; + + /** @brief inactive callback + * + * @note View is on inactive state. Get ready for unload. Hide transition may be triggered at this point. + * Inactive state is triggered on this scenario that the view is still visible but it's not interactive with users. + * In the most cases, when view is going to be popped or destroyed or pushed one more depth, the inactive state will be triggered. + * Some UI controls such as a center popup or a menu popup blocks the view, this view may be inactive but still visible in someway (with transparency) + */ + virtual void inactive() = 0; + + /** @brief pause callback + * + * @note When the system blocks the application running in cases such as phone call, system notification, switching applications ... + * When Window turns to deactivate. (@see ui_viewmgr_base :: deactivate()) + * If the view were inactive or unload state, the pause won't be called. + */ + virtual void pause() = 0; + + /** @brief resume callback + * + * @note View is turning back to the active state again from pause. + * When the system allows the application turns to activate. + * When the Window turns to activate. (@see ui_viewmgr_base :: activate()) + */ + virtual void resume() = 0; + + /** @brief destroy callback + * + * @note When this view is on destroying by popping or deleting. + */ + virtual void destroy() = 0; + + void set_view(ui_view_base *view); + + ui_view_base *get_view() + { + return this->view; + } +}; + +#endif /* UI_CONTROLLER_BASE_H_ */ diff --git a/src/ui_view.cpp b/src/ui_view.cpp new file mode 100644 index 0000000..113f45d --- /dev/null +++ b/src/ui_view.cpp @@ -0,0 +1,37 @@ +#include "ui_view.h" +#include "ui_controller.h" +#include "ui_viewmgr.h" + +using namespace efl; + +ui_view::ui_view(ui_controller *controller) : + ui_view_base(controller) +{ +} + +ui_view::~ui_view() +{ +} + +Evas_Object * +ui_view::set_content(Evas_Object *content) +{ + T pcontent = ui_view_base::set_content(CONVERT_TO_T(content)); + return static_cast(pcontent); +} + +Evas_Object * +ui_view::get_base() +{ + ui_viewmgr *viewmgr = dynamic_cast(ui_view_base::get_viewmgr()); + if (!viewmgr) + { + return NULL; + } + return viewmgr->get_base_layout(); +} + +void ui_view::load() +{ + ui_view_base::load(); +} diff --git a/src/ui_view.h b/src/ui_view.h new file mode 100644 index 0000000..879f810 --- /dev/null +++ b/src/ui_view.h @@ -0,0 +1,40 @@ +#ifndef UI_VIEW +#define UI_VIEW + +#include +#include "ui_view_base.h" + +#define CONVERT_TO_EO(T) static_cast((T)) +#define CONVERT_TO_T(EO) static_cast((EO)) + +namespace efl +{ +class ui_controller; + +class ui_view: public ui_view_base +{ +public: + ui_view(ui_controller *controller); + virtual ~ui_view(); + + virtual Evas_Object *set_content(Evas_Object *content); + //virtual Evas_Object *set_content(Evas_Object *content, const char *title); + virtual Evas_Object *get_base(); + +protected: + virtual void load(); + + /* protected: + + virtual void set_event_block(bool block) + { + //TO DO: Implement below to proper way. + //if (block) + // evas_object_freeze_events_set(elm_object_part_content_get(this->content, "swallow.view.this"), EINA_FALSE); + //else + // evas_object_freeze_events_set(ui_view_content_get(view_mgr->anim.view_this), EINA_TRUE); + } */ +}; +} + +#endif /* UI_VIEW */ diff --git a/src/ui_view_base.cpp b/src/ui_view_base.cpp new file mode 100644 index 0000000..ae5fb07 --- /dev/null +++ b/src/ui_view_base.cpp @@ -0,0 +1,125 @@ +#include +#include "ui_controller.h" +#include "ui_viewmgr.h" +#include "ui_view_base.h" + +using namespace efl; + +void ui_view_base::set_event_block(bool block) +{ + this->event_block = block; +} + +void ui_view_base::load() +{ + this->state = UI_VIEW_STATE_LOAD; + if (this->content) + return; + if (!this->controller) + return; + this->controller->load(); +} + +void ui_view_base::unload() +{ + this->state = UI_VIEW_STATE_UNLOAD; + if (!this->content) + return; + if (!this->controller) + return; + this->controller->unload(); +} + +void ui_view_base::active() +{ + this->state = UI_VIEW_STATE_ACTIVE; + if (!this->controller) + return; + this->controller->active(); +} + +void ui_view_base::inactive() +{ + this->state = UI_VIEW_STATE_INACTIVE; + if (!this->controller) + return; + this->controller->inactive(); +} + +void ui_view_base::pause() +{ + this->state = UI_VIEW_STATE_PAUSE; + if (!this->content) + return; + if (state != UI_VIEW_STATE_ACTIVE) + return; + if (!this->controller) + return; + this->controller->pause(); +} + +void ui_view_base::resume() +{ + this->state = UI_VIEW_STATE_ACTIVE; + if (state != UI_VIEW_STATE_PAUSE) + return; + if (!this->content) + return; + if (!this->controller) + return; + this->controller->resume(); +} + +void ui_view_base::destroy() +{ + if (!this->controller) + return; + this->controller->destroy(); +} + +ui_view_base::ui_view_base(T content, ui_controller_base *controller) : + content(content), controller(controller), name(string()), style(string()), viewmgr(NULL), state(UI_VIEW_STATE_LOAD), event_block( + false) +{ + if (!content) + this->state = UI_VIEW_STATE_UNLOAD; + else + this->state = UI_VIEW_STATE_LOAD; + controller->set_view(this); +} + +ui_view_base::ui_view_base(ui_controller_base *controller = NULL) : + ui_view_base(NULL, controller) +{ + this->state = UI_VIEW_STATE_UNLOAD; +} + +ui_view_base::~ui_view_base() +{ + this->viewmgr->remove_view(this); + if (this->controller) + delete (this->controller); +} + +ui_controller_base* +ui_view_base::set_controller(ui_controller_base *controller) +{ + ui_controller_base *prev_controller = this->controller; + this->controller = controller; + controller->set_view(this); + prev_controller->set_view(NULL); + return prev_controller; +} + +T ui_view_base::set_content(T content) +{ + T prev = this->content; + this->content = content; + return prev; +} + +bool ui_view_base::set_style(const char *style) +{ + this->style.assign(style); + return true; +} diff --git a/src/ui_view_base.h b/src/ui_view_base.h new file mode 100644 index 0000000..db7cf36 --- /dev/null +++ b/src/ui_view_base.h @@ -0,0 +1,222 @@ +/* + * ui_view_base.h + * + * Created on: Jan 15, 2016 + * Author: hermet + */ + +#ifndef UI_VIEW_BASE_H_ +#define UI_VIEW_BASE_H_ + +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "VIEWMGR" + +typedef void* T; + +class ui_viewmgr_base; +class ui_controller_base; + +/** + * @class ui_view_base + * + * @ingroup ui_viewmgr + * + * @brief UI View Base Class. This is the base class of view. A view must have one content instance which represents a view for a current screen. + * UI View may have it's own show/hide transition styles. That means, it's available that views have different show/hide effects on demands. + * It's not mandatory but view should describe the transitions in this class. + * + * @warning When the transitions are finished, the view must to call ui_viewmgr_base :: _push_finished(), ui_viewmgr_base :: _pop_finished() in order that + * The ui_viewmgr_base keeps the view states exactly. + * + * @date 2016/01/15 + * @author Hermet Park + */ +class ui_view_base +{ +private: + /// View state definition + enum ui_view_state + { + UI_VIEW_STATE_LOAD = 0, ///< Load state + UI_VIEW_STATE_UNLOAD, ///< Unload state + UI_VIEW_STATE_ACTIVE, ///< Active state + UI_VIEW_STATE_INACTIVE, ///< Inactive state + UI_VIEW_STATE_PAUSE, ///< Pause state + UI_VIEW_STATE_LAST + }; + + T content; ///< A content instance for a screen as a view. + ui_controller_base *controller; ///< view life-cycle controller interface. + std::string name; ///< view name + std::string style; ///< view style name. + ui_viewmgr_base *viewmgr; ///< viewmgr which this view belongs to. + ui_view_state state; ///< view state + bool event_block; ///< state of event block. + + //Need to check. + friend class ui_viewmgr_base; + //friend bool ui_viewmgr_base ::_connect_view(ui_view_base *view); + //friend bool ui_viewmgr_base ::_disconnect_view(ui_view_base *view); + //friend void ui_viewmgr_base ::_set_event_block(ui_view_base *view); + //friend bool ui_viewmgr_base ::_push_view_finished(ui_view_base *view); + //friend bool ui_viewmgr_base ::_pop_view_finished(ui_view_base *view); + +protected: + + /** @brief toggle event block + * + * @note This interface is designed for toggling touch event on view transition. + * ui_viewmgr_base will call this interface for notifying event blocking toggling on transition time. + * + * @param block @c true, when blocking is enabled, otherwise @c false. + * + */ + virtual void set_event_block(bool block); + + /** @brief view load state + * + * @note this state will be triggered by ui_viewmgr_base + * + * @see ui_controller_base for this state in detail. + */ + virtual void load(); + + /** @brief view unload state + * + * @note this state will be triggered by ui_viewmgr_base + * + * @see ui_controller_base for this state in detail. + */ + virtual void unload(); + + /** @brief view active state + * + * @note this state will be triggered by ui_viewmgr_base + * + * @see ui_controller_base for this state in detail. + */ + virtual void active(); + + /** @brief view inactive state + * + * @note this state will be triggered by ui_viewmgr_base + * + * @see ui_controller_base for this state in detail. + */ + virtual void inactive(); + + /** @brief view pause state + * + * @note this state will be triggered by ui_viewmgr_base + * + * @see ui_controller_base for this state in detail. + */ + virtual void pause(); + + /** @brief view resume state + * + * @note this state will be triggered by ui_viewmgr_base + * + * @see ui_controller_base for this state in detail. + */ + virtual void resume(); + + /** @brief view destroy state + * + * @note this state will be triggered by ui_viewmgr_base + * + * @see ui_controller_base for this state in detail. + */ + virtual void destroy(); + + /// Return the state of event block. + bool get_event_block() + { + return this->event_block; + } + +public: + /** @brief This is a constructor for initializing this view resources. + * + * @param content A content instance for a screen as a view. + * @param controller view life-cycle controller interface. + * @param name view name. + * + * @warning Be aware the deletion of controller passed here will be covered by ui_view_base. + * If you want to keep it for any reasons, please unset it using set_controller() before ui_view_base is deleted. + */ + + //Constructor + ui_view_base(T content, ui_controller_base *controller); + ///Constructor for initializing with controller. + ui_view_base(ui_controller_base *controller); + + ///Destructor for terminating view. + virtual ~ui_view_base(); + + /** @brief This is for replacing or setting a controller of the view. + * + * @param controller a new controller. It allows @c NULL for canceling the previous controller. + * @return A previous controller. If it wasn't, the return value will be @c NULL + * + * @warning Be aware deletion of controller passed here will be taken cover by ui_view_base. + * If you want to keep the controller for any reasons, please unset it using set_controller() before ui_view_base is deleted. + */ + ui_controller_base* set_controller(ui_controller_base *controller); + + /** @brief This is for replacing or setting a content of the view. + * + * @note @c content is a logical object that represents a view in your framework. The actual type of the content could be translated to any certain types. + * For instance, the type could be Evas_Object * in EFL and Layer * in Dali. + * + * @param content a new content. It allows @c NULL for canceling the previous content. + * @return A previous content. If it wasn't, return value will be @c NULL + */ + virtual T set_content(T content); + + /** @brief set style of the 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. + * + * @param style a new 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. + * + */ + virtual bool set_style(const char *style); + + /// Return a controller of this view. + const ui_controller_base* get_controller() + { + return this->controller; + } + /// Return a style name of this view. + const char *get_style() + { + return this->style.c_str(); + } + /// Return a content instance of this view. + T get_content() + { + return this->content; + } + /// Return a viewmgr which this view is belonging to + ui_viewmgr_base *get_viewmgr() + { + return this->viewmgr; + } + /// Return a state of this view. + ui_view_state get_state() + { + return this->state; + } +}; + +#endif /* UI_VIEW_BASE_H_ */ diff --git a/src/ui_viewmgr.cpp b/src/ui_viewmgr.cpp new file mode 100644 index 0000000..657186b --- /dev/null +++ b/src/ui_viewmgr.cpp @@ -0,0 +1,169 @@ +#include +#include "ui_view.h" +#include "ui_viewmgr.h" + +using namespace efl; + +void +win_delete_request_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + ui_viewmgr *viewmgr = static_cast(data); + delete(viewmgr); +} + +Evas_Object * +ui_viewmgr::create_conformant(Evas_Object *win) +{ + Evas_Object *conform = elm_conformant_add(win); + if (!conform) + return NULL; + + evas_object_size_hint_weight_set(conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, conform); + elm_win_conformant_set(win, EINA_TRUE); + evas_object_show(conform); + + return conform; +} + +Evas_Object * +ui_viewmgr::create_base_layout(Evas_Object *conform) +{ + Evas_Object *layout = elm_layout_add(conform); + if (!layout) + { + return NULL; + } + + elm_layout_theme_set(layout, "layout", "application", "default"); + elm_object_content_set(conform, layout); + + return layout; +} + +ui_viewmgr::ui_viewmgr(const char *pkg) : + ui_viewmgr_base() +{ + if (!pkg) + { + LOGE("Invalid package name"); + return; + } + //Window + this->win = elm_win_util_standard_add(pkg, pkg); + + if (!this->win) + { + LOGE("Failed to create a window (%s)", pkg); + return; + } + + //Set window rotation + if (elm_win_wm_rotation_supported_get(this->win)) + { + int rots[4] = { 0, 90, 180, 270 }; + elm_win_wm_rotation_available_rotations_set(this->win, (const int *) (&rots), 4); + } + + evas_object_smart_callback_add(this->win, "delete,request", win_delete_request_cb, this); + + //Conformant: Make this configurable. + this->conform = this->create_conformant(this->win); + + if (!this->conform) + { + LOGE("Failed to create a conformant (%s)", pkg); + return; + } + + this->base_layout = this->create_base_layout(this->conform); + + if (!this->base_layout) + { + LOGE("Failed to create a base layout (%s)", pkg); + return; + } + + //Set Indicator properties + elm_win_indicator_mode_set(this->win, ELM_WIN_INDICATOR_SHOW); + elm_win_indicator_opacity_set(this->win, ELM_WIN_INDICATOR_TRANSPARENT); + + elm_win_autodel_set(this->win, EINA_TRUE); +} + +ui_viewmgr::~ui_viewmgr() +{ +} + +bool ui_viewmgr::activate() +{ + elm_object_part_content_unset(this->base_layout, "elm.swallow.content"); + + ui_view *view = dynamic_cast(this->get_last_view()); + + //TODO: get parent? + Evas_Object *content = view->get_base(); + if (content == this->base_layout) + { + elm_object_part_content_set(this->base_layout, "elm.swallow.content", CONVERT_TO_EO(view->get_content())); + } else + { + elm_object_part_content_set(this->base_layout, "elm.swallow.content", CONVERT_TO_EO(view->get_base())); + } + + evas_object_show(this->win); + + return true; +} + +bool ui_viewmgr::deactivate() +{ + //TODO: based on the profile, we could hide window or destroy window. + evas_object_lower(this->win); + return true; +} + +bool ui_viewmgr::pop_view() +{ + if (!ui_viewmgr_base::pop_view()) + { + return false; + } + + ui_view *view = dynamic_cast(this->get_last_view()); + + //TODO: get parent? + Evas_Object *content = view->get_base(); + if (content == this->base_layout) + { + elm_object_part_content_set(this->base_layout, "elm.swallow.content", CONVERT_TO_EO(view->get_content())); + } else + { + elm_object_part_content_set(this->base_layout, "elm.swallow.content", CONVERT_TO_EO(view->get_base())); + } + + return true; +} + +ui_view * +ui_viewmgr::push_view(ui_view *view) +{ + ui_viewmgr_base::push_view(view); + + if (this->get_view_count() == 1) return view; + + elm_object_part_content_unset(this->base_layout, "elm.swallow.content"); + + Evas_Object *content = view->get_base(); + + if (content == this->base_layout) + { + elm_object_part_content_set(this->base_layout, "elm.swallow.content", CONVERT_TO_EO(view->get_content())); + } else + { + LOGE("view->base = %p", view->get_base()); + elm_object_part_content_set(this->base_layout, "elm.swallow.content", CONVERT_TO_EO(view->get_base())); + } + + return view; +} diff --git a/src/ui_viewmgr.h b/src/ui_viewmgr.h new file mode 100644 index 0000000..b3c6df6 --- /dev/null +++ b/src/ui_viewmgr.h @@ -0,0 +1,232 @@ +#ifndef UI_VIEWMGR +#define UI_VIEWMGR + +#include +#include "ui_viewmgr_base.h" + +namespace efl +{ + +class ui_view; + +class ui_viewmgr: public ui_viewmgr_base +{ +private: + Ecore_Job *animation_job; + bool animation_ongoing; + //CHECK is it really needed? + bool to_show; + Evas_Object *win; + Evas_Object *conform; + Evas_Object *base_layout; + + Evas_Object * create_conformant(Evas_Object *win); + Evas_Object * create_base_layout(Evas_Object *conform); + + /* + static void + _appear_finished_cb(void *data, Evas_Object *obj, const char *emision, const char *source) + { + LOGI("CALLED"); + ui_viewmgr *viewmgr = (ui_viewmgr *)data; + + viewmgr->_push_view_finished(viewmgr->anim.view_this); + + //TODO: Appear finish callback call? + + elm_object_part_content_set(viewmgr->base_layout, "swallow.back", obj); + + //TODO: Thaw event? + + viewmgr->anim.view_this = NULL; + viewmgr->anim.view_other = NULL; + viewmgr->animation_ongoing = false; + viewmgr->to_show = false; + } + + static void + _appear_effect(ui_viewmgr *viewmgr) + { + LOGI("CALLED"); + Evas_Object *layout; + + //TODO: send a style intead of NULL value below. + layout = _create_layout(viewmgr->base_layout, NULL); + elm_object_part_content_set(viewmgr->base_layout, "swallow.front", layout); + evas_object_show(layout); + + if (!viewmgr->anim.view_this->get_content()) + { + //TODO: Content load here? + } + + if (viewmgr->anim.view_this->get_content()) + { + //TODO: Freeze event? + elm_object_part_content_set(layout,"swallow.view.this", + viewmgr->anim.view_this->get_content()); + //View appear start. + } + + if (viewmgr->anim.view_other) + { + if (viewmgr->anim.view_other->get_content()) + { + //TODO: Freeze event? + elm_object_part_content_set(layout,"swallow.view.other", + viewmgr->anim.view_other->get_content()); + //View disappear start. + } + } + //ui_view_base *appear_view = viewmgr->view_list.back(); + + // delete old layout if any + _delete_layout(elm_object_part_content_get(viewmgr->base_layout, "swallow.back")); + + // start the animation + elm_object_signal_emit(layout, "appear,effect", "elm"); + elm_object_signal_callback_add(layout, "appear,effect,finished", "*", _appear_finished_cb, viewmgr); + } + + static void + _disappear_finished_cb(void *data, Evas_Object *obj, const char *emision, const char *source) + { + LOGI("CALLED"); + ui_viewmgr *viewmgr = (ui_viewmgr *)data; + + ui_view_base *appear_view = viewmgr->view_list.back(); + //appear_view->active(); + + //viewmgr->_pop_view_finished(appear_view); + + elm_object_part_content_set(viewmgr->base_layout, "swallow.back", obj); + //evas_object_freeze_events_set(elm_object_part_content_get(obj, "swallow.view.this"), EINA_FALSE); + //evas_object_freeze_events_set(elm_object_part_content_get(obj, "swallow.view.other"), EINA_FALSE); + + //destroy the view + // remove it from the view stack + //viewmgr->view_list.pop_back(); + elm_object_part_content_unset(obj,"swallow.view.this"); + viewmgr-> _pop_view_finished(viewmgr->anim.view_this); + //delete(viewmgr->anim.view_this); + //Do it in unload method? + evas_object_del(viewmgr->anim.view_this->get_content()); + + viewmgr->anim.view_this = NULL; + viewmgr->anim.view_other = NULL; + viewmgr->animation_ongoing = false; + } + + static void + _disappear_effect(ui_viewmgr* viewmgr) + { + LOGI("CALLED"); + Evas_Object *layout; + + //TODO: send a style intead of NULL value below. + layout = _create_layout(viewmgr->base_layout, NULL); + elm_object_part_content_set(viewmgr->base_layout, "swallow.front", layout); + evas_object_show(layout); + + //TODO: check the content is? + //TODO: event freeze? + + elm_object_part_content_set(layout,"swallow.view.this", + viewmgr->anim.view_this->get_content()); + elm_object_part_content_set(layout,"swallow.view.other", + viewmgr->anim.view_other->get_content()); + + //TODO: check is it right? + //ui_view_base *appear_view = viewmgr->view_list.back(); + + //view appear start + //elm_object_part_content_set(layout,"swallow.view.this", appear_view->get_content()); + + //evas_object_freeze_events_set(ui_view_content_get(view_mgr->anim.view_this), EINA_TRUE); + //evas_object_freeze_events_set(ui_view_content_get(view_mgr->anim.view_other), EINA_TRUE); + + // delete old layout if any + _delete_layout(elm_object_part_content_get(viewmgr->base_layout, "swallow.back")); + + elm_object_signal_emit(layout, "disappear,effect", "elm"); + elm_object_signal_callback_add(layout, "disappear,effect,finished", "*", _disappear_finished_cb, viewmgr); + } + + static void _animation_cb(void *data) + { + ui_viewmgr *viewmgr = (ui_viewmgr *)data; + viewmgr->animation_job = NULL; + + if (viewmgr->animation_ongoing) { + viewmgr->animation_job = ecore_job_add(_animation_cb, viewmgr); + return; + } else { + viewmgr->animation_ongoing = true; + } + + viewmgr->anim.view_this = viewmgr->view_list.back(); + + //TODO: fix below hard coding :( + + //if (viewmgr->anim.view_this->get_state() == 3) + if (viewmgr->to_show) + { + std::list*>::iterator li; + + for (li = viewmgr->view_list.begin(); li!= viewmgr->view_list.end(); li++) + { + ui_view *view = (ui_view *)*li; + if (view->get_state() == 2) + { + printf("Find active view %p\n", view); + viewmgr->anim.view_other = view; + break; + } + } + + _appear_effect(viewmgr); + } + else + { + std::list*>::reverse_iterator li; + + int i = 0; + for (li = viewmgr->view_list.rbegin(); li!= viewmgr->view_list.rend(); li++) + { + i++; + ui_view *view = (ui_view *)*li; + //if (view->get_state() == 2) + if (i == 2) + { + printf("Find view %p\n", view); + viewmgr->anim.view_other = view; + break; + } + } + + if (viewmgr->anim.view_other) + _disappear_effect(viewmgr); + } + } + */ +public: + ui_viewmgr(const char *pkg); + ~ui_viewmgr(); + bool activate(); + bool deactivate(); + Evas_Object *get_window() + { + return this->win; + } + ui_view *push_view(ui_view *view); + bool pop_view(); + + //TODO: Make this private + Evas_Object *get_base_layout() + { + return this->base_layout; + } +}; +} + +#endif /* UI_VIEWMGR */ diff --git a/src/ui_viewmgr_base.cpp b/src/ui_viewmgr_base.cpp new file mode 100644 index 0000000..0e8a27a --- /dev/null +++ b/src/ui_viewmgr_base.cpp @@ -0,0 +1,234 @@ +#include +#include +#include "ui_view_base.h" +#include "ui_viewmgr_base.h" + +bool ui_viewmgr_base::_connect_view(ui_view_base *view) +{ + LOGE("Conneted view with viewmgr"); + if (view->viewmgr) + { + LOGE("view(%p) has already connected to viewmgr(%p)", view, this); + return false; + } + + view->viewmgr = this; + return true; +} + +bool ui_viewmgr_base::_disconnect_view(ui_view_base *view) +{ + if (!view->viewmgr) + return false; + view->viewmgr = NULL; + return true; +} + +void ui_viewmgr_base::_set_event_block(ui_view_base *view, bool block) +{ + + if (!this->event_block) + return; + view->set_event_block(block); +} + +bool ui_viewmgr_base::_push_view_finished(ui_view_base *view) +{ + ui_view_base *last = this->view_list.back(); + + //The previous view has been pushed. This should be unload. + if (last != view) + { + view->unload(); + return true; + } + + //A new view has been pushed. This should be active. + view->active(); + this->_set_event_block(view, true); + + return true; +} + +bool ui_viewmgr_base::_pop_view_finished(ui_view_base *view) +{ + ui_view_base *last = this->view_list.back(); + + //This view has been popped. It should be destroyed. + if (last == view) + { + view->unload(); + view->destroy(); + delete (view); + return true; + } + + //The previous view has been popped. It should become active. + view->active(); + this->_set_event_block(view, true); + + return true; +} + +ui_viewmgr_base::ui_viewmgr_base() : + event_block(true) +{ + //TODO: Initialize ? +} + +ui_viewmgr_base::~ui_viewmgr_base() +{ + //Terminate views + for (typename std::list::reverse_iterator it = this->view_list.rbegin(); it != this->view_list.rend(); it++) + { + ui_view_base *view = *it; + view->inactive(); + view->unload(); + view->destroy(); + delete (view); + } + + //Terminate applicationn when viewmgr is destroyed. + ui_app_exit(); +} + +ui_view_base * +ui_viewmgr_base::push_view(ui_view_base *view) +{ + if (!view) + { + LOGE("invalid view argument. view(NULL)"); + return NULL; + } + + if (!this->_connect_view(view)) + { + LOGE("connect view failed"); + return NULL; + } + + ui_view_base *pview; + + //Previous view + if (this->view_list.size()) + { + 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); + + if (!view->get_content()) + { + view->load(); + } + + view->inactive(); + this->_set_event_block(view, true); + + return view; +} + +bool ui_viewmgr_base::pop_view() +{ + //No more view? destroy viewmgr? + if (this->get_view_count() == 0) + { + return false; + } + + //This is the last page. destroy viewmgr? + if (this->get_view_count() == 1) + { + //destroy viewmgr? + ui_view_base *view = this->view_list.back(); + view->inactive(); + view->unload(); + view->destroy(); + return true; + } + + //last page to be popped. + ui_view_base *view = this->view_list.back(); + view->inactive(); + this->_set_event_block(view, true); + + //Below object has to be used in child class... + //Make this getter method? or define instance? + //previous page to be current active. + auto nx = std::prev(this->view_list.end(), 2); + ui_view_base *pview = *nx; + LOGE("pview = %p", pview); + pview->load(); + 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; +} + +bool ui_viewmgr_base::insert_view_before(ui_view_base *view, ui_view_base *before) +{ + //TODO: ... + return true; +} + +bool ui_viewmgr_base::insert_view_after(ui_view_base *view, ui_view_base *after) +{ + //TODO: ... + return true; +} + +bool ui_viewmgr_base::remove_view(ui_view_base *view) +{ + this->view_list.remove(view); + this->_disconnect_view(view); + + //TODO: If this view is the top on the stack ? + return true; +} + +ui_view_base* +ui_viewmgr_base::get_view(unsigned int idx) +{ + if (idx < 0 || idx >= this->view_list.size()) + { + LOGE("Invalid idx(%d)! =? (idx range: %d ~ %d)", idx, 0, this->view_list.size() - 1); + return NULL; + } + typename std::list::iterator it = this->view_list.begin(); + std::advance(it, idx); + return *it; +} + +int ui_viewmgr_base::get_view_index(const ui_view_base *view) +{ + int idx = 0; + + for (typename std::list::iterator it = this->view_list.begin(); it != this->view_list.end(); it++) + { + if (view == *it) + return idx; + ++idx; + } + + return -1; +} + +ui_view_base * +ui_viewmgr_base::get_last_view() +{ + int cnt = this->get_view_count(); + LOGE("cnt = %d", cnt); + return this->get_view(cnt - 1); +} diff --git a/src/ui_viewmgr_base.h b/src/ui_viewmgr_base.h new file mode 100644 index 0000000..9156384 --- /dev/null +++ b/src/ui_viewmgr_base.h @@ -0,0 +1,220 @@ +/* + * ui_viewmgr_base.h + * + * Created on: Jan 15, 2016 + * Author: hermet + */ + +#ifndef UI_WINDOW_BASE_H_ +#define UI_WINDOW_BASE_H_ + +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "VIEWMGR" + +using namespace std; + +class ui_view_base; + +/** + * @class ui_viewmgr_base + * + * @ingroup ui_viewmgr + * + * @brief This is a base class of viewmgr. One viewmgr represents a window which contains multiple views. + * A viewmgr manages not only views life-cycle but constructs some basic infrastructure. It's up to derived classes. + * + * @warning viewmgr will remove all containing views when it's destroyed. + * @date 2016/01/29 + * @author Hermet Park + */ +class ui_viewmgr_base +{ +private: + //TODO: change name to view_stack + std::list view_list; //view list. + bool event_block; //event block on view transition. This value should be configurable by system. + + /** + * @brief link a given view to this viewmgr. + * + * @param view a view to connect to this viewmgr. + * @return success or not. + * + * @note This is s a friend function of ui_view_base + */ + bool _connect_view(ui_view_base *view); + + /** + * @brief unlink a given view from this viewmgr. + * + * @param view a view to disconnect from this viewmgr. + * @return @c true success or @c false not. + * + * @note This is s a friend function of ui_view_base + */ + bool _disconnect_view(ui_view_base *view); + + /** + * @brief toggle event blocking to the given view. + * + * @param view a view to toggle event blocking + * @param block @c true is block event, otherwise @c false. + * + * @note This is s a friend function of ui_view_base + */ + void _set_event_block(ui_view_base *view, bool block); + +protected: + + /** + * @brief This function is designed for end of push transition. + * + * @param view view which is finished pushing. + * @return @c true success or @c false not. + * + * @warning This function must be called definitely when push transition is finished. + * @note This is s a friend function of ui_view_base + */ + virtual bool _push_view_finished(ui_view_base *view); + + /** + * @brief This function is designed for end of pop transition. + * + * @param view view which is finished popping. + * @return @c true success or @c false not. + * + * @warning This function must be called definitely when push transition is finished. + * @note This is s a friend function of ui_view_base + */ + virtual bool _pop_view_finished(ui_view_base *view); + +public: + ///Constructor. + ui_viewmgr_base(); + + ///Destructor. Delete all contained views. + virtual ~ui_viewmgr_base(); + + //Activate a viewmgr. Implement this body to activate a viewmgr. + virtual bool activate() = 0; + + //Deactivate a viewmgr. Implement this body to deactivate a viewmgr. + virtual bool deactivate() = 0; + + /** + * @brief Push a new view into the viewmgr stack. + * This function is used for application switches the current view to a new one. + * + * @note Normally, the current view will be hidden by a new view. + * @return @c true on success, @c false otherwise. + */ + virtual ui_view_base *push_view(ui_view_base *view); + + /** + * @brief Pop the top view from the viewmgr stack. + * This function is used for application switches the current view back to the previous view. + * The top view will be removed from the view stack and then it will be deleted by the viewmgr. + * + * @note If the view is just one left, then viewmgr would be destroyed since the application might be terminated. + * But this behavior is optional. + * + * @return A view pointer which was popped. If it's failed to pop, @c NULL will be returned. + */ + bool pop_view(); + + /** + * @brief Insert a view into this viewmgr stack. Specially, right before of the given view, @before + * + * @param view a view to push into the viewmgr stack + * @param before a view that will be just after the @c view. + * If you pass @c NULL, @c view will be inserted at the front of the view stack. + * @return @c true success or @c false not. + */ + virtual bool insert_view_before(ui_view_base *view, ui_view_base *before); + + /** + * @brief Insert a view into this viewmgr stack. Specially, right after of the given view, @after + * + * @param view a view to push into the viewmgr stack + * @param after a view that will be just before the @c view. + * If you pass @c NULL, @c view will be inserted at the end of the view stack. + * @return @c true success or @c false not. + */ + virtual bool insert_view_after(ui_view_base *view, ui_view_base *after); + + /** + * @brief Remove the given view from this viewmgr stack. + * + * @return @c true on success or @c false if not. + * + */ + virtual bool remove_view(ui_view_base *view); + + /** + * @brief Return a stack index number of the given view. + * You could use this function to query the given view stack order. + * + * @param idx a view to query the index. + * @return an index of the give view. + * If there were no views on the idx, @c NULL will be returned. + * + * @warning the index number is variable since the view stack size is also variable. + */ + ui_view_base* get_view(unsigned int idx); + + /** + * @brief Return a view which is matched with the @c name. + * + * @param name the name of the view which you find. + * @return the view which name is matched with @c name. + * If there were no views name matched, @c NULL will be returned. + * + */ + ui_view_base *get_view(const char *name) + { + //TODO: ... + return NULL; + } + + //TODO: Doc. + ui_view_base *get_last_view(); + + /** + * @brief Return a stack index number of the given view. + * You could use this function to query the given view stack order. + * + * @param a view to query the index. + * @return an index of the give view on success, otherwise, -1. + * + * @warning the index number is variable since the view stack size is also variable. + */ + int get_view_index(const ui_view_base *view); + + /** + * @brief Return the number of views which this viewmgr has. + * + * @return the number of view + * + */ + unsigned int get_view_count() + { + return this->view_list.size(); + } + + /** + * @brief Return a list of views which this viewmgr has. + * + * @return a pointer of list of views. + * + */ + const list* const get_view_list() + { + return &this->view_list; + } +}; + +#endif /* UI_WINDOW_BASE_H_ */ diff --git a/ui-viewmgr.manifest b/ui-viewmgr.manifest deleted file mode 100644 index d486ced..0000000 --- a/ui-viewmgr.manifest +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui-viewmgr.pc.in b/ui-viewmgr.pc.in deleted file mode 100644 index ccdc293..0000000 --- a/ui-viewmgr.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@PREFIX@ -exec_prefix=@EXEC_DIR@ -libdir=@LIBDIR@ -includedir=@INCDIR@ - -Name: UI VIEW MANAGER -Description: An UI VIEW MANAGER library -Version: @VERSION@ -Requires: -Libs: -L${libdir} -lui-viewmgr -Cflags: -I${includedir}/ui-viewmgr -- 2.7.4