Copy efl wrapper from accessibility-settimg 46/211346/2
authorOskar Chodowicz <o.chodowicz@samsung.com>
Thu, 1 Aug 2019 13:18:05 +0000 (15:18 +0200)
committerOskar Chodowicz <o.chodowicz@samsung.com>
Fri, 2 Aug 2019 08:44:46 +0000 (08:44 +0000)
Change-Id: I2a11389924f5fd7d7a044433f2756c96b93993fb

16 files changed:
CMakeLists.txt
packaging/org.tizen.universal-switch.spec
src/CMakeLists.txt
src/ui/Layout.cpp [new file with mode: 0644]
src/ui/Layout.hpp [new file with mode: 0644]
src/ui/Popup.cpp [new file with mode: 0644]
src/ui/Popup.hpp [new file with mode: 0644]
src/ui/Widget.cpp [new file with mode: 0644]
src/ui/Widget.hpp [new file with mode: 0644]
src/ui/Window.cpp [new file with mode: 0644]
src/ui/Window.hpp [new file with mode: 0644]
src/utils/Observable.hpp [new file with mode: 0644]
src/utils/TranslatedString.cpp [new file with mode: 0644]
src/utils/TranslatedString.hpp [new file with mode: 0644]
src/utils/WidgetCallback.hpp [new file with mode: 0644]
src/utils/utils.hpp [new file with mode: 0644]

index dd6a6510fac8173bf43bb544637675f8defdd439..4cb8579e57a3bb6c5cf1ddf3ed8e72cbbaec6491 100644 (file)
@@ -13,6 +13,7 @@ option(DOCS "Build documentation" OFF)
 
 pkg_check_modules(pkgs REQUIRED
     atspi-2
+    appcore-efl
     capi-appfw-service-application
     capi-appfw-application
     capi-appfw-app-manager
@@ -39,7 +40,7 @@ pkg_check_modules(pkgs REQUIRED
 
 SET(COMMON_FLAGS "-fdiagnostics-color=always -fPIC")
 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_FLAGS}")
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_FLAGS} -std=c++14 -g")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_FLAGS} -std=c++17 -g")
 
 # install desktop file & icon
 SET(RES_DIR "${CMAKE_INSTALL_PREFIX}/res")
index ad7b264d8943b72eefce557dba66ddd544e8e85c..7dd7dd153e29099f63be553834c5c9a27bbe348f 100644 (file)
@@ -14,6 +14,8 @@ BuildRequires:  cmake
 BuildRequires:  gettext-tools
 BuildRequires:  tts
 BuildRequires:  tts-devel
+BuildRequires:  pkgconfig(appcore-efl)
+BuildRequires:  pkgconfig(appcore-common)
 BuildRequires:  pkgconfig(capi-appfw-service-application)
 BuildRequires:  pkgconfig(capi-appfw-application)
 BuildRequires:  pkgconfig(capi-appfw-app-manager)
index e3d588e82a0ffb0e825c9a916f50811eabd73227..aabf9a3598edea3637dc1096c9e8ce60c509f9f7 100644 (file)
@@ -1,4 +1,4 @@
-FILE(GLOB SRCS *.cpp batch/*.cpp ./hiberlite/src/*.cpp)
+FILE(GLOB SRCS *.cpp batch/*.cpp ./hiberlite/src/*.cpp ./ui/*.cpp ./utils/*.cpp)
 
 ADD_LIBRARY(universal-switch-obj OBJECT ${SRCS})
 
diff --git a/src/ui/Layout.cpp b/src/ui/Layout.cpp
new file mode 100644 (file)
index 0000000..af3d99e
--- /dev/null
@@ -0,0 +1,49 @@
+#include "Layout.hpp"
+
+#include "../UniversalSwitchLog.hpp"
+
+#include <app.h>
+
+namespace ui
+{
+
+       void Layout::createEflObject()
+       {
+               uniqueObj_.reset(elm_layout_add(parent_->getObject()));
+       }
+
+       void Layout::createEflObject(const std::string &edjeFile, const std::string &group)
+       {
+               createEflObject();
+               setWeightHint(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+               std::string edjePath;
+               if (auto resPath = app_get_resource_path()) {
+                       edjePath = std::string{resPath} + edjeFile;
+                       free(resPath);
+               }
+               setFile(edjePath, group);
+       }
+
+       void Layout::setContent(const std::string &swallow, Widget *widget)
+       {
+               elm_layout_content_set(uniqueObj_.get(), swallow.c_str(), widget->getObject());
+       }
+
+       void Layout::setFile(const std::string &edjeFile, const std::string &group)
+       {
+               elm_layout_file_set(uniqueObj_.get(), edjeFile.c_str(), group.c_str());
+       }
+
+       void Layout::setTheme(const std::string &klass, const std::string &group, const std::string &style)
+       {
+               elm_layout_theme_set(uniqueObj_.get(), klass.c_str(), group.c_str(), style.c_str());
+       }
+
+       void Layout::setText(const std::string &part, const TranslatedString &text)
+       {
+               if (elm_layout_text_set(uniqueObj_.get(), part.c_str(), text.c_str()) == EINA_FALSE)
+                       WARNING("Failed to set text: %s", text.c_str());
+       }
+
+}
diff --git a/src/ui/Layout.hpp b/src/ui/Layout.hpp
new file mode 100644 (file)
index 0000000..dd49ad1
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef LAYOUT_HPP
+#define LAYOUT_HPP
+
+#include "Widget.hpp"
+
+namespace ui
+{
+       class Layout : public Widget
+       {
+               template <typename T, typename... Args>
+               friend T *Widget::make(Widget *parent, Args &&... args);
+
+               public:
+               void setContent(const std::string &swallow, Widget *widget);
+               void setFile(const std::string &edjeFile, const std::string &group);
+               void setTheme(const std::string &klass, const std::string &group, const std::string &style);
+               void setText(const std::string &part, const TranslatedString &text);
+
+               protected:
+               using Widget::Widget;
+
+               private:
+               void createEflObject();
+               void createEflObject(const std::string &edjeFile, const std::string &group);
+       };
+
+}// namespace ui
+#endif
diff --git a/src/ui/Popup.cpp b/src/ui/Popup.cpp
new file mode 100644 (file)
index 0000000..82de293
--- /dev/null
@@ -0,0 +1,27 @@
+#include "Popup.hpp"
+
+namespace ui
+{
+       void Popup::createEflObject()
+       {
+               uniqueObj_.reset(elm_popup_add(parent_->getObject()));
+               setWeightHint(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+               show();
+       }
+
+       void Popup::createEflObject(const TranslatedString &title)
+       {
+               createEflObject();
+               setPartText("title,text", title);
+       }
+
+       void Popup::setOrientation(Elm_Popup_Orient orientation)
+       {
+               elm_popup_orient_set(uniqueObj_.get(), orientation);
+       }
+
+       void Popup::setAlignment(double h, double v)
+       {
+               elm_popup_align_set(uniqueObj_.get(), h, v);
+       }
+} //namesapce ui
diff --git a/src/ui/Popup.hpp b/src/ui/Popup.hpp
new file mode 100644 (file)
index 0000000..ea8f526
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef POPUP_HPP
+#define POPUP_HPP
+
+#include "Widget.hpp"
+
+namespace ui
+{
+       class Popup : public Widget
+       {
+               template <typename T, typename... Args>
+               friend T *Widget::make(Widget *parent, Args &&... args);
+
+               public:
+               void setOrientation(Elm_Popup_Orient orientation);
+               void setAlignment(double h, double v);
+
+               protected:
+               using Widget::Widget;
+
+               private:
+               void createEflObject();
+               void createEflObject(const TranslatedString &title);
+       };
+} //namespace ui
+#endif
diff --git a/src/ui/Widget.cpp b/src/ui/Widget.cpp
new file mode 100644 (file)
index 0000000..2e37e56
--- /dev/null
@@ -0,0 +1,204 @@
+#include "Widget.hpp"
+
+#include "../UniversalSwitchLog.hpp"
+
+namespace ui
+{
+
+       Widget::Widget(Widget *parent)
+               : parent_(parent)
+       {}
+
+       Widget::~Widget()
+       {
+               for (auto &it : smartCallbacks_) {
+                       evas_object_smart_callback_del(getObject(), it.first.c_str(), smartCallbackMethod);
+               }
+       }
+
+       void Widget::setText(const TranslatedString &text)
+       {
+               elm_object_text_set(uniqueObj_.get(), text.c_str());
+       }
+
+       void Widget::setPartText(const std::string &partName, const TranslatedString &text)
+       {
+               elm_object_part_text_set(uniqueObj_.get(), partName.c_str(), text.c_str());
+       }
+
+       void Widget::setWeightHint(double x, double y)
+       {
+               evas_object_size_hint_weight_set(uniqueObj_.get(), x, y);
+       }
+
+       void Widget::setAlignHint(double x, double y)
+       {
+               evas_object_size_hint_align_set(uniqueObj_.get(), x, y);
+       }
+
+       void Widget::setMinSizeHint(Evas_Coord v, Evas_Coord h)
+       {
+               evas_object_size_hint_min_set(uniqueObj_.get(), v, h);
+       }
+
+       void Widget::setMaxSizeHint(Evas_Coord v, Evas_Coord h)
+       {
+               evas_object_size_hint_max_set(uniqueObj_.get(), v, h);
+       }
+
+       void Widget::setAspectHint(Evas_Aspect_Control aspect, Evas_Coord w, Evas_Coord h)
+       {
+               evas_object_size_hint_aspect_set(uniqueObj_.get(), aspect, w, h);
+       }
+
+       Rectangle Widget::getGeometry()
+       {
+               int x, y, w, h;
+               evas_object_geometry_get(uniqueObj_.get(), &x, &y, &w, &h);
+               return {{x, y}, {w, h}};
+       }
+
+       void Widget::setPosition(Point anchor)
+       {
+               evas_object_move(uniqueObj_.get(), anchor.x, anchor.y);
+       }
+
+       void Widget::setEvasSmartCallback(const std::string &eventName, std::function<void()> callback)
+       {
+               auto cbData = std::make_unique<WidgetCallback::Data<Widget, std::string>>(this, eventName);
+               auto dataPtr = cbData.get();
+               smartCallbacks_.insert_or_assign(eventName, WidgetCallback::Value<Widget, std::string>{std::move(callback), std::move(cbData)});
+               evas_object_smart_callback_add(getObject(), eventName.c_str(), smartCallbackMethod, dataPtr);
+       }
+
+       void Widget::removeEvasSmartCallback(const std::string &eventName)
+       {
+               evas_object_smart_callback_del(uniqueObj_.get(), eventName.c_str(), smartCallbackMethod);
+               smartCallbacks_.erase(eventName);
+       }
+
+       void Widget::setEextEventCallback(const Eext_Callback_Type type, std::function<void()> callback)
+       {
+               auto cbData = std::make_unique<WidgetCallback::Data<Widget, Eext_Callback_Type>>(this, type);
+               auto dataPtr = cbData.get();
+               eextEventCallbacks_.insert_or_assign(
+                       type, WidgetCallback::Value<Widget, Eext_Callback_Type>{std::move(callback), std::move(cbData)});
+               eext_object_event_callback_add(getObject(), type, eextEventMethod, dataPtr);
+       }
+
+       void Widget::setStyle(const std::string &style)
+       {
+               elm_object_style_set(uniqueObj_.get(), style.c_str());
+       }
+
+       void Widget::setColor(int r, int g, int b, int a)
+       {
+               evas_object_color_set(uniqueObj_.get(), r, g, b, a);
+       }
+
+       void Widget::setContent(Widget *widget)
+       {
+               elm_object_content_set(uniqueObj_.get(), widget->getObject());
+       }
+
+       void Widget::setPartContent(const std::string &part, Widget *content)
+       {
+               elm_object_part_content_set(uniqueObj_.get(), part.c_str(), content->getObject());
+       }
+
+       void Widget::setHomogeneousDimensions()
+       {
+               elm_box_homogeneous_set(uniqueObj_.get(), EINA_TRUE);
+       }
+
+       void Widget::setPropagateEvents(bool prop)
+       {
+               evas_object_propagate_events_set(uniqueObj_.get(), prop ? EINA_TRUE : EINA_FALSE);
+       }
+
+       void Widget::disable(bool disable)
+       {
+               disable ? elm_object_disabled_set(uniqueObj_.get(), EINA_TRUE) : elm_object_disabled_set(uniqueObj_.get(), EINA_FALSE);
+       }
+
+       void Widget::emitSignal(const std::string &signal)
+       {
+               elm_object_signal_emit(uniqueObj_.get(), signal.c_str(), "");
+       }
+
+       void Widget::setFocus(bool focus)
+       {
+               elm_object_focus_set(uniqueObj_.get(), focus ? EINA_TRUE : EINA_FALSE);
+       }
+
+       void Widget::show()
+       {
+               evas_object_show(uniqueObj_.get());
+       }
+
+       void Widget::hide()
+       {
+               evas_object_hide(uniqueObj_.get());
+       }
+
+       void Widget::setPassEvents(bool pass)
+       {
+               evas_object_pass_events_set(uniqueObj_.get(), pass ? EINA_TRUE : EINA_FALSE);
+       }
+
+       Evas_Object *Widget::getObject()
+       {
+               return uniqueObj_.get();
+       }
+
+       Widget *Widget::getParent()
+       {
+               return parent_;
+       }
+
+       void Widget::addChild(std::unique_ptr<Widget> child)
+       {
+               child->parent_ = this;
+               children_.push_back(std::move(child));
+       }
+
+       void Widget::removeChild(Widget *child)
+       {
+               if (!child)
+                       return;
+
+               for (auto it = children_.begin(); it != children_.end(); ++it) {
+                       if (it->get() == child) {
+                               children_.erase(it);
+                               break;
+                       }
+               }
+       }
+
+       void Widget::smartCallbackMethod(void *data, Evas_Object *obj, void *event_info)
+       {
+               auto cbData = static_cast<WidgetCallback::Data<Widget, std::string> *>(data);
+
+               auto cb = cbData->self->smartCallbacks_.find(cbData->eventName);
+               if (cb == cbData->self->smartCallbacks_.end()) {
+                       ERROR("No callback registered for this event");
+                       return;
+               }
+               auto c = cb->second.callback;
+               c();
+       }
+
+       void Widget::eextEventMethod(void *data, Evas_Object *obj, void *event_info)
+       {
+               auto cbData = static_cast<WidgetCallback::Data<Widget, Eext_Callback_Type> *>(data);
+
+               auto cb = cbData->self->eextEventCallbacks_.find(cbData->eventName);
+               if (cb == cbData->self->eextEventCallbacks_.end()) {
+                       ERROR("No callback registered for this event");
+                       return;
+               }
+               auto c = cb->second.callback;
+               c();
+       }
+
+} //namesapce ui
\ No newline at end of file
diff --git a/src/ui/Widget.hpp b/src/ui/Widget.hpp
new file mode 100644 (file)
index 0000000..61e20c4
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef WIDGET_HPP
+#define WIDGET_HPP
+
+#include "../Geometry.hpp"
+#include "../utils/TranslatedString.hpp"
+#include "../utils/WidgetCallback.hpp"
+#include "../utils/utils.hpp"
+
+#include <Elementary.h>
+#include <efl_extension.h>
+#include <functional>
+#include <memory>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+namespace ui
+{
+       class Widget
+       {
+               public:
+               Widget(const Widget &) = delete;
+               Widget(Widget &&) = delete;
+               virtual ~Widget();
+
+               template <typename T, typename... Args>
+               static T *make(Widget *parent, Args &&... args)
+               {
+                       auto raw = new T(parent);
+                       parent->addChild(std::unique_ptr<T>(raw));
+                       raw->createEflObject(std::forward<Args>(args)...);
+                       return raw;
+               }
+
+               void setText(const TranslatedString &text);
+               void setPartText(const std::string &partName, const TranslatedString &text);
+               void setWeightHint(double x, double y);
+               void setAlignHint(double x, double y);
+               void setMinSizeHint(Evas_Coord v, Evas_Coord h);
+               void setMaxSizeHint(Evas_Coord v, Evas_Coord h);
+               void setAspectHint(Evas_Aspect_Control aspect, Evas_Coord w, Evas_Coord h);
+               Rectangle getGeometry();
+               void setPosition(Point anchor);
+               void setEvasSmartCallback(const std::string &eventName, std::function<void()> callback);
+               void removeEvasSmartCallback(const std::string &eventName);
+               void setEextEventCallback(const Eext_Callback_Type type, std::function<void()> callback);
+               void setStyle(const std::string &style);
+               void setColor(int r, int g, int b, int a);
+               void setContent(Widget *widget);
+               void setPartContent(const std::string &part, Widget *content);
+               void setHomogeneousDimensions();
+               void setPropagateEvents(bool prop);
+               void setFocus(bool focus);
+               void disable(bool disable);
+               void emitSignal(const std::string &signal);
+               void show();
+               void hide();
+               void setPassEvents(bool pass);
+
+               Evas_Object *getObject();
+               Widget *getParent();
+               void addChild(std::unique_ptr<Widget> child);
+               void removeChild(Widget *child);
+
+               protected:
+               Widget() = default;
+               Widget(Widget *parent);
+               static void smartCallbackMethod(void *data, Evas_Object *obj, void *event_info);
+               static void eextEventMethod(void *data, Evas_Object *obj, void *event_info);
+
+               std::unique_ptr<Evas_Object, utils::EvasDeleter> uniqueObj_;
+               Widget *parent_ = nullptr;
+               std::vector<std::unique_ptr<Widget>> children_;
+               std::unordered_map<std::string, WidgetCallback::Value<Widget, std::string>> smartCallbacks_;
+               std::unordered_map<Eext_Callback_Type, WidgetCallback::Value<Widget, Eext_Callback_Type>> eextEventCallbacks_;
+       };
+
+} //namespace ui
+
+#endif
diff --git a/src/ui/Window.cpp b/src/ui/Window.cpp
new file mode 100644 (file)
index 0000000..ff0b01a
--- /dev/null
@@ -0,0 +1,31 @@
+#include "Window.hpp"
+
+namespace ui
+{
+
+       Window::Window(const std::string &title)
+       {
+               uniqueObj_.reset(elm_win_add(NULL, NULL, ELM_WIN_BASIC));
+
+               elm_win_title_set(uniqueObj_.get(), title.c_str());
+
+               elm_win_indicator_mode_set(uniqueObj_.get(), ELM_WIN_INDICATOR_SHOW);
+               elm_win_indicator_opacity_set(uniqueObj_.get(), ELM_WIN_INDICATOR_OPAQUE);
+       }
+
+       void Window::setConformant(bool conformant)
+       {
+               elm_win_conformant_set(uniqueObj_.get(), conformant ? EINA_TRUE : EINA_FALSE);
+       }
+
+       void Window::addResizeObject(Widget *widget)
+       {
+               elm_win_resize_object_add(uniqueObj_.get(), widget->getObject());
+       }
+
+       void Window::addAvailableRotations(std::vector<int> rotations)
+       {
+               elm_win_wm_rotation_available_rotations_set(uniqueObj_.get(), rotations.data(), rotations.size());
+       }
+
+} //namespace ui
\ No newline at end of file
diff --git a/src/ui/Window.hpp b/src/ui/Window.hpp
new file mode 100644 (file)
index 0000000..dc6b1ef
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef WINDOW_HPP
+#define WINDOW_HPP
+
+#include "Widget.hpp"
+
+namespace ui
+{
+       class Window : public Widget
+       {
+               public:
+               Window(const std::string &title);
+
+               void setConformant(bool conformant);
+               void addResizeObject(Widget *widget);
+               void addAvailableRotations(std::vector<int> rotations);
+       };
+} // namespace ui
+#endif
diff --git a/src/utils/Observable.hpp b/src/utils/Observable.hpp
new file mode 100644 (file)
index 0000000..79accd9
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef OBSERVABLE_HPP
+#define OBSERVABLE_HPP
+
+#include <functional>
+#include <vector>
+
+template <typename... ARGS>
+class Observable
+{
+       public:
+       virtual ~Observable() = default;
+
+       void attach(std::function<void(ARGS...)> onChange)
+       {
+               onChangeCallbacks_.push_back(std::move(onChange));
+       }
+
+       protected:
+       void notify(ARGS... args)
+       {
+               for (auto &c : this->onChangeCallbacks_)
+                       if (c)
+                               c(args...);
+       }
+
+       std::vector<std::function<void(ARGS...)>> onChangeCallbacks_;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/utils/TranslatedString.cpp b/src/utils/TranslatedString.cpp
new file mode 100644 (file)
index 0000000..eb2d1c7
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2018 Samsung Electronics Co., Ltd
+ *
+ * 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 "TranslatedString.hpp"
+
+#include <appcore-common.h>
+#include <cstring>
+
+TranslatedString::TranslatedString(const std::string &str)
+       : value(std::string{gettext(str.c_str())})
+{}
+
+TranslatedString::TranslatedString(const char *str)
+       : value(std::string{gettext(str), strlen(gettext(str))})
+{}
+
+TranslatedString &TranslatedString::operator+=(const TranslatedString &ts)
+{
+       value += ts.value;
+       return *this;
+}
+
+bool TranslatedString::empty() const
+{
+       return value.empty();
+}
+
+std::string TranslatedString::str() const
+{
+       return value;
+}
+
+const char *TranslatedString::c_str() const
+{
+       return value.c_str();
+}
+
+TranslatedString operator+(TranslatedString lString, const TranslatedString &rString)
+{
+       lString += rString;
+       return lString;
+}
\ No newline at end of file
diff --git a/src/utils/TranslatedString.hpp b/src/utils/TranslatedString.hpp
new file mode 100644 (file)
index 0000000..0e98120
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2018 Samsung Electronics Co., Ltd
+ *
+ * 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 TRANSLATED_STRING_HPP
+#define TRANSLATED_STRING_HPP
+
+#include "../UniversalSwitchLog.hpp"
+
+#include <string>
+/**
+ * Class containing strings translated with usage of internatonalization API
+ *
+ * Main purpose of this class is to distinguish objects containing raw i18n keys
+ * from already translated
+ */
+class TranslatedString
+{
+       public:
+       TranslatedString() = default;
+       TranslatedString(const std::string &str);
+       TranslatedString(const char *str);
+
+       TranslatedString &operator+=(const TranslatedString &ts);
+
+       template <typename... ARGS>
+       static TranslatedString create(const char *str, const ARGS &... args)
+       {
+               char buf[1024] = {0};
+               auto ret = snprintf(buf, sizeof(buf), gettext(str), args...);
+               if (ret > 1024) {
+                       ERROR("snprintf failed");
+                       return {};
+               }
+               return {buf};
+       }
+
+       bool empty() const;
+
+       std::string str() const;
+       const char *c_str() const;
+
+       private:
+       std::string value;
+};
+
+TranslatedString operator+(TranslatedString lString, const TranslatedString &rString);
+
+#endif
diff --git a/src/utils/WidgetCallback.hpp b/src/utils/WidgetCallback.hpp
new file mode 100644 (file)
index 0000000..c2f39ef
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef WIDGET_CALLBACK_HPP
+#define WIDGET_CALLBACK_HPP
+
+#include <functional>
+#include <memory>
+#include <unordered_map>
+
+class Widget;
+
+namespace WidgetCallback
+{
+       template <typename S, typename T>
+       struct Data
+       {
+               Data(S *self, const T &name)
+                       : self(self), eventName(name)
+               {}
+
+               S *self = nullptr;
+               T eventName{};
+       };
+
+       template <typename S, typename T>
+       struct Value
+       {
+               std::function<void()> callback;
+               std::unique_ptr<Data<S, T>> data;
+       };
+
+} // namespace WidgetCallback
+#endif
diff --git a/src/utils/utils.hpp b/src/utils/utils.hpp
new file mode 100644 (file)
index 0000000..ac3d3b1
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2018 Samsung Electronics Co., Ltd
+ *
+ * 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 UTILS_HPP
+#define UTILS_HPP
+
+#include "Elementary.h"
+
+#include <sstream>
+#include <vector>
+
+using SettingCallback = void (*)(void *, Evas_Object *, void *);
+
+namespace utils
+{
+       struct EvasDeleter
+       {
+               template <typename T>
+               void operator()(T *t) const
+               {
+                       if (t)
+                               evas_object_del(t);
+               }
+       };
+
+       struct ElmGenlistItemClassDeleter
+       {
+               void operator()(Elm_Genlist_Item_Class *it) const
+               {
+                       if (it)
+                               elm_genlist_item_class_free(it);
+               }
+       };
+
+       template <typename T>
+       struct Range
+       {
+               T begin{};
+               T end{};
+       };
+
+       template <typename In, typename Out = double>
+       Out rescale(In value, Range<In> source, Range<Out> target = {0.0, 1.0})
+       {
+               auto denominator = source.end - source.begin;
+               auto rescaledValue = target.begin;
+               if (denominator != 0)
+                       rescaledValue += (value - source.begin) * (target.end - target.begin) / denominator;
+
+               return rescaledValue;
+       }
+
+       inline std::string doubleToPercent(double val)
+       {
+               return std::to_string(static_cast<int>(val * 100)) + "%";
+       }
+
+       inline std::string doubleToString(double val, size_t precision)
+       {
+               std::ostringstream out;
+               out.precision(1);
+
+               out << std::fixed << val;
+
+               return out.str();
+       }
+
+       inline std::vector<std::string> stringSplitByDelimiter(const std::string &s, char delimiter)
+       {
+               std::vector<std::string> tokens;
+               std::string token;
+               std::istringstream tokenStream(s);
+               while (std::getline(tokenStream, token, delimiter)) {
+                       tokens.push_back(token);
+               }
+               return tokens;
+       }
+} // namespace utils
+
+#endif