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