ucl::Result handleGroupMode(const std::string &operation,
app_control_h appControl);
+ ucl::Result ensureGalleryModel();
+
void createNoContentPage();
void createThumbnailPage();
- void createViewerPage(std::string filePath);
+ void createViewerPage(const MediaItemSRef &media);
+ void createVideoPlayerPage(const MediaItemSRef &media);
void onAlbumChanged();
void onPageExitRequest(Page &page);
#include <unordered_set>
-#include "ucl/gui/ElmWidget.h"
+#include "ucl/gui/Window.h"
#include "types.h"
ucl::Result prepare(ucl::ElmWidget &widget);
+ ucl::Window &getWindow();
+
void addDeactivatorSource(ucl::Widget &source);
void addDeactivatorException(void *deactivator);
private:
std::unordered_set<void *> m_deactivatorExceptions;
std::unordered_set<void *> m_deactivators;
- ucl::WidgetWRef m_topWidget;
+ ucl::WindowSRef m_window;
bool m_isPrepared;
};
}
--- /dev/null
+/*
+ * 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_PRESENTERS_VIDEO_PLAYER_PAGE_H__
+#define __GALLERY_PRESENTERS_VIDEO_PLAYER_PAGE_H__
+
+#include <player.h>
+
+#include "ucl/gui/Layout.h"
+
+#include "Page.h"
+
+namespace gallery {
+
+ class VideoPlayerPage final : public Page {
+ public:
+ class Builder {
+ public:
+ Builder();
+ ~Builder();
+ Builder &setNaviframe(const ucl::NaviframeSRef &navi);
+ Builder &setMedia(const MediaItemSRef &media);
+ VideoPlayerPageWRef build(ExitRequestHandler onExitRequest) const;
+ private:
+ ucl::NaviframeSRef m_navi;
+ MediaItemSRef m_media;
+ };
+
+ private:
+ friend class ucl::RefCountObj<VideoPlayerPage>;
+ VideoPlayerPage(ucl::RefCountObjBase &rc,
+ const ucl::NaviframeSRef &navi,
+ ExitRequestHandler onExitRequest,
+ const MediaItemSRef &media);
+ virtual ~VideoPlayerPage();
+
+ ucl::Result prepare();
+
+ void createImage();
+ ucl::Result preparePlayer();
+ ucl::Result seekToStart();
+
+ void createControls();
+ void createButton(ucl::ElmStyle style, ucl::EdjePart part,
+ const ucl::WidgetEventHandler &handler);
+
+ bool resetTimer(Ecore_Timer *&timer, double timeout, Ecore_Task_Cb func);
+ void stopTimer(Ecore_Timer *&timer);
+
+ bool resetAutoStartTimer();
+ bool resetControlsHideTimer();
+ bool resetTickTimer();
+
+ void showControls();
+ void hideControls();
+
+ bool updatePlayTimeText();
+ void updatePlayTimeText(int timeMs);
+
+ player_state_e getPlayerState() const;
+ void startPlayback();
+ void pausePlayback();
+
+ void setScreenOlwaysOn(bool isAlwaysOn);
+
+ void onPlaybackComplete();
+ void onPlaybackInterrupted(player_interrupted_code_e code);
+ void onSeekComplete();
+
+ Eina_Bool onAutoStartTimer();
+ Eina_Bool onControlsHideTimer();
+ Eina_Bool onTickTimer();
+
+ void onVolumeOnBtnClick(ucl::Widget &sender, void *eventInfo);
+ void onVolumeMuteBtnClick(ucl::Widget &sender, void *eventInfo);
+ void onPlayBtnClick(ucl::Widget &sender, void *eventInfo);
+ void onPauseBtnClick(ucl::Widget &sender, void *eventInfo);
+ void onTap(int x, int y);
+ Eina_Bool onRotary(Eext_Rotary_Event_Info *info);
+
+ void onInstancePaused(ucl::Widget &sender, void *eventInfo);
+ void onInstanceResumed(ucl::Widget &sender, void *eventInfo);
+
+ private:
+ enum class State {
+ PAUSED,
+ PLAYING
+ };
+
+ private:
+ const MediaItemSRef m_media;
+ ucl::LayoutSRef m_content;
+ ucl::WidgetSRef m_image;
+ TouchParserSRef m_touchParser;
+ player_h m_player;
+ int m_videoDuration;
+ Ecore_Timer *m_autoStartTimer;
+ Ecore_Timer *m_controlsHideTimer;
+ Ecore_Timer *m_tickTimer;
+ State m_state;
+ bool m_isControlsVisible;
+ bool m_needAutoStart;
+ bool m_isPlaybackCompleted;
+ };
+}
+
+#endif // __GALLERY_PRESENTERS_VIDEO_PLAYER_PAGE_H__
UCL_DECLARE_REF_ALIASES(ThumbnailPage);
UCL_DECLARE_REF_ALIASES(PreviewPage);
UCL_DECLARE_REF_ALIASES(ViewerPage);
+ UCL_DECLARE_REF_ALIASES(VideoPlayerPage);
}
#endif // __GALLERY_PRESENTERS_TYPES_H__
#undef UCL_LOG_TAG
#define UCL_LOG_TAG GALLERY_LOG_TAG
-#include "helpers.h"
+#include "internal.h"
#endif // __GALLERY_COMMON_H__
+++ /dev/null
-/*
- * 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_HELPERS_H__
-#define __GALLERY_HELPERS_H__
-
-#include "types.h"
-
-namespace gallery { namespace util {
-
- template <class GETTER, class V, class ...ARGS>
- ucl::Result get(GETTER &&getter, V &result, ARGS &&...args);
-
- template <class GETTER, class V, class ...ARGS>
- ucl::Result getNz(GETTER &&getter, V &result, ARGS &&...args);
-}}
-
-#include "helpers.hpp"
-
-#endif // __GALLERY_HELPERS_H__
+++ /dev/null
-/*
- * 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/util/logging.h"
-
-namespace gallery { namespace util { namespace himpl {
-
- template <class GETTER, class ...ARGS>
- inline ucl::Result get(GETTER &&getter, bool optional,
- std::string &result, ARGS &&...args)
- {
- char *value = nullptr;
- const int ret = getter(std::forward<ARGS>(args)..., &value);
- if ((ret != 0) || (!optional && !value)) {
- UCL_ELOG("get() failed: %d", ret);
- return ucl::RES_FAIL;
- }
-
- if (value) {
- result = value;
- free(value);
- } else {
- result.clear();
- }
-
- return ucl::RES_OK;
- }
-
- template <class GETTER, class V, class ...ARGS>
- inline ucl::Result get(GETTER &&getter, bool optional,
- V &result, ARGS &&...args)
- {
- V value = {};
- const int ret = getter(std::forward<ARGS>(args)..., &value);
- if ((ret != 0) || (!optional && !value)) {
- UCL_ELOG("get() failed: %d", ret);
- return ucl::RES_FAIL;
- }
-
- result = value;
-
- return ucl::RES_OK;
- }
-}}}
-
-namespace gallery { namespace util {
-
- template <class GETTER, class V, class ...ARGS>
- inline ucl::Result get(GETTER &&getter, V &result, ARGS &&...args)
- {
- return himpl::get(std::forward<GETTER>(getter), true,
- result, std::forward<ARGS>(args)...);
- }
-
- template <class GETTER, class V, class ...ARGS>
- inline ucl::Result getNz(GETTER &&getter, V &result, ARGS &&...args)
- {
- return himpl::get(std::forward<GETTER>(getter), false,
- result, std::forward<ARGS>(args)...);
- }
-}}
--- /dev/null
+/*
+ * 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_INTERNAL_H__
+#define __GALLERY_INTERNAL_H__
+
+#include "types.h"
+
+namespace gallery { namespace util {
+
+ template <class GETTER, class V, class ...ARGS>
+ ucl::Result get(GETTER &&getter, V &result, ARGS &&...args);
+
+ template <class GETTER, class V, class ...ARGS>
+ ucl::Result getNz(GETTER &&getter, V &result, ARGS &&...args);
+
+ template <class FUNC, class ...ARGS>
+ ucl::Result call(FUNC &&func, ARGS &&...args);
+}}
+
+#include "internal.hpp"
+
+#endif // __GALLERY_INTERNAL_H__
--- /dev/null
+/*
+ * 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/util/helpers.h"
+#include "ucl/util/logging.h"
+
+namespace gallery { namespace util { namespace himpl {
+
+ template <class GETTER, class ...ARGS>
+ inline ucl::Result get(GETTER &&getter, bool optional,
+ std::string &result, ARGS &&...args)
+ {
+ char *value = nullptr;
+ const int ret = getter(std::forward<ARGS>(args)..., &value);
+ if ((ret != 0) || (!optional && ucl::isEmpty(value))) {
+ UCL_ELOG("get() failed: %d", ret);
+ return ucl::RES_FAIL;
+ }
+
+ if (value) {
+ result = value;
+ free(value);
+ } else {
+ result.clear();
+ }
+
+ return ucl::RES_OK;
+ }
+
+ template <class GETTER, class V, class ...ARGS>
+ inline ucl::Result get(GETTER &&getter, bool optional,
+ V &result, ARGS &&...args)
+ {
+ V value = {};
+ const int ret = getter(std::forward<ARGS>(args)..., &value);
+ if ((ret != 0) || (!optional && !value)) {
+ UCL_ELOG("get() failed: %d", ret);
+ return ucl::RES_FAIL;
+ }
+
+ result = value;
+
+ return ucl::RES_OK;
+ }
+}}}
+
+namespace gallery { namespace util {
+
+ template <class GETTER, class V, class ...ARGS>
+ inline ucl::Result get(GETTER &&getter, V &result, ARGS &&...args)
+ {
+ return himpl::get(std::forward<GETTER>(getter), true,
+ result, std::forward<ARGS>(args)...);
+ }
+
+ template <class GETTER, class V, class ...ARGS>
+ inline ucl::Result getNz(GETTER &&getter, V &result, ARGS &&...args)
+ {
+ return himpl::get(std::forward<GETTER>(getter), false,
+ result, std::forward<ARGS>(args)...);
+ }
+
+ template <class FUNC, class ...ARGS>
+ inline ucl::Result call(FUNC &&func, ARGS &&...args)
+ {
+ const int ret = func(std::forward<ARGS>(args)...);
+ if (ret != 0) {
+ UCL_ELOG("func() failed: %d", ret);
+ return ucl::RES_FAIL;
+ }
+ return ucl::RES_OK;
+ }
+}}
#include <Ecore_File.h>
#include <storage.h>
+#include <mime_type.h>
#include "BaseJob.h"
#include "common.h"
+namespace gallery { namespace { namespace impl {
+
+ const std::string MIME_PREFIX_IMAGE {"image/"};
+ const std::string MIME_PREFIX_VIDEO {"video/"};
+
+ MediaType getFileMediaType(const std::string &filePath)
+ {
+ const auto ext = util::extractFileExtension(filePath);
+
+ std::string mime;
+ FAIL_RETURN_VALUE(util::get(mime_type_get_mime_type, mime, ext.c_str()),
+ MediaType::OTHERS,
+ "mime_type_get_mime_type() failed!");
+
+ if (util::beginsWith(mime, MIME_PREFIX_IMAGE)) {
+ return MediaType::IMAGE;
+ }
+ if (util::beginsWith(mime, MIME_PREFIX_VIDEO)) {
+ return MediaType::VIDEO;
+ }
+
+ return MediaType::OTHERS;
+ }
+}}}
+
namespace gallery {
using namespace ucl;
MediaItemSRef MediaItem::newInstance(std::string filePath)
{
auto result = makeShared<MediaItem>(FLAGS_SIMPLE_FILE,
- MediaType::IMAGE);
+ impl::getFileMediaType(filePath));
FAIL_RETURN_VALUE(result->prepare(std::move(filePath)), {},
"result->prepare() failed!");
#ifndef __GALLERY_MODEL_COMMON_H__
#define __GALLERY_MODEL_COMMON_H__
-#include "helpers.h"
+#include "internal.h"
#include "../common.h"
+++ /dev/null
-/*
- * 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 "helpers.h"
-
-#include <Ecore_File.h>
-#include <storage.h>
-
-#include "common.h"
-
-namespace gallery { namespace { namespace impl {
-
- constexpr auto UNIQUE_PATH_RESERVE = 10;
-}}}
-
-namespace gallery {
-
- using namespace ucl;
-
- Mutex &getMediaMutex()
- {
- static Mutex mutex{true};
- return mutex;
- }
-
- Result getInternalStorageId(int &result)
- {
- struct StorageIdRec {
- int id;
- bool valid;
- } storageIdRec {0, false};
-
- const int ret = storage_foreach_device_supported(
- [](int storageId, storage_type_e type,
- storage_state_e state, const char *path, void *userData)
- {
- if ((type != STORAGE_TYPE_INTERNAL) ||
- (state != STORAGE_STATE_MOUNTED)) {
- return true;
- }
- auto &storageIdRec = *static_cast<StorageIdRec *>(userData);
- storageIdRec.id = storageId;
- storageIdRec.valid = true;
- return false;
- },
- &storageIdRec);
- if (ret != 0) {
- LOG_RETURN(RES_FAIL,
- "storage_foreach_device_supported() failed: %d", ret);
- }
-
- if (!storageIdRec.valid) {
- LOG_RETURN(RES_FAIL, "Writable internal storage not found!");
- }
-
- result = storageIdRec.id;
-
- return RES_OK;
- }
-}
-
-namespace gallery { namespace util {
-
- std::string extractFileName(const std::string &path)
- {
- const auto bsPos = path.rfind('/');
- if (bsPos == (path.size() - 1)) {
- return {};
- }
- return path.substr(bsPos + 1);
- }
-
- std::string extractExtension(const std::string &name)
- {
- const auto dotPos = name.rfind('.');
- if ((dotPos == std::string::npos) ||
- (dotPos == 0) || (dotPos == (name.size() - 1))) {
- return {};
- }
- return name.substr(dotPos + 1);
- }
-
- void splitFilePath(const std::string &path, std::string &directory,
- std::string &baseName, std::string &extension)
- {
- splitFileName(path, baseName, extension);
- if (isNotEmpty(baseName)) {
- directory = path.substr(0, (path.size() - baseName.size() -
- (isNotEmpty(extension) ? (extension.size() - 1) : 0)));
- } else {
- directory = path;
- }
- }
-
- void splitFileName(const std::string &path,
- std::string &baseName, std::string &extension)
- {
- baseName = extractFileName(path);
- if (isNotEmpty(baseName)) {
- extension = extractExtension(baseName);
- if (isNotEmpty(extension)) {
- baseName.resize(baseName.size() - extension.size() - 1);
- }
- } else {
- extension.clear();
- }
- }
-
- std::string makeUniqueFilePath(const std::string &srcPath,
- const std::string &dstDir)
- {
- std::string baseName;
- std::string extension;
- splitFileName(srcPath, baseName, extension);
-
- std::string result;
- result.reserve(dstDir.size() + baseName.size() +
- extension.size() + impl::UNIQUE_PATH_RESERVE);
-
- result = dstDir;
- if (isNotEmpty(result) && (result.back() != '/')) {
- result += '/';
- }
- result += baseName;
-
- const auto baseSize = result.size();
-
- for (int counter = 2; ; ++counter) {
- if (isNotEmpty(extension)) {
- result += '.';
- result += extension;
- }
- if (!ecore_file_exists(result.c_str())) {
- break;
- }
- result.resize(baseSize);
- result += " (";
- result += std::to_string(counter);
- result += ')';
- }
-
- return result;
- }
-}}
+++ /dev/null
-/*
- * 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_MODEL_HELPERS_H__
-#define __GALLERY_MODEL_HELPERS_H__
-
-#include "ucl/util/threading.h"
-
-#include "model/types.h"
-
-namespace gallery {
-
- MediaType toMediaType(media_content_type_e contentType);
-
- ucl::Mutex &getMediaMutex();
-
- ucl::Result getInternalStorageId(int &result);
-}
-
-namespace gallery { namespace util {
-
- std::string extractFileName(const std::string &path);
-
- std::string extractFileExtension(const std::string &name);
-
- void splitFilePath(const std::string &path, std::string &directory,
- std::string &baseName, std::string &extension);
-
- void splitFileName(const std::string &path,
- std::string &baseName, std::string &extension);
-
- std::string makeUniqueFilePath(const std::string &srcPath,
- const std::string &dstDir);
-}}
-
-#include "helpers.hpp"
-
-#endif // __GALLERY_MODEL_HELPERS_H__
+++ /dev/null
-/*
- * 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 gallery {
-
- inline MediaType toMediaType(const media_content_type_e contentType)
- {
- switch (contentType) {
- case MEDIA_CONTENT_TYPE_IMAGE: return MediaType::IMAGE;
- case MEDIA_CONTENT_TYPE_VIDEO: return MediaType::VIDEO;
- case MEDIA_CONTENT_TYPE_SOUND: return MediaType::SOUND;
- case MEDIA_CONTENT_TYPE_MUSIC: return MediaType::MUSIC;
- default:
- break;
- }
- return MediaType::OTHERS;
- }
-}
--- /dev/null
+/*
+ * 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 "internal.h"
+
+#include <Ecore_File.h>
+#include <storage.h>
+
+#include "common.h"
+
+namespace gallery { namespace { namespace impl {
+
+ constexpr auto UNIQUE_PATH_RESERVE = 10;
+}}}
+
+namespace gallery {
+
+ using namespace ucl;
+
+ Mutex &getMediaMutex()
+ {
+ static Mutex mutex{true};
+ return mutex;
+ }
+
+ Result getInternalStorageId(int &result)
+ {
+ struct StorageIdRec {
+ int id;
+ bool valid;
+ } storageIdRec {0, false};
+
+ const int ret = storage_foreach_device_supported(
+ [](int storageId, storage_type_e type,
+ storage_state_e state, const char *path, void *userData)
+ {
+ if ((type != STORAGE_TYPE_INTERNAL) ||
+ (state != STORAGE_STATE_MOUNTED)) {
+ return true;
+ }
+ auto &storageIdRec = *static_cast<StorageIdRec *>(userData);
+ storageIdRec.id = storageId;
+ storageIdRec.valid = true;
+ return false;
+ },
+ &storageIdRec);
+ if (ret != 0) {
+ LOG_RETURN(RES_FAIL,
+ "storage_foreach_device_supported() failed: %d", ret);
+ }
+
+ if (!storageIdRec.valid) {
+ LOG_RETURN(RES_FAIL, "Writable internal storage not found!");
+ }
+
+ result = storageIdRec.id;
+
+ return RES_OK;
+ }
+}
+
+namespace gallery { namespace util {
+
+ std::string extractFileName(const std::string &path)
+ {
+ const auto bsPos = path.rfind('/');
+ if (bsPos == (path.size() - 1)) {
+ return {};
+ }
+ return path.substr(bsPos + 1);
+ }
+
+ std::string extractFileExtension(const std::string &name)
+ {
+ const auto dotPos = name.rfind('.');
+ if ((dotPos == std::string::npos) ||
+ (dotPos == 0) || (dotPos == (name.size() - 1))) {
+ return {};
+ }
+ return name.substr(dotPos + 1);
+ }
+
+ void splitFilePath(const std::string &path, std::string &directory,
+ std::string &baseName, std::string &extension)
+ {
+ splitFileName(path, baseName, extension);
+ if (isNotEmpty(baseName)) {
+ directory = path.substr(0, (path.size() - baseName.size() -
+ (isNotEmpty(extension) ? (extension.size() - 1) : 0)));
+ } else {
+ directory = path;
+ }
+ }
+
+ void splitFileName(const std::string &path,
+ std::string &baseName, std::string &extension)
+ {
+ baseName = extractFileName(path);
+ if (isNotEmpty(baseName)) {
+ extension = extractFileExtension(baseName);
+ if (isNotEmpty(extension)) {
+ baseName.resize(baseName.size() - extension.size() - 1);
+ }
+ } else {
+ extension.clear();
+ }
+ }
+
+ std::string makeUniqueFilePath(const std::string &srcPath,
+ const std::string &dstDir)
+ {
+ std::string baseName;
+ std::string extension;
+ splitFileName(srcPath, baseName, extension);
+
+ std::string result;
+ result.reserve(dstDir.size() + baseName.size() +
+ extension.size() + impl::UNIQUE_PATH_RESERVE);
+
+ result = dstDir;
+ if (isNotEmpty(result) && (result.back() != '/')) {
+ result += '/';
+ }
+ result += baseName;
+
+ const auto baseSize = result.size();
+
+ for (int counter = 2; ; ++counter) {
+ if (isNotEmpty(extension)) {
+ result += '.';
+ result += extension;
+ }
+ if (!ecore_file_exists(result.c_str())) {
+ break;
+ }
+ result.resize(baseSize);
+ result += " (";
+ result += std::to_string(counter);
+ result += ')';
+ }
+
+ return result;
+ }
+}}
--- /dev/null
+/*
+ * 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_MODEL_INTERNAL_H__
+#define __GALLERY_MODEL_INTERNAL_H__
+
+#include "ucl/util/threading.h"
+
+#include "model/types.h"
+
+namespace gallery {
+
+ MediaType toMediaType(media_content_type_e contentType);
+
+ ucl::Mutex &getMediaMutex();
+
+ ucl::Result getInternalStorageId(int &result);
+}
+
+namespace gallery { namespace util {
+
+ std::string extractFileName(const std::string &path);
+
+ std::string extractFileExtension(const std::string &name);
+
+ void splitFilePath(const std::string &path, std::string &directory,
+ std::string &baseName, std::string &extension);
+
+ void splitFileName(const std::string &path,
+ std::string &baseName, std::string &extension);
+
+ std::string makeUniqueFilePath(const std::string &srcPath,
+ const std::string &dstDir);
+
+ bool beginsWith(const std::string &container, const std::string &str);
+}}
+
+#include "internal.hpp"
+
+#endif // __GALLERY_MODEL_INTERNAL_H__
--- /dev/null
+/*
+ * 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 gallery {
+
+ inline MediaType toMediaType(const media_content_type_e contentType)
+ {
+ switch (contentType) {
+ case MEDIA_CONTENT_TYPE_IMAGE: return MediaType::IMAGE;
+ case MEDIA_CONTENT_TYPE_VIDEO: return MediaType::VIDEO;
+ case MEDIA_CONTENT_TYPE_SOUND: return MediaType::SOUND;
+ case MEDIA_CONTENT_TYPE_MUSIC: return MediaType::MUSIC;
+ default:
+ break;
+ }
+ return MediaType::OTHERS;
+ }
+}
+
+namespace gallery { namespace util {
+
+ inline bool beginsWith(const std::string &container, const std::string &str)
+ {
+ return (container.compare(0, str.size(), str) == 0);
+ }
+}}
eext_object_event_callback_del(*m_popup, EEXT_CALLBACK_BACK,
CALLBACK_A(AlertDialog::onPopupHWBackKey));
- m_popup.reset();
-
deactivateBy(m_popup.get());
broadcastActivateBy(this);
+ m_popup.reset();
m_rc->unref();
}
}
#include "presenters/NoContentPage.h"
#include "presenters/ThumbnailPage.h"
#include "presenters/ViewerPage.h"
+#include "presenters/VideoPlayerPage.h"
#include "resources.h"
#include "common.h"
{
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_sysEventProvider.addEventHandler(
DELEGATE(Instance::onSysEvent, this));
- m_gallery->getAlbum()->addChangeHandler(WEAK_DELEGATE(
- Instance::onAlbumChanged, asWeak(*this)));
-
return RES_OK;
}
void Instance::onPause()
{
DLOG("PAUSE");
+
+ setInstancePaused(*m_win, true);
}
void Instance::onResume()
{
DLOG("RESUME");
+ setInstancePaused(*m_win, false);
+
if (SCAN_MEDIA_ON_RESUME) {
rescanMediaContent();
}
Result Instance::handleSingleMode(const std::string &operation,
app_control_h appControl)
{
+ FAIL_RETURN(ensureGalleryModel(), "ensureGalleryModel() failed!");
+
if (!m_page) {
if (isEmpty(m_gallery->getAlbum())) {
createNoContentPage();
std::string uri;
FAIL_RETURN(util::getNz(app_control_get_uri, uri, appControl),
"app_control_get_uri() failed!");
- createViewerPage(uri);
+
+ const auto media = MediaItem::newInstance(std::move(uri));
+ if (!media) {
+ LOG_RETURN(RES_FAIL, "MediaItem::newInstance() failed!");
+ }
+
+ switch (media->getType()) {
+ case MediaType::IMAGE:
+ createViewerPage(media);
+ break;
+ case MediaType::VIDEO:
+ createVideoPlayerPage(media);
+ break;
+ default:
+ LOG_RETURN(RES_NOT_SUPPORTED,
+ "Media type is not supported: %d;", media->getType());
+ }
+
} else {
WLOG("Operation not supported for current mode!");
return RES_NOT_SUPPORTED;
return RES_OK;
}
+ Result Instance::ensureGalleryModel()
+ {
+ if (m_gallery) {
+ return RES_FALSE;
+ }
+
+ m_gallery = Gallery::newInstance();
+ if (!m_gallery) {
+ LOG_RETURN(RES_FAIL, "Gallery::newInstance() failed!");
+ }
+
+ m_gallery->getAlbum()->addChangeHandler(WEAK_DELEGATE(
+ Instance::onAlbumChanged, asWeak(*this)));
+
+ return RES_OK;
+ }
+
void Instance::createNoContentPage()
{
DLOG("Creating NoContentPage.");
void Instance::createThumbnailPage()
{
DLOG("Creating ThumbnailPage.");
+ FAIL_RETURN_VOID(ensureGalleryModel(), "ensureGalleryModel() failed!");
+
m_page = ThumbnailPage::Builder().setNaviframe(m_navi).
setAlbum(m_gallery->getAlbum()).
build(DELEGATE(Instance::onPageExitRequest, this));
}
- void Instance::createViewerPage(std::string filePath)
+ void Instance::createViewerPage(const MediaItemSRef &media)
{
DLOG("Creating ViewerPage.");
m_page = ViewerPage::Builder().setNaviframe(m_navi).
- setMedia(MediaItem::newInstance(std::move(filePath))).
+ setMedia(media).
setExitOnZoomOut(false).
build(DELEGATE(Instance::onPageExitRequest, this));
}
+ void Instance::createVideoPlayerPage(const MediaItemSRef &media)
+ {
+ DLOG("Creating VideoPlayerPage.");
+ m_page = VideoPlayerPage::Builder().setNaviframe(m_navi).
+ setMedia(media).
+ build(DELEGATE(Instance::onPageExitRequest, this));
+ }
+
void Instance::onAlbumChanged()
{
if (isEmpty(m_gallery->getAlbum())) {
m_widget->addEventHandler(impl::MORE_ITEM_SELECTED, WEAK_DELEGATE(
MoreOptionsPresenter::onItemSelected, asWeak(*this)));
+ deactivateBy(m_widget.get());
+
return RES_OK;
}
Result Presenter::prepare(ElmWidget &widget)
{
- m_topWidget = asWeak(asWidget(widget.getTopWidget()));
- if (!m_topWidget) {
- LOG_RETURN(RES_FAIL, "m_topWidget is NULL!");
+ m_window = asShared(widget.getWindow());
+ if (!m_window) {
+ LOG_RETURN(RES_FAIL, "m_window is NULL!");
}
- addDeactivatorSource(*m_topWidget);
+ addDeactivatorSource(*m_window);
m_isPrepared = true;
return RES_OK;
}
+ Window &Presenter::getWindow()
+ {
+ return *m_window;
+ }
+
void Presenter::addDeactivatorSource(Widget &source)
{
source.addEventHandler(impl::ACTIVATE_BY,
void Presenter::broadcastDeactivator(const SmartEvent event,
void *const deactivator)
{
- if (m_topWidget) {
- sendDeactivatorInfo(*m_topWidget, event, {deactivator, true});
- } else {
- ELOG("m_topWidget is NULL!");
- }
+ sendDeactivatorInfo(*m_window, event, {deactivator, true});
}
void Presenter::sendDeactivatorInfo(Widget &sender,
--- /dev/null
+/*
+ * 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 "presenters/VideoPlayerPage.h"
+
+#include <efl_util.h>
+
+#include "model/MediaItem.h"
+
+#include "view/TouchParser.h"
+
+#include "resources.h"
+#include "common.h"
+
+namespace gallery { namespace { namespace impl {
+
+ using namespace ucl;
+
+ constexpr auto AUTO_START_TIMEOUT_SEC = 0.3;
+ constexpr auto CONTROLS_PLAYBACK_HIDE_TIMEOUT_SEC = 3.0;
+ constexpr auto CONTROLS_PAUSE_HIDE_TIMEOUT_SEC = 6.0;
+
+ constexpr auto TICK_TIMER_INTERVAL_SEC = 0.1;
+
+ constexpr auto TIME_SEC_MS = 1000;
+ constexpr auto TIME_MIN_SEC = 60;
+ constexpr auto TIME_HOUR_MIN = 60;
+
+ const TString TIME_SHORT_FORMAT {"%02d:%02d / %02d:%02d"};
+ const TString TIME_LONG_FORMAT {"%02d:%02d:%02d / %02d:%02d:%02d"};
+
+ constexpr LayoutTheme LAYOUT_VIDEO_PLAYER
+ {"layout", "gallery", "video_player"};
+
+ constexpr ElmStyle STYLE_VOLUME_ON_BTN {"gallery_video_volume_on"};
+ constexpr ElmStyle STYLE_VOLUME_MUTE_BTN {"gallery_video_volume_mute"};
+ constexpr ElmStyle STYLE_PLAY_BTN {"gallery_video_play"};
+ constexpr ElmStyle STYLE_PAUSE_BTN {"gallery_video_pause"};
+
+ constexpr EdjePart PART_VOLUME_ON_BTN {"gallery.swallow.volume_on"};
+ constexpr EdjePart PART_VOLUME_MUTE_BTN {"gallery.swallow.volume_mute"};
+ constexpr EdjePart PART_PLAY_BTN {"gallery.swallow.play"};
+ constexpr EdjePart PART_PAUSE_BTN {"gallery.swallow.pause"};
+
+ constexpr EdjeSignal SHOW_VOLUME_ON_BTN {"show,volume_on,btn"};
+ constexpr EdjeSignal SHOW_VOLUME_MUTE_BTN {"show,volume_mute,btn"};
+ constexpr EdjeSignal HIDE_VOLUME_BTN {"hide,volume,btn"};
+
+ constexpr EdjeSignal SHOW_PLAY_BTN {"show,play,btn"};
+ constexpr EdjeSignal SHOW_PAUSE_BTN {"show,pause,btn"};
+ constexpr EdjeSignal HIDE_PLAY_PAUSE_BTN {"hide,play_pause,btn"};
+
+ constexpr EdjeSignal SHOW_TEXT {"show,text"};
+ constexpr EdjeSignal HIDE_TEXT {"hide,text"};
+
+ void timeMsToHMS(int timeMs, int &h, int &m, int &s)
+ {
+ int t = (timeMs / TIME_SEC_MS);
+ s = (t % TIME_MIN_SEC);
+ t /= TIME_MIN_SEC;
+ m = (t % TIME_HOUR_MIN);
+ h = (t / TIME_HOUR_MIN);
+ }
+}}}
+
+namespace gallery {
+
+ using namespace ucl;
+
+ // VideoPlayerPage::Builder //
+
+ VideoPlayerPage::Builder::Builder()
+ {
+ }
+
+ VideoPlayerPage::Builder::~Builder()
+ {
+ }
+
+ VideoPlayerPage::Builder &VideoPlayerPage::Builder::setNaviframe(
+ const NaviframeSRef &navi)
+ {
+ m_navi = navi;
+ return *this;
+ }
+
+ VideoPlayerPage::Builder &VideoPlayerPage::Builder::setMedia(
+ const MediaItemSRef &media)
+ {
+ m_media = media;
+ return *this;
+ }
+
+ VideoPlayerPageWRef VideoPlayerPage::Builder::build(
+ const ExitRequestHandler onExitRequest) const
+ {
+ if (!onExitRequest) {
+ LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {},
+ "onExitRequest is NULL");
+ }
+ if (!m_navi) {
+ LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {}, "m_navi is NULL");
+ }
+ if (!m_media) {
+ LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {}, "m_media is NULL");
+ }
+ if (m_media->getType() != MediaType::VIDEO) {
+ LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {}, "Wrong media type");
+ }
+
+ auto result = makeShared<VideoPlayerPage>(
+ m_navi, onExitRequest, m_media);
+
+ FAIL_RETURN_VALUE(result->prepare(), {}, "result->prepare() failed!");
+
+ return result;
+ }
+
+ // VideoPlayerPage //
+
+ VideoPlayerPage::VideoPlayerPage(RefCountObjBase &rc,
+ const NaviframeSRef &navi,
+ const ExitRequestHandler onExitRequest,
+ const MediaItemSRef &media) :
+ Page(rc, navi, onExitRequest),
+ m_media(media),
+ m_player(),
+ m_videoDuration(0),
+ m_autoStartTimer(nullptr),
+ m_controlsHideTimer(nullptr),
+ m_tickTimer(nullptr),
+ m_state(State::PAUSED),
+ m_isControlsVisible(false),
+ m_needAutoStart(true)
+ {
+ }
+
+ VideoPlayerPage::~VideoPlayerPage()
+ {
+ setScreenOlwaysOn(false);
+
+ delRotaryEventHandler(CALLBACK_A(VideoPlayerPage::onRotary), this);
+
+ stopTimer(m_autoStartTimer);
+ stopTimer(m_controlsHideTimer);
+ stopTimer(m_tickTimer);
+
+ if (m_player) {
+ if (getPlayerState() != PLAYER_STATE_IDLE) {
+ FAIL_LOG(util::call(player_unprepare, m_player),
+ "player_unprepare() failed!");
+ }
+ FAIL_LOG(util::call(player_destroy, m_player),
+ "player_destroy() failed!");
+ }
+ }
+
+ Result VideoPlayerPage::prepare()
+ {
+ m_content = Layout::Builder().
+ setTheme(impl::LAYOUT_VIDEO_PLAYER).
+ setIsOwner(true).
+ build(getNaviframe());
+ if (!m_content) {
+ LOG_RETURN(RES_FAIL, "m_content is NULL");
+ }
+
+ FAIL_RETURN(Page::prepare(
+ [this]()
+ {
+ return getNaviframe().push(*m_content, NAVIFRAME_EMPTY);
+ }),
+ "Page::prepare() failed!");
+
+ createImage();
+ FAIL_RETURN(preparePlayer(), "preparePlayer() failed!");
+
+ createControls();
+ updatePlayTimeText();
+
+ m_touchParser = makeShared<TouchParser>(*m_image);
+ m_touchParser->setTapHandler(
+ DELEGATE(VideoPlayerPage::onTap, this));
+
+ getWindow().addEventHandler(INSTANCE_PAUSED, WEAK_DELEGATE(
+ VideoPlayerPage::onInstancePaused, asWeak(*this)));
+ getWindow().addEventHandler(INSTANCE_RESUMED, WEAK_DELEGATE(
+ VideoPlayerPage::onInstanceResumed, asWeak(*this)));
+
+ addRotaryEventHandler(CALLBACK_A(VideoPlayerPage::onRotary), this);
+
+ if (!isInstancePaused(getWindow())) {
+ resetAutoStartTimer();
+ }
+
+ return RES_OK;
+ }
+
+ void VideoPlayerPage::createImage()
+ {
+ m_image = makeShared<Widget>(
+ evas_object_image_filled_add(m_content->getEvas()));
+ show(*m_image);
+
+ m_content->setContent(*m_image);
+ }
+
+ Result VideoPlayerPage::preparePlayer()
+ {
+ FAIL_RETURN(util::getNz(player_create, m_player),
+ "player_create() failed!");
+
+ FAIL_RETURN(util::call(player_set_display_mode, m_player,
+ PLAYER_DISPLAY_MODE_CROPPED_FULL),
+ "player_set_display_mode() failed!");
+
+ FAIL_RETURN(util::call(player_set_display, m_player,
+ PLAYER_DISPLAY_TYPE_EVAS, GET_DISPLAY(m_image->getEo())),
+ "player_set_display() failed!");
+
+ FAIL_RETURN(util::call(player_set_uri, m_player,
+ m_media->getFilePath().c_str()),
+ "player_set_uri() failed!");
+
+ FAIL_RETURN(util::call(player_prepare, m_player),
+ "player_prepare() failed!");
+
+ FAIL_RETURN(util::getNz(player_get_duration, m_videoDuration, m_player),
+ "player_get_duration() failed!");
+
+ FAIL_RETURN(seekToStart(), "seekToStart() failed!");
+
+ FAIL_RETURN(util::call(player_set_completed_cb, m_player,
+ CALLBACK_B(VideoPlayerPage::onPlaybackComplete), this),
+ "player_set_completed_cb() failed!");
+
+ FAIL_RETURN(util::call(player_set_interrupted_cb, m_player,
+ CALLBACK_B(VideoPlayerPage::onPlaybackInterrupted),
+ this), "player_set_interrupted_cb() failed!");
+
+ return RES_OK;
+ }
+
+ Result VideoPlayerPage::seekToStart()
+ {
+ FAIL_RETURN(util::call(player_set_play_position, m_player, true, 0,
+ CALLBACK_B(VideoPlayerPage::onSeekComplete), this),
+ "player_set_play_position() failed!");
+ return RES_OK;
+ }
+
+ void VideoPlayerPage::createControls()
+ {
+ createButton(impl::STYLE_VOLUME_ON_BTN, impl::PART_VOLUME_ON_BTN,
+ WEAK_DELEGATE(VideoPlayerPage::onVolumeOnBtnClick,
+ asWeak(*this)));
+
+ createButton(impl::STYLE_VOLUME_MUTE_BTN, impl::PART_VOLUME_MUTE_BTN,
+ WEAK_DELEGATE(VideoPlayerPage::onVolumeMuteBtnClick,
+ asWeak(*this)));
+
+ createButton(impl::STYLE_PLAY_BTN, impl::PART_PLAY_BTN,
+ WEAK_DELEGATE(VideoPlayerPage::onPlayBtnClick,
+ asWeak(*this)));
+
+ createButton(impl::STYLE_PAUSE_BTN, impl::PART_PAUSE_BTN,
+ WEAK_DELEGATE(VideoPlayerPage::onPauseBtnClick,
+ asWeak(*this)));
+ }
+
+ void VideoPlayerPage::createButton(const ElmStyle style,
+ const EdjePart part, const WidgetEventHandler &handler)
+ {
+ const auto btn = makeShared<StyledWidget>(elm_button_add(*m_content));
+ btn->setStyle(style);
+ show(*btn);
+
+ m_content->setContent(*btn, part);
+
+ btn->addEventHandler(BTN_CLICKED, handler);
+ }
+
+ bool VideoPlayerPage::resetTimer(Ecore_Timer *&timer,
+ const double timeout, Ecore_Task_Cb func)
+ {
+ stopTimer(timer);
+
+ timer = ecore_timer_add(timeout, func, this);
+ if (!timer) {
+ LOG_RETURN_VALUE(RES_FAIL, false, "ecore_timer_add() failed!");
+ }
+
+ return true;
+ }
+
+ void VideoPlayerPage::stopTimer(Ecore_Timer *&timer)
+ {
+ if (timer) {
+ ecore_timer_del(timer);
+ timer = nullptr;
+ }
+ }
+
+ bool VideoPlayerPage::resetAutoStartTimer()
+ {
+ return resetTimer(m_autoStartTimer, impl::AUTO_START_TIMEOUT_SEC,
+ CALLBACK_A(VideoPlayerPage::onAutoStartTimer));
+ }
+
+ bool VideoPlayerPage::resetControlsHideTimer()
+ {
+ if (m_isPlaybackCompleted) {
+ stopTimer(m_controlsHideTimer);
+ return true;
+ }
+ return resetTimer(m_controlsHideTimer,
+ ((m_state == State::PLAYING) ?
+ impl::CONTROLS_PLAYBACK_HIDE_TIMEOUT_SEC :
+ impl::CONTROLS_PAUSE_HIDE_TIMEOUT_SEC
+ ),
+ CALLBACK_A(VideoPlayerPage::onControlsHideTimer));
+ }
+
+ bool VideoPlayerPage::resetTickTimer()
+ {
+ return resetTimer(m_tickTimer, impl::TICK_TIMER_INTERVAL_SEC,
+ CALLBACK_A(VideoPlayerPage::onTickTimer));
+ }
+
+ void VideoPlayerPage::showControls()
+ {
+ if (!m_isControlsVisible) {
+ m_isControlsVisible = true;
+
+ if (m_state == State::PLAYING) {
+ m_content->emit(impl::SHOW_PAUSE_BTN);
+ resetTickTimer();
+ updatePlayTimeText();
+ } else {
+ m_content->emit(impl::SHOW_PLAY_BTN);
+ }
+
+ m_content->emit(impl::SHOW_TEXT);
+ }
+
+ resetControlsHideTimer();
+ }
+
+ void VideoPlayerPage::hideControls()
+ {
+ if (m_isControlsVisible) {
+ m_isControlsVisible = false;
+
+ m_content->emit(impl::HIDE_VOLUME_BTN);
+ m_content->emit(impl::HIDE_PLAY_PAUSE_BTN);
+ m_content->emit(impl::HIDE_TEXT);
+
+ stopTimer(m_tickTimer);
+ stopTimer(m_controlsHideTimer);
+ }
+ }
+
+ bool VideoPlayerPage::updatePlayTimeText()
+ {
+ int playPosition = 0;
+
+ if (isBad(util::get(player_get_play_position,
+ playPosition, m_player))) {
+ ELOG("player_get_play_position() failed!");
+ return false;
+ }
+
+ updatePlayTimeText(std::min(playPosition, m_videoDuration));
+
+ return true;
+ }
+
+ void VideoPlayerPage::updatePlayTimeText(const int timeMs)
+ {
+ int posH = 0;
+ int posM = 0;
+ int posS = 0;
+ impl::timeMsToHMS(timeMs, posH, posM, posS);
+
+ int durH = 0;
+ int durM = 0;
+ int durS = 0;
+ impl::timeMsToHMS(m_videoDuration, durH, durM, durS);
+
+ if (durH == 0) {
+ m_content->setText(impl::TIME_SHORT_FORMAT.format(
+ posM, posS, durM, durS));
+ } else {
+ m_content->setText(impl::TIME_LONG_FORMAT.format(
+ posH, posM, posS, durH, durM, durS));
+ }
+ }
+
+ player_state_e VideoPlayerPage::getPlayerState() const
+ {
+ player_state_e result = PLAYER_STATE_NONE;
+ FAIL_LOG(util::getNz(player_get_state, result, m_player),
+ "player_get_state() failed!");
+ return result;
+ }
+
+ void VideoPlayerPage::startPlayback()
+ {
+ if (m_state != State::PAUSED) {
+ return;
+ }
+ m_state = State::PLAYING;
+
+ const auto playerState = getPlayerState();
+ switch (playerState) {
+ case PLAYER_STATE_READY:
+ case PLAYER_STATE_PAUSED:
+ if (m_isPlaybackCompleted) {
+ m_isPlaybackCompleted = false;
+ FAIL_LOG(seekToStart(), "seekToStart() failed!");
+ } else {
+ FAIL_LOG(util::call(player_start, m_player),
+ "player_start() failed!");
+ }
+ break;
+ default:
+ WLOG("Unexpected player state: %d;", playerState);
+ break;
+ }
+
+ setScreenOlwaysOn(true);
+ resetTickTimer();
+ stopTimer(m_autoStartTimer);
+ m_needAutoStart = false;
+
+ if (m_isControlsVisible) {
+ m_content->emit(impl::SHOW_PAUSE_BTN);
+ }
+ }
+
+ void VideoPlayerPage::pausePlayback()
+ {
+ if (m_state != State::PLAYING) {
+ return;
+ }
+ m_state = State::PAUSED;
+
+ const auto playerState = getPlayerState();
+ switch (playerState) {
+ case PLAYER_STATE_PLAYING:
+ FAIL_LOG(util::call(player_pause, m_player),
+ "player_pause() failed!");
+ break;
+ default:
+ WLOG("Unexpected player state: %d;", playerState);
+ break;
+ }
+
+ setScreenOlwaysOn(false);
+ stopTimer(m_tickTimer);
+ updatePlayTimeText();
+
+ if (m_isControlsVisible) {
+ m_content->emit(impl::SHOW_PLAY_BTN);
+ }
+ }
+
+ void VideoPlayerPage::setScreenOlwaysOn(bool isAlwaysOn)
+ {
+ efl_util_set_window_screen_mode(getWindow(),
+ (isAlwaysOn ? EFL_UTIL_SCREEN_MODE_ALWAYS_ON :
+ EFL_UTIL_SCREEN_MODE_DEFAULT));
+ }
+
+ void VideoPlayerPage::onPlaybackComplete()
+ {
+ m_isPlaybackCompleted = true;
+ pausePlayback();
+ showControls();
+ }
+
+ void VideoPlayerPage::onPlaybackInterrupted(player_interrupted_code_e code)
+ {
+ if (code != PLAYER_INTERRUPTED_COMPLETED) {
+ pausePlayback();
+ showControls();
+ }
+ }
+
+ void VideoPlayerPage::onSeekComplete()
+ {
+ if ((m_state == State::PLAYING) &&
+ (getPlayerState() != PLAYER_STATE_PLAYING)) {
+ FAIL_LOG(util::call(player_start, m_player),
+ "player_start() failed!");
+ }
+ }
+
+ Eina_Bool VideoPlayerPage::onAutoStartTimer()
+ {
+ m_autoStartTimer = nullptr;
+
+ startPlayback();
+
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ Eina_Bool VideoPlayerPage::onControlsHideTimer()
+ {
+ m_controlsHideTimer = nullptr;
+
+ hideControls();
+
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ Eina_Bool VideoPlayerPage::onTickTimer()
+ {
+ if (!updatePlayTimeText()) {
+ m_tickTimer = nullptr;
+ return ECORE_CALLBACK_CANCEL;
+ }
+ return ECORE_CALLBACK_RENEW;
+ }
+
+ void VideoPlayerPage::onVolumeOnBtnClick(Widget &sender, void *eventInfo)
+ {
+ }
+
+ void VideoPlayerPage::onVolumeMuteBtnClick(Widget &sender, void *eventInfo)
+ {
+ }
+
+ void VideoPlayerPage::onPlayBtnClick(Widget &sender, void *eventInfo)
+ {
+ startPlayback();
+ resetControlsHideTimer();
+ }
+
+ void VideoPlayerPage::onPauseBtnClick(Widget &sender, void *eventInfo)
+ {
+ pausePlayback();
+ resetControlsHideTimer();
+ }
+
+ void VideoPlayerPage::onTap(int x, int y)
+ {
+ if (m_isControlsVisible) {
+ hideControls();
+ } else {
+ showControls();
+ }
+ }
+
+ Eina_Bool VideoPlayerPage::onRotary(Eext_Rotary_Event_Info *info)
+ {
+ showControls();
+ return EINA_TRUE;
+ }
+
+ void VideoPlayerPage::onInstancePaused(Widget &sender, void *eventInfo)
+ {
+ pausePlayback();
+ stopTimer(m_autoStartTimer);
+ stopTimer(m_controlsHideTimer);
+ }
+
+ void VideoPlayerPage::onInstanceResumed(Widget &sender, void *eventInfo)
+ {
+ if (m_needAutoStart) {
+ resetAutoStartTimer();
+ } else {
+ showControls();
+ }
+ }
+}
if (!m_media) {
LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {}, "m_media is NULL");
}
+ if (m_media->getType() != MediaType::IMAGE) {
+ LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {}, "Wrong media type");
+ }
auto result = makeShared<ViewerPage>(
m_navi, onExitRequest, m_media, m_exitOnZoomOut);
#ifndef __GALLERY_PRESENTERS_COMMON_H__
#define __GALLERY_PRESENTERS_COMMON_H__
+#include "internal.h"
+
#include "../view/common.h"
#endif // __GALLERY_PRESENTERS_COMMON_H__
--- /dev/null
+/*
+ * 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 "internal.h"
+
+#include "common.h"
+
+namespace gallery { namespace { namespace impl {
+
+ using namespace ucl;
+
+ constexpr EoDataKey INSTANCE_PTR {"gallery,instance,data,ptr"};
+}}}
+
+namespace gallery {
+
+ using namespace ucl;
+
+ void setInstancePaused(ucl::Window &win, const bool value)
+ {
+ win.setData(impl::INSTANCE_PTR, reinterpret_cast<void *>(value));
+ win.callEvent((value ? INSTANCE_PAUSED : INSTANCE_RESUMED), nullptr);
+ }
+
+ bool isInstancePaused(const ucl::Window &win)
+ {
+ return (reinterpret_cast<intptr_t>(
+ win.getData(impl::INSTANCE_PTR)) != 0);
+ }
+}
--- /dev/null
+/*
+ * 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_PRESENTERS_INTERNAL_H__
+#define __GALLERY_PRESENTERS_INTERNAL_H__
+
+#include "ucl/gui/Window.h"
+
+namespace gallery {
+
+ constexpr ucl::SmartEvent INSTANCE_PAUSED {"gallery,instance,paused"};
+ constexpr ucl::SmartEvent INSTANCE_RESUMED {"gallery,instance,resumed"};
+
+ void setInstancePaused(ucl::Window &win, bool value);
+ bool isInstancePaused(const ucl::Window &win);
+}
+
+#endif // __GALLERY_PRESENTERS_INTERNAL_H__
<app-control>
<operation name="http://tizen.org/appcontrol/operation/view"/>
<mime name="image/*"/>
+ <mime name="video/*"/>
</app-control>
</ui-application>
<privileges>