summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Kurzberg <i.kurtsberg@samsung.com>2017-07-21 17:59:51 +0300
committerEugene Kurzberg <i.kurtsberg@samsung.com>2017-07-24 10:00:47 +0300
commit9a17c5c733e5b15a5909d03a189300e50252ae2a (patch)
tree0ed2f6acd545cefe19c97806044a9c4860207af1
parentba10d486e51671cac51a6fa8f5562354e87c891a (diff)
downloadalarm-9a17c5c733e5b15a5909d03a189300e50252ae2a.tar.gz
alarm-9a17c5c733e5b15a5909d03a189300e50252ae2a.tar.bz2
alarm-9a17c5c733e5b15a5909d03a189300e50252ae2a.zip
Merge and integrate new ListView and SelectView.
Change-Id: I3f9c03d883f4e18da5b50c3aac357f4f3428f137 Signed-off-by: Eugene Kurzberg <i.kurtsberg@samsung.com>
-rw-r--r--alarm-app/inc/List/AlarmItem.h17
-rw-r--r--alarm-app/inc/List/AlarmsView.h43
-rw-r--r--alarm-app/inc/OperationPickController.h7
-rw-r--r--alarm-app/src/List/AlarmItem.cpp81
-rw-r--r--alarm-app/src/List/AlarmsView.cpp264
-rw-r--r--alarm-app/src/OperationPickController.cpp4
-rw-r--r--lib-apps-common/inc/Ui/CheckItem.h105
-rw-r--r--lib-apps-common/inc/Ux/CircleSelector.h31
-rw-r--r--lib-apps-common/inc/Ux/ListItem.h74
-rw-r--r--lib-apps-common/inc/Ux/ListView.h160
-rw-r--r--lib-apps-common/inc/Ux/MultiSelector.h44
-rw-r--r--lib-apps-common/inc/Ux/SelectAllItem.h62
-rw-r--r--lib-apps-common/inc/Ux/SelectItem.h86
-rw-r--r--lib-apps-common/inc/Ux/SelectTypes.h69
-rw-r--r--lib-apps-common/inc/Ux/SelectView.h123
-rw-r--r--lib-apps-common/src/Ui/CheckItem.cpp143
-rw-r--r--lib-apps-common/src/Ux/CircleSelector.cpp41
-rw-r--r--lib-apps-common/src/Ux/ListItem.cpp63
-rw-r--r--lib-apps-common/src/Ux/ListView.cpp180
-rw-r--r--lib-apps-common/src/Ux/MultiSelector.cpp12
-rw-r--r--lib-apps-common/src/Ux/SelectAllItem.cpp59
-rw-r--r--lib-apps-common/src/Ux/SelectItem.cpp131
-rw-r--r--lib-apps-common/src/Ux/SelectView.cpp285
23 files changed, 979 insertions, 1105 deletions
diff --git a/alarm-app/inc/List/AlarmItem.h b/alarm-app/inc/List/AlarmItem.h
index f95647a..1ee83b3 100644
--- a/alarm-app/inc/List/AlarmItem.h
+++ b/alarm-app/inc/List/AlarmItem.h
@@ -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;
};
}
diff --git a/alarm-app/inc/List/AlarmsView.h b/alarm-app/inc/List/AlarmsView.h
index 9586d3f..da1081c 100644
--- a/alarm-app/inc/List/AlarmsView.h
+++ b/alarm-app/inc/List/AlarmsView.h
@@ -21,11 +21,6 @@
#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;
};
}
diff --git a/alarm-app/inc/OperationPickController.h b/alarm-app/inc/OperationPickController.h
index 9edc855..23d7101 100644
--- a/alarm-app/inc/OperationPickController.h
+++ b/alarm-app/inc/OperationPickController.h
@@ -18,12 +18,7 @@
#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
{
diff --git a/alarm-app/src/List/AlarmItem.cpp b/alarm-app/src/List/AlarmItem.cpp
index 9704753..6573d36 100644
--- a/alarm-app/src/List/AlarmItem.cpp
+++ b/alarm-app/src/List/AlarmItem.cpp
@@ -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();
}
diff --git a/alarm-app/src/List/AlarmsView.cpp b/alarm-app/src/List/AlarmsView.cpp
index 7656e0b..c8c668e 100644
--- a/alarm-app/src/List/AlarmsView.cpp
+++ b/alarm-app/src/List/AlarmsView.cpp
@@ -14,23 +14,17 @@
* 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();
diff --git a/alarm-app/src/OperationPickController.cpp b/alarm-app/src/OperationPickController.cpp
index 5294fdb..6585af6 100644
--- a/alarm-app/src/OperationPickController.cpp
+++ b/alarm-app/src/OperationPickController.cpp
@@ -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
index f54c2aa..0000000
--- a/lib-apps-common/inc/Ui/CheckItem.h
+++ /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 */
diff --git a/lib-apps-common/inc/Ux/CircleSelector.h b/lib-apps-common/inc/Ux/CircleSelector.h
index 3adfe35..591e102 100644
--- a/lib-apps-common/inc/Ux/CircleSelector.h
+++ b/lib-apps-common/inc/Ux/CircleSelector.h
@@ -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
index 0000000..46a23f6
--- /dev/null
+++ b/lib-apps-common/inc/Ux/ListItem.h
@@ -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
index 0000000..e2b1c92
--- /dev/null
+++ b/lib-apps-common/inc/Ux/ListView.h
@@ -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 */
diff --git a/lib-apps-common/inc/Ux/MultiSelector.h b/lib-apps-common/inc/Ux/MultiSelector.h
index feb2e66..c69597c 100644
--- a/lib-apps-common/inc/Ux/MultiSelector.h
+++ b/lib-apps-common/inc/Ux/MultiSelector.h
@@ -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) { }
@@ -88,16 +105,23 @@ 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
index c2babc6..0000000
--- a/lib-apps-common/inc/Ux/SelectAllItem.h
+++ /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 */
diff --git a/lib-apps-common/inc/Ux/SelectItem.h b/lib-apps-common/inc/Ux/SelectItem.h
index 7f3fb71..4a39f7a 100644
--- a/lib-apps-common/inc/Ux/SelectItem.h
+++ b/lib-apps-common/inc/Ux/SelectItem.h
@@ -17,72 +17,82 @@
#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
index 0221525..0000000
--- a/lib-apps-common/inc/Ux/SelectTypes.h
+++ /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 */
diff --git a/lib-apps-common/inc/Ux/SelectView.h b/lib-apps-common/inc/Ux/SelectView.h
index ed0915f..03bb6da 100644
--- a/lib-apps-common/inc/Ux/SelectView.h
+++ b/lib-apps-common/inc/Ux/SelectView.h
@@ -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. */
@@ -59,6 +63,31 @@ namespace Ux
};
/**
+ * @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
* @param[in] isChecked Whether item is checked
@@ -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
index 72bf193..0000000
--- a/lib-apps-common/src/Ui/CheckItem.cpp
+++ /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;
-}
diff --git a/lib-apps-common/src/Ux/CircleSelector.cpp b/lib-apps-common/src/Ux/CircleSelector.cpp
index d12a547..4dcca40 100644
--- a/lib-apps-common/src/Ux/CircleSelector.cpp
+++ b/lib-apps-common/src/Ux/CircleSelector.cpp
@@ -18,43 +18,17 @@
#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
index 0000000..9842c79
--- /dev/null
+++ b/lib-apps-common/src/Ux/ListItem.cpp
@@ -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
index 0000000..76c5351
--- /dev/null
+++ b/lib-apps-common/src/Ux/ListView.cpp
@@ -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;
+}
diff --git a/lib-apps-common/src/Ux/MultiSelector.cpp b/lib-apps-common/src/Ux/MultiSelector.cpp
index ea64ce4..246fcfe 100644
--- a/lib-apps-common/src/Ux/MultiSelector.cpp
+++ b/lib-apps-common/src/Ux/MultiSelector.cpp
@@ -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
index ec6d8cb..0000000
--- a/lib-apps-common/src/Ux/SelectAllItem.cpp
+++ /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);
-}
diff --git a/lib-apps-common/src/Ux/SelectItem.cpp b/lib-apps-common/src/Ux/SelectItem.cpp
index 746d389..9d6e10d 100644
--- a/lib-apps-common/src/Ux/SelectItem.cpp
+++ b/lib-apps-common/src/Ux/SelectItem.cpp
@@ -16,18 +16,46 @@
#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;
}
diff --git a/lib-apps-common/src/Ux/SelectView.cpp b/lib-apps-common/src/Ux/SelectView.cpp
index 2b52467..dfb2f85 100644
--- a/lib-apps-common/src/Ux/SelectView.cpp
+++ b/lib-apps-common/src/Ux/SelectView.cpp
@@ -15,14 +15,14 @@
*/
#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
@@ -30,22 +30,17 @@
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();
}
}