#include "Page.h"
+#include "IMoreOptionsListener.h"
+
namespace gallery {
- class ViewerPage final : public Page {
+ class ViewerPage final : public Page,
+ private IMoreOptionsListener {
public:
class Builder {
public:
void onZoomEnd(ucl::Widget &widget, void *eventInfo);
void onDoubleTap(int x, int y);
+ void onJobComplete();
+
+ // Presenter //
+
+ virtual void onActivateBy(const DeactivatorInfo &info) final override;
+ virtual void onDeactivateBy(const DeactivatorInfo &info) final override;
+
// Page //
virtual void onBackKey() final override;
+ // IMoreOptionsListener //
+
+ virtual void onMoreOptionClicked(MoreOptionsPresenter &sender,
+ const MoreOption &option) final override;
+
private:
const MediaItemSRef m_media;
const bool m_exitOnZoomOut;
ImageViewerSRef m_imageViewer;
TouchParserSRef m_touchParser;
+ IJobSRef m_job;
+ PageContentSRef m_content;
+ MoreOptionsPresenterSRef m_more;
+ ProcessingPresenterSRef m_processing;
};
}
return result;
}
+ // MediaItem::Saver //
+
+ class MediaItem::Saver final : public BaseJob {
+ public:
+ friend class MediaItem::SaverBuilder;
+ Saver(const NotiHandler &onComplete,
+ const MediaItemSRef &item) :
+ BaseJob(onComplete, false),
+ m_item(item)
+ {
+ }
+
+ protected:
+ // BaseJob //
+ virtual Result execute() final override
+ {
+ FAIL_RETURN(m_item->saveToDevice(),
+ "m_item->saveToDevice() failed!");
+ return RES_OK;
+ }
+
+ private:
+ const MediaItemSRef m_item;
+ };
+
+ // MediaItem::SaverBuilder //
+
+ MediaItem::SaverBuilder &MediaItem::SaverBuilder::
+ setItem(const MediaItemSRef &item)
+ {
+ m_item = item;
+ return *this;
+ }
+
+ IJobSRef MediaItem::SaverBuilder::build(
+ const NotiHandler &onComplete) const
+ {
+ if (!onComplete) {
+ LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {}, "onComplete is NULL!");
+ }
+ if (!m_item) {
+ LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {}, "m_item is NULL!");
+ }
+
+ auto result = makeShared<Saver>(onComplete, m_item);
+
+ FAIL_RETURN_VALUE(result->prepare(), {}, "result->prepare() failed!");
+
+ return result;
+ }
+
// MediaItem //
MediaItem::MediaItem(const int flags, const MediaType type) :
#include "presenters/ViewerPage.h"
#include "model/MediaItem.h"
+#include "model/IJob.h"
+#include "view/PageContent.h"
#include "view/ImageViewer.h"
#include "view/TouchParser.h"
+#include "presenters/MoreOptionsPresenter.h"
+#include "presenters/ProcessingPresenter.h"
+
+#include "resources.h"
#include "common.h"
+namespace gallery { namespace { namespace impl {
+
+ enum {
+ MORE_OPTION_ID_SAVE
+ };
+}}}
+
namespace gallery {
using namespace ucl;
ViewerPage::~ViewerPage()
{
+ if (m_more) {
+ m_more->setOpened(false);
+ }
}
Result ViewerPage::prepare()
{
- const bool hasThumb = (m_media->getFlags() & MediaItem::FLAG_THUMBNAIL);
+ const int mediaFlags = m_media->getFlags();
+ const bool canSave = (mediaFlags & MediaItem::FLAG_SAVE);
+ const bool hasThumb = (mediaFlags & MediaItem::FLAG_THUMBNAIL);
m_imageViewer = ImageViewer::Builder().
setHighResImagePath(m_media->getFilePath()).
LOG_RETURN(RES_FAIL, "ImageViewer::build() failed!");
}
+ ElmWidget *rootWidget = m_imageViewer.get();
+
+ if (canSave) {
+ m_content = PageContent::Builder().
+ setFlags(PageContent::FLAG_MORE_OPTIONS).
+ build(getNaviframe());
+ if (!m_content) {
+ LOG_RETURN(RES_FAIL, "PageContent::build() failed!");
+ }
+
+ rootWidget = m_content.get();
+ m_content->set(*m_imageViewer);
+
+ m_more = MoreOptionsPresenter::Builder().
+ addOption({impl::MORE_OPTION_ID_SAVE,
+ STR_SAVE_TO_GEAR, nullptr,
+ getImageTheme(ICON_MORE_OPT_SAVE)}).
+ build(*m_content);
+ if (!m_more) {
+ LOG_RETURN(RES_FAIL, "MoreOptionsPresenter::build() failed!");
+ }
+
+ m_content->set(m_more->getWidget(),
+ PageContent::Part::MORE_OPTIONS);
+ addDeactivatorSource(m_more->getWidget());
+
+ m_more->setListener(asWeakThis<IMoreOptionsListener>(this));
+ }
+
if (hasThumb) {
FAIL_RETURN(m_media->getThumbnailPath(DELEGATE(
ViewerPage::onThumbnail, this)),
WEAK_DELEGATE(ViewerPage::onZoomEnd, asWeak(*this)));
FAIL_RETURN(Page::prepare(
- [this]()
+ [this, rootWidget]()
{
const auto topItem = getNaviframe().getTopItem();
if (topItem) {
return getNaviframe().insertAfter(topItem,
- *m_imageViewer, NAVIFRAME_EMPTY);
+ *rootWidget, NAVIFRAME_EMPTY);
}
- return getNaviframe().push(*m_imageViewer, NAVIFRAME_EMPTY);
+ return getNaviframe().push(*rootWidget, NAVIFRAME_EMPTY);
}),
"Page::prepare() failed!");
}
}
+ void ViewerPage::onActivateBy(const DeactivatorInfo &info)
+ {
+ if (m_more && (info.deactivator == &getNaviframe())) {
+ m_more->activateBy(info.deactivator);
+ }
+ }
+
+ void ViewerPage::onDeactivateBy(const DeactivatorInfo &info)
+ {
+ if (m_more && (info.deactivator == &getNaviframe())) {
+ m_more->deactivateBy(info.deactivator);
+ }
+ }
+
void ViewerPage::onBackKey()
{
if (m_imageViewer->isZoomedOut()) {
m_imageViewer->zoomOut();
}
}
+
+ void ViewerPage::onMoreOptionClicked(MoreOptionsPresenter &sender,
+ const MoreOption &option)
+ {
+ sender.setOpened(false);
+
+ if (m_job) {
+ LOG_RETURN_VOID(RES_ILLEGAL_STATE, "m_job is not NULL");
+ }
+
+ m_job = MediaItem::SaverBuilder().
+ setItem(m_media).
+ build(WEAK_DELEGATE(ViewerPage::onJobComplete, asWeak(*this)));
+ if (!m_job) {
+ LOG_RETURN_VOID(RES_FAIL,
+ "MediaItem::SaverBuilder::build() failed!");
+ }
+
+ m_processing = ProcessingPresenter::Builder().
+ setProcessingText(STR_SAVING).
+ build(*m_content);
+ }
+
+ void ViewerPage::onJobComplete()
+ {
+ if (m_processing) {
+ if (isGood(m_job->getResult())) {
+ m_processing->complete(STR_SAVED,
+ ProcessingPresenter::IconType::CHECK);
+ } else {
+ m_processing->complete(STR_FAILED);
+ }
+ m_processing.reset();
+ }
+
+ m_job.reset();
+ }
}