TizenRefApp-5183 Implement object type selector UI control 75/53475/3
authorEugene Kurzberg <i.kurtsberg@samsung.com>
Mon, 7 Dec 2015 07:39:17 +0000 (09:39 +0200)
committerEugene Kurzberg <i.kurtsberg@samsung.com>
Mon, 7 Dec 2015 15:40:03 +0000 (17:40 +0200)
Change-Id: I567026982805ef982479d19fbebb407620a35e9a
Signed-off-by: Eugene Kurzberg <i.kurtsberg@samsung.com>
lib-common/inc/Ui/Hoversel.h
lib-common/inc/Utils/Range.h
lib-common/src/Ui/Hoversel.cpp
lib-contact/inc/Contacts/Input/ContactObjectCustomTypePopup.h [new file with mode: 0644]
lib-contact/inc/Contacts/Input/ContactObjectTypeControl.h [new file with mode: 0644]
lib-contact/inc/Contacts/Model/ContactObject.h
lib-contact/inc/Contacts/Model/ContactTextField.h
lib-contact/src/Contacts/Input/ContactObjectCustomTypePopup.cpp [new file with mode: 0644]
lib-contact/src/Contacts/Input/ContactObjectTypeControl.cpp [new file with mode: 0644]
lib-contact/src/Contacts/Model/ContactObject.cpp
lib-contact/src/Contacts/Model/ContactTextField.cpp

index f29d380..f474dbc 100644 (file)
@@ -29,8 +29,9 @@ namespace Ui
                /**
                 * @brief Item selection callback.
                 * @param[in]   Item value
+                * @return Whether to display selected item in hoversel button automatically
                 */
-               typedef std::function<void(int)> SelectedCallback;
+               typedef std::function<bool(int)> SelectedCallback;
 
                /**
                 * @brief Add item.
@@ -40,6 +41,12 @@ namespace Ui
                Elm_Object_Item *addItem(const char *text, int value);
 
                /**
+                * @brief Set text of currently selected item.
+                * @param[in]   text        Text to be displayed in hoversel button
+                */
+               void setText(const char *text);
+
+               /**
                 * @brief Set item selection callback.
                 * @param[in]   callback    Callback to be called after item was selected
                 */
index 8212ab5..9d7c3fe 100644 (file)
 namespace Utils
 {
        /**
+        * @brief Convenience wrapper around std::advance.
+        * @param[in]   iterator    Input iterator
+        * @param[in]   distance    Distance to advance iterator
+        * @return New iterator at @a distance from @a iterator.
+        */
+       template <typename Iter, typename Distance>
+       inline Iter advance(Iter iterator, Distance distance)
+       {
+               std::advance(iterator, distance);
+               return iterator;
+       }
+
+       /**
         * @brief Convenience wrapper for iterator pair.
         */
        template <typename Iter>
        class Range
        {
        public:
-               typedef typename std::iterator_traits<Iter>::difference_type difference_type;
+               typedef typename std::iterator_traits<Iter>::reference reference;
 
                Range() = default;
 
                /**
                 * @brief Create iterator range from static array.
+                * @param[in]   array   Static array
                 */
                template <typename T, size_t N>
                Range(T(&array)[N])
@@ -46,7 +60,7 @@ namespace Utils
                 * @param[in]   count   Count of elements until range's end
                 */
                Range(Iter begin, size_t count)
-                       : m_Begin(std::move(begin)), m_End(m_Begin) { std::advance(m_End, count); }
+                       : m_Begin(std::move(begin)), m_End(advance(m_Begin, count)) { }
 
                /**
                 * @brief Create iterator range from pair of iterators
@@ -64,7 +78,7 @@ namespace Utils
                /**
                 * @return Range element count.
                 */
-               difference_type count() const { return std::distance(m_Begin, m_End); }
+               size_t count() const { return std::distance(m_Begin, m_End); }
 
                /**
                 * @return Range begin iterator.
@@ -91,6 +105,13 @@ namespace Utils
                 */
                explicit operator bool() const { return !empty(); }
 
+               /**
+                * @brief Get range element by index.
+                * @param[in]   index   Element index
+                * @return Range element reference.
+                */
+               reference operator[](size_t index) const { return *advance(m_Begin, index); }
+
        private:
                Iter m_Begin;
                Iter m_End;
index 8f03be3..ea585ae 100644 (file)
@@ -31,6 +31,11 @@ Elm_Object_Item *Hoversel::addItem(const char *text, int value)
        return item;
 }
 
+void Hoversel::setText(const char *text)
+{
+       elm_object_translatable_text_set(getEvasObject(), text);
+}
+
 void Hoversel::setSelectedCallback(SelectedCallback callback)
 {
        m_OnSelected = std::move(callback);
@@ -59,12 +64,11 @@ Evas_Object *Hoversel::onCreate(Evas_Object *parent)
 
 void Hoversel::onSelected(Evas_Object *hoversel, Elm_Object_Item *item)
 {
-       const char *text = elm_object_item_translatable_text_get(item);
-       elm_object_translatable_text_set(hoversel, text);
-
        if (m_OnSelected) {
                int value = (long) elm_object_item_data_get(item);
-               m_OnSelected(value);
+               if (m_OnSelected(value)) {
+                       setText(elm_object_item_translatable_text_get(item));
+               }
        }
 }
 
diff --git a/lib-contact/inc/Contacts/Input/ContactObjectCustomTypePopup.h b/lib-contact/inc/Contacts/Input/ContactObjectCustomTypePopup.h
new file mode 100644 (file)
index 0000000..4df54a1
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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_CONTACT_OBJECT_CUSTOM_TYPE_POPUP_H
+#define CONTACTS_INPUT_CONTACT_OBJECT_CUSTOM_TYPE_POPUP_H
+
+#include "Ui/Popup.h"
+
+namespace Ui
+{
+       class Editfield;
+}
+
+namespace Contacts
+{
+       namespace Input
+       {
+               /**
+                * @brief Popup for editing object's custom type label.
+                *
+                * @see ContactTypedObject
+                */
+               class ContactObjectCustomTypePopup : public Ui::Popup
+               {
+               public:
+                       /**
+                        * @brief User input result callback.
+                        * @param[in]   Inputed custom type label
+                        */
+                       typedef std::function<void(const char *)> ResultCallback;
+
+                       ContactObjectCustomTypePopup();
+
+                       /**
+                        * @brief Set user input result callback.
+                        * @param[in]   callback    Callback to be called when user confirmed inputed label
+                        */
+                       void setResultCallback(ResultCallback callback);
+
+               private:
+                       virtual void onCreated() override;
+                       void onCreatePressed();
+                       static void onEntryChanged(Evas_Object *button, Evas_Object *entry, void *eventInfo);
+
+                       ResultCallback m_OnResult;
+                       Ui::Editfield *m_Editfield;
+               };
+
+       }
+}
+
+#endif /* CONTACTS_INPUT_CONTACT_OBJECT_CUSTOM_TYPE_POPUP_H */
diff --git a/lib-contact/inc/Contacts/Input/ContactObjectTypeControl.h b/lib-contact/inc/Contacts/Input/ContactObjectTypeControl.h
new file mode 100644 (file)
index 0000000..af9f7ae
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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_CONTACT_OBJECT_TYPE_CONTROL_H
+#define CONTACTS_INPUT_CONTACT_OBJECT_TYPE_CONTROL_H
+
+#include "Ui/Hoversel.h"
+
+namespace Contacts
+{
+       namespace Model
+       {
+               class ContactEnumField;
+               class ContactTextField;
+       }
+
+       namespace Input
+       {
+               /**
+                * @brief UI control for displaying and editing type of typed object.
+                *
+                * @see ContactTypedObject
+                */
+               class ContactObjectTypeControl : public Ui::Hoversel
+               {
+               public:
+                       /**
+                        * @brief Create type control
+                        * @param[in]   typeField   Object's "type" field
+                        * @param[in]   labelField  Object's custom type label field
+                        */
+                       ContactObjectTypeControl(Model::ContactEnumField *typeField,
+                                       Model::ContactTextField *labelField);
+
+               private:
+                       virtual void onCreated() override;
+                       bool onSelected(int value);
+
+                       Model::ContactEnumField *m_TypeField;
+                       Model::ContactTextField *m_LabelField;
+               };
+       }
+}
+
+#endif /* CONTACTS_INPUT_CONTACT_OBJECT_TYPE_CONTROL_H */
index 99407d5..90f3393 100644 (file)
@@ -42,6 +42,11 @@ namespace Contacts
                        virtual bool isEmpty() const override;
 
                        /**
+                        * @see ContactField::reset()
+                        */
+                       virtual void reset() override;
+
+                       /**
                         * @return Begin iterator.
                         */
                        ContactObjectIterator begin() const;
index c3b9d27..180233a 100644 (file)
@@ -40,6 +40,11 @@ namespace Contacts
                        virtual bool isEmpty() const override;
 
                        /**
+                        * @see ContactField::reset()
+                        */
+                       virtual void reset() override;
+
+                       /**
                         * @return Text field value.
                         */
                        const char *getValue() const;
diff --git a/lib-contact/src/Contacts/Input/ContactObjectCustomTypePopup.cpp b/lib-contact/src/Contacts/Input/ContactObjectCustomTypePopup.cpp
new file mode 100644 (file)
index 0000000..5e3da13
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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/ContactObjectCustomTypePopup.h"
+#include "Ui/Editfield.h"
+
+using namespace Contacts::Input;
+
+ContactObjectCustomTypePopup::ContactObjectCustomTypePopup()
+       : m_Editfield(nullptr)
+{
+}
+
+void ContactObjectCustomTypePopup::setResultCallback(ResultCallback callback)
+{
+       m_OnResult = std::move(callback);
+}
+
+void ContactObjectCustomTypePopup::onCreated()
+{
+       setTitle("IDS_PB_HEADER_ENTER_CUSTOM_LABEL_ABB");
+
+       m_Editfield = Ui::Editfield::create(getEvasObject(), "IDS_MF_POP_INPUT_TEXT");
+       setContent(m_Editfield->getEvasObject());
+       addButton("IDS_PB_BUTTON_CANCEL");
+       Evas_Object *button = addButton("IDS_PB_SK_CREATE_ABB", [this] {
+               onCreatePressed();
+               return true;
+       });
+       elm_object_disabled_set(button, EINA_TRUE);
+
+       Evas_Object *entry = m_Editfield->getEntry();
+       elm_entry_input_panel_return_key_autoenabled_set(entry, EINA_TRUE);
+       elm_entry_input_panel_return_key_type_set(entry, ELM_INPUT_PANEL_RETURN_KEY_TYPE_DONE);
+       evas_object_smart_callback_add(entry, "changed",
+                       (Evas_Smart_Cb) &ContactObjectCustomTypePopup::onEntryChanged, button);
+       elm_object_focus_set(entry, EINA_TRUE);
+}
+
+void ContactObjectCustomTypePopup::onCreatePressed()
+{
+       if (m_OnResult) {
+               char *text = elm_entry_markup_to_utf8(elm_entry_entry_get(m_Editfield->getEntry()));
+               m_OnResult(text);
+               free(text);
+       }
+}
+
+void ContactObjectCustomTypePopup::onEntryChanged(Evas_Object *button, Evas_Object *entry, void *eventInfo)
+{
+       elm_object_disabled_set(button, elm_entry_is_empty(entry));
+}
diff --git a/lib-contact/src/Contacts/Input/ContactObjectTypeControl.cpp b/lib-contact/src/Contacts/Input/ContactObjectTypeControl.cpp
new file mode 100644 (file)
index 0000000..ccc948c
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 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/ContactObjectTypeControl.h"
+#include "Contacts/Input/ContactObjectCustomTypePopup.h"
+#include "Contacts/Model/ContactEnumField.h"
+#include "Contacts/Model/ContactTextField.h"
+#include "Contacts/Common/Strings.h"
+
+using namespace Contacts::Input;
+using namespace Contacts::Model;
+
+ContactObjectTypeControl::ContactObjectTypeControl(ContactEnumField *typeField,
+               ContactTextField *labelField)
+       : m_TypeField(typeField), m_LabelField(labelField)
+{
+}
+
+void ContactObjectTypeControl::onCreated()
+{
+       ContactEnumType enumType = (ContactEnumType) m_TypeField->getSubType();
+       auto names = Common::getContactEnumValueNames(enumType);
+       auto values = m_TypeField->getValues();
+       int currentValue = m_TypeField->getValue();
+
+       for (size_t i = 0; i < values.count(); ++i) {
+               addItem(names[i], values[i]);
+
+               if (values[i] == currentValue) {
+                       setText(names[i]);
+               }
+       }
+
+       if (m_TypeField->hasCustomValue()) {
+               setText(m_LabelField->getValue());
+       }
+
+       setSelectedCallback([this](int value) {
+               return onSelected(value);
+       });
+}
+
+bool ContactObjectTypeControl::onSelected(int value)
+{
+       if (value == m_TypeField->getCustomValue()) {
+               auto popup = new ContactObjectCustomTypePopup();
+               popup->setResultCallback([this, value](const char *label) {
+                       m_TypeField->setValue(value);
+                       m_LabelField->setValue(label);
+                       setText(label);
+               });
+
+               popup->create(getEvasObject());
+               return false;
+       } else {
+               if (m_TypeField->hasCustomValue()) {
+                       m_LabelField->reset();
+               }
+
+               m_TypeField->setValue(value);
+               return true;
+       }
+}
index c7c49ef..9f6255e 100644 (file)
@@ -34,6 +34,13 @@ bool ContactObject::isEmpty() const
        return isEmpty;
 }
 
+void ContactObject::reset()
+{
+       for (auto &&field : *this) {
+               field->reset();
+       }
+}
+
 ContactObjectIterator ContactObject::begin() const
 {
        return ContactObjectIterator(*this, 0);
index d00f836..c5ceaa2 100644 (file)
@@ -26,6 +26,11 @@ bool ContactTextField::isEmpty() const
        return !(value && *value);
 }
 
+void ContactTextField::reset()
+{
+       setValue("");
+}
+
 const char *ContactTextField::getValue() const
 {
        char *value = nullptr;