jaehyun pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=eefcb49419af9d0057ba4c03e6c9009a1265e31e

commit eefcb49419af9d0057ba4c03e6c9009a1265e31e
Author: Woochan Lee <wc0917....@samsung.com>
Date:   Mon Nov 20 19:12:49 2017 +0900

    efl_ui_spin: Add new spin and spin_button widgets
    
    Summary:
    https://phab.enlightenment.org/T5900
    
    Creating base class(efl_ui_spin) to support various shape of spinner.
    
    Added button interaction widget efl_ui_spin_button inherited from 
efl_ui_spin.
    
    Test Plan: Add tests in elementary_test.
    
    Reviewers: Jaehyun_Cho, woohyun, jpeg, singh.amitesh
    
    Subscribers: jenkins, id213sin, cedric, jpeg
    
    Differential Revision: https://phab.enlightenment.org/D5424
---
 data/elementary/themes/Makefile.am              |   2 +
 data/elementary/themes/default.edc              |   2 +
 data/elementary/themes/edc/elm/button.edc       |   6 +
 data/elementary/themes/edc/elm/entry.edc        |   2 +
 data/elementary/themes/edc/elm/spin.edc         |  27 +
 data/elementary/themes/edc/elm/spin_button.edc  | 218 ++++++
 src/Makefile_Efl.am                             |   1 -
 src/Makefile_Elementary.am                      |   8 +
 src/bin/elementary/Makefile.am                  |   2 +
 src/bin/elementary/test.c                       |   4 +
 src/bin/elementary/test_flipselector.c          |   8 +-
 src/bin/elementary/test_ui_spin.c               |  71 ++
 src/bin/elementary/test_ui_spin_button.c        |  43 ++
 src/lib/efl/CMakeLists.txt                      |   1 -
 src/lib/efl/Efl.h                               |   1 -
 src/lib/efl/interfaces/efl_interfaces_main.c    |   1 -
 src/lib/efl/interfaces/efl_ui_range.eo          |  18 +-
 src/lib/efl/interfaces/efl_ui_spin.eo           |  84 ---
 src/lib/elementary/Elementary.h                 |   2 +
 src/lib/elementary/efl_ui_spin.c                | 311 ++++++++
 src/lib/elementary/efl_ui_spin.eo               |  26 +
 src/lib/elementary/efl_ui_spin_button.c         | 922 ++++++++++++++++++++++++
 src/lib/elementary/efl_ui_spin_button.eo        |  80 ++
 src/lib/elementary/efl_ui_spin_button_private.h |  20 +
 src/lib/elementary/efl_ui_spin_private.h        |  29 +
 src/lib/elementary/elm_flipselector.c           |  32 +-
 src/lib/elementary/elm_flipselector.eo          |  43 +-
 src/lib/elementary/elm_flipselector_legacy.h    |  37 -
 src/lib/elementary/elm_spinner.c                |  40 +-
 src/lib/elementary/elm_spinner.eo               |  33 +-
 src/lib/elementary/elm_spinner_legacy.h         |  46 --
 31 files changed, 1886 insertions(+), 234 deletions(-)

diff --git a/data/elementary/themes/Makefile.am 
b/data/elementary/themes/Makefile.am
index dfe26d5848..f1ee7b15e8 100644
--- a/data/elementary/themes/Makefile.am
+++ b/data/elementary/themes/Makefile.am
@@ -146,6 +146,8 @@ elementary/themes/edc/elm/separator.edc \
 elementary/themes/edc/elm/slider.edc \
 elementary/themes/edc/elm/slideshow.edc \
 elementary/themes/edc/elm/spinner.edc \
+elementary/themes/edc/elm/spin.edc \
+elementary/themes/edc/elm/spin_button.edc \
 elementary/themes/edc/elm/textpath.edc \
 elementary/themes/edc/elm/thumb.edc \
 elementary/themes/edc/elm/toolbar.edc \
diff --git a/data/elementary/themes/default.edc 
b/data/elementary/themes/default.edc
index 5e54ffdcdd..9d615295b1 100644
--- a/data/elementary/themes/default.edc
+++ b/data/elementary/themes/default.edc
@@ -67,6 +67,8 @@ collections {
 #include "edc/elm/border.edc"
 // XXX: min size calc problems - too wide! ... err ok on my 32bit box... eh?
 #include "edc/elm/spinner.edc"
+#include "edc/elm/spin.edc"
+#include "edc/elm/spin_button.edc"
 #include "edc/elm/menu.edc"
 #include "edc/elm/clock.edc"
 #include "edc/elm/gengrid.edc"
diff --git a/data/elementary/themes/edc/elm/button.edc 
b/data/elementary/themes/edc/elm/button.edc
index a05260f4e3..c5c48d3a21 100644
--- a/data/elementary/themes/edc/elm/button.edc
+++ b/data/elementary/themes/edc/elm/button.edc
@@ -1472,6 +1472,7 @@ group { name: 
"elm/button/base/hoversel_horizontal_entry/default";
 /******************* SPINNER BUTTONS STYLES **********************/
    group { name: "elm/button/base/spinner/increase/default";
       alias: "elm/button/base/spinner/increase/colorselector/default";
+      alias: "elm/button/base/spin_button/increase/default";
       alias: "elm/button/base/calendar/increase/default";
       alias: "elm/button/base/calendar/increase/double_spinners";
       images.image: "sym_right_light_normal.png" COMP;
@@ -1626,6 +1627,7 @@ group { name: 
"elm/button/base/hoversel_horizontal_entry/default";
    group { name: "elm/button/base/spinner/decrease/default";
       alias: "elm/button/base/spinner/decrease/colorselector/default";
       inherit: "elm/button/base/spinner/increase/default";
+      alias: "elm/button/base/spin_button/decrease/default";
       alias: "elm/button/base/calendar/decrease/default";
       alias: "elm/button/base/calendar/decrease/double_spinners";
       images.image: "sym_left_light_normal.png" COMP;
@@ -1654,6 +1656,8 @@ group { name: 
"elm/button/base/hoversel_horizontal_entry/default";
    group { name: "elm/button/base/spinner/default";
       alias: "elm/button/base/spinner/colorselector/default";
       alias: "elm/button/base/spinner/vertical";
+      alias: "elm/button/base/spin_button/default";
+      alias: "elm/button/base/spin_button/vertical";
       parts {
          part { name: "bg";
             type: SPACER;
@@ -1730,6 +1734,7 @@ group { name: 
"elm/button/base/hoversel_horizontal_entry/default";
    }
    group { name: "elm/button/base/spinner/increase/vertical";
       inherit: "elm/button/base/spinner/increase/default";
+      alias: "elm/button/base/spin_button/increase/vertical";
       images.image: "sym_up_light_normal.png" COMP;
       images.image: "sym_up_glow_normal.png" COMP;
       images.image: "sym_up_dark_normal.png" COMP;
@@ -1755,6 +1760,7 @@ group { name: 
"elm/button/base/hoversel_horizontal_entry/default";
 
    group { name: "elm/button/base/spinner/decrease/vertical";
       inherit: "elm/button/base/spinner/decrease/default";
+      alias: "elm/button/base/spin_button/decrease/vertical";
       images.image: "sym_down_light_normal.png" COMP;
       images.image: "sym_down_glow_normal.png" COMP;
       images.image: "sym_down_dark_normal.png" COMP;
diff --git a/data/elementary/themes/edc/elm/entry.edc 
b/data/elementary/themes/edc/elm/entry.edc
index 4c43cff3df..bf881daf5b 100644
--- a/data/elementary/themes/edc/elm/entry.edc
+++ b/data/elementary/themes/edc/elm/entry.edc
@@ -854,6 +854,8 @@ group { name: "elm/entry/base-single/default";
 
 group { name: "elm/entry/base-single/spinner/default";
    alias: "elm/entry/base-single/spinner/vertical";
+   alias: "elm/entry/base-single/spin_button/default";
+   alias: "elm/entry/base-single/spin_button/vertical";
    inherit: "elm/entry/base-single/default";
    styles {
       style { name: "entry_single_spinner_style";
diff --git a/data/elementary/themes/edc/elm/spin.edc 
b/data/elementary/themes/edc/elm/spin.edc
new file mode 100644
index 0000000000..77cf917fd8
--- /dev/null
+++ b/data/elementary/themes/edc/elm/spin.edc
@@ -0,0 +1,27 @@
+group { name: "elm/spin/base/default";
+   parts {
+      part { name: "bg";
+         type: RECT;
+         scale: 1;
+         description { state: "default" 0.0;
+            color: 0 0 0 0;
+         }
+      }
+      part { name: "elm.text";
+         type: TEXT;
+         mouse_events: 0;
+         scale: 1;
+         description { state: "default" 0.0;
+            color: FN_COL_DEFAULT;
+            text {
+               font: FNBD;
+               size: 10;
+               min: 1 1;
+               ellipsis: -1;
+               align: 0.5 0.5;
+            }
+            rel.to: "bg";
+         }
+      }
+   }
+}
diff --git a/data/elementary/themes/edc/elm/spin_button.edc 
b/data/elementary/themes/edc/elm/spin_button.edc
new file mode 100644
index 0000000000..5b53382691
--- /dev/null
+++ b/data/elementary/themes/edc/elm/spin_button.edc
@@ -0,0 +1,218 @@
+group { name: "elm/spin_button/base/default";
+   images.image: "vert_bar_inset.png" COMP;
+   parts {
+      part { name: "clip"; type: RECT;
+         description { state: "default" 0.0;
+            rel1.to: "elm.swallow.text_button";
+            rel2.to: "elm.swallow.text_button";
+         }
+      }
+      part { name: "bg";
+         type: RECT;
+         scale: 1;
+         description { state: "default" 0.0;
+            color_class: "spinner_bg";
+         }
+      }
+      part { name: "inset"; mouse_events: 0;
+         description { state: "default" 0.0;
+            rel1.offset: 0 1;
+            rel2.offset: -1 -2;
+            image.normal: "vert_bar_inset.png";
+            image.border: 1 1 8 6;
+            image.middle: 0;
+            fill.smooth: 0;
+         }
+      }
+      part { name: "access";
+         type: RECT;
+         repeat_events: 1;
+         description { state: "default" 0.0;
+            fixed: 1 1;
+            color: 0 0 0 0;
+            rel1.to: "inset";
+            rel2.to: "inset";
+            visible: 0;
+         }
+         description { state: "active" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+         }
+      }
+      part { name: "elm.swallow.entry";
+         type: SWALLOW;
+         clip_to: "clip";
+         description { state: "default" 0.0;
+            fixed: 1 1;
+            rel1.to: "elm.swallow.text_button";
+            rel2.to: "elm.swallow.text_button";
+            visible: 0;
+         }
+         description { state: "active" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+         }
+      }
+      part { name: "elm.swallow.dec_button";
+         type: SWALLOW;
+         scale: 1;
+         description { state: "default" 0.0;
+            fixed: 1 0;
+            rel1.to: "inset";
+            rel1.offset: 1 1;
+            rel2.to: "inset";
+            rel2.offset: 1 -2;
+            rel2.relative: 0.0 1.0;
+            align: 0.0 0.5;
+            min: 15 15;
+            aspect: 1.0 1.0; aspect_preference: VERTICAL;
+         }
+      }
+      part { name: "elm.swallow.inc_button";
+         type: SWALLOW;
+         scale: 1;
+         description { state: "default" 0.0;
+            fixed: 1 0;
+            rel1.to: "inset";
+            rel1.offset: 1 1;
+            rel1.relative: 1.0 0.0;
+            rel2.to: "inset";
+            rel2.offset: 1 -2;
+            align: 1.0 0.5;
+            min: 15 15;
+            aspect: 1.0 1.0; aspect_preference: VERTICAL;
+         }
+      }
+      part { name: "elm.swallow.text_button";
+         type: SWALLOW;
+         scale: 1;
+         description { state: "default" 0.0;
+            visible: 1;
+            rel1.to_y: "inset";
+            rel1.to_x: "elm.swallow.dec_button";
+            rel1.relative: 1.0 0.0;
+            rel1.offset: 1 1;
+            rel2.to_y: "inset";
+            rel2.to_x: "elm.swallow.inc_button";
+            rel2.relative: 0.0 1.0;
+            rel2.offset: -2 -2;
+         }
+         description { state: "inactive" 0.0;
+            inherit: "default" 0.0;
+            visible: 0;
+         }
+      }
+      part { name: "disabler";
+         type: RECT;
+         repeat_events: 0;
+         mouse_events: 0;
+         description { state: "default" 0.0;
+            color: 0 0 0 0;
+            visible: 0;
+         }
+         description { state: "disabled" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+         }
+      }
+   }
+   programs {
+      program { name: "entry_active";
+         signal: "elm,state,entry,active";
+         source: "elm";
+         action: STATE_SET "active" 0.0;
+         target: "elm.swallow.entry";
+      }
+      program { name: "entry_inactive";
+         signal: "elm,state,entry,inactive";
+         source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "elm.swallow.entry";
+      }
+      program { name: "text_button_active";
+         signal: "elm,state,button,active";
+         source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "elm.swallow.text_button";
+      }
+      program { name: "text_button_inactive";
+         signal: "elm,state,button,inactive";
+         source: "elm";
+         action: STATE_SET "inactive" 0.0;
+         target: "elm.swallow.text_button";
+      }
+      program { name: "access_activate";
+         signal: "elm,state,access,active";
+         source: "elm";
+         action:  STATE_SET "active" 0.0;
+         target: "access";
+      }
+      program { name: "access_inactivate";
+         signal: "elm,state,access,inactive";
+         source: "elm";
+         action:  STATE_SET "default" 0.0;
+         target: "access";
+      }
+      program { name: "disable";
+         signal: "elm,state,disabled";
+         source: "elm";
+         action: STATE_SET "disabled" 0.0;
+         target: "disabler";
+      }
+      program { name: "enable";
+         signal: "elm,state,enabled";
+         source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "disabler";
+      }
+   }
+}
+
+group { name: "elm/spin_button/base/vertical";
+   inherit: "elm/spin_button/base/default";
+   parts {
+      part { name: "elm.swallow.inc_button";
+         type: SWALLOW;
+         scale: 1;
+         description { state: "default" 0.0;
+            rel1.to: "inset";
+            rel1.offset: 1 1;
+            rel1.relative: 1.0 0.0;
+            rel2.to: "inset";
+            rel2.offset: 1 -2;
+            align: 1.0 0.5;
+         }
+      }
+      part { name: "elm.swallow.text_button";
+         type: SWALLOW;
+         scale: 1;
+         description { state: "default" 0.0;
+            visible: 1;
+            rel1.to_y: "inset";
+            rel1.to_x: "elm.swallow.dec_button";
+            rel1.relative: 1.0 0.0;
+            rel1.offset: 1 1;
+            rel2.to_y: "inset";
+            rel2.to_x: "elm.swallow.inc_button";
+            rel2.relative: 0.0 1.0;
+            rel2.offset: -2 -2;
+         }
+         description { state: "active" 0.0;
+            inherit: "default" 0.0;
+            visible: 0;
+         }
+      }
+      part { name: "elm.swallow.dec_button";
+         type: SWALLOW;
+         scale: 1;
+         description { state: "default" 0.0;
+            rel1.to: "inset";
+            rel1.offset: 1 1;
+            rel2.to: "inset";
+            rel2.offset: 1 -2;
+            rel2.relative: 0.0 1.0;
+            align: 0.0 0.5;
+         }
+      }
+   }
+}
diff --git a/src/Makefile_Efl.am b/src/Makefile_Efl.am
index 39c7330e69..769abd6298 100644
--- a/src/Makefile_Efl.am
+++ b/src/Makefile_Efl.am
@@ -57,7 +57,6 @@ efl_eolian_files = \
       lib/efl/interfaces/efl_ui_base.eo \
       lib/efl/interfaces/efl_ui_direction.eo \
       lib/efl/interfaces/efl_ui_drag.eo \
-      lib/efl/interfaces/efl_ui_spin.eo \
       lib/efl/interfaces/efl_ui_range.eo \
       lib/efl/interfaces/efl_ui_view.eo \
       lib/efl/interfaces/efl_ui_model_connect.eo \
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index be45275fa8..3950d11e7d 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -20,6 +20,8 @@ elm_public_eolian_files = \
        lib/elementary/efl_ui_radio.eo \
        lib/elementary/efl_ui_slider.eo \
        lib/elementary/efl_ui_slider_interval.eo \
+       lib/elementary/efl_ui_spin.eo \
+       lib/elementary/efl_ui_spin_button.eo \
        lib/elementary/efl_ui_video.eo \
        lib/elementary/efl_ui_win.eo \
        lib/elementary/efl_ui_win_inlined.eo \
@@ -311,6 +313,8 @@ includesunstable_HEADERS = \
        lib/elementary/efl_ui_slider_private.h \
        lib/elementary/elm_widget_slideshow.h \
        lib/elementary/elm_widget_spinner.h \
+       lib/elementary/efl_ui_spin_private.h \
+       lib/elementary/efl_ui_spin_button_private.h \
        lib/elementary/elm_widget_table.h \
        lib/elementary/elm_widget_thumb.h \
        lib/elementary/elm_widget_toolbar.h \
@@ -656,6 +660,8 @@ lib_elementary_libelementary_la_SOURCES = \
        lib/elementary/elm_separator.c \
        lib/elementary/efl_ui_slider.c \
        lib/elementary/efl_ui_slider_interval.c \
+       lib/elementary/efl_ui_spin.c \
+       lib/elementary/efl_ui_spin_button.c \
        lib/elementary/elm_slideshow.c \
        lib/elementary/elm_spinner.c \
        lib/elementary/elm_store.c \
@@ -877,6 +883,8 @@ bin/elementary/test_segment_control.c \
 bin/elementary/test_separator.c \
 bin/elementary/test_slider.c \
 bin/elementary/test_ui_slider_interval.c \
+bin/elementary/test_ui_spin.c \
+bin/elementary/test_ui_spin_button.c \
 bin/elementary/test_slideshow.c \
 bin/elementary/test_spinner.c \
 bin/elementary/test_store.c \
diff --git a/src/bin/elementary/Makefile.am b/src/bin/elementary/Makefile.am
index 0ce67b0483..8f2a8106f4 100644
--- a/src/bin/elementary/Makefile.am
+++ b/src/bin/elementary/Makefile.am
@@ -128,6 +128,8 @@ test_slider.c \
 test_ui_slider_interval.c \
 test_slideshow.c \
 test_spinner.c \
+test_ui_spinner.c \
+test_ui_buttonspin.c \
 test_store.c \
 test_sys_notify.c \
 test_systray.c \
diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c
index c4f5e9b21f..68201b2556 100644
--- a/src/bin/elementary/test.c
+++ b/src/bin/elementary/test.c
@@ -176,6 +176,8 @@ void test_scroller3(void *data, Evas_Object *obj, void 
*event_info);
 void test_scroller4(void *data, Evas_Object *obj, void *event_info);
 void test_scroller5(void *data, Evas_Object *obj, void *event_info);
 void test_spinner(void *data, Evas_Object *obj, void *event_info);
+void test_ui_spin(void *data, Evas_Object *obj, void *event_info);
+void test_ui_spin_button(void *data, Evas_Object *obj, void *event_info);
 void test_index(void *data, Evas_Object *obj, void *event_info);
 void test_index2(void *data, Evas_Object *obj, void *event_info);
 void test_index3(void *data, Evas_Object *obj, void *event_info);
@@ -1016,6 +1018,8 @@ add_tests:
 
    //------------------------------//
    ADD_TEST(NULL, "Range Values", "Spinner", test_spinner);
+   ADD_TEST(NULL, "Range Values", "Ui.Spin", test_ui_spin);
+   ADD_TEST(NULL, "Range Values", "Ui.Spin.Button", test_ui_spin_button);
    ADD_TEST(NULL, "Range Values", "Slider", test_slider);
    ADD_TEST(NULL, "Range Values", "Progressbar", test_progressbar);
    ADD_TEST(NULL, "Range Values", "Progressbar 2", test_progressbar2);
diff --git a/src/bin/elementary/test_flipselector.c 
b/src/bin/elementary/test_flipselector.c
index b9cd93657b..13216bdc80 100644
--- a/src/bin/elementary/test_flipselector.c
+++ b/src/bin/elementary/test_flipselector.c
@@ -186,10 +186,10 @@ test_flipselector(void *data EINA_UNUSED, Evas_Object 
*obj EINA_UNUSED, void *ev
 
    fpd = elm_flipselector_add(bx);
    evas_object_size_hint_weight_set(fpd, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-   efl_ui_spin_step_set(fpd, 1.5);
-   efl_ui_spin_min_max_set(fpd, 2.3, 10.1);
-   efl_ui_spin_value_set(fpd, 5.3);
-   printf("Current value is %f\n", efl_ui_spin_value_get(fpd));
+   efl_ui_range_step_set(fpd, 1.5);
+   efl_ui_range_min_max_set(fpd, 2.3, 10.1);
+   efl_ui_range_value_set(fpd, 5.3);
+   printf("Current value is %f\n", efl_ui_range_value_get(fpd));
    elm_box_pack_end(bx, fpd);
    evas_object_show(fpd);
 
diff --git a/src/bin/elementary/test_ui_spin.c 
b/src/bin/elementary/test_ui_spin.c
new file mode 100644
index 0000000000..be41b75f5f
--- /dev/null
+++ b/src/bin/elementary/test_ui_spin.c
@@ -0,0 +1,71 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+#include <Elementary.h>
+
+static void
+_spin_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev)
+{
+   printf("Value changed %d\n", (int)efl_ui_range_value_get(ev->object));
+}
+static void
+_spin_min_reached_cb(void *data EINA_UNUSED, const Efl_Event *ev)
+{
+   printf("Min reached %d\n", (int)efl_ui_range_value_get(ev->object));
+}
+static void
+_spin_max_reached_cb(void *data EINA_UNUSED, const Efl_Event *ev)
+{
+   printf("Max reached %d\n", (int)efl_ui_range_value_get(ev->object));
+}
+
+static void
+_inc_clicked(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+   int val = (int)efl_ui_range_value_get(data);
+   efl_ui_range_value_set(data, ++val);
+}
+
+static void
+_dec_clicked(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+   int val = (int)efl_ui_range_value_get(data);
+   efl_ui_range_value_set(data, --val);
+}
+
+void
+test_ui_spin(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void 
*event_info EINA_UNUSED)
+{
+   Eo *win, *bx, *sp;
+
+   win = efl_add(EFL_UI_WIN_CLASS, NULL,
+                 efl_ui_win_type_set(efl_added, EFL_UI_WIN_BASIC),
+                 efl_text_set(efl_added, "Efl.Ui.Spin"),
+                 efl_ui_win_autodel_set(efl_added, EINA_TRUE));
+
+   bx = efl_add(EFL_UI_BOX_CLASS, win,
+                efl_content_set(win, efl_added),
+                efl_ui_direction_set(efl_added, EFL_UI_DIR_DOWN));
+
+   sp = efl_add(EFL_UI_SPIN_CLASS, bx,
+                efl_ui_range_min_max_set(efl_added, 0, 10),
+                efl_ui_range_value_set(efl_added, 6),
+                efl_ui_range_step_set(efl_added, 2),
+                efl_ui_format_string_set(efl_added, "test %d"),
+                efl_event_callback_add(efl_added, 
EFL_UI_SPIN_EVENT_CHANGED,_spin_changed_cb, NULL),
+                efl_event_callback_add(efl_added, 
EFL_UI_SPIN_EVENT_MIN_REACHED,_spin_min_reached_cb, NULL),
+                efl_event_callback_add(efl_added, 
EFL_UI_SPIN_EVENT_MAX_REACHED,_spin_max_reached_cb, NULL),
+                efl_pack(bx, efl_added));
+
+   efl_add(EFL_UI_BUTTON_CLASS, bx,
+           efl_text_set(efl_added, "Increse Spinner value"),
+           efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, 
_inc_clicked, sp),
+           efl_pack(bx, efl_added));
+
+   efl_add(EFL_UI_BUTTON_CLASS, bx,
+           efl_text_set(efl_added, "Decrease Spinner value"),
+           efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, 
_dec_clicked, sp),
+           efl_pack(bx, efl_added));
+
+   efl_gfx_size_set(win, EINA_SIZE2D(100, 80));
+}
diff --git a/src/bin/elementary/test_ui_spin_button.c 
b/src/bin/elementary/test_ui_spin_button.c
new file mode 100644
index 0000000000..e9730721e7
--- /dev/null
+++ b/src/bin/elementary/test_ui_spin_button.c
@@ -0,0 +1,43 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+#include <Elementary.h>
+
+static void
+_spin_delay_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev)
+{
+   printf("Value delay changed %d\n", (int)efl_ui_range_value_get(ev->object));
+}
+
+void
+test_ui_spin_button(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void 
*event_info EINA_UNUSED)
+{
+   Eo *win, *bx;
+
+   win = efl_add(EFL_UI_WIN_CLASS, NULL,
+                 efl_ui_win_type_set(efl_added, EFL_UI_WIN_BASIC),
+                 efl_text_set(efl_added, "Efl.Ui.Spin_Button"),
+                 efl_ui_win_autodel_set(efl_added, EINA_TRUE));
+
+   bx = efl_add(EFL_UI_BOX_CLASS, win,
+                efl_content_set(win, efl_added),
+                efl_ui_direction_set(efl_added, EFL_UI_DIR_DOWN));
+
+   efl_add(EFL_UI_SPIN_BUTTON_CLASS, bx,
+           efl_ui_range_min_max_set(efl_added, 0, 10),
+           efl_ui_range_value_set(efl_added, 6),
+           efl_ui_range_step_set(efl_added, 2),
+           efl_ui_spin_button_loop_set(efl_added, EINA_TRUE),
+           efl_ui_spin_button_editable_set(efl_added, EINA_TRUE),
+           efl_event_callback_add(efl_added, 
EFL_UI_SPIN_BUTTON_EVENT_DELAY_CHANGED,_spin_delay_changed_cb, NULL),
+           efl_pack(bx, efl_added));
+
+   efl_add(EFL_UI_SPIN_BUTTON_CLASS, bx,
+           efl_ui_range_min_max_set(efl_added, -100.0, 100.0),
+           efl_ui_range_value_set(efl_added, 0),
+           efl_ui_format_string_set(efl_added, "test float %0.2f"),
+           efl_ui_spin_button_editable_set(efl_added, EINA_FALSE),
+           efl_pack(bx, efl_added));
+
+   efl_gfx_size_set(win, EINA_SIZE2D(180, 100));
+}
diff --git a/src/lib/efl/CMakeLists.txt b/src/lib/efl/CMakeLists.txt
index af3c443475..6637bedfc4 100644
--- a/src/lib/efl/CMakeLists.txt
+++ b/src/lib/efl/CMakeLists.txt
@@ -54,7 +54,6 @@ set(PUBLIC_EO_FILES
   interfaces/efl_ui_item.eo
   interfaces/efl_ui_menu.eo
   interfaces/efl_ui_range.eo
-  interfaces/efl_ui_spin.eo
   interfaces/efl_ui_autorepeat.eo
   interfaces/efl_vpath.eo
   interfaces/efl_vpath_core.eo
diff --git a/src/lib/efl/Efl.h b/src/lib/efl/Efl.h
index 8e1c6a6233..683745f10a 100644
--- a/src/lib/efl/Efl.h
+++ b/src/lib/efl/Efl.h
@@ -90,7 +90,6 @@ typedef Efl_Gfx_Path_Command_Type Efl_Gfx_Path_Command;
 #include "interfaces/efl_ui_base.eo.h"
 #include "interfaces/efl_ui_direction.eo.h"
 #include "interfaces/efl_ui_drag.eo.h"
-#include "interfaces/efl_ui_spin.eo.h"
 #include "interfaces/efl_ui_range.eo.h"
 #include "interfaces/efl_ui_item.eo.h"
 #include "interfaces/efl_ui_menu.eo.h"
diff --git a/src/lib/efl/interfaces/efl_interfaces_main.c 
b/src/lib/efl/interfaces/efl_interfaces_main.c
index 5ebf0733f4..e3b4e5682c 100644
--- a/src/lib/efl/interfaces/efl_interfaces_main.c
+++ b/src/lib/efl/interfaces/efl_interfaces_main.c
@@ -58,7 +58,6 @@
 #include "interfaces/efl_ui_base.eo.c"
 #include "interfaces/efl_ui_direction.eo.c"
 #include "interfaces/efl_ui_drag.eo.c"
-#include "interfaces/efl_ui_spin.eo.c"
 #include "interfaces/efl_ui_range.eo.c"
 #include "interfaces/efl_ui_menu.eo.c"
 #include "interfaces/efl_ui_autorepeat.eo.c"
diff --git a/src/lib/efl/interfaces/efl_ui_range.eo 
b/src/lib/efl/interfaces/efl_ui_range.eo
index a13ce57c5b..56d4f89919 100644
--- a/src/lib/efl/interfaces/efl_ui_range.eo
+++ b/src/lib/efl/interfaces/efl_ui_range.eo
@@ -28,7 +28,7 @@ interface Efl.Ui.Range
               If it is bigger then $max, will be updated to $max. Actual value
               can be get with @Efl.Ui.Range.range_value.get
 
-              By default, min is equal to 0.0, and max is equal to 1.0.
+              The minimum and maximum values may be different for each class.
 
               Warning: maximum must be greater than minimum, otherwise behavior
               is undefined.
@@ -46,5 +46,21 @@ interface Efl.Ui.Range
             max: double; [[The maximum value.]]
          }
       }
+      @property range_step {
+         [[Control the step used to increment or decrement values for given 
widget.
+
+           This value will be incremented or decremented to the displayed 
value.
+
+           By default step value is equal to 1.
+
+           Warning: The step value should be bigger than 0.]]
+         set {
+         }
+         get {
+         }
+         values {
+           step: double; [[The step value.]]
+         }
+      }
    }
 }
diff --git a/src/lib/efl/interfaces/efl_ui_spin.eo 
b/src/lib/efl/interfaces/efl_ui_spin.eo
deleted file mode 100644
index bfeca2be70..0000000000
--- a/src/lib/efl/interfaces/efl_ui_spin.eo
+++ /dev/null
@@ -1,84 +0,0 @@
-interface Efl.Ui.Spin()
-{
-   [[Efl UI spinner interface]]
-   methods {
-      @property min_max {
-         [[Control the minimum and maximum values for the spinner.
-
-           Define the allowed range of values to be selected by the user.
-
-           If actual value is less than $min, it will be updated to $min. If it
-           is bigger then $max, will be updated to $max.
-
-           By default, min is equal to 0, and max is equal to 100.
-
-           Warning: Maximum must be greater than minimum.]]
-         set {
-         }
-         get {
-         }
-         values {
-            min: double; [[The minimum value.]]
-            max: double; [[The maximum value.]]
-         }
-      }
-      @property step {
-         [[Control the step used to increment or decrement the spinner value.
-
-           This value will be incremented or decremented to the displayed 
value.
-           It will be incremented while the user keep right or top arrow 
pressed,
-           and will be decremented while the user keep left or bottom arrow 
pressed.
-
-           The interval to increment / decrement can be set with 
@.interval.set.
-
-           By default step value is equal to 1.]]
-         set {
-         }
-         get {
-         }
-         values {
-            step: double; [[The step value.]]
-         }
-      }
-      @property value {
-         [[Control the value the spinner displays.
-
-           Value will be presented on the label following format specified with
-           elm_spinner_format_set().
-
-           Warning The value must to be between min and max values. This values
-           are set by elm_spinner_min_max_set().]]
-         set {
-         }
-         get {
-         }
-         values {
-            val: double; [[The value to be displayed.]]
-         }
-      }
-      @property interval {
-         [[Control the interval on time updates for an user mouse button hold 
on spinner widgets' arrows.
-
-           This interval value is decreased while the user holds the
-           mouse pointer either incrementing or decrementing spinner's value.
-
-           This helps the user to get to a given value distant from the
-           current one easier/faster, as it will start to change quicker and
-           quicker on mouse button holds.
-
-           The calculation for the next change interval value, starting from
-           the one set with this call, is the previous interval divided by
-           $1.05, so it decreases a little bit.
-
-           The default starting interval value for automatic changes is
-           $0.85 seconds.]]
-         set {
-         }
-         get {
-         }
-         values {
-            interval: double; [[The (first) interval value in seconds.]]
-         }
-      }
-   }
-}
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index 431c1e8e7b..64367cadc8 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -304,6 +304,8 @@ EAPI extern Elm_Version *elm_version;
 # include <efl_ui_text_editable.eo.h>
 # include <efl_ui_text_async.eo.h>
 # include <efl_ui_clock.eo.h>
+# include <efl_ui_spin.eo.h>
+# include <efl_ui_spin_button.eo.h>
 # include <efl_ui_image_factory.eo.h>
 #endif
 
diff --git a/src/lib/elementary/efl_ui_spin.c b/src/lib/elementary/efl_ui_spin.c
new file mode 100644
index 0000000000..13dbadc872
--- /dev/null
+++ b/src/lib/elementary/efl_ui_spin.c
@@ -0,0 +1,311 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define EFL_ACCESS_PROTECTED
+#define EFL_ACCESS_VALUE_PROTECTED
+#define EFL_ACCESS_WIDGET_ACTION_PROTECTED
+
+#include <Elementary.h>
+
+#include "elm_priv.h"
+#include "efl_ui_spin_private.h"
+
+#define MY_CLASS EFL_UI_SPIN_CLASS
+
+#define MY_CLASS_NAME "Efl.Ui.Spin"
+
+static Eina_Bool
+_is_valid_digit(char x)
+{
+   return ((x >= '0' && x <= '9') || (x == '.')) ? EINA_TRUE : EINA_FALSE;
+}
+
+static Efl_Ui_Spin_Format_Type
+_is_label_format_integer(const char *fmt)
+{
+   const char *itr = NULL;
+   const char *start = NULL;
+   Eina_Bool found = EINA_FALSE;
+   Efl_Ui_Spin_Format_Type ret_type = SPIN_FORMAT_INVALID;
+
+   start = strchr(fmt, '%');
+   if (!start) return SPIN_FORMAT_INVALID;
+
+   while (start)
+     {
+        if (found && start[1] != '%')
+          {
+             return SPIN_FORMAT_INVALID;
+          }
+
+        if (start[1] != '%' && !found)
+          {
+             found = EINA_TRUE;
+             for (itr = start + 1; *itr != '\0'; itr++)
+               {
+                  if ((*itr == 'd') || (*itr == 'u') || (*itr == 'i') ||
+                      (*itr == 'o') || (*itr == 'x') || (*itr == 'X'))
+                    {
+                       ret_type = SPIN_FORMAT_INT;
+                       break;
+                    }
+                  else if ((*itr == 'f') || (*itr == 'F'))
+                    {
+                       ret_type = SPIN_FORMAT_FLOAT;
+                       break;
+                    }
+                  else if (_is_valid_digit(*itr))
+                    {
+                       continue;
+                    }
+                  else
+                    {
+                       return SPIN_FORMAT_INVALID;
+                    }
+               }
+          }
+        start = strchr(start + 2, '%');
+     }
+
+   return ret_type;
+}
+static void
+_label_write(Evas_Object *obj)
+{
+   Efl_Ui_Spin_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+
+   if (sd->format_cb)
+     {
+        const char *buf;
+        Eina_Value val;
+
+        if (sd->format_type == SPIN_FORMAT_INT)
+          {
+             eina_value_setup(&val, EINA_VALUE_TYPE_INT);
+             eina_value_set(&val, (int)sd->val);
+          }
+        else
+          {
+             eina_value_setup(&val, EINA_VALUE_TYPE_DOUBLE);
+             eina_value_set(&val, sd->val);
+          }
+        eina_strbuf_reset(sd->format_strbuf);
+        sd->format_cb(sd->format_cb_data, sd->format_strbuf, val);
+
+        buf = eina_strbuf_string_get(sd->format_strbuf);
+        eina_value_flush(&val);
+        elm_layout_text_set(obj, "elm.text", buf);
+        sd->templates = buf;
+     }
+   else
+     {
+        char buf[1024];
+        snprintf(buf, sizeof(buf), "%.0f", sd->val);
+        elm_layout_text_set(obj, "elm.text", buf);
+     }
+}
+
+static int
+_decimal_points_get(const char *label)
+{
+   char result[16] = "0";
+   const char *start = strchr(label, '%');
+
+   while (start)
+     {
+        if (start[1] != '%')
+          {
+             start = strchr(start, '.');
+             if (start)
+                start++;
+             break;
+          }
+        else
+          start = strchr(start + 2, '%');
+     }
+
+   if (start)
+     {
+        const char *p = strchr(start, 'f');
+
+        if ((p) && ((p - start) < 15))
+          sscanf(start, "%[^f]", result);
+     }
+
+   return atoi(result);
+}
+
+EOLIAN static void
+_efl_ui_spin_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Spin_Data *_pd EINA_UNUSED)
+{
+   Evas_Coord minw = -1, minh = -1;
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   edje_object_size_min_restricted_calc
+     (wd->resize_obj, &minw, &minh, minw, minh);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+EOLIAN static Efl_Ui_Theme_Apply
+_efl_ui_spin_elm_widget_theme_apply(Eo *obj, Efl_Ui_Spin_Data *sd EINA_UNUSED)
+{
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EFL_UI_THEME_APPLY_FAILED);
+
+   if (!elm_layout_theme_set(obj, "spin", "base", elm_widget_style_get(obj)))
+     CRI("Failed to set layout!");
+
+   elm_layout_sizing_eval(obj);
+
+   return EFL_UI_THEME_APPLY_SUCCESS;
+}
+
+EOLIAN static Eo *
+_efl_ui_spin_efl_object_constructor(Eo *obj, Efl_Ui_Spin_Data *sd)
+{
+   obj = efl_constructor(efl_super(obj, MY_CLASS));
+
+   elm_widget_sub_object_parent_add(obj);
+
+   sd->val_max = 100.0;
+   sd->step = 1.0;
+
+   if (!elm_layout_theme_set(obj, "spin", "base",
+                             elm_widget_style_get(obj)))
+     CRI("Failed to set layout!");
+
+   _label_write(obj);
+   elm_widget_can_focus_set(obj, EINA_TRUE);
+
+   elm_layout_sizing_eval(obj);
+
+   return obj;
+}
+
+EOLIAN static Eo *
+_efl_ui_spin_efl_object_finalize(Eo *obj, Efl_Ui_Spin_Data *sd EINA_UNUSED)
+{
+   obj = efl_finalize(efl_super(obj, MY_CLASS));
+
+   return obj;
+}
+
+EOLIAN static void
+_efl_ui_spin_efl_object_destructor(Eo *obj, Efl_Ui_Spin_Data *sd EINA_UNUSED)
+{
+   efl_ui_format_cb_set(obj, NULL, NULL, NULL);
+   efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static void
+_efl_ui_spin_efl_ui_format_format_cb_set(Eo *obj, Efl_Ui_Spin_Data *sd, void 
*func_data, Efl_Ui_Format_Func_Cb func, Eina_Free_Cb func_free_cb)
+{
+   if (sd->format_cb_data == func_data && sd->format_cb == func)
+     return;
+
+   if (sd->format_cb_data && sd->format_free_cb)
+     sd->format_free_cb(sd->format_cb_data);
+
+   sd->format_cb = func;
+   sd->format_cb_data = func_data;
+   sd->format_free_cb = func_free_cb;
+   if (!sd->format_strbuf) sd->format_strbuf = eina_strbuf_new();
+
+   const char *format = efl_ui_format_string_get(obj);
+   if (format)
+     {
+        sd->format_type = _is_label_format_integer(format);
+        if (sd->format_type == SPIN_FORMAT_INVALID)
+          {
+             ERR("format:\"%s\" is invalid, cannot be set", format);
+             return;
+          }
+        else if (sd->format_type == SPIN_FORMAT_FLOAT)
+          sd->decimal_points = _decimal_points_get(format);
+     }
+
+   _label_write(obj);
+   elm_layout_sizing_eval(obj);
+}
+
+EOLIAN static void
+_efl_ui_spin_efl_ui_range_range_min_max_set(Eo *obj, Efl_Ui_Spin_Data *sd, 
double min, double max)
+{
+   if (max < min)
+     {
+        ERR("Wrong params. min(%lf) is bigger than max(%lf). It will swaped.", 
min, max);
+        double t = min;
+        min = max;
+        max = t;
+     }
+   if ((EINA_DBL_EQ(sd->val_min, min)) && (EINA_DBL_EQ(sd->val_max, max))) 
return;
+
+   sd->val_min = min;
+   sd->val_max = max;
+
+   if (sd->val < sd->val_min) sd->val = sd->val_min;
+   if (sd->val > sd->val_max) sd->val = sd->val_max;
+
+   _label_write(obj);
+}
+
+EOLIAN static void
+_efl_ui_spin_efl_ui_range_range_min_max_get(Eo *obj EINA_UNUSED, 
Efl_Ui_Spin_Data *sd, double *min, double *max)
+{
+   if (min) *min = sd->val_min;
+   if (max) *max = sd->val_max;
+}
+
+EOLIAN static void
+_efl_ui_spin_efl_ui_range_range_step_set(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Data 
*sd, double step)
+{
+   if (step <= 0)
+     {
+        ERR("Wrong param. The step(%lf) should be bigger than 0.0", step);
+        return;
+     }
+
+   sd->step = step;
+}
+
+EOLIAN static double
+_efl_ui_spin_efl_ui_range_range_step_get(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Data 
*sd)
+{
+   return sd->step;
+}
+
+EOLIAN static void
+_efl_ui_spin_efl_ui_range_range_value_set(Eo *obj, Efl_Ui_Spin_Data *sd, 
double val)
+{
+   if (val < sd->val_min)
+     val = sd->val_min;
+   else if (val > sd->val_max)
+     val = sd->val_max;
+
+   if (EINA_DBL_EQ(val, sd->val)) return;
+
+   sd->val = val;
+
+   if (EINA_DBL_EQ(sd->val, sd->val_min))
+     efl_event_callback_call(obj, EFL_UI_SPIN_EVENT_MIN_REACHED, NULL);
+   else if (EINA_DBL_EQ(sd->val, sd->val_max))
+     efl_event_callback_call(obj, EFL_UI_SPIN_EVENT_MAX_REACHED, NULL);
+
+   efl_event_callback_call(obj, EFL_UI_SPIN_EVENT_CHANGED, NULL);
+
+   _label_write(obj);
+}
+
+EOLIAN static double
+_efl_ui_spin_efl_ui_range_range_value_get(Eo *obj EINA_UNUSED, 
Efl_Ui_Spin_Data *sd)
+{
+   return sd->val;
+}
+
+#define EFL_UI_SPIN_EXTRA_OPS \
+   ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_spin), \
+
+#include "efl_ui_spin.eo.c"
diff --git a/src/lib/elementary/efl_ui_spin.eo 
b/src/lib/elementary/efl_ui_spin.eo
new file mode 100644
index 0000000000..df2e2bd1dc
--- /dev/null
+++ b/src/lib/elementary/efl_ui_spin.eo
@@ -0,0 +1,26 @@
+class Efl.Ui.Spin (Efl.Ui.Layout, Efl.Ui.Range, Efl.Ui.Format,
+                   Efl.Access.Value, Efl.Access.Widget.Action)
+{
+   [[A Spin.
+
+     This is a widget which allows the user to increase or decrease numeric 
values
+     using user interactions. It's base type of widget to picking a value and 
showing value.
+
+     @since 1.21
+   ]]
+   implements {
+      Efl.Object.constructor;
+      Efl.Object.finalize;
+      Efl.Object.destructor;
+      Elm.Widget.theme_apply;
+      Efl.Ui.Range.range_min_max { get; set; }
+      Efl.Ui.Range.range_step { get; set; }
+      Efl.Ui.Range.range_value { get; set; }
+      Efl.Ui.Format.format_cb { set; }
+   }
+   events {
+      changed; [[Called when spin changed]]
+      min,reached; [[Called when spin value reached min]]
+      max,reached; [[Called when spin value reached max]]
+   }
+}
diff --git a/src/lib/elementary/efl_ui_spin_button.c 
b/src/lib/elementary/efl_ui_spin_button.c
new file mode 100644
index 0000000000..21b0e28072
--- /dev/null
+++ b/src/lib/elementary/efl_ui_spin_button.c
@@ -0,0 +1,922 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define EFL_ACCESS_PROTECTED
+#define EFL_ACCESS_VALUE_PROTECTED
+#define EFL_ACCESS_WIDGET_ACTION_PROTECTED
+#define EFL_UI_FOCUS_COMPOSITION_PROTECTED
+
+#include <Elementary.h>
+
+#include "elm_priv.h"
+#include "efl_ui_spin_button_private.h"
+#include "efl_ui_spin_private.h"
+#include "elm_entry.eo.h"
+
+#define MY_CLASS EFL_UI_SPIN_BUTTON_CLASS
+
+#define MY_CLASS_NAME "Efl.Ui.Spin_Button"
+
+#define EFL_UI_SPIN_BUTTON_DELAY_CHANGE_TIME 0.2
+
+static void
+_inc_dec_button_clicked_cb(void *data, const Efl_Event *event);
+static void
+_inc_dec_button_pressed_cb(void *data, const Efl_Event *event);
+static void
+_inc_dec_button_unpressed_cb(void *data, const Efl_Event *event);
+static void
+_inc_dec_button_mouse_move_cb(void *data, const Efl_Event *event);
+static void
+_entry_activated_cb(void *data, const Efl_Event *event);
+static void
+_entry_focus_changed_cb(void *data, const Efl_Event *event);
+static void
+_access_increment_decrement_info_say(Evas_Object *obj, Eina_Bool 
is_incremented);
+
+EFL_CALLBACKS_ARRAY_DEFINE(_inc_dec_button_cb,
+                           { EFL_UI_EVENT_CLICKED, _inc_dec_button_clicked_cb},
+                           { EFL_UI_EVENT_PRESSED, _inc_dec_button_pressed_cb},
+                           { EFL_UI_EVENT_UNPRESSED, 
_inc_dec_button_unpressed_cb},
+                           { EFL_EVENT_POINTER_MOVE, 
_inc_dec_button_mouse_move_cb }
+                          );
+
+static void
+_entry_show(Evas_Object *obj)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+   Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
+   char buf[32], fmt[32] = "%0.f";
+
+   /* try to construct just the format from given label
+    * completely ignoring pre/post words
+    */
+   if (pd->templates)
+     {
+        const char *start = strchr(pd->templates, '%');
+        while (start)
+          {
+             /* handle %% */
+             if (start[1] != '%')
+               break;
+             else
+               start = strchr(start + 2, '%');
+          }
+
+        if (start)
+          {
+             const char *itr, *end = NULL;
+             for (itr = start + 1; *itr != '\0'; itr++)
+               {
+                  if ((*itr == 'd') || (*itr == 'u') || (*itr == 'i') || (*itr 
== 'o') ||
+                      (*itr == 'x') || (*itr == 'X') || (*itr == 'f') || (*itr 
== 'F'))
+                    {
+                       end = itr + 1;
+                       break;
+                    }
+               }
+
+             if ((end) && ((size_t)(end - start + 1) < sizeof(fmt)))
+               {
+                  memcpy(fmt, start, end - start);
+                  fmt[end - start] = '\0';
+               }
+          }
+     }
+
+   if (pd->format_type == SPIN_FORMAT_INT)
+     snprintf(buf, sizeof(buf), fmt, (int)pd->val);
+   else
+     snprintf(buf, sizeof(buf), fmt, pd->val);
+
+   elm_object_text_set(sd->ent, buf);
+}
+
+static void
+_label_write(Evas_Object *obj)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+
+   Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
+
+   if (pd->templates)
+     elm_layout_text_set(sd->text_button, "elm.text", pd->templates);
+   else
+     {
+        char buf[1024];
+
+        snprintf(buf, sizeof(buf), "%.0f", pd->val);
+        elm_layout_text_set(sd->text_button, "elm.text", buf);
+     }
+}
+
+static Eina_Bool
+_delay_change_timer_cb(void *data)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
+
+   sd->delay_change_timer = NULL;
+   efl_event_callback_call(data, EFL_UI_SPIN_BUTTON_EVENT_DELAY_CHANGED, NULL);
+
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool
+_value_set(Evas_Object *obj,
+           double new_val)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+   Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
+
+   if (sd->loop)
+     {
+        if (new_val < pd->val_min)
+          new_val = pd->val_max;
+        else if (new_val > pd->val_max)
+          new_val = pd->val_min;
+     }
+
+   efl_ui_range_value_set(obj, new_val);
+   ecore_timer_del(sd->delay_change_timer);
+   sd->delay_change_timer = 
ecore_timer_add(EFL_UI_SPIN_BUTTON_DELAY_CHANGE_TIME,
+                                            _delay_change_timer_cb, obj);
+
+   return EINA_TRUE;
+}
+
+static void
+_entry_hide(Evas_Object *obj)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+
+   elm_layout_signal_emit(obj, "elm,state,button,active", "elm");
+   evas_object_show(sd->text_button);
+   elm_layout_signal_emit(obj, "elm,state,entry,inactive", "elm");
+   evas_object_hide(sd->ent);
+
+   if (sd->entry_visible && !evas_focus_state_get(evas_object_evas_get(obj)))
+     sd->entry_reactivate = EINA_TRUE;
+
+   sd->entry_visible = EINA_FALSE;
+}
+
+static void
+_entry_value_apply(Evas_Object *obj)
+{
+   const char *str;
+   double val;
+   char *end;
+
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+   Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
+
+   if (!sd->entry_visible) return;
+
+   efl_event_callback_del(sd->ent, EFL_UI_FOCUS_OBJECT_EVENT_FOCUS_CHANGED,
+                          _entry_focus_changed_cb, obj);
+   _entry_hide(obj);
+   str = elm_object_text_get(sd->ent);
+   if (!str) return;
+
+   val = strtod(str, &end);
+   if (((*end != '\0') && (!isspace(*end))) || (fabs(val - pd->val) < 
DBL_EPSILON)) return;
+   efl_ui_range_value_set(obj, val);
+
+   efl_event_callback_call(obj, EFL_UI_SPIN_EVENT_CHANGED, NULL);
+   ecore_timer_del(sd->delay_change_timer);
+   sd->delay_change_timer = 
ecore_timer_add(EFL_UI_SPIN_BUTTON_DELAY_CHANGE_TIME,
+                                            _delay_change_timer_cb, obj);
+}
+
+static void
+_invalid_input_validity_filter(void *data EINA_UNUSED, Evas_Object *obj, char 
**text)
+{
+   char *insert = NULL;
+   const char *str = NULL;
+   int cursor_pos = 0;
+   int read_idx = 0, read_char, cmp_char;
+
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   EINA_SAFETY_ON_NULL_RETURN(text);
+
+   insert = *text;
+   str = elm_object_text_get(obj);
+
+   evas_string_char_next_get(*text, 0, &read_char);
+   cursor_pos = elm_entry_cursor_pos_get(obj);
+   if (read_char)
+     {
+       if (read_char == '-')
+         {
+            if (cursor_pos != 0)
+              {
+                 goto invalid_input;
+              }
+         }
+       if (read_char == '.')
+         {
+            read_idx = evas_string_char_next_get(str, 0, &cmp_char);
+            while (cmp_char)
+              {
+                 if (read_char == cmp_char)
+                   {
+                      goto invalid_input;
+                   }
+                 read_idx = evas_string_char_next_get(str, read_idx, 
&cmp_char);
+               }
+         }
+       read_idx = evas_string_char_next_get(str, 0, &cmp_char);
+       if ((cmp_char == '-') && (cursor_pos == 0))
+         {
+            goto invalid_input;
+         }
+     }
+   return;
+
+invalid_input:
+   *insert = 0;
+}
+
+static void
+_entry_accept_filter_add(Evas_Object *obj)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+   Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
+   static Elm_Entry_Filter_Accept_Set digits_filter_data;
+
+   if (!sd->ent) return;
+
+   elm_entry_markup_filter_remove(sd->ent, elm_entry_filter_accept_set, 
&digits_filter_data);
+
+   if (pd->decimal_points > 0)
+     digits_filter_data.accepted = "-.0123456789";
+   else
+     digits_filter_data.accepted = "-0123456789";
+
+   elm_entry_markup_filter_prepend(sd->ent, elm_entry_filter_accept_set, 
&digits_filter_data);
+}
+
+static char *
+_text_insert(const char *text, const char *input, int pos)
+{
+   char *result = NULL;
+   int text_len, input_len;
+
+   text_len = evas_string_char_len_get(text);
+   input_len = evas_string_char_len_get(input);
+   result = (char *)calloc(text_len + input_len + 1, sizeof(char));
+   if (!result) return NULL;
+
+   strncpy(result, text, pos);
+   strcpy(result + pos, input);
+   strcpy(result + pos + input_len, text + pos);
+
+   return result;
+}
+
+static void
+_min_max_validity_filter(void *data, Evas_Object *obj, char **text)
+{
+   const char *str, *point;
+   char *insert, *new_str = NULL;
+   double val;
+   int max_len, len;
+
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   EINA_SAFETY_ON_NULL_RETURN(text);
+
+   Efl_Ui_Spin_Data *pd = efl_data_scope_get(data, EFL_UI_SPIN_CLASS);
+
+   str = elm_object_text_get(obj);
+   if (!str) return;
+
+   insert = *text;
+   new_str = _text_insert(str, insert, elm_entry_cursor_pos_get(obj));
+   if (!new_str) return;
+   max_len = log10(fabs(pd->val_max)) + 1;
+
+   new_str = _text_insert(str, insert, elm_entry_cursor_pos_get(obj));
+   if (pd->format_type == SPIN_FORMAT_INT)
+     {
+        len = strlen(new_str);
+        if (len < max_len) goto end;
+     }
+   else if (pd->format_type == SPIN_FORMAT_FLOAT)
+     {
+        point = strchr(new_str, '.');
+        if (point)
+          {
+             if ((int) strlen(point + 1) > pd->decimal_points)
+               {
+                  *insert = 0;
+                  goto end;
+               }
+          }
+     }
+
+   val = strtod(new_str, NULL);
+   if ((val < pd->val_min) || (val > pd->val_max))
+     *insert = 0;
+
+end:
+   free(new_str);
+}
+
+static void
+_entry_show_cb(void *data,
+               Evas *e EINA_UNUSED,
+               Evas_Object *obj,
+               void *event_info EINA_UNUSED)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
+
+   _entry_show(data);
+   elm_object_focus_set(obj, EINA_TRUE);
+   elm_entry_select_all(obj);
+   sd->entry_visible = EINA_TRUE;
+   elm_layout_signal_emit(data, "elm,state,button,inactive", "elm");
+   evas_object_hide(sd->text_button);
+}
+
+static void
+_toggle_entry(Evas_Object *obj)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+
+   if (elm_widget_disabled_get(obj)) return;
+   if (!sd->editable) return;
+   if (sd->entry_visible) _entry_value_apply(obj);
+   else
+     {
+        if (!sd->ent)
+          {
+             sd->ent = elm_entry_add(obj);
+             Eina_Strbuf *buf = eina_strbuf_new();
+             eina_strbuf_append_printf(buf, "spinner/%s", 
elm_widget_style_get(obj));
+             elm_widget_style_set(sd->ent, eina_strbuf_string_get(buf));
+             eina_strbuf_free(buf);
+             evas_object_event_callback_add
+               (sd->ent, EVAS_CALLBACK_SHOW, _entry_show_cb, obj);
+             elm_entry_single_line_set(sd->ent, EINA_TRUE);
+             elm_layout_content_set(obj, "elm.swallow.entry", sd->ent);
+             _entry_accept_filter_add(obj);
+             elm_entry_markup_filter_append(sd->ent, 
_invalid_input_validity_filter, NULL);
+             if (_elm_config->spinner_min_max_filter_enable)
+               elm_entry_markup_filter_append(sd->ent, 
_min_max_validity_filter, obj);
+             efl_event_callback_add(sd->ent, ELM_ENTRY_EVENT_ACTIVATED,
+                                    _entry_activated_cb, obj);
+          }
+
+        efl_event_callback_add(sd->ent, 
EFL_UI_FOCUS_OBJECT_EVENT_FOCUS_CHANGED,
+                               _entry_focus_changed_cb, obj);
+        sd->entry_visible = EINA_TRUE;
+        elm_layout_signal_emit(obj, "elm,state,entry,active", "elm");
+        evas_object_show(sd->ent);
+        {
+           Eina_List *items = NULL;
+
+           items = eina_list_append(items, sd->dec_button);
+           items = eina_list_append(items, sd->text_button);
+           items = eina_list_append(items, sd->ent);
+           items = eina_list_append(items, sd->inc_button);
+
+           efl_ui_focus_composition_elements_set(obj, items);
+        }
+
+        efl_ui_focus_manager_focus_set(efl_ui_focus_user_manager_get(obj), 
sd->ent);
+     }
+}
+
+static void
+_entry_toggle_cb(void *data EINA_UNUSED,
+                 Evas_Object *obj,
+                 const char *emission EINA_UNUSED,
+                 const char *source EINA_UNUSED)
+{
+   _toggle_entry(obj);
+}
+
+static Eina_Bool
+_spin_value(void *data)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
+   Efl_Ui_Spin_Data *pd = efl_data_scope_get(data, EFL_UI_SPIN_CLASS);
+
+   if (_value_set(data, pd->val + (sd->inc_val ? pd->step : -pd->step))) 
+     _label_write(data);
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_spin_stop(Evas_Object *obj)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+
+   ELM_SAFE_FREE(sd->spin_timer, ecore_timer_del);
+
+   elm_widget_scroll_freeze_pop(obj);
+}
+
+static Eina_Bool
+_inc_dec_button_press_start(void *data)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
+
+   sd->interval = sd->first_interval;
+   sd->longpress_timer = NULL;
+   ecore_timer_del(sd->spin_timer);
+   sd->spin_timer = ecore_timer_add(sd->interval, _spin_value, data);
+   _spin_value(data);
+
+   elm_widget_scroll_freeze_push(data);
+
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_inc_dec_button_clicked_cb(void *data, const Efl_Event *event)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
+
+   _spin_stop(data);
+   sd->inc_val = sd->inc_button == event->object ? EINA_TRUE : EINA_FALSE;
+   _spin_value(data);
+
+   if (_elm_config->access_mode)
+     _access_increment_decrement_info_say(data, EINA_TRUE);
+}
+
+
+static void
+_inc_dec_button_pressed_cb(void *data, const Efl_Event *event)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
+
+   sd->inc_val = sd->inc_button == event->object ? EINA_TRUE : EINA_FALSE;
+
+   if (sd->longpress_timer) ecore_timer_del(sd->longpress_timer);
+
+   sd->longpress_timer = ecore_timer_add
+                           (_elm_config->longpress_timeout,
+                            _inc_dec_button_press_start, data);
+
+   if (sd->entry_visible) _entry_value_apply(data);
+}
+
+static void
+_inc_dec_button_unpressed_cb(void *data, const Efl_Event *event EINA_UNUSED)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
+
+   if (sd->longpress_timer)
+     {
+        ecore_timer_del(sd->longpress_timer);
+        sd->longpress_timer = NULL;
+     }
+
+   _spin_stop(data);
+}
+
+static void
+_inc_dec_button_mouse_move_cb(void *data, const Efl_Event *event)
+{
+   Efl_Input_Pointer *ev = event->info;
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
+
+   if (efl_input_processed_get(ev) && sd->longpress_timer)
+     {
+        ecore_timer_del(sd->longpress_timer);
+        sd->longpress_timer = NULL;
+     }
+}
+
+static void
+_text_button_focus_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
+{
+   _toggle_entry(data);
+}
+
+static void
+_entry_activated_cb(void *data, const Efl_Event *event EINA_UNUSED)
+{
+   _toggle_entry(data);
+}
+
+static void
+_entry_focus_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
+{
+   _toggle_entry(data);
+}
+
+static void
+_text_button_clicked_cb(void *data, const Efl_Event *event EINA_UNUSED)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
+
+   if (sd->entry_visible) return;
+   _toggle_entry(data);
+}
+
+static Eina_Bool
+_key_action_toggle(Evas_Object *obj, const char *params EINA_UNUSED)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+
+   if (sd->spin_timer) _spin_stop(obj);
+   else if (sd->entry_visible) _entry_toggle_cb(NULL, obj, NULL, NULL);
+
+   return EINA_FALSE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_spin_button_elm_widget_widget_event(Eo *obj, Efl_Ui_Spin_Button_Data 
*sd EINA_UNUSED, const Efl_Event *eo_event, Evas_Object *src EINA_UNUSED)
+{
+   Eo *ev = eo_event->info;
+
+   if (efl_input_processed_get(ev)) return EINA_FALSE;
+   if (eo_event->desc == EFL_EVENT_KEY_DOWN)
+     {
+        if (sd->spin_timer) _spin_stop(obj);
+        else return EINA_FALSE;
+     }
+   else if (eo_event->desc == EFL_EVENT_KEY_UP)
+     {
+        if (sd->spin_timer) _spin_stop(obj);
+        else return EINA_FALSE;
+     }
+   else if (eo_event->desc == EFL_EVENT_POINTER_WHEEL)
+     {
+        sd->interval = sd->first_interval;
+        if (efl_input_pointer_wheel_delta_get(ev) < 0)
+          sd->inc_val = EINA_TRUE;
+        else
+          sd->inc_val = EINA_FALSE;
+
+           _spin_value(obj);
+     }
+   else return EINA_FALSE;
+
+   efl_input_processed_set(ev, EINA_TRUE);
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_spin_button_elm_widget_on_focus_update(Eo *obj, 
Efl_Ui_Spin_Button_Data *sd, Elm_Object_Item *item EINA_UNUSED)
+{
+   Eina_Bool int_ret = EINA_FALSE;
+
+   int_ret = efl_ui_widget_on_focus_update(efl_super(obj, MY_CLASS), NULL);
+   if (!int_ret) return EINA_FALSE;
+
+   if (!elm_widget_focus_get(obj))
+     {
+        ELM_SAFE_FREE(sd->delay_change_timer, ecore_timer_del);
+        ELM_SAFE_FREE(sd->spin_timer, ecore_timer_del);
+     }
+   else
+     {
+        if (sd->entry_reactivate)
+          {
+             _toggle_entry(obj);
+
+             sd->entry_reactivate = EINA_FALSE;
+          }
+     }
+
+   return EINA_TRUE;
+}
+
+EOLIAN static void
+_efl_ui_spin_button_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Spin_Button_Data 
*_pd EINA_UNUSED)
+{
+   Evas_Coord minw = -1, minh = -1;
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   edje_object_size_min_restricted_calc
+     (wd->resize_obj, &minw, &minh, minw, minh);
+   elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+static char *
+_access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
+{
+   const char *txt = NULL;
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
+
+   if (sd->entry_visible)
+     txt = elm_object_text_get(sd->ent);
+   else
+        txt = elm_object_text_get(sd->text_button);
+
+   if (txt) return strdup(txt);
+
+   return NULL;
+}
+
+static char *
+_access_state_cb(void *data, Evas_Object *obj EINA_UNUSED)
+{
+   if (elm_widget_disabled_get(data))
+     return strdup(E_("State: Disabled"));
+
+   return NULL;
+}
+
+static void
+_access_activate_spin_button_cb(void *data,
+                            Evas_Object *part_obj EINA_UNUSED,
+                            Elm_Object_Item *item EINA_UNUSED)
+{
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
+
+   if (elm_widget_disabled_get(data)) return;
+   if (!sd->entry_visible)
+     _toggle_entry(data);
+}
+
+static void
+_access_increment_decrement_info_say(Evas_Object *obj,
+                                     Eina_Bool is_incremented)
+{
+   Eina_Strbuf *buf;
+
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+
+   buf = eina_strbuf_new();
+   if (is_incremented)
+     {
+        elm_object_signal_emit
+           (sd->inc_button, "elm,action,anim,activate", "elm");
+        eina_strbuf_append(buf, E_("incremented"));
+     }
+   else
+     {
+        elm_object_signal_emit
+           (sd->dec_button, "elm,action,anim,activate", "elm");
+        eina_strbuf_append(buf, E_("decremented"));
+     }
+
+   eina_strbuf_append_printf
+      (buf, "%s", elm_object_text_get(sd->text_button));
+
+   _elm_access_say(eina_strbuf_string_get(buf));
+   eina_strbuf_free(buf);
+}
+
+static void
+_access_spinner_register(Evas_Object *obj, Eina_Bool is_access)
+{
+   Evas_Object *ao;
+   Elm_Access_Info *ai;
+
+   Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+
+   if (!is_access)
+     {
+        /* unregister access */
+        _elm_access_edje_object_part_object_unregister
+           (obj, elm_layout_edje_get(obj), "access");
+        elm_layout_signal_emit(obj, "elm,state,access,inactive", "elm");
+        return;
+     }
+   elm_layout_signal_emit(obj, "elm,state,access,active", "elm");
+   ao = _elm_access_edje_object_part_object_register
+      (obj, elm_layout_edje_get(obj), "access");
+
+   ai = _elm_access_info_get(ao);
+   _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("spinner"));
+   _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, obj);
+   _elm_access_activate_callback_set(ai, _access_activate_spin_button_cb, obj);
+
+   /*Do not register spinner buttons if widget is disabled*/
+   if (!elm_widget_disabled_get(obj))
+     {
+        ai = _elm_access_info_get(sd->inc_button);
+        _elm_access_text_set(ai, ELM_ACCESS_TYPE,
+                             E_("spinner increment button"));
+        ai = _elm_access_info_get(sd->dec_button);
+        _elm_access_text_set(ai, ELM_ACCESS_TYPE,
+                             E_("spinner decrement button"));
+        ai = _elm_access_info_get(sd->text_button);
+        _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("spinner text"));
+        _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, obj);
+     }
+}
+
+EOLIAN static Efl_Ui_Theme_Apply
+_efl_ui_spin_button_elm_widget_theme_apply(Eo *obj, Efl_Ui_Spin_Button_Data 
*sd EINA_UNUSED)
+{
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EFL_UI_THEME_APPLY_FAILED);
+
+   if (!elm_layout_theme_set(obj, "spin_button", "base", 
elm_widget_style_get(obj)))
+     CRI("Failed to set layout!");
+
+   if (sd->ent)
+     {
+        Eina_Strbuf *buf = eina_strbuf_new();
+        eina_strbuf_append_printf(buf, "spin_button/%s", 
elm_widget_style_get(obj));
+        elm_widget_style_set(sd->ent, eina_strbuf_string_get(buf));
+        eina_strbuf_free(buf);
+     }
+
+   if (sd->inc_button)
+     {
+        Eina_Strbuf *buf = eina_strbuf_new();
+        eina_strbuf_append_printf(buf, "spin_button/increase/%s", 
elm_widget_style_get(obj));
+        elm_widget_style_set(sd->inc_button, eina_strbuf_string_get(buf));
+        eina_strbuf_free(buf);
+     }
+
+   if (sd->text_button)
+     {
+        Eina_Strbuf *buf = eina_strbuf_new();
+        eina_strbuf_append_printf(buf, "spin_button/%s", 
elm_widget_style_get(obj));
+        elm_widget_style_set(sd->text_button, eina_strbuf_string_get(buf));
+        eina_strbuf_free(buf);
+     }
+
+   if (sd->dec_button)
+     {
+        Eina_Strbuf *buf = eina_strbuf_new();
+        eina_strbuf_append_printf(buf, "spin_button/decrease/%s", 
elm_widget_style_get(obj));
+        elm_widget_style_set(sd->dec_button, eina_strbuf_string_get(buf));
+        eina_strbuf_free(buf);
+     }
+
+   if (_elm_config->access_mode)
+     _access_spinner_register(obj, EINA_TRUE);
+
+   elm_layout_sizing_eval(obj);
+   return EFL_UI_THEME_APPLY_SUCCESS;
+}
+
+EOLIAN static Eo *
+_efl_ui_spin_button_efl_object_finalize(Eo *obj, Efl_Ui_Spin_Button_Data *sd)
+{
+   obj = efl_finalize(efl_super(obj, MY_CLASS));
+
+   elm_widget_sub_object_parent_add(obj);
+
+   sd->first_interval = 0.85;
+
+   if (!elm_layout_theme_set(obj, "spin_button", "base",
+                             elm_widget_style_get(obj)))
+     CRI("Failed to set layout!");
+
+   sd->inc_button = elm_button_add(obj);
+   elm_object_style_set(sd->inc_button, "spinner/increase/default");
+
+   efl_event_callback_array_add(sd->inc_button, _inc_dec_button_cb(), obj);
+
+   elm_layout_content_set(obj, "elm.swallow.inc_button", sd->inc_button);
+   elm_widget_sub_object_add(obj, sd->inc_button);
+
+   sd->text_button = elm_button_add(obj);
+   elm_object_style_set(sd->text_button, "spinner/default");
+
+   efl_event_callback_add(sd->text_button, EFL_UI_EVENT_CLICKED,
+                          _text_button_clicked_cb, obj);
+   efl_event_callback_add(sd->text_button,
+                          EFL_UI_FOCUS_OBJECT_EVENT_FOCUS_CHANGED,
+                          _text_button_focus_changed_cb, obj);
+
+   elm_layout_content_set(obj, "elm.swallow.text_button", sd->text_button);
+   elm_widget_sub_object_add(obj, sd->text_button);
+
+   sd->dec_button = elm_button_add(obj);
+   elm_object_style_set(sd->dec_button, "spinner/decrease/default");
+
+   efl_event_callback_array_add(sd->dec_button, _inc_dec_button_cb(), obj);
+
+   elm_layout_content_set(obj, "elm.swallow.dec_button", sd->dec_button);
+   elm_widget_sub_object_add(obj, sd->dec_button);
+
+     {
+        Eina_List *items = NULL;
+
+        items = eina_list_append(items, sd->dec_button);
+        items = eina_list_append(items, sd->text_button);
+        items = eina_list_append(items, sd->inc_button);
+
+        efl_ui_focus_composition_elements_set(obj, items);
+     }
+
+   elm_layout_signal_callback_add
+      (obj, "elm,action,entry,toggle", "*", _entry_toggle_cb, NULL);
+
+   _label_write(obj);
+   elm_widget_can_focus_set(obj, EINA_TRUE);
+
+   elm_layout_sizing_eval(obj);
+   efl_access_role_set(obj, EFL_ACCESS_ROLE_SPIN_BUTTON);
+
+   return obj;
+}
+
+EOLIAN static void
+_efl_ui_spin_button_efl_ui_range_range_value_set(Eo *obj, 
Efl_Ui_Spin_Button_Data *sd EINA_UNUSED, double val)
+{
+   efl_ui_range_value_set(efl_super(obj, MY_CLASS), val);
+
+   _label_write(obj);
+}
+
+EOLIAN static void
+_efl_ui_spin_button_editable_set(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Button_Data 
*sd, Eina_Bool editable)
+{
+   sd->editable = editable;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_spin_button_editable_get(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Button_Data 
*sd)
+{
+   return sd->editable;
+}
+
+EOLIAN static void
+_efl_ui_spin_button_loop_set(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Button_Data *sd, 
Eina_Bool loop)
+{
+   sd->loop = loop;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_spin_button_loop_get(Eo *obj EINA_UNUSED, Efl_Ui_Spin_Button_Data *sd)
+{
+   return sd->loop;
+}
+
+EOLIAN static const Efl_Access_Action_Data *
+_efl_ui_spin_button_efl_access_widget_action_elm_actions_get(Eo *obj 
EINA_UNUSED, Efl_Ui_Spin_Button_Data *sd EINA_UNUSED)
+{
+   static Efl_Access_Action_Data atspi_actions[] = {
+          { "toggle", "toggle", NULL, _key_action_toggle},
+          { NULL, NULL, NULL, NULL }
+   };
+   return &atspi_actions[0];
+}
+
+// A11Y Accessibility
+
+EOLIAN static void
+_efl_ui_spin_button_efl_access_value_value_and_text_get(Eo *obj EINA_UNUSED, 
Efl_Ui_Spin_Button_Data *sd EINA_UNUSED, double *value, const char **text)
+{
+   Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
+
+   if (value) *value = pd->val;
+   if (text) *text = NULL;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_spin_button_efl_access_value_value_and_text_set(Eo *obj, 
Efl_Ui_Spin_Button_Data *sd EINA_UNUSED, double value, const char *text 
EINA_UNUSED)
+{
+   Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
+
+   if (pd->val_min > value) return EINA_FALSE;
+   if (pd->val_max < value) return EINA_FALSE;
+
+   pd->val = value;
+   efl_ui_range_value_set(efl_super(obj, MY_CLASS), value);
+
+   return EINA_TRUE;
+}
+
+EOLIAN static void
+_efl_ui_spin_button_efl_access_value_range_get(Eo *obj EINA_UNUSED, 
Efl_Ui_Spin_Button_Data *sd EINA_UNUSED, double *lower, double *upper, const 
char **descr)
+{
+   Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
+
+   if (lower) *lower = pd->val_min;
+   if (upper) *upper = pd->val_max;
+   if (descr) *descr = NULL;
+}
+
+EOLIAN static double
+_efl_ui_spin_button_efl_access_value_increment_get(Eo *obj EINA_UNUSED, 
Efl_Ui_Spin_Button_Data *sd EINA_UNUSED)
+{
+   Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
+
+   return pd->step;
+}
+
+EOLIAN static const char*
+_efl_ui_spin_button_efl_access_name_get(Eo *obj, Efl_Ui_Spin_Button_Data *sd 
EINA_UNUSED)
+{
+   const char *name;
+   name = efl_access_name_get(efl_super(obj, EFL_UI_SPIN_BUTTON_CLASS));
+   if (name) return name;
+   const char *ret = elm_layout_text_get(obj, "elm.text");
+   return ret;
+}
+
+// A11Y Accessibility - END
+
+#define EFL_UI_SPIN_BUTTON_EXTRA_OPS \
+   ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_spin_button), \
+
+#include "efl_ui_spin_button.eo.c"
diff --git a/src/lib/elementary/efl_ui_spin_button.eo 
b/src/lib/elementary/efl_ui_spin_button.eo
new file mode 100644
index 0000000000..06c604e574
--- /dev/null
+++ b/src/lib/elementary/efl_ui_spin_button.eo
@@ -0,0 +1,80 @@
+class Efl.Ui.Spin_Button (Efl.Ui.Spin, Efl.Ui.Focus.Composition,
+                                 Efl.Access.Value, Efl.Access.Widget.Action)
+{
+   [[A Button Spin.
+
+     This is a widget which allows the user to increase or decrease
+     numeric values using arrow buttons, or edit values directly, clicking
+     over it and typing the new value.
+
+     @since 1.21
+   ]]
+   methods {
+      @property loop {
+         [[Control whether the spin should loop when it reaches its minimum or 
maximum value.
+
+           Disabled by default. If disabled, when the user tries to increment 
the
+           value,
+           but displayed value plus step value is bigger than maximum value,
+           the new value will be the maximum value.
+           The same happens when the user tries to decrement it,
+           but the value less step is less than minimum value. In this case,
+           the new displayed value will be the minimum value.
+
+           When loop is enabled, when the user tries to increment the value,
+           but displayed value plus step value is bigger than maximum value,
+           the new value will be the minimum value. When the the user tries to
+           decrement it, but the value less step is less than minimum value,
+           the new displayed value will be the maximum value.
+
+           E.g.:
+           $min = 10
+           $max = 50
+           $step = 20
+           $displayed = 20
+
+           When the user decrement value (using left or bottom arrow), it will
+           displays $50.]]
+         set {
+         }
+         get {
+         }
+         values {
+            loop: bool(false); [[$true to enable loop or $false to disable 
it.]]
+         }
+      }
+      @property editable {
+         [[Control whether the spin can be directly edited by the user or not.
+
+           Spin objects can have edition disabled, in which state they will
+           be changed only by arrows.
+           Useful for contexts
+           where you don't want your users to interact with it writing the 
value.
+           Specially
+           when using special values, the user can see real value instead
+           of special label on edition.]]
+         set {
+         }
+         get {
+         }
+         values {
+            editable: bool(false); [[$true to allow users to edit it or $false 
to don't allow users to edit it directly.]]
+         }
+      }
+   }
+   implements {
+      Efl.Object.finalize;
+      Elm.Widget.theme_apply;
+      Elm.Widget.widget_event;
+      Elm.Widget.on_focus_update;
+      Efl.Ui.Range.range_value { set; }
+      Efl.Access.name { get; }
+      Efl.Access.Value.value_and_text { get; set; }
+      Efl.Access.Value.range { get; }
+      Efl.Access.Value.increment { get; }
+      Efl.Access.Widget.Action.elm_actions { get; }
+   }
+   events {
+      delay,changed; [[Called when spin delay changed]]
+   }
+}
diff --git a/src/lib/elementary/efl_ui_spin_button_private.h 
b/src/lib/elementary/efl_ui_spin_button_private.h
new file mode 100644
index 0000000000..4b59f7c88a
--- /dev/null
+++ b/src/lib/elementary/efl_ui_spin_button_private.h
@@ -0,0 +1,20 @@
+#ifndef EFL_UI_SPIN_BUTTON_PRIVATE_H
+#define EFL_UI_SPIN_BUTTON_PRIVATE_H
+
+typedef struct _Efl_Ui_Spin_Button_Data    Efl_Ui_Spin_Button_Data;
+struct _Efl_Ui_Spin_Button_Data
+{
+   double                interval, first_interval;
+   Evas_Object          *ent, *inc_button, *dec_button, *text_button;
+   Ecore_Timer          *delay_change_timer; /**< a timer for a delay,changed 
smart callback */
+   Ecore_Timer          *spin_timer; /**< a timer for a repeated spinner value 
change on mouse down */
+   Ecore_Timer          *longpress_timer; /**< a timer to detect long press. 
After lonpress timeout,
+                                          start continuous change of values 
until mouse up */
+   Eina_Bool             entry_visible : 1;
+   Eina_Bool             entry_reactivate : 1;
+   Eina_Bool             editable : 1;
+   Eina_Bool             inc_val : 1;
+   Eina_Bool             loop : 1;
+};
+
+#endif
diff --git a/src/lib/elementary/efl_ui_spin_private.h 
b/src/lib/elementary/efl_ui_spin_private.h
new file mode 100644
index 0000000000..a8065dc647
--- /dev/null
+++ b/src/lib/elementary/efl_ui_spin_private.h
@@ -0,0 +1,29 @@
+#ifndef EFL_UI_SPIN_PRIVATE_H
+#define EFL_UI_SPIN_PRIVATE_H
+
+#include "Elementary.h"
+
+typedef enum _Efl_Ui_Spin_Format_Type
+{
+   SPIN_FORMAT_FLOAT,
+   SPIN_FORMAT_INT,
+   SPIN_FORMAT_INVALID
+} Efl_Ui_Spin_Format_Type;
+
+typedef struct _Efl_Ui_Spin_Data    Efl_Ui_Spin_Data;
+struct _Efl_Ui_Spin_Data
+{
+   const char           *templates;
+   double                val, val_min, val_max;
+   double                step; /**< step for the value change. 1 by default. */
+   int                   decimal_points;
+   Ecore_Timer          *spin_timer; /**< a timer for a repeated spin value 
change on mouse down */
+   Efl_Ui_Spin_Format_Type format_type;
+
+   Efl_Ui_Format_Func_Cb format_cb;
+   Eina_Free_Cb          format_free_cb;
+   void                  *format_cb_data;
+   Eina_Strbuf           *format_strbuf;
+};
+
+#endif
diff --git a/src/lib/elementary/elm_flipselector.c 
b/src/lib/elementary/elm_flipselector.c
index 6a80600fb0..ac69bd6ff2 100644
--- a/src/lib/elementary/elm_flipselector.c
+++ b/src/lib/elementary/elm_flipselector.c
@@ -470,7 +470,7 @@ _items_add(Evas_Object *obj)
 }
 
 EOLIAN static void
-_elm_flipselector_efl_ui_spin_min_max_set(Eo *obj, Elm_Flipselector_Data *sd, 
double min, double max)
+_elm_flipselector_efl_ui_range_range_min_max_set(Eo *obj, 
Elm_Flipselector_Data *sd, double min, double max)
 {
    if (min > max) return;
    if ((sd->val_min == min) && (sd->val_max == max)) return;
@@ -482,14 +482,14 @@ _elm_flipselector_efl_ui_spin_min_max_set(Eo *obj, 
Elm_Flipselector_Data *sd, do
 }
 
 EOLIAN static void
-_elm_flipselector_efl_ui_spin_min_max_get(Eo *obj EINA_UNUSED, 
Elm_Flipselector_Data *sd, double *min, double *max)
+_elm_flipselector_efl_ui_range_range_min_max_get(Eo *obj EINA_UNUSED, 
Elm_Flipselector_Data *sd, double *min, double *max)
 {
    if (min) *min = sd->val_min;
    if (max) *max = sd->val_max;
 }
 
 EOLIAN static void
-_elm_flipselector_efl_ui_spin_step_set(Eo *obj EINA_UNUSED, 
Elm_Flipselector_Data *sd, double step)
+_elm_flipselector_efl_ui_range_range_step_set(Eo *obj EINA_UNUSED, 
Elm_Flipselector_Data *sd, double step)
 {
    if (sd->step == step) return;
 
@@ -498,13 +498,13 @@ _elm_flipselector_efl_ui_spin_step_set(Eo *obj 
EINA_UNUSED, Elm_Flipselector_Dat
 }
 
 EOLIAN static double
-_elm_flipselector_efl_ui_spin_step_get(Eo *obj EINA_UNUSED, 
Elm_Flipselector_Data *sd)
+_elm_flipselector_efl_ui_range_range_step_get(Eo *obj EINA_UNUSED, 
Elm_Flipselector_Data *sd)
 {
    return sd->step;
 }
 
 EOLIAN static double
-_elm_flipselector_efl_ui_spin_value_get(Eo *obj EINA_UNUSED, 
Elm_Flipselector_Data *sd)
+_elm_flipselector_efl_ui_range_range_value_get(Eo *obj EINA_UNUSED, 
Elm_Flipselector_Data *sd)
 {
    if (sd->val_min == 0 && sd->val_max == 0)
      {
@@ -516,7 +516,7 @@ _elm_flipselector_efl_ui_spin_value_get(Eo *obj 
EINA_UNUSED, Elm_Flipselector_Da
 }
 
 EOLIAN static void
-_elm_flipselector_efl_ui_spin_value_set(Eo *obj EINA_UNUSED, 
Elm_Flipselector_Data *sd, double val)
+_elm_flipselector_efl_ui_range_range_value_set(Eo *obj EINA_UNUSED, 
Elm_Flipselector_Data *sd, double val)
 {
    Eina_List *l;
    Elm_Object_Item *it;
@@ -657,18 +657,6 @@ elm_flipselector_add(Evas_Object *parent)
    return elm_legacy_add(MY_CLASS, parent);
 }
 
-EAPI void
-elm_flipselector_first_interval_set(Evas_Object *obj, double interval)
-{
-   efl_ui_spin_interval_set(obj, interval);
-}
-
-EAPI double
-elm_flipselector_first_interval_get(const Evas_Object *obj)
-{
-   return efl_ui_spin_interval_get(obj);
-}
-
 EOLIAN static Eo *
 _elm_flipselector_efl_object_constructor(Eo *obj, Elm_Flipselector_Data *sd)
 {
@@ -869,14 +857,14 @@ _elm_flipselector_item_next_get(const Eo *eo_item,
    return NULL;
 }
 
-EOLIAN static void
-_elm_flipselector_efl_ui_spin_interval_set(Eo *obj EINA_UNUSED, 
Elm_Flipselector_Data *sd, double interval)
+EOLIAN void
+_elm_flipselector_first_interval_set(Eo *obj EINA_UNUSED, 
Elm_Flipselector_Data *sd, double interval)
 {
    sd->first_interval = interval;
 }
 
-EOLIAN static double
-_elm_flipselector_efl_ui_spin_interval_get(Eo *obj EINA_UNUSED, 
Elm_Flipselector_Data *sd)
+EOLIAN double
+_elm_flipselector_first_interval_get(Eo *obj EINA_UNUSED, 
Elm_Flipselector_Data *sd)
 {
    return sd->first_interval;
 }
diff --git a/src/lib/elementary/elm_flipselector.eo 
b/src/lib/elementary/elm_flipselector.eo
index 964cc59fd2..4ba48de66e 100644
--- a/src/lib/elementary/elm_flipselector.eo
+++ b/src/lib/elementary/elm_flipselector.eo
@@ -1,4 +1,4 @@
-class Elm.Flipselector (Efl.Ui.Layout, Efl.Ui.Spin,
+class Elm.Flipselector (Efl.Ui.Layout, Efl.Ui.Range,
                         Efl.Access.Widget.Action,
                         Efl.Ui.Selectable)
 {
@@ -60,6 +60,40 @@ class Elm.Flipselector (Efl.Ui.Layout, Efl.Ui.Spin,
 
          }
       }
+      @property first_interval {
+         set {
+            [[Set the interval on time updates for a user mouse button hold
+              on a flip selector widget.
+
+              This interval value is decreased while the user holds the
+              mouse pointer either flipping up or flipping down a given flip
+              selector.
+
+              This helps the user to get to a given item distant from the
+              current one easier/faster, as it will start to flip quicker and
+              quicker on mouse button holds.
+
+              The calculation for the next flip interval value, starting from
+              the one set with this call, is the previous interval divided by
+              1.05, so it decreases a little bit.
+
+              The default starting interval value for automatic flips is
+              0.85 seconds.
+
+              See also @.first_interval.get.
+            ]]
+         }
+         get {
+            [[Get the interval on time updates for an user mouse button hold
+              on a flip selector widget.
+
+              See also @.first_interval.set for more details.
+            ]]
+         }
+         values {
+            interval: double; [[The (first) interval value in seconds.]]
+         }
+      }
       item_prepend {
          [[Prepend a (text) item to a flip selector widget
 
@@ -129,10 +163,9 @@ class Elm.Flipselector (Efl.Ui.Layout, Efl.Ui.Spin,
       Efl.Object.constructor;
       Elm.Widget.theme_apply;
       Elm.Widget.widget_event;
-      Efl.Ui.Spin.min_max { get; set; }
-      Efl.Ui.Spin.step { get; set; }
-      Efl.Ui.Spin.value { get; set; }
-      Efl.Ui.Spin.interval { get; set; }
+      Efl.Ui.Range.range_min_max { get; set; }
+      Efl.Ui.Range.range_step { get; set; }
+      Efl.Ui.Range.range_value { get; set; }
       Efl.Access.Widget.Action.elm_actions { get; }
    }
    events {
diff --git a/src/lib/elementary/elm_flipselector_legacy.h 
b/src/lib/elementary/elm_flipselector_legacy.h
index f928d35a8d..a2fbd58ae0 100644
--- a/src/lib/elementary/elm_flipselector_legacy.h
+++ b/src/lib/elementary/elm_flipselector_legacy.h
@@ -11,42 +11,5 @@
  */
 EAPI Evas_Object                *elm_flipselector_add(Evas_Object *parent);
 
-/**
- * @brief Set the interval on time updates for a user mouse button hold on a
- * flip selector widget.
- *
- * This interval value is decreased while the user holds the mouse pointer
- * either flipping up or flipping down a given flip selector.
- *
- * This helps the user to get to a given item distant from the current one
- * easier/faster, as it will start to flip quicker and quicker on mouse button
- * holds.
- *
- * The calculation for the next flip interval value, starting from the one set
- * with this call, is the previous interval divided by 1.05, so it decreases a
- * little bit.
- *
- * The default starting interval value for automatic flips is 0.85 seconds.
- *
- * See also @ref elm_obj_flipselector_first_interval_get.
- *
- * @param[in] interval The (first) interval value in seconds.
- *
- * @ingroup Elm_Flipselector
- */
-EAPI void elm_flipselector_first_interval_set(Evas_Object *obj, double 
interval);
-
-/**
- * @brief Get the interval on time updates for an user mouse button hold on a
- * flip selector widget.
- *
- * See also @ref elm_obj_flipselector_first_interval_set for more details.
- *
- * @return The (first) interval value in seconds.
- *
- * @ingroup Elm_Flipselector
- */
-EAPI double elm_flipselector_first_interval_get(const Evas_Object *obj);
-
 #include "elm_flipselector_item.eo.legacy.h"
 #include "elm_flipselector.eo.legacy.h"
diff --git a/src/lib/elementary/elm_spinner.c b/src/lib/elementary/elm_spinner.c
index 96fc4eb4f9..b1de7efde1 100644
--- a/src/lib/elementary/elm_spinner.c
+++ b/src/lib/elementary/elm_spinner.c
@@ -1359,49 +1359,37 @@ elm_spinner_add(Evas_Object *parent)
 EAPI void
 elm_spinner_min_max_set(Evas_Object *obj, double min, double max)
 {
-   efl_ui_spin_min_max_set(obj, min, max);
+   efl_ui_range_min_max_set(obj, min, max);
 }
 
 EAPI void
 elm_spinner_min_max_get(const Evas_Object *obj, double *min, double *max)
 {
-   efl_ui_spin_min_max_get(obj, min, max);
+   efl_ui_range_min_max_get(obj, min, max);
 }
 
 EAPI void
 elm_spinner_step_set(Evas_Object *obj, double step)
 {
-   efl_ui_spin_step_set(obj, step);
+   efl_ui_range_step_set(obj, step);
 }
 
 EAPI double
 elm_spinner_step_get(const Evas_Object *obj)
 {
-   return efl_ui_spin_step_get(obj);
-}
-
-EAPI void
-elm_spinner_interval_set(Evas_Object *obj, double interval)
-{
-   efl_ui_spin_interval_set(obj, interval);
-}
-
-EAPI double
-elm_spinner_interval_get(const Evas_Object *obj)
-{
-   return efl_ui_spin_interval_get(obj);
+   return efl_ui_range_step_get(obj);
 }
 
 EAPI void
 elm_spinner_value_set(Evas_Object *obj, double val)
 {
-   efl_ui_spin_value_set(obj, val);
+   efl_ui_range_value_set(obj, val);
 }
 
 EAPI double
 elm_spinner_value_get(const Evas_Object *obj)
 {
-   return efl_ui_spin_value_get(obj);
+   return efl_ui_range_value_get(obj);
 }
 
 EOLIAN static Eo *
@@ -1447,7 +1435,7 @@ _elm_spinner_label_format_get(Eo *obj EINA_UNUSED, 
Elm_Spinner_Data *sd)
 }
 
 EOLIAN static void
-_elm_spinner_efl_ui_spin_min_max_set(Eo *obj, Elm_Spinner_Data *sd, double 
min, double max)
+_elm_spinner_efl_ui_range_range_min_max_set(Eo *obj, Elm_Spinner_Data *sd, 
double min, double max)
 {
    if ((sd->val_min == min) && (sd->val_max == max)) return;
 
@@ -1462,26 +1450,26 @@ _elm_spinner_efl_ui_spin_min_max_set(Eo *obj, 
Elm_Spinner_Data *sd, double min,
 }
 
 EOLIAN static void
-_elm_spinner_efl_ui_spin_min_max_get(Eo *obj EINA_UNUSED, Elm_Spinner_Data 
*sd, double *min, double *max)
+_elm_spinner_efl_ui_range_range_min_max_get(Eo *obj EINA_UNUSED, 
Elm_Spinner_Data *sd, double *min, double *max)
 {
    if (min) *min = sd->val_min;
    if (max) *max = sd->val_max;
 }
 
 EOLIAN static void
-_elm_spinner_efl_ui_spin_step_set(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd, 
double step)
+_elm_spinner_efl_ui_range_range_step_set(Eo *obj EINA_UNUSED, Elm_Spinner_Data 
*sd, double step)
 {
    sd->step = step;
 }
 
 EOLIAN static double
-_elm_spinner_efl_ui_spin_step_get(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd)
+_elm_spinner_efl_ui_range_range_step_get(Eo *obj EINA_UNUSED, Elm_Spinner_Data 
*sd)
 {
    return sd->step;
 }
 
 EOLIAN static void
-_elm_spinner_efl_ui_spin_value_set(Eo *obj, Elm_Spinner_Data *sd, double val)
+_elm_spinner_efl_ui_range_range_value_set(Eo *obj, Elm_Spinner_Data *sd, 
double val)
 {
    if (sd->val == val) return;
 
@@ -1504,7 +1492,7 @@ _elm_spinner_efl_ui_spin_value_set(Eo *obj, 
Elm_Spinner_Data *sd, double val)
 }
 
 EOLIAN static double
-_elm_spinner_efl_ui_spin_value_get(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd)
+_elm_spinner_efl_ui_range_range_value_get(Eo *obj EINA_UNUSED, 
Elm_Spinner_Data *sd)
 {
    return sd->val;
 }
@@ -1601,13 +1589,13 @@ _elm_spinner_editable_get(Eo *obj EINA_UNUSED, 
Elm_Spinner_Data *sd)
 }
 
 EOLIAN static void
-_elm_spinner_efl_ui_spin_interval_set(Eo *obj EINA_UNUSED, Elm_Spinner_Data 
*sd, double interval)
+_elm_spinner_interval_set(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd, double 
interval)
 {
    sd->first_interval = interval;
 }
 
 EOLIAN static double
-_elm_spinner_efl_ui_spin_interval_get(Eo *obj EINA_UNUSED, Elm_Spinner_Data 
*sd)
+_elm_spinner_interval_get(Eo *obj EINA_UNUSED, Elm_Spinner_Data *sd)
 {
    return sd->first_interval;
 }
diff --git a/src/lib/elementary/elm_spinner.eo 
b/src/lib/elementary/elm_spinner.eo
index 880916710e..f1496108ad 100644
--- a/src/lib/elementary/elm_spinner.eo
+++ b/src/lib/elementary/elm_spinner.eo
@@ -1,4 +1,4 @@
-class Elm.Spinner (Efl.Ui.Layout, Efl.Ui.Spin, Efl.Ui.Focus.Composition,
+class Elm.Spinner (Efl.Ui.Layout, Efl.Ui.Range, Efl.Ui.Focus.Composition,
                    Efl.Access.Value, Efl.Access.Widget.Action)
 {
    [[Elementary spinner class]]
@@ -39,6 +39,30 @@ class Elm.Spinner (Efl.Ui.Layout, Efl.Ui.Spin, 
Efl.Ui.Focus.Composition,
             wrap: bool; [[$true to enable wrap or $false to disable it.]]
          }
       }
+      @property interval {
+         [[Control the interval on time updates for an user mouse button hold 
on spinner widgets' arrows.
+
+           This interval value is decreased while the user holds the
+           mouse pointer either incrementing or decrementing spinner's value.
+
+           This helps the user to get to a given value distant from the
+           current one easier/faster, as it will start to change quicker and
+           quicker on mouse button holds.
+
+           The calculation for the next change interval value, starting from
+           the one set with this call, is the previous interval divided by
+           $1.05, so it decreases a little bit.
+
+           The default starting interval value for automatic changes is
+           $0.85 seconds.]]
+         set {
+         }
+         get {
+         }
+         values {
+           interval: double; [[The (first) interval value in seconds.]]
+         }
+      }
       @property round {
          [[Control the round value for rounding
 
@@ -150,10 +174,9 @@ class Elm.Spinner (Efl.Ui.Layout, Efl.Ui.Spin, 
Efl.Ui.Focus.Composition,
       Elm.Widget.on_access_update;
       Elm.Widget.on_focus_update;
       Elm.Widget.widget_event;
-      Efl.Ui.Spin.min_max { get; set; }
-      Efl.Ui.Spin.step { get; set; }
-      Efl.Ui.Spin.value { get; set; }
-      Efl.Ui.Spin.interval { get; set; }
+      Efl.Ui.Range.range_min_max { get; set; }
+      Efl.Ui.Range.range_step { get; set; }
+      Efl.Ui.Range.range_value { get; set; }
       Efl.Access.name { get; }
       Efl.Access.Value.value_and_text { get; set; }
       Efl.Access.Value.range { get; }
diff --git a/src/lib/elementary/elm_spinner_legacy.h 
b/src/lib/elementary/elm_spinner_legacy.h
index a09c19d14a..8c4812b013 100644
--- a/src/lib/elementary/elm_spinner_legacy.h
+++ b/src/lib/elementary/elm_spinner_legacy.h
@@ -119,52 +119,6 @@ EAPI void elm_spinner_step_set(Evas_Object *obj, double 
step);
 EAPI double elm_spinner_step_get(const Evas_Object *obj);
 
 /**
- * @brief Control the interval on time updates for an user mouse button hold on
- * spinner widgets' arrows.
- *
- * This interval value is decreased while the user holds the mouse pointer
- * either incrementing or decrementing spinner's value.
- *
- * This helps the user to get to a given value distant from the current one
- * easier/faster, as it will start to change quicker and quicker on mouse
- * button holds.
- *
- * The calculation for the next change interval value, starting from the one
- * set with this call, is the previous interval divided by $1.05, so it
- * decreases a little bit.
- *
- * The default starting interval value for automatic changes is $0.85 seconds.
- *
- * @param[in] interval The (first) interval value in seconds.
- *
- * @ingroup Elm_Spinner
- */
-EAPI void elm_spinner_interval_set(Evas_Object *obj, double interval);
-
-/**
- * @brief Control the interval on time updates for an user mouse button hold on
- * spinner widgets' arrows.
- *
- * This interval value is decreased while the user holds the mouse pointer
- * either incrementing or decrementing spinner's value.
- *
- * This helps the user to get to a given value distant from the current one
- * easier/faster, as it will start to change quicker and quicker on mouse
- * button holds.
- *
- * The calculation for the next change interval value, starting from the one
- * set with this call, is the previous interval divided by $1.05, so it
- * decreases a little bit.
- *
- * The default starting interval value for automatic changes is $0.85 seconds.
- *
- * @return The (first) interval value in seconds.
- *
- * @ingroup Elm_Spinner
- */
-EAPI double elm_spinner_interval_get(const Evas_Object *obj);
-
-/**
  * @brief Control the value the spinner displays.
  *
  * Value will be presented on the label following format specified with

-- 


Reply via email to