target: "gallery.swallow.progress";
target: "elm.text";
}
+ program { "gallery,show,bg";
+ signal: "gallery,show,bg";
+ source: "";
+ action: STATE_SET "visible";
+ target: "bg";
+ }
program { "gallery,hide";
signal: "gallery,hide";
source: "";
class IMoreOptionsListener : public ucl::Polymorphic {
public:
- virtual void onMoreOptionsOpened(MoreOptionsPresenter &sender) = 0;
- virtual void onMoreOptionsClosed(MoreOptionsPresenter &sender) = 0;
virtual void onMoreOptionClicked(MoreOptionsPresenter &sender,
const MoreOption &option) = 0;
virtual void onMoreOptionSelected(MoreOptionsPresenter &sender,
const MoreOption &option) {};
+ virtual void onMoreOptionsOpened(MoreOptionsPresenter &sender) {};
+ virtual void onMoreOptionsClosed(MoreOptionsPresenter &sender) {};
};
}
#include "view/IImageGridListener.h"
+#include "IMoreOptionsListener.h"
+
namespace gallery {
class PreviewPage final : public Page,
- private IImageGridListener {
+ private IImageGridListener,
+ private IMoreOptionsListener {
public:
class Builder {
public:
void onAlbumChanged();
bool onEachMedia(MediaItemSRef &&media);
+ void closeTempViews();
void switchToSelectMode(int itemIndex);
void switchToNormalMode();
void toggleItemSelected(int itemIndex);
void onPageExitRequest(Page &page);
+ bool onAlertEvent(AlertDialog &dialog, int event);
+ void onJobComplete();
+
+ // Presenter //
+
+ virtual void onActivateBy(const DeactivatorInfo &info) final override;
+ virtual void onDeactivateBy(const DeactivatorInfo &info) final override;
+
// Page //
- virtual void onActivate() final override;
- virtual void onDeactivate() final override;
virtual void onBackKey() final override;
// IImageGridListener //
virtual void onItemUnrealized(int itemIndex) final override;
virtual void onItemEvent(int itemIndex,
int event, int x, int y) final override;
- virtual void onTransitionFinished() final override;
+
+ // IMoreOptionsListener //
+
+ virtual void onMoreOptionClicked(MoreOptionsPresenter &sender,
+ const MoreOption &option) final override;
private:
class Item;
const IMediaAlbumSRef m_album;
ImageGridSRef m_imageGrid;
std::vector<ItemUPtr> m_items;
+ IJobSRef m_job;
+ PageContentSRef m_content;
+ MoreOptionsPresenterSRef m_more;
+ AlertDialogWRef m_alert;
+ ProcessingPresenterSRef m_processing;
PageWRef m_page;
};
}
public:
Builder();
Builder &setProcessingText(ucl::TString text);
- Builder &setCompleteText(ucl::TString text);
- Builder &setIconType(IconType value);
Builder &setForceProgress(bool value);
ProcessingPresenterSRef build(ucl::ElmWidget &parent) const;
private:
ucl::TString m_processingText;
- ucl::TString m_completeText;
- IconType m_iconType;
bool m_forceProgress;
};
using DismissHandler = ucl::WeakDelegate<void()>;
public:
- void complete();
+ void complete(const ucl::TString &completeText,
+ IconType iconType = IconType::NONE);
void setDismissHandler(const DismissHandler &handler);
private:
friend class ucl::RefCountObj<ProcessingPresenter>;
- ProcessingPresenter(ucl::RefCountObjBase &rc, IconType iconType);
+ ProcessingPresenter(ucl::RefCountObjBase &rc);
virtual ~ProcessingPresenter();
ucl::Result prepare(ucl::ElmWidget &parent,
const ucl::TString &processingText,
- const ucl::TString &completeText,
bool forceProgress);
ucl::Result createWidget(ucl::ElmWidget &parent,
const ucl::TString &processingText);
ucl::Result moveWidget();
ucl::Result createProgress();
- ucl::Result createPopup(const ucl::TString &completeText);
+ ucl::Result createPopup();
ucl::Result createIcon();
bool resetTimer(double timeout);
};
private:
- const IconType m_iconType;
ucl::LayoutSRef m_widget;
ucl::StyledWidgetSRef m_popup;
ucl::LayoutWRef m_icon;
+ IconType m_iconType;
DismissHandler m_dismissHandler;
Ecore_Timer *m_timer;
State m_state;
private:
const IMediaAlbumSRef m_album;
- std::vector<MediaItemSRef> m_mediaItems;
+ MediaItems m_mediaItems;
std::vector<RealizedItemUPtr> m_realizedItems;
extern const ucl::TString STR_NO_PHOTOS;
extern const ucl::TString STR_SELECT_ALL;
extern const ucl::TString STR_DESELECT_ALL;
+ extern const ucl::TString STR_DELETE;
+ extern const ucl::TString STR_DELETE_CAPS;
+ extern const ucl::TString STR_DELETE_1_PHOTO;
+ extern const ucl::TString STR_DELETING;
+ extern const ucl::TString STR_DELETED;
+ extern const ucl::TString STR_FAILED;
}
#endif // __GALLERY_RESOURCES_H__
Result GalleryAlbum::update()
{
- Items newItems;
+ MediaItems 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));
+ MediaItems &newItems =
+ (*static_cast<MediaItems *>(user_data));
auto item = MediaItem::newInstance(media);
if (!item) {
ELOG("MediaItem::newInstance() failed! Skipping");
ucl::Result prepare();
- private:
- using Items = std::vector<MediaItemSRef>;
-
private:
filter_h m_filter;
ucl::Event<NotiHandler> m_onChange;
- Items m_items;
+ MediaItems m_items;
bool m_isValid;
};
}
#include "model/IMediaAlbum.h"
#include "model/MediaItem.h"
+#include "model/IJob.h"
+#include "view/PageContent.h"
#include "view/ImageGrid.h"
+#include "presenters/MoreOptionsPresenter.h"
+#include "presenters/AlertDialog.h"
+#include "presenters/ProcessingPresenter.h"
#include "presenters/ViewerPage.h"
+#include "resources.h"
#include "common.h"
namespace gallery { namespace { namespace impl {
constexpr auto BRING_IN_SCROLL_FRICTION = 0.25;
constexpr auto PAGE_SCROLL_IN_FRICTION = 0.25;
+
+ enum {
+ MORE_OPTION_ID_DELETE
+ };
}}}
namespace gallery {
PreviewPage::~PreviewPage()
{
+ closeTempViews();
if (m_page) {
m_page->exitNoTransition();
}
- m_imageGrid->setListener(nullptr);
+ if (m_imageGrid) {
+ m_imageGrid->setListener(nullptr);
+ }
}
void PreviewPage::reload()
Result PreviewPage::prepare(const bool enableSelectMode)
{
+ m_content = PageContent::Builder().
+ setFlags(PageContent::FLAG_MORE_OPTIONS).
+ build(getNaviframe());
+ if (!m_content) {
+ LOG_RETURN(RES_FAIL, "PageContent::build() failed!");
+ }
+
m_imageGrid = ImageGrid::Builder().
setListener(this).
setType(ImageGrid::Type::LINEAR).
setSelectModeStartup(enableSelectMode).
- build(getNaviframe());
+ build(*m_content);
if (!m_imageGrid) {
LOG_RETURN(RES_FAIL, "ImageGrid::build() failed!");
}
+ m_content->set(*m_imageGrid);
+
+ m_more = MoreOptionsPresenter::Builder().
+ addOption({impl::MORE_OPTION_ID_DELETE,
+ STR_DELETE, nullptr,
+ getImageTheme(ICON_MORE_OPT_DELETE)}).
+ 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());
+
FAIL_RETURN(m_album->forEachMedia(
DELEGATE(PreviewPage::onEachMedia, this)),
"m_album->forEachMedia() failed!");
FAIL_RETURN(Page::prepare(
[this]()
{
- return getNaviframe().push(*m_imageGrid, NAVIFRAME_EMPTY);
+ return getNaviframe().push(*m_content, NAVIFRAME_EMPTY);
}),
"Page::prepare() failed!");
m_album->addChangeHandler(WEAK_DELEGATE(
PreviewPage::onAlbumChanged, asWeak(*this)));
+ m_more->setListener(asWeakThis<IMoreOptionsListener>(this));
+
return RES_OK;
}
return true;
}
- void PreviewPage::onActivate()
+ void PreviewPage::onActivateBy(const DeactivatorInfo &info)
{
- elm_config_scroll_page_scroll_friction_set(
- impl::PAGE_SCROLL_IN_FRICTION);
- elm_config_scroll_bring_in_scroll_friction_set(
- impl::BRING_IN_SCROLL_FRICTION);
+ if (info.deactivator == &getNaviframe()) {
+ elm_config_scroll_page_scroll_friction_set(
+ impl::PAGE_SCROLL_IN_FRICTION);
+ elm_config_scroll_bring_in_scroll_friction_set(
+ impl::BRING_IN_SCROLL_FRICTION);
- m_imageGrid->activateRotary();
+ m_more->activateBy(info.deactivator);
+ }
+
+ if (isActive()) {
+ m_imageGrid->activateRotary();
+ }
}
- void PreviewPage::onDeactivate()
+ void PreviewPage::onDeactivateBy(const DeactivatorInfo &info)
{
+ if (info.deactivator == &getNaviframe()) {
+ m_more->deactivateBy(info.deactivator);
+ }
+
m_imageGrid->deactivateRotary();
}
void PreviewPage::onItemEvent(const int itemIndex,
const int event, const int x, const int y)
{
- if (!isActive()) {
+ if (m_more->isOpened()) {
return;
}
}
switch (event) {
- case ImageGrid::ITEM_EVENT_TAP_AND_HOLD:
- switchToSelectMode(itemIndex);
- break;
case ImageGrid::ITEM_EVENT_DOUBLE_TAP:
openViewer(itemIndex, x, y);
break;
}
}
- void PreviewPage::onTransitionFinished()
+ void PreviewPage::onMoreOptionClicked(MoreOptionsPresenter &sender,
+ const MoreOption &option)
+ {
+ sender.setOpened(false);
+
+ switch (option.id) {
+ case impl::MORE_OPTION_ID_DELETE:
+ m_alert = AlertDialog::Builder().
+ setType(AlertDialog::Type::OK_CANCEL).
+ setText(STR_DELETE_1_PHOTO).
+ setHandler(WEAK_DELEGATE(
+ PreviewPage::onAlertEvent, asWeak(*this))).
+ build(getNaviframe());
+ break;
+ default:
+ WLOG("Unknown option id: %d;", option.id);
+ break;
+ }
+ }
+
+ bool PreviewPage::onAlertEvent(AlertDialog &dialog, int event)
{
- m_imageGrid->update();
+ if (event != AlertDialog::EVENT_OK) {
+ return true;
+ }
+
+ const int itemIndex = getCurrentItemIndex();
+ if (itemIndex < 0) {
+ ELOG("Invalid item index!");
+ return true;
+ }
+
+ m_job = MediaItem::RemoverBuilder().
+ setItems({m_items[itemIndex]->getMedia()}).
+ build(WEAK_DELEGATE(
+ PreviewPage::onJobComplete, asWeak(*this)));
+ if (!m_job) {
+ ELOG("MediaItem::RemoverBuilder::build() failed!");
+ return true;
+ }
+
+ m_processing = ProcessingPresenter::Builder().
+ setProcessingText(STR_DELETING).
+ build(*m_content);
+
+ return true;
+ }
+
+ void PreviewPage::onJobComplete()
+ {
+ if (m_processing) {
+ if (isGood(m_job->getResult())) {
+ m_processing->complete(STR_DELETED,
+ ProcessingPresenter::IconType::CHECK);
+ } else {
+ m_processing->complete(STR_FAILED);
+ }
+ m_processing.reset();
+ }
+
+ m_job.reset();
+
+ m_album->defragment();
+ }
+
+ void PreviewPage::closeTempViews()
+ {
+ if (m_alert) {
+ m_alert->dismiss();
+ }
+ if (m_more) {
+ m_more->setOpened(false);
+ }
}
void PreviewPage::switchToSelectMode(const int itemIndex)
{
+ closeTempViews();
+
for (auto &item: m_items) {
item->setSelected(false);
}
void PreviewPage::switchToNormalMode()
{
+ closeTempViews();
+
m_imageGrid->setSelectModeEnabled(false);
}
{"layout", "gallery", "proccessing"};
constexpr EdjeSignal SIGNAL_SHOW {"gallery,show"};
+ constexpr EdjeSignal SIGNAL_SHOW_BG {"gallery,show,bg"};
constexpr EdjeSignal SIGNAL_HIDE {"gallery,hide"};
constexpr EdjeSignal SIGNAL_HIDE_PROGRESS {"gallery,hide,progress"};
// ProcessingPresenter::Builder //
ProcessingPresenter::Builder::Builder() :
- m_iconType(IconType::NONE),
m_forceProgress(false)
{
}
return *this;
}
- ProcessingPresenter::Builder &ProcessingPresenter::Builder::
- setCompleteText(TString text)
- {
- m_completeText = std::move(text);
- return *this;
- }
-
- ProcessingPresenter::Builder &ProcessingPresenter::Builder::
- setIconType(const IconType value)
- {
- m_iconType = value;
- return *this;
- }
-
ProcessingPresenter::Builder &ProcessingPresenter::Builder::
setForceProgress(const bool value)
{
ProcessingPresenterSRef ProcessingPresenter::Builder::
build(ElmWidget &parent) const
{
- auto result = makeShared<ProcessingPresenter>(m_iconType);
+ auto result = makeShared<ProcessingPresenter>();
FAIL_RETURN_VALUE(result->prepare(parent,
- m_processingText, m_completeText, m_forceProgress), {},
+ m_processingText, m_forceProgress), {},
"result->prepare() failed!");
return result;
// ProcessingPresenter //
- ProcessingPresenter::ProcessingPresenter(RefCountObjBase &rc,
- const IconType iconType) :
+ ProcessingPresenter::ProcessingPresenter(RefCountObjBase &rc) :
Presenter(rc),
- m_iconType(iconType),
+ m_iconType(IconType::NONE),
m_timer(nullptr),
m_state(State::WAITING),
m_mayComplete(true),
Result ProcessingPresenter::prepare(ElmWidget &parent,
const TString &processingText,
- const TString &completeText,
const bool forceProgress)
{
FAIL_RETURN(Presenter::prepare(parent),
FAIL_RETURN(createProgress(), "createProgress() failed!");
- FAIL_RETURN(createPopup(completeText), "createPopup() failed!");
-
- if (m_iconType != IconType::NONE) {
- FAIL_RETURN(createIcon(), "createIcon() failed!");
- }
+ FAIL_RETURN(createPopup(), "createPopup() failed!");
if (forceProgress) {
showProgress();
- } else if (!resetTimer(impl::IDLE_WAIT_TIME_SEC)) {
- LOG_RETURN(RES_FAIL, "resetTimer() failed!");
+ } else {
+ m_widget->emit(impl::SIGNAL_SHOW_BG);
+ if (!resetTimer(impl::IDLE_WAIT_TIME_SEC)) {
+ LOG_RETURN(RES_FAIL, "resetTimer() failed!");
+ }
}
addDeactivatorException(this);
return RES_OK;
}
- Result ProcessingPresenter::createPopup(const TString &completeText)
+ Result ProcessingPresenter::createPopup()
{
Evas_Object *const popupEo = elm_popup_add(m_widget->getTopWidget());
if (!popupEo) {
m_popup = makeShared<StyledWidget>(popupEo, true);
m_popup->setStyle(impl::POPUP_STYLE);
- m_popup->setText(completeText, PART_TEXT);
m_popup->addEventHandler(POPUP_DISMISSED, WEAK_DELEGATE(
ProcessingPresenter::onPopupDismissed, asWeak(*this)));
m_popup.reset();
+ deactivateBy(m_popup.get());
broadcastActivateBy(this);
m_rc->unref();
}
if (m_dismissHandler) {
m_dismissHandler();
}
+ m_widget.reset();
deletePopup();
}
}
}
- void ProcessingPresenter::complete()
+ void ProcessingPresenter::complete(const TString &completeText,
+ const IconType iconType)
{
if (m_isComplete) {
LOG_RETURN_VOID(RES_ILLEGAL_STATE, "Already in complete state!");
}
m_isComplete = true;
+ m_popup->setText(completeText, PART_TEXT);
+
+ if (iconType != IconType::NONE) {
+ m_iconType = iconType;
+ FAIL_LOG(createIcon(), "createIcon() failed!");
+ }
+
m_rc->ref();
tryShowPopup();
if (m_page) {
m_page->exitNoTransition();
}
- m_imageGrid->setListener(nullptr);
+ if (m_imageGrid) {
+ m_imageGrid->setListener(nullptr);
+ }
}
void ThumbnailPage::reload()
const ucl::TString STR_NO_PHOTOS {"No photos"};
const ucl::TString STR_SELECT_ALL {"Select all"};
const ucl::TString STR_DESELECT_ALL {"Deselect all"};
+ const ucl::TString STR_DELETE {"Delete"};
+ const ucl::TString STR_DELETE_CAPS {"DELETE"};
+ const ucl::TString STR_DELETE_1_PHOTO {"Delete 1 photo?"};
+ const ucl::TString STR_DELETING {"Deleting..."};
+ const ucl::TString STR_DELETED {"Deleted."};
+ const ucl::TString STR_FAILED {"Failed."};
}