bu5hm4n pushed a commit to branch master.

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

commit ebb685aae1fbf44d9600acc7b5b8be099f4bdea7
Author: WooHyun Jung <wh0705.j...@samsung.com>
Date:   Thu Aug 22 08:16:11 2019 +0000

    efl_ui_slider_interval: cut off the dependency with efl_ui_slider
    
    efl_ui_slider_interval is totally different widget from efl_ui_slider.
    Now, it extends efl_ui_layout_base and implements all efl_ui_slider's
    functionalities by its own.
    This class needs to be marked to @beta till reviewing whole class
    definitions again.
    
    @ref T7893
    
    Reviewed-by: Marcel Hollerbach <m...@marcel-hollerbach.de>
    Differential Revision: https://phab.enlightenment.org/D9696
---
 src/lib/elementary/efl_ui_slider_interval.c        | 825 +++++++++++++++++++--
 src/lib/elementary/efl_ui_slider_interval.eo       |  24 +-
 .../elementary/efl_ui_slider_interval_private.h    |  15 +-
 3 files changed, 781 insertions(+), 83 deletions(-)

diff --git a/src/lib/elementary/efl_ui_slider_interval.c 
b/src/lib/elementary/efl_ui_slider_interval.c
index a61d923464..63611226d3 100644
--- a/src/lib/elementary/efl_ui_slider_interval.c
+++ b/src/lib/elementary/efl_ui_slider_interval.c
@@ -4,6 +4,7 @@
 
 #define EFL_ACCESS_OBJECT_PROTECTED
 #define EFL_ACCESS_WIDGET_ACTION_PROTECTED
+#define EFL_ACCESS_VALUE_PROTECTED
 
 #include <Elementary.h>
 #include "elm_priv.h"
@@ -14,7 +15,15 @@
 #define MY_CLASS_PFX efl_ui_slider_interval
 #define MY_CLASS_NAME "Efl.Ui.Slider_Interval"
 
-#define SLIDER_DELAY_CHANGED_INTERVAL 1.2
+#define SLIDER_DELAY_CHANGED_INTERVAL 0.2
+#define SLIDER_STEP 0.05
+
+static Eina_Bool _key_action_drag(Evas_Object *obj, const char *params);
+
+static const Elm_Action key_actions[] = {
+   {"drag", _key_action_drag},
+   {NULL, NULL}
+};
 
 static Eina_Bool
 _delay_change(void *data)
@@ -30,13 +39,68 @@ _delay_change(void *data)
    return ECORE_CALLBACK_CANCEL;
 }
 
-void
-_efl_ui_slider_interval_val_fetch(Evas_Object *obj, 
Efl_Ui_Slider_Interval_Data *pd, Eina_Bool user_event)
+static inline Eina_Bool
+_is_horizontal(Efl_Ui_Layout_Orientation dir)
+{
+   return efl_ui_layout_orientation_is_horizontal(dir, EINA_TRUE);
+}
+
+static void
+_emit_events(Eo *obj, Efl_Ui_Slider_Interval_Data *sd)
+{
+   efl_event_callback_call(obj, EFL_UI_RANGE_EVENT_CHANGED, NULL);
+   if (sd->val == sd->val_min)
+     efl_event_callback_call(obj, EFL_UI_RANGE_EVENT_MIN_REACHED, NULL);
+   if (sd->val == sd->val_max)
+     efl_event_callback_call(obj, EFL_UI_RANGE_EVENT_MAX_REACHED, NULL);
+}
+
+static void
+_val_set(Evas_Object *obj)
+{
+   double pos, pos2;
+
+   EFL_UI_SLIDER_INTERVAL_DATA_GET(obj, sd);
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+   if (sd->val_max > sd->val_min)
+     {
+        pos = (sd->intvl_from - sd->val_min) / (sd->val_max - sd->val_min);
+        pos2 = (sd->intvl_to - sd->val_min) / (sd->val_max - sd->val_min);
+     }
+   else
+     {
+        pos = 0.0;
+        pos2 = 0.0;
+     }
+
+   if (pos < 0.0) pos = 0.0;
+   else if (pos > 1.0)
+     pos = 1.0;
+
+   if (pos2 < 0.0) pos2 = 0.0;
+   else if (pos2 > 1.0)
+     pos2 = 1.0;
+
+   efl_ui_drag_value_set(efl_part(wd->resize_obj, "efl.dragable.slider"),
+                         pos, pos);
+   efl_ui_drag_value_set(efl_part(wd->resize_obj, "efl.dragable2.slider"),
+                         pos2, pos2);
+
+   // emit accessibility event also if value was changed by API
+   if (_elm_config->atspi_mode)
+     efl_access_value_changed_signal_emit(obj);
+
+   evas_object_smart_changed(obj);
+}
+
+static void
+_val_fetch(Evas_Object *obj, Eina_Bool user_event)
 {
    double posx = 0.0, posy = 0.0, pos = 0.0, val;
    double posx2 = 0.0, posy2 = 0.0, pos2 = 0.0, val2;
 
-   EFL_UI_SLIDER_DATA_GET(obj, sd);
+   EFL_UI_SLIDER_INTERVAL_DATA_GET(obj, sd);
    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
 
    efl_ui_drag_value_get(efl_part(wd->resize_obj, "efl.dragable.slider"),
@@ -52,91 +116,52 @@ _efl_ui_slider_interval_val_fetch(Evas_Object *obj, 
Efl_Ui_Slider_Interval_Data
    val = (pos * (sd->val_max - sd->val_min)) + sd->val_min;
    val2 = (pos2 * (sd->val_max - sd->val_min)) + sd->val_min;
 
-   if (val > pd->intvl_to)
+   if (val > sd->intvl_to)
      {
-        val = pd->intvl_to;
-        efl_ui_slider_val_set(obj);
+        val = sd->intvl_to;
+        _val_set(obj);
      }
-   else if (val2 < pd->intvl_from)
+   else if (val2 < sd->intvl_from)
      {
-        val2 = pd->intvl_from;
-        efl_ui_slider_val_set(obj);
+        val2 = sd->intvl_from;
+        _val_set(obj);
      }
 
-   if (fabs(val - pd->intvl_from) > DBL_EPSILON)
+   if (fabs(val - sd->intvl_from) > DBL_EPSILON)
      {
         sd->val = val;
-        pd->intvl_from = val;
+        sd->intvl_from = val;
         if (user_event)
           {
              efl_event_callback_call(obj, EFL_UI_RANGE_EVENT_CHANGED, NULL);
              efl_event_callback_legacy_call(obj, EFL_UI_RANGE_EVENT_CHANGED, 
NULL);
-             ecore_timer_del(pd->delay);
-             pd->delay = ecore_timer_add(SLIDER_DELAY_CHANGED_INTERVAL, 
_delay_change, obj);
+             ecore_timer_del(sd->delay);
+             sd->delay = ecore_timer_add(SLIDER_DELAY_CHANGED_INTERVAL, 
_delay_change, obj);
           }
      }
 
-   if (fabs(val2 - pd->intvl_to) > DBL_EPSILON)
+   if (fabs(val2 - sd->intvl_to) > DBL_EPSILON)
      {
-        pd->intvl_to = val2;
+        sd->intvl_to = val2;
         if (user_event)
           {
              efl_event_callback_call(obj, EFL_UI_RANGE_EVENT_CHANGED, NULL);
              efl_event_callback_legacy_call(obj, EFL_UI_RANGE_EVENT_CHANGED, 
NULL);
-             ecore_timer_del(pd->delay);
-             pd->delay = ecore_timer_add(SLIDER_DELAY_CHANGED_INTERVAL, 
_delay_change, obj);
+             ecore_timer_del(sd->delay);
+             sd->delay = ecore_timer_add(SLIDER_DELAY_CHANGED_INTERVAL, 
_delay_change, obj);
           }
      }
 }
 
-void
-_efl_ui_slider_interval_val_set(Evas_Object *obj, Efl_Ui_Slider_Interval_Data 
*pd)
+static void
+_down_knob(Evas_Object *obj, double button_x, double button_y)
 {
-   double pos, pos2;
-
-   EFL_UI_SLIDER_DATA_GET(obj, sd);
-   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
-   if (sd->val_max > sd->val_min)
-     {
-        pos = (pd->intvl_from - sd->val_min) / (sd->val_max - sd->val_min);
-        pos2 = (pd->intvl_to - sd->val_min) / (sd->val_max - sd->val_min);
-     }
-   else
-     {
-        pos = 0.0;
-        pos2 = 0.0;
-     }
-
-   if (pos < 0.0) pos = 0.0;
-   else if (pos > 1.0)
-     pos = 1.0;
-
-   if (pos2 < 0.0) pos2 = 0.0;
-   else if (pos2 > 1.0)
-     pos2 = 1.0;
-
-   efl_ui_drag_value_set(efl_part(wd->resize_obj, "efl.dragable.slider"),
-                         pos, pos);
-   efl_ui_drag_value_set(efl_part(wd->resize_obj, "efl.dragable2.slider"),
-                         pos2, pos2);
-
-   // emit accessibility event also if value was changed by API
-   if (_elm_config->atspi_mode)
-     efl_access_value_changed_signal_emit(obj);
-
-   evas_object_smart_changed(obj);
-}
-
-void
-_efl_ui_slider_interval_down_knob(Evas_Object *obj, 
Efl_Ui_Slider_Interval_Data *pd, double button_x, double button_y)
-{
-   EFL_UI_SLIDER_DATA_GET(obj, sd);
+   EFL_UI_SLIDER_INTERVAL_DATA_GET(obj, sd);
    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
 
    double posx = 0.0, posy = 0.0, posx2 = 0.0, posy2 = 0.0, diff1, diff2, 
diff3;
 
-   pd->intvl_flag = 0;
+   sd->intvl_flag = 0;
 
    efl_ui_drag_value_get(efl_part(wd->resize_obj, "efl.dragable.slider"),
                          &posx, &posy);
@@ -160,13 +185,13 @@ _efl_ui_slider_interval_down_knob(Evas_Object *obj, 
Efl_Ui_Slider_Interval_Data
      {
         efl_ui_drag_value_set(efl_part(wd->resize_obj, "efl.dragable.slider"),
                                 button_x, button_y);
-        pd->intvl_flag = 1;
+        sd->intvl_flag = 1;
      }
    else if (diff1 > diff2)
      {
         efl_ui_drag_value_set(efl_part(wd->resize_obj, "efl.dragable2.slider"),
                                 button_x, button_y);
-        pd->intvl_flag = 2;
+        sd->intvl_flag = 2;
      }
    else
      {
@@ -174,28 +199,29 @@ _efl_ui_slider_interval_down_knob(Evas_Object *obj, 
Efl_Ui_Slider_Interval_Data
           {
              efl_ui_drag_value_set(efl_part(wd->resize_obj, 
"efl.dragable.slider"),
                                      button_x, button_y);
-             pd->intvl_flag = 1;
+             sd->intvl_flag = 1;
           }
         else
           {
              efl_ui_drag_value_set(efl_part(wd->resize_obj, 
"efl.dragable2.slider"),
                                      button_x, button_y);
-             pd->intvl_flag = 2;
+             sd->intvl_flag = 2;
           }
      }
 }
 
-void
-_efl_ui_slider_interval_move_knob(Evas_Object *obj, 
Efl_Ui_Slider_Interval_Data *pd, double button_x, double button_y)
+static void
+_move_knob(Evas_Object *obj, double button_x, double button_y)
 {
+   EFL_UI_SLIDER_INTERVAL_DATA_GET(obj, sd);
    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
 
-   if (pd->intvl_flag == 1)
+   if (sd->intvl_flag == 1)
      {
         efl_ui_drag_value_set(efl_part(wd->resize_obj, "efl.dragable.slider"),
                                 button_x, button_y);
      }
-   else if (pd->intvl_flag == 2)
+   else if (sd->intvl_flag == 2)
      {
         efl_ui_drag_value_set(efl_part(wd->resize_obj, "efl.dragable2.slider"),
                                 button_x, button_y);
@@ -205,7 +231,7 @@ _efl_ui_slider_interval_move_knob(Evas_Object *obj, 
Efl_Ui_Slider_Interval_Data
 EOLIAN static void
 _efl_ui_slider_interval_interval_value_set(Eo *obj, 
Efl_Ui_Slider_Interval_Data *pd, double from, double to)
 {
-   EFL_UI_SLIDER_DATA_GET(obj, sd);
+   EFL_UI_SLIDER_INTERVAL_DATA_GET(obj, sd);
    pd->intvl_from = from;
    sd->val = from;
    pd->intvl_to = to;
@@ -216,7 +242,7 @@ _efl_ui_slider_interval_interval_value_set(Eo *obj, 
Efl_Ui_Slider_Interval_Data
    }
    if (pd->intvl_to > sd->val_max) pd->intvl_to = sd->val_max;
 
-   efl_ui_slider_val_set(obj);
+   _val_set(obj);
 }
 
 EOLIAN static void
@@ -226,15 +252,338 @@ _efl_ui_slider_interval_interval_value_get(const Eo *obj 
EINA_UNUSED, Efl_Ui_Sli
    if (to) *to = fmax(pd->intvl_from, pd->intvl_to);
 }
 
+static const char *
+_theme_group_modify_pos_get(const char *cur_group, const char *search, size_t 
len)
+{
+   const char *pos = NULL;
+   const char *temp_str = NULL;
+
+   temp_str = cur_group + len - strlen(search);
+   if (temp_str >= cur_group)
+     {
+        if (!strcmp(temp_str, search))
+          pos = temp_str;
+     }
+
+   return pos;
+}
+
+static char *
+_efl_ui_slider_interval_theme_group_get(Evas_Object *obj, 
Efl_Ui_Slider_Interval_Data *sd)
+{
+   const char *pos = NULL;
+   const char *cur_group = elm_widget_theme_element_get(obj);
+   Eina_Strbuf *new_group = eina_strbuf_new();
+   size_t len = 0;
+
+   if (cur_group)
+     {
+        len = strlen(cur_group);
+        pos = _theme_group_modify_pos_get(cur_group, "horizontal", len);
+        if (!pos)
+          pos = _theme_group_modify_pos_get(cur_group, "vertical", len);
+
+        // TODO: change separator when it is decided.
+        //       can skip when prev_group == cur_group
+        if (!pos)
+          {
+             eina_strbuf_append(new_group, cur_group);
+             eina_strbuf_append(new_group, "/");
+          }
+        else
+          {
+             eina_strbuf_append_length(new_group, cur_group, pos - cur_group);
+          }
+     }
+
+   if (_is_horizontal(sd->dir))
+     eina_strbuf_append(new_group, "horizontal");
+   else
+     eina_strbuf_append(new_group, "vertical");
+
+   return eina_strbuf_release(new_group);
+}
+
+static void
+_slider_update(Evas_Object *obj, Eina_Bool user_event)
+{
+   _val_fetch(obj, user_event);
+   evas_object_smart_changed(obj);
+}
+
+static void
+_drag(void *data,
+      Evas_Object *obj EINA_UNUSED,
+      const char *emission EINA_UNUSED,
+      const char *source EINA_UNUSED)
+{
+   _slider_update(data, EINA_TRUE);
+}
+
+static void
+_drag_start(void *data,
+            Evas_Object *obj EINA_UNUSED,
+            const char *emission EINA_UNUSED,
+            const char *source EINA_UNUSED)
+{
+   if (!efl_ui_focus_object_focus_get(data))
+     elm_object_focus_set(data, EINA_TRUE);
+   _slider_update(data, EINA_TRUE);
+   efl_event_callback_call(data, 
EFL_UI_SLIDER_INTERVAL_EVENT_SLIDER_DRAG_START, NULL);
+   elm_widget_scroll_freeze_push(data);
+}
+
+static void
+_drag_stop(void *data,
+           Evas_Object *obj EINA_UNUSED,
+           const char *emission EINA_UNUSED,
+           const char *source EINA_UNUSED)
+{
+   _slider_update(data, EINA_TRUE);
+   efl_event_callback_call(data, 
EFL_UI_SLIDER_INTERVAL_EVENT_SLIDER_DRAG_STOP, NULL);
+   elm_widget_scroll_freeze_pop(data);
+}
+
+static void
+_drag_step(void *data,
+           Evas_Object *obj EINA_UNUSED,
+           const char *emission EINA_UNUSED,
+           const char *source EINA_UNUSED)
+{
+   _slider_update(data, EINA_TRUE);
+}
+
+static void
+_spacer_down_cb(void *data,
+                Evas *e EINA_UNUSED,
+                Evas_Object *obj EINA_UNUSED,
+                void *event_info)
+{
+   EFL_UI_SLIDER_INTERVAL_DATA_GET(data, sd);
+
+   Evas_Event_Mouse_Down *ev = event_info;
+   Eina_Rect sr;
+   double button_x = 0.0, button_y = 0.0;
+
+   sd->spacer_down = EINA_TRUE;
+   sr = efl_gfx_entity_geometry_get(sd->spacer);
+   sd->downx = ev->canvas.x - sr.x;
+   sd->downy = ev->canvas.y - sr.y;
+   if (_is_horizontal(sd->dir))
+     {
+        button_x = ((double)ev->canvas.x - (double)sr.x) / (double)sr.w;
+        if (button_x > 1) button_x = 1;
+        if (button_x < 0) button_x = 0;
+     }
+   else
+     {
+        button_y = ((double)ev->canvas.y - (double)sr.y) / (double)sr.h;
+        if (button_y > 1) button_y = 1;
+        if (button_y < 0) button_y = 0;
+     }
+
+   _down_knob(data, button_x, button_y);
+
+   if (!efl_ui_focus_object_focus_get(data))
+     elm_object_focus_set(data, EINA_TRUE);
+   _slider_update(data, EINA_TRUE);
+   efl_event_callback_call(data, 
EFL_UI_SLIDER_INTERVAL_EVENT_SLIDER_DRAG_START, NULL);
+}
+
+static void
+_spacer_move_cb(void *data,
+                Evas *e EINA_UNUSED,
+                Evas_Object *obj EINA_UNUSED,
+                void *event_info)
+{
+   EFL_UI_SLIDER_INTERVAL_DATA_GET(data, sd);
+
+   Eina_Rect sr;
+   double button_x = 0.0, button_y = 0.0;
+   Evas_Event_Mouse_Move *ev = event_info;
+
+   if (sd->spacer_down)
+     {
+        Evas_Coord d = 0;
+
+        sr = efl_gfx_entity_geometry_get(sd->spacer);
+        if (_is_horizontal(sd->dir))
+          d = abs(ev->cur.canvas.x - sr.x - sd->downx);
+        else d = abs(ev->cur.canvas.y - sr.y - sd->downy);
+        if (d > (_elm_config->thumbscroll_threshold - 1))
+          {
+             if (!sd->frozen)
+               {
+                  elm_widget_scroll_freeze_push(data);
+                  sd->frozen = EINA_TRUE;
+               }
+             ev->event_flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
+          }
+
+        if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
+          {
+             if (sd->spacer_down) sd->spacer_down = EINA_FALSE;
+             _slider_update(data, EINA_TRUE);
+             efl_event_callback_call
+               (data, EFL_UI_SLIDER_INTERVAL_EVENT_SLIDER_DRAG_STOP, NULL);
+             if (sd->frozen)
+               {
+                  elm_widget_scroll_freeze_pop(data);
+                  sd->frozen = EINA_FALSE;
+               }
+             return;
+          }
+        if (_is_horizontal(sd->dir))
+          {
+             button_x = ((double)ev->cur.canvas.x - (double)sr.x) / 
(double)sr.w;
+             if (button_x > 1) button_x = 1;
+             if (button_x < 0) button_x = 0;
+          }
+        else
+          {
+             button_y = ((double)ev->cur.canvas.y - (double)sr.y) / 
(double)sr.h;
+             if (button_y > 1) button_y = 1;
+             if (button_y < 0) button_y = 0;
+          }
+
+        _move_knob(data, button_x, button_y);
+        _slider_update(data, EINA_TRUE);
+     }
+}
+
+static void
+_spacer_up_cb(void *data,
+              Evas *e EINA_UNUSED,
+              Evas_Object *obj EINA_UNUSED,
+              void *event_info EINA_UNUSED)
+{
+   EFL_UI_SLIDER_INTERVAL_DATA_GET(data, sd);
+
+   if (!sd->spacer_down) return;
+   if (sd->spacer_down) sd->spacer_down = EINA_FALSE;
+
+   _slider_update(data, EINA_TRUE);
+   efl_event_callback_call(data, 
EFL_UI_SLIDER_INTERVAL_EVENT_SLIDER_DRAG_STOP, NULL);
+
+   if (sd->frozen)
+     {
+        elm_widget_scroll_freeze_pop(data);
+        sd->frozen = EINA_FALSE;
+     }
+}
+
+static void
+_mouse_in_cb(void *data EINA_UNUSED,
+              Evas *e EINA_UNUSED,
+              Evas_Object *obj,
+              void *event_info EINA_UNUSED)
+{
+   efl_ui_widget_scroll_hold_push(obj);
+}
+
+static void
+_mouse_out_cb(void *data EINA_UNUSED,
+              Evas *e EINA_UNUSED,
+              Evas_Object *obj,
+              void *event_info EINA_UNUSED)
+{
+   efl_ui_widget_scroll_hold_pop(obj);
+}
+
+static char *
+_access_info_cb(void *data EINA_UNUSED, Evas_Object *obj)
+{
+   const char *txt = elm_widget_access_info_get(obj);
+
+   if (!txt) txt = elm_layout_text_get(obj, NULL);
+   if (txt) return strdup(txt);
+
+   return NULL;
+}
+
+static char *
+_access_state_cb(void *data EINA_UNUSED, Evas_Object *obj)
+{
+   char *ret;
+   Eina_Strbuf *buf = eina_strbuf_new();
+
+   if (elm_widget_disabled_get(obj))
+     eina_strbuf_append(buf, " state: disabled");
+
+   if (eina_strbuf_length_get(buf))
+     {
+        ret = eina_strbuf_string_steal(buf);
+        eina_strbuf_free(buf);
+        return ret;
+     }
+
+   eina_strbuf_free(buf);
+   return NULL;
+}
+
 EOLIAN static Efl_Object *
-_efl_ui_slider_interval_efl_object_constructor(Eo *obj, 
Efl_Ui_Slider_Interval_Data *pd EINA_UNUSED)
+_efl_ui_slider_interval_efl_object_constructor(Eo *obj, 
Efl_Ui_Slider_Interval_Data *priv)
 {
    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
+   char *group;
 
    if (!elm_widget_theme_klass_get(obj))
      elm_widget_theme_klass_set(obj, "slider_interval");
+
    obj = efl_constructor(efl_super(obj, MY_CLASS));
 
+   efl_access_object_role_set(obj, EFL_ACCESS_ROLE_SLIDER);
+
+   if (!elm_widget_theme_klass_get(obj))
+     elm_widget_theme_klass_set(obj, "slider");
+
+   group = _efl_ui_slider_interval_theme_group_get(obj, priv);
+   if (elm_widget_theme_object_set(obj, wd->resize_obj,
+                                       elm_widget_theme_klass_get(obj),
+                                       group,
+                                       elm_widget_theme_style_get(obj)) == 
EFL_UI_THEME_APPLY_ERROR_GENERIC)
+     CRI("Failed to set layout!");
+
+   free(group);
+
+   priv->dir = EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL;
+   priv->val_max = 1.0;
+   priv->step = SLIDER_STEP;
+
+   efl_layout_signal_callback_add(obj, "drag", "*", obj, _drag, NULL);
+   efl_layout_signal_callback_add(obj, "drag,start", "*", obj, _drag_start, 
NULL);
+   efl_layout_signal_callback_add(obj, "drag,stop", "*", obj, _drag_stop, 
NULL);
+   efl_layout_signal_callback_add(obj, "drag,step", "*", obj, _drag_step, 
NULL);
+   efl_layout_signal_callback_add(obj, "drag,page", "*", obj, _drag_stop, 
NULL);
+
+   priv->spacer = efl_add(EFL_CANVAS_RECTANGLE_CLASS, obj,
+                          efl_gfx_color_set(efl_added, 0, 0, 0, 0));
+
+   efl_content_set(efl_part(obj, "efl.bar"), priv->spacer);
+
+   evas_object_event_callback_add
+     (priv->spacer, EVAS_CALLBACK_MOUSE_DOWN, _spacer_down_cb, obj);
+   evas_object_event_callback_add
+     (priv->spacer, EVAS_CALLBACK_MOUSE_MOVE, _spacer_move_cb, obj);
+   evas_object_event_callback_add
+     (priv->spacer, EVAS_CALLBACK_MOUSE_UP, _spacer_up_cb, obj);
+   evas_object_event_callback_add
+     (obj, EVAS_CALLBACK_MOUSE_IN, _mouse_in_cb, obj);
+   evas_object_event_callback_add
+     (obj, EVAS_CALLBACK_MOUSE_OUT, _mouse_out_cb, obj);
+
+   efl_ui_widget_focus_allow_set(obj, EINA_TRUE);
+
+   _elm_access_object_register(obj, wd->resize_obj);
+   _elm_access_text_set
+     (_elm_access_info_get(obj), ELM_ACCESS_TYPE, E_("slider"));
+   _elm_access_callback_set
+     (_elm_access_info_get(obj), ELM_ACCESS_INFO, _access_info_cb, NULL);
+   _elm_access_callback_set
+     (_elm_access_info_get(obj), ELM_ACCESS_STATE, _access_state_cb, NULL);
+
+   evas_object_smart_changed(obj);
+
    return obj;
 }
 
@@ -247,10 +596,332 @@ _efl_ui_slider_interval_efl_object_destructor(Eo *obj,
    efl_destructor(efl_super(obj, MY_CLASS));
 }
 
-#define EFL_UI_SLIDER_INTERVAL_EXTRA_OPS \
-   EFL_UI_SLIDER_VAL_FETCH_OPS(efl_ui_slider_interval), \
-   EFL_UI_SLIDER_VAL_SET_OPS(efl_ui_slider_interval), \
-   EFL_UI_SLIDER_DOWN_KNOB_OPS(efl_ui_slider_interval), \
-   EFL_UI_SLIDER_MOVE_KNOB_OPS(efl_ui_slider_interval), \
+EOLIAN static Eina_Error
+_efl_ui_slider_interval_efl_ui_widget_theme_apply(Eo *obj, 
Efl_Ui_Slider_Interval_Data *sd)
+{
+   Eina_Error int_ret = EFL_UI_THEME_APPLY_ERROR_GENERIC;
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EFL_UI_THEME_APPLY_ERROR_GENERIC);
+   char *group;
+
+   group = _efl_ui_slider_interval_theme_group_get(obj, sd);
+   if (group)
+     {
+        elm_widget_theme_element_set(obj, group);
+        free(group);
+     }
+
+   int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
+   if (int_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return int_ret;
+
+   if (efl_ui_layout_orientation_is_inverted(sd->dir))
+     efl_layout_signal_emit(obj, "efl,state,inverted,on", "efl");
+   else
+     efl_layout_signal_emit(obj, "efl,state,inverted,off", "efl");
+
+   _val_set(obj);
+
+   efl_layout_signal_process(wd->resize_obj, EINA_FALSE);
+   evas_object_smart_changed(obj);
+
+   return int_ret;
+}
+
+static void
+_drag_up(Evas_Object *obj)
+{
+   double step;
+   double relative_step;
+
+   EFL_UI_SLIDER_INTERVAL_DATA_GET(obj, sd);
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+   step = sd->step;
+
+   if (efl_ui_layout_orientation_is_inverted(sd->dir)) step *= -1.0;
+
+   relative_step = step/(sd->val_max - sd->val_min);
+
+   efl_ui_drag_step_move(efl_part(wd->resize_obj, "efl.dragable.slider"),
+                           relative_step, relative_step);
+   _slider_update(obj, EINA_TRUE);
+}
+
+static void
+_drag_down(Evas_Object *obj)
+{
+   double step;
+   double relative_step;
+
+   EFL_UI_SLIDER_INTERVAL_DATA_GET(obj, sd);
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+   step = -sd->step;
+
+   if (efl_ui_layout_orientation_is_inverted(sd->dir)) step *= -1.0;
+
+   relative_step = step/(sd->val_max - sd->val_min);
+
+   efl_ui_drag_step_move(efl_part(wd->resize_obj, "efl.dragable.slider"),
+                           relative_step, relative_step);
+   _slider_update(obj, EINA_TRUE);
+}
+
+static Eina_Bool
+_key_action_drag(Evas_Object *obj, const char *params)
+{
+   EFL_UI_SLIDER_INTERVAL_DATA_GET(obj, sd);
+   const char *dir = params;
+   double old_value, new_value;
+
+   old_value = efl_ui_range_value_get(obj);
+
+   if (!strcmp(dir, "left"))
+     {
+        if (!_is_horizontal(sd->dir))
+          return EINA_FALSE;
+        if (!efl_ui_layout_orientation_is_inverted(sd->dir))
+          _drag_down(obj);
+        else _drag_up(obj);
+     }
+   else if (!strcmp(dir, "right"))
+     {
+        if (!_is_horizontal(sd->dir))
+          return EINA_FALSE;
+        if (!efl_ui_layout_orientation_is_inverted(sd->dir))
+          _drag_up(obj);
+        else _drag_down(obj);
+     }
+   else if (!strcmp(dir, "up"))
+     {
+        if (_is_horizontal(sd->dir))
+          return EINA_FALSE;
+        if (efl_ui_layout_orientation_is_inverted(sd->dir))
+          _drag_up(obj);
+        else _drag_down(obj);
+     }
+   else if (!strcmp(dir, "down"))
+     {
+        if (_is_horizontal(sd->dir))
+          return EINA_FALSE;
+        if (efl_ui_layout_orientation_is_inverted(sd->dir))
+          _drag_down(obj);
+        else _drag_up(obj);
+     }
+   else return EINA_FALSE;
+
+   new_value = efl_ui_range_value_get(obj);
+   return !EINA_DBL_EQ(new_value, old_value);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_slider_interval_efl_ui_widget_on_access_activate(Eo *obj, 
Efl_Ui_Slider_Interval_Data *sd, Efl_Ui_Activate act)
+{
+   if (elm_widget_disabled_get(obj)) return EINA_FALSE;
+   if (act == EFL_UI_ACTIVATE_DEFAULT) return EINA_FALSE;
+
+   if ((act == EFL_UI_ACTIVATE_UP) ||
+       (act == EFL_UI_ACTIVATE_RIGHT))
+     {
+        if (!efl_ui_layout_orientation_is_inverted(sd->dir))
+          _drag_up(obj);
+        else _drag_down(obj);
+     }
+   else if ((act == EFL_UI_ACTIVATE_DOWN) ||
+            (act == EFL_UI_ACTIVATE_LEFT))
+     {
+        if (!efl_ui_layout_orientation_is_inverted(sd->dir))
+          _drag_down(obj);
+        else _drag_up(obj);
+     }
+
+   _slider_update(obj, EINA_TRUE);
+
+   return EINA_TRUE;
+}
+
+// _slider_efl_ui_widget_widget_input_event_handler
+ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(slider, Efl_Ui_Slider_Interval_Data)
+
+EOLIAN static Eina_Bool
+_efl_ui_slider_interval_efl_ui_widget_widget_input_event_handler(Eo *obj, 
Efl_Ui_Slider_Interval_Data *sd, const Efl_Event *eo_event, Evas_Object *src)
+{
+   Eo *ev = eo_event->info;
+
+   if (eo_event->desc == EFL_EVENT_KEY_DOWN)
+     {
+        if (!_slider_efl_ui_widget_widget_input_event_handler(obj, sd, 
eo_event, src))
+          return EINA_FALSE;
+     }
+   else if (eo_event->desc == EFL_EVENT_KEY_UP)
+     {
+        return EINA_FALSE;
+     }
+   else if (eo_event->desc == EFL_EVENT_POINTER_WHEEL)
+     {
+        if (efl_input_processed_get(ev)) return EINA_FALSE;
+        if (efl_input_pointer_wheel_delta_get(ev) < 0)
+          {
+             if (_is_horizontal(sd->dir))
+               _drag_up(obj);
+             else
+               _drag_down(obj);
+          }
+        else
+          {
+             if (_is_horizontal(sd->dir))
+               _drag_down(obj);
+             else
+               _drag_up(obj);
+          }
+        efl_input_processed_set(ev, EINA_TRUE);
+     }
+   else return EINA_FALSE;
+
+   _slider_update(obj, EINA_TRUE);
+
+   return EINA_TRUE;
+}
+
+EOLIAN static void
+_efl_ui_slider_interval_efl_ui_range_display_range_limits_set(Eo *obj, 
Efl_Ui_Slider_Interval_Data *sd, double min, double max)
+{
+   if (max < min)
+     {
+        ERR("Wrong params. min(%lf) is greater than max(%lf).", min, max);
+        return;
+     }
+   if (EINA_DBL_EQ(max, min))
+     {
+        ERR("min and max must have a different value");
+        return;
+     }
+   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;
+
+   _val_set(obj);
+}
+
+EOLIAN static void
+_efl_ui_slider_interval_efl_ui_range_display_range_limits_get(const Eo *obj 
EINA_UNUSED, Efl_Ui_Slider_Interval_Data *sd, double *min, double *max)
+{
+   if (min) *min = sd->val_min;
+   if (max) *max = sd->val_max;
+}
+
+EOLIAN static void
+_efl_ui_slider_interval_efl_ui_range_display_range_value_set(Eo *obj, 
Efl_Ui_Slider_Interval_Data *sd, double val)
+{
+   if (val < sd->val_min)
+     {
+        ERR("Error, value is less than minimum");
+        return;
+     }
+   if (val > sd->val_max)
+     {
+        ERR("Error, value is greater than maximum");
+        return;
+     }
+
+   if (EINA_DBL_EQ(val, sd->val)) return;
+   sd->val = val;
+
+   _emit_events(obj, sd);
+   _val_set(obj);
+}
+
+EOLIAN static double
+_efl_ui_slider_interval_efl_ui_range_display_range_value_get(const Eo *obj 
EINA_UNUSED, Efl_Ui_Slider_Interval_Data *sd)
+{
+   return sd->val;
+}
+
+EOLIAN static double
+_efl_ui_slider_interval_efl_ui_range_interactive_range_step_get(const Eo *obj 
EINA_UNUSED, Efl_Ui_Slider_Interval_Data *sd)
+{
+   return sd->step;
+}
+
+EOLIAN static void
+_efl_ui_slider_interval_efl_ui_range_interactive_range_step_set(Eo *obj 
EINA_UNUSED, Efl_Ui_Slider_Interval_Data *sd, double step)
+{
+   if (step <= 0)
+     {
+        ERR("Wrong param. The step(%lf) should be greater than 0.0", step);
+        return;
+     }
+
+   if (sd->step == step) return;
+
+   sd->step = step;
+}
+
+EOLIAN static void
+_efl_ui_slider_interval_efl_ui_layout_orientable_orientation_set(Eo *obj, 
Efl_Ui_Slider_Interval_Data *sd, Efl_Ui_Layout_Orientation dir)
+{
+   sd->dir = dir;
+
+   efl_ui_widget_theme_apply(obj);
+}
+
+EOLIAN static Efl_Ui_Layout_Orientation
+_efl_ui_slider_interval_efl_ui_layout_orientable_orientation_get(const Eo *obj 
EINA_UNUSED, Efl_Ui_Slider_Interval_Data *sd)
+{
+   return sd->dir;
+}
+
+// A11Y Accessibility
+EOLIAN static void
+_efl_ui_slider_interval_efl_access_value_value_and_text_get(const Eo *obj 
EINA_UNUSED, Efl_Ui_Slider_Interval_Data *sd, double *value, const char **text)
+{
+   if (value) *value = sd->val;
+   if (text) *text = NULL;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_slider_interval_efl_access_value_value_and_text_set(Eo *obj, 
Efl_Ui_Slider_Interval_Data *sd, double value, const char *text EINA_UNUSED)
+{
+   double oldval = sd->val;
+
+   if (value < sd->val_min) value = sd->val_min;
+   if (value > sd->val_max) value = sd->val_max;
+
+   efl_event_callback_call(obj, 
EFL_UI_SLIDER_INTERVAL_EVENT_SLIDER_DRAG_START, NULL);
+   sd->val = value;
+   _val_set(obj);
+   sd->val = oldval;
+   _slider_update(obj, EINA_TRUE);
+   efl_event_callback_call(obj, EFL_UI_SLIDER_INTERVAL_EVENT_SLIDER_DRAG_STOP, 
NULL);
+
+   return EINA_TRUE;
+}
+
+EOLIAN static void
+_efl_ui_slider_interval_efl_access_value_range_get(const Eo *obj EINA_UNUSED, 
Efl_Ui_Slider_Interval_Data *sd, double *lower, double *upper, const char 
**descr)
+{
+   if (lower) *lower = sd->val_min;
+   if (upper) *upper = sd->val_max;
+   if (descr) *descr = NULL;
+}
+
+EOLIAN static double
+_efl_ui_slider_interval_efl_access_value_increment_get(const Eo *obj 
EINA_UNUSED, Efl_Ui_Slider_Interval_Data *sd)
+{
+   return sd->step;
+}
+
+EOLIAN const Efl_Access_Action_Data *
+_efl_ui_slider_interval_efl_access_widget_action_elm_actions_get(const Eo *obj 
EINA_UNUSED, Efl_Ui_Slider_Interval_Data *pd EINA_UNUSED)
+{
+   static Efl_Access_Action_Data atspi_actions[] = {
+          { "drag,left", "drag", "left", _key_action_drag},
+          { "drag,right", "drag", "right", _key_action_drag},
+          { "drag,up", "drag", "up", _key_action_drag},
+          { "drag,down", "drag", "down", _key_action_drag},
+          { NULL, NULL, NULL, NULL}
+   };
+   return &atspi_actions[0];
+}
+// A11Y Accessibility - END
 
 #include "efl_ui_slider_interval.eo.c"
diff --git a/src/lib/elementary/efl_ui_slider_interval.eo 
b/src/lib/elementary/efl_ui_slider_interval.eo
index fcfc1b73bd..d62726f2ee 100644
--- a/src/lib/elementary/efl_ui_slider_interval.eo
+++ b/src/lib/elementary/efl_ui_slider_interval.eo
@@ -1,4 +1,5 @@
-class @beta Efl.Ui.Slider_Interval extends Efl.Ui.Slider
+class @beta Efl.Ui.Slider_Interval extends Efl.Ui.Layout_Base implements 
Efl.Ui.Range_Interactive,
+                              Efl.Ui.Layout_Orientable, Efl.Access.Value, 
Efl.Access.Widget.Action
 {
     [[An interval slider.
 
@@ -19,7 +20,24 @@ class @beta Efl.Ui.Slider_Interval extends Efl.Ui.Slider
         }
     }
     implements {
-         Efl.Object.constructor;
-         Efl.Object.destructor;
+       Efl.Object.constructor;
+       Efl.Object.destructor;
+       Efl.Ui.Widget.theme_apply;
+       Efl.Ui.Widget.on_access_activate;
+       Efl.Ui.Widget.widget_input_event_handler;
+       Efl.Ui.Range_Display.range_value { get; set; }
+       Efl.Ui.Range_Display.range_limits {get; set; }
+       Efl.Ui.Range_Interactive.range_step { get; set; }
+       Efl.Ui.Layout_Orientable.orientation { get; set; }
+       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 {
+      slider,drag,start: void; [[Called when a slider drag operation has 
started. This means a $press event
+                                 has been received on the slider thumb but not 
the $unpress.]]
+      slider,drag,stop: void; [[Called when a slider drag operation has 
finished. This means an $unpress event
+                                has been received on the slider thumb.]]
+   }
 }
diff --git a/src/lib/elementary/efl_ui_slider_interval_private.h 
b/src/lib/elementary/efl_ui_slider_interval_private.h
index 66b23e2d6f..dd33c80ae1 100644
--- a/src/lib/elementary/efl_ui_slider_interval_private.h
+++ b/src/lib/elementary/efl_ui_slider_interval_private.h
@@ -5,9 +5,18 @@
 typedef struct _Efl_Ui_Slider_Interval_Data Efl_Ui_Slider_Interval_Data;
 struct _Efl_Ui_Slider_Interval_Data
 {
-   Ecore_Timer          *delay;
-   double                intvl_from, intvl_to;
-   int                   intvl_flag;
+   Evas_Object                *spacer;
+   Ecore_Timer                *delay;
+
+   double                     intvl_from, intvl_to;
+   double                     val, val_min, val_max, step;
+
+   int                        intvl_flag;
+   Evas_Coord                 downx, downy;
+   Efl_Ui_Layout_Orientation  dir;
+
+   Eina_Bool                  spacer_down : 1;
+   Eina_Bool                  frozen : 1;
 };
 
 /**

-- 


Reply via email to