1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4 
5 #define EFL_ACCESS_OBJECT_PROTECTED
6 #define ELM_LAYOUT_PROTECTED
7 #define EFL_PART_PROTECTED
8 #define EFL_UI_FORMAT_PROTECTED
9 
10 #include <Elementary.h>
11 
12 #include "elm_priv.h"
13 #include "efl_ui_progressbar_private.h"
14 #include "elm_widget_layout.h"
15 
16 #include "efl_ui_progressbar_part.eo.h"
17 #include "elm_part_helper.h"
18 
19 #define MY_CLASS EFL_UI_PROGRESSBAR_CLASS
20 #define MY_CLASS_PFX efl_ui_progressbar
21 
22 #define MY_CLASS_NAME "Efl.Ui.Progressbar"
23 
24 static const char SIG_CHANGED[] = "changed";
25 
26 #define MIN_RATIO_LVL 0.0
27 #define MAX_RATIO_LVL 1.0
28 
29 /* smart callbacks coming from elm progressbar objects (besides the
30  * ones coming from elm layout): */
31 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
32    {SIG_CHANGED, ""},
33    {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
34    {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
35    {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
36    {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
37    {NULL, NULL}
38 };
39 
40 static const Elm_Layout_Part_Alias_Description _content_aliases[] =
41 {
42    {"icon", "elm.swallow.content"},
43    {NULL, NULL}
44 };
45 
46 static Efl_Ui_Progress_Status *
_progress_status_new(const char * part_name,double val,Eina_Bool exists)47 _progress_status_new(const char *part_name, double val, Eina_Bool exists)
48 {
49    Efl_Ui_Progress_Status *ps;
50    ps = calloc(1, sizeof(Efl_Ui_Progress_Status));
51    if (!ps) return NULL;
52    ps->part_name = eina_stringshare_add(part_name);
53    ps->val = val;
54    ps->part_exists = exists;
55    return ps;
56 }
57 
58 static inline void
_progress_status_free(Efl_Ui_Progress_Status * ps)59 _progress_status_free(Efl_Ui_Progress_Status *ps)
60 {
61    eina_stringshare_del(ps->part_name);
62    free(ps);
63 }
64 
65 static inline Eina_Bool
_is_horizontal(Efl_Ui_Layout_Orientation dir)66 _is_horizontal(Efl_Ui_Layout_Orientation dir)
67 {
68    return efl_ui_layout_orientation_is_horizontal(dir, EINA_TRUE);
69 }
70 
71 static void
_units_set(Evas_Object * obj)72 _units_set(Evas_Object *obj)
73 {
74    EFL_UI_PROGRESSBAR_DATA_GET(obj, sd);
75 
76    if (sd->show_progress_label)
77      {
78         Eina_Value val;
79 
80         eina_value_setup(&val, EINA_VALUE_TYPE_DOUBLE);
81         eina_value_set(&val, sd->val);
82 
83         // Keeping this bug since the legacy code was like that.
84         if (sd->is_legacy_format_string && !sd->is_legacy_format_cb)
85           eina_value_set(&val, 100 * sd->val);
86 
87         if (!sd->format_strbuf) sd->format_strbuf = eina_strbuf_new();
88         efl_ui_format_formatted_value_get(obj, sd->format_strbuf, val);
89 
90         eina_value_flush(&val);
91 
92         if (!sd->has_status_text_part) return;
93 
94         if (elm_widget_is_legacy(obj))
95           elm_layout_text_set(obj, "elm.text.status", eina_strbuf_string_get(sd->format_strbuf));
96         else
97           elm_layout_text_set(obj, "efl.text.status", eina_strbuf_string_get(sd->format_strbuf));
98      }
99    else if (sd->has_status_text_part)
100      {
101         if (elm_widget_is_legacy(obj))
102           elm_layout_text_set(obj, "elm.text.status", NULL);
103         else
104           elm_layout_text_set(obj, "efl.text.status", NULL);
105      }
106 }
107 
108 static void
_val_set(Evas_Object * obj)109 _val_set(Evas_Object *obj)
110 {
111    double pos;
112    Efl_Ui_Progress_Status *ps;
113    Eina_List *l;
114 
115    EFL_UI_PROGRESSBAR_DATA_GET(obj, sd);
116    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
117 
118    EINA_LIST_FOREACH(sd->progress_status, l, ps)
119      {
120         if (EINA_DBL_EQ(ps->val_max, ps->val_min))
121           {
122              WRN("progressbar min and max are equal.");
123              continue;
124           }
125         if (!ps->part_exists) continue;
126         pos = (ps->val - ps->val_min)/(ps->val_max - ps->val_min);
127 
128         if (efl_ui_mirrored_get(obj) ^ efl_ui_layout_orientation_is_inverted(sd->dir))
129           pos = MAX_RATIO_LVL - pos;
130 
131         edje_object_part_drag_value_set
132               (wd->resize_obj, ps->part_name, pos, pos);
133      }
134 }
135 
136 static void
_sync_widget_theme_klass(Eo * obj,Efl_Ui_Progressbar_Data * pd)137 _sync_widget_theme_klass(Eo *obj, Efl_Ui_Progressbar_Data *pd)
138 {
139    if (efl_ui_layout_orientation_is_horizontal(pd->dir, EINA_TRUE))
140      elm_widget_theme_element_set(obj, "horizontal");
141    else
142      elm_widget_theme_element_set(obj, "vertical");
143 }
144 
145 EOLIAN static Eina_Error
_efl_ui_progressbar_efl_ui_widget_theme_apply(Eo * obj,Efl_Ui_Progressbar_Data * sd)146 _efl_ui_progressbar_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Progressbar_Data *sd)
147 {
148    Eina_Error int_ret = EFL_UI_THEME_APPLY_ERROR_GENERIC;
149    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EFL_UI_THEME_APPLY_ERROR_GENERIC);
150 
151    const char *statuspart[] =
152    {
153      "efl.text.status",
154      "elm.text.status",
155    };
156    const char *curprogresspart[] =
157    {
158      "efl.cur.progressbar",
159      "elm.cur.progressbar",
160    };
161    _sync_widget_theme_klass(obj, sd);
162 
163    int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
164    if (int_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return int_ret;
165 
166    if (elm_widget_is_legacy(obj))
167      {
168         if (sd->pulse)
169           elm_layout_signal_emit(obj, "elm,state,pulse", "elm");
170         else
171           elm_layout_signal_emit(obj, "elm,state,fraction", "elm");
172 
173         if (sd->pulse_state)
174           elm_layout_signal_emit(obj, "elm,state,pulse,start", "elm");
175 
176         if (sd->show_progress_label && (!sd->pulse))
177           elm_layout_signal_emit(obj, "elm,state,units,visible", "elm");
178      }
179    else
180      {
181         if (sd->pulse)
182           elm_layout_signal_emit(obj, "efl,state,pulse", "efl");
183         else
184           elm_layout_signal_emit(obj, "efl,state,fraction", "efl");
185 
186         if (sd->pulse_state)
187           elm_layout_signal_emit(obj, "efl,state,pulse,start", "efl");
188 
189         if (sd->show_progress_label && (!sd->pulse))
190           elm_layout_signal_emit(obj, "efl,state,units,visible", "efl");
191      }
192    sd->has_status_text_part = edje_object_part_exists(obj, statuspart[elm_widget_is_legacy(obj)]);
193    sd->has_cur_progressbar_part = edje_object_part_exists(obj, curprogresspart[elm_widget_is_legacy(obj)]);
194 
195    if (_is_horizontal(sd->dir))
196      efl_gfx_hint_size_min_set
197        (sd->spacer, EINA_SIZE2D((double)sd->size * efl_gfx_entity_scale_get(obj) *
198        elm_config_scale_get(), 1));
199    else
200      efl_gfx_hint_size_min_set
201        (sd->spacer, EINA_SIZE2D(1, (double)sd->size * efl_gfx_entity_scale_get(obj) *
202        elm_config_scale_get()));
203 
204    if (elm_widget_is_legacy(obj))
205      {
206         if (efl_ui_layout_orientation_is_inverted(sd->dir))
207           elm_layout_signal_emit(obj, "elm,state,inverted,on", "elm");
208         else
209           elm_layout_signal_emit(obj, "elm,state,inverted,off", "elm");
210      }
211    else
212      {
213         if (efl_ui_layout_orientation_is_inverted(sd->dir))
214           elm_layout_signal_emit(obj, "efl,state,inverted,on", "efl");
215         else
216           elm_layout_signal_emit(obj, "efl,state,inverted,off", "efl");
217      }
218 
219    {
220     Efl_Ui_Progress_Status *ps;
221     const Eina_List *l;
222     EINA_LIST_FOREACH(sd->progress_status, l, ps)
223       ps->part_exists = edje_object_part_exists(obj, ps->part_name);
224    }
225 
226    _units_set(obj);
227    _val_set(obj);
228 
229    edje_object_message_signal_process(wd->resize_obj);
230 
231    if (elm_widget_is_legacy(obj))
232      elm_layout_content_set(obj, "elm.swallow.bar", sd->spacer);
233    else
234      elm_layout_content_set(obj, "efl.bar", sd->spacer);
235 
236    return int_ret;
237 }
238 
239 static char *
_access_info_cb(void * data EINA_UNUSED,Evas_Object * obj)240 _access_info_cb(void *data EINA_UNUSED, Evas_Object *obj)
241 {
242    const char *txt = elm_widget_access_info_get(obj);
243 
244    if (!txt) txt = elm_layout_text_get(obj, NULL);
245    if (txt) return strdup(txt);
246 
247    return NULL;
248 }
249 
250 static char *
_access_state_cb(void * data EINA_UNUSED,Evas_Object * obj)251 _access_state_cb(void *data EINA_UNUSED, Evas_Object *obj)
252 {
253    char *ret;
254    Eina_Strbuf *buf;
255    buf = eina_strbuf_new();
256 
257    const char *txt = NULL;
258    EFL_UI_PROGRESSBAR_DATA_GET(obj, sd);
259    if (sd->format_strbuf)
260      txt = eina_strbuf_string_get(sd->format_strbuf);
261 
262    if (txt) eina_strbuf_append(buf, txt);
263 
264    if (elm_widget_disabled_get(obj))
265      eina_strbuf_append(buf, " state: disabled");
266 
267    if (eina_strbuf_length_get(buf))
268      {
269         ret = eina_strbuf_string_steal(buf);
270         eina_strbuf_free(buf);
271         return ret;
272      }
273 
274    eina_strbuf_free(buf);
275    return NULL;
276 }
277 
278 EOLIAN static void
_efl_ui_progressbar_efl_canvas_group_group_add(Eo * obj,Efl_Ui_Progressbar_Data * priv)279 _efl_ui_progressbar_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Progressbar_Data *priv)
280 {
281    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
282 
283    efl_canvas_group_add(efl_super(obj, MY_CLASS));
284 
285    efl_ui_layout_finger_size_multiplier_set(obj, 0, 0);
286 
287    priv->dir = EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL;
288    priv->val = MIN_RATIO_LVL;
289    priv->val_max = 1.0;
290 
291    efl_ui_format_string_set(obj, "%.0f%%", EFL_UI_FORMAT_STRING_TYPE_SIMPLE);
292 
293    priv->spacer = evas_object_rectangle_add(evas_object_evas_get(obj));
294    evas_object_color_set(priv->spacer, 0, 0, 0, 0);
295    evas_object_pass_events_set(priv->spacer, EINA_TRUE);
296 
297    _units_set(obj);
298    _val_set(obj);
299 
300    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
301      elm_widget_can_focus_set(obj, EINA_TRUE);
302 
303    _elm_access_object_register(obj, wd->resize_obj);
304    _elm_access_text_set
305      (_elm_access_info_get(obj), ELM_ACCESS_TYPE, E_("progressbar"));
306    _elm_access_callback_set
307      (_elm_access_info_get(obj), ELM_ACCESS_INFO, _access_info_cb, NULL);
308    _elm_access_callback_set
309      (_elm_access_info_get(obj), ELM_ACCESS_STATE, _access_state_cb, NULL);
310 }
311 
312 EOLIAN static void
_efl_ui_progressbar_efl_canvas_group_group_del(Eo * obj,Efl_Ui_Progressbar_Data * sd)313 _efl_ui_progressbar_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Progressbar_Data *sd)
314 {
315    Efl_Ui_Progress_Status *progress_obj;
316 
317    if (sd->progress_status)
318       {
319          EINA_LIST_FREE(sd->progress_status, progress_obj)
320            {
321               _progress_status_free(progress_obj);
322            }
323       }
324 
325    eina_strbuf_free(sd->format_strbuf);
326    sd->format_strbuf = NULL;
327 
328    efl_canvas_group_del(efl_super(obj, MY_CLASS));
329 }
330 
331 EOLIAN static Eo *
_efl_ui_progressbar_efl_object_constructor(Eo * obj,Efl_Ui_Progressbar_Data * _pd EINA_UNUSED)332 _efl_ui_progressbar_efl_object_constructor(Eo *obj, Efl_Ui_Progressbar_Data *_pd EINA_UNUSED)
333 {
334    if (!elm_widget_theme_klass_get(obj))
335      elm_widget_theme_klass_set(obj, "progressbar");
336 
337    obj = efl_constructor(efl_super(obj, MY_CLASS));
338    evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
339    efl_access_object_role_set(obj, EFL_ACCESS_ROLE_PROGRESS_BAR);
340    efl_ui_range_limits_set(obj, 0.0, 1.0);
341    efl_ui_progressbar_show_progress_label_set(obj, EINA_TRUE);
342    return obj;
343 }
344 
345 EOLIAN static void
_efl_ui_progressbar_efl_ui_layout_orientable_orientation_set(Eo * obj,Efl_Ui_Progressbar_Data * sd,Efl_Ui_Layout_Orientation dir)346 _efl_ui_progressbar_efl_ui_layout_orientable_orientation_set(Eo *obj, Efl_Ui_Progressbar_Data *sd, Efl_Ui_Layout_Orientation dir)
347 {
348    if (sd->dir == dir) return;
349 
350    sd->dir = dir;
351 
352    efl_ui_widget_theme_apply(obj);
353 }
354 
355 EOLIAN static Efl_Ui_Layout_Orientation
_efl_ui_progressbar_efl_ui_layout_orientable_orientation_get(const Eo * obj EINA_UNUSED,Efl_Ui_Progressbar_Data * sd)356 _efl_ui_progressbar_efl_ui_layout_orientable_orientation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Progressbar_Data *sd)
357 {
358    return sd->dir;
359 }
360 
361 static void
_progressbar_span_size_set(Eo * obj,Efl_Ui_Progressbar_Data * sd,Evas_Coord size)362 _progressbar_span_size_set(Eo *obj, Efl_Ui_Progressbar_Data *sd, Evas_Coord size)
363 {
364    if (sd->size == size) return;
365 
366    sd->size = size;
367 
368    if (_is_horizontal(sd->dir))
369      efl_gfx_hint_size_min_set
370        (sd->spacer, EINA_SIZE2D((double)sd->size * efl_gfx_entity_scale_get(obj) *
371        elm_config_scale_get(), 1));
372    else
373      efl_gfx_hint_size_min_set
374        (sd->spacer, EINA_SIZE2D(1, (double)sd->size * efl_gfx_entity_scale_get(obj) *
375        elm_config_scale_get()));
376 
377    efl_canvas_group_change(obj);
378 }
379 
380 static void
_progress_part_min_max_set(Eo * obj,Efl_Ui_Progressbar_Data * sd,const char * part_name,double min,double max)381 _progress_part_min_max_set(Eo *obj, Efl_Ui_Progressbar_Data *sd, const char *part_name, double min, double max)
382 {
383    Efl_Ui_Progress_Status *ps;
384    Eina_Bool  existing_ps = EINA_FALSE;
385    Eina_List *l;
386 
387    if (EINA_DBL_EQ(min, max))
388      {
389         ERR("min & max provided are equal.");
390         return;
391      }
392 
393    if (min > max)
394      {
395         WRN("min is greater than max.");
396      }
397 
398    if (elm_widget_is_legacy(obj))
399      {
400         if (!strcmp(part_name, "elm.cur.progressbar"))
401           {
402              sd->val_min = min;
403              sd->val_max = max;
404           }
405      }
406    else
407      {
408         if (!strcmp(part_name, "efl.cur.progressbar"))
409           {
410              sd->val_min = min;
411              sd->val_max = max;
412           }
413      }
414 
415    EINA_LIST_FOREACH(sd->progress_status, l, ps)
416      {
417         if (!strcmp(ps->part_name, part_name))
418           {
419              existing_ps = EINA_TRUE;
420              ps->val_min = min;
421              ps->val_max = max;
422              break;
423           }
424      }
425     if (!existing_ps)
426     {
427       ps = _progress_status_new(part_name, min, edje_object_part_exists(obj, part_name));
428       ps->val_min = min;
429       ps->val_max = max;
430       sd->progress_status = eina_list_append(sd->progress_status, ps);
431     }
432     _val_set(obj);
433 }
434 
435 static void
_internal_theme_mode_pulse_set(Eo * obj,Efl_Ui_Progressbar_Data * sd,Eina_Bool pulse)436 _internal_theme_mode_pulse_set(Eo *obj, Efl_Ui_Progressbar_Data *sd, Eina_Bool pulse)
437 {
438    if (elm_widget_is_legacy(obj))
439      return;
440    if (sd->pulse == pulse)
441      return;
442    sd->pulse = pulse;
443    efl_ui_widget_theme_apply(obj);
444 }
445 
446 
447 static void
_progressbar_part_value_set(Eo * obj,Efl_Ui_Progressbar_Data * sd,const char * part_name,double val)448 _progressbar_part_value_set(Eo *obj, Efl_Ui_Progressbar_Data *sd, const char *part_name, double val)
449 {
450    Efl_Ui_Progress_Status *ps;
451    Eina_Bool  existing_ps = EINA_FALSE;
452    Eina_List *l;
453    double min = 0.0, max = 0.0;
454    const char *curprogresspart[] =
455    {
456      "efl.cur.progressbar",
457      "elm.cur.progressbar",
458    };
459    Eina_Bool is_cur_progressbar = !strcmp(part_name, curprogresspart[elm_widget_is_legacy(obj)]);
460 
461    _internal_theme_mode_pulse_set(obj, sd, EINA_FALSE);
462 
463    if ((!is_cur_progressbar) || sd->has_cur_progressbar_part)
464      efl_ui_range_limits_get(efl_part(obj, part_name), &min, &max);
465 
466    if (val < min) val = min;
467    if (val > max) val = max;
468 
469    if (is_cur_progressbar)
470      sd->val = val;
471 
472    EINA_LIST_FOREACH(sd->progress_status, l, ps)
473      {
474         if (!strcmp(ps->part_name, part_name))
475           {
476              existing_ps = EINA_TRUE;
477              break;
478           }
479      }
480 
481    if (!existing_ps)
482       {
483          ps = _progress_status_new(part_name, val, edje_object_part_exists(obj, part_name));
484          ps->val_min = 0.0;
485          ps->val_max = 1.0;
486          ps->val = val;
487          sd->progress_status = eina_list_append(sd->progress_status, ps);
488       }
489    else
490       ps->val = val;
491 
492    _val_set(obj);
493    _units_set(obj);
494    if (elm_widget_is_legacy(obj))
495      efl_event_callback_legacy_call
496        (obj, EFL_UI_RANGE_EVENT_CHANGED, NULL);
497    else
498      {
499         efl_event_callback_call(obj, EFL_UI_RANGE_EVENT_CHANGED, NULL);
500         if (EINA_DBL_EQ(sd->val, min))
501           efl_event_callback_call(obj, EFL_UI_RANGE_EVENT_MIN_REACHED, NULL);
502         if (EINA_DBL_EQ(sd->val, max))
503           efl_event_callback_call(obj, EFL_UI_RANGE_EVENT_MAX_REACHED, NULL);
504      }
505 }
506 
507 static double
_progressbar_part_value_get(Efl_Ui_Progressbar_Data * sd,const char * part)508 _progressbar_part_value_get(Efl_Ui_Progressbar_Data *sd, const char* part)
509 {
510    Efl_Ui_Progress_Status *ps;
511    Eina_List *l;
512 
513    EINA_LIST_FOREACH(sd->progress_status, l, ps)
514      {
515         if (!strcmp(ps->part_name, part)) return ps->val;
516      }
517 
518    return 0.0;
519 }
520 
521 EOLIAN static void
_efl_ui_progressbar_efl_ui_range_display_range_value_set(Eo * obj,Efl_Ui_Progressbar_Data * sd,double val)522 _efl_ui_progressbar_efl_ui_range_display_range_value_set(Eo *obj, Efl_Ui_Progressbar_Data *sd, double val)
523 {
524    if (EINA_DBL_EQ(sd->val, val)) return;
525 
526    if (elm_widget_is_legacy(obj))
527      _progressbar_part_value_set(obj, sd, "elm.cur.progressbar", val);
528    else
529      {
530         if (val < sd->val_min)
531           {
532              ERR("Error, value is less than minimum");
533              return;
534           }
535         if (val > sd->val_max)
536           {
537              ERR("Error, value is greater than maximum");
538              return;
539           }
540         _progressbar_part_value_set(obj, sd, "efl.cur.progressbar", val);
541      }
542 }
543 
544 EOLIAN static double
_efl_ui_progressbar_efl_ui_range_display_range_value_get(const Eo * obj,Efl_Ui_Progressbar_Data * sd)545 _efl_ui_progressbar_efl_ui_range_display_range_value_get(const Eo *obj, Efl_Ui_Progressbar_Data *sd)
546 {
547    if (!sd->has_cur_progressbar_part) return 0.0;
548    if (elm_widget_is_legacy(obj))
549      return efl_ui_range_value_get(efl_part(obj, "elm.cur.progressbar"));
550    else
551      return efl_ui_range_value_get(efl_part(obj, "efl.cur.progressbar"));
552 }
553 
554 static void
_apply_pulse_state(Eo * obj,Efl_Ui_Progressbar_Data * sd)555 _apply_pulse_state(Eo *obj, Efl_Ui_Progressbar_Data *sd)
556 {
557    Eina_Bool legacy = elm_widget_is_legacy(obj);
558    const char *emitter = legacy ? "elm" : "efl";
559    const char *signal = legacy ? "elm,state,pulse," : "efl,state,pulse,";
560    char signal_buffer[strlen(signal) + strlen("start") + 1];
561 
562    snprintf(signal_buffer, sizeof(signal_buffer), "%s%s", signal, sd->pulse_state ? "start" : "stop");
563    elm_layout_signal_emit(obj, signal_buffer, emitter);
564 }
565 
566 EOLIAN static void
_efl_ui_progressbar_infinite_mode_set(Eo * obj,Efl_Ui_Progressbar_Data * sd,Eina_Bool state)567 _efl_ui_progressbar_infinite_mode_set(Eo *obj, Efl_Ui_Progressbar_Data *sd, Eina_Bool state)
568 {
569    state = !!state;
570 
571    if (sd->pulse_state == state)
572      return;
573 
574    sd->pulse_state = state;
575 
576    _internal_theme_mode_pulse_set(obj, sd, EINA_TRUE);
577    _apply_pulse_state(obj, sd);
578 }
579 
580 EOLIAN static Eina_Bool
_efl_ui_progressbar_infinite_mode_get(const Eo * obj EINA_UNUSED,Efl_Ui_Progressbar_Data * sd)581 _efl_ui_progressbar_infinite_mode_get(const Eo *obj EINA_UNUSED, Efl_Ui_Progressbar_Data *sd)
582 {
583    return (sd->pulse_state && sd->pulse);
584 }
585 
586 EOLIAN static void
_efl_ui_progressbar_efl_ui_range_display_range_limits_set(Eo * obj,Efl_Ui_Progressbar_Data * sd,double min,double max)587 _efl_ui_progressbar_efl_ui_range_display_range_limits_set(Eo *obj, Efl_Ui_Progressbar_Data *sd, double min, double max)
588 {
589    if (max < min)
590      {
591         ERR("Wrong params. min(%lf) is greater than max(%lf).", min, max);
592         return;
593      }
594    if (EINA_DBL_EQ(max, min))
595      {
596         ERR("min and max must have a different value");
597         return;
598      }
599   if (elm_widget_is_legacy(obj))
600     _progress_part_min_max_set(obj, sd, "elm.cur.progressbar", min, max);
601   else
602     _progress_part_min_max_set(obj, sd, "efl.cur.progressbar", min, max);
603 }
604 
605 EOLIAN static void
_efl_ui_progressbar_efl_ui_range_display_range_limits_get(const Eo * obj EINA_UNUSED,Efl_Ui_Progressbar_Data * sd,double * min,double * max)606 _efl_ui_progressbar_efl_ui_range_display_range_limits_get(const Eo *obj EINA_UNUSED, Efl_Ui_Progressbar_Data *sd, double *min, double *max)
607 {
608    if (min) *min = sd->val_min;
609    if (max) *max = sd->val_max;
610 }
611 
612 /* Efl.Part begin */
613 
614 EOLIAN static Eo *
_efl_ui_progressbar_efl_part_part_get(const Eo * obj,Efl_Ui_Progressbar_Data * sd EINA_UNUSED,const char * part)615 _efl_ui_progressbar_efl_part_part_get(const Eo *obj, Efl_Ui_Progressbar_Data *sd EINA_UNUSED, const char *part)
616 {
617    EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
618    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
619 
620    if (elm_widget_is_legacy(obj))
621      {
622         // Progress bars are dragable types
623         if (edje_object_part_drag_dir_get(wd->resize_obj, part) != (Edje_Drag_Dir)EFL_UI_DRAG_DIR_NONE)
624           return ELM_PART_IMPLEMENT(EFL_UI_PROGRESSBAR_PART_CLASS, obj, part);
625      }
626    else
627      {
628         if (eina_streq(part, "efl.cur.progressbar"))
629           return ELM_PART_IMPLEMENT(EFL_UI_PROGRESSBAR_PART_CLASS, obj, part);
630      }
631    return efl_part_get(efl_super(obj, MY_CLASS), part);
632 }
633 
634 EOLIAN static void
_efl_ui_progressbar_part_efl_ui_range_display_range_value_set(Eo * obj,void * _pd EINA_UNUSED,double val)635 _efl_ui_progressbar_part_efl_ui_range_display_range_value_set(Eo *obj, void *_pd EINA_UNUSED, double val)
636 {
637   Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
638   Efl_Ui_Progressbar_Data *sd = efl_data_scope_get(pd->obj, EFL_UI_PROGRESSBAR_CLASS);
639 
640   _progressbar_part_value_set(pd->obj, sd, pd->part, val);
641 }
642 
643 EOLIAN static double
_efl_ui_progressbar_part_efl_ui_range_display_range_value_get(const Eo * obj,void * _pd EINA_UNUSED)644 _efl_ui_progressbar_part_efl_ui_range_display_range_value_get(const Eo *obj, void *_pd EINA_UNUSED)
645 {
646    Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
647    Efl_Ui_Progressbar_Data *sd = efl_data_scope_get(pd->obj, EFL_UI_PROGRESSBAR_CLASS);
648 
649    return _progressbar_part_value_get(sd, pd->part);
650 }
651 
652 EOLIAN static void
_efl_ui_progressbar_part_efl_ui_range_display_range_limits_set(Eo * obj,void * _pd EINA_UNUSED,double min,double max)653 _efl_ui_progressbar_part_efl_ui_range_display_range_limits_set(Eo *obj, void *_pd EINA_UNUSED, double min, double max)
654 {
655   Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
656   Efl_Ui_Progressbar_Data *sd = efl_data_scope_get(pd->obj, EFL_UI_PROGRESSBAR_CLASS);
657 
658   _progress_part_min_max_set(pd->obj, sd, pd->part, min, max);
659 }
660 
661 EOLIAN static void
_efl_ui_progressbar_part_efl_ui_range_display_range_limits_get(const Eo * obj,void * _pd EINA_UNUSED,double * min,double * max)662 _efl_ui_progressbar_part_efl_ui_range_display_range_limits_get(const Eo *obj, void *_pd EINA_UNUSED, double *min, double *max)
663 {
664    Efl_Ui_Progress_Status *ps;
665    Eina_List *l;
666 
667    Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
668    Efl_Ui_Progressbar_Data *sd = efl_data_scope_get(pd->obj, EFL_UI_PROGRESSBAR_CLASS);
669 
670    EINA_LIST_FOREACH(sd->progress_status, l, ps)
671      {
672         if (!strcmp(ps->part_name, pd->part))
673           {
674              if (min) *min = ps->val_min;
675              if (max) *max = ps->val_max;
676              break;
677           }
678      }
679 }
680 
681 EOLIAN static void
_efl_ui_progressbar_show_progress_label_set(Eo * obj EINA_UNUSED,Efl_Ui_Progressbar_Data * pd,Eina_Bool show)682 _efl_ui_progressbar_show_progress_label_set(Eo *obj EINA_UNUSED, Efl_Ui_Progressbar_Data *pd, Eina_Bool show)
683 {
684    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
685    char signal_name[32];
686    const char *ns = elm_widget_is_legacy(obj) ? "elm" : "efl";
687 
688    pd->show_progress_label = show;
689 
690    snprintf(signal_name, sizeof(signal_name), "%s,state,units,%s", ns,
691             show ? "visible" : "hidden");
692    elm_layout_signal_emit(obj, signal_name, ns);
693    edje_object_message_signal_process(wd->resize_obj);
694    _units_set(obj);
695    efl_canvas_group_change(obj);
696 }
697 
698 EOLIAN static Eina_Bool
_efl_ui_progressbar_show_progress_label_get(const Eo * obj EINA_UNUSED,Efl_Ui_Progressbar_Data * pd)699 _efl_ui_progressbar_show_progress_label_get(const Eo *obj EINA_UNUSED, Efl_Ui_Progressbar_Data *pd)
700 {
701    return pd->show_progress_label;
702 }
703 
704 EOLIAN static void
_efl_ui_progressbar_efl_ui_format_apply_formatted_value(Eo * obj,Efl_Ui_Progressbar_Data * pd EINA_UNUSED)705 _efl_ui_progressbar_efl_ui_format_apply_formatted_value(Eo *obj, Efl_Ui_Progressbar_Data *pd EINA_UNUSED)
706 {
707    _units_set(obj);
708 }
709 
710 #include "efl_ui_progressbar_part.eo.c"
711 
712 /* Efl.Part end */
713 
714 /* Internal EO APIs and hidden overrides */
ELM_PART_TEXT_DEFAULT_IMPLEMENT(efl_ui_progressbar,Efl_Ui_Progressbar_Data)715 ELM_PART_TEXT_DEFAULT_IMPLEMENT(efl_ui_progressbar, Efl_Ui_Progressbar_Data)
716 ELM_PART_MARKUP_DEFAULT_IMPLEMENT(efl_ui_progressbar, Efl_Ui_Progressbar_Data)
717 ELM_PART_CONTENT_DEFAULT_IMPLEMENT(efl_ui_progressbar, Efl_Ui_Progressbar_Data)
718 
719 EFL_UI_LAYOUT_CONTENT_ALIASES_IMPLEMENT(efl_ui_progressbar)
720 
721 #define EFL_UI_PROGRESSBAR_EXTRA_OPS \
722    EFL_UI_LAYOUT_CONTENT_ALIASES_OPS(efl_ui_progressbar), \
723    EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_progressbar)
724 
725 #include "efl_ui_progressbar.eo.c"
726 
727 #include "efl_ui_progressbar_legacy_eo.h"
728 #include "efl_ui_progressbar_legacy_part.eo.h"
729 
730 #define MY_CLASS_NAME_LEGACY "elm_progressbar"
731 
732 static void
733 _efl_ui_progressbar_legacy_class_constructor(Efl_Class *klass)
734 {
735    evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
736 }
737 
738 EOLIAN static Eo *
_efl_ui_progressbar_legacy_efl_object_constructor(Eo * obj,void * pd EINA_UNUSED)739 _efl_ui_progressbar_legacy_efl_object_constructor(Eo *obj, void *pd EINA_UNUSED)
740 {
741    obj = efl_constructor(efl_super(obj, EFL_UI_PROGRESSBAR_LEGACY_CLASS));
742    efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
743    legacy_object_focus_handle(obj);
744    return obj;
745 }
746 
747 /* FIXME: replicated from elm_layout just because progressbar's icon spot
748  * is elm.swallow.content, not elm.swallow.icon. Fix that whenever we
749  * can changed the theme API */
750 EOLIAN static Eina_Error
_efl_ui_progressbar_legacy_efl_ui_widget_theme_apply(Eo * obj,void * _pd EINA_UNUSED)751 _efl_ui_progressbar_legacy_efl_ui_widget_theme_apply(Eo *obj, void *_pd EINA_UNUSED)
752 {
753    Eina_Error int_ret = EFL_UI_THEME_APPLY_ERROR_GENERIC;
754 
755    int_ret = efl_ui_widget_theme_apply(efl_super(obj, EFL_UI_PROGRESSBAR_LEGACY_CLASS));
756    if (int_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return int_ret;
757    if (efl_finalized_get(obj)) _elm_layout_legacy_icon_signal_emit(obj);
758 
759    return int_ret;
760 }
761 
762 /* FIXME: replicated from elm_layout just because progressbar's icon spot
763  * is elm.swallow.content, not elm.swallow.icon. Fix that whenever we
764  * can changed the theme API */
765 EOLIAN static Eina_Bool
_efl_ui_progressbar_legacy_efl_ui_widget_widget_sub_object_del(Eo * obj,void * _pd EINA_UNUSED,Evas_Object * sobj)766 _efl_ui_progressbar_legacy_efl_ui_widget_widget_sub_object_del(Eo *obj, void *_pd EINA_UNUSED, Evas_Object *sobj)
767 {
768    Eina_Bool int_ret = EINA_FALSE;
769 
770    int_ret = elm_widget_sub_object_del(efl_super(obj, EFL_UI_PROGRESSBAR_LEGACY_CLASS), sobj);
771    if (!int_ret) return EINA_FALSE;
772 
773    _elm_layout_legacy_icon_signal_emit(obj);
774 
775    return EINA_TRUE;
776 }
777 
778 /* FIXME: replicated from elm_layout just because progressbar's icon spot
779  * is elm.swallow.content, not elm.swallow.icon. Fix that whenever we
780  * can changed the theme API */
781 static Eina_Bool
_efl_ui_progressbar_legacy_content_set(Eo * obj,void * _pd EINA_UNUSED,const char * part,Evas_Object * content)782 _efl_ui_progressbar_legacy_content_set(Eo *obj, void *_pd EINA_UNUSED, const char *part, Evas_Object *content)
783 {
784    Eina_Bool int_ret = EINA_FALSE;
785 
786    int_ret = efl_content_set(efl_part(efl_super(obj, EFL_UI_PROGRESSBAR_LEGACY_CLASS), part), content);
787    if (!int_ret) return EINA_FALSE;
788 
789    _elm_layout_legacy_icon_signal_emit(obj);
790 
791    return EINA_TRUE;
792 }
793 
794 /* Efl.Part for legacy begin */
795 
796 static Eina_Bool
_part_is_efl_ui_progressbar_legacy_part(const Eo * obj EINA_UNUSED,const char * part)797 _part_is_efl_ui_progressbar_legacy_part(const Eo *obj EINA_UNUSED, const char *part)
798 {
799    return eina_streq(part, "elm.swallow.content");
800 }
801 
ELM_PART_OVERRIDE_PARTIAL(efl_ui_progressbar_legacy,EFL_UI_PROGRESSBAR_LEGACY,void,_part_is_efl_ui_progressbar_legacy_part)802 ELM_PART_OVERRIDE_PARTIAL(efl_ui_progressbar_legacy, EFL_UI_PROGRESSBAR_LEGACY, void, _part_is_efl_ui_progressbar_legacy_part)
803 ELM_PART_OVERRIDE_CONTENT_SET_NO_SD(efl_ui_progressbar_legacy)
804 #include "efl_ui_progressbar_legacy_part.eo.c"
805 
806 /* Efl.Part for legacy end */
807 
808 EAPI Evas_Object *
809 elm_progressbar_add(Evas_Object *parent)
810 {
811    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
812    Eo *obj = elm_legacy_add(EFL_UI_PROGRESSBAR_LEGACY_CLASS, parent);
813    elm_progressbar_unit_format_set(obj, "%.0f%%");
814 
815    return obj;
816 }
817 
818 EAPI void
elm_progressbar_pulse_set(Evas_Object * obj,Eina_Bool pulse)819 elm_progressbar_pulse_set(Evas_Object *obj, Eina_Bool pulse)
820 {
821    EFL_UI_PROGRESSBAR_DATA_GET_OR_RETURN(obj, sd);
822    pulse = !!pulse;
823    if (sd->pulse == pulse) return;
824 
825    sd->pulse = pulse;
826 
827    efl_ui_widget_theme_apply(obj);
828 }
829 
830 EAPI Eina_Bool
elm_progressbar_pulse_get(const Evas_Object * obj)831 elm_progressbar_pulse_get(const Evas_Object *obj)
832 {
833    EFL_UI_PROGRESSBAR_DATA_GET_OR_RETURN(obj, sd, EINA_FALSE);
834    return sd->pulse;
835 }
836 
837 EAPI void
elm_progressbar_pulse(Evas_Object * obj,Eina_Bool state)838 elm_progressbar_pulse(Evas_Object *obj, Eina_Bool state)
839 {
840    EFL_UI_PROGRESSBAR_DATA_GET_OR_RETURN(obj, sd);
841 
842    state = !!state;
843    if ((!sd->pulse) || (sd->pulse_state == state)) return;
844 
845    sd->pulse_state = state;
846 
847    _apply_pulse_state(obj, sd);
848 }
849 
850 EAPI Eina_Bool
elm_progressbar_is_pulsing_get(const Evas_Object * obj)851 elm_progressbar_is_pulsing_get(const Evas_Object *obj)
852 {
853    EFL_UI_PROGRESSBAR_DATA_GET_OR_RETURN(obj, sd, EINA_FALSE);
854    return (sd->pulse_state && sd->pulse);
855 }
856 
857 EAPI void
elm_progressbar_part_value_set(Evas_Object * obj,const char * part,double val)858 elm_progressbar_part_value_set(Evas_Object *obj, const char *part, double val)
859 {
860    if (EINA_DBL_EQ(efl_ui_range_value_get(efl_part(obj, part)), val)) return;
861    efl_ui_range_value_set(efl_part(obj, part), val);
862 }
863 
864 EAPI double
elm_progressbar_part_value_get(const Evas_Object * obj,const char * part)865 elm_progressbar_part_value_get(const Evas_Object *obj, const char *part)
866 {
867    return efl_ui_range_value_get(efl_part(obj, part));
868 }
869 
870 EAPI Eina_Bool
elm_progressbar_horizontal_get(const Evas_Object * obj)871 elm_progressbar_horizontal_get(const Evas_Object *obj)
872 {
873    EFL_UI_PROGRESSBAR_DATA_GET_OR_RETURN(obj, sd, EINA_FALSE);
874 
875    return _is_horizontal(sd->dir);
876 }
877 
878 EAPI void
elm_progressbar_inverted_set(Evas_Object * obj,Eina_Bool inverted)879 elm_progressbar_inverted_set(Evas_Object *obj, Eina_Bool inverted)
880 {
881    Efl_Ui_Layout_Orientation dir;
882    EFL_UI_PROGRESSBAR_DATA_GET_OR_RETURN(obj, sd);
883 
884    dir = sd->dir & EFL_UI_LAYOUT_ORIENTATION_AXIS_BITMASK;
885    if (inverted) dir |= EFL_UI_LAYOUT_ORIENTATION_INVERTED;
886 
887    efl_ui_layout_orientation_set(obj, dir);
888 }
889 
890 EAPI Eina_Bool
elm_progressbar_inverted_get(const Evas_Object * obj)891 elm_progressbar_inverted_get(const Evas_Object *obj)
892 {
893    EFL_UI_PROGRESSBAR_DATA_GET_OR_RETURN(obj, sd, EINA_FALSE);
894 
895    return efl_ui_layout_orientation_is_inverted(sd->dir);
896 }
897 
898 EAPI void
elm_progressbar_horizontal_set(Evas_Object * obj,Eina_Bool horizontal)899 elm_progressbar_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
900 {
901    Efl_Ui_Layout_Orientation dir;
902    EFL_UI_PROGRESSBAR_DATA_GET_OR_RETURN(obj, sd);
903 
904    dir = horizontal ? EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL : EFL_UI_LAYOUT_ORIENTATION_VERTICAL;
905    dir |= (sd->dir & EFL_UI_LAYOUT_ORIENTATION_INVERTED);
906 
907    efl_ui_layout_orientation_set(obj, dir);
908 }
909 
910 typedef struct
911 {
912    progressbar_func_type format_cb;
913    progressbar_freefunc_type format_free_cb;
914 } Pb_Format_Wrapper_Data;
915 
916 static Eina_Bool
_format_legacy_to_format_eo_cb(void * data,Eina_Strbuf * str,const Eina_Value value)917 _format_legacy_to_format_eo_cb(void *data, Eina_Strbuf *str, const Eina_Value value)
918 {
919    Pb_Format_Wrapper_Data *pfwd = data;
920    char *buf = NULL;
921    double val = 0;
922    const Eina_Value_Type *type = eina_value_type_get(&value);
923 
924    if (type == EINA_VALUE_TYPE_DOUBLE)
925      eina_value_get(&value, &val);
926 
927    if (pfwd->format_cb)
928      buf = pfwd->format_cb(val);
929    if (buf)
930      eina_strbuf_append(str, buf);
931    if (pfwd->format_free_cb) pfwd->format_free_cb(buf);
932 
933    return EINA_TRUE;
934 }
935 
936 static void
_format_legacy_to_format_eo_free_cb(void * data)937 _format_legacy_to_format_eo_free_cb(void *data)
938 {
939    Pb_Format_Wrapper_Data *pfwd = data;
940    free(pfwd);
941 }
942 
943 EAPI void
elm_progressbar_unit_format_function_set(Evas_Object * obj,progressbar_func_type func,progressbar_freefunc_type free_func)944 elm_progressbar_unit_format_function_set(Evas_Object *obj, progressbar_func_type func, progressbar_freefunc_type free_func)
945 {
946    EFL_UI_PROGRESSBAR_DATA_GET_OR_RETURN(obj, sd);
947    Pb_Format_Wrapper_Data *pfwd = malloc(sizeof(Pb_Format_Wrapper_Data));
948    if (!pfwd) return;
949 
950    pfwd->format_cb = func;
951    pfwd->format_free_cb = free_func;
952    sd->is_legacy_format_cb = EINA_TRUE;
953 
954    efl_ui_format_func_set(obj, pfwd, _format_legacy_to_format_eo_cb,
955                           _format_legacy_to_format_eo_free_cb);
956 }
957 
958 EAPI void
elm_progressbar_span_size_set(Evas_Object * obj,Evas_Coord size)959 elm_progressbar_span_size_set(Evas_Object *obj, Evas_Coord size)
960 {
961    EFL_UI_PROGRESSBAR_DATA_GET_OR_RETURN(obj, sd);
962    _progressbar_span_size_set(obj, sd, size);
963 }
964 
965 EAPI Evas_Coord
elm_progressbar_span_size_get(const Evas_Object * obj)966 elm_progressbar_span_size_get(const Evas_Object *obj)
967 {
968    EFL_UI_PROGRESSBAR_DATA_GET_OR_RETURN(obj, sd, 0);
969    return sd->size;
970 }
971 
972 EAPI void
elm_progressbar_unit_format_set(Evas_Object * obj,const char * units)973 elm_progressbar_unit_format_set(Evas_Object *obj, const char *units)
974 {
975    EFL_UI_PROGRESSBAR_DATA_GET_OR_RETURN(obj, sd);
976 
977    sd->is_legacy_format_string = EINA_TRUE;
978    efl_ui_format_string_set(obj, units, EFL_UI_FORMAT_STRING_TYPE_SIMPLE);
979 }
980 
981 EAPI const char *
elm_progressbar_unit_format_get(const Evas_Object * obj)982 elm_progressbar_unit_format_get(const Evas_Object *obj)
983 {
984    const char *fmt = NULL;
985    efl_ui_format_string_get(obj, &fmt, NULL);
986    return fmt;
987 }
988 
989 EAPI void
elm_progressbar_value_set(Evas_Object * obj,double val)990 elm_progressbar_value_set(Evas_Object *obj, double val)
991 {
992    efl_ui_range_value_set(obj, val);
993 }
994 
995 EAPI double
elm_progressbar_value_get(const Evas_Object * obj)996 elm_progressbar_value_get(const Evas_Object *obj)
997 {
998    return efl_ui_range_value_get(obj);
999 }
1000 
1001 #include "efl_ui_progressbar_legacy_eo.c"
1002