World Clock: Reorder view implemented 86/92186/5
authorRadoslaw Czerski <r.czerski@samsung.com>
Thu, 27 Oct 2016 10:36:31 +0000 (12:36 +0200)
committerLukasz Stanislawski <l.stanislaws@samsung.com>
Fri, 28 Oct 2016 12:39:09 +0000 (05:39 -0700)
Change-Id: I3ba390759f255bbecc72c4f714824cdee4c7854a
Signed-off-by: Radoslaw Czerski <r.czerski@samsung.com>
16 files changed:
clock/inc/Controller/MainController.h
clock/inc/Model/WorldClock.h
clock/inc/Model/WorldClockEvents.h
clock/inc/Presenter/WorldClockPresenter.h
clock/inc/Presenter/WorldClockReorderPresenter.h [new file with mode: 0644]
clock/inc/View/WorldClockReorderView.h [new file with mode: 0644]
clock/inc/View/WorldClockView.h
clock/res/edje/WorldClockDeleteReorderList.edc [moved from clock/res/edje/WorldClockDeleteList.edc with 94% similarity]
clock/res/images/world_clock_reorder.png [new file with mode: 0644]
clock/src/Controller/MainController.cpp
clock/src/Model/WorldClock.cpp
clock/src/Presenter/WorldClockPresenter.cpp
clock/src/Presenter/WorldClockReorderPresenter.cpp [new file with mode: 0644]
clock/src/View/WorldClockDeleteItemsView.cpp
clock/src/View/WorldClockReorderView.cpp [new file with mode: 0644]
clock/src/View/WorldClockView.cpp

index 7d5c4d5..cf8760f 100644 (file)
@@ -30,6 +30,7 @@
 #include "View/StopWatchView.h"
 #include "View/TimerView.h"
 #include "View/WorldClockView.h"
+#include "View/WorldClockReorderView.h"
 
 #include "Model/AlarmProvider.h"
 #include "Model/StopWatch.h"
@@ -41,6 +42,7 @@
 #include "Presenter/TimerPresenter.h"
 #include "Presenter/WorldClockPresenter.h"
 #include "Presenter/WorldClockDeletePresenter.h"
+#include "Presenter/WorldClockReorderPresenter.h"
 
 
 /**
@@ -128,6 +130,12 @@ namespace controller {
                         */
                        void CreateNewWorldClockDeletePage(utils::Event &e);
 
+                       /**
+                        * @brief Creates new "Reorder" page in world clock;
+                        * @param e event data
+                        */
+                       void CreateNewWorldClockReorderPage(utils::Event &e);
+
                        model::WorldClock *world_clock_model_;
                        model::StopWatch *stop_watch_model_;
                        model::Timer *timer_model_;
@@ -139,12 +147,14 @@ namespace controller {
                        presenter::EditAlarmPresenter *edit_presenter_;
                        presenter::DeleteAlarmPresenter *delete_presenter_;
                        presenter::WorldClockDeletePresenter *world_clock_delete_presenter_;
+                       presenter::WorldClockReorderPresenter *world_clock_reorder_presenter_;
 
                        view::MainView main_view_;
 
                        view::EditAlarmView edit_page_;
                        view::DeleteAlarmView delete_page_;
                        view::WorldClockDeleteItemsView world_clock_delete_page_;
+                       view::WorldClockReorderView world_clock_reorder_page_;
 
                        /**
                         * @brief Creates new "Edit" alarm page.
index d11b575..c849162 100644 (file)
@@ -38,11 +38,20 @@ namespace model {
        class WorldClock {
                public:
 
-                       enum class SignalType {
+                       /**
+                        * @brief enumeration for signals that passes parameter
+                        * @details Only const model::Location & parameter type is allowed
+                        */
+                       enum class ParameterSignalType {
                                USER_LOCATION_REMOVED,
                                MAX
                        };
 
+                       enum class SignalType {
+                               CUSTOM_LIST_CHANGED,
+                               MAX
+                       };
+
                        /**
                         * @brief Enumeration for direction of time zone shift.
                         */
@@ -67,6 +76,16 @@ namespace model {
                        std::vector<const model::Location *> user_locations_;
 
                        /**
+                        * @brief Gets user locations list.
+                        */
+                       std::vector<const model::Location *> GetUserLocations() const;
+
+                       /**
+                        * @brief Sets user locations list.
+                        * @remarks It emits CUSTOM_LIST_CHANGED signal
+                        */
+                       void SetUserLocations(std::vector<const model::Location *> locations);
+                       /**
                         * @brief Adds location to UserLocations list.
                         * @remarks The location is retrieved from called Worldclock-efl app
                         *
@@ -153,11 +172,20 @@ namespace model {
 
                        /**
                         * @brief Registers signal handler
+                        * @brief func must have one parameter. For now only const model::Location & type is supported
                         *
                         * @param signal signal type
                         * @param func function to be called when registered signal is emitted.
                         */
-                       void RegisterSignalHandler(SignalType signal, std::function<void(const model::Location &)> func);
+                       void RegisterSignalHandler(ParameterSignalType signal, std::function<void(const model::Location &)> func);
+
+                       /**
+                        * @brief Registers signal handler
+                        *
+                        * @param signal signal type
+                        * @param func function to be called when registered signal is emitted.
+                        */
+                       void RegisterSignalHandler(SignalType signal, std::function<void(void)> func);
                private:
 
                        enum ItemKeyType {
@@ -182,7 +210,9 @@ namespace model {
                         */
                        static std::vector<Timezone> time_zones_;
 
-                       std::vector<std::function<void(const model::Location &)>> signals_;;
+                       std::vector<std::function<void(const model::Location &)>> parameter_signals_;
+
+                       std::vector<std::function<void(void)>> signals_;
 
                        /**
                         * @brief Saves items list state using app_preferences API
@@ -229,7 +259,15 @@ namespace model {
                         * @param s signal
                         * @param location location to pass to function registered for given signal
                         */
-                       void EmitSignal(SignalType s, const model::Location &location);
+                       void EmitSignal(ParameterSignalType s, const model::Location &location);
+
+                       /**
+                        * @brief Emits signal s
+                        * @param s signal
+                        * @param location location to pass to function registered for given signal
+                        */
+                       void EmitSignal(SignalType s);
+
        };
 } /* model */
 
index 3685393..56be7b3 100644 (file)
 
 namespace model {
 
-       class WorldClockDeleteRequestEvent : public utils::Event {
+       class WorldClockDeleteRequestEvent: public utils::Event {
+       };
+
+       class WorldClockReorderRequestEvent: public utils::Event {
        };
 }
 
index a817359..f8fa008 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef _CLOCK_PRESENTER_WORLDCLOCK_H_
 #define _CLOCK_PRESENTER_WORLDCLOCK_H_
 
+#include <View/WorldClockReorderView.h>
 #include "View/WorldClockView.h"
 #include "View/WorldClockDeleteItemsView.h"
 #include "Utils/EventBus.h"
@@ -60,6 +61,12 @@ namespace presenter {
                         */
                        void OnMoreDeleteButtonClicked();
 
+/**
+                        * @brief Invoked when Reorder option is chosen on "more" popup.
+                        * @details Created Reorder View
+                        */
+                       void OnMoreReorderButtonClicked();
+
                        void OnMapViewUpdateRequest();
                        void OnItemAdded();
 
@@ -69,6 +76,11 @@ namespace presenter {
                         */
                        void OnItemDeleted(const model::Location &location);
 
+                       /**
+                        * @brief Updates custom list.
+                        */
+                       void OnCustomListChanged();
+
        };
 }
 
diff --git a/clock/inc/Presenter/WorldClockReorderPresenter.h b/clock/inc/Presenter/WorldClockReorderPresenter.h
new file mode 100644 (file)
index 0000000..4ea3752
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016 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 _CLOCK_PRESENTER_WORLDCLOCKREORDER_H_
+#define _CLOCK_PRESENTER_WORLDCLOCKREORDER_H_
+
+#include "View/WorldClockReorderView.h"
+#include "Model/WorldClock.h"
+
+namespace presenter {
+
+       class WorldClockReorderPresenter {
+               public:
+                       /**
+                        * @brief Creates presenter for Reorder view
+                        *
+                        * @param view the view
+                        * @param model world clock data model
+                        */
+                       WorldClockReorderPresenter(view::WorldClockReorderView *view, model::WorldClock *model);
+
+                       /**
+                        * @brief Destructor
+                        */
+                       ~WorldClockReorderPresenter();
+
+               private:
+
+                       /**
+                        * @brief data model
+                        */
+                       model::WorldClock *model_;
+
+                       /**
+                        * @brief reorder view genlist Item data
+                        */
+                       view::WorldClockReorderView *reorder_view_;
+
+                       /**
+                        * @brief Invoked every time list is reordered in reorder view.
+                        */
+                       void OnListReordered();
+
+                       /**
+                        * @brief Invoked when "back arrow" button is clicked.
+                        * @details Pops Reorder View page
+                        */
+                       void OnBackClicked();
+       };
+}
+
+#endif /* _CLOCK_PRESENTER_WORLDCLOCKREORDER_H_ */
diff --git a/clock/inc/View/WorldClockReorderView.h b/clock/inc/View/WorldClockReorderView.h
new file mode 100644 (file)
index 0000000..fe1c61e
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2016 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 _CLOCK_VIEW_WORLDCLOCKREORDERITEMS_H_
+#define _CLOCK_VIEW_WORLDCLOCKREORDERITEMS_H_
+
+#include "View/PageView.h"
+#include "Model/Location.h"
+#include "Utils/Time.h"
+
+namespace view {
+
+       class WorldClockReorderView: public PageView {
+
+               public:
+
+                       /**
+                        * @brief Enumeration for callbacks signals
+                        */
+                       enum class Signals {
+                               LIST_REORDERED,      //!< LIST_REORDERED
+                               BUTTON_BACK_CLICKED, //!< BUTTON_BACK_CLICKED
+                               MAX                  //!< MAX
+                       };
+
+                       /**
+                        * @brief Creates Class object, push new page and invokes CreateContent().
+                        */
+                       WorldClockReorderView(ui::IView &main);
+
+                       /**
+                        * @brief Destroy all resources that can not be deleted automatically
+                        */
+                       ~WorldClockReorderView();
+
+                       /**
+                        * @brief Gets evas object of the page content -> genlist
+                        * @return the object
+                        */
+                       Evas_Object *GetEvasObject() override;
+
+                       /**
+                        * @brief Registers signals
+                        *
+                        * @param s signal enumerator
+                        * @param func function invoked when the signal will be emitted
+                        */
+                       void RegisterSignalHandler(Signals s, std::function<void(void)>func);
+
+                       /**
+                        * @brief Appends items(Locations) from given list to delete View genlist
+                        * @details The list is identical with user_locations_ list
+                        * @param locations list of locations
+                        */
+                       void AppendItems(std::vector<const model::Location *> locations);
+
+                       /**
+                        * @brief Gets reordered locations list
+                        *
+                        * @return reordered locations list
+                        */
+                       std::vector<const model::Location *> GetReorderedLocations();
+
+               protected:
+                       /**
+                        * @brief Creates main content of the Destroy View page
+                        */
+                       void CreateContent(Evas_Object *parent) override;
+
+                       /**
+                        * @brief Destroys main content of the Destroy View page
+                        */
+                       void DestroyContent() override;
+               private:
+
+                       /**
+                        * @brief Main content - genlist
+                        */
+                       Evas_Object *content_;
+
+                       /**
+                        * @brief Evas object of "Cancel" button
+                        */
+                       Evas_Object *left_button_;
+
+                       /**
+                        * @brief Item class for the main content genlist
+                        */
+                       static Elm_Genlist_Item_Class world_clock_reorder_items_view_itc_;
+
+                       /**
+                        * @brief list of signals
+                        */
+                       std::vector<std::function<void(void)>> signals_
+                                       = std::vector<std::function<void(void)>>((int)Signals::MAX, nullptr);
+
+                       /**
+                        * @brief Gets content for genlist item part
+                        * @param data user data
+                        * @param obj item object
+                        * @param part part related to content to get
+                        * @return Object of content that will be swallowed to the part
+                        */
+                       static Evas_Object *ContentGet(void *data, Evas_Object *obj, const char *part);
+
+                       /**
+                        * @brief Gets text for genlist item part
+                        * @param data user data
+                        * @param obj item object
+                        * @param part part related to text to get
+                        * @return text to set to the textblock part
+                        */
+                       static char *TextGet(void *data, Evas_Object *obj, const char *part);
+
+                       /**
+                        * @brief Deletes all resources of the item that cannot be deleted automatically
+                        * @param data user data
+                        * @param obj item object
+                        */
+                       static void Del(void *data, Evas_Object *obj);
+
+                       /**
+                        * @brief Creates evas object for time
+                        * @param parent parent
+                        * @return the object
+                        */
+                       static Evas_Object *CreateTimeObject(Evas_Object *parent, utils::Time t);
+
+                       /**
+                        * @brief Creates evas object for meridiem
+                        * @param parent parent
+                        * @return the object
+                        */
+                       static Evas_Object *CreateXMeridiemObject(Evas_Object *parent, utils::Time t);
+
+                       /**
+                        * @brief Creates evas object for padding
+                        * @param parent parent
+                        * @return the object
+                        */
+                       static Evas_Object *CreatePaddingObject(Evas_Object *parent, int width);
+
+                       /**
+                        * @brief emits signal
+                        * @details it cause invocation of registered function
+                        * @param s signal enumerator
+                        */
+                       void EmitSignal(Signals s);
+
+                       /**
+                        * @brief Emits LIST_REORDERED signal
+                        * @remarks Invoked everytime list is reordered
+                        */
+                       static void OnListReordered(void *data, Evas_Object *obj, void *event_info);
+
+                       /**
+                        * @brief Emits BUTTON_BACK_CLICKED signal
+                        * @remarks Invoked by clicking BACK naviframe button or back hardware key
+                        */
+                       static void OnBackButtonClicked(void *data, Evas_Object *obj, void *event_info);
+       };
+
+} /* view */
+
+
+#endif /* _CLOCK_VIEW_WORLDCLOCKREORDERITEMS_H_ */
index d96ed43..b9eb067 100644 (file)
@@ -32,6 +32,7 @@ namespace view {
                BUTTON_RIGHT_ARROW_CLICKED,
                BUTTON_MORE_CLICKED,
                BUTTON_MORE_DELETE_CLICKED,
+               BUTTON_MORE_REORDER_CLICKED,
 
                CUSTOM_LIST_ITEM_CLICKED,
                CUSTOM_LIST_ITEM_ADD,
@@ -62,6 +63,12 @@ namespace view {
 
                        void AppendItemToCustomList(const model::Location *location);
                        void RemoveItem(const model::Location &location);
+
+                       /**
+                        * @brief Clears user locations list
+                        */
+                       void ClearAllItems();
+
                        const model::Location *GetLastClickedItem();
                        const model::Location *GetLocationToAdd();
 
similarity index 94%
rename from clock/res/edje/WorldClockDeleteList.edc
rename to clock/res/edje/WorldClockDeleteReorderList.edc
index 0dff8ea..56e48a9 100644 (file)
@@ -2,7 +2,7 @@
 collections {
        base_scale: 2.6;
 
-       group { name: "elm/genlist/item/worldclock.delete.list/default";
+       group { name: "elm/genlist/item/worldclock.delete/reorder.list/default";
                styles {
                        style { name: "date_ATO042";
                                base: "font=Tizen:style=Regular color=#808080ff font_size=30 align=left";
@@ -16,7 +16,7 @@ collections {
                }
                data.item: "banded_bg_area" "elm.swallow.bg";
                data.item: "texts" "ampm date city.country gmt.offset.desc";
-               data.item: "contents" "time check";
+               data.item: "contents" "time sw.item";
                parts {
                        spacer { "base"; scale;
                                desc { "default";
@@ -116,7 +116,8 @@ collections {
                                        rel2.to: "base";
                                }
                        }
-                       swallow { "check";
+                       swallow { "sw.item";
+                               mouse;
                                desc { "default";
                                        min: 80 80;
                                        max: 80 80;
@@ -142,7 +143,7 @@ collections {
                                        }
                                        rel2 {
                                                relative: 0.0 1.0;
-                                               to_x: "check";
+                                               to_x: "sw.item";
                                        }
                                        text.style: "city_country_ATO043";
                                }
@@ -159,7 +160,7 @@ collections {
                                        }
                                        rel2 {
                                                relative: 0.0 1.0;
-                                               to_x: "check";
+                                               to_x: "sw.item";
                                        }
                                        text {
                                                style: "gmt_offset_desc_ATO044";
diff --git a/clock/res/images/world_clock_reorder.png b/clock/res/images/world_clock_reorder.png
new file mode 100644 (file)
index 0000000..b8f0901
Binary files /dev/null and b/clock/res/images/world_clock_reorder.png differ
index ec382cb..a22078b 100644 (file)
@@ -28,6 +28,9 @@
 #include "View/WorldClockDeleteItemsView.h"
 #include "Presenter/WorldClockDeletePresenter.h"
 
+#include "View/WorldClockReorderView.h"
+#include "Presenter/WorldClockReorderPresenter.h"
+
 using namespace controller;
 using namespace view;
 using namespace utils;
@@ -43,8 +46,9 @@ MainController &MainController::GetInstance()
 
 MainController::MainController() :
        edit_page_(main_view_), delete_page_(main_view_), world_clock_delete_page_(main_view_),
-       delete_presenter_(nullptr), edit_presenter_(nullptr),
-       world_clock_delete_presenter_(nullptr), initialized_(false)
+       world_clock_reorder_page_(main_view_), delete_presenter_(nullptr),
+       edit_presenter_(nullptr), world_clock_delete_presenter_(nullptr),
+       world_clock_reorder_presenter_(nullptr), initialized_(false)
 {
 }
 
@@ -86,7 +90,11 @@ int MainController::Init()
        listeners_.push_back(utils::EventBus::AddListener<WorldClockDeleteRequestEvent>(
                        std::bind(&MainController::CreateNewWorldClockDeletePage, this, _1)));
 
+       listeners_.push_back(utils::EventBus::AddListener<WorldClockReorderRequestEvent>(
+                       std::bind(&MainController::CreateNewWorldClockReorderPage, this, _1)));
+
        initialized_ = true;
+
        return 0;
 }
 
@@ -111,6 +119,7 @@ void MainController::Deinit()
 
 void MainController::CreateNewAlarmPage(Event &e)
 {
+
        delete edit_presenter_;
 
        edit_presenter_ = new EditAlarmPresenter(nullptr, edit_page_);
@@ -137,5 +146,11 @@ void MainController::CreateNewWorldClockDeletePage(utils::Event &e)
        delete world_clock_delete_presenter_;
 
        world_clock_delete_presenter_ = new WorldClockDeletePresenter(&world_clock_delete_page_, world_clock_model_);
+}
+
+void MainController::CreateNewWorldClockReorderPage(Event &e)
+{
+       delete world_clock_reorder_presenter_;
 
+       world_clock_reorder_presenter_ = new WorldClockReorderPresenter(&world_clock_reorder_page_, world_clock_model_);
 }
index 7fb1b2d..f7f5b81 100644 (file)
@@ -137,6 +137,7 @@ std::vector<Timezone> WorldClock::time_zones_ = {
 
 WorldClock::WorldClock()
 {
+       parameter_signals_.resize((int)ParameterSignalType::MAX);
        signals_.resize((int)SignalType::MAX);
        LoadItemsList();
 
@@ -234,6 +235,19 @@ void model::WorldClock::MoveCurrentTimezone(Direction direction)
        }
 }
 
+std::vector<const model::Location *> WorldClock::GetUserLocations() const
+{
+       return user_locations_;
+}
+
+void WorldClock::SetUserLocations(std::vector<const model::Location *> locations)
+{
+       DBG();
+       user_locations_ = locations;
+
+       EmitSignal(SignalType::CUSTOM_LIST_CHANGED);
+}
+
 bool WorldClock::AddUserLocation(const model::Location *l)
 {
        if (!user_locations_.empty()) {
@@ -256,7 +270,7 @@ void WorldClock::RemoveUserLocations(const std::vector<const model::Location *>
                for (auto it = user_locations_.begin(); it != user_locations_.end(); ++it) {
 
                        if (!((*it)->name.compare(d_it->name)) && !((*it)->country.compare(d_it->country))) {
-                               EmitSignal(SignalType::USER_LOCATION_REMOVED, **it);
+                               EmitSignal(ParameterSignalType::USER_LOCATION_REMOVED, **it);
                                user_locations_.erase(it);
                                break;
                        }
@@ -399,14 +413,26 @@ const model::Location *WorldClock::LoadItem(int i)
        return location;
 }
 
-void WorldClock::RegisterSignalHandler(SignalType signal, std::function<void(const model::Location &)> func)
+void WorldClock::RegisterSignalHandler(ParameterSignalType signal, std::function<void(const model::Location &)> func)
+{
+       parameter_signals_.at((int)signal) = func;
+}
+
+void WorldClock::EmitSignal(ParameterSignalType signal, const model::Location &location)
+{
+       if (parameter_signals_.at((int)signal) != nullptr) {
+               parameter_signals_.at((int)signal)(location);
+       }
+}
+
+void WorldClock::RegisterSignalHandler(SignalType signal, std::function<void(void)> func)
 {
        signals_.at((int)signal) = func;
 }
 
-void WorldClock::EmitSignal(SignalType signal, const model::Location &location)
+void WorldClock::EmitSignal(SignalType signal)
 {
        if (signals_.at((int)signal) != nullptr) {
-               signals_.at((int)signal)(location);
+               signals_.at((int)signal)();
        }
 }
index 5a59a17..c7ca481 100644 (file)
@@ -44,10 +44,15 @@ WorldClockPresenter::WorldClockPresenter(WorldClockView *view, WorldClock *model
                        WorldClockSignals::BUTTON_MORE_CLICKED);
        view_->RegisterSignal(std::bind(&WorldClockPresenter::OnMoreDeleteButtonClicked, this),
                        WorldClockSignals::BUTTON_MORE_DELETE_CLICKED);
+       view_->RegisterSignal(std::bind(&WorldClockPresenter::OnMoreReorderButtonClicked, this),
+                               WorldClockSignals::BUTTON_MORE_REORDER_CLICKED);
 
-       model_->RegisterSignalHandler(WorldClock::SignalType::USER_LOCATION_REMOVED,
+       model_->RegisterSignalHandler(WorldClock::ParameterSignalType::USER_LOCATION_REMOVED,
                        std::bind(&WorldClockPresenter::OnItemDeleted, this, _1));
 
+       model_->RegisterSignalHandler(WorldClock::SignalType::CUSTOM_LIST_CHANGED,
+                       std::bind(&WorldClockPresenter::OnCustomListChanged, this));
+
        view_->UpdateMapAndTimezoneDetails(model_->GetCurrentTimezone());
 
        for (auto it = model_->user_locations_.begin(); it != model_->user_locations_.end(); it++)
@@ -134,6 +139,16 @@ void WorldClockPresenter::OnItemDeleted(const model::Location &location)
        UpdateEmptyListBackground();
 }
 
+void WorldClockPresenter::OnCustomListChanged()
+{
+       view_->ClearAllItems();
+
+       for (auto it: model_->GetUserLocations())
+               view_->AppendItemToCustomList((it));
+
+       UpdateEmptyListBackground();
+}
+
 void WorldClockPresenter::OnMoreButtonClicked()
 {
        int cnt = view_->GetItemsCount();
@@ -159,4 +174,10 @@ void WorldClockPresenter::OnMoreDeleteButtonClicked()
        EventBus::FireEvent(ev);
 }
 
+void WorldClockPresenter::OnMoreReorderButtonClicked()
+{
+       WorldClockReorderRequestEvent ev;
+       EventBus::FireEvent(ev);
+}
+
 } /* presenter */
diff --git a/clock/src/Presenter/WorldClockReorderPresenter.cpp b/clock/src/Presenter/WorldClockReorderPresenter.cpp
new file mode 100644 (file)
index 0000000..10762a5
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 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 "Presenter/WorldClockReorderPresenter.h"
+#include "Utils/Log.h"
+
+namespace presenter {
+using namespace view;
+
+
+WorldClockReorderPresenter::WorldClockReorderPresenter(
+        WorldClockReorderView *view, model::WorldClock *model) :
+                       reorder_view_(view), model_(model)
+{
+       reorder_view_->RegisterSignalHandler(WorldClockReorderView::Signals::LIST_REORDERED,
+                       std::bind(&WorldClockReorderPresenter::OnListReordered, this));
+
+       reorder_view_->RegisterSignalHandler(WorldClockReorderView::Signals::BUTTON_BACK_CLICKED,
+                       std::bind(&WorldClockReorderPresenter::OnBackClicked, this));
+
+       reorder_view_->PushPage();
+       reorder_view_->AppendItems(model_->user_locations_);
+}
+
+WorldClockReorderPresenter::~WorldClockReorderPresenter()
+{
+}
+
+void WorldClockReorderPresenter::OnListReordered()
+{
+       model_->SetUserLocations(reorder_view_->GetReorderedLocations());
+}
+
+void WorldClockReorderPresenter::OnBackClicked()
+{
+       reorder_view_->PopPage();
+}
+
+} /** presenter **/
index fe7b7af..9d946a8 100644 (file)
@@ -49,7 +49,7 @@ struct LocationDeleteItemData {
 /* Delete list View */
 
 Elm_Genlist_Item_Class WorldClockDeleteItemsView::world_clock_delete_view_itc_= {
-       .item_style = "worldclock.delete.list",
+       .item_style = "worldclock.delete/reorder.list",
        .func.content_get = WorldClockDeleteItemsView::ContentGet,
        .func.text_get = WorldClockDeleteItemsView::TextGet,
        .func.del = WorldClockDeleteItemsView::Del
@@ -131,7 +131,7 @@ Evas_Object *WorldClockDeleteItemsView::ContentGet(void *data, Evas_Object *obj,
 
                return ldid->time;
 
-       } else if (!strcmp(part, "check")) {
+       } else if (!strcmp(part, "sw.item")) {
                ldid->checkbox = elm_check_add(obj);
                evas_object_propagate_events_set(ldid->checkbox, EINA_FALSE);
                elm_check_state_set(ldid->checkbox, ldid->selected ? EINA_TRUE : EINA_FALSE);
@@ -191,7 +191,6 @@ Evas_Object *WorldClockDeleteItemsView::CreateXMeridiemObject(Evas_Object *paren
        Evas_Object *ampm = elm_label_add(parent);
        evas_object_size_hint_align_set(ampm, EVAS_HINT_FILL, 0.75);
 
-
        std::string meridiem = t.Format("a");
        char ampm_formatted[MAX_STYLE_LEN] = { 0, };
        snprintf(ampm_formatted, sizeof(ampm_formatted),
@@ -239,7 +238,7 @@ void WorldClockDeleteItemsView::CreateContent(Evas_Object *parent)
        if (!extension_init) {
                elm_theme_extension_add(NULL,
                                Utils::GetAppResourcePath(Utils::APP_DIR_RESOURCE,
-                               "edje/WorldClockDeleteList.edj"));
+                               "edje/WorldClockDeleteReorderList.edj"));
                extension_init = true;
        }
        left_button_ = elm_button_add(parent);
diff --git a/clock/src/View/WorldClockReorderView.cpp b/clock/src/View/WorldClockReorderView.cpp
new file mode 100644 (file)
index 0000000..d3d8710
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2016 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 <efl_extension.h>
+#include <View/WorldClockReorderView.h>
+#include <vector>
+#include <sstream>
+#include "Internal/WorldClockDefs.h"
+#include "Model/Location.h"
+#include "Utils/WorldClock.h"
+#include "Utils/Time.h"
+#include "Utils/Log.h"
+#include "Utils/Utils.h"
+
+namespace view {
+
+using namespace utils;
+
+struct LocationReorderItemData {
+
+               WorldClockReorderView *view;
+               Evas_Object *time;
+
+               const model::Location *location;
+               char *ampm;
+               char *date;
+               char *city_country;
+               char *gmt_offset_relative;
+
+               int gmt_offset;
+               Elm_Object_Item *it;
+};
+
+
+/* Reorder list View */
+
+Elm_Genlist_Item_Class WorldClockReorderView::world_clock_reorder_items_view_itc_ = {
+       .item_style = "worldclock.delete/reorder.list",
+       .func.content_get = WorldClockReorderView::ContentGet,
+       .func.text_get = WorldClockReorderView::TextGet,
+       .func.del = WorldClockReorderView::Del
+};
+
+
+
+WorldClockReorderView::WorldClockReorderView(ui::IView &main) :
+               PageView(main)
+{
+
+}
+
+WorldClockReorderView::~WorldClockReorderView()
+{
+       DestroyContent();
+}
+
+Evas_Object* WorldClockReorderView::GetEvasObject()
+{
+       return content_;
+}
+
+void WorldClockReorderView::AppendItems(
+        std::vector<const model::Location*> locations)
+{
+       std::stringstream ss;
+
+       for (auto it = locations.begin(); it != locations.end(); it++) {
+               LocationReorderItemData *lrid = new LocationReorderItemData;
+               Time t = Time::Now().InTimezone(Time::GetTimezoneNameByOffset((*it)->gmt_offset_).c_str());
+               int local_timezone_offset = Time::GetTimezoneOffset(Time::GetCurrentTimezone().c_str());
+
+               ss.str(std::string());
+               ss.clear();
+               ss << (*it)->name << ", " << (*it)->country;
+               lrid->city_country = strdup(ss.str().c_str());
+
+               lrid->location = *it;
+               lrid->view = this;
+               lrid->ampm = strdup(t.Format("a").c_str());
+               lrid->gmt_offset_relative = strdup(GetTimezoneDiffDescription(local_timezone_offset,
+                               (*it)->gmt_offset_).c_str());
+               lrid->gmt_offset = (*it)->gmt_offset_;
+               lrid->date = strdup(t.Format("E d MMM").c_str());
+               lrid->it = elm_genlist_item_append(content_,
+                               &world_clock_reorder_items_view_itc_,
+                               lrid,
+                               NULL,
+                               ELM_GENLIST_ITEM_NONE,
+                               NULL,
+                               lrid);
+       }
+}
+
+
+void WorldClockReorderView::CreateContent(Evas_Object *parent)
+{
+       elm_object_item_style_set(navi_item_, "basic");
+
+       static bool extension_init = false;
+
+       if (!extension_init) {
+               elm_theme_extension_add(NULL,
+                               Utils::GetAppResourcePath(Utils::APP_DIR_RESOURCE,
+                               "edje/WorldClockDeleteReorderList.edj"));
+               extension_init = true;
+       }
+
+       left_button_ = elm_button_add(parent);
+       elm_object_text_set(left_button_, "BACK");
+       elm_object_style_set(left_button_, "naviframe/title_left");
+       evas_object_smart_callback_add(left_button_, "clicked", OnBackButtonClicked, this);
+       evas_object_show(left_button_);
+
+       content_ = elm_genlist_add(parent);
+       evas_object_size_hint_align_set(content_, EVAS_HINT_FILL, EVAS_HINT_FILL);
+       evas_object_size_hint_weight_set(content_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       elm_genlist_mode_set(content_, ELM_LIST_COMPRESS);
+       elm_genlist_homogeneous_set(content_, EINA_TRUE);
+       elm_genlist_highlight_mode_set(content_, EINA_FALSE);
+       evas_object_show(content_);
+
+       elm_object_item_part_text_set(navi_item_, "elm.text.title", "Reorder");
+       elm_object_item_part_content_set(navi_item_, "title_left_btn", left_button_);
+       elm_object_item_content_set(navi_item_, content_);
+
+       evas_object_smart_callback_add(content_, "moved" , OnListReordered, this);
+}
+
+void WorldClockReorderView::DestroyContent()
+{
+       evas_object_del(content_);
+       evas_object_del(left_button_);
+}
+
+void longpress_cb(void *data, Evas_Object *obj, void *event_info)
+{
+       LocationReorderItemData *lrid = static_cast<LocationReorderItemData *>(data);
+       static Eina_Bool reorder = EINA_TRUE;
+
+       elm_genlist_reorder_mode_set(lrid->view->GetEvasObject(), reorder);
+       reorder = !reorder;
+}
+
+Evas_Object *WorldClockReorderView::ContentGet(void *data,
+        Evas_Object *obj, const char *part)
+{
+       LocationReorderItemData *lrid = static_cast<LocationReorderItemData *>(data);
+
+       if (!strcmp(part, "time")) {
+               Time t = Time::Now().InTimezone(Time::GetTimezoneNameByOffset(lrid->gmt_offset).c_str());
+
+               lrid->time = elm_table_add(obj);
+               evas_object_size_hint_align_set(lrid->time, 0.0, 0.0);
+
+               Evas_Object *time = CreateTimeObject(lrid->time, t);
+               Evas_Object *padding = CreatePaddingObject(lrid->time, 8);
+               Evas_Object *ampm = CreateXMeridiemObject(lrid->time, t);
+
+               Evas_Object *dynamic_padding = elm_bg_add(lrid->time);
+               evas_object_color_set(dynamic_padding, 0, 0, 0, 0);
+               evas_object_size_hint_weight_set(dynamic_padding, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+               elm_table_pack(lrid->time, time, 0, 0, 1, 1);
+               elm_table_pack(lrid->time, padding, 1, 0, 1, 1);
+               elm_table_pack(lrid->time, ampm, 2, 0, 1, 1);
+               elm_table_pack(lrid->time, dynamic_padding, 3, 0, 1, 1);
+
+               return lrid->time;
+       } else if (!strcmp(part, "sw.item")) {
+               Evas_Object *img = elm_image_add(obj);
+
+               evas_object_size_hint_weight_set(img, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+               elm_image_file_set(img, Utils::GetAppResourcePath(Utils::APP_DIR_RESOURCE, "images/world_clock_reorder.png"), NULL);
+               evas_object_propagate_events_set(img, EINA_TRUE);
+
+               evas_object_smart_callback_add(img, "mouse,down", longpress_cb, data);
+               evas_object_smart_callback_add(img, "mouse,up", longpress_cb, data);
+
+               return img;
+       }
+       return NULL;
+}
+
+char* WorldClockReorderView::TextGet(void* data, Evas_Object* obj,
+        const char* part)
+{
+       LocationReorderItemData *lrid = static_cast<LocationReorderItemData *>(data);
+       if (!strcmp(part, "ampm"))
+               return strdup(lrid->ampm);
+       if (!strcmp(part, "date"))
+               return strdup(lrid->date);
+       if (!strcmp(part, "city.country"))
+               return strdup(lrid->city_country);
+       if (!strcmp(part, "gmt.offset.desc"))
+               return strdup(lrid->gmt_offset_relative);
+
+       return nullptr;
+}
+
+void WorldClockReorderView::Del(void* data, Evas_Object* obj)
+{
+       LocationReorderItemData *lrid = static_cast<LocationReorderItemData *>(data);
+
+       free(lrid->ampm);
+       free(lrid->city_country);
+       free(lrid->date);
+       free(lrid->gmt_offset_relative);
+       delete lrid;
+}
+
+Evas_Object *WorldClockReorderView::CreateTimeObject(Evas_Object *parent, Time t)
+{
+       Evas_Object *label = elm_label_add(parent);
+       evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+       std::string timezone_time = t.Format("HH:mm");
+       char time_formatted[MAX_STYLE_LEN] = { 0, };
+       snprintf(time_formatted, sizeof(time_formatted),
+                       CUSTOM_LIST_TIME_STYLE("%s"), timezone_time.c_str());
+       elm_object_text_set(label, time_formatted);
+
+       evas_object_show(label);
+
+       return label;
+}
+
+Evas_Object *WorldClockReorderView::CreateXMeridiemObject(Evas_Object *parent, Time t)
+{
+       Evas_Object *ampm = elm_label_add(parent);
+       evas_object_size_hint_align_set(ampm, EVAS_HINT_FILL, 0.75);
+
+       std::string meridiem = t.Format("a");
+       char ampm_formatted[MAX_STYLE_LEN] = { 0, };
+       snprintf(ampm_formatted, sizeof(ampm_formatted),
+                       CUSTOM_LIST_AMPM_STYLE("%s"), meridiem.c_str());
+       elm_object_text_set(ampm, ampm_formatted);
+
+       evas_object_show(ampm);
+
+       return ampm;
+}
+
+Evas_Object *WorldClockReorderView::CreatePaddingObject(Evas_Object *parent, int width)
+{
+       Evas_Object *padding = elm_bg_add(parent);
+       evas_object_size_hint_min_set(padding, width, 10);
+       evas_object_size_hint_max_set(padding, width, 10);
+       evas_object_color_set(padding, 0, 0, 0, 0);
+       evas_object_show(padding);
+
+       return padding;
+}
+
+void WorldClockReorderView::RegisterSignalHandler(WorldClockReorderView::Signals s, std::function<void(void)> func)
+{
+       signals_.at((int)s) = func;
+}
+
+void WorldClockReorderView::EmitSignal(Signals s)
+{
+       if (signals_.at((int)s) != nullptr)
+               signals_.at((int)s)();
+}
+
+void WorldClockReorderView::OnListReordered(void *data,
+        Evas_Object *obj, void *event_info)
+{
+       WorldClockReorderView *view = static_cast<WorldClockReorderView *>(data);
+       view->EmitSignal(Signals::LIST_REORDERED);
+}
+
+void WorldClockReorderView::OnBackButtonClicked(void *data,
+        Evas_Object *obj, void *event_info)
+{
+       WorldClockReorderView *view = static_cast<WorldClockReorderView *>(data);
+       view->EmitSignal(Signals::BUTTON_BACK_CLICKED);
+}
+
+std::vector<const model::Location *> WorldClockReorderView::GetReorderedLocations()
+{
+       std::vector<const model::Location *> reordered;
+
+       Elm_Genlist_Item *it = elm_genlist_nth_item_get(content_, 0);
+       while (it) {
+               LocationReorderItemData *lrid = static_cast<LocationReorderItemData *>(elm_object_item_data_get(it));
+               reordered.push_back(lrid->location);
+               it = elm_genlist_item_next_get(it);
+       }
+       return reordered;
+}
+
+} /** view **/
index 223a0cb..3b79507 100644 (file)
@@ -113,6 +113,11 @@ void WorldClockView::RemoveItem(const model::Location &location)
        }
 }
 
+void WorldClockView::ClearAllItems()
+{
+       elm_genlist_clear(custom_locations_list_);
+}
+
 void WorldClockView::ItemClicked(void *data, Evas_Object *obj, void *event_info)
 {
        LocationItemData *lid = static_cast<LocationItemData *>(data);
@@ -308,6 +313,7 @@ void WorldClockView::MorePopupReorderItemCallback(void *data, Evas_Object *obj,
 {
        WorldClockView *view = static_cast<WorldClockView *>(data);
 
+       view->EmitSignal(view::WorldClockSignals::BUTTON_MORE_REORDER_CLICKED);
        evas_object_del(view->more_popup_);
        view->more_popup_ = nullptr;
 }