TizenRefApp-8732 [Gallery] Implement ucl::ListPresenter 00/135500/2
authorIgor Nazarov <i.nazarov@samsung.com>
Thu, 22 Jun 2017 17:40:47 +0000 (20:40 +0300)
committerIgor Nazarov <i.nazarov@samsung.com>
Fri, 23 Jun 2017 10:08:49 +0000 (13:08 +0300)
Change-Id: Ia53b98d1847eab0bb41245ce0d599e3be2a03e11

project_def.prop
ucl/inc/ucl/mvp/ListPresenter.h [new file with mode: 0644]
ucl/src/mvp/ListItemPresenter.cpp
ucl/src/mvp/ListPresenter.cpp [new file with mode: 0644]

index eba950a4ee180f9b1569855741f4250782e8ee80..405f2c56e53c5cd914e189858598e95846e95f4a 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 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
+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 ucl/src/mvp/ListPresenter.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
diff --git a/ucl/inc/ucl/mvp/ListPresenter.h b/ucl/inc/ucl/mvp/ListPresenter.h
new file mode 100644 (file)
index 0000000..1d62e41
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * 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_PRESENTER_H__
+#define __UCL_MVP_LIST_PRESENTER_H__
+
+#include "ucl/gui/Genlist.h"
+
+#include "GuiPresenter.h"
+#include "ListItemPresenter.h"
+
+namespace ucl {
+
+       UCL_DECLARE_REF_ALIASES(ListPresenter);
+
+       class ListPresenter final : public GuiPresenter {
+       public:
+               enum {
+                       FLAG_HOMOGENEOUS = (1 << 0),
+                       FLAG_CALC_X_MIN = (1 << 1),
+                       FLAG_CALC_Y_MIN = (1 << 2),
+
+                       FLAG_NOTIFY_REALIZED = (1 << 8),
+                       FLAG_NOTIFY_UNREALIZED = (1 << 9),
+                       FLAG_NOTIFY_HIGHLIGHTED = (1 << 10),
+                       FLAG_NOTIFY_UNHIGHLIGHTED = (1 << 11),
+               };
+
+               class Builder final {
+               public:
+                       Builder();
+                       Builder &setStyle(ElmStyle style);
+                       Builder &setFlags(int flags);
+                       Builder &setParentWidget(const ElmWidgetSRef &parentWidget);
+                       ListPresenterSRef build(GuiPresenter &parent) const;
+               private:
+                       ucl::ElmWidgetSRef m_parentWidget;
+                       ElmStyle m_style;
+                       int m_flags;
+               };
+
+       public:
+               Genlist &getWidget();
+
+               void clear();
+
+               Result append(ListItemPresenter &itemPresenter,
+                               ListItemPresenter *parent = nullptr);
+
+               Result prepend(ListItemPresenter &itemPresenter,
+                               ListItemPresenter *parent = nullptr);
+
+               Result insertAfter(const ListItemPresenter &after,
+                               ListItemPresenter &itemPresenter,
+                               ListItemPresenter *parent = nullptr);
+
+               Result insertBefore(const ListItemPresenter &before,
+                               ListItemPresenter &itemPresenter,
+                               ListItemPresenter *parent = nullptr);
+
+       private:
+               friend class ReffedObj<ListPresenter>;
+               ListPresenter(IRefCountObj &rc);
+               virtual ~ListPresenter();
+
+               Result prepare(GuiPresenter &parent, ElmWidget &parentWidget,
+                               ElmStyle style, int flags);
+
+               template <class INSERT_FUNC>
+               Result insert(ListItemPresenter &itemPresenter,
+                               ListItemPresenter *parent,
+                               INSERT_FUNC &&insertFunc);
+
+               template <class INSERT_FUNC>
+               Result insertRelative(const ListItemPresenter &relative,
+                               ListItemPresenter &itemPresenter,
+                               ListItemPresenter *parent, INSERT_FUNC &&insertFunc);
+
+               void setIsActiveRef(bool value);
+
+               void onItemSelected(Widget &widget, void *eventInfo);
+
+               void onItemRealized(Widget &widget, void *eventInfo);
+               void onItemUnrealized(Widget &widget, void *eventInfo);
+               void onItemHighlighted(Widget &widget, void *eventInfo);
+               void onItemUnhighlighted(Widget &widget, void *eventInfo);
+
+               // GuiPresenter //
+
+               virtual void onActivate() final override;
+               virtual void onDeactivate() final override;
+
+       private:
+               GenlistSRef m_genlist;
+               ListItemPresenter::ItemClassCacheSRef m_itcCache;
+               SharedRef<bool> m_isActiveRef;
+       };
+}
+
+#endif // __UCL_MVP_LIST_PRESENTER_H__
index 70128b268e6e5ae9cb778abb63b1455005f3133d..e2ad69a26a42ae4d2cf104adfe738d643c82a122 100644 (file)
@@ -26,7 +26,7 @@ namespace ucl {
                        newInstance(const ElmStyle itemStyle)
        {
                auto result = makeShared<ItemClass>(itemStyle);
-               if (!result->m_itc) {
+               if (!result->get()) {
                        LOG_RETURN_VALUE(RES_FAIL, {}, "Failed to create ItemClass()!");
                }
                return result;
@@ -47,7 +47,7 @@ namespace ucl {
                                if (!data) {
                                        LOG_RETURN_VALUE(RES_FATAL, nullptr, "data is NULL");
                                }
-                               return (char *)static_cast<ListItemPresenter *>(data)->
+                               return static_cast<ListItemPresenter *>(data)->
                                                getItemPartText(EdjePart(part)).release();
                        };
 
diff --git a/ucl/src/mvp/ListPresenter.cpp b/ucl/src/mvp/ListPresenter.cpp
new file mode 100644 (file)
index 0000000..220b10e
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * 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/ListPresenter.h"
+
+#include "common.h"
+
+namespace ucl { namespace { namespace impl {
+
+       constexpr SmartEvent ITEM_SELECTED {"selected"};
+
+       constexpr SmartEvent ITEM_REALIZED {"realized"};
+       constexpr SmartEvent ITEM_UNREALIZED {"unrealized"};
+       constexpr SmartEvent ITEM_HIGHLIGHTED {"highlighted"};
+       constexpr SmartEvent ITEM_UNHIGHLIGHTED {"unhighlighted"};
+
+       ListItemPresenter *toItemPresenter(void *eventInfo)
+       {
+               if (!eventInfo) {
+                       LOG_RETURN_VALUE(RES_FATAL, nullptr, "eventInfo is NULL");
+               }
+
+               const GenlistItem item{static_cast<Elm_Object_Item *>(eventInfo)};
+               const auto data = item.getData();
+               if (!data) {
+                       LOG_RETURN_VALUE(RES_FATAL, nullptr, "data is NULL");
+               }
+
+               return static_cast<ListItemPresenter *>(data);
+       }
+}}}
+
+namespace ucl {
+
+       // ListPresenter::Builder //
+
+       ListPresenter::Builder::Builder() :
+               m_flags(FLAG_HOMOGENEOUS)
+       {
+       }
+
+       ListPresenter::Builder &ListPresenter::Builder::setStyle(
+                       const ElmStyle style)
+       {
+               m_style = style;
+               return *this;
+       }
+
+       ListPresenter::Builder &ListPresenter::Builder::setFlags(const int flags)
+       {
+               m_flags = flags;
+               return *this;
+       }
+
+       ListPresenter::Builder &ListPresenter::Builder::setParentWidget(
+                       const ElmWidgetSRef &parentWidget)
+       {
+               m_parentWidget = parentWidget;
+               return *this;
+       }
+
+       ListPresenterSRef ListPresenter::Builder::build(GuiPresenter &parent) const
+       {
+               if (!m_parentWidget) {
+                       LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {},
+                                       "m_parentWidget is NULL!");
+               }
+
+               auto result = makeShared<ListPresenter>();
+
+               FAIL_RETURN_VALUE(result->prepare(
+                               parent, *m_parentWidget, m_style, m_flags),
+                               {}, "result->prepare() failed!");
+
+               return result;
+       }
+
+       // ListPresenter //
+
+       ListPresenter::ListPresenter(IRefCountObj &rc) :
+                       GuiPresenter(rc)
+       {
+       }
+
+       ListPresenter::~ListPresenter()
+       {
+       }
+
+       Result ListPresenter::prepare(
+                       GuiPresenter &parent, ElmWidget &parentWidget,
+                       const ElmStyle style, const int flags)
+       {
+               FAIL_RETURN(GuiPresenter::prepare(parent, PF_DEACTIVATOR),
+                               "GuiPresenter::prepare() failed!");
+
+               m_genlist = Genlist::Builder().
+                               setStyle(style).
+                               setMode(Genlist::Mode::COMPRESS).
+                               setHomogeneous(flags & FLAG_HOMOGENEOUS).
+                               setIsOwner(true).
+                               setNeedBindToEo(true).
+                               build(parentWidget);
+               if (!m_genlist) {
+                       LOG_RETURN(RES_FAIL, "Genlist::build() failed!");
+               }
+
+               expandAndFill(*m_genlist);
+
+               // TODO Add Scroller widget.
+               elm_scroller_content_min_limit(*m_genlist,
+                               toEina((flags & FLAG_CALC_X_MIN) != 0),
+                               toEina((flags & FLAG_CALC_Y_MIN) != 0));
+
+               m_itcCache = makeShared<ListItemPresenter::ItemClassCache>();
+
+               m_isActiveRef = makeShared<bool>();
+               *m_isActiveRef = isActive();
+
+               m_genlist->addEventHandler(impl::ITEM_SELECTED, WEAK_DELEGATE(
+                               ListPresenter::onItemSelected, asWeak(*this)));
+
+               if (flags & FLAG_NOTIFY_REALIZED) {
+                       m_genlist->addEventHandler(impl::ITEM_REALIZED, WEAK_DELEGATE(
+                                       ListPresenter::onItemRealized, asWeak(*this)));
+               }
+               if (flags & FLAG_NOTIFY_UNREALIZED) {
+                       m_genlist->addEventHandler(impl::ITEM_UNREALIZED, WEAK_DELEGATE(
+                                       ListPresenter::onItemUnrealized, asWeak(*this)));
+               }
+               if (flags & FLAG_NOTIFY_HIGHLIGHTED) {
+                       m_genlist->addEventHandler(impl::ITEM_HIGHLIGHTED, WEAK_DELEGATE(
+                                       ListPresenter::onItemHighlighted, asWeak(*this)));
+               }
+               if (flags & FLAG_NOTIFY_UNHIGHLIGHTED) {
+                       m_genlist->addEventHandler(impl::ITEM_UNHIGHLIGHTED, WEAK_DELEGATE(
+                                       ListPresenter::onItemUnhighlighted, asWeak(*this)));
+               }
+
+               return RES_OK;
+       }
+
+       Genlist &ListPresenter::getWidget()
+       {
+               return *m_genlist;
+       }
+
+       void ListPresenter::clear()
+       {
+               m_genlist->clear();
+               m_itcCache->purge();
+       }
+
+       Result ListPresenter::append(ListItemPresenter &itemPresenter,
+                               ListItemPresenter *parent)
+       {
+               return insert(itemPresenter, parent,
+                       [this](const Elm_Genlist_Item_Class *itc, const void *data,
+                                       GenlistItem parent, GenlistItem::Type type)
+                       {
+                               return m_genlist->append(itc, data, nullptr, type, parent);
+                       });
+       }
+
+       Result ListPresenter::prepend(ListItemPresenter &itemPresenter,
+                               ListItemPresenter *parent)
+       {
+               return insert(itemPresenter, parent,
+                       [this](const Elm_Genlist_Item_Class *itc, const void *data,
+                                       GenlistItem parent, GenlistItem::Type type)
+                       {
+                               return m_genlist->prepend(itc, data, nullptr, type, parent);
+                       });
+       }
+
+       Result ListPresenter::insertAfter(const ListItemPresenter &after,
+                       ListItemPresenter &itemPresenter,
+                               ListItemPresenter *parent)
+       {
+               return insertRelative(after, itemPresenter, parent,
+                       [this](GenlistItem rel, const Elm_Genlist_Item_Class *itc,
+                               const void *data, GenlistItem parent, GenlistItem::Type type)
+                       {
+                               return m_genlist->insertAfter(
+                                               rel, itc, data, nullptr, type, parent);
+                       });
+       }
+
+       Result ListPresenter::insertBefore(const ListItemPresenter &before,
+                       ListItemPresenter &itemPresenter,
+                               ListItemPresenter *parent)
+       {
+               return insertRelative(before, itemPresenter, parent,
+                       [this](GenlistItem rel, const Elm_Genlist_Item_Class *itc,
+                               const void *data, GenlistItem parent, GenlistItem::Type type)
+                       {
+                               return m_genlist->insertBefore(
+                                               rel, itc, data, nullptr, type, parent);
+                       });
+       }
+
+       template <class INSERT_FUNC>
+       Result ListPresenter::insert(ListItemPresenter &itemPresenter,
+                       ListItemPresenter *parent, INSERT_FUNC &&insertFunc)
+       {
+               const auto params = itemPresenter.getItemInsertionParams();
+
+               const auto itc = m_itcCache->getItemClass(params.itemStyle);
+               if (!itc) {
+                       LOG_RETURN(RES_FAIL, "m_itcCache.getItemClass() failed!");
+               }
+
+               GenlistItem parentItem;
+               if (parent) {
+                       parentItem = parent->m_item;
+                       if (!parentItem) {
+                               ELOG("parentItem is NULL");
+                       }
+               }
+
+               const auto item = insertFunc(itc->get(),
+                               &itemPresenter, parentItem, params.itemType);
+               if (!item) {
+                       LOG_RETURN(RES_FAIL, "insertFunc() failed!");
+               }
+
+               itemPresenter.attachItem(item, m_itcCache, m_isActiveRef);
+
+               return RES_OK;
+       }
+
+       template <class INSERT_FUNC>
+       Result ListPresenter::insertRelative(const ListItemPresenter &relative,
+                       ListItemPresenter &itemPresenter, ListItemPresenter *parent,
+                       INSERT_FUNC &&insertFunc)
+       {
+               const auto relItem = relative.m_item;
+               if (!relItem) {
+                       LOG_RETURN(RES_FAIL, "relItem is NULL!");
+               }
+               if (relItem.getWidget() != m_genlist->getEo()) {
+                       LOG_RETURN(RES_FAIL, "relItem has wrong genlist!");
+               }
+               return insert(itemPresenter, parent,
+                       [relItem, &insertFunc](const Elm_Genlist_Item_Class *itc,
+                               const void *data, GenlistItem parent, GenlistItem::Type type)
+                       {
+                               return insertFunc(relItem, itc, data, parent, type);
+                       });
+       }
+
+       void ListPresenter::setIsActiveRef(const bool value)
+       {
+               if (!m_isActiveRef) {
+                       LOG_RETURN_VOID(RES_FATAL, "m_isActiveRef is NULL");
+               }
+               *m_isActiveRef = value;
+       }
+
+       void ListPresenter::onItemSelected(Widget &widget, void *eventInfo)
+       {
+               const auto itemPresenter = impl::toItemPresenter(eventInfo);
+               if (!itemPresenter) {
+                       LOG_RETURN_VOID(RES_FATAL, "itemPresenter is NULL");
+               }
+               itemPresenter->onItemSelectedHook();
+       }
+
+       void ListPresenter::onItemRealized(Widget &widget, void *eventInfo)
+       {
+               const auto itemPresenter = impl::toItemPresenter(eventInfo);
+               if (!itemPresenter) {
+                       LOG_RETURN_VOID(RES_FATAL, "itemPresenter is NULL");
+               }
+               itemPresenter->onItemRealized();
+       }
+
+       void ListPresenter::onItemUnrealized(Widget &widget, void *eventInfo)
+       {
+               const auto itemPresenter = impl::toItemPresenter(eventInfo);
+               if (!itemPresenter) {
+                       LOG_RETURN_VOID(RES_FATAL, "itemPresenter is NULL");
+               }
+               itemPresenter->onItemUnrealized();
+       }
+
+       void ListPresenter::onItemHighlighted(Widget &widget, void *eventInfo)
+       {
+               const auto itemPresenter = impl::toItemPresenter(eventInfo);
+               if (!itemPresenter) {
+                       LOG_RETURN_VOID(RES_FATAL, "itemPresenter is NULL");
+               }
+               itemPresenter->onItemHighlighted();
+       }
+
+       void ListPresenter::onItemUnhighlighted(Widget &widget, void *eventInfo)
+       {
+               const auto itemPresenter = impl::toItemPresenter(eventInfo);
+               if (!itemPresenter) {
+                       LOG_RETURN_VOID(RES_FATAL, "itemPresenter is NULL");
+               }
+               itemPresenter->onItemUnhighlighted();
+       }
+
+       void ListPresenter::onActivate()
+       {
+               setIsActiveRef(true);
+       }
+
+       void ListPresenter::onDeactivate()
+       {
+               setIsActiveRef(false);
+       }
+}