Merge and integrate new ListView and SelectView. 65/140065/2
authorEugene Kurzberg <i.kurtsberg@samsung.com>
Fri, 21 Jul 2017 14:59:51 +0000 (17:59 +0300)
committerEugene Kurzberg <i.kurtsberg@samsung.com>
Mon, 24 Jul 2017 07:00:47 +0000 (10:00 +0300)
Change-Id: I3f9c03d883f4e18da5b50c3aac357f4f3428f137
Signed-off-by: Eugene Kurzberg <i.kurtsberg@samsung.com>
23 files changed:
alarm-app/inc/List/AlarmItem.h
alarm-app/inc/List/AlarmsView.h
alarm-app/inc/OperationPickController.h
alarm-app/src/List/AlarmItem.cpp
alarm-app/src/List/AlarmsView.cpp
alarm-app/src/OperationPickController.cpp
lib-apps-common/inc/Ui/CheckItem.h [deleted file]
lib-apps-common/inc/Ux/CircleSelector.h
lib-apps-common/inc/Ux/ListItem.h [new file with mode: 0644]
lib-apps-common/inc/Ux/ListView.h [new file with mode: 0644]
lib-apps-common/inc/Ux/MultiSelector.h
lib-apps-common/inc/Ux/SelectAllItem.h [deleted file]
lib-apps-common/inc/Ux/SelectItem.h
lib-apps-common/inc/Ux/SelectTypes.h [deleted file]
lib-apps-common/inc/Ux/SelectView.h
lib-apps-common/src/Ui/CheckItem.cpp [deleted file]
lib-apps-common/src/Ux/CircleSelector.cpp
lib-apps-common/src/Ux/ListItem.cpp [new file with mode: 0644]
lib-apps-common/src/Ux/ListView.cpp [new file with mode: 0644]
lib-apps-common/src/Ux/MultiSelector.cpp
lib-apps-common/src/Ux/SelectAllItem.cpp [deleted file]
lib-apps-common/src/Ux/SelectItem.cpp
lib-apps-common/src/Ux/SelectView.cpp

index f95647aa7b15b5fbf03d4bf49fdfc74db40a6510..1ee83b38797e91eede7f0c440750402fbca712dc 100644 (file)
@@ -29,7 +29,7 @@ namespace Common
 
 namespace List
 {
-       class AlarmItem: public Ux::SelectItem
+       class AlarmItem : public Ux::SelectItem
        {
        public:
                /**
@@ -38,19 +38,7 @@ namespace List
                 */
                explicit AlarmItem(Common::Model::Alarm &alarm);
 
-               /**
-                * @return Alarm associated with the item.
-                */
-               const Common::Model::Alarm &getAlarm() const;
-
-               /**
-                * @brief Update the item according to the changes.
-                * @param[in]   changes     Mask specifying which data has changed
-                */
-               void update(int changes);
-
        private:
-               virtual Ux::SelectResult getDefaultResult() const override;
                virtual Elm_Gen_Item_Class *getItemClass() const override;
                virtual char *getText(Evas_Object *parent, const char *part) override;
                virtual Evas_Object *getContent(Evas_Object *parent, const char *part) override;
@@ -58,9 +46,8 @@ namespace List
 
                virtual void onInserted() override;
                virtual void onSelected() override;
+               virtual void onUpdate(int changes) override;
                void onAlarmEnabled(Evas_Object *check, void *eventInfo);
-
-               Common::Model::Alarm &m_Alarm;
        };
 }
 
index 9586d3f7b0aacb871fc8b50e1085e38182f7623d..da1081cc29d69b86ab7f9fdc83c6818c15101d9a 100644 (file)
 #include "Ux/SelectView.h"
 #include <system_settings.h>
 
-namespace Ui
-{
-       class Genlist;
-}
-
 namespace Ux
 {
        class ActionButtonsItem;
@@ -33,8 +28,7 @@ namespace Ux
 
 namespace List
 {
-       class AlarmItem;
-       class AlarmsView: public Ux::SelectView
+       class AlarmsView : public Ux::SelectView
        {
        public:
                /**
@@ -53,43 +47,20 @@ namespace List
                void setAddCallback(AddCallback callback);
 
        private:
-               virtual Evas_Object *onCreate(Evas_Object *parent) override;
-               virtual void onCreated() override;
-               virtual void onPageAttached(Ui::NavigatorPage *page) override;
-               virtual void onNavigation(bool isCurrent) override;
-               virtual void onSelectModeChanged(Ux::SelectMode selectMode) override;
-               virtual void onSelectCountChanged(size_t selectCount) override;
-               virtual Evas_Object *createDoneButton() override;
-               virtual Ux::MultiSelector *createMultiSelector() override;
-
-               Evas_Object *createContentLayout(Evas_Object *parent);
-               Evas_Object *createNoContents(Evas_Object *parent);
-               void updateEmptyState();
+               virtual Evas_Object *createContent(Evas_Object *parent) override;
+               virtual Evas_Object *createNoContents(Evas_Object *parent) override;
+               virtual Ux::ListItem *createItem(::Model::DataItem &dataItem) override;
 
-               AlarmItem *createItem(::Model::DataItem &dataItem);
-               AlarmItem *insertItem(AlarmItem *alarmItem);
-
-               Ui::GenItem *getCenterItem();
-               Elm_Interface_Atspi_Accessible *getNextItem();
-               Elm_Interface_Atspi_Accessible *getPrevItem();
-
-               Evas_Point getWindowCenter();
-
-               void onAlarmInserted(::Model::DataItem &dataItem);
-               void onAlarmUpdated(AlarmItem *item, int changes);
-               void onAlarmDeleted(AlarmItem *item);
+               virtual void onFilled() override;
+               virtual void onItemInserted(Ux::ListItem *item) override;
+               virtual void onSelectModeChanged(Ux::SelectMode selectMode) override;
                void onAddPressed();
                void onFormatChanged(system_settings_key_e key);
                void onItemLongpressed(Evas_Object *genlist, Elm_Object_Item *item);
                bool onSelectFinished();
 
                Model::AlarmProvider m_Provider;
-               Evas_Object *m_NoContents;
-               Evas_Object *m_ContentLayout;
-               Ui::Genlist *m_Genlist;
                Ux::ActionButtonsItem *m_AddAlarmItem;
-               Evas_Object *m_DeleteButton;
-
                AddCallback m_OnAlarmAdded;
        };
 }
index 9edc855e17a8f7d153f2584bb07b1e5a228dc134..23d71019d834bb8b179cb0c69f7015c4ce752baa 100644 (file)
 #define OPERATION_PICK_CONTROLLER_H
 
 #include "App/OperationController.h"
-#include "Ux/SelectTypes.h"
-
-namespace Ui
-{
-       class View;
-}
+#include "Ux/SelectView.h"
 
 class OperationPickController : public App::OperationController
 {
index 9704753f623f1b14723f7fa4e8ac377acb6698b9..6573d367b9781467174af3fffc7a35e85d8ccd7c 100644 (file)
@@ -39,37 +39,10 @@ using namespace Common::Model;
 using namespace List;
 
 AlarmItem::AlarmItem(Alarm &alarm)
-       : m_Alarm(alarm)
+       :  ListItem(alarm), SelectItem(alarm)
 {
 }
 
-const Common::Model::Alarm &AlarmItem::getAlarm() const
-{
-       return m_Alarm;
-}
-
-void AlarmItem::update(int changes)
-{
-       if (changes & Alarm::ChangedDate) {
-               GenItem::update(PART_TIME, ELM_GENLIST_ITEM_FIELD_TEXT);
-               if (!m_Alarm.getRepeat()) {
-                       GenItem::update(PART_DATE, ELM_GENLIST_ITEM_FIELD_TEXT);
-               }
-       }
-       if (changes & Alarm::ChangedRepeat) {
-               GenItem::update(PART_DATE, ELM_GENLIST_ITEM_FIELD_TEXT);
-       }
-       if (changes & Alarm::ChangedEnabled) {
-               Evas_Object *check = elm_object_item_part_content_get(getObjectItem(), PART_ON_OFF);
-               elm_check_state_set(check, m_Alarm.isEnabled());
-       }
-}
-
-Ux::SelectResult AlarmItem::getDefaultResult() const
-{
-       return { 0, &m_Alarm };
-}
-
 Elm_Gen_Item_Class *AlarmItem::getItemClass() const
 {
        static Elm_Gen_Item_Class itc = createItemClass("2text.1icon.1");
@@ -78,13 +51,14 @@ Elm_Gen_Item_Class *AlarmItem::getItemClass() const
 
 char *AlarmItem::getText(Evas_Object *parent, const char *part)
 {
+       auto &alarm = getDataItem<Alarm>();
        if (strcmp(part, PART_TIME) == 0) {
-               return strdup(Common::formatTime(m_Alarm.getDate(), AM_PM_FONT_SIZE));
+               return strdup(Common::formatTime(alarm.getDate(), AM_PM_FONT_SIZE));
        } else if (strcmp(part, PART_DATE) == 0) {
-               if (m_Alarm.getRepeat()) {
-                       return strdup(Common::formatRepeat(m_Alarm.getRepeat()));
+               if (alarm.getRepeat()) {
+                       return strdup(Common::formatRepeat(alarm.getRepeat()));
                } else {
-                       return strdup(Common::formatDate(m_Alarm.getDate()).c_str());
+                       return strdup(Common::formatDate(alarm.getDate()).c_str());
                }
        }
 
@@ -96,7 +70,7 @@ Evas_Object *AlarmItem::getContent(Evas_Object *parent, const char *part)
        if (strcmp(part, PART_ON_OFF) == 0) {
                Evas_Object *check = elm_check_add(parent);
                elm_object_style_set(check, STYLE_CHECK_ALARM_ON_OFF);
-               elm_check_state_set(check, m_Alarm.isEnabled());
+               elm_check_state_set(check, getDataItem<Alarm>().isEnabled());
 
                evas_object_propagate_events_set(check, EINA_FALSE);
                evas_object_size_hint_min_set(check, ON_OFF_WH, ON_OFF_WH);
@@ -119,20 +93,23 @@ Evas_Object *AlarmItem::getContent(Evas_Object *parent, const char *part)
 
 char *AlarmItem::getAccessibleName(Evas_Object *obj)
 {
+       auto &alarm = getDataItem<Alarm>();
+
        std::string name;
-       name.append(Common::formatTime(m_Alarm.getDate()));
+       name.append(Common::formatTime(alarm.getDate()));
        name.append(", ");
 
-       if (m_Alarm.getRepeat()) {
-               name.append(Common::formatVerbalRepeat(m_Alarm.getRepeat()));
+       if (alarm.getRepeat()) {
+               name.append(Common::formatVerbalRepeat(alarm.getRepeat()));
        } else {
-               name.append(Common::formatVerbalDate(m_Alarm.getDate()));
+               name.append(Common::formatVerbalDate(alarm.getDate()));
        }
        return strdup(name.c_str());
 }
 
 void AlarmItem::onInserted()
 {
+       SelectItem::onInserted();
        elm_atspi_accessible_name_cb_set(getObjectItem(),
                        makeCallback(&AlarmItem::getAccessibleName), this);
 }
@@ -145,16 +122,36 @@ void AlarmItem::onSelected()
        }
 
        if (auto navigator = getParent()->findParent<Ui::Navigator>()) {
-               navigator->navigateTo(new Input::InputView(m_Alarm));
+               navigator->navigateTo(new Input::InputView(getDataItem<Alarm>()));
+       }
+}
+
+void AlarmItem::onUpdate(int changes)
+{
+       auto &alarm = getDataItem<Alarm>();
+       if (changes & Alarm::ChangedDate) {
+               GenItem::update(PART_TIME, ELM_GENLIST_ITEM_FIELD_TEXT);
+               if (!alarm.getRepeat()) {
+                       GenItem::update(PART_DATE, ELM_GENLIST_ITEM_FIELD_TEXT);
+               }
+       }
+       if (changes & Alarm::ChangedRepeat) {
+               GenItem::update(PART_DATE, ELM_GENLIST_ITEM_FIELD_TEXT);
+       }
+       if (changes & Alarm::ChangedEnabled) {
+               Evas_Object *check = elm_object_item_part_content_get(getObjectItem(), PART_ON_OFF);
+               elm_check_state_set(check, alarm.isEnabled());
        }
 }
 
 void AlarmItem::onAlarmEnabled(Evas_Object *check, void *eventInfo)
 {
-       m_Alarm.setEnabled(elm_check_state_get(check));
-       AlarmConsumer::getInstance().updateDataItem(m_Alarm, [this](bool isSuccess, int alarmId) {
-               if (isSuccess && m_Alarm.isEnabled()) {
-                       auto popup = new Common::AlarmSetPopup(m_Alarm);
+       auto &alarm = getDataItem<Alarm>();
+       alarm.setEnabled(elm_check_state_get(check));
+       AlarmConsumer::getInstance().updateDataItem(alarm, [this](bool isSuccess, int alarmId) {
+               auto &alarm = getDataItem<Alarm>();
+               if (isSuccess && alarm.isEnabled()) {
+                       auto popup = new Common::AlarmSetPopup(alarm);
                        popup->create(getParent()->getEvasObject());
                        popup->show();
                }
index 7656e0b42e6f16523f5f82c7c84421832b3185f6..c8c668e4241323d9412c1b7edae6b7430ce43fe7 100644 (file)
  * limitations under the License.
  */
 
-#include "Common/Model/AlarmConsumer.h"
-#include "List/AlarmItem.h"
 #include "List/AlarmsView.h"
+#include "List/AlarmItem.h"
 #include "Input/InputView.h"
+#include "Common/Model/AlarmConsumer.h"
 
 #include "App/Path.h"
 #include "System/Settings.h"
 #include "Ui/Accessibility.h"
-#include "Ui/CircleMenu.h"
-#include "Ui/Genlist.h"
-#include "Ui/GenGroupItem.h"
-#include "Ui/PaddingItem.h"
 #include "Ui/Toast.h"
-#include "Ui/Window.h"
-#include "Utils/Callback.h"
 #include "Ux/ActionButtonsItem.h"
-#include "Ux/CircleSelector.h"
+#include "Utils/Callback.h"
 
 #include "AppsCommonList.h"
 #include "ListPath.h"
@@ -45,17 +39,24 @@ using namespace List;
 using namespace std::placeholders;
 
 AlarmsView::AlarmsView()
-       : m_Provider(AlarmConsumer::getInstance()),
-         m_NoContents(nullptr), m_ContentLayout(nullptr), m_Genlist(nullptr),
-         m_AddAlarmItem(nullptr), m_DeleteButton(nullptr)
+       : SelectView(m_Provider),
+         m_Provider(AlarmConsumer::getInstance()),
+         m_AddAlarmItem(nullptr)
 {
-       Strings strings{};
-       strings.selectAll = "WDS_MSG_OPT_SELECT_ALL_ABB";
-       strings.deselectAll = "WDS_MSG_OPT_DESELECT_ALL_ABB";
+       Strings strings = { };
+       strings.selectorStrings.selectAll = "WDS_MSG_OPT_SELECT_ALL_ABB";
+       strings.selectorStrings.deselectAll = "WDS_MSG_OPT_DESELECT_ALL_ABB";
        strings.buttonDone = "WDS_ALM_ACBUTTON_DELETE_ABB";
-       strings.titleMulti = "0";
        strings.titleWithCount = "%d";
        setStrings(strings);
+       setAccessibleStrings({ {
+               "WDS_TTS_TBOPT_SELECT_MODE_POP_UP",
+               "WDS_TTS_TBBODY_DOUBLE_TAP_TO_CLOSE_THE_POP_UP",
+               "WDS_TTS_TBBODY_DOUBLE_TAP_TO_SELECT_ALL",
+               "WDS_TTS_TBBODY_DOUBLE_TAP_TO_DESELECT_ALL" },
+               "WDS_GALLERY_HEADER_PD_SELECTED_ABB",
+               nullptr
+       });
 
        System::Settings::addCallback(SYSTEM_SETTINGS_KEY_LOCALE_TIMEFORMAT_24HOUR,
                        { std::bind(&AlarmsView::onFormatChanged, this, _1), this });
@@ -71,128 +72,15 @@ void AlarmsView::setAddCallback(AddCallback callback)
        m_OnAlarmAdded = std::move(callback);
 }
 
-Evas_Object *AlarmsView::onCreate(Evas_Object *parent)
-{
-       Evas_Object *layout = elm_layout_add(parent);
-       elm_layout_theme_set(layout, "layout", "bottom_button", "default");
-
-       m_ContentLayout = createContentLayout(layout);
-       m_NoContents = createNoContents(layout);
-
-       return layout;
-}
-
-void AlarmsView::onCreated()
-{
-       m_Provider.onUpdated() += { std::bind(&AlarmsView::updateEmptyState, this), this };
-       m_Provider.onInserted() += { std::bind(&AlarmsView::onAlarmInserted, this, _1), this };
-       m_Provider.initialize({ [this] {
-               for (auto &&dataItem : m_Provider.getDataList()) {
-                       insertItem(createItem(*dataItem));
-               }
-               m_AddAlarmItem->getNextItem()->scrollTo(ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
-               updateEmptyState();
-       }, this });
-}
-
-void AlarmsView::onPageAttached(Ui::NavigatorPage *page)
-{
-       page->setStyle("empty");
-}
-
-void AlarmsView::onNavigation(bool isCurrent)
-{
-       eext_rotary_object_event_activated_set(m_Genlist->getEvasObject(), isCurrent);
-}
-
-void AlarmsView::onSelectModeChanged(Ux::SelectMode selectMode)
-{
-       if (!getEvasObject()) {
-               return;
-       }
-
-       if (selectMode != Ux::SelectMulti) {
-               elm_layout_signal_emit(m_ContentLayout, "select_mode,button,hide", "");
-               m_AddAlarmItem->getControl()->setEnabled(true);
-
-               for (auto &&selectItem : getSelectItems()) {
-                       elm_atspi_accessible_relationships_clear(selectItem->getObjectItem());
-               }
-       } else {
-               elm_layout_signal_emit(m_ContentLayout, "select_mode,button,show", "");
-               m_AddAlarmItem->getControl()->setEnabled(false);
-
-               if (auto selector = getMultiSelector().lock()) {
-                       for (auto &&selectItem : getSelectItems()) {
-                               elm_atspi_accessible_relationship_append(selectItem->getObjectItem(), ELM_ATSPI_RELATION_FLOWS_TO, selector->getEvasObject());
-                               elm_atspi_accessible_relationship_append(selectItem->getObjectItem(), ELM_ATSPI_RELATION_FLOWS_FROM, m_DeleteButton);
-                       }
-               }
-       }
-}
-
-void AlarmsView::onSelectCountChanged(size_t selectCount)
-{
-       if (auto multiSelector = getPtr<Ux::CircleSelector>(getMultiSelector())) {
-               multiSelector->setCount(selectCount);
-       }
-}
-
-Evas_Object *AlarmsView::createDoneButton()
-{
-       m_DeleteButton = elm_button_add(getEvasObject());
-       elm_object_style_set(m_DeleteButton, "bottom");
-       elm_object_translatable_text_set(m_DeleteButton, "WDS_ALM_ACBUTTON_DELETE_ABB");
-       elm_object_part_content_set(getEvasObject(), "elm.swallow.button", m_DeleteButton);
-       evas_object_smart_callback_add(m_DeleteButton, "atspi,highlighted",
-               [](void *data, Evas_Object *button, void *) {
-                       auto view = (AlarmsView *)data;
-                       elm_atspi_accessible_relationships_clear(button);
-                       elm_atspi_accessible_relationship_append(button, ELM_ATSPI_RELATION_FLOWS_TO, view->getNextItem());
-               }, this);
-
-       return m_DeleteButton;
-}
-
-Ux::MultiSelector *AlarmsView::createMultiSelector()
+Evas_Object *AlarmsView::createContent(Evas_Object *parent)
 {
-       auto multiSelector = new Ux::CircleSelector();
-       multiSelector->create(m_ContentLayout);
-       multiSelector->setAccessibilityStrings({
-                       "WDS_TTS_TBOPT_SELECT_MODE_POP_UP",
-                       "WDS_TTS_TBBODY_DOUBLE_TAP_TO_CLOSE_THE_POP_UP",
-                       "WDS_GALLERY_HEADER_PD_SELECTED_ABB",
-                       "WDS_TTS_TBBODY_DOUBLE_TAP_TO_SELECT_ALL",
-                       "WDS_TTS_TBBODY_DOUBLE_TAP_TO_DESELECT_ALL" });
-       elm_object_part_content_set(m_ContentLayout, "elm.swallow.icon", multiSelector->getEvasObject());
+       Evas_Object *layout = SelectView::createContent(parent);
 
-       evas_object_smart_callback_add(multiSelector->getEvasObject(), "atspi,highlighted",
-               [](void *data, Evas_Object *selector, void *) {
-                       auto view = (AlarmsView *)data;
-                       elm_atspi_accessible_relationships_clear(selector);
-                       elm_atspi_accessible_relationship_append(selector, ELM_ATSPI_RELATION_FLOWS_FROM, view->getPrevItem());
-               }, this);
-
-       return multiSelector;
-}
-
-Evas_Object *AlarmsView::createContentLayout(Evas_Object *parent)
-{
-       Evas_Object *layout = elm_layout_add(parent);
-       elm_layout_theme_set(layout, "layout", "select_mode", "default");
-
-       auto surface = findParent<Ui::Window>(parent)->getCircleConformant();
-       m_Genlist = new Ui::Genlist();
-       m_Genlist->create(parent);
-       eext_circle_object_genlist_add(m_Genlist->getEvasObject(), surface);
-       evas_object_smart_callback_add(m_Genlist->getEvasObject(), "longpressed",
+       Ui::GenContainer *container = getContainer();
+       evas_object_smart_callback_add(container->getEvasObject(), "longpressed",
                        (Evas_Smart_Cb)makeCallback(&AlarmsView::onItemLongpressed), this);
-       elm_object_content_set(layout, m_Genlist->getEvasObject());
-
-       m_Genlist->insert(new Ui::PaddingItem());
-       m_Genlist->insert(m_AddAlarmItem = new Ux::ActionButtonsItem());
-       m_Genlist->insert(new Ui::PaddingItem());
 
+       container->insert(m_AddAlarmItem = new Ux::ActionButtonsItem(), nullptr, container->getLastItem());
        m_AddAlarmItem->getControl()->addButton("WDS_ALM_BUTTON_ADD_ABB", PATH_ICON_ADD_ALARM,
                        std::bind(&AlarmsView::onAddPressed, this));
 
@@ -226,112 +114,29 @@ Evas_Object *AlarmsView::createNoContents(Evas_Object *parent)
        return layout;
 }
 
-void AlarmsView::updateEmptyState()
-{
-       Evas_Object *content = m_Provider.getDataList().size() > 0
-                       ? m_ContentLayout : m_NoContents;
-
-       if (content != elm_object_content_get(getEvasObject())) {
-               evas_object_hide(elm_object_content_unset(getEvasObject()));
-               elm_object_content_set(getEvasObject(), content);
-       }
-}
-
-AlarmItem *AlarmsView::createItem(::Model::DataItem &dataItem)
+Ux::ListItem *AlarmsView::createItem(::Model::DataItem &dataItem)
 {
-       auto item = new AlarmItem(static_cast<Alarm &>(dataItem));
-       dataItem.onUpdated() += { std::bind(&AlarmsView::onAlarmUpdated, this, item, _1), item };
-       dataItem.onDeleted() += { std::bind(&AlarmsView::onAlarmDeleted, this, item), item };
-       addSelectItem(item);
-       return item;
+       return new AlarmItem(static_cast<Alarm &>(dataItem));
 }
 
-AlarmItem *AlarmsView::insertItem(AlarmItem *alarmItem)
+void AlarmsView::onFilled()
 {
-       Ui::GenItem *firstItem = m_AddAlarmItem->getNextItem();
-       Ui::GenItem *lastItem = m_Genlist->getLastItem();
-       Ui::GenItem *nextItem = lastItem;
-
-       for (auto item = firstItem; item != lastItem; item = item->getNextItem()) {
-               if (alarmItem->getAlarm() < static_cast<AlarmItem *>(item)->getAlarm()) {
-                       nextItem = item;
-                       break;
-               }
-       }
-
-       m_Genlist->insert(alarmItem, nullptr, nextItem);
-       return alarmItem;
+       m_AddAlarmItem->scrollTo(ELM_GENLIST_ITEM_SCROLLTO_TOP);
 }
 
-Ui::GenItem *AlarmsView::getCenterItem()
+void AlarmsView::onItemInserted(Ux::ListItem *item)
 {
-       static auto center = getWindowCenter();
-       if (auto item = elm_genlist_at_xy_item_get(m_Genlist->getEvasObject(), center.x, center.y, nullptr)) {
-               return (Ui::GenItem *)elm_object_item_data_get(item);
-       }
-
-       return nullptr;
+       SelectView::onItemInserted(item);
+       item->scrollTo();
 }
 
-Elm_Interface_Atspi_Accessible *AlarmsView::getNextItem()
-{
-       if (auto item = getCenterItem()) {
-               if (auto nextItem = item->getNextItem()) {
-                       if (nextItem != m_Genlist->getLastItem()) {
-                               return nextItem->getObjectItem();
-                       }
-               }
-       }
-
-       return nullptr;
-}
-
-Elm_Interface_Atspi_Accessible *AlarmsView::getPrevItem()
-{
-       if (auto item = getCenterItem()) {
-               if (auto prevItem = item->getPrevItem()) {
-                       if (prevItem != m_Genlist->getFirstItem()) {
-                               return prevItem->getObjectItem();
-                       }
-               }
-       }
-
-       return nullptr;
-}
-
-Evas_Point AlarmsView::getWindowCenter()
-{
-       Evas_Point point { 0 };
-       if (auto window = findParent<Ui::Window>()) {
-               evas_object_geometry_get(window->getEvasObject(), nullptr, nullptr, &point.x, &point.y);
-               point.x /= 2;
-               point.y /= 2;
-       }
-
-       return point;
-}
-
-void AlarmsView::onAlarmInserted(::Model::DataItem &dataItem)
-{
-       insertItem(createItem(dataItem))->scrollTo(ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
-}
-
-void AlarmsView::onAlarmUpdated(AlarmItem *item, int changes)
+void AlarmsView::onSelectModeChanged(Ux::SelectMode selectMode)
 {
-       if (changes & Alarm::ChangedDate) {
-               item->pop();
-               insertItem(item);
-       } else {
-               item->update(changes);
+       if (m_AddAlarmItem) {
+               m_AddAlarmItem->getControl()->setEnabled(selectMode != Ux::SelectMulti);
        }
 }
 
-void AlarmsView::onAlarmDeleted(AlarmItem *item)
-{
-       removeSelectItem(item);
-       delete item;
-}
-
 void AlarmsView::onAddPressed()
 {
        if (m_Provider.getDataList().size() < ALARM_MAX_COUNT) {
@@ -351,7 +156,7 @@ void AlarmsView::onAddPressed()
 
 void AlarmsView::onFormatChanged(system_settings_key_e key)
 {
-       m_Genlist->update("elm.text", ELM_GENLIST_ITEM_FIELD_TEXT);
+       getContainer()->update("elm.text", ELM_GENLIST_ITEM_FIELD_TEXT);
 }
 
 void AlarmsView::onItemLongpressed(Evas_Object *genlist, Elm_Object_Item *item)
@@ -365,8 +170,7 @@ void AlarmsView::onItemLongpressed(Evas_Object *genlist, Elm_Object_Item *item)
                setCancelCallback(std::bind(&AlarmsView::onSelectFinished, this));
                setSelectCallback([this](Ux::SelectResults results) {
                        for (auto &&result : results) {
-                               auto alarm = (Alarm *)result.value.data;
-                               AlarmConsumer::getInstance().deleteDataItem(alarm->getId(), nullptr);
+                               AlarmConsumer::getInstance().deleteDataItem(result->getDataItem<Alarm>().getId(), nullptr);
                        }
 
                        return onSelectFinished();
index 5294fdbae74c17f19b005bd89ec52e1450014b49..6585af674e3cabe50fd8892b8722a18d40074aa8 100644 (file)
@@ -35,8 +35,8 @@ void OperationPickController::onRequest(const char *operation, app_control_h req
 
 bool OperationPickController::onAlarmSelected(Ux::SelectResults results)
 {
-       Alarm *alarm = (Alarm *) results.begin()->value.data;
-       sendReply(alarm->getId());
+       auto &alarm = results.front()->getDataItem<Alarm>();
+       sendReply(alarm.getId());
        return true;
 }
 
diff --git a/lib-apps-common/inc/Ui/CheckItem.h b/lib-apps-common/inc/Ui/CheckItem.h
deleted file mode 100644 (file)
index f54c2aa..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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 UI_CHECK_ITEM
-#define UI_CHECK_ITEM
-
-#include "Ui/GenItem.h"
-
-namespace Ui
-{
-       /**
-        * @brief GenContainer check item
-        */
-       class EXPORT_API CheckItem : public Ui::GenItem
-       {
-       public:
-               /**
-                * @brief Item check callback.
-                * @param[in]   Whether item is checked
-                * @return Whether item's state should be changed.
-                */
-               typedef std::function<bool(bool)> CheckCallback;
-
-               CheckItem(GenContainer::Type type = GenContainer::TypeGenlist);
-               virtual ~CheckItem() override;
-
-               /**
-                * @return Whether the item is checked.
-                */
-               bool isChecked() const;
-
-               /**
-                * @brief Set item check state.
-                * @param[in]   isChecked   Whether item is checked
-                * @return Whether the state was changed successfully.
-                */
-               bool setChecked(bool isChecked);
-
-               /**
-                * @brief Set item check callback.
-                * @param[in]   callback    Callback to be called when item is checked/unchecked
-                */
-               void setCheckCallback(CheckCallback callback);
-
-               /**
-                * @brief Set item which "checked" state should be synchronized with this item.
-                * @param[in]   item    Item to link with
-                */
-               void setLinkedItem(CheckItem *item);
-
-               /**
-                * @brief Unset linked item.
-                */
-               void unsetLinkedItem();
-
-       protected:
-               /**
-                * @brief Update the part containing check component.
-                */
-               void updateCheckPart();
-
-               /**
-                * @see GenItem::getContent()
-                * @remark Use it in derived class to create check component
-                */
-               virtual Evas_Object *getContent(Evas_Object *parent, const char *part) override;
-
-               /**
-                * @see GenItem::onSelected()
-                */
-               virtual void onSelected() override;
-
-               /**
-                * @brief Called when item's "checked" state changes.
-                * @param[in]   isChecked   Whether item is checked
-                * @return Whether item's state should be changed.
-                */
-               virtual bool onChecked(bool isChecked) { return true; }
-
-       private:
-               void onCheckChanged(Evas_Object *check, void *eventInfo);
-               bool notifyCheck();
-
-               std::string m_CheckPart;
-               Eina_Bool m_IsChecked;
-               bool m_IsChecking;
-               CheckCallback m_OnChecked;
-               CheckItem *m_LinkedItem;
-       };
-}
-
-#endif /* UI_CHECK_ITEM */
index 3adfe357871fa73db8765dd14a2e79a0c342fd23..591e1029389f4bc0a5f9d95e5fff1642664a3836 100644 (file)
@@ -23,43 +23,12 @@ namespace Ux
 {
        class EXPORT_API CircleSelector : public Ux::MultiSelector
        {
-       public:
-               /**
-                * @brief Structure with information, that should be pronounced by accessibility engine.
-                */
-               struct AccessibilityStrings
-               {
-                       const char *name;                   /**< Selector name. */
-                       const char *description;            /**< Selector description. */
-                       const char *title;                  /**< Selector title. */
-                       const char *selectAllDescription;   /**< Description for "Select all" item. */
-                       const char *deselectAllDescription; /**< Description for "Deselect all" item. */
-               };
-
-               CircleSelector();
-
-               /**
-                * @brief Set count of selected items.
-                */
-               void setCount(size_t count);
-
-               /**
-                * @brief Set accessibility strings.
-                * @param[in]   strings Accessibility strings.
-                * @see AccessibilityStrings.
-                */
-               void setAccessibilityStrings(const AccessibilityStrings &strings);
-
        private:
                virtual Evas_Object *onCreate(Evas_Object *parent) override;
                void onButtonClicked(Evas_Object *button, void *eventInfo);
 
                void makeAccessible(Evas_Object *menu);
                void makeAccessible(Elm_Object_Item *item, const char *description);
-               char *getAccessibleName(Evas_Object *button);
-
-               AccessibilityStrings m_AccessibilityStrings;
-               size_t m_Count;
        };
 }
 
diff --git a/lib-apps-common/inc/Ux/ListItem.h b/lib-apps-common/inc/Ux/ListItem.h
new file mode 100644 (file)
index 0000000..46a23f6
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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 UX_LIST_ITEM_H
+#define UX_LIST_ITEM_H
+
+#include "Ui/GenItem.h"
+
+namespace Model
+{
+       class DataItem;
+}
+
+namespace Ux
+{
+       /**
+        * @brief GenContainer item representing DataItem in ListView.
+        */
+       class EXPORT_API ListItem : virtual public Ui::GenItem
+       {
+       public:
+               /**
+                * @brief Create list item.
+                * @param[in]   dataItem    Data item associated with list item
+                * @param[in]   type        Parent container type
+                */
+               explicit ListItem(Model::DataItem &dataItem,
+                               Ui::GenContainer::Type type = Ui::GenContainer::TypeGenlist);
+               virtual ~ListItem() override;
+
+               /**@{*/
+               /**
+                * @return Data item associated with list item.
+                */
+               template <typename ItemType>
+               const ItemType &getDataItem() const { return static_cast<const ItemType &>(m_DataItem); }
+               template <typename ItemType>
+               ItemType &getDataItem() { return static_cast<ItemType &>(m_DataItem); }
+               /**@}*/
+
+       protected:
+               /**
+                * @brief Called after associated DataItem was updated.
+                * @param[in]   changes     DataItem changes mask
+                */
+               virtual void onUpdate(int changes) { update(); }
+
+               /**
+                * @brief Called before associated DataItem is deleted.
+                */
+               virtual void onDelete() { }
+
+       private:
+               void onDataItemUpdated(int changes, Model::DataItem *nextDataItem);
+               void onDataItemDeleted();
+
+               Model::DataItem &m_DataItem;
+       };
+}
+
+#endif /* UX_LIST_ITEM_H */
diff --git a/lib-apps-common/inc/Ux/ListView.h b/lib-apps-common/inc/Ux/ListView.h
new file mode 100644 (file)
index 0000000..e2b1c92
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * 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 UX_LIST_VIEW_H
+#define UX_LIST_VIEW_H
+
+#include "Ui/View.h"
+#include <functional>
+
+namespace Model
+{
+       class DataItem;
+       class DataProvider;
+}
+
+namespace Ui
+{
+       class GenContainer;
+}
+
+namespace Ux
+{
+       class ListItem;
+       class EXPORT_API ListView : public Ui::View
+       {
+       public:
+               /**
+                * @brief Called once view is filled.
+                */
+               typedef std::function<void()> FillCallback;
+
+               /**
+                * @brief Create list view.
+                * @param[in]   provider    Data provider for the view
+                * @param[in]   container   Item container (default is Genlist)
+                */
+               explicit ListView(Model::DataProvider &provider, Ui::GenContainer *container = nullptr);
+
+               /**
+                * @brief Set fill callback.
+                * @param[in]   callback    Callback to be called when view is filled
+                */
+               void setFillCallback(FillCallback callback);
+
+       protected:
+               /**
+                * @brief Creates main layout and calls createContent() and createNoContents().
+                * @see Control::onCreate()
+                */
+               virtual Evas_Object *onCreate(Evas_Object *parent) override;
+
+               /**
+                * @brief Initializes the provider and fills the container.
+                * @see Control::onCreated()
+                */
+               virtual void onCreated() override;
+
+               /**
+                * @brief Changes provider's update mode according to view's state.
+                * @see View::onNavigation()
+                */
+               virtual void onNavigation(bool isCurrent) override;
+
+               /**
+                * @brief Create layout with item container.
+                * @param[in]   parent  Parent Evas_Object
+                * @return Layout that displays item container.
+                */
+               virtual Evas_Object *createContent(Evas_Object *parent);
+
+               /**
+                * @brief Create "No Contents" layout.
+                * @param[in]   parent  Parent Evas_Object
+                * @return Layout to display when there is no content.
+                */
+               virtual Evas_Object *createNoContents(Evas_Object *parent);
+
+               /**
+                * @brief Create "More" menu.
+                * @param[in]   parent  Parent Evas_Object
+                * @return Menu object to be displayed in the view.
+                */
+               virtual Evas_Object *createMoreMenu(Evas_Object *parent) { return nullptr; }
+
+               /**
+                * @brief Create list item for specified dataItem.
+                * @param[in]   dataItem    Data item to be represented by ListItem
+                * @return New list item.
+                */
+               virtual ListItem *createItem(Model::DataItem &dataItem) = 0;
+
+               /**
+                * @brief Update main layout according to content's empty state.
+                * @details Switches between "Content" and "No Contents" layouts.
+                */
+               virtual void updateEmptyState();
+
+               /**
+                * @brief Called once view is filled.
+                */
+               virtual void onFilled() { }
+
+               /**
+                * @brief Called when new list item is inserted.
+                * @param[in]   item    New list item
+                */
+               virtual void onItemInserted(ListItem *item) { }
+
+               /**
+                * @return Data provider.
+                */
+               Model::DataProvider &getProvider() const;
+
+               /**
+                * @return Item container.
+                */
+               Ui::GenContainer *getContainer() const;
+
+               /**
+                * @return Content layout.
+                */
+               Evas_Object *getContent() const;
+
+               /**
+                * @return "No Contents" layout.
+                */
+               Evas_Object *getNoContents() const;
+
+               /**
+                * @return "More" menu.
+                */
+               Evas_Object *getMoreMenu() const;
+
+       private:
+               ListItem *addItem(Model::DataItem &dataItem, Model::DataItem *nextDataItem = nullptr);
+
+               Ui::GenContainer *m_Container;
+               Evas_Object *m_Content;
+               Evas_Object *m_NoContents;
+               Evas_Object *m_MoreMenu;
+
+               Model::DataProvider &m_Provider;
+               FillCallback m_OnFilled;
+       };
+}
+
+#endif /* UX_LIST_VIEW_H */
index feb2e66ce4b49bd4a5af88bf389a15959014d3b2..c69597cca015c4c7d01c7609cd8baa47c87753a0 100644 (file)
@@ -35,17 +35,28 @@ namespace Ux
                };
 
                /**
-                * @brief Translatable strings for selector menu items.
+                * @brief Translatable strings table for selector elements.
                 */
                struct Strings
                {
-                       const char *selectAll;      /**< "Select all" item text. */
-                       const char *deselectAll;    /**< "Deselect all" item text. */
+                       const char *selectAll;      /**< "Select all" text. */
+                       const char *deselectAll;    /**< "Deselect all" text. */
+               };
+
+               /**
+                * @brief Translatable strings table for accessibility feature.
+                */
+               struct AccessibleStrings
+               {
+                       const char *name;           /**< Selector control name. */
+                       const char *desc;           /**< Selector control description. */
+                       const char *selectAll;      /**< "Select all" description. */
+                       const char *deselectAll;    /**< "Deselect all" description. */
                };
 
                /**
                 * @brief Change callback.
-                * @param[in]   Selector state.
+                * @param[in]   Selector state
                 * @return Whether contol's state should be changed.
                 */
                typedef std::function<bool(State)> ChangeCallback;
@@ -54,26 +65,32 @@ namespace Ux
 
                /**
                 * @brief Set change callback.
-                * @param[in]   callback    Change callback.
+                * @param[in]   callback    Change callback
                 */
                void setChangeCallback(ChangeCallback callback);
 
                /**
                 * @brief Set state.
-                * @param[in]   state   MultiSelector state.
+                * @param[in]   state   MultiSelector state
                 */
                void setState(State state);
 
                /**
-                * @brief Set translatable strings for menu.
-                * @param[in]   strings     Translatable strings table.
+                * @brief Set translatable strings for selector elements.
+                * @param[in]   strings Translatable strings table
                 */
                void setStrings(const Strings &strings);
 
+               /**
+                * @brief Set translatable strings for accessibility.
+                * @param[in]   strings Translatable strings table
+                */
+               void setAccessibleStrings(const AccessibleStrings &strings);
+
        protected:
                /**
                 * @brief Called when inner state was changed by public @setState method.
-                * @param[in]   state   Selector state.
+                * @param[in]   state   Selector state
                 */
                virtual void onStateChanged(State state) { }
 
@@ -87,17 +104,24 @@ namespace Ux
                 */
                const Strings &getStrings() const;
 
+               /**
+                * @return Translatable strings for accessibility.
+                */
+               const AccessibleStrings &getAccessibleStrings() const;
+
                /**
                 * @brief Called when MultiSelector state was changed.
                 * @remark MUST be called only when change was performed by user interaction.
-                * @param[in]   state   Selector state.
+                * @param[in]   state   Selector state
                 */
                bool notifyChanged(State state);
 
        private:
                ChangeCallback m_OnChanged;
                State m_State;
+
                Strings m_Strings;
+               AccessibleStrings m_AccessStrings;
        };
 }
 
diff --git a/lib-apps-common/inc/Ux/SelectAllItem.h b/lib-apps-common/inc/Ux/SelectAllItem.h
deleted file mode 100644 (file)
index c2babc6..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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 UX_SELECT_ALL_ITEM_H
-#define UX_SELECT_ALL_ITEM_H
-
-#include "Ui/CheckItem.h"
-
-namespace Ux
-{
-       /**
-        * @brief "Select all" genlist item
-        */
-       class EXPORT_API SelectAllItem : public Ui::CheckItem
-       {
-       public:
-               /**
-                * @brief Create "Select all" item.
-                * @param[in]   text    Item text
-                */
-               SelectAllItem(const char *text);
-
-       protected:
-               /**
-                * @see GenItem::getItemClass()
-                */
-               virtual Elm_Gen_Item_Class *getItemClass() const override;
-
-               /**
-                * @see GenItem::getText()
-                */
-               virtual char *getText(Evas_Object *parent, const char *part) override;
-
-               /**
-                * @see GenItem::getContent()
-                */
-               virtual Evas_Object *getContent(Evas_Object *parent, const char *part) override;
-
-               /**
-                * @see GenItem::onInserted()
-                */
-               virtual void onInserted() override;
-
-       private:
-               std::string m_Text;
-       };
-}
-
-#endif /* UX_SELECT_ALL_ITEM_H */
index 7f3fb717b0e2cadb17147e6f3c46c2b2ffb7526e..4a39f7a451b00580a169b25b3869bf362da48bf7 100644 (file)
 #ifndef UX_SELECT_ITEM_H
 #define UX_SELECT_ITEM_H
 
-#include "Ui/CheckItem.h"
-#include "Ux/SelectTypes.h"
+#include "Ux/ListItem.h"
 
 namespace Ux
 {
        class SelectView;
 
+       /**
+        * @brief Determines how items can be selected.
+        */
+       enum SelectMode
+       {
+               SelectNone,     /**< Selection is disabled */
+               SelectSingle,   /**< Only one item can be selected */
+               SelectMulti     /**< Multiple items can be selected */
+       };
+
        /**
         * @brief GenContainer item for SelectView that supports selection mode switching.
         */
-       class EXPORT_API SelectItem : public Ui::CheckItem
+       class EXPORT_API SelectItem : virtual public ListItem
        {
        public:
-               SelectItem(Ui::GenContainer::Type type = Ui::GenContainer::TypeGenlist);
-
                /**
-                * @return Whether item is excluded from multiple selection.
+                * @brief Create select item.
+                * @param[in]   checkPart   Part which should contain "check" widget
+                * @see ListItem::ListItem()
                 */
-               bool isExcluded() const;
+               explicit SelectItem(Model::DataItem &dataItem,
+                               const char *checkPart = "elm.swallow.center_check",
+                               Ui::GenContainer::Type type = Ui::GenContainer::TypeGenlist);
 
                /**
-                * @brief Set item exclusion.
-                * @param[in]   isExcluded  Whether item is excluded from multiple selection
-                */
-               void setExcluded(bool isExcluded);
-
-               /**
-                * @return Item selection mode.
+                * @return Whether the item is checked.
                 */
-               SelectMode getSelectMode() const;
+               bool isChecked() const;
 
                /**
-                * @brief Set item selection mode.
+                * @brief Set item check state.
+                * @param[in]   isChecked   Whether item is checked
+                * @return Whether the state was changed successfully.
                 */
-               void setSelectMode(SelectMode selectMode);
+               bool setChecked(bool isChecked);
 
                /**
-                * @return Selection result associated with the item.
+                * @return Whether item is excluded from multiple selection.
                 */
-               SelectResult getSelectResult() const;
+               bool isExcluded() const;
 
                /**
-                * @return Whether item has custom selection result.
+                * @brief Set item exclusion.
+                * @param[in]   isExcluded  Whether item is excluded from multiple selection
                 */
-               bool hasCustomResult() const;
+               void setExcluded(bool isExcluded);
 
                /**
-                * @brief Set custom selection result to override the default result.
+                * @return Item selection mode.
                 */
-               void setCustomResult(SelectResult result);
+               SelectMode getSelectMode() const;
 
+       protected:
                /**
-                * @brief Unset custom selection result to use default result.
+                * @see GenItem::getContent()
                 */
-               void unsetCustomResult();
+               virtual Evas_Object *getContent(Evas_Object *parent, const char *part) override;
 
-       protected:
                /**
-                * @return Default selection result associated with the item.
+                * @brief Adds this item to the parent SelectView.
+                * @see GenItem::onInserted()
                 */
-               virtual SelectResult getDefaultResult() const = 0;
+               virtual void onInserted() override;
 
                /**
-                * @see GenItem::getContent()
+                * @brief Removes this item from the parent SelectView.
+                * @see ListItem::onDelete()
                 */
-               virtual Evas_Object *getContent(Evas_Object *parent, const char *part) override;
+               virtual void onDelete() override;
 
                /**
                 * @GenItem::onVisibilityChanged()
@@ -95,9 +105,11 @@ namespace Ux
                virtual void onSelected() override;
 
                /**
-                * @see CheckItem::onChecked()
+                * @brief Called when item's "checked" state changes.
+                * @param[in]   isChecked   Whether item is checked
+                * @return Whether item's state should be changed.
                 */
-               virtual bool onChecked(bool isChecked) override;
+               virtual bool onChecked(bool isChecked) { return true; }
 
                /**
                 * @brief Called when selection mode was changed.
@@ -107,11 +119,17 @@ namespace Ux
 
        private:
                friend class SelectView;
+               void setSelectMode(SelectMode selectMode);
+
+               void onCheckChanged(Evas_Object *check, void *eventInfo);
+               bool isCheckAllowed();
+
+               const char *m_CheckPart;
+               Eina_Bool m_IsChecked;
+               bool m_IsChecking;
 
                SelectView *m_SelectView;
                SelectMode m_SelectMode;
-               SelectResult m_CustomResult;
-               bool m_HasCustomResult;
                bool m_IsExcluded;
        };
 }
diff --git a/lib-apps-common/inc/Ux/SelectTypes.h b/lib-apps-common/inc/Ux/SelectTypes.h
deleted file mode 100644 (file)
index 0221525..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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 UX_SELECT_TYPES_H
-#define UX_SELECT_TYPES_H
-
-#include <functional>
-#include <vector>
-
-namespace Ux
-{
-       /**
-        * @brief Determines how items can be selected.
-        */
-       enum SelectMode
-       {
-               SelectNone,     /**< Selection is disabled */
-               SelectSingle,   /**< Only one item can be selected */
-               SelectMulti     /**< Multiple items can be selected */
-       };
-
-       /**
-        * @brief Selection result.
-        */
-       struct SelectResult
-       {
-               unsigned type;  /**< Result type (depends on result source) */
-               union Value
-               {
-                       Value(void *data) : data(data) { }
-                       Value(int id) : id(id) { }
-                       void *data; /**< Result data */
-                       int id;     /**< Result data ID */
-               } value;        /**< Result value (depends on type) */
-       };
-
-       /**
-        * @brief Range of consecutive selection results.
-        */
-       typedef std::vector<SelectResult> SelectResults;
-
-       /**
-        * @brief Callback to be called when selection is done.
-        * @param[in]   Selection results
-        * @return Whether the component that provided the selection should be destroyed.
-        */
-       typedef std::function<bool(SelectResults)> SelectCallback;
-
-       /**
-        * @brief Callback to be called when cancel is pressed.
-        * @return Whether the component that provided the selection should be destroyed.
-        */
-       typedef std::function<bool()> CancelCallback;
-}
-
-#endif /* UX_SELECT_TYPES_H */
index ed0915f9630218faf64202149e2b0f85c8e6cb03..03bb6dafd669fda1ea89044b9ee3e28e93700655 100644 (file)
@@ -17,9 +17,9 @@
 #ifndef UX_SELECT_VIEW_H
 #define UX_SELECT_VIEW_H
 
-#include "Ui/View.h"
+#include "Ux/ListView.h"
 #include "Ux/MultiSelector.h"
-#include "Ux/SelectTypes.h"
+#include "Ux/SelectItem.h"
 
 #include <vector>
 
@@ -30,21 +30,25 @@ namespace Ui
 
 namespace Ux
 {
-       class SelectItem;
+       /**
+        * @brief List of selected items.
+        */
+       typedef std::vector<SelectItem *> SelectResults;
 
        /**
         * @brief Base class for a view that support single and multiple selection modes.
         */
-       class EXPORT_API SelectView : public Ui::View
+       class EXPORT_API SelectView : public ListView
        {
        public:
+               DEFINE_CLASS_TYPE(SelectView, ListView)
+
                /**
                 * @brief Translatable strings table for view elements.
                 */
                struct Strings
                {
-                       const char *selectAll;      /**< "Select all" text. */
-                       const char *deselectAll;    /**< "Deselect all" text. */
+                       MultiSelector::Strings selectorStrings;
                        const char *buttonDone;     /**< "Done" button text. */
                        const char *buttonCancel;   /**< "Cancel" button text. */
                        const char *titleDefault;   /**< Title for #SelectNone mode. */
@@ -58,6 +62,31 @@ namespace Ux
                                                                                         Can contain one integer format specifiers. */
                };
 
+               /**
+                * @brief Translatable strings table for accessibility feature.
+                */
+               struct AccessibleStrings
+               {
+                       MultiSelector::AccessibleStrings selectorStrings;
+                       const char *titleWithCount; /**< Title for #SelectMulti mode with selection count.
+                                                                                        Can contain one integer format specifier. */
+                       const char *titleWithLimit; /**< Title for #SelectMulti mode with limit.
+                                                                                        Can contain two integer format specifiers. */
+               };
+
+               /**
+                * @brief Callback to be called when selection is done.
+                * @param[in]   Selection results
+                * @return Whether the view should be closed.
+                */
+               typedef std::function<bool(SelectResults)> SelectCallback;
+
+               /**
+                * @brief Callback to be called when cancel is pressed.
+                * @return Whether the view should be closed.
+                */
+               typedef std::function<bool()> CancelCallback;
+
                /**
                 * @brief Called when item's "checked" state changed in #SelectMulti mode.
                 * @param[in]   item            Changed item
@@ -78,8 +107,10 @@ namespace Ux
                 */
                typedef std::vector<SelectItem *> SelectItems;
 
-               SelectView();
-               virtual ~SelectView() override;
+               /**
+                * @see ListView::ListView()
+                */
+               explicit SelectView(Model::DataProvider &provider, Ui::GenContainer *container = nullptr);
 
                /**
                 * @return View selection mode.
@@ -102,16 +133,18 @@ namespace Ux
                const SelectItems &getSelectItems() const;
 
                /**
-                * @return Whether all items are selected.
+                * @brief Set translatable strings for the view.
+                * @remark Should be called before create().
+                * @param[in]   strings    Translatable strings table
                 */
-               bool isMaxSelected() const;
+               void setStrings(const Strings &strings);
 
                /**
-                * @brief Set translatable strings for the view.
+                * @brief Set translatable strings for accessibility.
                 * @remark Should be called before create().
                 * @param[in]   strings    Translatable strings table
                 */
-               void setStrings(const Strings &strings);
+               void setAccessibleStrings(const AccessibleStrings &strings);
 
                /**
                 * @brief Set selection mode.
@@ -157,10 +190,9 @@ namespace Ux
 
        protected:
                /**
-                * @brief Creates "Done" and "Cancel" buttons in #SelectMulti mode.
-                * @see View::onPageAttached()
+                * @see ListView::createContent()
                 */
-               virtual void onPageAttached(Ui::NavigatorPage *page) override;
+               virtual Evas_Object *createContent(Evas_Object *parent) override;
 
                /**
                 * @brief Calls cancel callback if it exists.
@@ -169,10 +201,10 @@ namespace Ux
                virtual bool onBackPressed() override;
 
                /**
-                * @brief Called when title was changed.
-                * @param[in]   title  Title
+                * @brief Registers accessible siblings for the item when in #SelectMulti mode.
+                * @see ListView::onItemInserted()
                 */
-               virtual void onTitleChanged(const char *title);
+               virtual void onItemInserted(ListItem *item) override;
 
                /**
                 * @brief Called when selection mode was changed.
@@ -192,38 +224,6 @@ namespace Ux
                 */
                virtual void onSelectCountChanged(size_t selectCount) { }
 
-               /**
-                * @return Done button.
-                */
-               virtual Evas_Object *createDoneButton();
-
-               /**
-                * @return Cancel button.
-                */
-               virtual Evas_Object *createCancelButton();
-
-               /**
-                * @return MultiSelector control.
-                */
-               virtual Ux::MultiSelector *createMultiSelector() = 0;
-
-               /**
-                * @brief Add selectable item to be managed by the view.
-                * @param[in]   item    Item to add
-                */
-               void addSelectItem(SelectItem *item);
-
-               /**
-                * @brief Remove selectable item.
-                * @param[in]   item    Item to remove
-                */
-               void removeSelectItem(SelectItem *item);
-
-               /**
-                * @return MultiSelector
-                */
-               Ui::ControlPtr getMultiSelector();
-
        private:
                friend class SelectItem;
 
@@ -233,11 +233,18 @@ namespace Ux
                        CountDecrement
                };
 
+               Evas_Object *createMultiSelector(Evas_Object *parent);
+               Evas_Object *createDoneButton(Evas_Object *parent);
+               void setAccessSiblings(ListItem *item);
+               void unsetAccessSiblings(ListItem *item);
+               void onScrolled(Evas_Object *obj, void *eventInfo);
+
                size_t getSelectMax() const;
                bool isLimitReached() const;
+               bool isMaxSelected() const;
 
-               void updatePageTitle();
-               void updatePageButtons();
+               char *getAccessibleTitle(Evas_Object *obj);
+               void updateTitle();
                void updateDoneButtonState();
                void updateMultiSelector();
                void updateMultiSelectorState();
@@ -248,8 +255,8 @@ namespace Ux
                void updateVisibleCount(CountChange change, SelectItem *item);
                void updateVisibleSelectCount(CountChange change, SelectItem *item);
 
-               void createPageButtons();
-               void destroyPageButtons();
+               void addSelectItem(SelectItem *item);
+               void removeSelectItem(SelectItem *item);
 
                void onItemExcluded(SelectItem *item, bool isExcluded);
                void onItemVisibilityChanged(SelectItem *item, bool isVisible);
@@ -261,19 +268,18 @@ namespace Ux
                void onCancelPressed(Evas_Object *button, void *eventInfo);
                void onLimitReached();
 
-               Ui::ControlPtr m_MultiSelector;
                SelectItems m_Items;
-
+               MultiSelector *m_MultiSelector;
                Evas_Object *m_DoneButton;
-               Evas_Object *m_CancelButton;
 
+               bool m_IsEmptyResultAllowed;
                bool m_IsMultiChecking;
+
                size_t m_TotalCount;
                size_t m_TotalSelectCount;
                size_t m_VisibleCount;
                size_t m_VisibleSelectCount;
                size_t m_SelectLimit;
-               bool m_IsEmptyResultAllowed;
 
                SelectMode     m_SelectMode;
                SelectCallback m_OnSelected;
@@ -282,6 +288,7 @@ namespace Ux
                LimitCallback  m_OnLimitReached;
 
                Strings m_Strings;
+               AccessibleStrings m_AccessStrings;
        };
 }
 
diff --git a/lib-apps-common/src/Ui/CheckItem.cpp b/lib-apps-common/src/Ui/CheckItem.cpp
deleted file mode 100644 (file)
index 72bf193..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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 "Ui/CheckItem.h"
-#include "Utils/Callback.h"
-
-using namespace Ui;
-
-CheckItem::CheckItem(GenContainer::Type type)
-       : GenItem(type),
-         m_CheckPart("*"), m_IsChecked(false), m_IsChecking(false),
-         m_LinkedItem(nullptr)
-{
-}
-
-CheckItem::~CheckItem()
-{
-       unsetLinkedItem();
-}
-
-bool CheckItem::isChecked() const
-{
-       return m_IsChecked;
-}
-
-bool CheckItem::setChecked(bool isChecked)
-{
-       if (isChecked == m_IsChecked) {
-               return true;
-       }
-
-       m_IsChecked = isChecked;
-       if (!notifyCheck()) {
-               m_IsChecked = !m_IsChecked;
-               return false;
-       }
-
-       Evas_Object *check = elm_object_item_part_content_get(getObjectItem(), m_CheckPart.c_str());
-       if (check) {
-               /* Enable animation */
-               elm_object_signal_emit(check, m_IsChecked
-                               ? "elm,activate,check,on" : "elm,activate,check,off", "elm");
-               elm_check_state_set(check, m_IsChecked);
-       }
-
-       return true;
-}
-
-void CheckItem::setCheckCallback(CheckCallback callback)
-{
-       m_OnChecked = std::move(callback);
-}
-
-void CheckItem::setLinkedItem(CheckItem *item)
-{
-       if (!item) {
-               return;
-       }
-
-       unsetLinkedItem();
-       item->unsetLinkedItem();
-
-       item->setChecked(m_IsChecked);
-       item->m_LinkedItem = this;
-       m_LinkedItem = item;
-}
-
-void CheckItem::unsetLinkedItem()
-{
-       if (m_LinkedItem) {
-               m_LinkedItem->m_LinkedItem = nullptr;
-               m_LinkedItem = nullptr;
-       }
-}
-
-void CheckItem::updateCheckPart()
-{
-       update(m_CheckPart.c_str(), ELM_GENLIST_ITEM_FIELD_CONTENT);
-}
-
-Evas_Object *CheckItem::getContent(Evas_Object *parent, const char *part)
-{
-       m_CheckPart = part;
-
-       Elm_Check *check = elm_check_add(parent);
-       elm_check_state_set(check, m_IsChecked);
-       elm_check_state_pointer_set(check, &m_IsChecked);
-       evas_object_propagate_events_set(check, EINA_FALSE);
-       evas_object_smart_callback_add(check, "changed",
-                       makeCallback(&CheckItem::onCheckChanged), this);
-
-       elm_atspi_accessible_relationship_append(check, ELM_ATSPI_RELATION_CONTROLLED_BY, getObjectItem());
-       elm_atspi_accessible_relationship_append(getObjectItem(), ELM_ATSPI_RELATION_CONTROLLER_FOR, check);
-       elm_atspi_accessible_relationship_append(getObjectItem(), ELM_ATSPI_RELATION_DESCRIBED_BY, check);
-
-       return check;
-}
-
-void CheckItem::onSelected()
-{
-       setChecked(!m_IsChecked);
-}
-
-void CheckItem::onCheckChanged(Evas_Object *check, void *eventInfo)
-{
-       if (!notifyCheck()) {
-               elm_check_state_set(check, !m_IsChecked);
-       }
-}
-
-bool CheckItem::notifyCheck()
-{
-       if (m_IsChecking) {
-               return false;
-       }
-
-       bool isAllowed = false;
-       m_IsChecking = true;
-
-       if (onChecked(m_IsChecked)) {
-               if (!m_OnChecked || m_OnChecked(m_IsChecked)) {
-                       if (!m_LinkedItem || m_LinkedItem->setChecked(m_IsChecked)) {
-                               isAllowed = true;
-                       }
-               }
-       }
-
-       m_IsChecking = false;
-       return isAllowed;
-}
index d12a54720353b09b34c04992c7e99671e65ef7e9..4dcca40a0ae209531d1a639bda4aec8567b2c759 100644 (file)
 #include "Ui/Accessibility.h"
 #include "Ui/CircleMenu.h"
 #include "Utils/Callback.h"
-#include <app_i18n.h>
-
-#define BUF_SIZE 8
-#define BTN_BUF_SIZE 32
 
 using namespace Ui;
 using namespace Ux;
 
-CircleSelector::CircleSelector()
-       : m_AccessibilityStrings{ nullptr },
-         m_Count(0)
-{
-}
-
-void CircleSelector::setCount(size_t count)
-{
-       m_Count = count;
-       char buf[BUF_SIZE];
-       snprintf(buf, sizeof(buf), "%zu", count);
-       elm_object_text_set(getEvasObject(), buf);
-}
-
-void CircleSelector::setAccessibilityStrings(const AccessibilityStrings &strings)
-{
-       m_AccessibilityStrings = strings;
-}
-
 Evas_Object *CircleSelector::onCreate(Evas_Object *parent)
 {
        auto button = elm_button_add(parent);
        elm_object_style_set(button, "select_mode");
-       elm_object_text_set(button, "0");
        evas_object_smart_callback_add(button, "clicked",
                        makeCallback(&CircleSelector::onButtonClicked), this);
 
-       elm_atspi_accessible_name_cb_set(button, makeCallback(&CircleSelector::getAccessibleName), this);
-
        return button;
 }
 
@@ -67,13 +41,13 @@ void CircleSelector::onButtonClicked(Evas_Object *button, void *eventInfo)
                auto item = menu->addItem(getStrings().selectAll, [this] {
                        notifyChanged(SelectedAll);
                });
-               makeAccessible(item, m_AccessibilityStrings.selectAllDescription);
+               makeAccessible(item, getAccessibleStrings().selectAll);
        }
        if (getState() != SelectedNone) {
                auto item = menu->addItem(getStrings().deselectAll, [this] {
                        notifyChanged(SelectedNone);
                });
-               makeAccessible(item, m_AccessibilityStrings.deselectAllDescription);
+               makeAccessible(item, getAccessibleStrings().deselectAll);
        }
        menu->show();
 
@@ -85,8 +59,8 @@ void CircleSelector::makeAccessible(Evas_Object *menu)
        elm_atspi_accessible_reading_info_type_set(menu, Elm_Accessible_Reading_Info_Type(
                        ELM_ACCESSIBLE_READING_INFO_TYPE_NAME |
                        ELM_ACCESSIBLE_READING_INFO_TYPE_DESCRIPTION));
-       elm_atspi_accessible_name_cb_set(menu, getTranslatableAccessText, m_AccessibilityStrings.name);
-       elm_atspi_accessible_description_cb_set(menu, getTranslatableAccessText, m_AccessibilityStrings.description);
+       elm_atspi_accessible_name_cb_set(menu, getTranslatableAccessText, getAccessibleStrings().name);
+       elm_atspi_accessible_description_cb_set(menu, getTranslatableAccessText, getAccessibleStrings().desc);
 
        elm_access_action_cb_set(menu, ELM_ACCESS_ACTION_ACTIVATE,
                [](void *, Evas_Object *obj, Elm_Access_Action_Info *) {
@@ -100,10 +74,3 @@ void CircleSelector::makeAccessible(Elm_Object_Item *item, const char *descripti
        elm_atspi_accessible_reading_info_type_set(item, ELM_ACCESSIBLE_READING_INFO_TYPE_DESCRIPTION);
        elm_atspi_accessible_description_cb_set(item, getTranslatableAccessText, description);
 }
-
-char *CircleSelector::getAccessibleName(Evas_Object *button)
-{
-       char buf[BTN_BUF_SIZE];
-       snprintf(buf, sizeof(buf), _(m_AccessibilityStrings.title), (int)m_Count);
-       return strdup(buf);
-}
diff --git a/lib-apps-common/src/Ux/ListItem.cpp b/lib-apps-common/src/Ux/ListItem.cpp
new file mode 100644 (file)
index 0000000..9842c79
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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 "Ux/ListItem.h"
+#include "Model/DataItem.h"
+
+using namespace Ux;
+using namespace std::placeholders;
+
+ListItem::ListItem(Model::DataItem &dataItem, Ui::GenContainer::Type type)
+       : GenItem(type), m_DataItem(dataItem)
+{
+       m_DataItem.setUserData(this);
+       m_DataItem.onUpdated() += { std::bind(&ListItem::onDataItemUpdated, this, _1, _2), this };
+       m_DataItem.onDeleted() += { std::bind(&ListItem::onDataItemDeleted, this), this };
+}
+
+ListItem::~ListItem()
+{
+       m_DataItem.onUpdated() -= this;
+       m_DataItem.onDeleted() -= this;
+       m_DataItem.setUserData(nullptr);
+}
+
+void ListItem::onDataItemUpdated(int changes, Model::DataItem *nextDataItem)
+{
+       if (!isInserted()) {
+               return;
+       }
+
+       Ui::GenItem *nextItem = getParent()->getLastItem();
+       if (nextDataItem && nextDataItem->getUserData()) {
+               nextItem = (ListItem *) nextDataItem->getUserData();
+       }
+       if (nextItem != getNextItem()) {
+               Ui::GenGroupItem *parentItem = getParentItem();
+               if (parentItem != nextItem->getParentItem()) {
+                       nextItem = nullptr;
+               }
+               getParent()->insert(this, parentItem, nextItem);
+       } else {
+               onUpdate(changes);
+       }
+}
+
+void ListItem::onDataItemDeleted()
+{
+       onDelete();
+       delete this;
+}
diff --git a/lib-apps-common/src/Ux/ListView.cpp b/lib-apps-common/src/Ux/ListView.cpp
new file mode 100644 (file)
index 0000000..76c5351
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * 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 "Ux/ListView.h"
+#include "Ux/ListItem.h"
+
+#include "Ui/Accessibility.h"
+#include "Ui/GenGroupItem.h"
+#include "Ui/Genlist.h"
+#include "Ui/PaddingItem.h"
+#include "Model/DataProvider.h"
+
+#include <efl_extension.h>
+
+using namespace Model;
+using namespace Ux;
+using namespace std::placeholders;
+
+ListView::ListView(DataProvider &provider, Ui::GenContainer *container)
+       : m_Container(container), m_Content(nullptr), m_NoContents(nullptr), m_MoreMenu(nullptr),
+         m_Provider(provider)
+{
+}
+
+void ListView::setFillCallback(FillCallback callback)
+{
+       m_OnFilled = std::move(callback);
+}
+
+Evas_Object *ListView::onCreate(Evas_Object *parent)
+{
+       Evas_Object *layout = elm_layout_add(parent);
+       elm_layout_theme_set(layout, "layout", "application", "default");
+
+       m_Content = createContent(layout);
+       m_NoContents = createNoContents(layout);
+       return layout;
+}
+
+void ListView::onCreated()
+{
+       m_Provider.onInserted() += { std::bind(&ListView::addItem, this, _1, _2), this };
+       m_Provider.onUpdated() += { std::bind(&ListView::updateEmptyState, this), this };
+       m_Provider.initialize({ [this] {
+               for (auto &&dataItem : m_Provider.getDataList()) {
+                       addItem(*dataItem);
+               }
+               updateEmptyState();
+
+               onFilled();
+               if (m_OnFilled) {
+                       m_OnFilled();
+               }
+       }, this });
+}
+
+void ListView::onNavigation(bool isCurrent)
+{
+       eext_rotary_object_event_activated_set(m_Container->getEvasObject(), isCurrent);
+       m_Provider.setUpdateEnabled(isCurrent);
+}
+
+Evas_Object *ListView::createContent(Evas_Object *parent)
+{
+       Evas_Object *layout = elm_layout_add(parent);
+       elm_layout_theme_set(layout, "layout", "list", "default");
+
+       if (!m_Container) {
+               m_Container = new Ui::Genlist();
+       }
+       m_Container->create(layout);
+       m_Container->insert(new Ui::PaddingItem());
+       m_Container->insert(new Ui::PaddingItem());
+       elm_object_content_set(layout, m_Container->getEvasObject());
+
+       m_MoreMenu = createMoreMenu(layout);
+       if (m_MoreMenu) {
+               /* FIXME: Remove this workaround once eext_more_option stops repeating events */
+               evas_object_repeat_events_set(elm_object_part_content_get(m_MoreMenu, "elm.swallow.right"), EINA_FALSE);
+               evas_object_smart_callback_add(m_MoreMenu, "more,option,closed",
+                       [](void *data, Evas_Object *menu, void *) {
+                               auto view = (ListView *) data;
+                               eext_rotary_object_event_activated_set(view->m_Container->getEvasObject(), EINA_TRUE);
+                               evas_object_repeat_events_set(elm_object_part_content_get(menu, "elm.swallow.right"), EINA_FALSE);
+                       }, this);
+
+               evas_object_smart_callback_add(getContainer()->getEvasObject(), "scroll",
+                       [](void *data, Evas_Object *, void *) {
+                               auto view = (ListView *) data;
+                               elm_atspi_accessible_relationships_clear(view->m_MoreMenu);
+                               elm_atspi_accessible_relationship_append(view->m_MoreMenu,
+                                               ELM_ATSPI_RELATION_FLOWS_FROM, view->m_Container->getMiddleItem()->getObjectItem());
+                       }, this);
+               elm_object_part_content_set(layout, "elm.swallow.more_option", m_MoreMenu);
+       }
+
+       return layout;
+}
+
+Evas_Object *ListView::createNoContents(Evas_Object *parent)
+{
+       Evas_Object *layout = elm_layout_add(parent);
+       elm_layout_theme_set(layout, "layout", "nocontents", "default");
+       Ui::createTextAccessObject(layout, "elm.text.title");
+       return layout;
+}
+
+void ListView::updateEmptyState()
+{
+       Evas_Object *content = m_Provider.getDataList().empty() ? m_NoContents : m_Content;
+       if (content != elm_object_content_get(getEvasObject())) {
+               evas_object_hide(elm_object_content_unset(getEvasObject()));
+               elm_object_content_set(getEvasObject(), content);
+       }
+}
+
+Model::DataProvider &ListView::getProvider() const
+{
+       return m_Provider;
+}
+
+Ui::GenContainer *ListView::getContainer() const
+{
+       return m_Container;
+}
+
+Evas_Object *ListView::getContent() const
+{
+       return m_Content;
+}
+
+Evas_Object *ListView::getNoContents() const
+{
+       return m_NoContents;
+}
+
+Evas_Object *ListView::getMoreMenu() const
+{
+       return m_MoreMenu;
+}
+
+ListItem *ListView::addItem(DataItem &dataItem, DataItem *nextDataItem)
+{
+       Ui::GenItem *nextItem = m_Container->getLastItem();
+       if (nextDataItem && nextDataItem->getUserData()) {
+               nextItem = (ListItem *) nextDataItem->getUserData();
+       }
+
+       ListItem *item = createItem(dataItem);
+       m_Container->insert(item, nullptr, nextItem);
+
+       if (m_MoreMenu) {
+               if (item->isGroupItem()) {
+                       for (auto &&subItem : *dynamic_cast<Ui::GenGroupItem *>(item)) {
+                               elm_atspi_accessible_relationship_append(subItem->getObjectItem(),
+                                               ELM_ATSPI_RELATION_FLOWS_TO, m_MoreMenu);
+                               onItemInserted(dynamic_cast<ListItem *>(subItem));
+                       }
+               } else {
+                       elm_atspi_accessible_relationship_append(item->getObjectItem(),
+                                       ELM_ATSPI_RELATION_FLOWS_TO, m_MoreMenu);
+                       onItemInserted(item);
+               }
+       }
+
+       return item;
+}
index ea64ce4721b0196765445923c3f13ea309cef83b..246fcfeba942ec884238f6d49b8ae1b65b305618 100644 (file)
@@ -20,7 +20,7 @@ using namespace Ux;
 
 MultiSelector::MultiSelector()
        : m_State(SelectedNone),
-         m_Strings{ nullptr }
+         m_Strings{ }, m_AccessStrings{ }
 {
 }
 
@@ -40,6 +40,11 @@ void MultiSelector::setStrings(const Strings &strings)
        m_Strings = strings;
 }
 
+void MultiSelector::setAccessibleStrings(const AccessibleStrings &strings)
+{
+       m_AccessStrings = strings;
+}
+
 MultiSelector::State MultiSelector::getState() const
 {
        return m_State;
@@ -50,6 +55,11 @@ const MultiSelector::Strings &MultiSelector::getStrings() const
        return m_Strings;
 }
 
+const MultiSelector::AccessibleStrings &MultiSelector::getAccessibleStrings() const
+{
+       return m_AccessStrings;
+}
+
 bool MultiSelector::notifyChanged(State state)
 {
        return !m_OnChanged || m_OnChanged(state);
diff --git a/lib-apps-common/src/Ux/SelectAllItem.cpp b/lib-apps-common/src/Ux/SelectAllItem.cpp
deleted file mode 100644 (file)
index ec6d8cb..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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 "Ux/SelectAllItem.h"
-#include <app_i18n.h>
-
-#define TEXT_COLOR 61, 185, 204, 255
-
-using namespace Ux;
-
-SelectAllItem::SelectAllItem(const char *text)
-{
-       if (text) {
-               m_Text = text;
-       }
-}
-
-Elm_Gen_Item_Class *SelectAllItem::getItemClass() const
-{
-       static Elm_Gen_Item_Class itc = createItemClass("end_icon");
-       return &itc;
-}
-
-char *SelectAllItem::getText(Evas_Object *parent, const char *part)
-{
-       if (strcmp(part, "elm.text") == 0) {
-               return strdup(_(m_Text.c_str()));
-       }
-
-       return nullptr;
-}
-
-Evas_Object *SelectAllItem::getContent(Evas_Object *parent, const char *part)
-{
-       if (strcmp(part, "elm.swallow.end") == 0) {
-               return CheckItem::getContent(parent, part);
-       }
-
-       return nullptr;
-}
-
-void SelectAllItem::onInserted()
-{
-       elm_object_item_color_class_color_set(getObjectItem(), "text", TEXT_COLOR);
-       elm_object_item_color_class_color_set(getObjectItem(), "text_pressed", TEXT_COLOR);
-}
index 746d389e49767dab467c96f7b4e79c971fcb6653..9d6e10dadd480a004eadf61075a30a4c08c39628 100644 (file)
 
 #include "Ux/SelectItem.h"
 #include "Ux/SelectView.h"
+#include "Utils/Callback.h"
 
 using namespace Ux;
-using namespace Ui;
 
-SelectItem::SelectItem(GenContainer::Type type)
-       : CheckItem(type),
+SelectItem::SelectItem(Model::DataItem &dataItem, const char *checkPart, Ui::GenContainer::Type type)
+       : ListItem(dataItem, type),
+         m_CheckPart(checkPart), m_IsChecked(false), m_IsChecking(false),
          m_SelectView(nullptr), m_SelectMode(SelectNone),
-         m_CustomResult{ 0, 0 }, m_HasCustomResult(false),
          m_IsExcluded(false)
 {
 }
 
+bool SelectItem::isChecked() const
+{
+       return m_IsChecked;
+}
+
+bool SelectItem::setChecked(bool isChecked)
+{
+       if (isChecked == m_IsChecked) {
+               return true;
+       }
+
+       m_IsChecked = isChecked;
+       if (!isCheckAllowed()) {
+               m_IsChecked = !m_IsChecked;
+               return false;
+       }
+
+       Evas_Object *check = elm_object_item_part_content_get(getObjectItem(), m_CheckPart);
+       if (check) {
+               /* Enable animation */
+               elm_object_signal_emit(check, m_IsChecked
+                               ? "elm,activate,check,on" : "elm,activate,check,off", "elm");
+               elm_check_state_set(check, m_IsChecked);
+       }
+
+       return true;
+}
+
 bool SelectItem::isExcluded() const
 {
        return m_IsExcluded;
@@ -50,49 +78,50 @@ SelectMode SelectItem::getSelectMode() const
        return m_SelectMode;
 }
 
-void SelectItem::setSelectMode(SelectMode selectMode)
-{
-       m_SelectMode = selectMode;
-
-       setChecked(false);
-       updateCheckPart();
-       onSelectModeChanged(m_SelectMode);
-}
-
-SelectResult SelectItem::getSelectResult() const
-{
-       return m_HasCustomResult ? m_CustomResult : getDefaultResult();
-}
-
-bool SelectItem::hasCustomResult() const
+Evas_Object *SelectItem::getContent(Evas_Object *parent, const char *part)
 {
-       return m_HasCustomResult;
-}
+       if (m_SelectMode == SelectMulti) {
+               if (strcmp(part, m_CheckPart) == 0) {
+                       Elm_Check *check = elm_check_add(parent);
+                       elm_check_state_set(check, m_IsChecked);
+                       elm_check_state_pointer_set(check, &m_IsChecked);
+                       elm_object_style_set(check, "genlist/select_mode");
+                       evas_object_propagate_events_set(check, EINA_FALSE);
+                       evas_object_smart_callback_add(check, "changed",
+                                       makeCallback(&SelectItem::onCheckChanged), this);
+
+                       elm_atspi_accessible_relationship_append(check, ELM_ATSPI_RELATION_CONTROLLED_BY, getObjectItem());
+                       elm_atspi_accessible_relationship_append(getObjectItem(), ELM_ATSPI_RELATION_CONTROLLER_FOR, check);
+                       elm_atspi_accessible_relationship_append(getObjectItem(), ELM_ATSPI_RELATION_DESCRIBED_BY, check);
+
+                       return check;
+               }
+       }
 
-void SelectItem::setCustomResult(SelectResult result)
-{
-       m_CustomResult = result;
-       m_HasCustomResult = true;
+       return nullptr;
 }
 
-void SelectItem::unsetCustomResult()
+void SelectItem::onInserted()
 {
-       m_HasCustomResult = false;
+       if (!m_SelectView) {
+               m_SelectView = getParent()->findParent<SelectView>();
+               if (m_SelectView) {
+                       m_SelectView->addSelectItem(this);
+               }
+       }
 }
 
-Evas_Object *SelectItem::getContent(Evas_Object *parent, const char *part)
+void SelectItem::onDelete()
 {
-       if (m_SelectMode == SelectMulti) {
-               return CheckItem::getContent(parent, part);
+       if (m_SelectView) {
+               m_SelectView->removeSelectItem(this);
        }
-
-       return nullptr;
 }
 
 void SelectItem::onVisibilityChanged(bool isVisible)
 {
        if (m_SelectView && !m_IsExcluded) {
-               return m_SelectView->onItemVisibilityChanged(this, isVisible);
+               m_SelectView->onItemVisibilityChanged(this, isVisible);
        }
 }
 
@@ -103,15 +132,41 @@ void SelectItem::onSelected()
                        m_SelectView->onItemSelected(this);
                }
        } else if (m_SelectMode == SelectMulti) {
-               CheckItem::onSelected();
+               setChecked(!m_IsChecked);
        }
 }
 
-bool SelectItem::onChecked(bool isChecked)
+void SelectItem::setSelectMode(SelectMode selectMode)
 {
-       if (m_SelectView && !m_IsExcluded) {
-               return m_SelectView->onItemChecked(this, isChecked);
+       m_SelectMode = selectMode;
+
+       setChecked(false);
+       update(m_CheckPart, ELM_GENLIST_ITEM_FIELD_CONTENT);
+       onSelectModeChanged(m_SelectMode);
+}
+
+void SelectItem::onCheckChanged(Evas_Object *check, void *eventInfo)
+{
+       if (!isCheckAllowed()) {
+               elm_check_state_set(check, !m_IsChecked);
        }
+}
 
-       return true;
+bool SelectItem::isCheckAllowed()
+{
+       if (m_IsChecking) {
+               return false;
+       }
+
+       bool isAllowed = false;
+       m_IsChecking = true;
+
+       if (onChecked(m_IsChecked)) {
+               if (m_IsExcluded || !m_SelectView || m_SelectView->onItemChecked(this, m_IsChecked)) {
+                       isAllowed = true;
+               }
+       }
+
+       m_IsChecking = false;
+       return isAllowed;
 }
index 2b52467b12ad2c6a7ea395cb0904c81fe05a111b..dfb2f8548ed9128eba7bc5532d41d4e8cdf93b01 100644 (file)
  */
 
 #include "Ux/SelectView.h"
-#include "Ux/SelectItem.h"
-
+#include "Ux/CircleSelector.h"
 #include "Ui/Genlist.h"
+#include "Ui/GenGroupItem.h"
+#include "Ui/Toast.h"
 #include "Utils/Callback.h"
 
 #include <app_i18n.h>
 #include <algorithm>
-#include <notification.h>
 
 #define TITLE_BUFFER_SIZE 64
 #define POPUP_BUFFER_SIZE 256
 using namespace Ux;
 using namespace std::placeholders;
 
-SelectView::SelectView()
-       : m_DoneButton(nullptr), m_CancelButton(nullptr), m_IsMultiChecking(false),
+SelectView::SelectView(Model::DataProvider &provider, Ui::GenContainer *container)
+       : ListView(provider, container),
+         m_MultiSelector(nullptr), m_DoneButton(nullptr),
+         m_IsEmptyResultAllowed(false), m_IsMultiChecking(false),
          m_TotalCount(0), m_TotalSelectCount(0),
          m_VisibleCount(0), m_VisibleSelectCount(0),
-         m_SelectLimit(0), m_IsEmptyResultAllowed(false), m_SelectMode(SelectNone),
-         m_Strings{ nullptr }
+         m_SelectLimit(0), m_SelectMode(SelectNone),
+         m_Strings{ }, m_AccessStrings{ }
 {
 }
 
-SelectView::~SelectView()
-{
-       if (auto multiSelector = m_MultiSelector.lock()) {
-               delete multiSelector.get();
-       }
-}
-
 SelectMode SelectView::getSelectMode() const
 {
        return m_SelectMode;
@@ -66,14 +61,14 @@ const SelectView::SelectItems &SelectView::getSelectItems() const
        return m_Items;
 }
 
-bool SelectView::isMaxSelected() const
+void SelectView::setStrings(const Strings &strings)
 {
-       return m_VisibleSelectCount == getSelectMax();
+       m_Strings = strings;
 }
 
-void SelectView::setStrings(const Strings &strings)
+void SelectView::setAccessibleStrings(const AccessibleStrings &strings)
 {
-       m_Strings = strings;
+       m_AccessStrings = strings;
 }
 
 void SelectView::setSelectMode(SelectMode selectMode)
@@ -81,12 +76,16 @@ void SelectView::setSelectMode(SelectMode selectMode)
        if (m_SelectMode != selectMode) {
                m_SelectMode = selectMode;
 
-               updatePageTitle();
-               updatePageButtons();
+               updateTitle();
                updateMultiSelector();
 
                for (auto &&item : m_Items) {
                        item->setSelectMode(m_SelectMode);
+                       if (m_SelectMode == SelectMulti) {
+                               setAccessSiblings(item);
+                       } else {
+                               unsetAccessSiblings(item);
+                       }
                }
 
                onSelectModeChanged(m_SelectMode);
@@ -111,7 +110,7 @@ void SelectView::setSelectLimit(size_t selectLimit)
 
                updateMultiSelectorState();
                updateDoneButtonState();
-               updatePageTitle();
+               updateTitle();
 
                onSelectLimitChanged(m_SelectLimit);
        }
@@ -145,15 +144,24 @@ void SelectView::setLimitCallback(LimitCallback callback)
        m_OnLimitReached = std::move(callback);
 }
 
-void SelectView::onPageAttached(Ui::NavigatorPage *page)
+Evas_Object *SelectView::createContent(Evas_Object *parent)
 {
-       updatePageTitle();
-       updatePageButtons();
+       Evas_Object *layout = elm_layout_add(parent);
+       elm_layout_theme_set(layout, "layout", "select_mode", "default");
+       elm_object_content_set(layout, ListView::createContent(layout));
+       elm_object_part_content_set(layout, "elm.swallow.icon", createMultiSelector(layout));
+       elm_object_part_content_set(layout, "elm.swallow.button", createDoneButton(layout));
 
-       evas_object_smart_callback_add(getEvasObject(), "language,changed",
+       evas_object_smart_callback_add(getContainer()->getEvasObject(), "scroll",
+                       makeCallback(&SelectView::onScrolled), this);
+       evas_object_smart_callback_add(layout, "language,changed",
                [](void *data, Evas_Object *, void *) {
-                       ((SelectView *) data)->updatePageTitle();
+                       auto view = (SelectView *) data;
+                       view->updateTitle();
                }, this);
+       updateTitle();
+
+       return layout;
 }
 
 bool SelectView::onBackPressed()
@@ -167,59 +175,66 @@ bool SelectView::onBackPressed()
        return true;
 }
 
-void SelectView::onTitleChanged(const char *title)
+void SelectView::onItemInserted(ListItem *item)
 {
-       if (auto page = getPage()) {
-               page->setTitle(title);
+       if (m_SelectMode == SelectMulti) {
+               setAccessSiblings(item);
        }
 }
 
-Evas_Object *SelectView::createDoneButton()
+Evas_Object *SelectView::createMultiSelector(Evas_Object *parent)
 {
-       if (auto page = getPage()) {
-               return page->addTitleButton(Ui::ButtonRight, m_Strings.buttonDone, nullptr, nullptr);
-       }
-
-       return nullptr;
+       m_MultiSelector = new CircleSelector();
+       m_MultiSelector->setStrings(m_Strings.selectorStrings);
+       m_MultiSelector->setAccessibleStrings(m_AccessStrings.selectorStrings);
+       m_MultiSelector->setChangeCallback(std::bind(&SelectView::onMultiSelectorChanged, this, _1));
+       m_MultiSelector->create(parent);
+       elm_atspi_accessible_name_cb_set(m_MultiSelector->getEvasObject(),
+                       makeCallback(&SelectView::getAccessibleTitle), this);
+       return m_MultiSelector->getEvasObject();
 }
 
-Evas_Object *SelectView::createCancelButton()
+Evas_Object *SelectView::createDoneButton(Evas_Object *parent)
 {
-       if (auto page = getPage()) {
-               return page->addTitleButton(Ui::ButtonLeft, m_Strings.buttonCancel, nullptr, nullptr);
-       }
-
-       return nullptr;
+       m_DoneButton = elm_button_add(parent);
+       elm_object_style_set(m_DoneButton, "bottom");
+       elm_object_translatable_text_set(m_DoneButton, m_Strings.buttonDone);
+       evas_object_smart_callback_add(m_DoneButton, "clicked", makeCallback(&SelectView::onDonePressed), this);
+       elm_atspi_accessible_relationship_append(m_DoneButton, ELM_ATSPI_RELATION_FLOWS_TO, getMoreMenu());
+       return m_DoneButton;
 }
 
-void SelectView::addSelectItem(SelectItem *item)
+void SelectView::setAccessSiblings(ListItem *item)
 {
-       item->m_SelectView = this;
-       item->setSelectMode(m_SelectMode);
-       m_Items.push_back(item);
+       elm_atspi_accessible_relationship_append(item->getObjectItem(),
+                       ELM_ATSPI_RELATION_FLOWS_FROM, m_MultiSelector->getEvasObject());
+       elm_atspi_accessible_relationship_append(item->getObjectItem(),
+                       ELM_ATSPI_RELATION_FLOWS_TO, m_DoneButton);
+}
 
-       if (!item->isExcluded()) {
-               updateTotalCount(CountIncrement, item);
-       }
+void SelectView::unsetAccessSiblings(ListItem *item)
+{
+       elm_atspi_accessible_relationship_remove(item->getObjectItem(),
+                       ELM_ATSPI_RELATION_FLOWS_FROM, m_MultiSelector->getEvasObject());
+       elm_atspi_accessible_relationship_remove(item->getObjectItem(),
+                       ELM_ATSPI_RELATION_FLOWS_TO, m_DoneButton);
 }
 
-void SelectView::removeSelectItem(SelectItem *item)
+void SelectView::onScrolled(Evas_Object *obj, void *eventInfo)
 {
-       auto it = std::find(m_Items.begin(), m_Items.end(), item);
-       if (it == m_Items.end()) {
-               return;
+       Ui::GenItem *middleItem = getContainer()->getMiddleItem();
+       Ui::GenGroupItem *groupItem = middleItem->getParentItem();
+       if (!groupItem || groupItem->getFirstItem() != middleItem) {
+               groupItem = nullptr;
        }
 
-       m_Items.erase(it);
-       if (!item->isExcluded()) {
-               updateTotalCount(CountDecrement, item);
-       }
-       item->m_SelectView = nullptr;
-}
+       elm_atspi_accessible_relationships_clear(m_MultiSelector->getEvasObject());
+       elm_atspi_accessible_relationship_append(m_MultiSelector->getEvasObject(),
+                       ELM_ATSPI_RELATION_FLOWS_TO, groupItem ? groupItem->getObjectItem() : middleItem->getObjectItem());
 
-Ui::ControlPtr SelectView::getMultiSelector()
-{
-       return m_MultiSelector;
+       elm_atspi_accessible_relationships_clear(m_DoneButton);
+       elm_atspi_accessible_relationship_append(m_DoneButton,
+                       ELM_ATSPI_RELATION_FLOWS_FROM, middleItem->getObjectItem());
 }
 
 size_t SelectView::getSelectMax() const
@@ -236,8 +251,37 @@ bool SelectView::isLimitReached() const
        return m_SelectLimit && m_TotalSelectCount == m_SelectLimit;
 }
 
-void SelectView::updatePageTitle()
+bool SelectView::isMaxSelected() const
+{
+       return m_VisibleSelectCount == getSelectMax();
+}
+
+char *SelectView::getAccessibleTitle(Evas_Object *obj)
+{
+       char buffer[TITLE_BUFFER_SIZE];
+       if (m_SelectMode == SelectMulti) {
+               if (m_SelectLimit) {
+                       int len = snprintf(buffer, sizeof(buffer), _(m_AccessStrings.titleWithLimit), m_TotalSelectCount, m_SelectLimit);
+                       if (len > 0) {
+                               return strdup(buffer);
+                       }
+               } else if (m_TotalSelectCount || !m_Strings.titleMulti) {
+                       int len = snprintf(buffer, sizeof(buffer), _(m_AccessStrings.titleWithCount), m_TotalSelectCount);
+                       if (len > 0) {
+                               return strdup(buffer);
+                       }
+               }
+       }
+
+       return Utils::safeDup(elm_object_text_get(obj));
+}
+
+void SelectView::updateTitle()
 {
+       if (!m_MultiSelector) {
+               return;
+       }
+
        char buffer[TITLE_BUFFER_SIZE];
        const char *title = nullptr;
 
@@ -250,37 +294,22 @@ void SelectView::updatePageTitle()
                        break;
                case SelectMulti:
                        if (m_SelectLimit) {
-                               snprintf(buffer, sizeof(buffer), _(m_Strings.titleWithLimit), m_TotalSelectCount, m_SelectLimit);
-                               title = buffer;
-                       } else if (m_TotalSelectCount) {
-                               snprintf(buffer, sizeof(buffer), _(m_Strings.titleWithCount), m_TotalSelectCount);
-                               title = buffer;
+                               int len = snprintf(buffer, sizeof(buffer), _(m_Strings.titleWithLimit), m_TotalSelectCount, m_SelectLimit);
+                               if (len > 0) {
+                                       title = buffer;
+                               }
+                       } else if (m_TotalSelectCount || !m_Strings.titleMulti) {
+                               int len = snprintf(buffer, sizeof(buffer), _(m_Strings.titleWithCount), m_TotalSelectCount);
+                               if (len > 0) {
+                                       title = buffer;
+                               }
                        } else {
                                title = m_Strings.titleMulti;
                        }
                        break;
        }
 
-       onTitleChanged(title);
-}
-
-void SelectView::updatePageButtons()
-{
-       switch (m_SelectMode) {
-               case SelectNone:
-               case SelectSingle:
-                       if (m_DoneButton) {
-                               destroyPageButtons();
-                       }
-                       break;
-
-               case SelectMulti:
-                       if (!m_DoneButton) {
-                               createPageButtons();
-                       }
-                       updateDoneButtonState();
-                       break;
-       }
+       elm_object_translatable_text_set(m_MultiSelector->getEvasObject(), title);
 }
 
 void SelectView::updateDoneButtonState()
@@ -291,35 +320,29 @@ void SelectView::updateDoneButtonState()
 
 void SelectView::updateMultiSelector()
 {
-       if (m_SelectMode == SelectMulti && m_VisibleCount) {
-               if (m_MultiSelector.expired()) {
-                       auto multiSelector = createMultiSelector();
-                       multiSelector->setStrings({ m_Strings.selectAll, m_Strings.deselectAll });
-                       multiSelector->setChangeCallback(std::bind(&SelectView::onMultiSelectorChanged, this, _1));
-
-                       m_MultiSelector = multiSelector->getWeakPtr();
-               }
-
-               updateMultiSelectorState();
-       } else {
-               if (auto multiSelector = m_MultiSelector.lock()) {
-                       delete multiSelector.get();
-               }
+       if (!m_MultiSelector) {
+               return;
        }
+
+       Evas_Object *layout = elm_object_parent_widget_get(m_MultiSelector->getEvasObject());
+       elm_layout_signal_emit(layout, m_SelectMode == SelectMulti && m_VisibleCount
+                       ? "select_mode,button,show" : "select_mode,button,hide", "");
 }
 
 void SelectView::updateMultiSelectorState()
 {
-       if (auto multiSelector = getPtr<MultiSelector>(m_MultiSelector)) {
-               auto state = MultiSelector::SelectedNone;
-               if (isMaxSelected()) {
-                       state = MultiSelector::SelectedAll;
-               } else if (getSelectCount()) {
-                       state = MultiSelector::SelectedPartially;
-               }
+       if (!m_MultiSelector) {
+               return;
+       }
 
-               multiSelector->setState(state);
+       auto state = MultiSelector::SelectedNone;
+       if (isMaxSelected()) {
+               state = MultiSelector::SelectedAll;
+       } else if (getSelectCount()) {
+               state = MultiSelector::SelectedPartially;
        }
+
+       m_MultiSelector->setState(state);
 }
 
 void SelectView::updateTotalCount(CountChange change, SelectItem *item)
@@ -348,7 +371,7 @@ void SelectView::updateTotalSelectCount(CountChange change, SelectItem *item)
        updateDoneButtonState();
        /* Prevent updating if multiple checking is in progress (performance optimization) */
        if (!m_IsMultiChecking) {
-               updatePageTitle();
+               updateTitle();
        }
 }
 
@@ -369,22 +392,27 @@ void SelectView::updateVisibleSelectCount(CountChange change, SelectItem *item)
        updateMultiSelectorState();
 }
 
-void SelectView::createPageButtons()
+void SelectView::addSelectItem(SelectItem *item)
 {
-       m_DoneButton = createDoneButton();
-       evas_object_smart_callback_add(m_DoneButton, "clicked", makeCallback(&SelectView::onDonePressed), this);
+       item->setSelectMode(m_SelectMode);
+       m_Items.push_back(item);
 
-       m_CancelButton = createCancelButton();
-       evas_object_smart_callback_add(m_CancelButton, "clicked", makeCallback(&SelectView::onCancelPressed), this);
+       if (!item->isExcluded()) {
+               updateTotalCount(CountIncrement, item);
+       }
 }
 
-void SelectView::destroyPageButtons()
+void SelectView::removeSelectItem(SelectItem *item)
 {
-       evas_object_del(m_DoneButton);
-       evas_object_del(m_CancelButton);
+       auto it = std::find(m_Items.begin(), m_Items.end(), item);
+       if (it == m_Items.end()) {
+               return;
+       }
 
-       m_DoneButton = nullptr;
-       m_CancelButton = nullptr;
+       m_Items.erase(it);
+       if (!item->isExcluded()) {
+               updateTotalCount(CountDecrement, item);
+       }
 }
 
 void SelectView::onItemExcluded(SelectItem *item, bool isExcluded)
@@ -399,9 +427,8 @@ void SelectView::onItemVisibilityChanged(SelectItem *item, bool isVisible)
 
 void SelectView::onItemSelected(SelectItem *item)
 {
-       if  (m_SelectMode == SelectSingle) {
-               SelectResult result = item->getSelectResult();
-               if (m_OnSelected && m_OnSelected({ result })) {
+       if (m_SelectMode == SelectSingle) {
+               if (m_OnSelected && m_OnSelected({ item })) {
                        getPage()->close();
                }
        }
@@ -440,16 +467,16 @@ bool SelectView::onMultiSelectorChanged(MultiSelector::State state)
        }
 
        m_IsMultiChecking = false;
-       updatePageTitle();
+       updateTitle();
        return isAllSelected == isMaxSelected();
 }
 
 void SelectView::onDonePressed(Evas_Object *button, void *eventInfo)
 {
-       std::vector<SelectResult> results;
+       std::vector<SelectItem *> results;
        for (auto &&item : m_Items) {
                if (!item->isExcluded() && item->isChecked()) {
-                       results.push_back(item->getSelectResult());
+                       results.push_back(item);
                }
        }
 
@@ -470,6 +497,10 @@ void SelectView::onLimitReached()
        if (!m_OnLimitReached || m_OnLimitReached()) {
                char buffer[POPUP_BUFFER_SIZE];
                snprintf(buffer, sizeof(buffer), _(m_Strings.popupLimit), m_SelectLimit);
-               notification_status_message_post(buffer);
+
+               auto toast = new Ui::Toast();
+               toast->create(getEvasObject());
+               toast->setText(buffer);
+               toast->show();
        }
 }