From: Igor Nazarov Date: Thu, 22 Jun 2017 13:39:31 +0000 (+0300) Subject: TizenRefApp-8731 [Gallery] Implement ucl::ListItemPresenter X-Git-Tag: submit/tizen/20170703.071445~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=50b8d9f3371d0669427a2991026b85c74dc7536c;p=profile%2Fwearable%2Fapps%2Fnative%2Fgallery.git TizenRefApp-8731 [Gallery] Implement ucl::ListItemPresenter - Implemented ucl::ListItemPresenter class; - Added HashMap::clear() function; - Added "const" to ucl::GenlistItem methods. Change-Id: I5430756a1afc30e0583e258943bb2e204e138d1b --- diff --git a/project_def.prop b/project_def.prop index b90d2da..eba950a 100644 --- a/project_def.prop +++ b/project_def.prop @@ -9,7 +9,7 @@ type = app profile = wearable-4.0 # C/CPP Sources -USER_SRCS = ucl/src/gui/NaviItem.cpp src/resources.cpp ucl/src/gui/Layout.cpp src/model/Gallery.cpp src/presenters/ThumbnailPage.cpp ucl/src/misc/Timeout.cpp src/view/PageContent.cpp src/presenters/ViewerPage.cpp ucl/src/appfw/UIApp.cpp src/model/MediaItem.cpp ucl/src/gui/ElmWidget.cpp ucl/src/appfw/helpers.cpp src/presenters/SelectModePresenter.cpp ucl/src/gui/EdjeWidget.cpp src/model/helpers.cpp src/view/ImageViewer.cpp src/presenters/AtspiHighlightHelper.cpp src/view/TouchParser.cpp ucl/src/gui/Window.cpp ucl/src/gui/Widget.cpp ucl/src/util/types/Result.cpp src/model/SoundManager.cpp src/model/GalleryAlbum.cpp src/presenters/Instance.cpp ucl/src/misc/Variant.cpp src/main.cpp src/presenters/InstanceManager.cpp src/presenters/AlertDialog.cpp src/model/BaseJob.cpp ucl/src/appfw/InstanceManagerBase.cpp src/presenters/VideoPlayerPage.cpp ucl/src/util/logging.cpp ucl/src/appfw/SysEventProvider.cpp src/view/helpers.cpp src/presenters/MoreOptionsPresenter.cpp src/presenters/PreviewPage.cpp ucl/src/mvp/GuiPresenter.cpp src/presenters/NoContentPage.cpp src/presenters/ProcessingPresenter.cpp ucl/src/gui/Naviframe.cpp src/presenters/Dialog.cpp src/presenters/Page.cpp src/view/ImageGrid.cpp src/presenters/helpers.cpp ucl/src/gui/WidgetItem.cpp +USER_SRCS = ucl/src/gui/NaviItem.cpp src/resources.cpp ucl/src/gui/Layout.cpp src/model/Gallery.cpp src/presenters/ThumbnailPage.cpp ucl/src/misc/Timeout.cpp src/view/PageContent.cpp src/presenters/ViewerPage.cpp ucl/src/appfw/UIApp.cpp src/model/MediaItem.cpp ucl/src/gui/ElmWidget.cpp ucl/src/appfw/helpers.cpp src/presenters/SelectModePresenter.cpp ucl/src/gui/EdjeWidget.cpp src/model/helpers.cpp src/view/ImageViewer.cpp src/presenters/AtspiHighlightHelper.cpp src/view/TouchParser.cpp ucl/src/gui/Window.cpp ucl/src/gui/Widget.cpp ucl/src/util/types/Result.cpp src/model/SoundManager.cpp ucl/src/mvp/ListItemPresenter.cpp src/model/GalleryAlbum.cpp src/presenters/Instance.cpp ucl/src/misc/Variant.cpp src/main.cpp src/presenters/InstanceManager.cpp src/presenters/AlertDialog.cpp src/model/BaseJob.cpp ucl/src/appfw/InstanceManagerBase.cpp src/presenters/VideoPlayerPage.cpp ucl/src/util/logging.cpp ucl/src/appfw/SysEventProvider.cpp src/view/helpers.cpp src/presenters/MoreOptionsPresenter.cpp src/presenters/PreviewPage.cpp ucl/src/mvp/GuiPresenter.cpp src/presenters/NoContentPage.cpp ucl/src/gui/Genlist.cpp src/presenters/ProcessingPresenter.cpp ucl/src/gui/Naviframe.cpp src/presenters/Dialog.cpp src/presenters/Page.cpp src/view/ImageGrid.cpp src/presenters/helpers.cpp ucl/src/gui/WidgetItem.cpp # EDC Sources USER_EDCS = diff --git a/ucl/inc/ucl/gui/GenlistItem.h b/ucl/inc/ucl/gui/GenlistItem.h index fddf153..2c96b9c 100644 --- a/ucl/inc/ucl/gui/GenlistItem.h +++ b/ucl/inc/ucl/gui/GenlistItem.h @@ -46,15 +46,15 @@ namespace ucl { public: using WidgetItem::WidgetItem; - void setSelectMode(SelectMode mode); + void setSelectMode(SelectMode mode) const; SelectMode getSelectMode() const; - void setSelected(bool isSelected); + void setSelected(bool isSelected) const; bool isSelected() const; - void update(); - void update(const Elm_Genlist_Item_Class *newItc); - void update(const char *parts, int fields = FIELD_ALL); + void update() const; + void update(const Elm_Genlist_Item_Class *newItc) const; + void update(const char *parts, int fields = FIELD_ALL) const; }; } diff --git a/ucl/inc/ucl/gui/GenlistItem.hpp b/ucl/inc/ucl/gui/GenlistItem.hpp index b711464..6920a88 100644 --- a/ucl/inc/ucl/gui/GenlistItem.hpp +++ b/ucl/inc/ucl/gui/GenlistItem.hpp @@ -16,7 +16,7 @@ namespace ucl { - inline void GenlistItem::setSelectMode(const SelectMode mode) + inline void GenlistItem::setSelectMode(const SelectMode mode) const { elm_genlist_item_select_mode_set(getIt(), static_cast(mode)); @@ -28,7 +28,7 @@ namespace ucl { elm_genlist_item_select_mode_get(getIt())); } - inline void GenlistItem::setSelected(const bool isSelected) + inline void GenlistItem::setSelected(const bool isSelected) const { elm_genlist_item_selected_set(getIt(), toEina(isSelected)); } @@ -38,17 +38,19 @@ namespace ucl { return elm_genlist_item_selected_get(getIt()); } - inline void GenlistItem::update() + inline void GenlistItem::update() const { elm_genlist_item_update(getIt()); } - inline void GenlistItem::update(const Elm_Genlist_Item_Class *const newItc) + inline void GenlistItem::update( + const Elm_Genlist_Item_Class *const newItc) const { elm_genlist_item_item_class_update(getIt(), newItc); } - inline void GenlistItem::update(const char *const parts, const int fields) + inline void GenlistItem::update( + const char *const parts, const int fields) const { elm_genlist_item_fields_update(getIt(), parts, static_cast(fields)); diff --git a/ucl/inc/ucl/misc/HashMap.h b/ucl/inc/ucl/misc/HashMap.h index af41cdb..8470fed 100644 --- a/ucl/inc/ucl/misc/HashMap.h +++ b/ucl/inc/ucl/misc/HashMap.h @@ -42,6 +42,8 @@ namespace ucl { bool get(const KEY &key, VALUE2 &value) const; VALUE get(const KEY &key) const; + void clear(); + private: template struct EnumClassHash final { diff --git a/ucl/inc/ucl/misc/HashMap.hpp b/ucl/inc/ucl/misc/HashMap.hpp index 05a0652..2ba4ffd 100644 --- a/ucl/inc/ucl/misc/HashMap.hpp +++ b/ucl/inc/ucl/misc/HashMap.hpp @@ -18,7 +18,7 @@ namespace ucl { template template - HashMap &HashMap:: + inline HashMap &HashMap:: set(const KEY &key, VALUE2 &&value) { m_map.emplace(key, std::forward(value)); @@ -26,7 +26,7 @@ namespace ucl { } template - HashMap &HashMap:: + inline HashMap &HashMap:: unset(const KEY &key) { m_map.erase(key); @@ -35,7 +35,7 @@ namespace ucl { template template - bool HashMap:: + inline bool HashMap:: get(const KEY &key, VALUE2 &value) const { const auto it = m_map.find(key); @@ -47,7 +47,7 @@ namespace ucl { } template - VALUE HashMap:: + inline VALUE HashMap:: get(const KEY &key) const { const auto it = m_map.find(key); @@ -56,4 +56,10 @@ namespace ucl { } return it->second; } + + template + inline void HashMap::clear() + { + m_map.clear(); + } } diff --git a/ucl/inc/ucl/mvp/ListItemPresenter.h b/ucl/inc/ucl/mvp/ListItemPresenter.h new file mode 100644 index 0000000..2c90f42 --- /dev/null +++ b/ucl/inc/ucl/mvp/ListItemPresenter.h @@ -0,0 +1,128 @@ +/* + * 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_MVP_LIST_ITEM_PRESENTER_H__ +#define __UCL_MVP_LIST_ITEM_PRESENTER_H__ + +#include "ucl/gui/GenlistItem.h" + +#include "ucl/misc/HashMap.h" + +#include "types.h" + +namespace ucl { + + UCL_DECLARE_REF_ALIASES(ListItemPresenter); + + class ListItemPresenter : public RefCountAware, + public IDisposable { + public: + // IDisposable // + + virtual void dispose() final override; + virtual bool isDisposed() const final override; + + protected: + friend class ListPresenter; + + UCL_DECLARE_REF_ALIASES(ItemClass); + UCL_DECLARE_REF_ALIASES(ItemClassCache); + + // Flags + enum { + PF_AUTO_UNSELECT = 1 + }; + + struct ItemInsertionParams { + ElmStyle itemStyle; + GenlistItem::Type itemType; + + ItemInsertionParams(ElmStyle itemStyle, + GenlistItem::Type itemType = GenlistItem::Type::SIMPLE) : + itemStyle(itemStyle), itemType(itemType) {} + }; + + class ItemClass final : public NonCopyable { + public: + static ItemClassSRef newInstance(ElmStyle itemStyle); + public: + Elm_Genlist_Item_Class *get(); + private: + friend class ReffedObj; + ItemClass(ElmStyle itemStyle); + ~ItemClass(); + private: + Elm_Genlist_Item_Class *const m_itc; + }; + + class ItemClassCache final : public NonCopyable { + public: + ItemClassSRef getItemClass(ElmStyle itemStyle); + void purge(); + private: + HashMap m_itcMap; + }; + + protected: + ListItemPresenter(IRefCountObj &rc); + virtual ~ListItemPresenter(); + + void setFlags(int flags); + int getFlags() const; + + bool isActive() const; + + GenlistItem getItem(); + ItemClassCacheSRef getItemClassCache(); + + Result updateItemStyle(ElmStyle newItemStyle); + + virtual ItemInsertionParams getItemInsertionParams() = 0; + + virtual void onItemAttached(); + virtual void onItemDetached(); + + virtual CString getItemPartText(EdjePart part); + virtual WidgetSRef getItemPartContent(EdjePart part); + virtual bool getItemPartState(EdjePart part); + + virtual void onItemSelected(); + virtual void onItemRealized(); + virtual void onItemUnrealized(); + virtual void onItemHighlighted(); + virtual void onItemUnhighlighted(); + + private: + void attachItem(GenlistItem item, + const ItemClassCacheSRef &itcCache, + const SharedRef &isActiveRef); + + void deleteDetachedItem(bool silent = false); + void detachItem(bool silent = false); + + void onItemSelectedHook(); + void onItemDel(Evas_Object *obj, void *eventInfo); + + private: + ListItemPresenterSRef m_selfRef; + GenlistItem m_item; + ItemClassCacheWRef m_itcCache; + SharedRef m_isActiveRef; + int m_flags; + }; +} + +#endif // __UCL_MVP_LIST_ITEM_PRESENTER_H__ diff --git a/ucl/src/mvp/ListItemPresenter.cpp b/ucl/src/mvp/ListItemPresenter.cpp new file mode 100644 index 0000000..70128b2 --- /dev/null +++ b/ucl/src/mvp/ListItemPresenter.cpp @@ -0,0 +1,292 @@ +/* + * 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 "ucl/mvp/ListItemPresenter.h" + +#include "common.h" + +namespace ucl { + + // ListItemPresenter::ItemClass // + + ListItemPresenter::ItemClassSRef ListItemPresenter::ItemClass:: + newInstance(const ElmStyle itemStyle) + { + auto result = makeShared(itemStyle); + if (!result->m_itc) { + LOG_RETURN_VALUE(RES_FAIL, {}, "Failed to create ItemClass()!"); + } + return result; + } + + ListItemPresenter::ItemClass::ItemClass(const ElmStyle itemStyle) : + m_itc(elm_genlist_item_class_new()) + { + if (!m_itc) { + return; + } + + m_itc->item_style = itemStyle.name; + + m_itc->func.text_get = + [](void *data, Evas_Object *obj, const char *part) -> char * + { + if (!data) { + LOG_RETURN_VALUE(RES_FATAL, nullptr, "data is NULL"); + } + return (char *)static_cast(data)-> + getItemPartText(EdjePart(part)).release(); + }; + + m_itc->func.content_get = + [](void *data, Evas_Object *obj, const char *part) -> Evas_Object * + { + if (!data) { + LOG_RETURN_VALUE(RES_FATAL, nullptr, "data is NULL"); + } + if (const auto widget = static_cast(data)-> + getItemPartContent(EdjePart(part))) { + widget->setIsOwner(false); + return widget->getEo(); + } + return nullptr; + }; + + m_itc->func.state_get = + [](void *data, Evas_Object *obj, const char *part) -> Eina_Bool + { + if (!data) { + LOG_RETURN_VALUE(RES_FATAL, false, "data is NULL"); + } + return static_cast(data)-> + getItemPartState(EdjePart(part)); + }; + } + + ListItemPresenter::ItemClass::~ItemClass() + { + if (m_itc) { + elm_genlist_item_class_free(m_itc); + } + } + + Elm_Genlist_Item_Class *ListItemPresenter::ItemClass::get() + { + return m_itc; + } + + // ListItemPresenter::ItemClassCache // + + ListItemPresenter::ItemClassSRef ListItemPresenter::ItemClassCache:: + getItemClass(const ElmStyle itemStyle) + { + ItemClassSRef result; + + if (!m_itcMap.get(itemStyle, result)) { + result = ItemClass::newInstance(itemStyle); + if (result) { + m_itcMap.set(itemStyle, result); + } else { + ELOG("ItemClass::newInstance() failed!"); + } + } + + return result; + } + + void ListItemPresenter::ItemClassCache::purge() + { + m_itcMap.clear(); + } + + // ListItemPresenter // + + ListItemPresenter::ListItemPresenter(IRefCountObj &rc) : + RefCountAware(&rc), + m_flags(PF_AUTO_UNSELECT) + { + } + + ListItemPresenter::~ListItemPresenter() + { + if (m_item) { + FLOG("m_item is still alive!"); + deleteDetachedItem(true); + } + } + + void ListItemPresenter::attachItem(GenlistItem item, + const ItemClassCacheSRef &itcCache, + const SharedRef &isActiveRef) + { + if (!item) { + LOG_RETURN_VOID(RES_FAIL, "item is NULL!"); + } + + if (m_item) { + deleteDetachedItem(); + } + + m_item = item; + m_item.setData(this); + m_item.setDelCallback(CALLBACK_A(ListItemPresenter::onItemDel)); + + m_itcCache = itcCache; + m_isActiveRef = isActiveRef; + + if (!m_selfRef) { + m_selfRef = asShared(*this); + } + + onItemAttached(); + } + + void ListItemPresenter::deleteDetachedItem(const bool silent) + { + auto item = m_item; + detachItem(silent); + item.del(); + } + + void ListItemPresenter::detachItem(const bool silent) + { + m_item.setData(nullptr); + m_item.setDelCallback(nullptr); + m_item = nullptr; + if (!silent) { + onItemDetached(); + } + } + + void ListItemPresenter::onItemDel(Evas_Object *obj, void *eventInfo) + { + if (m_item) { + detachItem(); + } + m_selfRef.reset(); + } + + void ListItemPresenter::setFlags(const int flags) + { + m_flags = flags; + } + + int ListItemPresenter::getFlags() const + { + return m_flags; + } + + bool ListItemPresenter::isActive() const + { + return (m_isActiveRef ? *m_isActiveRef : false); + } + + GenlistItem ListItemPresenter::getItem() + { + return m_item; + } + + ListItemPresenter::ItemClassCacheSRef + ListItemPresenter::getItemClassCache() + { + return m_itcCache.lock(); + } + + Result ListItemPresenter::updateItemStyle(const ElmStyle newItemStyle) + { + if (!m_item) { + LOG_RETURN(RES_ILLEGAL_STATE, "m_item is NULL!"); + } + + const auto itcCache = getItemClassCache(); + if (!itcCache) { + LOG_RETURN(RES_FATAL, "itcCache is NULL!"); + } + + const auto itc = itcCache->getItemClass(newItemStyle); + if (!itc) { + LOG_RETURN(RES_FAIL, "itcCache.getItemClass() failed!"); + } + + m_item.update(itc->get()); + + return RES_OK; + } + + void ListItemPresenter::dispose() + { + if (m_item) { + deleteDetachedItem(); + m_selfRef.reset(); + } + } + + bool ListItemPresenter::isDisposed() const + { + return !m_item; + } + + void ListItemPresenter::onItemAttached() + { + } + + void ListItemPresenter::onItemDetached() + { + } + + WidgetSRef ListItemPresenter::getItemPartContent(const EdjePart part) + { + return nullptr; + } + + CString ListItemPresenter::getItemPartText(const EdjePart part) + { + return nullptr; + } + + bool ListItemPresenter::getItemPartState(const EdjePart part) + { + return false; + } + + void ListItemPresenter::onItemSelectedHook() + { + if (m_flags & PF_AUTO_UNSELECT) { + m_item.setSelected(false); + } + onItemSelected(); + } + + void ListItemPresenter::onItemSelected() + { + } + + void ListItemPresenter::onItemRealized() + { + } + + void ListItemPresenter::onItemUnrealized() + { + } + + void ListItemPresenter::onItemHighlighted() + { + } + + void ListItemPresenter::onItemUnhighlighted() + { + } +}