static GallerySRef newInstance();
~Gallery();
+ // TODO Temporary feature while support only offline mode
+ void updateAlbum();
+
IMediaAlbumSRef getAlbum();
private:
using EachCb = ucl::Delegate<bool(MediaItemSRef &&media)>;
public:
+ virtual void addChangeHandler(const NotiHandler &handler) = 0;
+ virtual void delChangeHandler(const NotiHandler &handler) = 0;
+
virtual ucl::Result forEachMedia(EachCb cb) const = 0;
virtual ucl::Result getMediaCount(int &count) const = 0;
+
+ virtual void defragment() = 0;
};
// Non-member functions //
m_isMediaDbConnected = true;
- m_album = GalleryAlbum::newInstance();
- if (!m_album) {
+ auto album = GalleryAlbum::newInstance();
+ if (!album) {
LOG_RETURN(RES_FAIL, "GalleryAlbum::newInstance() failed!");
}
+ FAIL_RETURN(album->update(), "album->update() failed!");
+
+ m_album = std::move(album);
+
return RES_OK;
}
+ void Gallery::updateAlbum()
+ {
+ const auto album = dynamic_cast<GalleryAlbum *>(m_album.get());
+ if (album) {
+ album->update();
+ } else {
+ ELOG("m_album is not a GalleryAlbum!");
+ }
+ }
+
IMediaAlbumSRef Gallery::getAlbum()
{
return m_album;
using namespace ucl;
GalleryAlbum::GalleryAlbum() :
- m_filter(nullptr)
+ m_filter(nullptr),
+ m_isValid(false)
{
}
return RES_OK;
}
- Result GalleryAlbum::forEachMedia(EachCb cb) const
+ Result GalleryAlbum::update()
{
- MutexLock lock(getMediaMutex());
-
- const int ret = media_info_foreach_media_from_db(m_filter,
- [](media_info_h media, void *user_data)
- {
- auto item = MediaItem::newInstance(media);
- if (!item) {
- ELOG("MediaItem::newInstance() failed! Skipping");
+ Items newItems;
+
+ {
+ MutexLock lock(getMediaMutex());
+
+ const int ret = media_info_foreach_media_from_db(m_filter,
+ [](media_info_h media, void *user_data)
+ {
+ Items &newItems = (*static_cast<Items *>(user_data));
+ auto item = MediaItem::newInstance(media);
+ if (!item) {
+ ELOG("MediaItem::newInstance() failed! Skipping");
+ return true;
+ }
+ newItems.emplace_back(std::move(item));
return true;
- }
- return (*static_cast<EachCb *>(user_data))(std::move(item));
- },
- &cb);
+ },
+ &newItems);
- if (ret != 0) {
- ELOG("media_info_foreach_media_from_db() failed: %d", ret);
- return RES_FAIL;
+ if (ret != 0) {
+ ELOG("media_info_foreach_media_from_db() failed: %d", ret);
+ return RES_FAIL;
+ }
}
+ swap(newItems, m_items);
+ m_isValid = true;
+
+ m_onChange.dispatch();
+
return RES_OK;
}
- Result GalleryAlbum::getMediaCount(int &count) const
+ void GalleryAlbum::addChangeHandler(const NotiHandler &handler)
{
- MutexLock lock(getMediaMutex());
+ m_onChange += handler;
+ }
+
+ void GalleryAlbum::delChangeHandler(const NotiHandler &handler)
+ {
+ m_onChange -= handler;
+ }
- const int ret = media_info_get_media_count_from_db(m_filter, &count);
- if ((ret != 0) || (count < 0)) {
- count = 0;
- LOG_RETURN(RES_FAIL,
- "media_info_foreach_media_from_db() failed: %d", ret);
+ Result GalleryAlbum::forEachMedia(EachCb cb) const
+ {
+ if (!m_isValid) {
+ LOG_RETURN(RES_INVALID_DATA, "m_isValid: false;");
}
+ for (auto item: m_items) {
+ if (!item->isValid()) {
+ WLOG("Fragmented!");
+ } else if (!cb(std::move(item))) {
+ break;
+ }
+ }
+
+ return RES_OK;
+ }
+
+ Result GalleryAlbum::getMediaCount(int &count) const
+ {
+ if (!m_isValid) {
+ LOG_RETURN(RES_INVALID_DATA, "m_isValid: false;");
+ }
+
+ count = m_items.size();
+
return RES_OK;
}
+
+ void GalleryAlbum::defragment()
+ {
+ if (!m_isValid) {
+ LOG_RETURN_VOID(RES_INVALID_DATA, "m_isValid: false;");
+ }
+
+ const auto newEnd = std::remove_if(
+ m_items.begin(), m_items.end(),
+ [](const MediaItemSRef &item)
+ {
+ return !item->isValid();
+ });
+
+ if (newEnd != m_items.end()) {
+ m_items.erase(newEnd, m_items.end());
+ m_onChange.dispatch();
+ }
+ }
}
#ifndef __GALLERY_MODEL_GALLERY_ALBUM_H__
#define __GALLERY_MODEL_GALLERY_ALBUM_H__
+#include <vector>
+
+#include "ucl/misc/Event.h"
+
#include "model/IMediaAlbum.h"
namespace gallery {
static GalleryAlbumSRef newInstance();
virtual ~GalleryAlbum();
+ ucl::Result update();
+
// IMediaAlbum //
+ virtual void addChangeHandler(
+ const NotiHandler &handler) final override;
+ virtual void delChangeHandler(
+ const NotiHandler &handler) final override;
+
virtual ucl::Result forEachMedia(EachCb cb) const final override;
virtual ucl::Result getMediaCount(int &count) const final override;
+ virtual void defragment() final override;
+
private:
friend class ucl::RefCountObj<GalleryAlbum>;
GalleryAlbum();
ucl::Result prepare();
+ private:
+ using Items = std::vector<MediaItemSRef>;
+
private:
filter_h m_filter;
+ ucl::Event<NotiHandler> m_onChange;
+ Items m_items;
+ bool m_isValid;
};
}
m_isScanInProgress = false;
+ m_gallery->updateAlbum();
+
const auto thumbPage = dynamicRefCast<ThumbnailPage>(m_page);
if (isNotEmpty(m_gallery->getAlbum())) {
void Page::dispatchTopPageChanged()
{
- m_navi->callEvent(impl::TOP_PAGE_CHANGED, nullptr);
+ if (!m_navi->isInTransition()) {
+ m_navi->callEvent(impl::TOP_PAGE_CHANGED, nullptr);
+ } else {
+ WLOG("Forcig Transition Finished!");
+ m_navi->setInTransition(false);
+ }
}
void Page::onItemDel(Evas_Object *obj, void *eventInfo)
};
public:
+ void setInTransition(bool inTransition);
bool isInTransition() const;
void setAutoBackBtn(bool value);
private:
friend class RefCountObj<Naviframe>;
- friend class NaviItem;
Naviframe(RefCountObjBase &rc, Evas_Object *eo);
- void startTransition();
-
void onTransitionFinished(Widget &widget, void *eventInfo);
private:
{
auto result = elm_naviframe_item_pop(getEo());
if (getBottomItem()) {
- startTransition();
+ setInTransition(true);
}
return result;
}
nullptr, backBtn, moreBtn, content, style.name));
result.setTitle(title);
if (result != getBottomItem()) {
- startTransition();
+ setInTransition(true);
}
return result;
}
bool isEmpty() const;
template <class ...ARGS>
- void invoke(ARGS &&...args);
+ void dispatch(ARGS &&...args);
template <class PREDICATE, class ...ARGS>
- void invokePred(PREDICATE &&pred, ARGS &&...args);
+ void dispatchPred(PREDICATE &&pred, ARGS &&...args);
private:
template <class DO_INVOKE, class ...ARGS>
- void invokeImpl(const DO_INVOKE &doInvoke, ARGS &&...args);
+ void dispatchImpl(const DO_INVOKE &doInvoke, ARGS &&...args);
void lock();
void unlock();
template <class DELEGATE>
template <class ...ARGS>
- void Event<DELEGATE>::invoke(ARGS &&...args)
+ void Event<DELEGATE>::dispatch(ARGS &&...args)
{
- invokeImpl(
+ dispatchImpl(
[](const DELEGATE &delegate, ARGS &&...args)
{
delegate(std::forward<ARGS>(args)...);
template <class DELEGATE>
template <class PREDICATE, class ...ARGS>
- void Event<DELEGATE>::invokePred(PREDICATE &&pred, ARGS &&...args)
+ void Event<DELEGATE>::dispatchPred(PREDICATE &&pred, ARGS &&...args)
{
- invokeImpl(
+ dispatchImpl(
[&pred](const DELEGATE &delegate, ARGS &&...args)
{
return impl::doInvokePred(std::forward<PREDICATE>(pred),
template <class DELEGATE>
template <class DO_INVOKE, class ...ARGS>
- void Event<DELEGATE>::invokeImpl(const DO_INVOKE &doInvoke, ARGS &&...args)
+ void Event<DELEGATE>::dispatchImpl(const DO_INVOKE &doInvoke, ARGS &&...args)
{
lock();
- for (size_t i = 0; i < m_delegates.size(); ++i) {
+ const auto size = m_delegates.size();
+ for (size_t i = 0; i < size; ++i) {
const auto &delegate = m_delegates[i];
if (delegate) {
if (!doInvoke(delegate, std::forward<ARGS>(args)...)) {
void SysEventProvider::dispatch(SysEvent sysEvent)
{
- m_event.invoke(sysEvent);
+ m_event.dispatch(sysEvent);
}
}
elm_naviframe_item_pop_to(getIt());
if (needStartTransition) {
- navi->startTransition();
+ navi->setInTransition(true);
}
}
elm_naviframe_item_promote(getIt());
if (needStartTransition) {
- navi->startTransition();
+ navi->setInTransition(true);
}
}
}
Naviframe::onTransitionFinished, asWeak(*this)));
}
- void Naviframe::startTransition()
+ void Naviframe::setInTransition(const bool inTransition)
{
- if (!m_isInTransition) {
- m_isInTransition = true;
- callEvent(NAVI_TRANSITION_STARTED);
+ if (inTransition != m_isInTransition) {
+ m_isInTransition = inTransition;
+ if (inTransition) {
+ callEvent(NAVI_TRANSITION_STARTED);
+ } else {
+ callEvent(NAVI_TRANSITION_FINISHED);
+ }
}
}