Accessories Switches Pages in mvp 45/209145/17
authorOskar Chodowicz <o.chodowicz@samsung.com>
Fri, 12 Jul 2019 14:42:45 +0000 (16:42 +0200)
committerOskar Chodowicz <o.chodowicz@samsung.com>
Fri, 12 Jul 2019 14:43:29 +0000 (16:43 +0200)
Change-Id: If2b5f42d76aa2ae34fdf6be43191d9c32c76c125

39 files changed:
src/model/AddAccessoriesSwitchesPageModel.cpp [new file with mode: 0644]
src/model/AddAccessoriesSwitchesPageModel.hpp [new file with mode: 0644]
src/model/UpdateAccessoriesSwitchPageModel.cpp [new file with mode: 0644]
src/model/UpdateAccessoriesSwitchPageModel.hpp [new file with mode: 0644]
src/presenter/AddAccessoriesSwitchesPagePresenter.cpp [new file with mode: 0644]
src/presenter/AddAccessoriesSwitchesPagePresenter.hpp [new file with mode: 0644]
src/presenter/AddSwitchPagePresenter.cpp
src/presenter/AlreadyMappedSwitchModalPresenter.cpp [new file with mode: 0644]
src/presenter/AlreadyMappedSwitchModalPresenter.hpp [new file with mode: 0644]
src/presenter/AppContext.cpp
src/presenter/AppContext.hpp
src/presenter/EntryNameModalPresenter.cpp [new file with mode: 0644]
src/presenter/EntryNameModalPresenter.hpp [new file with mode: 0644]
src/presenter/LabelPresenter.hpp [new file with mode: 0644]
src/presenter/ListPresenter.cpp
src/presenter/ListPresenter.hpp
src/presenter/ModalPresenter.cpp
src/presenter/ModalPresenter.hpp
src/presenter/Presenter.cpp
src/presenter/Presenter.hpp
src/presenter/RemoveSwitchesModalPresenter.cpp
src/presenter/SelectActionPagePresenter.cpp
src/presenter/SelectActionPagePresenter.hpp
src/presenter/SwitchesPagePresenter.cpp
src/presenter/SwitchesPagePresenter.hpp
src/presenter/UpdateAccessoriesSwitchPagePresenter.cpp [new file with mode: 0644]
src/presenter/UpdateAccessoriesSwitchPagePresenter.hpp [new file with mode: 0644]
src/service/DBus.cpp
src/service/DBus.hpp
src/ui/Entry.cpp
src/ui/Entry.hpp
src/ui/GenlistItem.cpp
src/view/LabelView.cpp [new file with mode: 0644]
src/view/LabelView.hpp [new file with mode: 0644]
src/view/ListView.cpp
src/view/ListView.hpp
src/view/ModalView.cpp
src/view/ModalView.hpp
src/view/NavigationContext.cpp

diff --git a/src/model/AddAccessoriesSwitchesPageModel.cpp b/src/model/AddAccessoriesSwitchesPageModel.cpp
new file mode 100644 (file)
index 0000000..5c686b7
--- /dev/null
@@ -0,0 +1,50 @@
+#include "AddAccessoriesSwitchesPageModel.hpp"
+
+#include "UniversalSwitchConstants.hpp"
+
+AddAccessoriesSwitchesPageModel::AddAccessoriesSwitchesPageModel()
+{
+       dBusClient_ = DBus::DBusClient{BUS, PATH, IFACE, DBus::ConnectionType::SESSION};
+}
+
+AddAccessoriesSwitchesPageModel::~AddAccessoriesSwitchesPageModel()
+{
+       cancelCaptureSwitch();
+}
+
+void AddAccessoriesSwitchesPageModel::captureSwitch(std::function<void(std::string)> onCapture, std::string providerId)
+{
+       dBusClient_.method<std::string(std::string)>("captureSwitch").timeout(DBus::InfinitiveTimeout).asyncCall([onCapture](DBus::ValueOrError<std::string> msg) {
+               if (msg) {
+                       onCapture(std::get<0>(msg));
+               } else {
+                       ERROR("Error on function captureSwitch asyncCall");
+                       ERROR("failed '%s'", msg.getError().message.c_str());
+               }
+       },
+               providerId);
+}
+
+void AddAccessoriesSwitchesPageModel::cancelCaptureSwitch()
+{
+       auto reply = dBusClient_.method<DBus::ValueOrError<>()>("cancelCaptureSwitch").call();
+       if (!reply) {
+               ERROR("Error on function cancelCaptureSwitch call");
+               ERROR("%s", reply.getError().message.c_str());
+       }
+}
+
+bool AddAccessoriesSwitchesPageModel::isConfigured(const std::string &switchId)
+{
+       auto reply = dBusClient_.method<DBus::ValueOrError<std::vector<std::tuple<std::string, std::string, std::string, ChangeType>>>()>("getAllSwitchConfigurationItems").call();
+       if (reply) {
+               for (auto &item : std::get<0>(reply))
+                       if (std::get<0>(item) == switchId)
+                               return true;
+       } else {
+               ERROR("Error on function getAllSwitchConfigurationItems call");
+               ERROR("%s", reply.getError().message.c_str());
+               ASSERT(0, "unable to know that switch is configured");
+       }
+       return false;
+}
diff --git a/src/model/AddAccessoriesSwitchesPageModel.hpp b/src/model/AddAccessoriesSwitchesPageModel.hpp
new file mode 100644 (file)
index 0000000..0b0a9d9
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef ADD_ACCESSORIES_SWITCHES_PAGE_MODEL_HPP
+#define ADD_ACCESSORIES_SWITCHES_PAGE_MODEL_HPP
+
+#include "DBus.hpp"
+#include "ObservableProperty.hpp"
+#include "UniversalSwitchTypes.hpp"
+#include "VConf.hpp"
+
+#include <chrono>
+
+class AddAccessoriesSwitchesPageModel
+{
+       public:
+       AddAccessoriesSwitchesPageModel();
+       ~AddAccessoriesSwitchesPageModel();
+       void captureSwitch(std::function<void(std::string)> onCapture, std::string providerId);
+       void cancelCaptureSwitch();
+       bool isConfigured(const std::string &switchId);
+
+       private:
+       DBus::DBusClient dBusClient_;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/model/UpdateAccessoriesSwitchPageModel.cpp b/src/model/UpdateAccessoriesSwitchPageModel.cpp
new file mode 100644 (file)
index 0000000..07195c9
--- /dev/null
@@ -0,0 +1,48 @@
+#include "UpdateAccessoriesSwitchPageModel.hpp"
+
+#include "UniversalSwitchConstants.hpp"
+
+UpdateAccessoriesSwitchPageModel::UpdateAccessoriesSwitchPageModel()
+{
+}
+
+SwitchConfigurationItem UpdateAccessoriesSwitchPageModel::getDetailsForSwitchConfigurationItem(const std::string &switchId)
+{
+       auto reply = DBus::DBusClient{BUS, PATH, IFACE, DBus::ConnectionType::SESSION}.method<DBus::ValueOrError<std::vector<std::tuple<std::string, std::string, std::string>>>()>("getAllSwitchConfigurationItems").call();
+       if (reply) {
+               for (auto &item : std::get<0>(reply))
+                       if (std::get<0>(item) == switchId)
+                               return SwitchConfigurationItem{std::get<0>(item), std::get<1>(item), std::get<2>(item)};
+       } else {
+               ERROR("Error on function getAllSwitchConfigurationItems call");
+               ERROR("%s", reply.getError().message.c_str());
+       }
+       return {};
+}
+
+InfoType UpdateAccessoriesSwitchPageModel::getActivityDetails(const std::string &activityId)
+{
+       auto dBusClient = DBus::DBusClient{BUS, PATH, IFACE, DBus::ConnectionType::SESSION};
+       auto reply = dBusClient.method<DBus::ValueOrError<std::vector<std::tuple<std::string, std::string, std::string>>>()>("getBindableActivityTypes").call();
+       if (reply) {
+               for (auto &activity : std::get<0>(reply))
+                       if (std::get<0>(activity) == activityId)
+                               return InfoType{std::get<0>(activity), std::get<1>(activity), std::get<2>(activity)};
+       } else {
+               ERROR("Error on function getBindableActivityTypes call");
+               ERROR("%s", reply.getError().message.c_str());
+       }
+       return {};
+}
+
+void UpdateAccessoriesSwitchPageModel::updateSwitch(const SwitchConfigurationItem &item)
+{
+       auto dBusClient = DBus::DBusClient{BUS, PATH, IFACE, DBus::ConnectionType::SESSION};
+       auto reply = dBusClient.method<DBus::ValueOrError<>(std::string, std::string, std::string)>("updateSwitchConfigurationItem").call(item.switchId, item.userName, item.activityType);
+       if (reply)
+               DEBUG("Switch: %s updated successfully", item.switchId.c_str());
+       else {
+               ERROR("Error on function updateSwitchConfigurationItem call");
+               ERROR("%s", reply.getError().message.c_str());
+       }
+}
\ No newline at end of file
diff --git a/src/model/UpdateAccessoriesSwitchPageModel.hpp b/src/model/UpdateAccessoriesSwitchPageModel.hpp
new file mode 100644 (file)
index 0000000..24fe67a
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef UPDATE_ACCESSORIES_SWITCH_PAGE_MODEL_HPP
+#define UPDATE_ACCESSORIES_SWITCH_PAGE_MODEL_HPP
+
+#include "DBus.hpp"
+#include "ObservableProperty.hpp"
+#include "UniversalSwitchTypes.hpp"
+#include "VConf.hpp"
+
+#include <chrono>
+
+class UpdateAccessoriesSwitchPageModel
+{
+       public:
+       UpdateAccessoriesSwitchPageModel();
+       SwitchConfigurationItem getDetailsForSwitchConfigurationItem(const std::string &switchId);
+       InfoType getActivityDetails(const std::string &actionId);
+       void updateSwitch(const SwitchConfigurationItem &item);
+};
+
+#endif
\ No newline at end of file
diff --git a/src/presenter/AddAccessoriesSwitchesPagePresenter.cpp b/src/presenter/AddAccessoriesSwitchesPagePresenter.cpp
new file mode 100644 (file)
index 0000000..1941772
--- /dev/null
@@ -0,0 +1,35 @@
+#include "AddAccessoriesSwitchesPagePresenter.hpp"
+
+#include "AlreadyMappedSwitchModalPresenter.hpp"
+#include "AppContext.hpp"
+#include "EntryNameModalPresenter.hpp"
+#include "Singleton.hpp"
+#include "UniversalSwitchConstants.hpp"
+
+AddAccessoriesSwitchesPagePresenter::AddAccessoriesSwitchesPagePresenter()
+{
+       setTitle("IDS_ACCS_UNIVERSAL_SWITCH_ADD_SWITCH_ACCESSORIES_TITLE");
+       labelText_ = "IDS_ACCS_UNIVERSAL_SWITCH_ADD_SWITCH_ACCESSORIES_DESC";
+}
+
+void AddAccessoriesSwitchesPagePresenter::onTop()
+{
+       model_.captureSwitch([this](auto switchId) {
+               this->onSwitchCapture(switchId);
+       },
+               ACCESSIBILITY_UNIVERSAL_SWITCH_ACCESSORIES_SWITCH_PROVIDER);
+}
+
+void AddAccessoriesSwitchesPagePresenter::notOnTop()
+{
+       model_.cancelCaptureSwitch();
+}
+
+void AddAccessoriesSwitchesPagePresenter::onSwitchCapture(const std::string &switchId)
+{
+       notOnTop();
+       if (model_.isConfigured(switchId))
+               Singleton<AppContext>::instance().pushModal(std::make_unique<AlreadyMappedSwitchModalPresenter>());
+       else
+               Singleton<AppContext>::instance().pushModal(std::make_unique<EntryNameModalPresenter>(switchId));
+}
diff --git a/src/presenter/AddAccessoriesSwitchesPagePresenter.hpp b/src/presenter/AddAccessoriesSwitchesPagePresenter.hpp
new file mode 100644 (file)
index 0000000..0610257
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef ADD_ACCESSORIES_SWITCHES_PAGE_PRESENTER
+#define ADD_ACCESSORIES_SWITCHES_PAGE_PRESENTER
+
+#include "AddAccessoriesSwitchesPageModel.hpp"
+#include "LabelPresenter.hpp"
+
+class AddAccessoriesSwitchesPagePresenter : public LabelPresenter
+{
+       public:
+       AddAccessoriesSwitchesPagePresenter();
+
+       private:
+       void onTop() override;
+       void notOnTop() override;
+       void onSwitchCapture(const std::string &switchId);
+       AddAccessoriesSwitchesPageModel model_;
+};
+
+#endif
\ No newline at end of file
index cb0bd00f98dcf9d6063196533006234b792b0f99..a7241b39e309c200ce704214e55c24c54264a016 100644 (file)
@@ -1,5 +1,6 @@
 #include "AddSwitchPagePresenter.hpp"
 
+#include "AddAccessoriesSwitchesPagePresenter.hpp"
 #include "AppContext.hpp"
 #include "CameraSwitchesPagePresenter.hpp"
 #include "SelectActionPagePresenter.hpp"
@@ -55,7 +56,7 @@ void AddSwitchPagePresenter::createPageForScreenProvider()
 
 void AddSwitchPagePresenter::createPageForAccessoriesProvider()
 {
-       //Singleton<AppContext>::instance().push(std::make_unique<AccessoriesProviderPagePresenter>());
+       Singleton<AppContext>::instance().push(std::make_unique<AddAccessoriesSwitchesPagePresenter>());
 }
 
 void AddSwitchPagePresenter::createPageForCameraProvider()
diff --git a/src/presenter/AlreadyMappedSwitchModalPresenter.cpp b/src/presenter/AlreadyMappedSwitchModalPresenter.cpp
new file mode 100644 (file)
index 0000000..1d0c337
--- /dev/null
@@ -0,0 +1,8 @@
+#include "AlreadyMappedSwitchModalPresenter.hpp"
+
+AlreadyMappedSwitchModalPresenter::AlreadyMappedSwitchModalPresenter()
+{
+       setTitle("IDS_ACCS_UNIVERSAL_SWITCH_UNABLE_TO_ADD");
+       text_ = "IDS_ACCS_UNIVERSAL_SWITCH_ALREADY_ADDED";
+       cancelText_ = "IDS_ACCS_UNIVERSAL_SWITCH_OK";
+}
diff --git a/src/presenter/AlreadyMappedSwitchModalPresenter.hpp b/src/presenter/AlreadyMappedSwitchModalPresenter.hpp
new file mode 100644 (file)
index 0000000..f001cac
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef ALREADY_MAPPED_SWITCH_MODAL_PRESENTER
+#define ALREADY_MAPPED_SWITCH_MODAL_PRESENTER
+
+#include "ModalPresenter.hpp"
+
+class AlreadyMappedSwitchModalPresenter : public ModalPresenter
+{
+       public:
+       AlreadyMappedSwitchModalPresenter();
+};
+
+#endif
\ No newline at end of file
index 57ca8be671150c279778976061cdaff800b84997..d7c989c50ee3231e7803cffb0e0e5f4e55388363 100644 (file)
@@ -16,7 +16,10 @@ AppContext::AppContext()
 
 void AppContext::push(std::unique_ptr<Presenter> presenter)
 {
+       if (presentersStack_.size() > 0)
+               presentersStack_.back()->notOnTop();
        presentersStack_.push_back(std::move(presenter));
+       presentersStack_.back()->onTop();
        presenterToBroadcast_ = presentersStack_.back().get();
        countOfPagesToPop_ = 1;
        notify();
@@ -33,13 +36,18 @@ void AppContext::pop(size_t countOfPagesToPop)
        else
                countOfPagesToPop_ = countOfPagesToPop;
 
+       if (presentersStack_.size() > 0)
+               presentersStack_.back()->notOnTop();
+
        for (auto i = 0u; i < countOfPagesToPop_; ++i)
                presentersStack_.pop_back();
 
-       if (presentersStack_.empty())
+       if (presentersStack_.empty()) {
                ui_app_exit();
-       else
+       } else {
+               presentersStack_.back()->onTop();
                notify();
+       }
 }
 
 Presenter *AppContext::back()
@@ -54,6 +62,8 @@ bool AppContext::empty()
 
 void AppContext::pushModal(std::unique_ptr<ModalPresenter> presenter)
 {
+       if (presentersStack_.size() > 0)
+               presentersStack_.back()->notOnTop();
        modalPresentersStack_.push_back(std::move(presenter));
        modalPresenterToBroadcast_ = modalPresentersStack_.back().get();
        notifyAboutModal();
@@ -61,9 +71,11 @@ void AppContext::pushModal(std::unique_ptr<ModalPresenter> presenter)
 
 void AppContext::popModal()
 {
+       if (presentersStack_.size() > 0)
+               presentersStack_.back()->onTop();
+       modalPresentersStack_.pop_back();
        modalPresenterToBroadcast_ = nullptr;
        notifyAboutModal();
-       modalPresentersStack_.pop_back();
 }
 
 ModalPresenter *AppContext::modalsBack()
index e34b812d192d5e5ac8986b3adaa4a9bad78264fc..7d6c2b35480eba5580c5d4edb5e27014c5b99592 100644 (file)
@@ -25,6 +25,7 @@ class AppContext : public Observable<Presenter *, size_t>, public Observable<Mod
        void popModal();
        ModalPresenter *modalsBack();
        bool modalsEmpty();
+       std::unordered_map<std::string, std::string> sharedPreferences;
 
        private:
        std::vector<std::unique_ptr<Presenter>> presentersStack_;
diff --git a/src/presenter/EntryNameModalPresenter.cpp b/src/presenter/EntryNameModalPresenter.cpp
new file mode 100644 (file)
index 0000000..0ecec72
--- /dev/null
@@ -0,0 +1,20 @@
+#include "EntryNameModalPresenter.hpp"
+
+#include "AppContext.hpp"
+#include "SelectActionPagePresenter.hpp"
+#include "Singleton.hpp"
+
+EntryNameModalPresenter::EntryNameModalPresenter(std::string switchId)
+{
+       setTitle("IDS_ACCS_UNIVERSAL_SWITCH_ADD_SWITCH");
+       entryAction_ = addAction(std::make_unique<Action>("modalEntry", "IDS_ACCS_UNIVERSAL_SWITCH_ADD_SWITCH_NAME", std::function<void(Action *)>{}));
+       doneText_ = "IDS_ACCS_UNIVERSAL_SWITCH_SAVE";
+       cancelText_ = "IDS_ACCS_UNIVERSAL_SWITCH_CANCEL";
+       doneCb_ = [this, switchId]() {
+               auto switchUserName = this->entryAction_->title_.value();
+               if (!switchUserName.empty()) {
+                       Singleton<AppContext>::instance().popModal();
+                       Singleton<AppContext>::instance().push(std::make_unique<SelectActionPagePresenter>(switchId, switchUserName, ChangeType::ADD, 2));
+               }
+       };
+}
\ No newline at end of file
diff --git a/src/presenter/EntryNameModalPresenter.hpp b/src/presenter/EntryNameModalPresenter.hpp
new file mode 100644 (file)
index 0000000..05999f7
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef ENTRY_NAME_MODAL_PRESENTER_HPP
+#define ENTRY_NAME_MODAL_PRESENTER_HPP
+
+#include "ModalPresenter.hpp"
+
+class EntryNameModalPresenter : public ModalPresenter
+{
+       public:
+       EntryNameModalPresenter(std::string switchId);
+
+       private:
+       Action *entryAction_ = nullptr;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/presenter/LabelPresenter.hpp b/src/presenter/LabelPresenter.hpp
new file mode 100644 (file)
index 0000000..08ff134
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef LABEL_PRESENTER
+#define LABEL_PRESENTER
+
+#include "ObservableProperty.hpp"
+#include "Presenter.hpp"
+
+class LabelPresenter : public Presenter
+{
+       public:
+       ObservableProperty<std::string> labelText_;
+
+       protected:
+       using Presenter::Presenter;
+};
+
+#endif
\ No newline at end of file
index 4b51eae1092d53ddbd9223d9af8eb9d4936f1bcc..bae2f6bf7ca530bdde5cb13143ce883a36caf540 100644 (file)
@@ -5,24 +5,6 @@ const std::vector<ListGroup> &ListPresenter::getListGroups() const
        return groups_;
 }
 
-Action *ListPresenter::getAction(const std::string &actionId) const
-{
-       auto it = actions_.find(actionId);
-       if (it == actions_.end()) {
-               // DEBUG("Action with id: %s doesn't exist", actionId.c_str());
-               return nullptr;
-       }
-       return it->second.get();
-}
-
-Action *ListPresenter::addAction(std::unique_ptr<Action> action)
-{
-       auto ret = actions_.insert_or_assign(action->actionId_, std::move(action));
-       ASSERT(ret.second, "Action cannot be added");
-
-       return ret.first->second.get();
-}
-
 void ListPresenter::setOnListUpdateCallback(std::function<void()> callback)
 {
        onListUpdate_ = std::move(callback);
index 23737c7511e4b4bdedc5a6f7b54e1c5fc62dbd84..aa28c21c0060126592b6400a1e33866ba485e7f5 100644 (file)
@@ -1,19 +1,14 @@
 #ifndef LIST_PRESENTER_HPP
 #define LIST_PRESENTER_HPP
 
-#include "Action.hpp"
 #include "ListGroup.hpp"
 #include "Observable.hpp"
 #include "Presenter.hpp"
 
-#include <unordered_map>
-
 class ListPresenter : public Presenter, public Observable<>
 {
        public:
        const std::vector<ListGroup> &getListGroups() const;
-       Action *getAction(const std::string &actionId) const;
-       Action *addAction(std::unique_ptr<Action> action);
        void setOnListUpdateCallback(std::function<void()> callback);
 
        protected:
@@ -21,7 +16,6 @@ class ListPresenter : public Presenter, public Observable<>
 
        std::function<void()> onListUpdate_;
        std::vector<ListGroup> groups_;
-       std::unordered_map<std::string, std::unique_ptr<Action>> actions_;
 };
 
 #endif
\ No newline at end of file
index 5a14dc872febac83df0f222f0957c00103645441..351142d0dee4b464d626a12727d46f496cfc0ffd 100644 (file)
@@ -18,4 +18,9 @@ std::string ModalPresenter::getText()
 std::string ModalPresenter::getDoneText()
 {
        return doneText_;
+}
+
+std::string ModalPresenter::getCancelText()
+{
+       return cancelText_;
 }
\ No newline at end of file
index 5cd77dfc00218f019de1da4f4deeca0905975dc5..852eea87e9459a50c7aac80be8895e4b823baec5 100644 (file)
@@ -10,6 +10,7 @@ class ModalPresenter : public Presenter
        std::function<void()> getCancelCb();
        std::string getText();
        std::string getDoneText();
+       std::string getCancelText();
 
        protected:
        using Presenter::Presenter;
@@ -18,6 +19,7 @@ class ModalPresenter : public Presenter
        std::function<void()> cancelCb_;
        std::string text_;
        std::string doneText_;
+       std::string cancelText_;
 };
 
 #endif
\ No newline at end of file
index 724f8f947f65b95991ecadf38e1fea72a4ca0116..26ebeb0fdaeff32768c4e2c1e910cc1de5b43e8f 100644 (file)
@@ -24,3 +24,23 @@ void Presenter::onAppPause()
 
 void Presenter::onAppResume()
 {}
+
+void Presenter::onTop()
+{}
+
+void Presenter::notOnTop()
+{}
+
+Action *Presenter::getAction(const std::string &actionId) const
+{
+       auto it = actions_.find(actionId);
+       if (it == actions_.end()) {
+               return nullptr;
+       }
+       return it->second.get();
+}
+
+Action *Presenter::addAction(std::unique_ptr<Action> action)
+{
+       return actions_.insert_or_assign(action->actionId_, std::move(action)).first->second.get();
+}
\ No newline at end of file
index 47ad30db61689760b6b7c51cd98a70a3284529d6..f6e4ca6ec462cfb0ff21a4ffc3fb17717e81955b 100644 (file)
@@ -1,10 +1,12 @@
 #ifndef PRESENTER_HPP
 #define PRESENTER_HPP
 
+#include "Action.hpp"
 #include "GenlistItem.hpp"
 #include "TranslatedString.hpp"
 
 #include <functional>
+#include <unordered_map>
 #include <vector>
 
 class Presenter
@@ -17,12 +19,17 @@ class Presenter
        const std::function<void()> getOnPopCallback() const;
        virtual void onAppPause();
        virtual void onAppResume();
+       virtual void onTop();
+       virtual void notOnTop();
+       Action *getAction(const std::string &actionId) const;
+       Action *addAction(std::unique_ptr<Action> action);
 
        protected:
        Presenter(TranslatedString title = {}, std::function<void()> onPopCallback = {});
 
        TranslatedString title_;
        std::function<void()> onPopCallback_;
+       std::unordered_map<std::string, std::unique_ptr<Action>> actions_;
 };
 
 #endif
\ No newline at end of file
index ad0f702ca3c7546e9fcea13d9f620bb206398841..8bbc19f33759b9346c8eace79a873ade8b40451b 100644 (file)
@@ -10,10 +10,11 @@ RemoveSwitchesModalPresenter::RemoveSwitchesModalPresenter(std::vector<SwitchCon
        if (switchesToRemove_.size() == switches_.size() && model_.isUniversalSwitchActive_.value()) {
                text_ = "IDS_ACCS_UNIVERSAL_SWITCH_DELETE_ALL_SWITCHES_DESC";
        } else {
-               text_ = std::to_string(switchesToRemove_.size()) + " " + "IDS_ACCS_UNIVERSAL_SWITCH_DELETE_SWITCHES_DESC";
+               text_ = std::to_string(switchesToRemove_.size()) + " " + TranslatedString{"IDS_ACCS_UNIVERSAL_SWITCH_DELETE_SWITCHES_DESC"}.str();
        }
 
        doneText_ = "IDS_ACCS_DELETE";
+       cancelText_ = "IDS_ST_BUTTON_CANCEL";
 
        doneCb_ = [this]() {
                model_.removeSwitches(switchesToRemove_);
index 46747c451e6b3ed777f6fc9d335c7e76a1014bb6..0a0e99f15de1269036cea9ced3065506dc72adb5 100644 (file)
@@ -2,7 +2,7 @@
 
 #include "AppContext.hpp"
 
-SelectActionPagePresenter::SelectActionPagePresenter(std::string switchId, std::string userName, ChangeType changeType, size_t countOfPagesToPop)
+SelectActionPagePresenter::SelectActionPagePresenter(std::string switchId, std::string userName, ChangeType changeType, size_t countOfPagesToPop, std::string activityId, bool locally)
        : switchId_(std::move(switchId)), userName_(std::move(userName)), changeType_(changeType), countOfPagesToPop_(countOfPagesToPop)
 {
        setTitle("IDS_ACCS_UNIVERSAL_SWITCH_SELECT_ACTION");
@@ -14,20 +14,26 @@ SelectActionPagePresenter::SelectActionPagePresenter(std::string switchId, std::
                        activity.name,
                        std::string{},
                        [=](auto item) {
-                               this->addOrUpdateSwitchConfigurationItem(activity.id);
+                               this->addOrUpdateSwitchConfigurationItem(activity.id, locally);
                        },
-                       ListItem::WidgetType::radio));
+                       ListItem::WidgetType::radio,
+                       std::function<void(ListItem * item)>{},
+                       std::function<void(ListItem * item)>{},
+                       activityId == activity.id));
        }
 }
 
-void SelectActionPagePresenter::addOrUpdateSwitchConfigurationItem(const std::string &activityType)
+void SelectActionPagePresenter::addOrUpdateSwitchConfigurationItem(const std::string &activityType, bool locally)
 {
        switch (changeType_) {
        case ChangeType::ADD:
                model_.addSwitch({switchId_, userName_, activityType});
                break;
        case ChangeType::UPDATE:
-               model_.updateSwitch({switchId_, userName_, activityType});
+               if (locally)
+                       Singleton<AppContext>::instance().sharedPreferences.insert_or_assign(switchId_, activityType);
+               else
+                       model_.updateSwitch({switchId_, userName_, activityType});
                break;
        default:
                ASSERT(0, "Unhandled change type");
index 5dbf89670f4e2d6c74de0fd89663a9ade1d3defa..0a0af5ce3d41cbdacea922983c7ecbd32c4b415c 100644 (file)
@@ -8,10 +8,10 @@
 class SelectActionPagePresenter : public ListPresenter
 {
        public:
-       SelectActionPagePresenter(std::string switchId, std::string userName, ChangeType changeType, size_t countOfPagesToPop);
+       SelectActionPagePresenter(std::string switchId, std::string userName, ChangeType changeType, size_t countOfPagesToPop, std::string activityId = {}, bool locally = false);
 
        private:
-       void addOrUpdateSwitchConfigurationItem(const std::string &activityType);
+       void addOrUpdateSwitchConfigurationItem(const std::string &activityType, bool locally);
        const std::string switchId_;
        const std::string userName_;
        ChangeType changeType_;
index 3db4552b0ca407b8e706b29cd8e7880244d83591..265dfb899183145e87f35b6d8689743e5247abe4 100644 (file)
@@ -5,6 +5,7 @@
 #include "RemoveSwitchesPagePresenter.hpp"
 #include "SelectActionPagePresenter.hpp"
 #include "UniversalSwitchConstants.hpp"
+#include "UpdateAccessoriesSwitchPagePresenter.hpp"
 
 SwitchesPagePresenter::SwitchesPagePresenter()
 {
@@ -35,7 +36,7 @@ void SwitchesPagePresenter::addItemsToList()
                        oneSwitch.userName,
                        model_.getActivityName(oneSwitch.activityType),
                        [this, oneSwitch](auto item) {
-                               this->createUpdatePage(oneSwitch.switchId, oneSwitch.userName);
+                               this->createUpdatePage(oneSwitch);
                        }));
        }
        items.push_back(std::make_unique<ListItem>(
@@ -51,18 +52,19 @@ void SwitchesPagePresenter::addItemsToList()
                ACCESSIBILITY_UNIVERSAL_SWITCH_PLUS_ICON));
 }
 
-void SwitchesPagePresenter::createUpdatePage(const std::string &switchId, const std::string &userName)
+void SwitchesPagePresenter::createUpdatePage(const SwitchConfigurationItem &item)
 {
-       auto providerName = utils::stringSplitByDelimiter(switchId, '_')[0];
+       auto providerName = utils::stringSplitByDelimiter(item.switchId, '_')[0];
        if (providerName == ACCESSIBILITY_UNIVERSAL_SWITCH_SCREEN_SWITCH_PROVIDER) {
-               Singleton<AppContext>::instance().push(std::make_unique<SelectActionPagePresenter>(switchId, userName, ChangeType::UPDATE, 0));
+               Singleton<AppContext>::instance().push(std::make_unique<SelectActionPagePresenter>(item.switchId, item.userName, ChangeType::UPDATE, 0, item.activityType));
                return;
        }
        if (providerName == ACCESSIBILITY_UNIVERSAL_SWITCH_ACCESSORIES_SWITCH_PROVIDER) {
+               Singleton<AppContext>::instance().push(std::make_unique<UpdateAccessoriesSwitchPagePresenter>(item.switchId));
                return;
        }
        if (providerName == ACCESSIBILITY_UNIVERSAL_SWITCH_CAMERA_SWITCH_PROVIDER) {
-               Singleton<AppContext>::instance().push(std::make_unique<SelectActionPagePresenter>(switchId, userName, ChangeType::UPDATE, 0));
+               Singleton<AppContext>::instance().push(std::make_unique<SelectActionPagePresenter>(item.switchId, item.userName, ChangeType::UPDATE, 0, item.activityType));
                return;
        }
 }
index 8ba66de7e6d9b765296f4ac808cd38283d135d34..cc392654412b5f3a13ddd4179309e6a2834a128d 100644 (file)
@@ -11,7 +11,7 @@ class SwitchesPagePresenter : public ListPresenter
 
        private:
        void addItemsToList();
-       void createUpdatePage(const std::string &switchId, const std::string &userName);
+       void createUpdatePage(const SwitchConfigurationItem &item);
        void updateSwitchDeleteAction();
        SwitchesPageModel model_;
        Action *deleteSwitchesAction_ = nullptr;
diff --git a/src/presenter/UpdateAccessoriesSwitchPagePresenter.cpp b/src/presenter/UpdateAccessoriesSwitchPagePresenter.cpp
new file mode 100644 (file)
index 0000000..f6b6ae4
--- /dev/null
@@ -0,0 +1,61 @@
+#include "UpdateAccessoriesSwitchPagePresenter.hpp"
+
+#include "AppContext.hpp"
+#include "SelectActionPagePresenter.hpp"
+
+UpdateAccessoriesSwitchPagePresenter::UpdateAccessoriesSwitchPagePresenter(std::string switchId) : switchId_(std::move(switchId))
+{
+       cancelAction_ = addAction(std::make_unique<Action>("cancelAction",
+               "IDS_ACCS_UNIVERSAL_SWITCH_CANCEL",
+               [this](auto action) {
+                       Singleton<AppContext>::instance().pop();
+               }));
+       saveAction_ = addAction(std::make_unique<Action>("saveAction",
+               "IDS_ACCS_UNIVERSAL_SWITCH_SAVE",
+               [this](auto action) {
+                       if (!entryItem_->entryText_.value().empty()) {
+                               model_.updateSwitch(SwitchConfigurationItem{switchId_, entryItem_->entryText_.value(), activityId_});
+                               Singleton<AppContext>::instance().pop();
+                       }
+               }));
+       groups_.emplace_back("");
+       auto &items = groups_.back().items_;
+
+       items.push_back(std::make_unique<ListItem>(
+               "IDS_ACCS_UNIVERSAL_SWITCH_NAME",
+               std::string{},
+               std::function<void(ListItem *)>{},
+               ListItem::WidgetType::entry));
+
+       entryItem_ = items.back().get();
+       auto switchInfo = model_.getDetailsForSwitchConfigurationItem(switchId_);
+       entryItem_->entryText_ = switchInfo.userName;
+       activityId_ = switchInfo.activityType;
+
+       items.push_back(std::make_unique<ListItem>(
+               "IDS_ACCS_UNIVERSAL_SWITCH_ACTION",
+               model_.getActivityDetails(switchInfo.activityType).name,
+               [this](auto item) {
+                       Singleton<AppContext>::instance().push(std::make_unique<SelectActionPagePresenter>(switchId_, entryItem_->entryText_.value(), ChangeType::UPDATE, 0, activityId_, true));
+               },
+               ListItem::WidgetType::none,
+               std::function<void(ListItem *)>{},
+               std::function<void(ListItem *)>{},
+               false));
+       actionItem_ = items.back().get();
+}
+
+void UpdateAccessoriesSwitchPagePresenter::onTop()
+{
+       auto &sharedPreferences = Singleton<AppContext>::instance().sharedPreferences;
+       auto val = sharedPreferences.find(switchId_);
+       if (val != sharedPreferences.end()) {
+               activityId_ = val->second;
+               actionItem_->description_ = model_.getActivityDetails(activityId_).name;
+       }
+}
+
+UpdateAccessoriesSwitchPagePresenter::~UpdateAccessoriesSwitchPagePresenter()
+{
+       Singleton<AppContext>::instance().sharedPreferences.erase(switchId_);
+}
\ No newline at end of file
diff --git a/src/presenter/UpdateAccessoriesSwitchPagePresenter.hpp b/src/presenter/UpdateAccessoriesSwitchPagePresenter.hpp
new file mode 100644 (file)
index 0000000..45f3c6a
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef UPDATE_ACCESSORIES_SWITCH_PAGE_PRESENTER
+#define UPDATE_ACCESSORIES_SWITCH_PAGE_PRESENTER
+
+#include "ListPresenter.hpp"
+#include "UpdateAccessoriesSwitchPageModel.hpp"
+
+class UpdateAccessoriesSwitchPagePresenter : public ListPresenter
+{
+       public:
+       UpdateAccessoriesSwitchPagePresenter(std::string switchId);
+       ~UpdateAccessoriesSwitchPagePresenter();
+
+       private:
+       void onTop() override;
+       std::string switchId_;
+       std::string activityId_;
+       Action *saveAction_ = nullptr;
+       Action *cancelAction_ = nullptr;
+       ListItem *entryItem_ = nullptr;
+       ListItem *actionItem_ = nullptr;
+       UpdateAccessoriesSwitchPageModel model_;
+};
+
+#endif
\ No newline at end of file
index 5495905613a1e3b4a3a0c2fa5ac8d5426bc0ff44..0720693148adf3785f02df778e605af610b0e801 100644 (file)
@@ -342,9 +342,9 @@ struct DefaultDBusWrapper : public DBusWrapper
        {
                return create(eldbus_proxy_method_call_new(get(proxy), funcName.c_str()));
        }
-       MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) override
+       MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg, double timeout) override
        {
-               return create(eldbus_proxy_send_and_block(get(proxy), release(msg), ELDBUS_CALL_TIMEOUT));
+               return create(eldbus_proxy_send_and_block(get(proxy), release(msg), timeout < 0 ? ELDBUS_TIMEOUT_INFINITE : timeout * 1000));
        }
        bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) override
        {
@@ -377,10 +377,10 @@ struct DefaultDBusWrapper : public DBusWrapper
                delete d;
        }
 
-       PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) override
+       PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback, double timeout) override
        {
                auto cb = new SendCallback{callback};
-               auto pending = eldbus_proxy_send(get(proxy), release(msg), callAsyncCb, cb, ELDBUS_CALL_TIMEOUT);
+               auto pending = eldbus_proxy_send(get(proxy), release(msg), callAsyncCb, cb, timeout < 0 ? ELDBUS_TIMEOUT_INFINITE : timeout * 1000);
                if (pending) {
                        eldbus_pending_free_cb_add(pending, pendingFreeCb, cb);
                } else {
index fc80948e2644ebb6a0fd47eb3fe2e49ba83f84b4..5dcfed7a129cfd8da7b9023faea3619072936433 100644 (file)
@@ -232,12 +232,12 @@ namespace DBus
                virtual MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) = 0;
                virtual MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &it, bool write) = 0;
                virtual MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) = 0;
-               virtual MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) = 0;
+               virtual MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg, double timeout) = 0;
                virtual bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) = 0;
                virtual std::string eldbus_message_signature_get_impl(const MessagePtr &msg) = 0;
 
                using SendCallback = std::function<void(const MessagePtr &msg)>;
-               virtual PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) = 0;
+               virtual PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback, double timeout) = 0;
                virtual std::string eldbus_proxy_interface_get_impl(const ProxyPtr &) = 0;
                virtual void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) = 0;
                virtual std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) = 0;
@@ -605,10 +605,10 @@ namespace DBus
                MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) override;
                MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &it, bool write) override;
                MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) override;
-               MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) override;
+               MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg, double timeout) override;
                bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) override;
                std::string eldbus_message_signature_get_impl(const MessagePtr &msg) override;
-               PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) override;
+               PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback, double timeout) override;
                std::string eldbus_proxy_interface_get_impl(const ProxyPtr &) override;
                void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) override;
                std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) override;
@@ -2549,7 +2549,7 @@ namespace DBus
                        DBusWrapper::ProxyPtr proxy, propertiesProxy;
                };
                template <typename RETTYPE, typename... ARGS>
-               RETTYPE call(CallId callId, const ConnectionState &connectionState, bool property, const std::string &funcName, const ARGS &... args)
+               RETTYPE call(CallId callId, const ConnectionState &connectionState, bool property, double timeout, const std::string &funcName, const ARGS &... args)
                {
                        const auto &proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
                        if (!proxy) {
@@ -2565,7 +2565,7 @@ namespace DBus
                        }
 
                        detail::packValues(callId, msg, args...);
-                       auto reply = DBUS_W->eldbus_proxy_send_and_block_impl(proxy, msg);
+                       auto reply = DBUS_W->eldbus_proxy_send_and_block_impl(proxy, msg, timeout);
                        DBUS_DEBUG("call %d: calling '%s' done", callId.id, funcName.c_str());
                        if (!reply) {
                                DBUS_DEBUG("call %d: failed", callId.id);
@@ -2581,7 +2581,7 @@ namespace DBus
                }
 
                template <typename RETTYPE, typename... ARGS>
-               void asyncCall(CallId callId, const ConnectionState &connectionState, bool property, const std::string &funcName, std::function<void(RETTYPE)> callback, const ARGS &... args)
+               void asyncCall(CallId callId, const ConnectionState &connectionState, bool property, double timeout, const std::string &funcName, std::function<void(RETTYPE)> callback, const ARGS &... args)
                {
                        const auto &proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
                        if (!proxy) {
@@ -2613,7 +2613,8 @@ namespace DBus
                                                callback(detail::unpackValues<RETTYPE>(callId, reply));
                                        }
                                }
-                       });
+                       },
+                               timeout);
                        if (pending) {
                                DBUS_DEBUG("call %d: call sent", callId.id);
                        } else {
@@ -2749,6 +2750,11 @@ namespace DBus
 
        using ConnectionType = DBusWrapper::ConnectionType;
 
+       struct InfinitiveTimeout_
+       {
+       };
+       static constexpr InfinitiveTimeout_ InfinitiveTimeout;
+
        /**
        * @brief Class representing client's end of DBUS connection
        *
@@ -2756,6 +2762,7 @@ namespace DBus
        * Allows (synchronous and asynchronos) setting / getting properties.
        * Allows registering signals.
        */
+
        class DBusClient
        {
                /// \cond
@@ -2829,6 +2836,7 @@ namespace DBus
                        std::string funcName;
                        std::string info;
                        std::shared_ptr<ConnectionInfo> connectionInfo;
+                       double timeout_ = 1.0;
                        /// \endcond
 
                        /**
@@ -2844,9 +2852,20 @@ namespace DBus
                        {
                                detail::CallId callId;
                                detail::displayDebugCallInfo(callId, funcName, info, connectionInfo->interfaceName);
-                               return detail::call<RetType>(callId, connectionState, false, funcName, args...);
+                               return detail::call<RetType>(callId, connectionState, false, timeout_, funcName, args...);
+                       }
+
+                       auto &timeout(double d)
+                       {
+                               timeout_ = d;
+                               return *this;
                        }
 
+                       auto &timeout(InfinitiveTimeout_)
+                       {
+                               timeout_ = -1;
+                               return *this;
+                       }
                        /**
                         * @brief Executes asynchronous call on DBUS's method
                         *
@@ -2860,7 +2879,7 @@ namespace DBus
                        {
                                detail::CallId callId;
                                detail::displayDebugCallInfo(callId, funcName, info, connectionInfo->interfaceName);
-                               detail::asyncCall<RetType>(callId, connectionState, false, funcName, std::move(callback), args...);
+                               detail::asyncCall<RetType>(callId, connectionState, false, timeout_, funcName, std::move(callback), args...);
                        }
                };
 
index fca5d6716427cfe256753c508c7f1c7205bdbda0..36fb43115ea2f4547eaf5bc4f3f9f18506afa230 100644 (file)
@@ -26,3 +26,13 @@ void Entry::moveCursorToEnd()
 {
        elm_entry_cursor_end_set(uniqueObj_.get());
 }
+
+void Entry::setSingleline(bool singleline)
+{
+       elm_entry_single_line_set(uniqueObj_.get(), singleline ? EINA_TRUE : EINA_FALSE);
+}
+
+bool Entry::isSingleline()
+{
+       return elm_entry_single_line_get(uniqueObj_.get()) != EINA_FALSE;
+}
index 744c6d2105e089e2d2f62fd3beb4cb7267d5f433..2ae710a60021519c67b879ce3706a7581a2f76cd 100644 (file)
@@ -12,6 +12,8 @@ class Entry : public Widget
        void setEntryText(const TranslatedString &text);
        std::string getEntryText();
        void moveCursorToEnd();
+       void setSingleline(bool singleline);
+       bool isSingleline();
 
        protected:
        using Widget::Widget;
index 56ee340a10908083b79db040aa635149287bea7f..ae56774bdd25f61bb67679f879f22df5aa070133 100644 (file)
@@ -362,6 +362,7 @@ Evas_Object *GenlistItem::realizeEntry(const std::string &part)
        auto entry = Widget::make<Entry>(layout);
        layout->setPartContent("elm.swallow.content", entry);
        entry->setEntryText(entryText_);
+       entry->setSingleline(true);
        entry->setEvasSmartCallback("changed,user", [=]() {
                this->entryText_ = entry->getEntryText();
                if (onContentValueChanged_) {
diff --git a/src/view/LabelView.cpp b/src/view/LabelView.cpp
new file mode 100644 (file)
index 0000000..d6fa2f7
--- /dev/null
@@ -0,0 +1,27 @@
+#include "LabelView.hpp"
+
+#include "AppContext.hpp"
+#include "Button.hpp"
+#include "NavigationContext.hpp"
+#include "Singleton.hpp"
+
+#define EDJ_ACCESSORY "edje/accessibility-smart-switch-accessory.edj"
+#define GRP_ACCESSORY "accessory"
+#define PRT_ACCESSORY_LABEL "accessory_label"
+
+LabelView::LabelView(const NavigationContext &context, Presenter *presenter)
+       : NaviframeView(context), labelPresenter_(static_cast<LabelPresenter *>(presenter))
+{
+       auto naviframe = context.getNaviframe();
+       layout_ = Widget::make<Layout>(naviframe, EDJ_ACCESSORY, GRP_ACCESSORY);
+       layout_->setText(PRT_ACCESSORY_LABEL, labelPresenter_->labelText_.value());
+
+       labelPresenter_->labelText_.attach([this](auto value) {
+               layout_->setText(PRT_ACCESSORY_LABEL, value);
+       });
+       backItem_ = Widget::make<Button>(context.getNaviframe(),
+               []() { Singleton<AppContext>::instance().pop(); },
+               "IDS_ST_BUTTON_BACK",
+               Button::BACK_BUTTON_ARROW_STYLE);
+       naviframeItem_ = naviframe->pushBack(labelPresenter_->getTitle(), layout_, {}, backItem_);
+}
\ No newline at end of file
diff --git a/src/view/LabelView.hpp b/src/view/LabelView.hpp
new file mode 100644 (file)
index 0000000..2ac3d58
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef LABEL_VIEW
+#define LABEL_VIEW
+
+#include "Label.hpp"
+#include "LabelPresenter.hpp"
+#include "Layout.hpp"
+#include "NaviframeView.hpp"
+
+class LabelView : public NaviframeView
+{
+       public:
+       LabelView(const NavigationContext &context, Presenter *presenter);
+
+       protected:
+       LabelPresenter *labelPresenter_;
+       Layout *layout_;
+       Widget *backItem_ = nullptr;
+};
+
+#endif
\ No newline at end of file
index 3eab1abe899d8e8b8c76306ef31eb2547bc068c8..c77a095247b8b69448eb0ac75371811278b2a960 100644 (file)
@@ -13,8 +13,8 @@ ListView::ListView(const NavigationContext &context, Presenter *presenter)
 {
        ASSERT(listPresenter_, "ListPresenter required");
 
-       auto naviframe = context.getNaviframe();
-       genlist_ = Widget::make<Genlist>(naviframe);
+       naviframe_ = context.getNaviframe();
+       genlist_ = Widget::make<Genlist>(naviframe_);
        genlist_->setMode(ELM_LIST_COMPRESS);
        genlist_->setStyle("dialogue");
 
@@ -25,8 +25,60 @@ ListView::ListView(const NavigationContext &context, Presenter *presenter)
                addItemsToGenlist();
        });
 
+       if (!isToolbarNeeded())
+               handleNonToolbarActionsBeforeNaviframePush();
+
+       auto style = isToolbarNeeded() ? "tabbar/notitle" : std::string{};
+       naviframeItem_ = naviframe_->pushBack(listPresenter_->getTitle(), genlist_, {}, backItem_, style);
+
+       if (isToolbarNeeded())
+               handleToolbarActions();
+       else
+               handleNonToolbarActionsAfterNaviframePush();
+}
+
+ListView::~ListView()
+{
+       if (titleRightButton_) {
+               auto parent = titleRightButton_->getParent();
+               parent->removeChild(titleRightButton_);
+       }
+       if (toolbar_) {
+               auto parent = toolbar_->getParent();
+               parent->removeChild(toolbar_);
+       }
+}
+
+bool ListView::isToolbarNeeded()
+{
+       auto cancelAction = listPresenter_->getAction("cancelAction");
+       auto saveAction = listPresenter_->getAction("saveAction");
+       return cancelAction || saveAction;
+}
+
+void ListView::handleToolbarActions()
+{
+       auto cancelAction = listPresenter_->getAction("cancelAction");
+       auto saveAction = listPresenter_->getAction("saveAction");
+       toolbar_ = Widget::make<Toolbar>(naviframe_);
+       if (cancelAction) {
+               toolbar_->addItem(cancelAction->title_.value(), [=]() {
+                       cancelAction->onInvoke_(cancelAction);
+               });
+       }
+       if (saveAction) {
+               toolbar_->addItem(saveAction->title_.value(), [=]() {
+                       saveAction->onInvoke_(saveAction);
+               });
+       }
+       if (naviframeItem_)
+               naviframeItem_.setPartContent("tabbar", toolbar_);
+}
+
+void ListView::handleNonToolbarActionsBeforeNaviframePush()
+{
        if (auto action = listPresenter_->getAction("selectAll")) {
-               auto checkbox = Widget::make<Check>(context.getNaviframe());
+               auto checkbox = Widget::make<Check>(naviframe_);
                checkbox->setState(action->state_.value());
                checkbox->setEvasSmartCallback("changed", [this, action, checkbox]() {
                        action->state_ = checkbox->getState();
@@ -43,7 +95,7 @@ ListView::ListView(const NavigationContext &context, Presenter *presenter)
                        auto wrappedOnClick = [this, action]() {
                                action->onInvoke_(action);
                        };
-                       backItem_ = Widget::make<Button>(context.getNaviframe(),
+                       backItem_ = Widget::make<Button>(naviframe_,
                                wrappedOnClick,
                                "IDS_ST_BUTTON_BACK",
                                Button::BACK_BUTTON_ARROW_STYLE);
@@ -51,17 +103,18 @@ ListView::ListView(const NavigationContext &context, Presenter *presenter)
                                backItem_->disable(!val);
                        });
                } else {
-                       backItem_ = Widget::make<Button>(context.getNaviframe(),
+                       backItem_ = Widget::make<Button>(naviframe_,
                                []() { Singleton<AppContext>::instance().pop(); },
                                "IDS_ST_BUTTON_BACK",
                                Button::BACK_BUTTON_ARROW_STYLE);
                }
        }
+}
 
-       naviframeItem_ = naviframe->pushBack(listPresenter_->getTitle(), genlist_, {}, backItem_);
-
+void ListView::handleNonToolbarActionsAfterNaviframePush()
+{
        if (auto action = listPresenter_->getAction("titleRightAction")) {
-               titleRightButton_ = Widget::make<Button>(context.getNaviframe(), [this, action]() {
+               titleRightButton_ = Widget::make<Button>(naviframe_, [this, action]() {
                        action->onInvoke_(action);
                },
                        "<font_size=30>" + TranslatedString{action->title_.value()}.str() + "</font_size>",
@@ -74,15 +127,7 @@ ListView::ListView(const NavigationContext &context, Presenter *presenter)
                action->enabled_.attach([this](auto val) {
                        titleRightButton_->disable(!val);
                });
-               naviframe->setPartContent("title_right_btn", titleRightButton_);
-       }
-}
-
-ListView::~ListView()
-{
-       if (titleRightButton_) {
-               auto parent = titleRightButton_->getParent();
-               parent->removeChild(titleRightButton_);
+               naviframe_->setPartContent("title_right_btn", titleRightButton_);
        }
 }
 
@@ -130,7 +175,7 @@ void ListView::addItemsToGenlist()
                                genlistItem = genlist_->appendItem({style,
                                                                                                           it->title_.value(),
                                                                                                           it->description_.value(),
-                                                                                                          it->onItemSelection_ ? wrappedOnItemSelection : std::function<void(GenlistItem *)>{},
+                                                                                                          wrappedOnItemSelection,
                                                                                                           it->iconPath_,
                                                                                                           type},
                                        groupItem);
@@ -138,9 +183,9 @@ void ListView::addItemsToGenlist()
                                genlistItem = genlist_->appendItem({style,
                                                                                                           it->title_.value(),
                                                                                                           it->description_.value(),
-                                                                                                          it->onItemSelection_ ? wrappedOnItemSelection : std::function<void(GenlistItem *)>{},
-                                                                                                          it->onWidgetSelection_ ? wrappedOnWidgetSelection : std::function<void(GenlistItem *)>{},
-                                                                                                          it->onWidgetChanged_ ? wrappedOnWidgetChanged : std::function<void(GenlistItem *)>{},
+                                                                                                          wrappedOnItemSelection,
+                                                                                                          wrappedOnWidgetSelection,
+                                                                                                          wrappedOnWidgetChanged,
                                                                                                           type},
                                        groupItem);
 
index 094647127e28074bdbeac45d08596fb761f86892..88b7739a7304bce63df0f45940b65e7bf336c9c8 100644 (file)
@@ -5,6 +5,7 @@
 #include "ListPresenter.hpp"
 #include "NaviframeView.hpp"
 #include "Presenter.hpp"
+#include "Toolbar.hpp"
 
 #include <unordered_map>
 
@@ -16,6 +17,10 @@ class ListView : public NaviframeView
 
        private:
        void addItemsToGenlist();
+       bool isToolbarNeeded();
+       void handleToolbarActions();
+       void handleNonToolbarActionsBeforeNaviframePush();
+       void handleNonToolbarActionsAfterNaviframePush();
        GenlistItem::WidgetType translateType(ListItem::WidgetType t);
 
        ListPresenter *listPresenter_ = nullptr;
@@ -23,6 +28,8 @@ class ListView : public NaviframeView
        std::unordered_map<GenlistItem *, ListItem *> itemsMapping_;
        Widget *backItem_ = nullptr;
        Button *titleRightButton_ = nullptr;
+       Toolbar *toolbar_ = nullptr;
+       Naviframe *naviframe_ = nullptr;
 };
 
 #endif
\ No newline at end of file
index fadda6468a111ba4ac1c169a97657d16178403ac..8877051de5505d262ac4e19a3d8206b979a00e69 100644 (file)
@@ -1,38 +1,79 @@
 #include "ModalView.hpp"
 
+#include "AppContext.hpp"
 #include "Button.hpp"
 #include "NavigationContext.hpp"
-#include "Popup.hpp"
+#include "Singleton.hpp"
+
+#define EDJ_ACCESSORY_POPUP "edje/accessibility-smart-switch-accessory-popup.edj"
+#define GRP_ACCESSORY_POPUP "accessory_popup"
+#define PRT_ACCESSORY_POPUP_LABEL "accessory_popup_label"
+#define PRT_ACCESSORY_POPUP_ENTRY "accessory_popup_entry"
 
 ModalView::ModalView(const NavigationContext &context, ModalPresenter *presenter)
        : View(context), presenter_(presenter)
 {
        auto naviframe = context.getNaviframe();
-       auto popup = Widget::make<Popup>(naviframe, presenter_->getTitle());
-       popup->setOrientation(ELM_POPUP_ORIENT_CENTER);
+       popup_ = Widget::make<Popup>(naviframe, presenter_->getTitle());
+       popup_->setOrientation(ELM_POPUP_ORIENT_CENTER);
 
-       popup->setText(presenter_->getText());
+       auto text = presenter_->getText();
+       if (auto action = presenter_->getAction("modalEntry")) {
+               layout_ = Widget::make<Layout>(popup_, EDJ_ACCESSORY_POPUP, GRP_ACCESSORY_POPUP);
+               entry_ = Widget::make<Entry>(layout_);
+               entry_->setWeightHint(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+               if (!text.empty())
+                       entry_->setEntryText(text);
+               if (!action->title_.value().empty())
+                       entry_->setPartText("guide", action->title_.value());
+               entry_->setEvasSmartCallback("changed,user", [=]() {
+                       action->title_ = entry_->getEntryText();
+                       if (action->onInvoke_)
+                               action->onInvoke_(action);
+               });
+               layout_->setPartContent(PRT_ACCESSORY_POPUP_ENTRY, entry_);
+               popup_->setContent(layout_);
+       } else {
+               if (!text.empty())
+                       popup_->setText(text);
+       }
 
-       auto removeCb = [p = popup, nf = naviframe, this]() {
+       auto removeCb = [this]() {
                auto c = presenter_->getCancelCb();
                if (c)
                        c();
-               nf->removeChild(p);
+               else
+                       Singleton<AppContext>::instance().popModal();
        };
-       popup->setEextEventCallback(EEXT_CALLBACK_BACK, removeCb);
-       popup->setEvasSmartCallback("dismissed", removeCb);
-       popup->setEvasSmartCallback("block,clicked", removeCb);
+       popup_->setEextEventCallback(EEXT_CALLBACK_BACK, removeCb);
+       popup_->setEvasSmartCallback("dismissed", removeCb);
+       popup_->setEvasSmartCallback("block,clicked", removeCb);
 
-       auto cancelBtn = Widget::make<Button>(popup, removeCb, "IDS_ST_BUTTON_CANCEL", "bottom");
-       popup->setPartContent("button1", cancelBtn);
+       auto cancelText = presenter_->getCancelText();
+       if (!cancelText.empty()) {
+               auto cancelBtn = Widget::make<Button>(popup_, removeCb, cancelText, "bottom");
+               popup_->setPartContent("button1", cancelBtn);
+       }
 
-       auto doneBtn = Widget::make<Button>(popup, [this, p = popup, nf = naviframe]() {
-               auto c = presenter_->getDoneCb();
-               if (c)
-                       c();
-               nf->removeChild(p);
-       },
-               presenter->getDoneText(),
-               "bottom");
-       popup->setPartContent("button2", doneBtn);
+       auto doneText = presenter_->getDoneText();
+       if (!doneText.empty()) {
+               auto doneBtn = Widget::make<Button>(popup_, [this]() {
+                       auto c = presenter_->getDoneCb();
+                       if (c)
+                               c();
+                       else
+                               Singleton<AppContext>::instance().popModal();
+               },
+                       doneText,
+                       "bottom");
+               popup_->setPartContent(cancelText.empty() ? "button1" : "button2", doneBtn);
+       }
+}
+
+ModalView::~ModalView()
+{
+       if (popup_) {
+               auto parent = popup_->getParent();
+               parent->removeChild(popup_);
+       }
 }
\ No newline at end of file
index d5cad0dd6ab4515b3223c52b4eeaa5a7ed2fea51..8850b8e93cffba89a155e2fb9a55a7d59e9b47c0 100644 (file)
@@ -1,15 +1,22 @@
 #ifndef MODAL_VIEW_HPP
 #define MODAL_VIEW_HPP
 
+#include "Entry.hpp"
+#include "Layout.hpp"
 #include "ModalPresenter.hpp"
+#include "Popup.hpp"
 #include "View.hpp"
 
 class ModalView : public View
 {
        public:
        ModalView(const NavigationContext &context, ModalPresenter *presenter);
+       ~ModalView();
 
        protected:
+       Popup *popup_ = nullptr;
+       Layout *layout_ = nullptr;
+       Entry *entry_ = nullptr;
        ModalPresenter *presenter_ = nullptr;
 };
 
index 2d60bfce67b13e5b2c32756c5ca08d8bd9054204..25963f7aebf2663d583c84e3722cb6f806cb228e 100644 (file)
@@ -2,6 +2,8 @@
 
 #include "AppContext.hpp"
 #include "Conformant.hpp"
+#include "LabelPresenter.hpp"
+#include "LabelView.hpp"
 #include "ListPresenter.hpp"
 #include "ListView.hpp"
 #include "Singleton.hpp"
@@ -84,6 +86,11 @@ void NavigationContext::emplaceView(Presenter *presenter)
                return;
        }
 
+       if (auto lp = dynamic_cast<LabelPresenter *>(presenter)) {
+               viewsStack_.push_back(std::make_unique<LabelView>(*this, lp));
+               return;
+       }
+
        ASSERT(0, "Presenter not supported");
 }