TizenRefApp-8731 [Gallery] Implement ucl::ListItemPresenter 85/135485/2
authorIgor Nazarov <i.nazarov@samsung.com>
Thu, 22 Jun 2017 13:39:31 +0000 (16:39 +0300)
committerIgor Nazarov <i.nazarov@samsung.com>
Thu, 22 Jun 2017 17:37:49 +0000 (20:37 +0300)
- Implemented ucl::ListItemPresenter class;
- Added HashMap::clear() function;
- Added "const" to ucl::GenlistItem methods.

Change-Id: I5430756a1afc30e0583e258943bb2e204e138d1b

project_def.prop
ucl/inc/ucl/gui/GenlistItem.h
ucl/inc/ucl/gui/GenlistItem.hpp
ucl/inc/ucl/misc/HashMap.h
ucl/inc/ucl/misc/HashMap.hpp
ucl/inc/ucl/mvp/ListItemPresenter.h [new file with mode: 0644]
ucl/src/mvp/ListItemPresenter.cpp [new file with mode: 0644]

index b90d2dac221f1952074d5d4900d15e6192a18042..eba950a4ee180f9b1569855741f4250782e8ee80 100644 (file)
@@ -9,7 +9,7 @@ type = app
 profile = wearable-4.0\r
 \r
 # C/CPP Sources\r
-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 \r
+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 \r
 \r
 # EDC Sources\r
 USER_EDCS =  \r
index fddf15346736df57d73bcd401225839e2b5a9661..2c96b9caa6791dfd119065e31ba108e9d9bf9191 100644 (file)
@@ -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;
        };
 }
 
index b71146425b92c1e8599f6ced82dfc748bb54a1bb..6920a88e14ca01f007e635c868ca86055bc5afb5 100644 (file)
@@ -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<Elm_Object_Select_Mode>(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<Elm_Genlist_Item_Field_Type>(fields));
index af41cdbf28abd4e99bae36c529ca0816db770a20..8470fed6ebdd33e23a2597c9afb54ae9f1a77570 100644 (file)
@@ -42,6 +42,8 @@ namespace ucl {
                bool get(const KEY &key, VALUE2 &value) const;
                VALUE get(const KEY &key) const;
 
+               void clear();
+
        private:
                template <class ENUM_CLASS>
                struct EnumClassHash final {
index 05a0652c6b0f8d0df2d3e9c2d10bd20751fea53c..2ba4ffdb581e8a7ed85c92b12a514374b51f878e 100644 (file)
@@ -18,7 +18,7 @@ namespace ucl {
 
        template <class KEY, class VALUE>
        template <class VALUE2>
-       HashMap<KEY, VALUE> &HashMap<KEY, VALUE>::
+       inline HashMap<KEY, VALUE> &HashMap<KEY, VALUE>::
                        set(const KEY &key, VALUE2 &&value)
        {
                m_map.emplace(key, std::forward<VALUE2>(value));
@@ -26,7 +26,7 @@ namespace ucl {
        }
 
        template <class KEY, class VALUE>
-       HashMap<KEY, VALUE> &HashMap<KEY, VALUE>::
+       inline HashMap<KEY, VALUE> &HashMap<KEY, VALUE>::
                        unset(const KEY &key)
        {
                m_map.erase(key);
@@ -35,7 +35,7 @@ namespace ucl {
 
        template <class KEY, class VALUE>
        template <class VALUE2>
-       bool HashMap<KEY, VALUE>::
+       inline bool HashMap<KEY, VALUE>::
                        get(const KEY &key, VALUE2 &value) const
        {
                const auto it = m_map.find(key);
@@ -47,7 +47,7 @@ namespace ucl {
        }
 
        template <class KEY, class VALUE>
-       VALUE HashMap<KEY, VALUE>::
+       inline VALUE HashMap<KEY, VALUE>::
                        get(const KEY &key) const
        {
                const auto it = m_map.find(key);
@@ -56,4 +56,10 @@ namespace ucl {
                }
                return it->second;
        }
+
+       template <class KEY, class VALUE>
+       inline void HashMap<KEY, VALUE>::clear()
+       {
+               m_map.clear();
+       }
 }
diff --git a/ucl/inc/ucl/mvp/ListItemPresenter.h b/ucl/inc/ucl/mvp/ListItemPresenter.h
new file mode 100644 (file)
index 0000000..2c90f42
--- /dev/null
@@ -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>;
+                       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<ElmStyle, ItemClassSRef> 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<bool> &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<bool> 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 (file)
index 0000000..70128b2
--- /dev/null
@@ -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<ItemClass>(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<ListItemPresenter *>(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<ListItemPresenter *>(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<ListItemPresenter *>(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<bool> &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()
+       {
+       }
+}