class IMediaAlbum : public ucl::Polymorphic {
public:
- using EachCb = ucl::Delegate<bool(MediaItemUPtr &&media)>;
+ using EachCb = ucl::Delegate<bool(MediaItemSRef &&media)>;
public:
virtual ucl::Result forEachMedia(EachCb cb) const = 0;
ucl::Delegate<void(ucl::Result, const std::string &path)>;
public:
- static MediaItemUPtr newInstance(media_info_h media);
+ static MediaItemSRef newInstance(media_info_h media);
virtual ~MediaItem();
bool isValid() const;
ucl::Result removeFile();
protected:
+ friend class ucl::RefCountObj<MediaItem>;
MediaItem(MediaType type);
ucl::Result prepare(media_info_h media);
UCL_DECLARE_REF_ALIASES(IMediaAlbum);
- class MediaItem;
- using MediaItemUPtr = std::unique_ptr<MediaItem>;
+ UCL_DECLARE_REF_ALIASES(MediaItem);
}
#endif // __GALLERY_MODEL_TYPES_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_PRESENTATION_IMAGE_VIEWER_H__
+#define __GALLERY_PRESENTATION_IMAGE_VIEWER_H__
+
+#include "ucl/gui/StyledWidget.h"
+#include "ucl/gui/Layout.h"
+
+#include "types.h"
+
+namespace gallery {
+
+ constexpr ucl::SmartEvent IMAGE_VIEWER_ZOOM_END {"gallery,zoom,end"};
+
+ class ImageViewer final : public ucl::Widget {
+ public:
+ class Builder {
+ public:
+ Builder();
+ Builder &setImageSize(int w, int h);
+ ImageViewerSRef build(ucl::Widget &parent) const;
+ private:
+ int m_imageW;
+ int m_imageH;
+ };
+
+ public:
+ void setLowResImagePath(const std::string &path);
+ void setHighResImagePath(const std::string &path);
+
+ bool zoomIn(int originX, int originY);
+ bool zoomOut();
+
+ bool isZooming() const;
+ bool isZoomedIn() const;
+ bool isZoomedOut() const;
+
+ private:
+ friend class ucl::RefCountObj<ImageViewer>;
+ ImageViewer(ucl::RefCountObjBase &rc, int imageW,
+ int imageH, Evas_Object *scroller);
+ virtual ~ImageViewer();
+
+ void prepare();
+
+ void onImagePreloaded(ucl::Widget &widget, void *eventInfo);
+ void onScrollerResize(ucl::Widget &widget, void *eventInfo);
+
+ bool updateScrollerSize();
+ void updateScales();
+ void updateGridSize();
+ void updateScrollOffset();
+
+ void calcZoomInFactors(int originX, int originY);
+ void calcZoomOutFactors();
+ void startAnimation();
+
+ Eina_Bool onAnimationStartTimer();
+ Eina_Bool onAnimationFrame(double pos);
+
+ private:
+ enum class State {
+ ZOOMED_OUT,
+ ZOOMED_IN,
+ ZOOMING_OUT,
+ ZOOMING_IN
+ };
+
+ private:
+ const int m_imageW;
+ const int m_imageH;
+
+ ucl::StyledWidgetWRef m_scroller;
+ ucl::Layout m_layout;
+ ucl::Widget m_grid;
+ ucl::Widget m_lowResImage;
+ ucl::Widget m_highResImage;
+
+ int m_scrollerW;
+ int m_scrollerH;
+ int m_gridW;
+ int m_gridH;
+ double m_scale0;
+ double m_scale1;
+
+ double m_xf1;
+ double m_yf1;
+ double m_xf2;
+ double m_yf2;
+ double m_zoom;
+
+ Ecore_Timer *m_animationStartTimer;
+ Ecore_Animator *m_animator;
+ State m_state;
+ };
+}
+
+#endif // __GALLERY_PRESENTATION_IMAGE_VIEWER_H__
ucl::Result prepare();
void showItem(int itemIndex);
- bool onEachMedia(MediaItemUPtr &&media);
+ bool onEachMedia(MediaItemSRef &&media);
// Page //
ucl::Result prepare();
- bool onEachMedia(MediaItemUPtr &&media);
+ bool onEachMedia(MediaItemSRef &&media);
void onPageExitRequest(Page &page);
private:
const IMediaAlbumSRef m_album;
- std::vector<MediaItemUPtr> m_mediaItems;
+ std::vector<MediaItemSRef> m_mediaItems;
std::vector<RealizedItemUPtr> m_realizedItems;
--- /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_PRESENTATION_VIEWER_PAGE_H__
+#define __GALLERY_PRESENTATION_VIEWER_PAGE_H__
+
+#include "Page.h"
+
+#include "model/types.h"
+
+namespace gallery {
+
+ class ViewerPage final : public Page {
+ public:
+ class Builder {
+ public:
+ Builder();
+ ~Builder();
+ Builder &setNaviframe(const ucl::NaviframeSRef &navi);
+ Builder &setMedia(const MediaItemSRef &media);
+ Builder &setExitOnZoomOut(bool value);
+ ViewerPageSRef build(ExitRequestHandler onExitRequest) const;
+ private:
+ ucl::NaviframeSRef m_navi;
+ MediaItemSRef m_media;
+ bool m_exitOnZoomOut;
+ };
+
+ public:
+ void zoomIn(int originX, int originY);
+
+ private:
+ friend class ucl::RefCountObj<ViewerPage>;
+ ViewerPage(ucl::RefCountObjBase &rc, const ucl::NaviframeSRef &navi,
+ ExitRequestHandler onExitRequest, const MediaItemSRef &media,
+ bool exitOnZoomOut);
+ virtual ~ViewerPage();
+
+ ucl::Result prepare();
+
+ void onThumbnail(ucl::Result result, const std::string &path);
+ void onZoomEnd(ucl::Widget &widget, void *eventInfo);
+
+ // Page //
+
+ virtual void onBackKey() final override;
+
+ private:
+ const MediaItemSRef m_media;
+ const bool m_exitOnZoomOut;
+ ImageViewerSRef m_imageViewer;
+ };
+}
+
+#endif // __GALLERY_PRESENTATION_VIEWER_PAGE_H__
class IImageGridListener;
UCL_DECLARE_REF_ALIASES(ImageGrid);
+ UCL_DECLARE_REF_ALIASES(ImageViewer);
UCL_DECLARE_REF_ALIASES(Page);
+ UCL_DECLARE_REF_ALIASES(NoContentPage);
UCL_DECLARE_REF_ALIASES(ThumbnailPage);
UCL_DECLARE_REF_ALIASES(PreviewPage);
- UCL_DECLARE_REF_ALIASES(NoContentPage);
+ UCL_DECLARE_REF_ALIASES(ViewerPage);
}
#endif // __GALLERY_PRESENTATION_TYPES_H__
freeMediaInfo();
}
- MediaItemUPtr MediaItem::newInstance(const media_info_h media)
+ MediaItemSRef MediaItem::newInstance(const media_info_h media)
{
media_content_type_e contentType = MEDIA_CONTENT_TYPE_OTHERS;
const int ret = media_info_get_media_type(media, &contentType);
"media_info_get_media_type() failed: %d", ret);
}
- MediaItemUPtr result{new MediaItem(toMediaType(contentType))};
+ auto result = makeShared<MediaItem>(toMediaType(contentType));
FAIL_RETURN_VALUE(result->prepare(media), {},
"result->prepare() failed!");
// Related to ImageGrid //
const TString SLOT_PART_FMT {"swallow.cell_%d"};
- // Related to Scroller //
- constexpr ElmStyle SCROLLER_STYLE {"effect"};
-
// Related to Button //
constexpr ElmStyle ITEM_BTN_STYLE {"gallery_image"};
constexpr EdjePart PART_BTN_BG {"swallow.bg"};
elm_box_horizontal_set(m_box, toEina(m_info.isHorizontal));
show(m_box);
- m_scroller->setStyle(impl::SCROLLER_STYLE);
+ m_scroller->setStyle(SCROLLER_STYLE);
expandAndFill(*m_scroller);
if (m_info.isHorizontal) {
elm_scroller_page_scroll_limit_set(
--- /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 "presentation/ImageViewer.h"
+
+#include "common.h"
+
+namespace gallery { namespace { namespace impl {
+
+ constexpr auto ANIMATION_START_TIMEOUT_SEC = (1.0 / 30.0);
+ constexpr auto ANIMATION_RUNTIME_SEC = (300.0 / 1000.0);
+}}}
+
+namespace gallery {
+
+ using namespace ucl;
+
+ // ImageViewer::Builder //
+
+ ImageViewer::Builder::Builder() :
+ m_imageW(0),
+ m_imageH(0)
+ {
+ }
+
+ ImageViewer::Builder &ImageViewer::Builder::setImageSize(
+ const int w, const int h)
+ {
+ m_imageW = w;
+ m_imageH = h;
+ return *this;
+ }
+
+ ImageViewerSRef ImageViewer::Builder::build(Widget &parent) const
+ {
+ if ((m_imageW <= 0) || (m_imageH <= 0)) {
+ LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {}, "Image size is invalid");
+ }
+
+ auto scroller = elm_scroller_add(parent);
+ if (!scroller) {
+ LOG_RETURN_VALUE(RES_FAIL, {}, "elm_scroller_add() failed!");
+ }
+
+ return makeShared<ImageViewer>(m_imageW, m_imageH, scroller);
+ }
+
+ // ImageViewer //
+
+ ImageViewer::ImageViewer(RefCountObjBase &rc,
+ const int imageW, const int imageH,
+ Evas_Object *const scroller) :
+ Widget(&rc, scroller, true),
+ m_imageW(imageW),
+ m_imageH(imageH),
+
+ m_scroller(makeShared<StyledWidget>(scroller)),
+ m_layout(elm_layout_add(*m_scroller)),
+ m_grid(evas_object_grid_add(m_layout.getEvas())),
+ m_lowResImage(evas_object_image_filled_add(m_grid.getEvas())),
+ m_highResImage(evas_object_image_filled_add(m_grid.getEvas())),
+
+ m_scrollerW(0),
+ m_scrollerH(0),
+ m_gridW(0),
+ m_gridH(0),
+ m_scale0(0),
+ m_scale1(0),
+
+ m_xf1(0.5),
+ m_yf1(0.5),
+ m_xf2(0.5),
+ m_yf2(0.5),
+ m_zoom(0.0),
+
+ m_animationStartTimer(nullptr),
+ m_animator(nullptr),
+ m_state(State::ZOOMED_OUT)
+ {
+ prepare();
+ }
+
+ ImageViewer::~ImageViewer()
+ {
+ if (m_animationStartTimer) {
+ ecore_timer_del(m_animationStartTimer);
+ }
+ if (m_animator) {
+ ecore_animator_del(m_animator);
+ }
+ }
+
+ void ImageViewer::prepare()
+ {
+ expandAndFill(*m_scroller);
+ m_scroller->setStyle(SCROLLER_STYLE);
+ elm_scroller_bounce_set(*m_scroller, EINA_TRUE, EINA_TRUE);
+ elm_scroller_policy_set(*m_scroller,
+ ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+ elm_object_scroll_freeze_push(*m_scroller);
+ show(*m_scroller);
+
+ expandAndFill(m_layout);
+ m_layout.setTheme(LAYOUT_DEFAULT);
+ m_scroller->setContent(m_layout);
+ show(m_layout);
+
+ evas_object_grid_size_set(m_grid, 1, 1);
+ m_layout.setContent(m_grid);
+ show(m_grid);
+
+ evas_object_grid_pack(m_grid, m_lowResImage, 0, 0, 1, 1);
+ show(m_lowResImage);
+ evas_object_grid_pack(m_grid, m_highResImage, 0, 0, 1, 1);
+ show(m_highResImage);
+
+ m_scroller->addEventHandler(WidgetEvent::RESIZE,
+ WEAK_DELEGATE(ImageViewer::onScrollerResize, asWeak(*this)));
+
+ m_highResImage.addEventHandler(WidgetEvent::IMAGE_PRELOADED,
+ WEAK_DELEGATE(ImageViewer::onImagePreloaded, asWeak(*this)));
+ }
+
+ void ImageViewer::onScrollerResize(Widget &widget, void *eventInfo)
+ {
+ if (updateScrollerSize()) {
+ updateScales();
+ updateGridSize();
+ updateScrollOffset();
+ }
+ }
+
+ bool ImageViewer::updateScrollerSize()
+ {
+ int scrollerW = 0;
+ int scrollerH = 0;
+ getSize(*m_scroller, &scrollerW, &scrollerH);
+
+ if ((scrollerW == 0) || (scrollerH == 0)) {
+ DLOG("Scroller has 0 size. Skip.");
+ return false;
+ }
+
+ if ((scrollerW != m_scrollerW) || (scrollerH != m_scrollerH)) {
+ m_scrollerW = scrollerW;
+ m_scrollerH = scrollerH;
+ return true;
+ }
+
+ return false;
+ }
+
+ void ImageViewer::updateScales()
+ {
+ const double sx = (1.0 * m_scrollerW / m_imageW);
+ const double sy = (1.0 * m_scrollerH / m_imageH);
+
+ m_scale0 = ((sx > sy) ? sx : sy);
+ m_scale1 = 1.0;
+ }
+
+ void ImageViewer::updateGridSize()
+ {
+ const double scale = (m_scale0 + m_zoom * (m_scale1 - m_scale0));
+
+ m_gridW = std::lround(scale * m_imageW);
+ m_gridH = std::lround(scale * m_imageH);
+
+ m_grid.setMin(m_gridW, m_gridH);
+ m_grid.setMax(m_gridW, m_gridH);
+
+ evas_object_smart_calculate(m_layout);
+ }
+
+ void ImageViewer::updateScrollOffset()
+ {
+ const double xf2 = (m_xf2 + m_zoom * (0.5 - m_xf2));
+ const double yf2 = (m_yf2 + m_zoom * (0.5 - m_yf2));
+
+ const int sx = std::lround((m_xf1 * m_gridW) - (xf2 * m_scrollerW));
+ const int sy = std::lround((m_yf1 * m_gridH) - (yf2 * m_scrollerH));
+
+ elm_scroller_region_show(*m_scroller, sx, sy, m_scrollerW, m_scrollerH);
+ }
+
+ void ImageViewer::setLowResImagePath(const std::string &path)
+ {
+ evas_object_image_file_set(m_lowResImage, path.c_str(), nullptr);
+ }
+
+ void ImageViewer::setHighResImagePath(const std::string &path)
+ {
+ hide(m_highResImage);
+ evas_object_image_file_set(m_highResImage, path.c_str(), nullptr);
+ evas_object_image_preload(m_highResImage, EINA_FALSE);
+ }
+
+ void ImageViewer::onImagePreloaded(Widget &widget, void *eventInfo)
+ {
+ show(widget);
+ }
+
+ bool ImageViewer::zoomIn(const int originX, const int originY)
+ {
+ if (m_state != State::ZOOMED_OUT) {
+ WLOG("Can't zoom in!");
+ return false;
+ }
+
+ m_state = State::ZOOMING_IN;
+
+ calcZoomInFactors(originX, originY);
+ startAnimation();
+
+ return true;
+ }
+
+ bool ImageViewer::zoomOut()
+ {
+ if (m_state != State::ZOOMED_IN) {
+ WLOG("Can't zoom out!");
+ return false;
+ }
+
+ m_state = State::ZOOMING_OUT;
+
+ calcZoomOutFactors();
+ startAnimation();
+
+ return true;
+ }
+
+ bool ImageViewer::isZooming() const
+ {
+ return ((m_state == State::ZOOMING_IN) ||
+ (m_state == State::ZOOMING_OUT));
+ }
+
+ bool ImageViewer::isZoomedIn() const
+ {
+ return (m_state == State::ZOOMED_IN);
+ }
+
+ bool ImageViewer::isZoomedOut() const
+ {
+ return (m_state == State::ZOOMED_OUT);
+ }
+
+ void ImageViewer::calcZoomInFactors(const int originX, const int originY)
+ {
+ if (m_scale0 > m_scale1) {
+ m_xf1 = 0.5;
+ m_yf1 = 0.5;
+ m_xf2 = 0.5;
+ m_yf2 = 0.5;
+ return;
+ }
+
+ int x = 0;
+ int y = 0;
+ getPosition(*m_scroller, &x, &y);
+
+ const int newOriginX = (originX - x);
+ const int newOriginY = (originY - x);
+
+ int sx = 0;
+ int sy = 0;
+ elm_scroller_region_get(*m_scroller, &sx, &sy, nullptr, nullptr);
+
+ m_xf1 = (1.0 * (sx + newOriginX) / m_gridW);
+ m_yf1 = (1.0 * (sy + newOriginY) / m_gridH);
+ m_xf2 = (1.0 * newOriginX / m_scrollerW);
+ m_yf2 = (1.0 * newOriginY / m_scrollerH);
+ }
+
+ void ImageViewer::calcZoomOutFactors()
+ {
+ int sx = 0;
+ int sy = 0;
+ elm_scroller_region_get(*m_scroller, &sx, &sy, nullptr, nullptr);
+
+ if (m_gridW < m_scrollerW) {
+ sx = (0.5 * (m_gridW - m_scrollerW));
+ }
+ if (m_gridH < m_scrollerH) {
+ sy = (0.5 * (m_gridH - m_scrollerH));
+ }
+
+ m_xf1 = ((sx + 0.5 * m_scrollerW) / m_gridW);
+ m_yf1 = ((sy + 0.5 * m_scrollerH) / m_gridH);
+ m_xf2 = (m_scale0 * m_imageW * (m_xf1 - 0.5) / m_scrollerW + 0.5);
+ m_yf2 = (m_scale0 * m_imageH * (m_yf1 - 0.5) / m_scrollerH + 0.5);
+ }
+
+ void ImageViewer::startAnimation()
+ {
+ if (m_animationStartTimer) {
+ WLOG("Timer is running!");
+ ecore_timer_del(m_animationStartTimer);
+ }
+
+ m_animationStartTimer = ecore_timer_add(
+ impl::ANIMATION_START_TIMEOUT_SEC,
+ CALLBACK_A(ImageViewer::onAnimationStartTimer), this);
+ }
+
+ Eina_Bool ImageViewer::onAnimationStartTimer()
+ {
+ m_animationStartTimer = nullptr;
+
+ if (m_animator) {
+ WLOG("Animator is running!");
+ ecore_animator_del(m_animator);
+ }
+ m_animator = ecore_animator_timeline_add(
+ impl::ANIMATION_RUNTIME_SEC,
+ CALLBACK_A(ImageViewer::onAnimationFrame), this);
+
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ Eina_Bool ImageViewer::onAnimationFrame(const double pos)
+ {
+ const double t = ecore_animator_pos_map(
+ pos, ECORE_POS_MAP_DECELERATE, 0.0, 0.0);
+
+ m_zoom = ((m_state == State::ZOOMING_IN) ? t : (1.0 - t));
+
+ updateGridSize();
+ updateScrollOffset();
+
+ if (pos == 1.0) {
+ m_animator = nullptr;
+ if (m_state == State::ZOOMING_IN) {
+ m_state = State::ZOOMED_IN;
+ elm_object_scroll_freeze_pop(*m_scroller);
+ } else {
+ m_state = State::ZOOMED_OUT;
+ elm_object_scroll_freeze_push(*m_scroller);
+ }
+ callSmartEvent(IMAGE_VIEWER_ZOOM_END, nullptr);
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ return ECORE_CALLBACK_RENEW;
+ }
+}
FAIL_RETURN(Page::prepare(
[this, &layout]()
{
- return getNaviframe().push(*layout);
+ return getNaviframe().push(*layout, NAVIFRAME_EMPTY);
}),
"Page::prepare() failed!");
class PreviewPage::Item : public NonCopyable {
public:
- Item(MediaItemUPtr &&media, ImageGrid &imageGrid, const int itemIndex) :
+ Item(MediaItemSRef &&media, ImageGrid &imageGrid, const int itemIndex) :
m_media(std::move(media)),
m_imageGrid(imageGrid),
m_index(itemIndex)
}
private:
- const MediaItemUPtr m_media;
+ const MediaItemSRef m_media;
ImageGrid &m_imageGrid;
const int m_index;
};
FAIL_RETURN(Page::prepare(
[this]()
{
- return getNaviframe().push(*m_imageGrid);
+ return getNaviframe().push(*m_imageGrid, NAVIFRAME_EMPTY);
}),
"Page::prepare() failed!");
m_imageGrid->scrollToItem(itemIndex);
}
- bool PreviewPage::onEachMedia(MediaItemUPtr &&media)
+ bool PreviewPage::onEachMedia(MediaItemSRef &&media)
{
m_items.emplace_back(
new Item(std::move(media), *m_imageGrid, m_items.size()));
FAIL_RETURN(Page::prepare(
[this]()
{
- return getNaviframe().push(*m_imageGrid);
+ return getNaviframe().push(*m_imageGrid, NAVIFRAME_EMPTY);
}),
"Page::prepare() failed!");
return RES_OK;
}
- bool ThumbnailPage::onEachMedia(MediaItemUPtr &&media)
+ bool ThumbnailPage::onEachMedia(MediaItemSRef &&media)
{
m_mediaItems.emplace_back(std::move(media));
return true;
--- /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 "presentation/ViewerPage.h"
+
+#include "model/MediaItem.h"
+
+#include "presentation/ImageViewer.h"
+
+#include "common.h"
+
+namespace gallery {
+
+ using namespace ucl;
+
+ // ViewerPage::Builder //
+
+ ViewerPage::Builder::Builder() :
+ m_exitOnZoomOut(true)
+ {
+ }
+
+ ViewerPage::Builder::~Builder()
+ {
+ }
+
+ ViewerPage::Builder &ViewerPage::Builder::setNaviframe(
+ const NaviframeSRef &navi)
+ {
+ m_navi = navi;
+ return *this;
+ }
+
+ ViewerPage::Builder &ViewerPage::Builder::setMedia(
+ const MediaItemSRef &media)
+ {
+ m_media = media;
+ return *this;
+ }
+
+ ViewerPage::Builder &ViewerPage::Builder::setExitOnZoomOut(const bool value)
+ {
+ m_exitOnZoomOut = value;
+ return *this;
+ }
+
+ ViewerPageSRef ViewerPage::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");
+ }
+
+ auto result = makeShared<ViewerPage>(
+ m_navi, onExitRequest, m_media, m_exitOnZoomOut);
+
+ FAIL_RETURN_VALUE(result->prepare(), {}, "result->prepare() failed!");
+
+ return result;
+ }
+
+ // ViewerPage //
+
+ ViewerPage::ViewerPage(RefCountObjBase &rc,
+ const NaviframeSRef &navi,
+ const ExitRequestHandler onExitRequest,
+ const MediaItemSRef &media,
+ const bool exitOnZoomOut) :
+ Page(rc, navi, onExitRequest),
+ m_media(media),
+ m_exitOnZoomOut(exitOnZoomOut)
+ {
+ }
+
+ ViewerPage::~ViewerPage()
+ {
+ }
+
+ void ViewerPage::zoomIn(const int originX, const int originY)
+ {
+ m_imageViewer->zoomIn(originX, originY);
+ }
+
+ Result ViewerPage::prepare()
+ {
+ int mediaW = 0;
+ int mediaH = 0;
+ m_media->getResolution(mediaW, mediaH);
+
+ m_imageViewer = ImageViewer::Builder().
+ setImageSize(mediaW, mediaH).
+ build(getNaviframe());
+ if (!m_imageViewer) {
+ LOG_RETURN(RES_FAIL, "ImageViewer::build() failed!");
+ }
+
+ FAIL_RETURN(m_media->getThumbnailPath(DELEGATE(
+ ViewerPage::onThumbnail, this)),
+ "m_media->getThumbnailPath() failed!");
+
+ m_imageViewer->setHighResImagePath(m_media->getFilePath());
+
+ m_imageViewer->addEventHandler(IMAGE_VIEWER_ZOOM_END,
+ WEAK_DELEGATE(ViewerPage::onZoomEnd, asWeak(*this)));
+
+ FAIL_RETURN(Page::prepare(
+ [this]()
+ {
+ const auto topItem = getNaviframe().getTopItem();
+ if (topItem) {
+ return getNaviframe().insertAfter(topItem,
+ *m_imageViewer, NAVIFRAME_EMPTY);
+ }
+ return getNaviframe().push(*m_imageViewer, NAVIFRAME_EMPTY);
+ }),
+ "Page::prepare() failed!");
+
+ return RES_OK;
+ }
+
+ void ViewerPage::onThumbnail(const Result result, const std::string &path)
+ {
+ FAIL_RETURN_VOID(result, "Failed to get thumbnail!");
+
+ m_imageViewer->setLowResImagePath(path);
+ }
+
+ void ViewerPage::onZoomEnd(ucl::Widget &widget, void *eventInfo)
+ {
+ if (m_exitOnZoomOut && m_imageViewer->isZoomedOut()) {
+ requestExit();
+ }
+ }
+
+ void ViewerPage::onBackKey()
+ {
+ if (m_imageViewer->isZoomedOut()) {
+ requestExit();
+ return;
+ }
+
+ m_imageViewer->zoomOut();
+ }
+}
#ifndef __GALLERY_PRESENTATION_COMMON_H__
#define __GALLERY_PRESENTATION_COMMON_H__
+#include "helpers.h"
+
#include "../common.h"
-#include "helpers.h"
+namespace gallery {
+
+ constexpr ucl::ElmStyle SCROLLER_STYLE {"effect"};
+}
#endif // __GALLERY_PRESENTATION_COMMON_H__
Evas_Object *pop();
- NaviItem push(const TString &title, Evas_Object *backBtn,
- Evas_Object *moreBtn, Evas_Object *content, ElmStyle style);
- NaviItem push(const TString &title, Evas_Object *content);
- NaviItem push(Evas_Object *content);
+ NaviItem push(const TString &title,
+ Evas_Object *backBtn, Evas_Object *moreBtn,
+ Evas_Object *content, ElmStyle style = nullptr);
+ NaviItem push(const TString &title,
+ Evas_Object *content, ElmStyle style = nullptr);
+ NaviItem push(Evas_Object *content, ElmStyle style = nullptr);
NaviItem insertAfter(NaviItem after, const TString &title,
Evas_Object *backBtn, Evas_Object *moreBtn,
- Evas_Object *content, ElmStyle style);
+ Evas_Object *content, ElmStyle style = nullptr);
NaviItem insertAfter(NaviItem after, const TString &title,
- Evas_Object *content);
+ Evas_Object *content, ElmStyle style = nullptr);
NaviItem insertAfter(NaviItem after,
- Evas_Object *content);
+ Evas_Object *content, ElmStyle style = nullptr);
NaviItem insertBefore(NaviItem before, const TString &title,
Evas_Object *backBtn, Evas_Object *moreBtn,
- Evas_Object *content, ElmStyle style);
+ Evas_Object *content, ElmStyle style = nullptr);
NaviItem insertBefore(NaviItem before, const TString &title,
- Evas_Object *content);
+ Evas_Object *content, ElmStyle style = nullptr);
NaviItem insertBefore(NaviItem before,
- Evas_Object *content);
+ Evas_Object *content, ElmStyle style = nullptr);
NaviItem getTopItem()const;
NaviItem getBottomItem() const;
}
inline NaviItem Naviframe::push(const TString &title,
- Evas_Object *const content)
+ Evas_Object *const content, const ElmStyle style)
{
- return push(title, nullptr, nullptr, content, nullptr);
+ return push(title, nullptr, nullptr, content, style);
}
- inline NaviItem Naviframe::push(Evas_Object *const content)
+ inline NaviItem Naviframe::push(
+ Evas_Object *const content, const ElmStyle style)
{
- return push(nullptr, nullptr, nullptr, content, nullptr);
+ return push(nullptr, nullptr, nullptr, content, style);
}
inline NaviItem Naviframe::insertAfter(NaviItem after,
}
inline NaviItem Naviframe::insertAfter(NaviItem after,
- const TString &title, Evas_Object *const content)
+ const TString &title,
+ Evas_Object *const content, const ElmStyle style)
{
- return insertAfter(after, title, nullptr, nullptr, content, nullptr);
+ return insertAfter(after, title, nullptr, nullptr, content, style);
}
inline NaviItem Naviframe::insertAfter(NaviItem after,
- Evas_Object *const content)
+ Evas_Object *const content, const ElmStyle style)
{
- return insertAfter(after, nullptr, nullptr, nullptr, content, nullptr);
+ return insertAfter(after, nullptr, nullptr, nullptr, content, style);
}
inline NaviItem Naviframe::insertBefore(NaviItem before,
}
inline NaviItem Naviframe::insertBefore(NaviItem before,
- const TString &title, Evas_Object *const content)
+ const TString &title,
+ Evas_Object *const content, const ElmStyle style)
{
- return insertAfter(before, title, nullptr, nullptr, content, nullptr);
+ return insertAfter(before, title, nullptr, nullptr, content, style);
}
inline NaviItem Naviframe::insertBefore(NaviItem before,
- Evas_Object *const content)
+ Evas_Object *const content, const ElmStyle style)
{
- return insertAfter(before, nullptr, nullptr, nullptr, content, nullptr);
+ return insertAfter(before, nullptr, nullptr, nullptr, content, style);
}
inline NaviItem Naviframe::getTopItem()const
StyledWidget &getConformant();
const StyledWidget &getConformant() const;
+ void getScreenSize(int *w, int *h) const;
+
void setTitle(const std::string &title);
std::string getTitle() const;
return m_conform;
}
+ inline void Window::getScreenSize(int *const w, int *const h) const
+ {
+ elm_win_screen_size_get(getEo(), nullptr, nullptr, w, h);
+ }
+
inline void Window::setTitle(const std::string &title)
{
elm_win_title_set(getEo(), title.c_str());
#include "stdTheme/common.h"
#include "stdTheme/layout.h"
+#include "stdTheme/naviframe.h"
#endif // __UCL_GUI_STD_THEME_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 __UCL_GUI_STD_THEME_NAVIFRAME_H__
+#define __UCL_GUI_STD_THEME_NAVIFRAME_H__
+
+#include "common.h"
+
+namespace ucl {
+
+ constexpr ElmStyle NAVIFRAME_EMPTY {"empty"};
+}
+
+#endif // __UCL_GUI_STD_THEME_NAVIFRAME_H__