From 172ce60d58be401233a090882f4fd001b6c99775 Mon Sep 17 00:00:00 2001 From: Igor Nazarov Date: Wed, 24 May 2017 15:36:21 +0300 Subject: [PATCH] TizenRefApp-8535 [Gallery] Improve image load size calculation in ImageGrid - Improved image load size calculation in ImageGrid; - Returned "MediaItem::getResoulution()" method; - Improved ViewrPage image quality; - Added gray bg for not loaded images. Change-Id: Ic1df38ac846f1df0fce549fc265c9911b505a5df --- edc/button.edc | 7 +- edc/colors.h | 1 + edc/image-grid.edc | 3 + inc/model/MediaItem.h | 16 +++- inc/model/types.h | 2 + inc/presenters/ViewerPage.h | 5 +- inc/view/ImageGrid.h | 12 ++- inc/view/ImageViewer.h | 7 +- src/model/MediaItem.cpp | 85 +++++++++++------- src/presenters/PreviewPage.cpp | 19 ++-- src/presenters/ThumbnailPage.cpp | 2 + src/presenters/ViewerPage.cpp | 25 +++++- src/view/ImageGrid.cpp | 148 ++++++++++++++++++++++--------- src/view/ImageViewer.cpp | 24 ++++- 14 files changed, 262 insertions(+), 94 deletions(-) diff --git a/edc/button.edc b/edc/button.edc index 49fe390..e6b652e 100644 --- a/edc/button.edc +++ b/edc/button.edc @@ -133,9 +133,14 @@ group{ "elm/button/base/transparent"; group{ "elm/button/base/gallery_image"; inherit: "elm/button/base/transparent"; parts { + rect { "rect.bg"; + before: "swallow.bg"; + desc { "default"; + color: GALLERY_COLOR_IMG_BG; + } + } swallow { "swallow.bg"; before: "elm.swallow.content"; - scale; desc { "default"; } } diff --git a/edc/colors.h b/edc/colors.h index 8eb78bc..09373c0 100644 --- a/edc/colors.h +++ b/edc/colors.h @@ -19,6 +19,7 @@ #define GALLERY_COLOR_WHITE 255 255 255 255 +#define GALLERY_COLOR_IMG_BG 64 64 64 255 #define GALLERY_COLOR_IMG_EF_NORMAL 0 0 0 0 #define GALLERY_COLOR_IMG_EF_PRESSED 0 0 0 102 #define GALLERY_COLOR_IMG_EF_DISABLED 0 0 0 77 diff --git a/edc/image-grid.edc b/edc/image-grid.edc index 7ca4b37..842a3ce 100644 --- a/edc/image-grid.edc +++ b/edc/image-grid.edc @@ -20,6 +20,7 @@ images { image: "gallery_thumbnail_select_ring_1x1.png" COMP; } group { "elm/layout/gallery_image_grid/hcomb_3x3_even"; + data.item: "image_min_load_size" 116; parts { spacer { "spacer_t"; scale; @@ -67,6 +68,7 @@ group { "elm/layout/gallery_image_grid/hcomb_3x3_even"; } } group { "elm/layout/gallery_image_grid/hcomb_3x3_odd"; + data.item: "image_min_load_size" 116; parts { spacer { "spacer_t"; scale; @@ -149,6 +151,7 @@ group { "elm/layout/gallery_image_grid/hcomb_3x3_odd"; } } group { "elm/layout/gallery_image_grid/linear"; + data.item: "image_min_load_size" 360; parts { spacer { "spacer"; scale; diff --git a/inc/model/MediaItem.h b/inc/model/MediaItem.h index 5f62b9e..16ce969 100644 --- a/inc/model/MediaItem.h +++ b/inc/model/MediaItem.h @@ -48,8 +48,10 @@ namespace gallery { FLAG_THUMBNAIL = 1, FLAG_REMOVE = 2, FLAG_SAVE = 4, + FLAG_RESOLUTION = 8, - FLAGS_FROM_MEDIA_DB = (FLAG_THUMBNAIL | FLAG_REMOVE), + FLAGS_FROM_MEDIA_DB = (FLAG_THUMBNAIL | FLAG_REMOVE | + FLAG_RESOLUTION), FLAGS_SIMPLE_FILE = (FLAG_SAVE) }; @@ -64,6 +66,8 @@ namespace gallery { const std::string &getId() const; + ucl::Result getResolution(int &x, int &y) const; + const std::string &getFilePath() const; ucl::Result getThumbnailPath(ThumbnailPathGetCb cb) const; @@ -77,11 +81,11 @@ namespace gallery { MediaItem(int flags, MediaType type); ucl::Result prepare(media_info_h media); + ucl::Result prepareImage(media_info_h media); ucl::Result prepare(std::string filePath); private: ucl::Result initThumbPath(media_info_h media) const; - void freeMediaInfo() const; private: // XXX This proxy is needed to deal with cases when @@ -93,12 +97,18 @@ namespace gallery { void completeCb(media_content_error_e error, const char *path); }; + private: + using AutoMediaInfo = ucl::AutoHandle< + media_info_h, int, media_info_destroy>; + private: const int m_flags; const MediaType m_type; std::string m_mediaId; std::string m_filePath; - mutable media_info_h m_media; + int m_resolutionX; + int m_resolutionY; + mutable AutoMediaInfo m_media; mutable std::string m_thumbPath; mutable std::unique_ptr m_thumbCbProxy; bool m_isValid; diff --git a/inc/model/types.h b/inc/model/types.h index 0ee2040..181b26b 100644 --- a/inc/model/types.h +++ b/inc/model/types.h @@ -21,6 +21,8 @@ #include +#include "ucl/misc/AutoHandle.h" + #include "../types.h" namespace gallery { diff --git a/inc/presenters/ViewerPage.h b/inc/presenters/ViewerPage.h index bef8407..c685909 100644 --- a/inc/presenters/ViewerPage.h +++ b/inc/presenters/ViewerPage.h @@ -33,6 +33,7 @@ namespace gallery { Builder &setNaviframe(const ucl::NaviframeSRef &navi); Builder &setMedia(const MediaItemSRef &media); Builder &setZoomIn(int x, int y); + Builder &setImageLoadSize(int size, bool isFull); Builder &setExitOnZoomOut(bool value); ViewerPageWRef build(ExitRequestHandler onExitRequest) const; private: @@ -40,6 +41,8 @@ namespace gallery { MediaItemSRef m_media; int m_zoomInX; int m_zoomInY; + int m_imageLoadSize; + bool m_isImageLoadSizeFull; bool m_exitOnZoomOut; }; @@ -53,7 +56,7 @@ namespace gallery { bool exitOnZoomOut); virtual ~ViewerPage(); - ucl::Result prepare(); + ucl::Result prepare(int imageLoadSize, bool isImageLoadSizeFull); void zoomIn(int originX, int originY); diff --git a/inc/view/ImageGrid.h b/inc/view/ImageGrid.h index 8fac6c3..019031d 100644 --- a/inc/view/ImageGrid.h +++ b/inc/view/ImageGrid.h @@ -59,9 +59,17 @@ namespace gallery { }; struct ItemParams { - int flags; std::string imagePath; std::string bgImagePath; + int imageWidth; + int imageHeight; + int flags; + }; + + struct ItemInfo { + int imageLoadSize; + bool isImageLoadSizeFull; + bool isImageLoaded; }; class Unrealizer : ucl::NonCopyable { @@ -87,6 +95,8 @@ namespace gallery { ucl::Result isItemRealized(int itemIndex) const; + ucl::Result getItemInfo(int itemIndex, ItemInfo &info) const; + int getScrolledToItemIndex() const; ucl::Result scrollToItem(int itemIndex); ucl::Result bringInItem(int itemIndex); diff --git a/inc/view/ImageViewer.h b/inc/view/ImageViewer.h index e6126de..73395db 100644 --- a/inc/view/ImageViewer.h +++ b/inc/view/ImageViewer.h @@ -32,10 +32,12 @@ namespace gallery { public: Builder(); Builder &setHighResImagePath(std::string path); + Builder &setLoadSize(int value); Builder &setForceLoad(bool value); ImageViewerSRef build(ucl::ElmWidget &parent) const; private: std::string m_highResPath; + int m_loadSize; bool m_forceLoad; }; @@ -51,10 +53,11 @@ namespace gallery { private: friend class ucl::RefCountObj; ImageViewer(ucl::RefCountObjBase &rc, Evas_Object *scroller, - const std::string &highResPath, bool forceLoad); + const std::string &highResPath, int loadSize, bool forceLoad); virtual ~ImageViewer(); - void prepare(const std::string &highResPath, bool forceLoad); + void prepare(const std::string &highResPath, + int loadSize, bool forceLoad); void onImagePreloaded(ucl::Widget &widget, void *eventInfo); void onScrollerResize(ucl::Widget &widget, void *eventInfo); diff --git a/src/model/MediaItem.cpp b/src/model/MediaItem.cpp index f8802b8..61d3a27 100644 --- a/src/model/MediaItem.cpp +++ b/src/model/MediaItem.cpp @@ -26,9 +26,13 @@ namespace gallery { namespace { namespace impl { + using namespace ucl; + const std::string MIME_PREFIX_IMAGE {"image/"}; const std::string MIME_PREFIX_VIDEO {"video/"}; + using AutoImageMeta = AutoHandle; + MediaType getFileMediaType(const std::string &filePath) { const auto ext = util::extractFileExtension(filePath); @@ -176,7 +180,8 @@ namespace gallery { MediaItem::MediaItem(const int flags, const MediaType type) : m_flags(flags), m_type(type), - m_media(nullptr), + m_resolutionX(0), + m_resolutionY(0), m_isValid(false) { } @@ -184,17 +189,13 @@ namespace gallery { MediaItem::~MediaItem() { cancelThumbnailPathGet(); - freeMediaInfo(); } 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); - if (ret != 0) { - LOG_RETURN_VALUE(RES_FAIL, {}, - "media_info_get_media_type() failed: %d", ret); - } + FAIL_RETURN_VALUE(util::get(media_info_get_media_type, contentType, + media), {}, "media_info_get_media_type() failed!"); auto result = makeShared(FLAGS_FROM_MEDIA_DB, toMediaType(contentType)); @@ -221,28 +222,47 @@ namespace gallery { FAIL_RETURN(initThumbPath(media), "initThumbPath() failed!"); if (isEmpty(m_thumbPath)) { - const int ret = media_info_clone(&m_media, media); - if (ret != 0) { - m_media = nullptr; - LOG_RETURN(RES_FAIL, "media_info_clone() failed: %d", ret); - } + media_info_h mediaClone = nullptr; + FAIL_RETURN(util::call(media_info_clone, &mediaClone, media), + "media_info_clone() failed!"); + m_media = mediaClone; } FAIL_RETURN(util::getNz(media_info_get_media_id, m_mediaId, media), - "media_info_get_media_id() failed!"); + "media_info_get_media_id() failed!"); FAIL_RETURN(util::getNz(media_info_get_file_path, m_filePath, media), - "media_info_get_file_path() failed!"); + "media_info_get_file_path() failed!"); + + if (m_type == MediaType::IMAGE) { + prepareImage(media); + } m_isValid = true; return RES_OK; } + Result MediaItem::prepareImage(const media_info_h media) + { + impl::AutoImageMeta imageMeta; + + FAIL_RETURN(util::getNz(media_info_get_image, imageMeta, media), + "media_info_get_image() failed!"); + + FAIL_RETURN(util::getNz(image_meta_get_width, m_resolutionX, + imageMeta), "image_meta_get_width() failed!"); + + FAIL_RETURN(util::getNz(image_meta_get_height, m_resolutionY, + imageMeta), "image_meta_get_height() failed!"); + + return RES_OK; + } + Result MediaItem::initThumbPath(const media_info_h media) const { FAIL_RETURN(util::get(media_info_get_thumbnail_path, m_thumbPath, - media), "media_info_get_thumbnail_path() failed!"); + media), "media_info_get_thumbnail_path() failed!"); return RES_OK; } @@ -253,17 +273,6 @@ namespace gallery { return RES_OK; } - void MediaItem::freeMediaInfo() const - { - if (m_media) { - const int ret = media_info_destroy(m_media); - if (ret != 0) { - WLOG("media_info_destroy() failed: %d", ret); - } - m_media = nullptr; - } - } - bool MediaItem::isValid() const { return m_isValid; @@ -284,6 +293,18 @@ namespace gallery { return m_mediaId; } + Result MediaItem::getResolution(int &x, int &y) const + { + if (!(m_flags & FLAG_RESOLUTION)) { + LOG_RETURN(RES_NOT_SUPPORTED, "Operation not supported!"); + } + + x = m_resolutionX; + y = m_resolutionY; + + return RES_OK; + } + const std::string &MediaItem::getFilePath() const { return m_filePath; @@ -306,7 +327,7 @@ namespace gallery { LOG_RETURN(RES_FAIL, "media_info_delete_from_db() failed: %d", ret); } - freeMediaInfo(); + m_media = nullptr; m_isValid = false; } @@ -385,11 +406,9 @@ namespace gallery { { MutexLock lock(getMediaMutex()); - const int ret = media_info_create_thumbnail(m_media, - CALLBACK_B(ThumbCbProxy::completeCb), cbProxy.get()); - if (ret != 0) { - LOG_RETURN(RES_FAIL, "media_info_clone() failed: %d", ret); - } + FAIL_RETURN(util::call(media_info_create_thumbnail, m_media, + CALLBACK_B(ThumbCbProxy::completeCb), cbProxy.get()), + "media_info_create_thumbnail() failed!"); } m_thumbCbProxy = std::move(cbProxy); @@ -444,7 +463,7 @@ namespace gallery { result = RES_FAIL; } else { item->m_thumbPath = path; - item->freeMediaInfo(); + item->m_media = nullptr; } const auto proxy = std::move(*item->m_thumbCbProxy); diff --git a/src/presenters/PreviewPage.cpp b/src/presenters/PreviewPage.cpp index cc92357..0bdd68c 100644 --- a/src/presenters/PreviewPage.cpp +++ b/src/presenters/PreviewPage.cpp @@ -184,6 +184,7 @@ namespace gallery { ImageGrid::ItemParams params = {}; params.imagePath = m_media->getFilePath(); params.bgImagePath = path; + m_media->getResolution(params.imageWidth, params.imageHeight); addFlags(params); m_imageGrid.updateItem(m_index, params); @@ -668,11 +669,19 @@ namespace gallery { void PreviewPage::openViewer(const int itemIndex, const int x, const int y) { - m_page = ViewerPage::Builder(). - setNaviframe(asShared(getNaviframe())). - setZoomIn(x, y). - setMedia(m_items[itemIndex]->getMedia()). - build(DELEGATE(PreviewPage::onPageExitRequest, this)); + ViewerPage::Builder builder; + builder.setNaviframe(asShared(getNaviframe())); + builder.setZoomIn(x, y); + builder.setMedia(m_items[itemIndex]->getMedia()); + + ImageGrid::ItemInfo info = {}; + m_imageGrid->getItemInfo(itemIndex, info); + if (info.isImageLoaded) { + builder.setImageLoadSize(info.imageLoadSize, + info.isImageLoadSizeFull); + } + + m_page = builder.build(DELEGATE(PreviewPage::onPageExitRequest, this)); } void PreviewPage::onPageExitRequest(Page &page) diff --git a/src/presenters/ThumbnailPage.cpp b/src/presenters/ThumbnailPage.cpp index 2828c13..0114b4c 100644 --- a/src/presenters/ThumbnailPage.cpp +++ b/src/presenters/ThumbnailPage.cpp @@ -120,6 +120,8 @@ namespace gallery { ImageGrid::ItemParams params = {}; params.imagePath = path; + m_parent.m_mediaItems[m_index]->getResolution( + params.imageWidth, params.imageHeight); m_parent.m_imageGrid->updateItem(m_index, params); } diff --git a/src/presenters/ViewerPage.cpp b/src/presenters/ViewerPage.cpp index 5d4fcbc..8765444 100644 --- a/src/presenters/ViewerPage.cpp +++ b/src/presenters/ViewerPage.cpp @@ -45,6 +45,8 @@ namespace gallery { ViewerPage::Builder::Builder() : m_zoomInX(-1), m_zoomInY(-1), + m_imageLoadSize(-1), + m_isImageLoadSizeFull(false), m_exitOnZoomOut(true) { } @@ -75,6 +77,14 @@ namespace gallery { return *this; } + ViewerPage::Builder &ViewerPage::Builder::setImageLoadSize( + const int size, const bool isFull) + { + m_imageLoadSize = size; + m_isImageLoadSizeFull = isFull; + return *this; + } + ViewerPage::Builder &ViewerPage::Builder::setExitOnZoomOut(const bool value) { m_exitOnZoomOut = value; @@ -101,7 +111,8 @@ namespace gallery { auto result = makeShared( m_navi, onExitRequest, m_media, m_exitOnZoomOut); - FAIL_RETURN_VALUE(result->prepare(), {}, "result->prepare() failed!"); + FAIL_RETURN_VALUE(result->prepare(m_imageLoadSize, + m_isImageLoadSizeFull), {}, "result->prepare() failed!"); if ((m_zoomInX >= 0) && (m_zoomInY >= 0)) { result->zoomIn(m_zoomInX, m_zoomInY); @@ -130,15 +141,19 @@ namespace gallery { } } - Result ViewerPage::prepare() + Result ViewerPage::prepare(const int imageLoadSize, + const bool isImageLoadSizeFull) { const int mediaFlags = m_media->getFlags(); const bool canSave = (mediaFlags & MediaItem::FLAG_SAVE); const bool hasThumb = (mediaFlags & MediaItem::FLAG_THUMBNAIL); + const bool useThumb = (hasThumb && (imageLoadSize < 0)); + const bool forceLoad = (!useThumb && isImageLoadSizeFull); m_imageViewer = ImageViewer::Builder(). setHighResImagePath(m_media->getFilePath()). - setForceLoad(!hasThumb). + setLoadSize(imageLoadSize). + setForceLoad(forceLoad). build(getNaviframe()); if (!m_imageViewer) { LOG_RETURN(RES_FAIL, "ImageViewer::build() failed!"); @@ -173,10 +188,12 @@ namespace gallery { m_more->setListener(asWeakThis(this)); } - if (hasThumb) { + if (useThumb) { FAIL_RETURN(m_media->getThumbnailPath(DELEGATE( ViewerPage::onThumbnail, this)), "m_media->getThumbnailPath() failed!"); + } else if (!forceLoad) { + m_imageViewer->setLowResImagePath(m_media->getFilePath()); } m_imageViewer->addEventHandler(IMAGE_VIEWER_ZOOM_END, diff --git a/src/view/ImageGrid.cpp b/src/view/ImageGrid.cpp index 864056d..beaa6d7 100644 --- a/src/view/ImageGrid.cpp +++ b/src/view/ImageGrid.cpp @@ -36,6 +36,8 @@ namespace gallery { namespace { namespace impl { const TString SIGNAL_SELECT_ITEM_FMT {"gallery,select,%d"}; const TString SIGNAL_UNSELECT_ITEM_FMT {"gallery,unselect,%d"}; + constexpr EdjeDataKey DATA_IMAGE_MIN_LOAD_SIZE {"image_min_load_size"}; + constexpr EdjeSignal SIGNAL_FORCE_SELECT_MODE {"gallery,force,select,mode"}; constexpr EdjeSignal SIGNAL_ENABLE_SELECT_MODE @@ -237,13 +239,7 @@ namespace gallery { RefCountAware(&rc), m_imageGrid(imageGrid), m_btn(elm_button_add(parent)), - m_image(evas_object_image_filled_add(m_btn.getEvas())), - m_realizeIndex(-1), - m_imageLoadSize(0), - m_wasUpdated(false), - m_isImageEmpty(false), - m_isClicksBlocked(false), - m_isSelected(false) + m_image(evas_object_image_filled_add(m_btn.getEvas())) { m_btn.setFocusAlowed(false); m_btn.setStyle(impl::ITEM_BTN_STYLE); @@ -270,11 +266,9 @@ namespace gallery { return m_btn; } - void setImageLoadSize(const int value) + void setImageMinLoadSize(const int value) { - m_imageLoadSize = value; - evas_object_image_load_size_set(m_image, - m_imageLoadSize, m_imageLoadSize); + m_imageMinLoadSize = std::max(value, 1); } bool isRealized() const @@ -282,6 +276,20 @@ namespace gallery { return (m_realizeIndex >= 0); } + void getInfo(ItemInfo &info) const + { + int w = m_imageWidth; + int h = m_imageHeight; + if (!impl::getImageSize(m_image, w, h)) { + WLOG("Invalid image size!"); + } + + info.imageLoadSize = m_imageLoadSize; + info.isImageLoadSizeFull = ( + (w == m_imageWidth) && (h == m_imageHeight)); + info.isImageLoaded = m_isImageLoaded; + } + void realize(const int itemIndex) { if (isRealized()) { @@ -366,31 +374,82 @@ namespace gallery { if (!m_wasUpdated || (params.flags & UF_LOSE_IMAGE)) { makeTransparent(m_image); m_isImageEmpty = true; + m_isImageLoaded = false; } return; } makeTransparent(m_image); m_isImageEmpty = false; + m_isImageLoaded = false; + + m_imageWidth = std::max(params.imageWidth, 1); + m_imageHeight = std::max(params.imageHeight, 1); evas_object_image_file_set(m_image, params.imagePath.c_str(), NULL); + updateImageLoadSize(); + evas_object_image_preload(m_image, EINA_FALSE); } - void onImagePreloaded(Widget &widget, void *eventInfo) + void updateImageLoadSize() { - if (m_isImageEmpty) { + const int newLoadSize = ((m_imageWidth > m_imageHeight) ? + (m_imageMinLoadSize * m_imageWidth / m_imageHeight) : + (m_imageMinLoadSize * m_imageHeight / m_imageWidth)); + if (newLoadSize == m_imageLoadSize) { return; } - int w = 1; - int h = 1; + int w = m_imageWidth; + int h = m_imageHeight; if (!impl::getImageSize(m_image, w, h)) { WLOG("Invalid image size!"); } - m_image.setARHint(WidgetARHint::NEITHER, w, h); + + if (isCurentLoadSizeSatisfying(w, h) || + !isImageRespectsLoadSize(w, h)) { + return; + } + + m_imageLoadSize = newLoadSize; + evas_object_image_load_size_set(m_image, + newLoadSize, newLoadSize); + } + + bool isCurentLoadSizeSatisfying( + const int curImgW, const int curImgH) const + { + const int kw = ((m_imageWidth > m_imageMinLoadSize) ? + (curImgW / m_imageMinLoadSize) : 1); + const int kh = ((m_imageHeight > m_imageMinLoadSize) ? + (curImgH / m_imageMinLoadSize) : 1); + return (((kw == 1) && (kh >= 1)) || ((kh == 1) && (kw >= 1))); + } + + bool isImageRespectsLoadSize( + const int curImgW, const int curImgH) const + { + return ((m_imageLoadSize <= 0) || + (curImgW != m_imageWidth) || + (curImgH != m_imageHeight) || ( + ((curImgW / m_imageLoadSize) <= 1) && + ((curImgH / m_imageLoadSize) <= 1) + )); + } + + void onImagePreloaded(Widget &widget, void *eventInfo) + { + if (m_isImageEmpty) { + return; + } + + m_isImageLoaded = true; + + m_image.setARHint(WidgetARHint::NEITHER, + m_imageWidth, m_imageHeight); makeWhite(m_image); } @@ -408,8 +467,6 @@ namespace gallery { if (!m_bgImage) { m_bgImage = makeShared( evas_object_image_filled_add(m_btn.getEvas())); - evas_object_image_load_size_set(*m_bgImage, - m_imageLoadSize, m_imageLoadSize); m_btn.setContent(*m_bgImage, impl::BTN_PART_BG); show(*m_bgImage); } @@ -417,13 +474,8 @@ namespace gallery { evas_object_image_file_set(*m_bgImage, params.bgImagePath.c_str(), NULL); - int w = 1; - int h = 1; - if (!impl::getImageSize(m_image, w, h) && - !impl::getImageSize(*m_bgImage, w, h)) { - WLOG("Invalid image size!"); - } - m_bgImage->setARHint(WidgetARHint::NEITHER, w, h); + m_bgImage->setARHint(WidgetARHint::NEITHER, + m_imageWidth, m_imageHeight); makeWhite(*m_bgImage); } @@ -458,12 +510,16 @@ namespace gallery { StyledWidget m_image; WidgetSRef m_bgImage; TouchParserSRef m_touchParser; - int m_realizeIndex; - int m_imageLoadSize; - bool m_wasUpdated; - bool m_isImageEmpty; - bool m_isClicksBlocked; - bool m_isSelected; + int m_realizeIndex = -1; + int m_imageLoadSize = 0; + int m_imageMinLoadSize = 1; + int m_imageWidth = 1; + int m_imageHeight = 1; + bool m_wasUpdated = false; + bool m_isImageEmpty = false; + bool m_isImageLoaded = false; + bool m_isClicksBlocked = false; + bool m_isSelected = false; }; public: @@ -472,6 +528,8 @@ namespace gallery { m_layout(elm_layout_add(imageGrid.m_box), true), m_isRealized(false) { + int imageMinLoadSize = 0; + if (isValid(m_info.slotThemes[isOdd])) { if (!m_layout.setTheme(m_info.slotThemes[isOdd])) { ELOG("setTheme() failed!"); @@ -480,6 +538,8 @@ namespace gallery { edje_object_message_signal_process( elm_layout_edje_get(m_layout)); } + imageMinLoadSize = ELM_SCALE_SIZE(m_layout.getData( + impl::DATA_IMAGE_MIN_LOAD_SIZE).asInt()); } fill(m_layout); show(m_layout); @@ -491,6 +551,8 @@ namespace gallery { const auto partName = impl::SLOT_PART_FMT.format(i); m_layout.setContent(m_items.back()->getWidget(), EdjePart(partName.c_str())); + + m_items.back()->setImageMinLoadSize(imageMinLoadSize); } } @@ -507,13 +569,6 @@ namespace gallery { return std::max((m_info.isHorizontal ? w : h), 1); } - void setImageLoadSize(const int value) - { - for (auto &item: m_items) { - item->setImageLoadSize(value); - } - } - void unrealize() { if (!m_isRealized) { @@ -557,6 +612,11 @@ namespace gallery { return m_items[itemOffset]->isRealized(); } + void getItemInfo(const int itemOffset, ItemInfo &info) const + { + m_items[itemOffset]->getInfo(info); + } + private: void setSelected(const int itemOffset, const bool selected) { @@ -928,6 +988,16 @@ namespace gallery { }); } + Result ImageGrid::getItemInfo(const int itemIndex, ItemInfo &info) const + { + return doWithItem(itemIndex, + [&info](Slot &slot, const int itemOffset) + { + slot.getItemInfo(itemOffset, info); + return RES_OK; + }); + } + template Result ImageGrid::doWithItem(const int itemIndex, FUNC &&func) const { @@ -1087,8 +1157,6 @@ namespace gallery { setSlotSize(slot->getSize()); } - slot->setImageLoadSize(m_slotSize); - elm_box_pack_before(m_box, slot->getLayout(), m_rect2); m_slots.emplace_back(std::move(slot)); diff --git a/src/view/ImageViewer.cpp b/src/view/ImageViewer.cpp index 17abcc2..0437bfc 100644 --- a/src/view/ImageViewer.cpp +++ b/src/view/ImageViewer.cpp @@ -32,6 +32,7 @@ namespace gallery { // ImageViewer::Builder // ImageViewer::Builder::Builder() : + m_loadSize(0), m_forceLoad(false) { } @@ -43,6 +44,12 @@ namespace gallery { return *this; } + ImageViewer::Builder &ImageViewer::Builder::setLoadSize(const int value) + { + m_loadSize = value; + return *this; + } + ImageViewer::Builder &ImageViewer::Builder::setForceLoad(const bool value) { m_forceLoad = value; @@ -61,13 +68,15 @@ namespace gallery { LOG_RETURN_VALUE(RES_FAIL, {}, "elm_scroller_add() failed!"); } - return makeShared(scroller, m_highResPath, m_forceLoad); + return makeShared(scroller, m_highResPath, + m_loadSize, m_forceLoad); } // ImageViewer // ImageViewer::ImageViewer(RefCountObjBase &rc, Evas_Object *const scroller, - const std::string &highResPath, const bool forceLoad) : + const std::string &highResPath, const int loadSize, + const bool forceLoad) : ElmWidget(&rc, scroller, true), m_scroller(makeShared(scroller)), @@ -96,7 +105,7 @@ namespace gallery { m_animator(nullptr), m_state(State::ZOOMED_OUT) { - prepare(highResPath, forceLoad); + prepare(highResPath, loadSize, forceLoad); } ImageViewer::~ImageViewer() @@ -110,7 +119,7 @@ namespace gallery { } void ImageViewer::prepare(const std::string &highResPath, - const bool forceLoad) + const int loadSize, const bool forceLoad) { expandAndFill(*m_scroller); m_scroller->setStyle(SCROLLER_STYLE); @@ -131,11 +140,18 @@ namespace gallery { show(m_grid); evas_object_grid_pack(m_grid, m_lowResImage, 0, 0, 1, 1); + if (loadSize > 0) { + evas_object_image_load_size_set(m_lowResImage, loadSize, loadSize); + } show(m_lowResImage); makeTransparent(m_lowResImage); evas_object_grid_pack(m_grid, m_highResImage, 0, 0, 1, 1); if (forceLoad) { + if (loadSize > 0) { + evas_object_image_load_size_set(m_highResImage, + loadSize, loadSize); + } evas_object_image_file_set(m_highResImage, highResPath.c_str(), nullptr); show(m_highResImage); -- 2.34.1