TizenRefApp-8237 [Gallery] Integrate ThumbnailPage into application 02/120902/1
authorIgor Nazarov <i.nazarov@samsung.com>
Fri, 24 Mar 2017 13:53:58 +0000 (15:53 +0200)
committerIgor Nazarov <i.nazarov@samsung.com>
Fri, 24 Mar 2017 14:01:11 +0000 (16:01 +0200)
- Implemented code in Instance that integrates ThumbnailPage as a main
  page;
- Added SCAN_MEDIA_ON_RESUME temporary feature;
- Added Theme class to UCL;
- IInstance * changed to IInstanceSRef in UCL appfw module;
- Added helpers to UCL appfw.

Change-Id: I385bc669d13dcbcc71354714905238cd4c508490

20 files changed:
.project
inc/config.h
inc/main/Instance.h
inc/main/InstanceManager.h
inc/presentation/ThumbnailPage.h
inc/resources.h [new file with mode: 0644]
src/main/Instance.cpp
src/main/InstanceManager.cpp
src/presentation/ImageGrid.cpp
src/presentation/ThumbnailPage.cpp
ucl/inc/ucl/appfw/IInstance.h
ucl/inc/ucl/appfw/InstanceManagerBase.h
ucl/inc/ucl/appfw/UIApp.h
ucl/inc/ucl/appfw/helpers.h [new file with mode: 0644]
ucl/inc/ucl/gui/ElmWidget.h
ucl/inc/ucl/gui/ElmWidget.hpp
ucl/inc/ucl/gui/Theme.h [new file with mode: 0644]
ucl/inc/ucl/gui/Theme.hpp [new file with mode: 0644]
ucl/src/appfw/UIApp.cpp
ucl/src/appfw/helpers.cpp [new file with mode: 0644]

index 93a255d1024e1a375e942345a5ee6cf10a973141..ea7151d20b5dbbb205531d37c10c7dea98d4349d 100644 (file)
--- a/.project
+++ b/.project
@@ -7,7 +7,6 @@
        <buildSpec>
                <buildCommand>
                        <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
-                       <triggers>clean,full,incremental,</triggers>
                        <arguments>
                        </arguments>
                </buildCommand>
index ab8de836d24e7a05535bb5fb22ece0d251bd16b7..927210340327f992bfab2e7f1c90ad1fd066122d 100644 (file)
@@ -24,6 +24,9 @@ namespace gallery {
        constexpr auto WINDOW_NAME = "org.tizen.gallery";
 
        constexpr auto BASE_SCALE = 1.3;
+
+       // TODO Temporary feature while support only offline mode
+       constexpr auto SCAN_MEDIA_ON_RESUME = true;
 }
 
 #endif // __GALLERY_CONFIG_H__
index 4323e019870edd4315fcbc7db46d83dec2957188..09e53eabec86afce3376e3e8ec44815d97708f36 100644 (file)
 #include "ucl/appfw/IInstance.h"
 #include "ucl/appfw/IInstanceAppControlExt.h"
 
-#include "ucl/appfw/SysEventProvider.h"
+#include "ucl/gui/Theme.h"
+#include "ucl/gui/Naviframe.h"
+
+#include "model/types.h"
+#include "presentation/types.h"
 
 namespace gallery {
 
-       class Instance :
+       class Instance final :
                        public ucl::IInstance,
                        public ucl::IInstanceAppControlExt {
        public:
                Instance(ucl::SysEventProvider &sysEventProvider);
+               virtual ~Instance();
 
                // IInstance //
 
@@ -44,13 +49,29 @@ namespace gallery {
                virtual void onAppControl(app_control_h appControl) final override;
 
        private:
-               void onBack(Evas_Object *obj, void *event_info);
+               ucl::Result setupTheme();
+
+               void rescanMediaContent();
+               void stopMediaContentScan();
+               void startMediaContentScan();
+               void onScanComplete(media_content_error_e error);
+
                void onSysEvent(const ucl::SysEvent sysEvent);
 
+               void onPageExitRequest(Page &page);
+
        private:
                ucl::SysEventProvider &m_sysEventProvider;
                ucl::IInstanceContext *m_context;
+
+               GallerySRef m_gallery;
+               bool m_isScanInProgress;
+
                ucl::WindowSRef m_win;
+               ucl::Theme m_theme;
+               ucl::NaviframeSRef m_navi;
+
+               PageWRef m_page;
        };
 }
 
index 1ca4808770efd2e6ef0a7d7348576ff5fc3a4050..b9e98fd444634ef87b925552bc9ad3b087c0fcb2 100644 (file)
@@ -29,7 +29,7 @@ namespace gallery {
 
                // ucl::InstanceManagerBase //
 
-               virtual ucl::IInstance *newInstance() const final override;
+               virtual ucl::IInstanceSRef newInstance() const final override;
        };
 }
 
index 8186b2579cb2d14349801dc3577c85e97bbfdb94..00ab02a7d17829199cabf600d53d18f3ccd87133 100644 (file)
@@ -40,6 +40,9 @@ namespace gallery {
                        IMediaAlbumSRef m_album;
                };
 
+       public:
+               void reload();
+
        private:
                friend class ucl::RefCountObj<ThumbnailPage>;
                ThumbnailPage(ucl::RefCountObjBase &rc, const ucl::NaviframeSRef &navi,
diff --git a/inc/resources.h b/inc/resources.h
new file mode 100644 (file)
index 0000000..720ee58
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __GALLERY_RESOURCES_H__
+#define __GALLERY_RESOURCES_H__
+
+#include "config.h"
+
+namespace gallery {
+
+       constexpr auto THEME_EDJE_PATH = "edje/theme.edj";
+}
+
+#endif // __GALLERY_RESOURCES_H__
index c2287526fe2912fab12f0f94303d75385e0700e9..e2fc956f267f23a5c305fb34fafe9de0f2c9a0fa 100644 (file)
 #include "main/Instance.h"
 
 #include <system_settings.h>
-#include <efl_extension.h>
+
+#include "ucl/appfw/SysEventProvider.h"
+#include "ucl/appfw/helpers.h"
+
+#include "model/Gallery.h"
+
+#include "presentation/ThumbnailPage.h"
+
+#include "resources.h"
 
 #include "../common.h"
 
+namespace gallery { namespace { namespace impl {
+
+       // TODO Since feature is temporary using hard-coded path
+       constexpr auto MEDIA_FOLDER = "/opt/usr/home/owner/media";
+}}}
+
 namespace gallery {
 
        using namespace ucl;
 
        Instance::Instance(SysEventProvider &sysEventProvider) :
-               m_sysEventProvider(sysEventProvider)
+               m_sysEventProvider(sysEventProvider),
+               m_isScanInProgress(false)
        {
        }
 
+       Instance::~Instance()
+       {
+               stopMediaContentScan();
+       }
+
        Result Instance::onCreate(IInstanceContext *const context)
        {
                m_context = context;
 
+               m_gallery = Gallery::newInstance();
+               if (!m_gallery) {
+                       LOG_RETURN(RES_FAIL, "Gallery::newInstance() failed!");
+               }
+
                m_win = m_context->getWindow();
 
+               FAIL_RETURN(setupTheme(), "setupTheme() failed!");
+
+               m_navi = Naviframe::Builder().
+                               build(m_win->getConformant());
+               if (!m_navi) {
+                       LOG_RETURN(RES_FAIL, "Naviframe::build() failed!");
+               }
+
+               m_win->getConformant().setContent(*m_navi);
+
                m_sysEventProvider.addEventHandler(
                                DELEGATE(Instance::onSysEvent, this));
 
-               eext_object_event_callback_add(*m_win, EEXT_CALLBACK_BACK,
-                               CALLBACK_A(Instance::onBack), this);
+               return RES_OK;
+       }
+
+       Result Instance::setupTheme()
+       {
+               m_theme = Theme::create();
+               if (isNotValid(m_theme)) {
+                       LOG_RETURN(RES_FAIL, "Theme::create() failed!");
+               }
+
+               m_theme.addExtension(getResPath(THEME_EDJE_PATH));
+
+               m_win->setTheme(m_theme);
 
                return RES_OK;
        }
 
        void Instance::onPause()
        {
-               ILOG("PAUSED");
+               DLOG("PAUSE");
        }
 
        void Instance::onResume()
        {
-               ILOG("RESUMED");
+               DLOG("RESUME");
+
+               if (SCAN_MEDIA_ON_RESUME) {
+                       rescanMediaContent();
+               }
        }
 
-       void Instance::onAppControl(app_control_h appControl)
+       void Instance::rescanMediaContent()
+       {
+               stopMediaContentScan();
+               startMediaContentScan();
+       }
+
+       void Instance::stopMediaContentScan()
        {
-               char *op = {};
-               app_control_get_operation(appControl, &op);
-               ILOG("operation: %s", op);
-               free(op);
+               if (m_isScanInProgress) {
+                       m_isScanInProgress = false;
+                       DLOG("Scan is in progress. Terminating...");
+                       const int ret = media_content_cancel_scan_folder(
+                                       impl::MEDIA_FOLDER);
+                       if (ret != 0) {
+                               WLOG("media_content_cancel_scan_folder() failed: %d", ret);
+                       }
+               }
+       }
 
-               if (!m_win->isVisible()) {
-                       show(*m_win);
+       void Instance::startMediaContentScan()
+       {
+               DLOG("Starting media scan...");
+
+               int ret = media_content_scan_folder(impl::MEDIA_FOLDER, true,
+                               CALLBACK_B(Instance::onScanComplete), this);
+               if (ret != 0) {
+                       ELOG("media_content_scan_folder() failed: %d", ret);
+                       return;
+               }
+
+               m_isScanInProgress = true;
+       }
+
+       void Instance::onScanComplete(media_content_error_e error)
+       {
+               DLOG("Media scan complete. error: %d", error);
+
+               m_isScanInProgress = false;
+
+               const auto thumbPage = dynamicRefCast<ThumbnailPage>(m_page);
+               if (thumbPage) {
+                       DLOG("Reloading the ThumbnailPage...");
+                       thumbPage->reload();
                }
        }
 
-       void Instance::onBack(Evas_Object *obj, void *event_info)
+       void Instance::onAppControl(app_control_h appControl)
        {
-               ILOG("Exiting the application...");
-               m_context->exitApp();
+               DLOG("APP CONTROL");
+
+               if (!m_page) {
+                       DLOG("Creating ThumbnailPage.");
+                       m_page = ThumbnailPage::Builder().
+                                       setNaviframe(m_navi).
+                                       setAlbum(m_gallery->getAlbum()).
+                                       build(DELEGATE(Instance::onPageExitRequest, this));
+               }
+
+               if (!m_win->isVisible()) {
+                       DLOG("Show the window.");
+                       show(*m_win);
+               }
        }
 
        void Instance::onSysEvent(const SysEvent sysEvent)
        {
                switch(sysEvent) {
                case SysEvent::LANGUAGE_CHANGED:
-                       ILOG("SysEvent::LANGUAGE_CHANGED");
+                       DLOG("SysEvent::LANGUAGE_CHANGED");
                        {
                                char *locale = NULL;
                                system_settings_get_value_string(
@@ -87,8 +183,19 @@ namespace gallery {
                        }
                        break;
                default:
-                       ILOG("sysEvent: %d", sysEvent);
+                       DLOG("sysEvent: %d", sysEvent);
                        break;
                }
        }
+
+       void Instance::onPageExitRequest(Page &page)
+       {
+               if (isLast(page)) {
+                       DLOG("Last page. Lowering the window.");
+                       m_win->lower();
+               } else {
+                       DLOG("Exit page.");
+                       page.exit();
+               }
+       }
 }
index 2f9271114fbe5d3d26a0516c3c5913737ebe6929..1ede15eaa63e66af168fb1fbf0dc54f590650827 100644 (file)
@@ -29,8 +29,8 @@ namespace gallery {
        {
        }
 
-       IInstance *InstanceManager::newInstance() const
+       IInstanceSRef InstanceManager::newInstance() const
        {
-               return new Instance(getSysEventProvider());
+               return makeShared<Instance>(getSysEventProvider());
        }
 }
index df3a7e4dc661a48be896852b32c25be00edb2a52..7b7be9c29d4b4b02a5a760adbb18e3f2aa9b450d 100644 (file)
@@ -215,7 +215,7 @@ namespace gallery {
                                                params.imagePath.c_str(), NULL);
 
                                int w, h;
-                               getSize(m_image, &w, &h);
+                               evas_object_image_size_get(m_image, &w, &h);
                                m_image.setARHint(WidgetARHint::NEITHER, w, h);
 
                                makeWhite(m_image);
index f9c304a12247b7af6574ab28aa8349d49e556268..4d96a2c44a879ada9fb707ec05600e24953111dc 100644 (file)
@@ -126,6 +126,19 @@ namespace gallery {
                m_imageGrid->setListener(nullptr);
        }
 
+       void ThumbnailPage::reload()
+       {
+               ImageGrid::Unrealizer u(*m_imageGrid);
+
+               m_mediaItems.clear();
+
+               FAIL_LOG(m_album->forEachMedia(
+                               DELEGATE(ThumbnailPage::onEachMedia, this)),
+                               "m_album->forEachMedia() failed!");
+
+               m_imageGrid->setItemCount(m_mediaItems.size());
+       }
+
        Result ThumbnailPage::prepare()
        {
                FAIL_RETURN(m_album->forEachMedia(
index f0ba4034356e8d07cafe40af392d08650d671f59..bf0920538fee9b3e3a0c3db737e26051b7c76b21 100644 (file)
@@ -21,8 +21,7 @@
 
 namespace ucl {
 
-       class IInstance;
-       using IInstanceUPtr = std::unique_ptr<IInstance>;
+       UCL_DECLARE_REF_ALIASES(IInstance);
 
        class IInstance : public Polymorphic {
        public:
index 5443aef882dfb883d891362dd8fcb7322adc21ad..0fdde8ca7d37512d7b308d7ef4654bc447ba8cee 100644 (file)
@@ -31,7 +31,7 @@ namespace ucl {
 
                void setSysEventProvider(SysEventProviderUPtr provider);
 
-               virtual IInstance *newInstance() const = 0;
+               virtual IInstanceSRef newInstance() const = 0;
 
        protected:
                SysEventProvider &getSysEventProvider() const;
index 00046c87d60b3d6c37478c0e2fa588ed3c7e90c7..f482ce43c11ee72e82a9afb703854bd57ace1965 100644 (file)
@@ -52,7 +52,7 @@ namespace ucl {
        private:
                InstanceManagerBase &m_instanceMgr;
                WindowSRef m_window;
-               IInstanceUPtr m_instance;
+               IInstanceSRef m_instance;
        };
 }
 
diff --git a/ucl/inc/ucl/appfw/helpers.h b/ucl/inc/ucl/appfw/helpers.h
new file mode 100644 (file)
index 0000000..fe598d9
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __UCL_APPFW_HELPERS_H__
+#define __UCL_APPFW_HELPERS_H__
+
+#include "types.h"
+
+namespace ucl {
+
+       std::string getResPath(const char *relativePath);
+}
+
+#endif // __UCL_APPFW_HELPERS_H__
index 7b1307760291d094d8efe9c652d27744cfba0a85..6e27717d0fa7c9ca5347c88bda3792fa6328838e 100644 (file)
@@ -31,6 +31,9 @@ namespace ucl {
                void setEnabled(bool value);
                bool isEnabled() const;
 
+               void setTheme(Elm_Theme *th);
+               Elm_Theme *getTheme();
+
        protected:
                virtual void setFocusedImpl(bool value) final override;
                virtual bool isFocusedImpl() const final override;
index 71383843fd6b87242ee0a87b9fc0d300f4b40fab..8a68dd1957627fbeee2b9a22368af803d8b2d17d 100644 (file)
@@ -26,6 +26,16 @@ namespace ucl {
                return !elm_object_disabled_get(getEo());
        }
 
+       inline void ElmWidget::setTheme(Elm_Theme *th)
+       {
+               elm_object_theme_set(getEo(), th);
+       }
+
+       inline Elm_Theme *ElmWidget::getTheme()
+       {
+               return elm_object_theme_get(getEo());
+       }
+
        // Non-member functions //
 
        inline void enable(ElmWidget &widget)
diff --git a/ucl/inc/ucl/gui/Theme.h b/ucl/inc/ucl/gui/Theme.h
new file mode 100644 (file)
index 0000000..f82d675
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __UCL_GUI_THEME_H__
+#define __UCL_GUI_THEME_H__
+
+#include "types.h"
+
+namespace ucl {
+
+       class Theme final : NonCopyable {
+       public:
+               static Theme create();
+
+               friend void swap(Theme &x, Theme &y);
+
+       public:
+               Theme();
+               Theme(nullptr_t);
+               explicit Theme(Elm_Theme *th, bool isOwner = false);
+               Theme(Theme &&tmp);
+               Theme &operator=(Theme &&tmp);
+               ~Theme();
+
+               Elm_Theme *getTh();
+               const Elm_Theme *getTh() const;
+
+               operator Elm_Theme *();
+               operator const Elm_Theme *() const;
+
+               void addExtension(const std::string edjePath);
+               void addOverlay(const std::string edjePath);
+
+       private:
+               Elm_Theme *m_th;
+               bool m_isOwner;
+       };
+
+       // Non-member functions //
+
+       bool isValid(const Theme &item);
+}
+
+#include "Theme.hpp"
+
+#endif // __UCL_GUI_THEME_H__
diff --git a/ucl/inc/ucl/gui/Theme.hpp b/ucl/inc/ucl/gui/Theme.hpp
new file mode 100644 (file)
index 0000000..dac1d57
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace ucl {
+
+       inline Theme Theme::create()
+       {
+               Elm_Theme *const th = elm_theme_new();
+               if (th) {
+                       elm_theme_ref_set(th, nullptr);
+               }
+               return Theme(th, true);
+       }
+
+       inline Theme::Theme() :
+               m_th(nullptr),
+               m_isOwner(false)
+       {
+       }
+
+       inline Theme::Theme(nullptr_t) :
+               Theme()
+       {
+       }
+
+       inline Theme::Theme(Elm_Theme *const th, const bool isOwner) :
+               m_th(th),
+               m_isOwner(isOwner)
+       {
+       }
+
+       inline Theme::Theme(Theme &&tmp)
+       {
+               m_th = tmp.m_th;
+               tmp.m_th = nullptr;
+       }
+
+       inline Theme &Theme::operator=(Theme &&tmp)
+       {
+               swap(*this, tmp);
+               return *this;
+       }
+
+       inline Theme::~Theme()
+       {
+               if (m_isOwner && m_th) {
+                       elm_theme_free(m_th);
+               }
+       }
+
+       inline Elm_Theme *Theme::getTh()
+       {
+               return m_th;
+       }
+
+       inline const Elm_Theme *Theme::getTh() const
+       {
+               return m_th;
+       }
+
+       inline Theme::operator Elm_Theme *()
+       {
+               return getTh();
+       }
+
+       inline Theme::operator const Elm_Theme *() const
+       {
+               return getTh();
+       }
+
+       inline void Theme::addExtension(const std::string edjePath)
+       {
+               elm_theme_extension_add(getTh(), edjePath.c_str());
+       }
+
+       inline void Theme::addOverlay(const std::string edjePath)
+       {
+               elm_theme_overlay_add(getTh(), edjePath.c_str());
+       }
+
+       // Non-member functions //
+
+       inline bool isValid(const Theme &item)
+       {
+               return !!item.getTh();
+       }
+
+       inline void swap(Theme &x, Theme &y)
+       {
+               std::swap(x.m_th, y.m_th);
+               std::swap(x.m_isOwner, y.m_isOwner);
+       }
+}
index 4b2109fb2d710676280efdbb1bcd79dd6989a9e2..49c5e67bec76036b0a3dc77ffe571f7253130eea 100644 (file)
@@ -177,7 +177,7 @@ namespace ucl {
 
        Result UIApp::createInstance()
        {
-               auto instance = util::makeUnique(m_instanceMgr.newInstance());
+               auto instance = m_instanceMgr.newInstance();
                if (!instance) {
                        LOG_RETURN(RES_FAIL, "m_instanceMgr.newInstance() failed!");
                }
diff --git a/ucl/src/appfw/helpers.cpp b/ucl/src/appfw/helpers.cpp
new file mode 100644 (file)
index 0000000..a87e4ac
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ucl/appfw/helpers.h"
+
+#include "../common.h"
+
+namespace ucl {
+
+       std::string getResPath(const char *const relativePath)
+       {
+               std::string result;
+               char *const resDir = app_get_resource_path();
+               if (resDir) {
+                       result = resDir;
+                       free(resDir);
+               } else {
+                       ELOG("app_get_resource_path() failed!");
+               }
+               result += relativePath;
+               return result;
+       }
+}