TizenRefApp-8585[Call UI] Implement VolumeControl view 68/131168/3
authorIgor Olshevskyi <i.olshevskyi@samsung.com>
Thu, 25 May 2017 14:18:10 +0000 (17:18 +0300)
committerIgor Olshevskyi <i.olshevskyi@samsung.com>
Tue, 30 May 2017 11:50:13 +0000 (14:50 +0300)
Change-Id: Icacfeeaae1d70c437bed7c65d7152506bd1511fd

edc/accessory.edc [new file with mode: 0644]
edc/buttons.edc
edc/color_classes.edc
edc/images/b_slider_btn_bg.png [new file with mode: 0644]
edc/images/b_slider_icon_minus.png [new file with mode: 0644]
edc/images/b_slider_icon_plus.png [new file with mode: 0644]
edc/volume_control.edc [new file with mode: 0644]
inc/view/VolumeControl.h [new file with mode: 0644]
inc/view/types.h
res/edje/theme.edc
src/view/VolumeControl.cpp [new file with mode: 0644]

diff --git a/edc/accessory.edc b/edc/accessory.edc
new file mode 100644 (file)
index 0000000..740a4e0
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * 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.
+ */
+
+/*
+#define CU_BTN_VOLUME_EFF_DEFAULT_SIZE 160 160
+#define CU_BTN_VOLUME_EFF_PRESSED_SIZE 144 144
+#define CU_BTN_VOLUME_ICON_SIZE 64 64
+
+#define CU_BTN_VOLUME_CONTROL(_name, _icon)
+       group { "elm/button/base/"_name;
+       images {
+               image: "w_call_button_press_circle.png" COMP;
+               image: _icon COMP;
+       }
+       parts {
+               image { "image.bg";
+                       nomouse;
+                       scale;
+                       desc { "default";
+                               fixed: 1 1;
+                               min: CU_BTN_VOLUME_EFF_DEFAULT_SIZE;
+                               image.normal: "w_call_button_press_circle.png";
+                               color: 255 255 255 0;
+                       }
+                       desc { "pressed_effect";
+                               inherit: "default";
+                               min: CU_BTN_VOLUME_EFF_PRESSED_SIZE;
+                               color: 255 255 255 33;
+                       }
+                       desc { "pressed";
+                               inherit: "pressed_effect";
+                               min: CU_BTN_VOLUME_EFF_DEFAULT_SIZE;
+                       }
+               }
+               image { "icon";
+                       scale;
+                       desc { "default";
+                               min: CU_BTN_VOLUME_ICON_SIZE;
+                               max: CU_BTN_VOLUME_ICON_SIZE;
+                               image.normal: _icon;
+                       }
+               }
+       }
+       programs {
+               program {
+                       signal: "mouse,clicked,*";
+                       source: "icon";
+                       action: SIGNAL_EMIT "elm,action,click" "";
+               }
+               program {
+                       signal: "mouse,down,*";
+                       source: "icon";
+                       sequence {
+                               action: STATE_SET "pressed_effect";
+                               target: "image.bg";
+                               action: STATE_SET "pressed";
+                               target: "image.bg";
+                               transition: TRANSITION_GLIDE(0.3);
+                       }
+               }
+               program {
+                       signal: "mouse,up,*";
+                       source: "icon";
+                       action: STATE_SET "default";
+                       target: "image.bg";
+                       transition: LINEAR 0.535;
+               }
+       }
+*/
+
+group { "elm/layout/callui/accessory";
+       parts {
+               swallow { "swl.volume_control"
+                       scale;
+                       desc { "default";
+                       }
+               }
+       }
+}
\ No newline at end of file
index 2b1b968feaedd8ce42e710d7dfb47b86a4c2790f..20ca4b325da9f15dcfb39942d961172dc52a9248 100644 (file)
 #define CU_BTN_BOTTOM_SIZE_INC              360 78
 #define CU_BTN_BOTTOM_ICON_SIZE_INC         50 50
 
+#define CU_BTN_VOLUME_EFF_DEFAULT_SIZE      160 160
+#define CU_BTN_VOLUME_EFF_PRESSED_SIZE      144 144
+#define CU_BTN_VOLUME_ICON_SIZE             64 64
+
 #define CU_BTN_INCOM_CALL(_name, _icon, _bg_cc, _effect_cc, _icon_norm_cc, _icon_pressed_cc) \
 group { "elm/button/base/"_name; \
        script { \
@@ -498,8 +502,110 @@ group { "elm/button/base/"_name; \
                } \
        }
 
+#define CU_BTN_VOLUME_CONTROL(_name, _icon) \
+       group { "elm/button/base/"_name; \
+       images { \
+               image: "w_call_button_press_circle.png" COMP; \
+               image: _icon COMP; \
+       } \
+       parts { \
+               image { "image.bg"; \
+                       nomouse; \
+                       scale; \
+                       desc { "default"; \
+                               fixed: 1 1; \
+                               min: CU_BTN_VOLUME_EFF_DEFAULT_SIZE; \
+                               image.normal: "w_call_button_press_circle.png"; \
+                               color: 255 255 255 0; \
+                       } \
+                       desc { "pressed_effect"; \
+                               inherit: "default"; \
+                               min: CU_BTN_VOLUME_EFF_PRESSED_SIZE; \
+                               color: 255 255 255 33; \
+                       } \
+                       desc { "pressed"; \
+                               inherit: "pressed_effect"; \
+                               min: CU_BTN_VOLUME_EFF_DEFAULT_SIZE; \
+                       } \
+               } \
+               image { "icon"; \
+                       scale; \
+                       clip_to: "icon.clipper"; \
+                       desc { "default"; \
+                               min: CU_BTN_VOLUME_ICON_SIZE; \
+                               max: CU_BTN_VOLUME_ICON_SIZE; \
+                               image.normal: _icon; \
+                       } \
+               } \
+               rect { "icon.clipper"; \
+                       scale; \
+                       desc { "default"; \
+                               rel.to: "icon"; \
+                               color_class: "FO22L1i"; \
+                       } \
+                       desc { "disabled"; \
+                               inherit: "default"; \
+                               color_class: "FO22L1iD"; \
+                       } \
+               } \
+               rect { "event"; \
+                       scale; \
+                       desc { "default"; \
+                               rel.to: "icon"; \
+                               color: 0 0 0 0; \
+                       } \
+                       desc { "disabled"; \
+                               inherit: "default"; \
+                               hid; \
+                       } \
+               } \
+       } \
+       programs { \
+               program { \
+                       signal: "mouse,clicked,*"; \
+                       source: "event"; \
+                       action: SIGNAL_EMIT "elm,action,click" ""; \
+               } \
+               program { \
+                       signal: "mouse,down,*"; \
+                       source: "event"; \
+                       sequence { \
+                               action: STATE_SET "pressed_effect"; \
+                               target: "image.bg"; \
+                               action: STATE_SET "pressed"; \
+                               target: "image.bg"; \
+                               transition: TRANSITION_GLIDE(0.3); \
+                       } \
+               } \
+               program { \
+                       signal: "mouse,up,*"; \
+                       source: "event"; \
+                       action: STATE_SET "default"; \
+                       target: "image.bg"; \
+                       transition: LINEAR 0.535; \
+               } \
+               program { \
+             signal: "elm,state,enabled"; \
+             source: "elm"; \
+             action: STATE_SET "default"; \
+             target: "event"; \
+             target: "icon.clipper"; \
+         } \
+               program { \
+            signal: "elm,state,disabled"; \
+            source: "elm"; \
+            action: STATE_SET "disabled"; \
+            target: "event"; \
+            target: "icon.clipper"; \
+         } \
+       } \
+}
+
 CU_BTN_INCOM_CALL("callui/accept", "w_call_incoming_icon_accept.png", "AO01131", "AO01132", "AO0113", "AO0113P")
 CU_BTN_INCOM_CALL("callui/reject", "w_call_incoming_icon_reject.png", "AO01151", "AO01152", "AO0115", "AO0115P")
 
 CU_BTN_BOTTOM("callui/end_call", "w_incoming_icon_end_phone.png", "AO0121", "AO0121P", "B013A", "B013")
 CU_BTN_BOTTOM("callui/call_back", "w_incoming_icon_call.png", "AO0171", "AO0171P", "B013A", "B013")
+
+CU_BTN_VOLUME_CONTROL("callui/minus", "b_slider_icon_minus.png")
+CU_BTN_VOLUME_CONTROL("callui/plus", "b_slider_icon_plus.png")
\ No newline at end of file
index 3f4f1b7411faffeb944dcb74df9914a8bd83984f..10e7ac48ce5ef5edd0fe07814d4f55dc02e1cd11 100644 (file)
@@ -98,4 +98,11 @@ color_classes {
        color_class { name: "B013";
                color: 0 146 204 77;
        }
+       color_class { name: "FO22L1i";
+               color: 255 255 255 255;
+       }
+       color_class { name: "FO22L1iD";
+               color: 255 255 255 90;
+       }
+
 }
diff --git a/edc/images/b_slider_btn_bg.png b/edc/images/b_slider_btn_bg.png
new file mode 100644 (file)
index 0000000..c061f95
Binary files /dev/null and b/edc/images/b_slider_btn_bg.png differ
diff --git a/edc/images/b_slider_icon_minus.png b/edc/images/b_slider_icon_minus.png
new file mode 100644 (file)
index 0000000..35affbe
Binary files /dev/null and b/edc/images/b_slider_icon_minus.png differ
diff --git a/edc/images/b_slider_icon_plus.png b/edc/images/b_slider_icon_plus.png
new file mode 100644 (file)
index 0000000..63e81d4
Binary files /dev/null and b/edc/images/b_slider_icon_plus.png differ
diff --git a/edc/volume_control.edc b/edc/volume_control.edc
new file mode 100644 (file)
index 0000000..8c9632e
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * 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.
+ */
+
+#define CU_VOLUME_PAD_TOP_MIN       0 39
+#define CU_VOLUME_PAD_BOTTOM_MIN    0 24
+#define CU_VOLUME_ACTION_ZONE_MIN   154 64
+#define CU_VOLUME_ACTION_BTN_SIZE   64 64
+#define CU_VOLUME_ACTION_BTN_MIN    0 7
+#define CU_VOLUME_VALUE_TXT_MIN     66 52
+#define CU_VOLUME_INFO_TXT_ZONE_MIN 168 74
+#define CU_VOLUME_INFO_TXT_MIN      168 37
+#define CU_VOLUME_ICON_SIZE         150 150
+
+styles {
+       style { "volume_value";
+               base: "font=Tizen font_weight=Bold font_width=Condensed font_size=40 align=center valign=center color=#FFFFFF ellipsis=1.0";
+       }
+       style { "volume_info";
+               base: "font=Tizen font_weight=Regular font_width=Condensed font_size=32 align=center valign=center color=#FFFFFF ellipsis=1.0";
+       }
+}
+
+group { "elm/layout/callui/volume_control";
+       images {
+               image: "b_slider_btn_bg.png" COMP;
+               image: "w_call_opt_volume.png" COMP;
+       }
+       parts {
+               spacer { "sizer"
+                       scale;
+                       desc { "default";
+                               min: 360 360;
+                       }
+               }
+               rect { "bg";
+                       scale;
+                       desc { "default";
+                               color: 0 0 0 191;
+                       }
+                       desc { "hide";
+                               hid;
+                       }
+               }
+               swallow { "swl.slider";
+                       scale;
+                       desc { "default";
+                               rel1.to: "sizer";
+                               rel2.to: "sizer";
+                       }
+               }
+               spacer { "pad.top";
+            scale;
+            desc { "default";
+                               min: CU_VOLUME_PAD_TOP_MIN;
+                               fixed: 0 1;
+                               rel1 { relative: 0.0 0.0; to: "sizer"; }
+                               rel2 { relative: 1.0 0.0; to: "sizer"; }
+                               align: 0.0 0.0;
+            }
+         }
+         spacer { "pad.bottom";
+            scale;
+                       desc { "default";
+                               min: CU_VOLUME_PAD_BOTTOM_MIN;
+                               fixed: 0 1;
+                               rel1 { relative: 0.0 1.0; to: "sizer"; }
+                               rel2 { relative: 1.0 1.0; to: "sizer"; }
+                               align: 0.0 1.0;
+                       }
+         }
+         spacer { "action_zone";
+               scale;
+               desc { "default";
+                       min: CU_VOLUME_ACTION_ZONE_MIN;
+                       max: CU_VOLUME_ACTION_ZONE_MIN;
+                       fixed: 1 1;
+                       rel1 { relative: 0.0 1.0; to_y: "pad.top"; }
+                       rel2 { relative: 1.0 1.0; to_y: "pad.top"; }
+                       align: 0.5 0.0;
+               }
+         }
+         spacer { "txt.value.pad.bottom";
+            scale;
+                       desc { "default";
+                               min: CU_VOLUME_ACTION_BTN_MIN;
+                               fixed: 0 1;
+                               rel1 { relative: 0.0 1.0; to: "action_zone"; }
+                               rel2 { relative: 1.0 1.0; to: "action_zone"; }
+                               align: 0.0 1.0;
+                       }
+               }
+               textblock { "txt.value";
+                       scale;
+                       desc { "default";
+                               min: CU_VOLUME_VALUE_TXT_MIN;
+                               fixed: 1 1;
+                               rel1 { relative: 0.5 0.0; to_y: "txt.value.pad.bottom"; }
+                               rel2 { relative: 0.5 0.0; to_y: "txt.value.pad.bottom"; }
+                               align: 0.5 1.0;
+                               text.style: "volume_value";
+                       }
+                       desc { "hide";
+                               hid;
+                       }
+               }
+               swallow { "swl.minus";
+               scale;
+               desc { "default";
+                       min: CU_VOLUME_ACTION_BTN_SIZE;
+                       max: CU_VOLUME_ACTION_BTN_SIZE;
+                       fixed: 1 1;
+                       rel1 { relative: 0.0 0.0; to: "action_zone"; }
+                       rel2 { relative: 0.0 1.0; to: "action_zone"; }
+                       align: 0.0 0.5;
+               }
+               desc { "hide";
+                               hid;
+                       }
+               }
+               swallow { "swl.plus";
+               scale;
+               desc { "default";
+                       min: CU_VOLUME_ACTION_BTN_SIZE;
+                       max: CU_VOLUME_ACTION_BTN_SIZE;
+                       fixed: 1 1;
+                       rel1 { relative: 1.0 0.0; to: "action_zone"; }
+                       rel2 { relative: 1.0 1.0; to: "action_zone"; }
+                       align: 1.0 0.5;
+               }
+               desc { "hide";
+                               hid;
+                       }
+         }
+               spacer { "txt.info.zone";
+                       scale;
+               desc { "default";
+                       min: CU_VOLUME_INFO_TXT_ZONE_MIN;
+                       fixed: 1 1;
+                       rel1 { relative: 0.5 0.0; to_y: "pad.bottom"; }
+                               rel2 { relative: 0.5 0.0; to_y: "pad.bottom"; }
+                               align: 0.5 1.0;
+                       }
+               }
+               textblock { "txt.info";
+                       scale;
+               desc { "default";
+                       min: CU_VOLUME_INFO_TXT_MIN;
+                       fixed: 1 1;
+                       rel1 { relative: 0.5 0.5; to_y: "txt.info.zone"; }
+                               rel2 { relative: 0.5 0.5; to_y: "txt.info.zone"; }
+                               text.style: "volume_info";
+                       }
+                       desc { "hide";
+                               hid;
+                       }
+               }
+               image { "icon.bg"
+                       scale;
+                       desc { "default";
+                               min: CU_VOLUME_ICON_SIZE;
+                               max: CU_VOLUME_ICON_SIZE;
+                               rel1.to: "sizer";
+                               rel2.to: "sizer";
+                               image.normal: "b_slider_btn_bg.png";
+                       }
+                       desc { "hide";
+                               hid;
+                       }
+               }
+               image { "icon"
+                       scale;
+                       desc { "default";
+                               min: CU_VOLUME_ICON_SIZE;
+                               max: CU_VOLUME_ICON_SIZE;
+                               rel1.to: "sizer";
+                               rel2.to: "sizer";
+                               image.normal: "w_call_opt_volume.png";
+                               color: 0 0 0 255;
+                       }
+                       desc { "hide";
+                               hid;
+                       }
+               }
+       }
+       programs {
+               program {
+                       signal: "hide_controls";
+                       source: "volume_control";
+                       action: STATE_SET "hide";
+                       target: "bg";
+                       target: "txt.value";
+                       target: "swl.plus";
+                       target: "swl.minus";
+                       target: "txt.info";
+                       target: "icon.bg";
+                       target: "icon";
+               }
+               program {
+                       signal: "show_controls";
+                       source: "volume_control";
+                       action: STATE_SET "default";
+                       target: "bg";
+                       target: "txt.value";
+                       target: "swl.plus";
+                       target: "swl.minus";
+                       target: "txt.info";
+                       target: "icon.bg";
+                       target: "icon";
+               }
+       }
+}
diff --git a/inc/view/VolumeControl.h b/inc/view/VolumeControl.h
new file mode 100644 (file)
index 0000000..4fcb55b
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * 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 __CALLUI_VIEW_VOLUME_CONTROL_H__
+#define __CALLUI_VIEW_VOLUME_CONTROL_H__
+
+#include "ucl/gui/StyledWidget.h"
+#include "ucl/gui/Layout.h"
+
+#include "types.h"
+
+namespace callui {
+
+       class VolumeControl final : public ucl::ElmWidget {
+       public:
+               class Builder {
+               public:
+                       Builder();
+                       Builder &setInfoText(const ucl::TString &info);
+                       Builder &setMaxSliderValue(int maxValue);
+                       Builder &setSliderValue(int curValue);
+                       Builder &setShowControls(bool isShown);
+                       Builder &setEventHandler(const VolumeControlEventHandler &handler);
+                       VolumeControlSRef build(ucl::ElmWidget &parent) const;
+
+               private:
+                       ucl::TString m_info;
+                       int m_maxValue;
+                       int m_curValue;
+                       bool m_showControls;
+                       VolumeControlEventHandler m_handler;
+               };
+
+       public:
+               void showControls();
+               void hideControls();
+               bool getControlsVisibilityState();
+               void setInfoText(const ucl::TString &info);
+               void setSliderValue(int value);
+               void setMaxSliderValue(int maxValue);
+               void setDecreaseBtnEnable(bool isEnable);
+               void setIncreaseBtnEnable(bool isEnable);
+               void setEventHandler(const VolumeControlEventHandler &handler);
+
+       private:
+               friend class ucl::RefCountObj<VolumeControl>;
+               VolumeControl(ucl::RefCountObjBase &rc,
+                               const ucl::LayoutSRef &layout,
+                               const ucl::TString &info,
+                               int maxValue,
+                               int curValue,
+                               bool showControls,
+                               const VolumeControlEventHandler &handler);
+               virtual ~VolumeControl();
+
+               void prepare(const ucl::TString &info,
+                               int maxValue,
+                               int curValue,
+                               bool showControls);
+
+               void onDecreaseBtnClickedCb(ucl::Widget &widget, void *eventInfo);
+               void onIncreaseBtnClickedCb(ucl::Widget &widget, void *eventInfo);
+
+       private:
+               ucl::LayoutWRef m_layout;
+               ucl::ElmWidget m_slider;
+               ucl::StyledWidget m_decreaseBtn;
+               ucl::StyledWidget m_increaseBtn;
+               VolumeControlEventHandler m_handler;
+               bool m_isControlsShown;
+       };
+
+}
+
+#endif // __CALLUI_VIEW_VOLUME_CONTROL_H__
index 4ff7915bc9f39a29b492568d709cdaba7a56dec7..4a38550302d26fbdc7d6644143ddb6dbbce1820a 100644 (file)
 
 #include "../types.h"
 
+namespace callui {
+
+       enum class VolumeControlEvent {
+               INCREASE,
+               DECREASE
+       };
+
+       UCL_DECLARE_REF_ALIASES(VolumeControl);
+
+       using VolumeControlEventHandler = ucl::WeakDelegate<void(VolumeControlEvent)>;
+
+}
+
 #endif // __CALLUI_VIEW_TYPES_H__
index 75b394d1448fa7c8330d744e941ddea2d55527bf..e583fd47f2550a05d2e860b678a4f14347c32c49 100644 (file)
@@ -41,5 +41,7 @@ collections {
        #include "../../edc/indicator.edc"
        #include "../../edc/call_info.edc"
        #include "../../edc/reject_msg.edc"
+       #include "../../edc/volume_control.edc"
+       #include "../../edc/accessory.edc"
 
 }
diff --git a/src/view/VolumeControl.cpp b/src/view/VolumeControl.cpp
new file mode 100644 (file)
index 0000000..dea42cb
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * 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 "view/VolumeControl.h"
+
+#include "common.h"
+
+namespace callui { namespace { namespace impl {
+
+       using namespace ucl;
+
+       constexpr LayoutTheme LAYOUT_VOLUME
+               {"layout", "callui", "volume_control"};
+
+       constexpr ElmStyle STYLE_BTN_MINUS {"callui/minus"};
+       constexpr ElmStyle STYLE_BTN_PLUS {"callui/plus"};
+
+       constexpr EdjePart PART_SWL_SLIDER {"swl.slider"};
+       constexpr EdjePart PART_SWL_MINUS {"swl.minus"};
+       constexpr EdjePart PART_SWL_PLUS {"swl.plus"};
+
+       constexpr EdjePart PART_TXT_INFO {"txt.info"};
+       constexpr EdjePart PART_TXT_VALUE {"txt.value"};
+
+       constexpr EdjeSignal SIGNAL_SHOW_CONTROLS {"show_controls"};
+       constexpr EdjeSignal SIGNAL_HIDE_CONTROLS {"hide_controls"};
+
+       constexpr EdjeSignalSrc SIGNAL_SRC_VOICE_CONTROL {"volume_control"};
+}}}
+
+namespace callui {
+
+       using namespace ucl;
+
+       VolumeControl::Builder::Builder():
+                       m_maxValue(0),
+                       m_curValue(0),
+                       m_showControls(true)
+       {
+       }
+
+       VolumeControl::Builder &VolumeControl::Builder::setInfoText(const TString &info)
+       {
+               m_info = info;
+               return *this;
+       }
+
+       VolumeControl::Builder &VolumeControl::Builder::setMaxSliderValue(int maxValue)
+       {
+               m_maxValue = maxValue;
+               return *this;
+       }
+
+       VolumeControl::Builder &VolumeControl::Builder::setSliderValue(int curValue)
+       {
+               m_curValue = curValue;
+               return *this;
+       }
+
+       VolumeControl::Builder &VolumeControl::Builder::setShowControls(bool isShown)
+       {
+               m_showControls = isShown;
+               return *this;
+       }
+
+       VolumeControl::Builder &VolumeControl::Builder::setEventHandler(
+                       const VolumeControlEventHandler &handler)
+       {
+               m_handler = handler;
+               return *this;
+       }
+
+       VolumeControlSRef VolumeControl::Builder::build(ElmWidget &parent) const
+       {
+               auto layout = Layout::Builder().
+                               setTheme(impl::LAYOUT_VOLUME).
+                               setIsOwner(true).
+                               build(parent);
+               if (!layout) {
+                       LOG_RETURN_VALUE(RES_FAIL, {}, "Layout::build() failed!");
+               }
+
+               auto result = makeShared<VolumeControl>(layout,
+                               m_info,
+                               m_maxValue,
+                               m_curValue,
+                               m_showControls,
+                               m_handler);
+
+               result->bindToEo();
+
+               return result;
+       }
+
+       VolumeControl::VolumeControl(RefCountObjBase &rc,
+                       const LayoutSRef &layout,
+                       const TString &info,
+                       int maxValue,
+                       int curValue,
+                       bool showControls,
+                       const VolumeControlEventHandler &handler):
+                               ElmWidget(&rc, *layout, true),
+                               m_layout(layout),
+                               m_slider(eext_circle_object_slider_add(*m_layout,
+                                               getCircleSurface(*m_layout))),
+                               m_decreaseBtn(elm_button_add(*m_layout)),
+                               m_increaseBtn(elm_button_add(*m_layout)),
+                               m_handler(handler),
+                               m_isControlsShown(true)
+       {
+               prepare(info, maxValue, curValue, showControls);
+       }
+
+       VolumeControl::~VolumeControl()
+       {
+       }
+
+       void VolumeControl::prepare(const TString &info,
+                       int maxValue,
+                       int curValue,
+                       bool showControls)
+       {
+               m_layout->setIsOwner(false);
+
+               evas_object_size_hint_align_set(m_slider,
+                               EVAS_HINT_FILL, 0.5);
+               evas_object_size_hint_weight_set(m_slider,
+                               EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+               m_layout->setContent(m_slider, impl::PART_SWL_SLIDER);
+               show(*m_layout);
+
+               m_decreaseBtn.setStyle(impl::STYLE_BTN_MINUS);
+               m_decreaseBtn.addEventHandler(BTN_CLICKED, WEAK_DELEGATE(
+                               VolumeControl::onDecreaseBtnClickedCb, asWeak(*this)));
+               m_layout->setContent(m_decreaseBtn, impl::PART_SWL_MINUS);
+               show(m_decreaseBtn);
+
+               m_increaseBtn.setStyle(impl::STYLE_BTN_PLUS);
+               m_increaseBtn.addEventHandler(BTN_CLICKED, WEAK_DELEGATE(
+                               VolumeControl::onIncreaseBtnClickedCb, asWeak(*this)));
+               m_layout->setContent(m_increaseBtn, impl::PART_SWL_PLUS);
+               show(m_increaseBtn);
+
+               setInfoText(info);
+               setMaxSliderValue(maxValue);
+               setSliderValue(curValue);
+
+               if (!showControls) {
+                       hideControls();
+               }
+       }
+
+       void VolumeControl::showControls()
+       {
+               if (!m_isControlsShown) {
+                       m_layout->emit(impl::SIGNAL_SHOW_CONTROLS,
+                                       impl::SIGNAL_SRC_VOICE_CONTROL);
+                       m_isControlsShown = true;
+               }
+       }
+
+       void VolumeControl::hideControls()
+       {
+               if (m_isControlsShown) {
+                       m_layout->emit(impl::SIGNAL_HIDE_CONTROLS,
+                                       impl::SIGNAL_SRC_VOICE_CONTROL);
+                       m_isControlsShown = false;
+               }
+       }
+
+       bool VolumeControl::getControlsVisibilityState()
+       {
+               return m_isControlsShown;
+       }
+
+       void VolumeControl::setInfoText(const TString &info)
+       {
+               m_layout->setText(info.translate(), impl::PART_TXT_INFO);
+       }
+
+       void VolumeControl::setSliderValue(int value)
+       {
+               eext_circle_object_value_set(m_slider, static_cast<double>(value));
+               m_layout->setText(std::to_string(value), impl::PART_TXT_VALUE);
+       }
+
+       void VolumeControl::setMaxSliderValue(int maxValue)
+       {
+               eext_circle_object_value_min_max_set(m_slider,
+                               0, maxValue);
+       }
+
+       void VolumeControl::setIncreaseBtnEnable(bool isEnable)
+       {
+               isEnable ? enable(m_increaseBtn) : disable(m_increaseBtn);
+       }
+
+       void VolumeControl::setDecreaseBtnEnable(bool isEnable)
+       {
+               isEnable ? enable(m_decreaseBtn) : disable(m_decreaseBtn);
+       }
+
+       void VolumeControl::setEventHandler(
+                       const VolumeControlEventHandler &handler)
+       {
+               m_handler = handler;
+       }
+
+       void VolumeControl::onDecreaseBtnClickedCb(Widget &widget, void *eventInfo)
+       {
+               if (m_isControlsShown) {
+                       ILOG("Ignored as callback called after control was hidden");
+               }
+
+               if (m_handler) {
+                       m_handler(VolumeControlEvent::DECREASE);
+               }
+       }
+
+       void VolumeControl::onIncreaseBtnClickedCb(Widget &widget, void *eventInfo)
+       {
+               if (m_isControlsShown) {
+                       ILOG("Ignored as callback called after control was hidden");
+               }
+
+               if (m_handler) {
+                       m_handler(VolumeControlEvent::INCREASE);
+               }
+       }
+
+}