[atspi] slider uses max value when atspi tries to set value.
[platform/upstream/elementary.git] / src / lib / elm_slider.c
1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
6 #define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
7 #define ELM_INTERFACE_ATSPI_VALUE_PROTECTED
8
9 #include <Elementary.h>
10
11 #include "elm_priv.h"
12 #include "elm_widget_slider.h"
13 #include "elm_widget_layout.h"
14
15 #define MY_CLASS ELM_SLIDER_CLASS
16
17 #define MY_CLASS_NAME "Elm_Slider"
18 #define MY_CLASS_NAME_LEGACY "elm_slider"
19 #define SLIDER_DELAY_CHANGED_INTERVAL 0.2
20 #define SLIDER_STEP 0.05
21
22 static const Elm_Layout_Part_Alias_Description _content_aliases[] =
23 {
24    {"icon", "elm.swallow.icon"},
25    {"end", "elm.swallow.end"},
26    {NULL, NULL}
27 };
28
29 static const Elm_Layout_Part_Alias_Description _text_aliases[] =
30 {
31    {"default", "elm.text"},
32    {NULL, NULL}
33 };
34
35 static const char SIG_CHANGED[] = "changed";
36 static const char SIG_DELAY_CHANGED[] = "delay,changed";
37 static const char SIG_DRAG_START[] = "slider,drag,start";
38 static const char SIG_DRAG_STOP[] = "slider,drag,stop";
39 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
40    {SIG_CHANGED, ""},
41    {SIG_DELAY_CHANGED, ""},
42    {SIG_DRAG_START, ""},
43    {SIG_DRAG_STOP, ""},
44    {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
45    {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
46    {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
47    {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
48    {NULL, NULL}
49 };
50
51 static void _min_max_set(Evas_Object *obj);
52
53 static Eina_Bool _key_action_drag(Evas_Object *obj, const char *params);
54
55 static const Elm_Action key_actions[] = {
56    {"drag", _key_action_drag},
57    {NULL, NULL}
58 };
59
60 static Eina_Bool
61 _delay_change(void *data)
62 {
63    ELM_SLIDER_DATA_GET(data, sd);
64
65    sd->delay = NULL;
66    //TIZEN_ONLY(20160616): Moved atspi value change signal to delay change
67    elm_interface_atspi_accessible_value_changed_signal_emit(data);
68    //
69    eo_do(data, eo_event_callback_call(ELM_SLIDER_EVENT_DELAY_CHANGED, NULL));
70
71    return ECORE_CALLBACK_CANCEL;
72 }
73
74 static void
75 _val_fetch(Evas_Object *obj, Eina_Bool user_event)
76 {
77    Eina_Bool rtl;
78    double posx = 0.0, posy = 0.0, pos = 0.0, val;
79
80    ELM_SLIDER_DATA_GET(obj, sd);
81    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
82
83    edje_object_part_drag_value_get
84      (wd->resize_obj, "elm.dragable.slider", &posx, &posy);
85    if (sd->horizontal) pos = posx;
86    else pos = posy;
87
88    rtl = elm_widget_mirrored_get(obj);
89    if ((!rtl && sd->inverted) ||
90        (rtl && ((!sd->horizontal && sd->inverted) ||
91                 (sd->horizontal && !sd->inverted))))
92      pos = 1.0 - pos;
93
94    val = (pos * (sd->val_max - sd->val_min)) + sd->val_min;
95    if (fabs(val - sd->val) > DBL_EPSILON)
96      {
97         sd->val = val;
98         if (user_event)
99           {
100              eo_do(obj, eo_event_callback_call(ELM_SLIDER_EVENT_CHANGED, NULL));
101              //TIZEN_ONLY(20160616): Moved atspi value change signal to delay change
102              //elm_interface_atspi_accessible_value_changed_signal_emit(obj);
103              //
104              ecore_timer_del(sd->delay);
105              sd->delay = ecore_timer_add(SLIDER_DELAY_CHANGED_INTERVAL, _delay_change, obj);
106           }
107      }
108 }
109
110 static void
111 _val_set(Evas_Object *obj)
112 {
113    Eina_Bool rtl;
114    double pos;
115
116    ELM_SLIDER_DATA_GET(obj, sd);
117
118    if (sd->val_max > sd->val_min)
119      pos = (sd->val - sd->val_min) / (sd->val_max - sd->val_min);
120    else pos = 0.0;
121
122    if (pos < 0.0) pos = 0.0;
123    else if (pos > 1.0)
124      pos = 1.0;
125
126    rtl = elm_widget_mirrored_get(obj);
127    if ((!rtl && sd->inverted) ||
128        (rtl && ((!sd->horizontal && sd->inverted) ||
129                 (sd->horizontal && !sd->inverted))))
130      pos = 1.0 - pos;
131
132    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
133    edje_object_part_drag_value_set
134      (wd->resize_obj, "elm.dragable.slider", pos, pos);
135 }
136
137 static void
138 _units_set(Evas_Object *obj)
139 {
140    ELM_SLIDER_DATA_GET(obj, sd);
141
142    if (sd->units_format_func)
143      {
144         char *buf;
145
146         buf = sd->units_format_func(sd->val);
147         if (buf)
148           {
149              elm_layout_text_set(obj, "elm.units", buf);
150              if (!sd->units_show)
151                {
152                   elm_layout_signal_emit(obj, "elm,state,units,visible", "elm");
153                   sd->units_show = EINA_TRUE;
154                }
155           }
156         else
157           {
158              elm_layout_text_set(obj, "elm.units", NULL);
159              if (sd->units_show)
160                {
161                   elm_layout_signal_emit(obj, "elm,state,units,hidden", "elm");
162                   sd->units_show = EINA_FALSE;
163                }
164           }
165         if (sd->units_format_free) sd->units_format_free(buf);
166      }
167    else if (sd->units)
168      {
169         char buf[1024];
170
171         snprintf(buf, sizeof(buf), sd->units, sd->val);
172         elm_layout_text_set(obj, "elm.units", buf);
173         if (!sd->units_show)
174           {
175              elm_layout_signal_emit(obj, "elm,state,units,visible", "elm");
176              sd->units_show = EINA_TRUE;
177           }
178      }
179    else
180      {
181         elm_layout_text_set(obj, "elm.units", NULL);
182         if (sd->units_show)
183           {
184              elm_layout_signal_emit(obj, "elm,state,units,hidden", "elm");
185              sd->units_show = EINA_FALSE;
186           }
187      }
188 }
189
190 static void
191 _indicator_set(Evas_Object *obj)
192 {
193    ELM_SLIDER_DATA_GET(obj, sd);
194
195    if (sd->indicator_format_func)
196      {
197         char *buf;
198
199         buf = sd->indicator_format_func(sd->val);
200         elm_layout_text_set(obj, "elm.indicator", buf);
201         elm_layout_text_set(obj, "elm.dragable.slider:elm.indicator", buf);
202         if (sd->popup)
203           edje_object_part_text_set(sd->popup, "elm.indicator", buf);
204
205         if (sd->indicator_format_free) sd->indicator_format_free(buf);
206      }
207    else if (sd->indicator)
208      {
209         char buf[1024];
210
211         snprintf(buf, sizeof(buf), sd->indicator, sd->val);
212         elm_layout_text_set(obj, "elm.indicator", buf);
213         elm_layout_text_set(obj, "elm.dragable.slider:elm.indicator", buf);
214         if (sd->popup)
215           edje_object_part_text_set(sd->popup, "elm.indicator", buf);
216      }
217    else
218      {
219         elm_layout_text_set(obj, "elm.indicator", NULL);
220         elm_layout_text_set(obj, "elm.dragable.slider:elm.indicator", NULL);
221         if (sd->popup)
222           edje_object_part_text_set(sd->popup, "elm.indicator", NULL);
223      }
224 }
225
226 static void
227 _slider_update(Evas_Object *obj, Eina_Bool user_event)
228 {
229    _val_fetch(obj, user_event);
230    evas_object_smart_changed(obj);
231 }
232
233 static void
234 _drag(void *data,
235       Evas_Object *obj EINA_UNUSED,
236       const char *emission EINA_UNUSED,
237       const char *source EINA_UNUSED)
238 {
239    _slider_update(data, EINA_TRUE);
240 }
241
242 static void
243 _drag_start(void *data,
244             Evas_Object *obj EINA_UNUSED,
245             const char *emission EINA_UNUSED,
246             const char *source EINA_UNUSED)
247 {
248    if (!elm_widget_focus_get(data))
249      elm_object_focus_set(data, EINA_TRUE);
250    _slider_update(data, EINA_TRUE);
251    eo_do(data, eo_event_callback_call(ELM_SLIDER_EVENT_SLIDER_DRAG_START, NULL));
252    elm_widget_scroll_freeze_push(data);
253 }
254
255 static void
256 _drag_stop(void *data,
257            Evas_Object *obj EINA_UNUSED,
258            const char *emission EINA_UNUSED,
259            const char *source EINA_UNUSED)
260 {
261    _slider_update(data, EINA_TRUE);
262    eo_do(data, eo_event_callback_call(ELM_SLIDER_EVENT_SLIDER_DRAG_STOP, NULL));
263    elm_widget_scroll_freeze_pop(data);
264 }
265
266 static void
267 _drag_step(void *data,
268            Evas_Object *obj EINA_UNUSED,
269            const char *emission EINA_UNUSED,
270            const char *source EINA_UNUSED)
271 {
272    _slider_update(data, EINA_TRUE);
273 }
274
275 static void
276 _drag_up(void *data,
277          Evas_Object *obj EINA_UNUSED,
278          const char *emission EINA_UNUSED,
279          const char *source EINA_UNUSED)
280 {
281    double step;
282
283    ELM_SLIDER_DATA_GET(data, sd);
284    step = sd->step;
285
286    if (sd->inverted) step *= -1.0;
287
288    ELM_WIDGET_DATA_GET_OR_RETURN(data, wd);
289    edje_object_part_drag_step
290      (wd->resize_obj, "elm.dragable.slider", step, step);
291 }
292
293 static void
294 _drag_down(void *data,
295            Evas_Object *obj EINA_UNUSED,
296            const char *emission EINA_UNUSED,
297            const char *source EINA_UNUSED)
298 {
299    double step;
300
301    ELM_SLIDER_DATA_GET(data, sd);
302    step = -sd->step;
303
304    if (sd->inverted) step *= -1.0;
305
306    ELM_WIDGET_DATA_GET_OR_RETURN(data, wd);
307    edje_object_part_drag_step
308      (wd->resize_obj, "elm.dragable.slider", step, step);
309 }
310
311 static void
312 _popup_show(void *data,
313             Evas_Object *obj EINA_UNUSED,
314             const char *emission EINA_UNUSED,
315             const char *source EINA_UNUSED)
316 {
317    ELM_SLIDER_DATA_GET(data, sd);
318    if (sd->popup &&
319        (sd->indicator_visible_mode != ELM_SLIDER_INDICATOR_VISIBLE_MODE_NONE))
320      {
321         evas_object_raise(sd->popup);
322         evas_object_show(sd->popup);
323         sd->popup_visible = EINA_TRUE;
324         edje_object_signal_emit(sd->popup, "popup,show", "elm"); // XXX: for compat
325         edje_object_signal_emit(sd->popup, "elm,popup,show", "elm");
326      }
327 }
328
329 static void
330 _popup_hide(void *data,
331             Evas_Object *obj EINA_UNUSED,
332             const char *emission EINA_UNUSED,
333             const char *source EINA_UNUSED)
334 {
335    ELM_SLIDER_DATA_GET(data, sd);
336
337    if (!sd->popup_visible || !sd->popup) return;
338
339    if (sd->indicator_visible_mode == ELM_SLIDER_INDICATOR_VISIBLE_MODE_ALWAYS) return;
340    if ((sd->indicator_visible_mode == ELM_SLIDER_INDICATOR_VISIBLE_MODE_ON_FOCUS) &&
341        elm_widget_focus_get(data))
342      return;
343
344    edje_object_signal_emit(sd->popup, "popup,hide", "elm"); // XXX: for compat
345    edje_object_signal_emit(sd->popup, "elm,popup,hide", "elm");
346 }
347
348 static void
349 _popup_hide_done(void *data,
350                  Evas_Object *obj EINA_UNUSED,
351                  const char *emission EINA_UNUSED,
352                  const char *source EINA_UNUSED)
353 {
354    ELM_SLIDER_DATA_GET(data, sd);
355    if (sd->popup)
356      {
357         if (!((elm_widget_focus_get(data)) &&
358               (sd->indicator_visible_mode == ELM_SLIDER_INDICATOR_VISIBLE_MODE_ON_FOCUS)))
359           {
360              evas_object_hide(sd->popup);
361              sd->popup_visible = EINA_FALSE;
362           }
363      }
364 }
365
366 static void
367 _popup_emit(void *data,
368             Evas_Object *obj EINA_UNUSED,
369             const char *emission,
370             const char *source)
371 {
372    ELM_SLIDER_DATA_GET(data, sd);
373    if (sd->popup)
374      {
375         edje_object_signal_emit(sd->popup, emission, source);
376      }
377 }
378
379 static Eina_Bool
380 _key_action_drag(Evas_Object *obj, const char *params)
381 {
382    ELM_SLIDER_DATA_GET(obj, sd);
383    const char *dir = params;
384
385    if (!strcmp(dir, "left"))
386      {
387         if (!sd->horizontal) return EINA_FALSE;
388         if (!sd->inverted) _drag_down(obj, NULL, NULL, NULL);
389         else _drag_up(obj, NULL, NULL, NULL);
390      }
391    else if (!strcmp(dir, "right"))
392      {
393         if (!sd->horizontal) return EINA_FALSE;
394         if (!sd->inverted) _drag_up(obj, NULL, NULL, NULL);
395         else _drag_down(obj, NULL, NULL, NULL);
396      }
397    else if (!strcmp(dir, "up"))
398      {
399         if (sd->horizontal) return EINA_FALSE;
400         if (sd->inverted) _drag_up(obj, NULL, NULL, NULL);
401         else _drag_down(obj, NULL, NULL, NULL);
402      }
403    else if (!strcmp(dir, "down"))
404      {
405         if (sd->horizontal) return EINA_FALSE;
406         if (sd->inverted) _drag_down(obj, NULL, NULL, NULL);
407         else _drag_up(obj, NULL, NULL, NULL);
408      }
409    else return EINA_FALSE;
410
411    return EINA_TRUE;
412 }
413
414 EOLIAN static Eina_Bool
415 _elm_slider_elm_widget_event(Eo *obj, Elm_Slider_Data *sd EINA_UNUSED, Evas_Object *src, Evas_Callback_Type type, void *event_info)
416 {
417    (void) src;
418
419    if (type == EVAS_CALLBACK_KEY_DOWN)
420      {
421         Evas_Event_Key_Down *ev = event_info;
422         if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
423
424         if (!_elm_config_key_binding_call(obj, ev, key_actions))
425           return EINA_FALSE;
426         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
427      }
428    else if (type == EVAS_CALLBACK_KEY_UP)
429      {
430           _popup_hide(obj, NULL, NULL, NULL);
431         return EINA_FALSE;
432      }
433    else if (type == EVAS_CALLBACK_MOUSE_WHEEL)
434      {
435         Evas_Event_Mouse_Wheel *mev = event_info;
436         if (mev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
437
438         if (mev->z < 0) _drag_up(obj, NULL, NULL, NULL);
439         else _drag_down(obj, NULL, NULL, NULL);
440         mev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
441      }
442    else return EINA_FALSE;
443
444    _popup_show(obj, NULL, NULL, NULL);
445    _slider_update(obj, EINA_TRUE);
446
447    return EINA_TRUE;
448 }
449
450 EOLIAN static Eina_Bool
451 _elm_slider_elm_widget_activate(Eo *obj, Elm_Slider_Data *sd, Elm_Activate act)
452 {
453    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
454    if (act == ELM_ACTIVATE_DEFAULT) return EINA_FALSE;
455
456    if ((act == ELM_ACTIVATE_UP) ||
457        (act == ELM_ACTIVATE_RIGHT))
458      {
459         if (!sd->inverted) _drag_up(obj, NULL, NULL, NULL);
460         else _drag_down(obj, NULL, NULL, NULL);
461      }
462    else if ((act == ELM_ACTIVATE_DOWN) ||
463             (act == ELM_ACTIVATE_LEFT))
464      {
465         if (!sd->inverted) _drag_down(obj, NULL, NULL, NULL);
466         else _drag_up(obj, NULL, NULL, NULL);
467      }
468
469    _slider_update(obj, EINA_TRUE);
470
471    return EINA_TRUE;
472 }
473
474 static void
475 _visuals_refresh(Evas_Object *obj)
476 {
477    _val_set(obj);
478    evas_object_smart_changed(obj);
479 }
480
481 static void
482 _track_move_cb(void *data,
483                Evas *e EINA_UNUSED,
484                Evas_Object *obj,
485                void *event_info EINA_UNUSED)
486 {
487    Evas_Coord x, y;
488
489    ELM_SLIDER_DATA_GET(data, sd);
490    evas_object_geometry_get(obj, &x, &y, NULL, NULL);
491    evas_object_move(sd->popup, x, y);
492 }
493
494 static void
495 _track_resize_cb(void *data,
496                  Evas *e EINA_UNUSED,
497                  Evas_Object *obj,
498                  void *event_info EINA_UNUSED)
499 {
500    Evas_Coord w, h;
501
502    ELM_SLIDER_DATA_GET(data, sd);
503    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
504    evas_object_resize(sd->popup, w, h);
505 }
506
507 static void
508 _popup_add(Elm_Slider_Data *sd, Eo *obj)
509 {
510    /* if theme has an overlayed slider mode, then lets support it */
511    if (!edje_object_part_exists(elm_layout_edje_get(obj), "elm.track.slider")) return;
512
513    // XXX popup needs to adapt to theme etc.
514    sd->popup = edje_object_add(evas_object_evas_get(obj));
515    /* TIZEN_ONLY(20161031): apply color_class parent-child relationship to all widgets */
516    _elm_widget_color_class_parent_set(sd->popup, obj);
517    /* END */
518    if (sd->horizontal)
519      _elm_theme_set(elm_widget_theme_get(obj), sd->popup, "slider", "horizontal/popup", elm_widget_style_get(obj));
520    else
521      _elm_theme_set(elm_widget_theme_get(obj), sd->popup, "slider", "vertical/popup", elm_widget_style_get(obj));
522    edje_object_scale_set(sd->popup, elm_widget_scale_get(obj) *
523                          elm_config_scale_get());
524    edje_object_signal_callback_add(sd->popup, "popup,hide,done", "elm", // XXX: for compat
525                                    _popup_hide_done, obj);
526    edje_object_signal_callback_add(sd->popup, "elm,popup,hide,done", "elm",
527                                    _popup_hide_done, obj);
528
529    /* create a rectangle to track position+size of the dragable */
530    sd->track = evas_object_rectangle_add(evas_object_evas_get(obj));
531    evas_object_event_callback_add
532      (sd->track, EVAS_CALLBACK_MOVE, _track_move_cb, obj);
533    evas_object_event_callback_add
534      (sd->track, EVAS_CALLBACK_RESIZE, _track_resize_cb, obj);
535
536    evas_object_color_set(sd->track, 0, 0, 0, 0);
537    evas_object_pass_events_set(sd->track, EINA_TRUE);
538    elm_layout_content_set(obj, "elm.track.slider", sd->track);
539 }
540
541 EOLIAN static Elm_Theme_Apply
542 _elm_slider_elm_widget_theme_apply(Eo *obj, Elm_Slider_Data *sd)
543 {
544    Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
545    ELM_LAYOUT_DATA_GET(obj, ld);
546    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, ELM_THEME_APPLY_FAILED);
547
548    if (sd->horizontal)
549      {
550         eina_stringshare_replace(&ld->group, "horizontal");
551         if (sd->popup)
552           _elm_theme_set(elm_widget_theme_get(obj), sd->popup,
553                          "slider", "horizontal/popup",
554                          elm_widget_style_get(obj));
555      }
556    else
557      {
558         eina_stringshare_replace(&ld->group, "vertical");
559         if (sd->popup)
560           _elm_theme_set(elm_widget_theme_get(obj), sd->popup,
561                          "slider", "vertical/popup",
562                          elm_widget_style_get(obj));
563      }
564
565    eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
566    if (!int_ret) return ELM_THEME_APPLY_FAILED;
567
568 #ifdef TIZEN_VECTOR_UX
569    tizen_vg_slider_set(obj, sd->popup);
570 #endif
571
572    if (sd->popup)
573      edje_object_scale_set(sd->popup, elm_widget_scale_get(obj) *
574                            elm_config_scale_get());
575    else
576      _popup_add(sd, obj);
577
578    if (sd->horizontal)
579      evas_object_size_hint_min_set
580        (sd->spacer, (double)sd->size * elm_widget_scale_get(obj) *
581        elm_config_scale_get(), 1);
582    else
583      evas_object_size_hint_min_set
584        (sd->spacer, 1, (double)sd->size * elm_widget_scale_get(obj) *
585        elm_config_scale_get());
586
587    if (sd->inverted)
588      {
589         elm_layout_signal_emit(obj, "elm,state,inverted,on", "elm");
590         if (sd->popup)
591           edje_object_signal_emit(sd->popup, "elm,state,inverted,on", "elm");
592      }
593    if (sd->indicator_show)
594      {
595         elm_layout_signal_emit(obj, "elm,state,val,show", "elm");
596         if (sd->popup)
597           edje_object_signal_emit(sd->popup, "elm,state,val,show", "elm");
598      }
599    _min_max_set(obj);
600    _units_set(obj);
601    _indicator_set(obj);
602    _visuals_refresh(obj);
603
604    edje_object_message_signal_process(wd->resize_obj);
605    if (sd->popup)
606      edje_object_message_signal_process(sd->popup);
607
608    evas_object_smart_changed(obj);
609
610    return int_ret;
611 }
612
613 EOLIAN static void
614 _elm_slider_elm_layout_sizing_eval(Eo *obj, Elm_Slider_Data *_pd EINA_UNUSED)
615 {
616    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
617    Evas_Coord minw = -1, minh = -1;
618
619    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
620    edje_object_size_min_restricted_calc
621      (wd->resize_obj, &minw, &minh, minw, minh);
622    evas_object_size_hint_min_set(obj, minw, minh);
623    evas_object_size_hint_max_set(obj, -1, -1);
624 }
625
626 static void
627 _spacer_down_cb(void *data,
628                 Evas *e EINA_UNUSED,
629                 Evas_Object *obj EINA_UNUSED,
630                 void *event_info)
631 {
632    ELM_SLIDER_DATA_GET(data, sd);
633
634    Evas_Event_Mouse_Down *ev = event_info;
635    Evas_Coord x, y, w, h;
636    double button_x = 0.0, button_y = 0.0;
637
638    sd->spacer_down = EINA_TRUE;
639    sd->val2 = sd->val;
640    evas_object_geometry_get(sd->spacer, &x, &y, &w, &h);
641    sd->downx = ev->canvas.x - x;
642    sd->downy = ev->canvas.y - y;
643    if (sd->horizontal)
644      {
645         button_x = ((double)ev->canvas.x - (double)x) / (double)w;
646         if (button_x > 1) button_x = 1;
647         if (button_x < 0) button_x = 0;
648      }
649    else
650      {
651         button_y = ((double)ev->canvas.y - (double)y) / (double)h;
652         if (button_y > 1) button_y = 1;
653         if (button_y < 0) button_y = 0;
654      }
655
656    ELM_WIDGET_DATA_GET_OR_RETURN(data, wd);
657    edje_object_part_drag_value_set
658      (wd->resize_obj, "elm.dragable.slider",
659      button_x, button_y);
660    if (!elm_widget_focus_get(data))
661      elm_object_focus_set(data, EINA_TRUE);
662    _slider_update(data, EINA_TRUE);
663    eo_do(data, eo_event_callback_call(ELM_SLIDER_EVENT_SLIDER_DRAG_START, NULL));
664    elm_layout_signal_emit(data, "elm,state,indicator,show", "elm");
665 }
666
667 static void
668 _spacer_move_cb(void *data,
669                 Evas *e EINA_UNUSED,
670                 Evas_Object *obj EINA_UNUSED,
671                 void *event_info)
672 {
673    ELM_SLIDER_DATA_GET(data, sd);
674
675    Evas_Coord x, y, w, h;
676    double button_x = 0.0, button_y = 0.0;
677    Evas_Event_Mouse_Move *ev = event_info;
678
679    if (sd->spacer_down)
680      {
681         Evas_Coord d = 0;
682
683         evas_object_geometry_get(sd->spacer, &x, &y, &w, &h);
684         if (sd->horizontal) d = abs(ev->cur.canvas.x - x - sd->downx);
685         else d = abs(ev->cur.canvas.y - y - sd->downy);
686         if (d > (_elm_config->thumbscroll_threshold - 1))
687           {
688              if (!sd->frozen)
689                {
690                   elm_widget_scroll_freeze_push(data);
691                   sd->frozen = EINA_TRUE;
692                }
693              ev->event_flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
694           }
695
696         if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
697           {
698              if (sd->spacer_down) sd->spacer_down = EINA_FALSE;
699              _slider_update(data, EINA_TRUE);
700              eo_do(data, eo_event_callback_call
701                (ELM_SLIDER_EVENT_SLIDER_DRAG_STOP, NULL));
702              if (sd->frozen)
703                {
704                   elm_widget_scroll_freeze_pop(data);
705                   sd->frozen = EINA_FALSE;
706                }
707              elm_layout_signal_emit(data, "elm,state,indicator,hide", "elm");
708              elm_slider_value_set(data, sd->val2);
709              return;
710           }
711         if (sd->horizontal)
712           {
713              button_x = ((double)ev->cur.canvas.x - (double)x) / (double)w;
714              if (button_x > 1) button_x = 1;
715              if (button_x < 0) button_x = 0;
716           }
717         else
718           {
719              button_y = ((double)ev->cur.canvas.y - (double)y) / (double)h;
720              if (button_y > 1) button_y = 1;
721              if (button_y < 0) button_y = 0;
722           }
723
724         ELM_WIDGET_DATA_GET_OR_RETURN(data, wd);
725         edje_object_part_drag_value_set
726           (wd->resize_obj, "elm.dragable.slider",
727           button_x, button_y);
728         _slider_update(data, EINA_TRUE);
729      }
730 }
731
732 static void
733 _spacer_up_cb(void *data,
734               Evas *e EINA_UNUSED,
735               Evas_Object *obj EINA_UNUSED,
736               void *event_info EINA_UNUSED)
737 {
738    ELM_SLIDER_DATA_GET(data, sd);
739
740    if (!sd->spacer_down) return;
741    if (sd->spacer_down) sd->spacer_down = EINA_FALSE;
742
743    _slider_update(data, EINA_TRUE);
744    eo_do(data, eo_event_callback_call(ELM_SLIDER_EVENT_SLIDER_DRAG_STOP, NULL));
745
746    if (sd->frozen)
747      {
748         elm_widget_scroll_freeze_pop(data);
749         sd->frozen = EINA_FALSE;
750      }
751    elm_layout_signal_emit(data, "elm,state,indicator,hide", "elm");
752 }
753
754 static void
755 _min_max_set(Evas_Object *obj)
756 {
757    char *buf_min = NULL;
758    char *buf_max = NULL;
759
760    ELM_SLIDER_DATA_GET(obj, sd);
761
762    if (sd->units_format_func)
763      {
764         buf_min = sd->units_format_func(sd->val_min);
765         buf_max = sd->units_format_func(sd->val_max);
766      }
767    else if (sd->units)
768      {
769         int length = eina_stringshare_strlen(sd->units);
770
771         buf_min = alloca(length + 128);
772         buf_max = alloca(length + 128);
773
774         snprintf((char *)buf_min, length + 128, sd->units, sd->val_min);
775         snprintf((char *)buf_max, length + 128, sd->units, sd->val_max);
776      }
777
778    elm_layout_text_set(obj, "elm.units.min", buf_min);
779    elm_layout_text_set(obj, "elm.units.max", buf_max);
780
781    if (sd->units_format_func && sd->units_format_free)
782      {
783         sd->units_format_free(buf_min);
784         sd->units_format_free(buf_max);
785      }
786 }
787
788 EOLIAN static void
789 _elm_slider_evas_object_smart_calculate(Eo *obj, Elm_Slider_Data *sd)
790 {
791    elm_layout_freeze(obj);
792
793    if (sd->horizontal)
794      evas_object_size_hint_min_set
795        (sd->spacer, (double)sd->size * elm_widget_scale_get(obj) *
796        elm_config_scale_get(), 1);
797    else
798      evas_object_size_hint_min_set
799        (sd->spacer, 1, (double)sd->size * elm_widget_scale_get(obj) *
800        elm_config_scale_get());
801
802    _val_fetch(obj, EINA_FALSE);
803    _min_max_set(obj);
804    _units_set(obj);
805    _indicator_set(obj);
806
807    elm_layout_thaw(obj);
808 }
809
810 static char *
811 _access_info_cb(void *data EINA_UNUSED, Evas_Object *obj)
812 {
813    const char *txt = elm_widget_access_info_get(obj);
814
815    if (!txt) txt = elm_layout_text_get(obj, NULL);
816    if (txt) return strdup(txt);
817
818    return NULL;
819 }
820
821 static char *
822 _access_state_cb(void *data EINA_UNUSED, Evas_Object *obj)
823 {
824    char *ret;
825    Eina_Strbuf *buf = eina_strbuf_new();
826    const char *txt = elm_layout_text_get(obj, "elm.units");
827
828    if (txt) eina_strbuf_append(buf, txt);
829
830    if (elm_widget_disabled_get(obj))
831      eina_strbuf_append(buf, " state: disabled");
832
833    if (eina_strbuf_length_get(buf))
834      {
835         ret = eina_strbuf_string_steal(buf);
836         eina_strbuf_free(buf);
837         return ret;
838      }
839
840    eina_strbuf_free(buf);
841    return NULL;
842 }
843
844 static void
845 _on_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj,
846          void *event_info EINA_UNUSED)
847 {
848    ELM_SLIDER_DATA_GET(obj, sd);
849    if (sd->indicator_visible_mode == ELM_SLIDER_INDICATOR_VISIBLE_MODE_ALWAYS)
850      _popup_show(obj, NULL, NULL, NULL);
851 }
852
853 EOLIAN static void
854 _elm_slider_evas_object_smart_add(Eo *obj, Elm_Slider_Data *priv)
855 {
856    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
857
858    eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
859    elm_widget_sub_object_parent_add(obj);
860
861    priv->horizontal = EINA_TRUE;
862    priv->indicator_show = EINA_FALSE;
863    priv->indicator_visible_mode = elm_config_slider_indicator_visible_mode_get();
864    priv->val_max = 1.0;
865    priv->step = SLIDER_STEP;
866
867    if (!elm_layout_theme_set
868        (obj, "slider", "horizontal", elm_widget_style_get(obj)))
869      CRI("Failed to set layout!");
870
871    elm_layout_signal_callback_add(obj, "drag", "*", _drag, obj);
872    elm_layout_signal_callback_add(obj, "drag,start", "*", _drag_start, obj);
873    elm_layout_signal_callback_add(obj, "drag,stop", "*", _drag_stop, obj);
874    elm_layout_signal_callback_add(obj, "drag,step", "*", _drag_step, obj);
875    elm_layout_signal_callback_add(obj, "drag,page", "*", _drag_stop, obj);
876    elm_layout_signal_callback_add(obj, "popup,show", "elm", _popup_show, obj); // XXX: for compat
877    elm_layout_signal_callback_add(obj, "popup,hide", "elm", _popup_hide, obj); // XXX: for compat
878    elm_layout_signal_callback_add(obj, "elm,popup,show", "elm", _popup_show, obj);
879    elm_layout_signal_callback_add(obj, "elm,popup,hide", "elm", _popup_hide, obj);
880    elm_layout_signal_callback_add(obj, "*", "popup,emit", _popup_emit, obj);
881    edje_object_part_drag_value_set
882      (wd->resize_obj, "elm.dragable.slider", 0.0, 0.0);
883
884    priv->spacer = evas_object_rectangle_add(evas_object_evas_get(obj));
885    evas_object_color_set(priv->spacer, 0, 0, 0, 0);
886    evas_object_pass_events_set(priv->spacer, EINA_TRUE);
887    elm_layout_content_set(obj, "elm.swallow.bar", priv->spacer);
888
889    _popup_add(priv, obj);
890
891 #ifdef TIZEN_VECTOR_UX
892    tizen_vg_slider_set(obj, priv->popup);
893 #endif
894
895    evas_object_event_callback_add
896      (priv->spacer, EVAS_CALLBACK_MOUSE_DOWN, _spacer_down_cb, obj);
897    evas_object_event_callback_add
898      (priv->spacer, EVAS_CALLBACK_MOUSE_MOVE, _spacer_move_cb, obj);
899    evas_object_event_callback_add
900      (priv->spacer, EVAS_CALLBACK_MOUSE_UP, _spacer_up_cb, obj);
901
902    evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _on_show, NULL);
903
904    elm_widget_can_focus_set(obj, EINA_TRUE);
905
906    _elm_access_object_register(obj, wd->resize_obj);
907    _elm_access_text_set
908      (_elm_access_info_get(obj), ELM_ACCESS_TYPE, E_("slider"));
909    _elm_access_callback_set
910      (_elm_access_info_get(obj), ELM_ACCESS_INFO, _access_info_cb, NULL);
911    _elm_access_callback_set
912      (_elm_access_info_get(obj), ELM_ACCESS_STATE, _access_state_cb, NULL);
913
914    evas_object_smart_changed(obj);
915 }
916
917 EOLIAN static void
918 _elm_slider_evas_object_smart_del(Eo *obj, Elm_Slider_Data *sd)
919 {
920    eina_stringshare_del(sd->indicator);
921    eina_stringshare_del(sd->units);
922    ecore_timer_del(sd->delay);
923    evas_object_del(sd->popup);
924
925    eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
926 }
927
928 EOLIAN static const Elm_Layout_Part_Alias_Description*
929 _elm_slider_elm_layout_text_aliases_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *_pd EINA_UNUSED)
930 {
931    return _text_aliases;
932 }
933
934 EOLIAN static const Elm_Layout_Part_Alias_Description*
935 _elm_slider_elm_layout_content_aliases_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *_pd EINA_UNUSED)
936 {
937    return _content_aliases;
938 }
939
940 EAPI Evas_Object *
941 elm_slider_add(Evas_Object *parent)
942 {
943    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
944    Evas_Object *obj = eo_add(MY_CLASS, parent);
945    return obj;
946 }
947
948 EOLIAN static Eo *
949 _elm_slider_eo_base_constructor(Eo *obj, Elm_Slider_Data *_pd EINA_UNUSED)
950 {
951    obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
952    eo_do(obj,
953          evas_obj_type_set(MY_CLASS_NAME_LEGACY),
954          evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
955          elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_SLIDER));
956
957    return obj;
958 }
959
960 EOLIAN static void
961 _elm_slider_span_size_set(Eo *obj, Elm_Slider_Data *sd, Evas_Coord size)
962 {
963    if (sd->size == size) return;
964    sd->size = size;
965
966    if (sd->indicator_show)
967      {
968         elm_layout_signal_emit(obj, "elm,state,val,show", "elm");
969         if (sd->popup)
970           edje_object_signal_emit(sd->popup, "elm,state,val,show", "elm");
971      }
972    else
973      {
974         elm_layout_signal_emit(obj, "elm,state,val,hide", "elm");
975         if (sd->popup)
976           edje_object_signal_emit(sd->popup, "elm,state,val,hide", "elm");
977      }
978
979    evas_object_smart_changed(obj);
980 }
981
982 EOLIAN static Evas_Coord
983 _elm_slider_span_size_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd)
984 {
985    return sd->size;
986 }
987
988 EOLIAN static void
989 _elm_slider_unit_format_set(Eo *obj, Elm_Slider_Data *sd, const char *units)
990 {
991    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
992
993    eina_stringshare_replace(&sd->units, units);
994    if (units)
995      {
996         elm_layout_signal_emit(obj, "elm,state,units,visible", "elm");
997         edje_object_message_signal_process(wd->resize_obj);
998         if (sd->popup)
999           edje_object_signal_emit(sd->popup, "elm,state,units,visible", "elm");
1000      }
1001    else
1002      {
1003         elm_layout_signal_emit(obj, "elm,state,units,hidden", "elm");
1004         edje_object_message_signal_process(wd->resize_obj);
1005         if (sd->popup)
1006           edje_object_signal_emit(sd->popup, "elm,state,units,hidden", "elm");
1007      }
1008    evas_object_smart_changed(obj);
1009 }
1010
1011 EOLIAN static const char*
1012 _elm_slider_unit_format_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd)
1013 {
1014    return sd->units;
1015 }
1016
1017 EOLIAN static void
1018 _elm_slider_indicator_format_set(Eo *obj, Elm_Slider_Data *sd, const char *indicator)
1019 {
1020    eina_stringshare_replace(&sd->indicator, indicator);
1021    evas_object_smart_changed(obj);
1022 }
1023
1024 EOLIAN static const char*
1025 _elm_slider_indicator_format_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd)
1026 {
1027    return sd->indicator;
1028 }
1029
1030 EOLIAN static void
1031 _elm_slider_horizontal_set(Eo *obj, Elm_Slider_Data *sd, Eina_Bool horizontal)
1032 {
1033    horizontal = !!horizontal;
1034    if (sd->horizontal == horizontal) return;
1035    sd->horizontal = horizontal;
1036
1037    eo_do(obj, elm_obj_widget_theme_apply());
1038 }
1039
1040 EOLIAN static Eina_Bool
1041 _elm_slider_horizontal_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd)
1042 {
1043    return sd->horizontal;
1044 }
1045
1046 EOLIAN static void
1047 _elm_slider_min_max_set(Eo *obj, Elm_Slider_Data *sd, double min, double max)
1048 {
1049    if ((sd->val_min == min) && (sd->val_max == max)) return;
1050    sd->val_min = min;
1051    sd->val_max = max;
1052    if (sd->val < sd->val_min) sd->val = sd->val_min;
1053    if (sd->val > sd->val_max) sd->val = sd->val_max;
1054
1055    _visuals_refresh(obj);
1056 }
1057
1058 EOLIAN static void
1059 _elm_slider_min_max_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd, double *min, double *max)
1060 {
1061    if (min) *min = sd->val_min;
1062    if (max) *max = sd->val_max;
1063 }
1064
1065 EOLIAN static void
1066 _elm_slider_value_set(Eo *obj, Elm_Slider_Data *sd, double val)
1067 {
1068    if (sd->val == val) return;
1069    sd->val = val;
1070
1071    if (sd->val < sd->val_min) sd->val = sd->val_min;
1072    if (sd->val > sd->val_max) sd->val = sd->val_max;
1073
1074    _visuals_refresh(obj);
1075 }
1076
1077 EOLIAN static double
1078 _elm_slider_value_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd)
1079 {
1080    return sd->val;
1081 }
1082
1083 EOLIAN static void
1084 _elm_slider_inverted_set(Eo *obj, Elm_Slider_Data *sd, Eina_Bool inverted)
1085 {
1086    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1087
1088    inverted = !!inverted;
1089    if (sd->inverted == inverted) return;
1090    sd->inverted = inverted;
1091
1092    if (sd->inverted)
1093      {
1094         elm_layout_signal_emit(obj, "elm,state,inverted,on", "elm");
1095         if (sd->popup)
1096           edje_object_signal_emit(sd->popup, "elm,state,inverted,on", "elm");
1097      }
1098    else
1099      {
1100         elm_layout_signal_emit(obj, "elm,state,inverted,off", "elm");
1101         if (sd->popup)
1102           edje_object_signal_emit(sd->popup, "elm,state,inverted,off", "elm");
1103      }
1104
1105    edje_object_message_signal_process(wd->resize_obj);
1106
1107    _visuals_refresh(obj);
1108 }
1109
1110 EOLIAN static Eina_Bool
1111 _elm_slider_inverted_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd)
1112 {
1113    return sd->inverted;
1114 }
1115
1116 EOLIAN static void
1117 _elm_slider_indicator_format_function_set(Eo *obj, Elm_Slider_Data *sd, slider_func_type func, slider_freefunc_type free_func)
1118 {
1119    sd->indicator_format_func = func;
1120    sd->indicator_format_free = free_func;
1121    evas_object_smart_changed(obj);
1122 }
1123
1124 EOLIAN static void
1125 _elm_slider_units_format_function_set(Eo *obj, Elm_Slider_Data *sd, slider_func_type func, slider_freefunc_type free_func)
1126 {
1127    sd->units_format_func = func;
1128    sd->units_format_free = free_func;
1129
1130    evas_object_smart_changed(obj);
1131 }
1132
1133 EOLIAN static void
1134 _elm_slider_indicator_show_set(Eo *obj, Elm_Slider_Data *sd, Eina_Bool show)
1135 {
1136    if (show)
1137      {
1138         sd->indicator_show = EINA_TRUE;
1139         elm_layout_signal_emit(obj, "elm,state,val,show", "elm");
1140         if (sd->popup)
1141           edje_object_signal_emit(sd->popup, "elm,state,val,show", "elm");
1142      }
1143    else
1144      {
1145         sd->indicator_show = EINA_FALSE;
1146         elm_layout_signal_emit(obj, "elm,state,val,hide", "elm");
1147         if (sd->popup)
1148           edje_object_signal_emit(sd->popup, "elm,state,val,hide", "elm");
1149      }
1150
1151    evas_object_smart_changed(obj);
1152 }
1153
1154 EOLIAN static Eina_Bool
1155 _elm_slider_indicator_show_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd)
1156 {
1157    return sd->indicator_show;
1158 }
1159
1160 EOLIAN static void
1161 _elm_slider_step_set(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd, double step)
1162 {
1163    if (sd->step == step) return;
1164
1165    if (step < 0.0) step = 0.0;
1166    else if (step > 1.0) step = 1.0;
1167
1168    sd->step = step;
1169 }
1170
1171 EOLIAN static double
1172 _elm_slider_step_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd)
1173 {
1174    return sd->step;
1175 }
1176
1177 EOLIAN static void
1178 _elm_slider_indicator_show_on_focus_set(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd, Eina_Bool flag)
1179 {
1180    if (flag)
1181      sd->indicator_visible_mode = ELM_SLIDER_INDICATOR_VISIBLE_MODE_ON_FOCUS;
1182    else
1183      sd->indicator_visible_mode = ELM_SLIDER_INDICATOR_VISIBLE_MODE_DEFAULT;
1184 }
1185
1186 EOLIAN static Eina_Bool
1187 _elm_slider_indicator_show_on_focus_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd)
1188 {
1189    return (sd->indicator_visible_mode == ELM_SLIDER_INDICATOR_VISIBLE_MODE_ON_FOCUS);
1190 }
1191
1192 EOLIAN static void
1193 _elm_slider_indicator_visible_mode_set(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd, Elm_Slider_Indicator_Visible_Mode indicator_visible_mode)
1194 {
1195    if (sd->indicator_visible_mode == indicator_visible_mode) return;
1196    sd->indicator_visible_mode = indicator_visible_mode;
1197 }
1198
1199 EOLIAN static Elm_Slider_Indicator_Visible_Mode
1200 _elm_slider_indicator_visible_mode_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd)
1201 {
1202    return sd->indicator_visible_mode;
1203 }
1204
1205 EOLIAN static Eina_Bool
1206 _elm_slider_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Slider_Data *_pd EINA_UNUSED)
1207 {
1208    return EINA_FALSE;
1209 }
1210
1211 EOLIAN static Eina_Bool
1212 _elm_slider_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Slider_Data *_pd EINA_UNUSED)
1213 {
1214    return EINA_FALSE;
1215 }
1216
1217 EOLIAN static Eina_Bool
1218 _elm_slider_elm_widget_on_focus(Eo *obj, Elm_Slider_Data *sd EINA_UNUSED, Elm_Object_Item *item EINA_UNUSED)
1219 {
1220    Eina_Bool int_ret = EINA_FALSE;
1221
1222    eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_on_focus(NULL));
1223
1224    if ((sd->indicator_visible_mode == ELM_SLIDER_INDICATOR_VISIBLE_MODE_ON_FOCUS) && elm_widget_focus_get(obj))
1225      _popup_show(obj, NULL, NULL, NULL);
1226    //TIZEN_ONLY(20150915): slider: fix slider's handler bug
1227    else if (!elm_widget_focus_get(obj))
1228    //
1229      _popup_hide(obj, NULL, NULL, NULL);
1230
1231    return int_ret;
1232 }
1233
1234 //TIZEN_ONLY(20161115): apply UI Mirroring for Tizen 3.0 UX
1235 EOLIAN static Eina_Bool
1236 _elm_slider_elm_widget_mirrored_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *_pd EINA_UNUSED)
1237 {
1238    return EINA_FALSE;
1239 }
1240 //
1241
1242 //TIZEN_ONLY(20161115): apply UI Mirroring for Tizen 3.0 UX
1243 EOLIAN static void
1244 _elm_slider_elm_widget_mirrored_set(Eo *obj EINA_UNUSED, Elm_Slider_Data *_pd EINA_UNUSED, Eina_Bool mirrored EINA_UNUSED)
1245 {
1246    return;
1247 }
1248 //
1249
1250 EOLIAN static void
1251 _elm_slider_class_constructor(Eo_Class *klass)
1252 {
1253    evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
1254 }
1255
1256 // A11Y Accessibility
1257
1258 EOLIAN static void
1259 _elm_slider_elm_interface_atspi_value_value_and_text_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd, double *value, const char **text)
1260 {
1261    if (value) *value = sd->val;
1262    if (text) *text = NULL;
1263 }
1264
1265 EOLIAN static Eina_Bool
1266 _elm_slider_elm_interface_atspi_value_value_and_text_set(Eo *obj, Elm_Slider_Data *sd, double value, const char *text EINA_UNUSED)
1267 {
1268    double oldval = sd->val;
1269
1270    if (value < sd->val_min) value = sd->val_min;
1271    if (value > sd->val_max) value = sd->val_max;
1272
1273    eo_do(obj, eo_event_callback_call(ELM_SLIDER_EVENT_SLIDER_DRAG_START, NULL));
1274    sd->val = value;
1275    _visuals_refresh(obj);
1276    sd->val = oldval;
1277    _slider_update(obj, EINA_TRUE);
1278    eo_do(obj, eo_event_callback_call(ELM_SLIDER_EVENT_SLIDER_DRAG_STOP, NULL));
1279
1280    return EINA_TRUE;
1281 }
1282
1283 EOLIAN static void
1284 _elm_slider_elm_interface_atspi_value_range_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd, double *lower, double *upper, const char **descr)
1285 {
1286    if (lower) *lower = sd->val_min;
1287    if (upper) *upper = sd->val_max;
1288    if (descr) *descr = NULL;
1289 }
1290
1291 EOLIAN static double
1292 _elm_slider_elm_interface_atspi_value_increment_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *sd)
1293 {
1294    return sd->step;
1295 }
1296
1297 EOLIAN const Elm_Atspi_Action *
1298 _elm_slider_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Slider_Data *pd EINA_UNUSED)
1299 {
1300    static Elm_Atspi_Action atspi_actions[] = {
1301           { "drag,left", "drag", "left", _key_action_drag},
1302           { "drag,right", "drag", "right", _key_action_drag},
1303           { "drag,up", "drag", "up", _key_action_drag},
1304           { "drag,down", "drag", "down", _key_action_drag},
1305           { NULL, NULL, NULL, NULL}
1306    };
1307    return &atspi_actions[0];
1308 }
1309
1310 // A11Y Accessibility - END
1311
1312 #include "elm_slider.eo.c"