ami pushed a commit to branch master.

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

commit 92296545710fbea3eab112978eb4823addc5f227
Author: Amitesh Singh <amitesh...@samsung.com>
Date:   Mon Mar 28 14:05:51 2016 +0530

    slider: Add range support
    
    Slider can have two indicators if enabled and user can select
    range values.
    
    phab: https://phab.enlightenment.org/D3822
    Test Plan: elementary_test -to slider
    
    @feature
    
    Change-Id: If4ca74de6f5a94531ebd21750d52704b2b02afee
---
 src/bin/elementary/test_slider.c       | 220 ++++++++++++++++++++-
 src/lib/elementary/elm_slider.c        | 345 +++++++++++++++++++++++++++++----
 src/lib/elementary/elm_slider.eo       |  23 +++
 src/lib/elementary/elm_widget_slider.h |   5 +-
 4 files changed, 554 insertions(+), 39 deletions(-)

diff --git a/src/bin/elementary/test_slider.c b/src/bin/elementary/test_slider.c
index c613da6..9956a9b 100644
--- a/src/bin/elementary/test_slider.c
+++ b/src/bin/elementary/test_slider.c
@@ -58,10 +58,20 @@ _step_size_calculate(double min, double max)
    return step;
 }
 
+static void
+_change_range_print_cb(void *data EINA_UNUSED, Evas_Object *obj, void 
*event_info EINA_UNUSED)
+{
+   double from, to;
+
+   elm_slider_range_get(obj, &from, &to);
+
+   printf("range values:- from: %f, to: %f\n", from, to);
+}
+
 void
 test_slider(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void 
*event_info EINA_UNUSED)
 {
-   Evas_Object *win, *fr, *bx, *sl, *ic, *sl1, *bx2, *bt;
+   Evas_Object *win, *fr, *bx, *sl, *ic, *sl1, *bx2, *bx3, *bx4, *bt;
    double step;
    char buf[PATH_MAX];
 
@@ -264,7 +274,6 @@ test_slider(void *data EINA_UNUSED, Evas_Object *obj 
EINA_UNUSED, void *event_in
    elm_slider_span_size_set(sl, 60);
    evas_object_size_hint_align_set(sl, 0.5, EVAS_HINT_FILL);
    evas_object_size_hint_weight_set(sl, 0.0, EVAS_HINT_EXPAND);
-   elm_slider_indicator_show_set(sl, EINA_FALSE);
    elm_slider_value_set(sl, 0.2);
    elm_object_scale_set(sl, 1.0);
    elm_slider_horizontal_set(sl, EINA_FALSE);
@@ -303,5 +312,212 @@ test_slider(void *data EINA_UNUSED, Evas_Object *obj 
EINA_UNUSED, void *event_in
    evas_object_show(bt);
    elm_box_pack_end(bx2, bt);
 
+   fr = elm_frame_add(bx);
+   elm_object_text_set(fr, "Range");
+   evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(bx, fr);
+   evas_object_show(fr);
+
+   bx3 = elm_box_add(fr);
+   evas_object_size_hint_weight_set(bx3, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bx3);
+   elm_object_content_set(fr, bx3);
+
+   //Disabled
+   sl = elm_slider_add(bx3);
+   elm_object_text_set(sl, "Disabled");
+   elm_slider_unit_format_set(sl, "%1.1f units");
+   elm_slider_span_size_set(sl, 120);
+   elm_slider_min_max_set(sl, 50, 150);
+   evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.0);
+   elm_object_disabled_set(sl, EINA_TRUE);
+   elm_slider_range_enabled_set(sl, EINA_TRUE);
+   elm_slider_range_set(sl, 20, 100);
+   elm_box_pack_end(bx3, sl);
+   evas_object_show(sl);
+
+   // horizontal slider with range
+   sl = elm_slider_add(bx3);
+   evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_slider_indicator_show_set(sl, EINA_TRUE);
+   elm_object_text_set(sl, "Horizontal");
+   elm_slider_unit_format_set(sl, "%1.5f units");
+   elm_slider_indicator_format_set(sl, "%1.5f");
+   elm_slider_span_size_set(sl, 160);
+   elm_slider_range_enabled_set(sl, EINA_TRUE);
+   elm_slider_range_set(sl, 0.4, 0.9);
+   elm_box_pack_end(bx3, sl);
+   evas_object_show(sl);
+
+   sl = elm_slider_add(bx3);
+   elm_slider_unit_format_set(sl, "%1.0f units");
+   elm_slider_indicator_format_set(sl, "%1.0f");
+   elm_slider_span_size_set(sl, 120);
+   elm_slider_min_max_set(sl, 0, 9);
+   elm_object_text_set(sl, "Manual step");
+   step = _step_size_calculate(0, 9);
+   elm_slider_step_set(sl, step);
+   evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.0);
+   elm_slider_range_enabled_set(sl, EINA_TRUE);
+   elm_box_pack_end(bx3, sl);
+   evas_object_show(sl);
+
+   sl = elm_slider_add(bx3);
+   elm_slider_unit_format_set(sl, "%1.0f units");
+   elm_slider_indicator_format_set(sl, "%1.0f");
+   elm_slider_span_size_set(sl, 120);
+   elm_slider_min_max_set(sl, 0, 100);
+   elm_object_text_set(sl, "Show Indicator on Focus: ");
+   step = _step_size_calculate(0, 9);
+   elm_slider_step_set(sl, step);
+   elm_slider_indicator_show_on_focus_set(sl, EINA_TRUE);
+   evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.0);
+   elm_slider_range_enabled_set(sl, EINA_TRUE);
+   elm_box_pack_end(bx3, sl);
+   evas_object_show(sl);
+
+   // normal horizontal slider
+   ic = elm_icon_add(bx3);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", 
elm_app_data_dir_get());
+   elm_image_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+
+   sl = elm_slider_add(bx3);
+   elm_object_text_set(sl, "Horizontal");
+   elm_object_part_content_set(sl, "icon", ic);
+   elm_slider_unit_format_set(sl, "%1.1f units");
+   elm_slider_indicator_format_set(sl, "%1.1f");
+   elm_slider_span_size_set(sl, 120);
+   evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.0);
+   elm_slider_range_enabled_set(sl, EINA_TRUE);
+   elm_box_pack_end(bx3, sl);
+   evas_object_show(sl);
+
+   ic = elm_icon_add(bx3);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", 
elm_app_data_dir_get());
+   elm_image_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+
+   sl = elm_slider_add(bx3);
+   elm_object_text_set(sl, "Horizontal inverted");
+   elm_object_part_content_set(sl, "end", ic);
+   elm_slider_unit_format_set(sl, "%3.0f units");
+   elm_slider_span_size_set(sl, 80);
+   elm_slider_indicator_format_set(sl, "%3.0f");
+   elm_slider_min_max_set(sl, 50, 150);
+   elm_slider_inverted_set(sl, EINA_TRUE);
+   evas_object_size_hint_align_set(sl, 0.5, 0.5);
+   evas_object_size_hint_weight_set(sl, 0.0, 0.0);
+   elm_slider_range_enabled_set(sl, EINA_TRUE);
+   elm_box_pack_end(bx3, sl);
+   evas_object_show(sl);
+
+   ic = elm_icon_add(bx3);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", 
elm_app_data_dir_get());
+   elm_image_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+
+   sl = elm_slider_add(bx3);
+   elm_object_text_set(sl, "Disabled inverted");
+   elm_object_part_content_set(sl, "end", ic);
+   elm_slider_span_size_set(sl, 80);
+   elm_slider_indicator_format_set(sl, "%3.0f");
+   elm_slider_min_max_set(sl, 50, 150);
+   elm_slider_inverted_set(sl, EINA_TRUE);
+   elm_object_disabled_set(sl, EINA_TRUE);
+   evas_object_size_hint_align_set(sl, 0.5, 0.5);
+   evas_object_size_hint_weight_set(sl, 0.0, 0.0);
+   elm_slider_range_enabled_set(sl, EINA_TRUE);
+   elm_slider_inverted_set(sl, EINA_TRUE);
+   elm_box_pack_end(bx3, sl);
+   evas_object_show(sl);
+
+   sl = elm_slider_add(bx3);
+   elm_slider_indicator_show_set(sl, EINA_FALSE);
+   elm_object_text_set(sl, "Scale doubled");
+   elm_slider_unit_format_set(sl, "%3.0f units");
+   elm_slider_span_size_set(sl, 40);
+   evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
+   evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.0);
+   elm_slider_indicator_format_set(sl, "%3.0f");
+   elm_slider_min_max_set(sl, 50, 150);
+   elm_object_scale_set(sl, 2.0);
+   elm_slider_range_enabled_set(sl, EINA_TRUE);
+   elm_slider_range_set(sl, 100, 145);
+   elm_box_pack_end(bx3, sl);
+   evas_object_show(sl);
+
+   //Vertical
+   bx4 = elm_box_add(bx);
+   evas_object_size_hint_weight_set(bx4, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(bx4, 0.5, EVAS_HINT_FILL);
+   elm_box_horizontal_set(bx4, EINA_TRUE);
+   elm_box_pack_end(bx3, bx4);
+   evas_object_show(bx4);
+
+   sl = elm_slider_add(bx4);
+   elm_slider_range_enabled_set(sl, EINA_TRUE);
+   elm_slider_range_set(sl, 0.2, 0.9);
+   elm_slider_horizontal_set(sl, EINA_FALSE);
+   elm_object_text_set(sl, "Vertical");
+   elm_slider_unit_format_set(sl, "%1.1f units");
+   elm_slider_span_size_set(sl, 60);
+   evas_object_size_hint_align_set(sl, 0.5, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(sl, 0.0, EVAS_HINT_EXPAND);
+   elm_slider_indicator_format_set(sl, "%1.1f");
+   elm_object_scale_set(sl, 1.0);
+   evas_object_smart_callback_add(sl, "changed", _change_range_print_cb, sl);
+   elm_box_pack_end(bx4, sl);
+   evas_object_show(sl);
+
+   ic = elm_icon_add(bx4);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", 
elm_app_data_dir_get());
+   elm_image_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_HORIZONTAL, 1, 1);
+   evas_object_show(ic);
+
+   sl = elm_slider_add(bx4);
+   elm_slider_unit_format_set(sl, "%1.1f units");
+   elm_object_text_set(sl, "Vertical inverted");
+   elm_slider_inverted_set(sl, EINA_TRUE);
+   elm_slider_span_size_set(sl, 60);
+   evas_object_size_hint_align_set(sl, 0.5, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(sl, 0.0, EVAS_HINT_EXPAND);
+   elm_slider_indicator_format_set(sl, "%1.1f");
+   elm_object_scale_set(sl, 1.0);
+   elm_slider_horizontal_set(sl, EINA_FALSE);
+   elm_slider_range_enabled_set(sl, EINA_TRUE);
+   elm_box_pack_end(bx4, sl);
+   evas_object_show(sl);
+   elm_slider_min_max_set(sl, 50, 150);
+   elm_slider_range_set(sl, 100, 130);
+
+   ic = elm_icon_add(bx4);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", 
elm_app_data_dir_get());
+   elm_image_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_HORIZONTAL, 1, 1);
+   evas_object_show(ic);
+
+   sl = elm_slider_add(bx4);
+   elm_object_part_content_set(sl, "icon", ic);
+   elm_object_text_set(sl, "Disabled vertical");
+   elm_slider_inverted_set(sl, EINA_TRUE);
+   elm_slider_unit_format_set(sl, "%1.1f units");
+   elm_slider_span_size_set(sl, 100);
+   evas_object_size_hint_align_set(sl, 0.5, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(sl, 0.0, EVAS_HINT_EXPAND);
+   elm_slider_indicator_format_set(sl, "%1.1f");
+   elm_object_scale_set(sl, 1.0);
+   elm_slider_horizontal_set(sl, EINA_FALSE);
+   elm_object_disabled_set(sl, EINA_TRUE);
+   elm_slider_range_enabled_set(sl, EINA_TRUE);
+   elm_slider_range_set(sl, 0.2, 0.9);
+   elm_box_pack_end(bx4, sl);
+   evas_object_show(sl);
+
    evas_object_show(win);
 }
diff --git a/src/lib/elementary/elm_slider.c b/src/lib/elementary/elm_slider.c
index 37ea643..f32ddbe 100644
--- a/src/lib/elementary/elm_slider.c
+++ b/src/lib/elementary/elm_slider.c
@@ -76,6 +76,7 @@ _val_fetch(Evas_Object *obj, Eina_Bool user_event)
 {
    Eina_Bool rtl;
    double posx = 0.0, posy = 0.0, pos = 0.0, val;
+   double posx2 = 0.0, posy2 = 0.0, pos2 = 0.0, val2;
 
    ELM_SLIDER_DATA_GET(obj, sd);
    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
@@ -85,16 +86,37 @@ _val_fetch(Evas_Object *obj, Eina_Bool user_event)
    if (sd->horizontal) pos = posx;
    else pos = posy;
 
+   edje_object_part_drag_value_get
+     (wd->resize_obj, "elm.dragable2.slider", &posx2, &posy2);
+   if (sd->horizontal) pos2 = posx2;
+   else pos2 = posy2;
+
    rtl = elm_widget_mirrored_get(obj);
    if ((!rtl && sd->inverted) ||
        (rtl && ((!sd->horizontal && sd->inverted) ||
                 (sd->horizontal && !sd->inverted))))
-     pos = 1.0 - pos;
+     {
+        pos = 1.0 - pos;
+        pos2 = 1.0 - pos2;
+     }
 
    val = (pos * (sd->val_max - sd->val_min)) + sd->val_min;
+   val2 = (pos2 * (sd->val_max - sd->val_min)) + sd->val_min;
+
    if (fabs(val - sd->val) > DBL_EPSILON)
      {
         sd->val = val;
+        sd->range_from = val;
+        if (user_event)
+          {
+             eo_event_callback_call(obj, ELM_SLIDER_EVENT_CHANGED, NULL);
+             ecore_timer_del(sd->delay);
+             sd->delay = ecore_timer_add(SLIDER_DELAY_CHANGED_INTERVAL, 
_delay_change, obj);
+          }
+     }
+   if (fabs(val2 - sd->range_to) > DBL_EPSILON)
+     {
+        sd->range_to = val2;
         if (user_event)
           {
              eo_event_callback_call(obj, ELM_SLIDER_EVENT_CHANGED, NULL);
@@ -108,28 +130,45 @@ static void
 _val_set(Evas_Object *obj)
 {
    Eina_Bool rtl;
-   double pos;
+   double pos, pos2;
 
    ELM_SLIDER_DATA_GET(obj, sd);
 
    if (sd->val_max > sd->val_min)
-     pos = (sd->val - sd->val_min) / (sd->val_max - sd->val_min);
-   else pos = 0.0;
+     {
+        pos = (sd->val - sd->val_min) / (sd->val_max - sd->val_min);
+        pos2 = (sd->range_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;
 
    rtl = elm_widget_mirrored_get(obj);
    if ((!rtl && sd->inverted) ||
        (rtl && ((!sd->horizontal && sd->inverted) ||
                 (sd->horizontal && !sd->inverted))))
-     pos = 1.0 - pos;
+     {
+        pos = 1.0 - pos;
+        pos2 = 1.0 - pos2;
+     }
 
    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
    edje_object_part_drag_value_set
      (wd->resize_obj, "elm.dragable.slider", pos, pos);
 
+   if (sd->range_enable)
+     edje_object_part_drag_value_set
+        (wd->resize_obj, "elm.dragable2.slider", pos2, pos2);
+
    // emit accessiblity event also if value was chagend by API
    if (_elm_config->atspi_mode)
      elm_interface_atspi_accessible_value_changed_signal_emit(obj);
@@ -169,7 +208,16 @@ _units_set(Evas_Object *obj)
      {
         char buf[1024];
 
-        snprintf(buf, sizeof(buf), sd->units, sd->val);
+        if (!sd->range_enable)
+          snprintf(buf, sizeof(buf), sd->units, sd->val);
+        else
+          {
+             double v1, v2;
+
+             elm_slider_range_get(obj, &v1, &v2);
+             snprintf(buf, sizeof(buf), sd->units, v2 - v1);
+          }
+
         elm_layout_text_set(obj, "elm.units", buf);
         if (!sd->units_show)
           {
@@ -202,6 +250,13 @@ _indicator_set(Evas_Object *obj)
         elm_layout_text_set(obj, "elm.dragable.slider:elm.indicator", buf);
         if (sd->popup)
           edje_object_part_text_set(sd->popup, "elm.indicator", buf);
+        if (sd->popup2)
+          {
+             if (sd->indicator_format_free) sd->indicator_format_free(buf);
+             buf = sd->indicator_format_func(sd->range_to);
+             elm_layout_text_set(obj, "elm.dragable2.slider:elm.indicator", 
buf);
+             edje_object_part_text_set(sd->popup2, "elm.indicator", buf);
+          }
 
         if (sd->indicator_format_free) sd->indicator_format_free(buf);
      }
@@ -214,6 +269,13 @@ _indicator_set(Evas_Object *obj)
         elm_layout_text_set(obj, "elm.dragable.slider:elm.indicator", buf);
         if (sd->popup)
           edje_object_part_text_set(sd->popup, "elm.indicator", buf);
+        if (sd->popup2)
+          {
+             memset(buf, 0, 1024);
+             snprintf(buf, sizeof(buf), sd->indicator, sd->range_to);
+             elm_layout_text_set(obj, "elm.dragable2.slider:elm.indicator", 
buf);
+             edje_object_part_text_set(sd->popup2, "elm.indicator", buf);
+          }
      }
    else
      {
@@ -221,6 +283,11 @@ _indicator_set(Evas_Object *obj)
         elm_layout_text_set(obj, "elm.dragable.slider:elm.indicator", NULL);
         if (sd->popup)
           edje_object_part_text_set(sd->popup, "elm.indicator", NULL);
+        if (sd->popup2)
+          {
+             elm_layout_text_set(obj, "elm.dragable2.slider:elm.indicator", 
NULL);
+             edje_object_part_text_set(sd->popup2, "elm.indicator", NULL);
+          }
      }
 }
 
@@ -325,6 +392,14 @@ _popup_show(void *data,
         edje_object_signal_emit(sd->popup, "popup,show", "elm"); // XXX: for 
compat
         edje_object_signal_emit(sd->popup, "elm,popup,show", "elm");
      }
+   if (sd->popup2 &&
+       (sd->indicator_visible_mode != ELM_SLIDER_INDICATOR_VISIBLE_MODE_NONE))
+     {
+        evas_object_raise(sd->popup2);
+        evas_object_show(sd->popup2);
+        edje_object_signal_emit(sd->popup2, "popup,show", "elm"); // XXX: for 
compat
+        edje_object_signal_emit(sd->popup2, "elm,popup,show", "elm");
+     }
    ELM_SAFE_FREE(sd->wheel_indicator_timer, ecore_timer_del);
 }
 
@@ -345,6 +420,12 @@ _popup_hide(void *data,
 
    edje_object_signal_emit(sd->popup, "popup,hide", "elm"); // XXX: for compat
    edje_object_signal_emit(sd->popup, "elm,popup,hide", "elm");
+
+   if (sd->popup2)
+     {
+        edje_object_signal_emit(sd->popup2, "popup,hide", "elm"); // XXX: for 
compat
+        edje_object_signal_emit(sd->popup2, "elm,popup,hide", "elm");
+     }
 }
 
 static void
@@ -363,6 +444,14 @@ _popup_hide_done(void *data,
              sd->popup_visible = EINA_FALSE;
           }
      }
+   if (sd->popup2)
+     {
+        if (!((elm_widget_focus_get(data)) &&
+              (sd->indicator_visible_mode == 
ELM_SLIDER_INDICATOR_VISIBLE_MODE_ON_FOCUS)))
+          {
+             evas_object_hide(sd->popup2);
+          }
+     }
 }
 
 static void
@@ -376,6 +465,10 @@ _popup_emit(void *data,
      {
         edje_object_signal_emit(sd->popup, emission, source);
      }
+   if (sd->popup2)
+     {
+        edje_object_signal_emit(sd->popup2, emission, source);
+     }
 }
 
 static Eina_Bool
@@ -510,6 +603,19 @@ _track_move_cb(void *data,
 }
 
 static void
+_track2_move_cb(void *data,
+               Evas *e EINA_UNUSED,
+               Evas_Object *obj,
+               void *event_info EINA_UNUSED)
+{
+   Evas_Coord x, y;
+
+   ELM_SLIDER_DATA_GET(data, sd);
+   evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+   evas_object_move(sd->popup2, x, y);
+}
+
+static void
 _track_resize_cb(void *data,
                  Evas *e EINA_UNUSED,
                  Evas_Object *obj,
@@ -523,35 +629,64 @@ _track_resize_cb(void *data,
 }
 
 static void
-_popup_add(Elm_Slider_Data *sd, Eo *obj)
+_track2_resize_cb(void *data,
+                 Evas *e EINA_UNUSED,
+                 Evas_Object *obj,
+                 void *event_info EINA_UNUSED)
+{
+   Evas_Coord w, h;
+
+   ELM_SLIDER_DATA_GET(data, sd);
+   evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+   evas_object_resize(sd->popup2, w, h);
+}
+
+static void
+_popup_add(Elm_Slider_Data *sd, Eo *obj, Evas_Object **popup,
+           Evas_Object **track, Eina_Bool is_range)
 {
    /* if theme has an overlayed slider mode, then lets support it */
-   if (!edje_object_part_exists(elm_layout_edje_get(obj), "elm.track.slider")) 
return;
+   if (!is_range
+       && !edje_object_part_exists(elm_layout_edje_get(obj), 
"elm.track.slider"))
+     return;
+   else if (is_range
+            && !edje_object_part_exists(elm_layout_edje_get(obj), 
"elm.track2.slider"))
+     return;
 
    // XXX popup needs to adapt to theme etc.
-   sd->popup = edje_object_add(evas_object_evas_get(obj));
-   evas_object_smart_member_add(sd->popup, obj);
+   *popup = edje_object_add(evas_object_evas_get(obj));
+   evas_object_smart_member_add(*popup, obj);
    if (sd->horizontal)
-     _elm_theme_set(elm_widget_theme_get(obj), sd->popup, "slider", 
"horizontal/popup", elm_widget_style_get(obj));
+     _elm_theme_set(elm_widget_theme_get(obj), *popup, "slider", 
"horizontal/popup", elm_widget_style_get(obj));
    else
-     _elm_theme_set(elm_widget_theme_get(obj), sd->popup, "slider", 
"vertical/popup", elm_widget_style_get(obj));
-   edje_object_scale_set(sd->popup, elm_widget_scale_get(obj) *
+     _elm_theme_set(elm_widget_theme_get(obj), *popup, "slider", 
"vertical/popup", elm_widget_style_get(obj));
+   edje_object_scale_set(*popup, elm_widget_scale_get(obj) *
                          elm_config_scale_get());
-   edje_object_signal_callback_add(sd->popup, "popup,hide,done", "elm", // 
XXX: for compat
+   edje_object_signal_callback_add(*popup, "popup,hide,done", "elm", // XXX: 
for compat
                                    _popup_hide_done, obj);
-   edje_object_signal_callback_add(sd->popup, "elm,popup,hide,done", "elm",
+   edje_object_signal_callback_add(*popup, "elm,popup,hide,done", "elm",
                                    _popup_hide_done, obj);
 
    /* create a rectangle to track position+size of the dragable */
-   sd->track = evas_object_rectangle_add(evas_object_evas_get(obj));
-   evas_object_event_callback_add
-     (sd->track, EVAS_CALLBACK_MOVE, _track_move_cb, obj);
-   evas_object_event_callback_add
-     (sd->track, EVAS_CALLBACK_RESIZE, _track_resize_cb, obj);
-
-   evas_object_color_set(sd->track, 0, 0, 0, 0);
-   evas_object_pass_events_set(sd->track, EINA_TRUE);
-   elm_layout_content_set(obj, "elm.track.slider", sd->track);
+   *track = evas_object_rectangle_add(evas_object_evas_get(obj));
+   evas_object_color_set(*track, 0, 0, 0, 0);
+   evas_object_pass_events_set(*track, EINA_TRUE);
+   if (!is_range)
+     {
+        evas_object_event_callback_add
+           (*track, EVAS_CALLBACK_MOVE, _track_move_cb, obj);
+        evas_object_event_callback_add
+           (*track, EVAS_CALLBACK_RESIZE, _track_resize_cb, obj);
+        elm_layout_content_set(obj, "elm.track.slider", *track);
+     }
+   else
+     {
+        evas_object_event_callback_add
+           (*track, EVAS_CALLBACK_MOVE, _track2_move_cb, obj);
+        evas_object_event_callback_add
+           (*track, EVAS_CALLBACK_RESIZE, _track2_resize_cb, obj);
+        elm_layout_content_set(obj, "elm.track2.slider", *track);
+     }
 }
 
 EOLIAN static Eina_Bool
@@ -568,6 +703,10 @@ _elm_slider_elm_widget_theme_apply(Eo *obj, 
Elm_Slider_Data *sd)
           _elm_theme_set(elm_widget_theme_get(obj), sd->popup,
                          "slider", "horizontal/popup",
                          elm_widget_style_get(obj));
+        if (sd->popup2)
+          _elm_theme_set(elm_widget_theme_get(obj), sd->popup2,
+                         "slider", "horizontal/popup",
+                         elm_widget_style_get(obj));
      }
    else
      {
@@ -576,16 +715,31 @@ _elm_slider_elm_widget_theme_apply(Eo *obj, 
Elm_Slider_Data *sd)
           _elm_theme_set(elm_widget_theme_get(obj), sd->popup,
                          "slider", "vertical/popup",
                          elm_widget_style_get(obj));
+        if (sd->popup2)
+          _elm_theme_set(elm_widget_theme_get(obj), sd->popup2,
+                         "slider", "vertical/popup",
+                         elm_widget_style_get(obj));
      }
 
    int_ret = elm_obj_widget_theme_apply(eo_super(obj, MY_CLASS));
    if (!int_ret) return EINA_FALSE;
 
    if (sd->popup)
-     edje_object_scale_set(sd->popup, elm_widget_scale_get(obj) *
-                           elm_config_scale_get());
+     {
+        edje_object_scale_set(sd->popup, elm_widget_scale_get(obj) *
+                              elm_config_scale_get());
+        if (sd->range_enable && sd->popup2)
+          edje_object_scale_set(sd->popup2, elm_widget_scale_get(obj) *
+                                elm_config_scale_get());
+        else if (sd->range_enable && !sd->popup2)
+          _popup_add(sd, obj, &sd->popup2, &sd->track2, EINA_TRUE);
+     }
    else
-     _popup_add(sd, obj);
+     {
+        _popup_add(sd, obj, &sd->popup, &sd->track, EINA_FALSE);
+        if (sd->range_enable && !sd->popup2)
+          _popup_add(sd, obj, &sd->popup2, &sd->track2, EINA_TRUE);
+     }
 
    if (sd->horizontal)
      evas_object_size_hint_min_set
@@ -596,18 +750,28 @@ _elm_slider_elm_widget_theme_apply(Eo *obj, 
Elm_Slider_Data *sd)
        (sd->spacer, 1, (double)sd->size * elm_widget_scale_get(obj) *
        elm_config_scale_get());
 
+   if (sd->range_enable)
+     elm_layout_signal_emit(obj, "elm,slider,range,enable", "elm");
+   else
+     elm_layout_signal_emit(obj, "elm,slider,range,disable", "elm");
+
    if (sd->inverted)
      {
         elm_layout_signal_emit(obj, "elm,state,inverted,on", "elm");
         if (sd->popup)
           edje_object_signal_emit(sd->popup, "elm,state,inverted,on", "elm");
+        if (sd->popup2)
+          edje_object_signal_emit(sd->popup2, "elm,state,inverted,on", "elm");
      }
    if (sd->indicator_show)
      {
         elm_layout_signal_emit(obj, "elm,state,val,show", "elm");
         if (sd->popup)
           edje_object_signal_emit(sd->popup, "elm,state,val,show", "elm");
+        if (sd->popup2)
+          edje_object_signal_emit(sd->popup2, "elm,state,val,show", "elm");
      }
+
    _min_max_set(obj);
    _units_set(obj);
    _indicator_set(obj);
@@ -616,6 +780,8 @@ _elm_slider_elm_widget_theme_apply(Eo *obj, Elm_Slider_Data 
*sd)
    edje_object_message_signal_process(wd->resize_obj);
    if (sd->popup)
      edje_object_message_signal_process(sd->popup);
+   if (sd->popup2)
+     edje_object_message_signal_process(sd->popup2);
 
    evas_object_smart_changed(obj);
 
@@ -636,6 +802,54 @@ _elm_slider_elm_layout_sizing_eval(Eo *obj, 
Elm_Slider_Data *_pd EINA_UNUSED)
 }
 
 static void
+_move_knob_on_mouse(Evas_Object *obj, double button_x, double button_y)
+{
+   ELM_SLIDER_DATA_GET(obj, sd);
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+   if (!sd->range_enable)
+     {
+        edje_object_part_drag_value_set
+           (wd->resize_obj, "elm.dragable.slider",
+            button_x, button_y);
+     }
+   else
+     {
+        double posx = 0.0, posy = 0.0, posx2 = 0.0, posy2 = 0.0, diff1, diff2;
+
+        edje_object_part_drag_value_get
+           (wd->resize_obj, "elm.dragable.slider", &posx, &posy);
+        edje_object_part_drag_value_get
+           (wd->resize_obj, "elm.dragable2.slider", &posx2, &posy2);
+
+        if (sd->horizontal)
+          {
+             diff1 = fabs(button_x - posx);
+             diff2 = fabs(button_x - posx2);
+          }
+        else
+          {
+             diff1 = fabs(button_y - posy);
+             diff2 = fabs(button_y - posy2);
+          }
+
+        if (diff1 < diff2)
+          {
+             edje_object_part_drag_value_set
+                (wd->resize_obj, "elm.dragable.slider",
+                 button_x, button_y);
+          }
+        else
+          {
+             edje_object_part_drag_value_set
+                (wd->resize_obj, "elm.dragable2.slider",
+                 button_x, button_y);
+          }
+     }
+
+}
+
+static void
 _spacer_down_cb(void *data,
                 Evas *e EINA_UNUSED,
                 Evas_Object *obj EINA_UNUSED,
@@ -665,10 +879,8 @@ _spacer_down_cb(void *data,
         if (button_y < 0) button_y = 0;
      }
 
-   ELM_WIDGET_DATA_GET_OR_RETURN(data, wd);
-   edje_object_part_drag_value_set
-     (wd->resize_obj, "elm.dragable.slider",
-     button_x, button_y);
+   _move_knob_on_mouse(data, button_x, button_y);
+
    if (!elm_widget_focus_get(data))
      elm_object_focus_set(data, EINA_TRUE);
    _slider_update(data, EINA_TRUE);
@@ -733,10 +945,7 @@ _spacer_move_cb(void *data,
              if (button_y < 0) button_y = 0;
           }
 
-        ELM_WIDGET_DATA_GET_OR_RETURN(data, wd);
-        edje_object_part_drag_value_set
-          (wd->resize_obj, "elm.dragable.slider",
-          button_x, button_y);
+        _move_knob_on_mouse(data, button_x, button_y);
         _slider_update(data, EINA_TRUE);
      }
 }
@@ -900,7 +1109,10 @@ _elm_slider_evas_object_smart_add(Eo *obj, 
Elm_Slider_Data *priv)
    evas_object_pass_events_set(priv->spacer, EINA_TRUE);
    elm_layout_content_set(obj, "elm.swallow.bar", priv->spacer);
 
-   _popup_add(priv, obj);
+   if (!priv->range_enable)
+     _popup_add(priv, obj, &priv->popup, &priv->track, priv->range_enable);
+   else
+     _popup_add(priv, obj, &priv->popup2, &priv->track2, priv->range_enable);
 
    evas_object_event_callback_add
      (priv->spacer, EVAS_CALLBACK_MOUSE_DOWN, _spacer_down_cb, obj);
@@ -932,6 +1144,7 @@ _elm_slider_evas_object_smart_del(Eo *obj, Elm_Slider_Data 
*sd)
    ecore_timer_del(sd->delay);
    ecore_timer_del(sd->wheel_indicator_timer);
    evas_object_del(sd->popup);
+   evas_object_del(sd->popup2);
 
    evas_obj_smart_del(eo_super(obj, MY_CLASS));
 }
@@ -948,6 +1161,53 @@ _elm_slider_elm_layout_content_aliases_get(Eo *obj 
EINA_UNUSED, Elm_Slider_Data
    return _content_aliases;
 }
 
+EOLIAN static Eina_Bool
+_elm_slider_range_enabled_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *pd)
+{
+   return pd->range_enable;
+}
+
+EOLIAN static void
+_elm_slider_range_enabled_set(Eo *obj, Elm_Slider_Data *sd, Eina_Bool enable)
+{
+   if (sd->range_enable == enable) return;
+
+   sd->range_enable = enable;
+   if (sd->range_enable)
+     {
+        _popup_add(sd, obj, &sd->popup2, &sd->track2, sd->range_enable);
+        elm_layout_signal_emit(obj, "elm,slider,range,enable", "elm");
+        if (sd->indicator_show)
+          edje_object_signal_emit(sd->popup2, "elm,state,val,show", "elm");
+     }
+   else
+     {
+        elm_layout_signal_emit(obj, "elm,slider,range,disable", "elm");
+        ELM_SAFE_FREE(sd->popup2, evas_object_del);
+     }
+}
+
+EOLIAN static void
+_elm_slider_range_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *pd, double *from, 
double *to)
+{
+   if (from) *from = fmin(pd->range_from, pd->range_to);
+   if (to) *to = fmax(pd->range_from, pd->range_to);
+}
+
+EOLIAN static void
+_elm_slider_range_set(Eo *obj, Elm_Slider_Data *pd, double from, double to)
+{
+   pd->range_from = from;
+   //TODO: remove val later
+   pd->val = from;
+   pd->range_to = to;
+
+   if (pd->range_from < pd->val_min) pd->range_from = pd->val_min;
+   if (pd->range_to > pd->val_max) pd->range_to = pd->val_max;
+
+   _visuals_refresh(obj);
+}
+
 EAPI Evas_Object *
 elm_slider_add(Evas_Object *parent)
 {
@@ -978,12 +1238,16 @@ _elm_slider_span_size_set(Eo *obj, Elm_Slider_Data *sd, 
Evas_Coord size)
         elm_layout_signal_emit(obj, "elm,state,val,show", "elm");
         if (sd->popup)
           edje_object_signal_emit(sd->popup, "elm,state,val,show", "elm");
+        if (sd->popup2)
+          edje_object_signal_emit(sd->popup2, "elm,state,val,show", "elm");
      }
    else
      {
         elm_layout_signal_emit(obj, "elm,state,val,hide", "elm");
         if (sd->popup)
           edje_object_signal_emit(sd->popup, "elm,state,val,hide", "elm");
+        if (sd->popup2)
+          edje_object_signal_emit(sd->popup2, "elm,state,val,hide", "elm");
      }
 
    evas_object_smart_changed(obj);
@@ -1007,6 +1271,8 @@ _elm_slider_unit_format_set(Eo *obj, Elm_Slider_Data *sd, 
const char *units)
         edje_object_message_signal_process(wd->resize_obj);
         if (sd->popup)
           edje_object_signal_emit(sd->popup, "elm,state,units,visible", "elm");
+        if (sd->popup2)
+          edje_object_signal_emit(sd->popup2, "elm,state,units,visible", 
"elm");
      }
    else
      {
@@ -1014,6 +1280,8 @@ _elm_slider_unit_format_set(Eo *obj, Elm_Slider_Data *sd, 
const char *units)
         edje_object_message_signal_process(wd->resize_obj);
         if (sd->popup)
           edje_object_signal_emit(sd->popup, "elm,state,units,hidden", "elm");
+        if (sd->popup2)
+          edje_object_signal_emit(sd->popup2, "elm,state,units,hidden", "elm");
      }
    evas_object_smart_changed(obj);
 }
@@ -1077,6 +1345,7 @@ _elm_slider_value_set(Eo *obj, Elm_Slider_Data *sd, 
double val)
 {
    if (sd->val == val) return;
    sd->val = val;
+   sd->range_from = val;
 
    if (sd->val < sd->val_min) sd->val = sd->val_min;
    if (sd->val > sd->val_max) sd->val = sd->val_max;
@@ -1149,6 +1418,8 @@ _elm_slider_indicator_show_set(Eo *obj, Elm_Slider_Data 
*sd, Eina_Bool show)
         elm_layout_signal_emit(obj, "elm,state,val,show", "elm");
         if (sd->popup)
           edje_object_signal_emit(sd->popup, "elm,state,val,show", "elm");
+        if (sd->popup2)
+          edje_object_signal_emit(sd->popup2, "elm,state,val,show", "elm");
      }
    else
      {
@@ -1156,6 +1427,8 @@ _elm_slider_indicator_show_set(Eo *obj, Elm_Slider_Data 
*sd, Eina_Bool show)
         elm_layout_signal_emit(obj, "elm,state,val,hide", "elm");
         if (sd->popup)
           edje_object_signal_emit(sd->popup, "elm,state,val,hide", "elm");
+        if (sd->popup2)
+          edje_object_signal_emit(sd->popup2, "elm,state,val,hide", "elm");
      }
 
    evas_object_smart_changed(obj);
diff --git a/src/lib/elementary/elm_slider.eo b/src/lib/elementary/elm_slider.eo
index 729073c..c04b9b1 100644
--- a/src/lib/elementary/elm_slider.eo
+++ b/src/lib/elementary/elm_slider.eo
@@ -263,6 +263,29 @@ class Elm.Slider (Elm.Layout, Elm.Interface_Atspi_Value,
             free_func: slider_freefunc_type @nullable; [[The freeing function 
for the format string.]]
          }
       }
+      @property range_enabled {
+         set {
+            [[Enables the range. This enables two indicators in slider.]]
+         }
+         get {
+            [[Get whether the range is enabled.]]
+         }
+         values {
+            enable: Eina_Bool;
+         }
+      }
+      @property range {
+         set {
+            [[Set the values of two indicators.]]
+         }
+         get {
+            [[Get the values of two indicators.]]
+         }
+         values {
+            from: double; [[range minimum value]]
+            to: double; [[range maximum value]]
+         }
+      }
    }
    implements {
       class.constructor;
diff --git a/src/lib/elementary/elm_widget_slider.h 
b/src/lib/elementary/elm_widget_slider.h
index 49ebd8a..54a8408 100644
--- a/src/lib/elementary/elm_widget_slider.h
+++ b/src/lib/elementary/elm_widget_slider.h
@@ -26,7 +26,7 @@
 typedef struct _Elm_Slider_Data Elm_Slider_Data;
 struct _Elm_Slider_Data
 {
-   Evas_Object          *spacer, *popup, *track;
+   Evas_Object          *spacer, *popup, *popup2, *track, *track2;
    Ecore_Timer          *delay;
 
    const char           *units;
@@ -48,6 +48,8 @@ struct _Elm_Slider_Data
    Evas_Coord            size;
    Evas_Coord            downx, downy;
 
+   double                range_from, range_to;
+
    Eina_Bool             horizontal : 1;
    Eina_Bool             inverted : 1;
    Eina_Bool             indicator_show : 1;
@@ -55,6 +57,7 @@ struct _Elm_Slider_Data
    Eina_Bool             frozen : 1;
    Eina_Bool             units_show : 1;
    Eina_Bool             popup_visible : 1;
+   Eina_Bool             range_enable : 1;
 };
 
 /**

-- 


Reply via email to