TizenRefApp-5233 Implement Input::AddFieldsItem component 03/54503/4
authorEugene Kurzberg <i.kurtsberg@samsung.com>
Wed, 16 Dec 2015 09:51:46 +0000 (11:51 +0200)
committerEugene Kurzberg <i.kurtsberg@samsung.com>
Wed, 16 Dec 2015 11:58:24 +0000 (13:58 +0200)
Change-Id: I444b171b9633c6ad11d18c4346d279872a1a4357
Signed-off-by: Eugene Kurzberg <i.kurtsberg@samsung.com>
12 files changed:
lib-contact/inc/Contacts/Input/AddFieldsItem.h [new file with mode: 0644]
lib-contact/inc/Contacts/Input/InputView.h
lib-contact/res/input/CMakeLists.txt
lib-contact/res/input/edje/InputItemLayout.h
lib-contact/res/input/edje/InputPath.h
lib-contact/res/input/edje/input-item-layout.edc
lib-contact/res/input/images/contacts_circle_btn_ic_call.png [new file with mode: 0644]
lib-contact/res/input/images/contacts_circle_btn_ic_email.png [new file with mode: 0644]
lib-contact/res/input/images/contacts_circle_btn_ic_more.png [new file with mode: 0644]
lib-contact/res/input/images/contacts_circle_btn_ic_note.png [new file with mode: 0644]
lib-contact/src/Contacts/Input/AddFieldsItem.cpp [new file with mode: 0644]
lib-contact/src/Contacts/Input/InputView.cpp

diff --git a/lib-contact/inc/Contacts/Input/AddFieldsItem.h b/lib-contact/inc/Contacts/Input/AddFieldsItem.h
new file mode 100644 (file)
index 0000000..0095a70
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 CONTACTS_INPUT_ADD_FIELDS_ITEM_H
+#define CONTACTS_INPUT_ADD_FIELDS_ITEM_H
+
+#include "Contacts/Model/ContactFields.h"
+#include "Ui/GenlistItem.h"
+#include <functional>
+
+namespace Contacts
+{
+       namespace Input
+       {
+               /**
+                * @brief Genlist item with buttons for adding contact fields.
+                */
+               class AddFieldsItem : public Ui::GenlistItem
+               {
+               public:
+                       /**
+                        * @brief Add field callback.
+                        * @param[in]   ID of field to add
+                        */
+                       typedef std::function<void(Model::ContactFieldId)> AddFieldCallback;
+
+                       AddFieldsItem();
+
+                       /**
+                        * @brief Set add field callback.
+                        * @param[in]   callback    Callback to be called when add field requested
+                        */
+                       void setAddFieldCallback(AddFieldCallback callback);
+
+                       /**
+                        * @brief Set whether field can be added or not.
+                        * @param[in]   fieldId     Field ID to set the state for
+                        * @param[in]   isEnabled  Whether option to add field is enabled
+                        */
+                       void setAddFieldState(Model::ContactFieldId fieldId, bool isEnabled);
+
+               private:
+                       virtual Evas_Object *getContent(Evas_Object *parent, const char *part) override;
+                       virtual void onUnrealized() override;
+
+                       Evas_Object *createButton(Evas_Object *parent, const char *text,
+                                       const char *iconPath, Evas_Smart_Cb callback, void *data);
+                       Evas_Object *createAddFieldButton(Evas_Object *parent,
+                                       Model::ContactFieldId fieldId, const char *iconPath);
+
+                       void onAddField(Model::ContactFieldId fieldId);
+                       void onAddButtonPressed(Evas_Object *button, void *eventInfo);
+                       void onMoreButtonPressed(Evas_Object *button, void *eventInfo);
+
+                       AddFieldCallback m_OnAddField;
+                       bool m_AddFieldStates[Model::FieldEnd];
+                       Evas_Object *m_Buttons[Model::FieldEnd];
+               };
+       }
+}
+
+#endif /* CONTACTS_INPUT_ADD_FIELDS_ITEM_H */
index 00b511a..abe2838 100644 (file)
@@ -24,6 +24,7 @@
 namespace Ui
 {
        class Genlist;
+       class GenlistItem;
 }
 
 namespace Contacts
@@ -31,6 +32,7 @@ namespace Contacts
        namespace Input
        {
                class ContactObjectItem;
+               class AddFieldsItem;
 
                /**
                 * @brief Contact/My profile create/edit view.
@@ -58,16 +60,18 @@ namespace Contacts
                        virtual Evas_Object *onCreate(Evas_Object *parent) override;
                        virtual void onCreated() override;
                        virtual void onPageAttached() override;
-                       virtual void onMenuPressed() override;
 
                        ContactObjectItem *createFieldItem(Model::ContactFieldPtr field);
-                       ContactObjectItem *getNextFieldItem(unsigned fieldId);
+                       Ui::GenlistItem *getNextFieldItem(Model::ContactFieldId fieldId);
 
-                       Model::ContactFieldPtr addField(unsigned fieldId);
+                       Model::ContactFieldPtr addField(Model::ContactFieldId fieldId);
                        void removeField(Model::ContactFieldPtr field);
 
                        ContactObjectItem *addFieldItem(Model::ContactFieldPtr field);
-                       void removeFieldItem(ContactObjectItem *item, unsigned fieldId);
+                       void removeFieldItem(ContactObjectItem *item, Model::ContactFieldId fieldId);
+
+                       void onAddField(Model::ContactFieldId fieldId);
+                       void onRemoveField(ContactObjectItem *item, Model::ContactFieldPtr field);
 
                        void onDonePressed(Evas_Object *button, void *eventInfo);
                        void onCancelPressed(Evas_Object *button, void *eventInfo);
@@ -75,7 +79,9 @@ namespace Contacts
                        Model::Contact m_Contact;
                        Evas_Object *m_DoneButton;
                        Ui::Genlist *m_Genlist;
+
                        ContactObjectItem *m_Items[Model::FieldEnd];
+                       AddFieldsItem *m_AddFieldsItem;
                };
        }
 }
index 8362023..163bef7 100644 (file)
@@ -1,15 +1,18 @@
-set(EDCFILES input-item-layout.edc)
-set(EDJDIR "${RES_DIR}/input/edje")
+set(EDC_FILES input-item-layout.edc)
+set(EDJ_DIR "${RES_DIR}/input/edje")
+set(IMG_DIR "${RES_DIR}/input/images")
 
-foreach(EDCFILE ${EDCFILES})
-       get_filename_component(EDJFILE ${EDCFILE} NAME_WE)
-       set(EDJFILE ${EDJFILE}.edj)
+foreach(EDC_FILE ${EDC_FILES})
+       get_filename_component(EDJ_FILE ${EDC_FILE} NAME_WE)
+       set(EDJ_FILE ${EDJ_FILE}.edj)
 
-       add_custom_target(${EDJFILE}
-               COMMAND edje_cc -id .. edje/${EDCFILE} ${EDJFILE}
-               DEPENDS edje/${EDCFILE}
+       add_custom_target(${EDJ_FILE}
+               COMMAND edje_cc -id .. edje/${EDC_FILE} ${EDJ_FILE}
+               DEPENDS edje/${EDC_FILE}
        )
 
-       add_dependencies(${PROJECT_NAME} ${EDJFILE})
-       install(FILES ${EDJFILE} DESTINATION ${EDJDIR})
-endforeach(${EDCFILE})
+       add_dependencies(${PROJECT_NAME} ${EDJ_FILE})
+       install(FILES ${EDJ_FILE} DESTINATION ${EDJ_DIR})
+endforeach(${EDC_FILE})
+
+install(DIRECTORY images/ DESTINATION ${IMG_DIR})
index 333d5f0..22a6855 100644 (file)
 
 #include "InputPath.h"
 
-#define INPUT_ITEM_STYLE        "input_item"
+#define INPUT_ITEM_STYLE         "input_item"
+#define INPUT_ITEM_STYLE_BUTTONS "input_buttons"
 
-#define PART_LEFT               "swallow.left"
-#define PART_MIDDLE             "swallow.middle"
-#define PART_RIGHT              "swallow.right"
+#define PART_LEFT                "swallow.left"
+#define PART_MIDDLE              "swallow.middle"
+#define PART_RIGHT               "swallow.right"
+
+#define PART_BUTTON_1            "swallow.button.1"
+#define PART_BUTTON_2            "swallow.button.2"
+#define PART_BUTTON_3            "swallow.button.3"
+#define PART_BUTTON_4            "swallow.button.4"
 
 #endif /* INPUT_ITEM_LAYOUT_H */
index d7d123c..1338ddf 100644 (file)
@@ -23,4 +23,9 @@
 
 #define INPUT_ITEM_LAYOUT_EDJ   INPUT_EDJ_DIR"input-item-layout.edj"
 
+#define INPUT_ICON_ADD_NUMBER   INPUT_IMG_DIR"contacts_circle_btn_ic_call.png"
+#define INPUT_ICON_ADD_EMAIL    INPUT_IMG_DIR"contacts_circle_btn_ic_email.png"
+#define INPUT_ICON_ADD_NOTE     INPUT_IMG_DIR"contacts_circle_btn_ic_note.png"
+#define INPUT_ICON_ADD_MORE     INPUT_IMG_DIR"contacts_circle_btn_ic_more.png"
+
 #endif /* INPUT_PATH_H */
index 08ef6f6..7dec126 100644 (file)
@@ -24,6 +24,10 @@ collections
 
        group {
                name: "elm/genlist/item/"INPUT_ITEM_STYLE"/default";
+               alias: "elm/genlist/item_compress/"INPUT_ITEM_STYLE"/default";
+               alias: "elm/genlist/tree/"INPUT_ITEM_STYLE"/default";
+               alias: "elm/genlist/tree_compress/"INPUT_ITEM_STYLE"/default";
+
                data.item: "banded_bg_area" "swallow.bg";
                data.item: "contents" PART_LEFT" "PART_MIDDLE" "PART_RIGHT;
 
@@ -70,4 +74,58 @@ collections
                        }
                }
        }
+
+       group {
+               name: "elm/genlist/item/"INPUT_ITEM_STYLE_BUTTONS"/default";
+               alias: "elm/genlist/item_compress/"INPUT_ITEM_STYLE_BUTTONS"/default";
+
+               data.item: "banded_bg_area" "swallow.bg";
+               data.item: "contents" PART_BUTTON_1" "PART_BUTTON_2" "PART_BUTTON_3" "PART_BUTTON_4;
+
+               parts {
+                       part {
+                               name: "swallow.bg";
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                               }
+                       }
+                       part {
+                               name: PART_BUTTON_1;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1.relative: 0 0;
+                                       rel2.relative: 0.25 1;
+                               }
+                       }
+                       part {
+                               name: PART_BUTTON_2;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1.relative: 0.25 0;
+                                       rel2.relative: 0.5 1;
+                               }
+                       }
+                       part {
+                               name: PART_BUTTON_3;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1.relative: 0.5 0;
+                                       rel2.relative: 0.75 1;
+                               }
+                       }
+                       part {
+                               name: PART_BUTTON_4;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1.relative: 0.75 0;
+                                       rel2.relative: 1 1;
+                               }
+                       }
+               }
+       }
 }
diff --git a/lib-contact/res/input/images/contacts_circle_btn_ic_call.png b/lib-contact/res/input/images/contacts_circle_btn_ic_call.png
new file mode 100644 (file)
index 0000000..ca9ef39
Binary files /dev/null and b/lib-contact/res/input/images/contacts_circle_btn_ic_call.png differ
diff --git a/lib-contact/res/input/images/contacts_circle_btn_ic_email.png b/lib-contact/res/input/images/contacts_circle_btn_ic_email.png
new file mode 100644 (file)
index 0000000..19a804a
Binary files /dev/null and b/lib-contact/res/input/images/contacts_circle_btn_ic_email.png differ
diff --git a/lib-contact/res/input/images/contacts_circle_btn_ic_more.png b/lib-contact/res/input/images/contacts_circle_btn_ic_more.png
new file mode 100644 (file)
index 0000000..4b2e446
Binary files /dev/null and b/lib-contact/res/input/images/contacts_circle_btn_ic_more.png differ
diff --git a/lib-contact/res/input/images/contacts_circle_btn_ic_note.png b/lib-contact/res/input/images/contacts_circle_btn_ic_note.png
new file mode 100644 (file)
index 0000000..db0856c
Binary files /dev/null and b/lib-contact/res/input/images/contacts_circle_btn_ic_note.png differ
diff --git a/lib-contact/src/Contacts/Input/AddFieldsItem.cpp b/lib-contact/src/Contacts/Input/AddFieldsItem.cpp
new file mode 100644 (file)
index 0000000..d080de5
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "Contacts/Input/AddFieldsItem.h"
+#include "Contacts/Common/Strings.h"
+
+#include "App/Path.h"
+#include "Ui/Menu.h"
+#include "Utils/Callback.h"
+
+#include "InputItemLayout.h"
+
+using namespace Contacts::Input;
+using namespace Contacts::Model;
+
+namespace
+{
+       Elm_Genlist_Item_Class itc = Ui::GenlistItem::createItemClass(INPUT_ITEM_STYLE_BUTTONS);
+}
+
+AddFieldsItem::AddFieldsItem()
+       : GenlistItem(&itc), m_Buttons{nullptr}
+{
+       memset(m_AddFieldStates, true, sizeof(m_AddFieldStates));
+}
+
+void AddFieldsItem::setAddFieldCallback(AddFieldCallback callback)
+{
+       m_OnAddField = std::move(callback);
+}
+
+void AddFieldsItem::setAddFieldState(ContactFieldId fieldId, bool isEnabled)
+{
+       m_AddFieldStates[fieldId] = isEnabled;
+       elm_object_disabled_set(m_Buttons[fieldId], !isEnabled);
+}
+
+Evas_Object *AddFieldsItem::getContent(Evas_Object *parent, const char *part)
+{
+       if (strcmp(part, PART_BUTTON_1) == 0) {
+               return createAddFieldButton(parent, FieldNumber, INPUT_ICON_ADD_NUMBER);
+       } else if (strcmp(part, PART_BUTTON_2) == 0) {
+               return createAddFieldButton(parent, FieldEmail, INPUT_ICON_ADD_EMAIL);
+       } else if (strcmp(part, PART_BUTTON_3) == 0) {
+               return createAddFieldButton(parent, FieldNote, INPUT_ICON_ADD_NOTE);
+       } else if (strcmp(part, PART_BUTTON_4) == 0) {
+               return createButton(parent, "IDS_PB_BUTTON_MORE", INPUT_ICON_ADD_MORE,
+                               makeCallback(&AddFieldsItem::onMoreButtonPressed), this);
+       }
+
+       return nullptr;
+}
+
+void AddFieldsItem::onUnrealized()
+{
+       memset(m_Buttons, 0, sizeof(m_Buttons));
+}
+
+Evas_Object *AddFieldsItem::createButton(Evas_Object *parent, const char *text,
+               const char *iconPath, Evas_Smart_Cb callback, void *data)
+{
+       Evas_Object *image = elm_image_add(parent);
+       elm_image_file_set(image, App::getResourcePath(iconPath).c_str(), nullptr);
+
+       Evas_Object *button = elm_button_add(parent);
+       elm_object_style_set(button, "circle");
+       elm_object_translatable_text_set(button, text);
+       elm_object_part_content_set(button, "elm.swallow.content", image);
+       evas_object_smart_callback_add(button, "clicked", callback, data);
+
+       return button;
+}
+
+Evas_Object *AddFieldsItem::createAddFieldButton(Evas_Object *parent,
+               ContactFieldId fieldId, const char *iconPath)
+{
+       Evas_Object *button = createButton(parent, Common::getContactFieldName(fieldId), iconPath,
+                       makeCallback(&AddFieldsItem::onAddButtonPressed), this);
+       evas_object_smart_data_set(button, (void *) fieldId);
+       elm_object_disabled_set(button, !m_AddFieldStates[fieldId]);
+
+       m_Buttons[fieldId] = button;
+       return button;
+}
+
+void AddFieldsItem::onAddField(ContactFieldId fieldId)
+{
+       if (m_OnAddField) {
+               m_OnAddField(fieldId);
+       }
+}
+
+void AddFieldsItem::onAddButtonPressed(Evas_Object *button, void *eventInfo)
+{
+       onAddField((ContactFieldId) (long) evas_object_smart_data_get(button));
+}
+
+void AddFieldsItem::onMoreButtonPressed(Evas_Object *button, void *eventInfo)
+{
+       Ui::Menu *menu = new Ui::Menu();
+       menu->create(button);
+
+       for (unsigned id = FieldBegin; id < FieldEnd; ++id) {
+               ContactFieldId fieldId = ContactFieldId(id);
+               if (!m_Buttons[fieldId] && m_AddFieldStates[fieldId]) {
+                       menu->addItem(Common::getContactFieldName(fieldId),
+                               std::bind(&AddFieldsItem::onAddField, this, fieldId));
+               }
+       }
+
+       menu->show();
+}
index 89ca9ed..400819c 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include "Contacts/Input/InputView.h"
+#include "Contacts/Input/AddFieldsItem.h"
 #include "Contacts/Input/ContactTypedObjectItem.h"
 #include "Contacts/Model/ContactArray.h"
 #include "Contacts/Common/Strings.h"
 using namespace Contacts;
 using namespace Contacts::Input;
 using namespace Contacts::Model;
+using namespace std::placeholders;
 
 InputView::InputView(int recordId, Type type)
        : m_Contact(ContactObjectType(type), recordId),
-         m_DoneButton(nullptr), m_Genlist(nullptr), m_Items{nullptr}
+         m_DoneButton(nullptr), m_Genlist(nullptr),
+         m_Items{nullptr}, m_AddFieldsItem(nullptr)
 {
 }
 
@@ -47,6 +50,10 @@ Evas_Object *InputView::onCreate(Evas_Object *parent)
        m_Genlist->create(parent);
        elm_genlist_select_mode_set(m_Genlist->getEvasObject(), ELM_OBJECT_SELECT_MODE_NONE);
 
+       m_AddFieldsItem = new AddFieldsItem();
+       m_AddFieldsItem->setAddFieldCallback(std::bind(&InputView::onAddField, this, _1));
+       m_Genlist->insert(m_AddFieldsItem);
+
        return m_Genlist->getEvasObject();
 }
 
@@ -97,27 +104,6 @@ void InputView::onPageAttached()
        page->setContent("title_left_btn", cancelButton);
 }
 
-void InputView::onMenuPressed()
-{
-       Ui::Menu *menu = new Ui::Menu();
-       menu->create(getEvasObject());
-
-       for (auto &&field : m_Contact) {
-               ContactFieldId fieldId = ContactFieldId(field->getId());
-
-               if (field->getType() != TypeArray && m_Items[fieldId] != nullptr) {
-                       continue;
-               }
-
-               menu->addItem(Common::getContactFieldName(fieldId), [this, fieldId] {
-                       ContactObjectItem *item = addFieldItem(addField(fieldId));
-                       elm_genlist_item_bring_in(item->getObjectItem(), ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
-               });
-       }
-
-       menu->show();
-}
-
 ContactObjectItem *InputView::createFieldItem(Model::ContactFieldPtr field)
 {
        ContactObjectItem *item = nullptr;
@@ -127,48 +113,48 @@ ContactObjectItem *InputView::createFieldItem(Model::ContactFieldPtr field)
                item = new ContactObjectItem(std::move(field));
        }
 
-       item->setRemoveCallback([this](ContactObjectItem *item, ContactFieldPtr field) {
-               removeFieldItem(item, field->getId());
-               removeField(std::move(field));
-       });
+       item->setRemoveCallback(std::bind(&InputView::onRemoveField, this, _1, _2));
 
        return item;
 }
 
-ContactObjectItem *InputView::getNextFieldItem(unsigned fieldId)
+Ui::GenlistItem *InputView::getNextFieldItem(ContactFieldId fieldId)
 {
-       for (++fieldId; fieldId < Utils::count(m_Items); ++fieldId) {
-               if (m_Items[fieldId]) {
-                       return m_Items[fieldId];
+       for (unsigned id = fieldId + 1; id < Utils::count(m_Items); ++id) {
+               if (m_Items[id]) {
+                       return m_Items[id];
                }
        }
 
-       return nullptr;
+       return m_AddFieldsItem;
 }
 
-ContactFieldPtr InputView::addField(unsigned fieldId)
+ContactFieldPtr InputView::addField(ContactFieldId fieldId)
 {
        ContactFieldPtr parentField = m_Contact.getFieldById(fieldId);
        if (parentField->getType() == TypeArray) {
                return parentField->cast<ContactArray>().addField();
        } else {
+               m_AddFieldsItem->setAddFieldState(fieldId, false);
                return parentField;
        }
 }
 
 void InputView::removeField(ContactFieldPtr field)
 {
-       ContactFieldPtr parentField = m_Contact.getFieldById(field->getId());
+       ContactFieldId fieldId = ContactFieldId(field->getId());
+       ContactFieldPtr parentField = m_Contact.getFieldById(fieldId);
        if (parentField->getType() == TypeArray) {
                parentField->cast<ContactArray>().removeField(std::move(field));
        } else {
+               m_AddFieldsItem->setAddFieldState(fieldId, true);
                field->reset();
        }
 }
 
 ContactObjectItem *InputView::addFieldItem(Model::ContactFieldPtr field)
 {
-       unsigned fieldId = field->getId();
+       ContactFieldId fieldId = ContactFieldId(field->getId());
 
        ContactObjectItem *item = createFieldItem(std::move(field));
        m_Genlist->insert(item, nullptr, getNextFieldItem(fieldId));
@@ -180,7 +166,7 @@ ContactObjectItem *InputView::addFieldItem(Model::ContactFieldPtr field)
        return item;
 }
 
-void InputView::removeFieldItem(ContactObjectItem *item, unsigned fieldId)
+void InputView::removeFieldItem(ContactObjectItem *item, ContactFieldId fieldId)
 {
        if (item == m_Items[fieldId]) {
                ContactObjectItem *nextItem = static_cast<ContactObjectItem *>(item->getNextGroupItem());
@@ -192,6 +178,18 @@ void InputView::removeFieldItem(ContactObjectItem *item, unsigned fieldId)
        }
 }
 
+void InputView::onAddField(ContactFieldId fieldId)
+{
+       ContactObjectItem *item = addFieldItem(addField(fieldId));
+       elm_genlist_item_bring_in(item->getObjectItem(), ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
+}
+
+void InputView::onRemoveField(ContactObjectItem *item, ContactFieldPtr field)
+{
+       removeFieldItem(item, ContactFieldId(field->getId()));
+       removeField(std::move(field));
+}
+
 void InputView::onDonePressed(Evas_Object *button, void *eventInfo)
 {
        m_Contact.save();