1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4 
5 #define EFL_ACCESS_OBJECT_PROTECTED
6 #define EFL_ACCESS_COMPONENT_PROTECTED
7 #define EFL_ACCESS_WIDGET_ACTION_PROTECTED
8 #define EFL_UI_FOCUS_COMPOSITION_PROTECTED
9 #define EFL_UI_FOCUS_OBJECT_PROTECTED
10 
11 #include <Elementary.h>
12 #include "elm_priv.h"
13 #include "elm_widget_colorselector.h"
14 #include "elm_widget_spinner.h"
15 
16 #define MY_CLASS ELM_COLORSELECTOR_CLASS
17 
18 #define MY_CLASS_NAME "Elm_Colorselector"
19 #define MY_CLASS_NAME_LEGACY "elm_colorselector"
20 
21 #define BASE_STEP       360.0
22 #define HUE_STEP        360.0
23 #define SAT_STEP        128.0
24 #define LIG_STEP        256.0
25 #define ALP_STEP        256.0
26 #define DEFAULT_HOR_PAD 10
27 #define DEFAULT_VER_PAD 10
28 
29 static const char SIG_CHANGED[] = "changed";
30 static const char SIG_CHANGED_USER[] = "changed,user";
31 static const char SIG_COLOR_ITEM_SELECTED[] = "color,item,selected";
32 static const char SIG_COLOR_ITEM_LONGPRESSED[] = "color,item,longpressed";
33 static const Evas_Smart_Cb_Description _smart_callbacks[] =
34 {
35    {SIG_COLOR_ITEM_SELECTED, ""},
36    {SIG_COLOR_ITEM_LONGPRESSED, ""},
37    {SIG_CHANGED, ""},
38    {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
39    {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
40    {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
41    {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
42    {SIG_CHANGED_USER, ""},
43    {NULL, NULL}
44 };
45 
46 static const Elm_Color_Name _color_name[] = {
47    {{0, 0, 0, 255},       "black"},
48    {{0, 0, 128, 255},     "navy"},
49    {{0, 0, 139, 255},     "dark blue"},
50    {{0, 0, 205, 255},     "medium blue"},
51    {{0, 0, 255, 255},     "blue"},
52    {{0, 100, 0, 255},     "dark green"},
53    {{0, 128, 0, 255},     "green"},
54    {{0, 128, 128, 255},   "teal"},
55    {{0, 139, 139, 255},   "dark cyan"},
56    {{0, 191, 255, 255},   "deep sky blue"},
57    {{0, 206, 209, 255},   "dark turquoise"},
58    {{0, 250, 154, 255},   "medium spring green"},
59    {{0, 255, 0, 255},     "lime"},
60    {{0, 255, 127, 255},   "spring green"},
61    {{0, 255, 255, 255},   "aqua"},
62    {{0, 255, 255, 255},   "cyan"},
63    {{25, 25, 112, 255},   "midnight blue"},
64    {{30, 144, 255, 255},  "dodger blue"},
65    {{32, 178, 170, 255},  "light sea green"},
66    {{34, 139, 34, 255},   "forest green"},
67    {{46, 139, 87, 255},   "sea green"},
68    {{47, 79, 79, 255},    "dark slate grey"},
69    {{50, 205, 50, 255},   "lime green"},
70    {{60, 179, 113, 255},  "medium sea green"},
71    {{64, 224, 208, 255},  "turquoise"},
72    {{65, 105, 225, 255},  "royal blue"},
73    {{70, 130, 180, 255},  "steel blue"},
74    {{72, 61, 139, 255},   "dark slate blue"},
75    {{72, 209, 204, 255},  "medium turquoise"},
76    {{75, 0, 130, 255},    "indigo"},
77    {{85, 107, 47, 255},   "dark olive green"},
78    {{95, 158, 160, 255},  "cadet blue"},
79    {{100, 149, 237, 255}, "corn flower blue"},
80    {{102, 205, 170, 255}, "medium aquamarine"},
81    {{105, 105, 105, 255}, "dim grey"},
82    {{106, 90, 205, 255},  "slate blue"},
83    {{107, 142, 35, 255},  "olive drab"},
84    {{112, 128, 144, 255}, "slate grey"},
85    {{119, 136, 153, 255}, "light slate grey"},
86    {{123, 104, 238, 255}, "medium slate blue"},
87    {{124, 252, 0, 255},   "lawn green"},
88    {{127, 255, 0, 255},   "chartreuse"},
89    {{127, 255, 212, 255}, "aquamarine"},
90    {{128, 0, 0, 255},     "maroon"},
91    {{128, 0, 128, 255},   "purple"},
92    {{128, 128, 0, 255},   "olive"},
93    {{128, 128, 128, 255}, "grey"},
94    {{135, 206, 235, 255}, "sky blue"},
95    {{135, 206, 250, 255}, "light sky blue"},
96    {{138, 43, 226, 255},  "blue violet"},
97    {{139, 0, 0, 255},     "dark red"},
98    {{139, 0, 139, 255},   "dark magenta"},
99    {{139, 69, 19, 255},   "saddle brown"},
100    {{143, 188, 143, 255}, "dark sea green"},
101    {{144, 238, 144, 255}, "light green"},
102    {{147, 112, 219, 255}, "medium purple"},
103    {{148, 0, 211, 255},   "dark violet"},
104    {{152, 251, 152, 255}, "pale green"},
105    {{153, 50, 204, 255},  "dark orchid"},
106    {{154, 205, 50, 255},  "yellow green"},
107    {{160, 82, 45, 255},   "sienna"},
108    {{165, 42, 42, 255},   "brown"},
109    {{169, 169, 169, 255}, "dark grey"},
110    {{173, 216, 230, 255}, "light blue"},
111    {{173, 255, 47, 255},  "green yellow"},
112    {{175, 238, 238, 255}, "pale turquoise"},
113    {{176, 196, 222, 255}, "light steel blue"},
114    {{176, 224, 230, 255}, "powder blue"},
115    {{178, 34, 34, 255},   "fire brick"},
116    {{184, 134, 11, 255},  "dark golden rod"},
117    {{186, 85, 211, 255},  "medium orchid"},
118    {{188, 143, 143, 255}, "rosy brown"},
119    {{189, 183, 107, 255}, "dark khaki"},
120    {{192, 192, 192, 255}, "silver"},
121    {{199, 21, 133, 255},  "medium violet red"},
122    {{205, 92, 92, 255},   "indian red"},
123    {{205, 133, 63, 255},  "peru"},
124    {{210, 105, 30, 255},  "chocolate"},
125    {{210, 180, 140, 255}, "tan"},
126    {{211, 211, 211, 255}, "light grey"},
127    {{216, 191, 216, 255}, "thistle"},
128    {{218, 112, 214, 255}, "orchid"},
129    {{218, 165, 32, 255},  "golden rod"},
130    {{219, 112, 147, 255}, "pale violet red"},
131    {{220, 20, 60, 255},   "crimson"},
132    {{220, 220, 220, 255}, "gainsboro"},
133    {{221, 160, 221, 255}, "plum"},
134    {{222, 184, 135, 255}, "burlywood"},
135    {{224, 255, 255, 255}, "light cyan"},
136    {{230, 230, 250, 255}, "lavender"},
137    {{233, 150, 122, 255}, "dark salmon"},
138    {{238, 130, 238, 255}, "violet"},
139    {{238, 232, 170, 255}, "pale golden rod"},
140    {{240, 128, 128, 255}, "light coral"},
141    {{240, 230, 140, 255}, "khaki"},
142    {{240, 248, 255, 255}, "alice blue"},
143    {{240, 255, 255, 255}, "azure"},
144    {{240, 255, 240, 255}, "honey dew"},
145    {{244, 164, 96, 255},  "sandy brown"},
146    {{245, 222, 179, 255}, "wheat"},
147    {{245, 245, 220, 255}, "beige"},
148    {{245, 245, 245, 255}, "white smoke"},
149    {{245, 255, 250, 255}, "mint cream"},
150    {{248, 248, 255, 255}, "ghost white"},
151    {{250, 235, 215, 255}, "antique white"},
152    {{250, 128, 114, 255}, "salmon"},
153    {{250, 250, 210, 255}, "light golden rod yellow"},
154    {{250, 240, 230, 255}, "linen"},
155    {{253, 245, 230, 255}, "old lace"},
156    {{255, 0, 0, 255},     "red"},
157    {{255, 0, 255, 255},   "fuchsia"},
158    {{255, 0, 255, 255},   "magenta"},
159    {{255, 20, 147, 255},  "deep pink"},
160    {{255, 69, 0, 255},    "orange red"},
161    {{255, 99, 71, 255},   "tomato"},
162    {{255, 105, 180, 255}, "hot pink"},
163    {{255, 127, 80, 255},  "coral"},
164    {{255, 140, 0, 255},   "dark orange"},
165    {{255, 160, 122, 255}, "light salmon"},
166    {{255, 165, 0, 255},   "orange"},
167    {{255, 182, 193, 255}, "light pink "},
168    {{255, 192, 203, 255}, "pink"},
169    {{255, 215, 0, 255},   "gold"},
170    {{255, 218, 185, 255}, "peach puff"},
171    {{255, 222, 173, 255}, "navajo white"},
172    {{255, 228, 181, 255}, "moccasin"},
173    {{255, 228, 196, 255}, "bisque"},
174    {{255, 228, 225, 255}, "misty rose"},
175    {{255, 235, 205, 255}, "blanched almond"},
176    {{255, 239, 213, 255}, "papaya whip"},
177    {{255, 240, 245, 255}, "lavender blush"},
178    {{255, 245, 238, 255}, "sea shell"},
179    {{255, 248, 220, 255}, "corn silk"},
180    {{255, 250, 205, 255}, "lemon chiffon"},
181    {{255, 250, 240, 255}, "floral white"},
182    {{255, 255, 0, 255},   "yellow"},
183    {{255, 255, 224, 255}, "light yellow"},
184    {{255, 255, 240, 255}, "ivory"},
185    {{255, 250, 250, 255}, "snow"},
186    {{255, 255, 255, 255}, "white"}
187 };
188 
189 static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
190 static Eina_Bool _key_action_activate(Evas_Object *obj, const char *params);
191 
192 static const Elm_Action key_actions[] = {
193    {"move", _key_action_move},
194    {"activate", _key_action_activate},
195    {NULL, NULL}
196 };
197 
198 static void
_flush_color_children(Eo * obj,Elm_Colorselector_Data * pd)199 _flush_color_children(Eo *obj, Elm_Colorselector_Data *pd)
200 {
201    Eina_List *items = NULL;
202 
203    if (pd->mode == ELM_COLORSELECTOR_ALL) {
204       items = eina_list_append(items, pd->picker);
205       items = eina_list_merge(items, eina_list_clone(pd->items));
206       items = eina_list_append(items, pd->col_bars_area);
207    } else if (pd->mode == ELM_COLORSELECTOR_BOTH) {
208       items = eina_list_merge(items, eina_list_clone(pd->items));
209       items = eina_list_append(items, pd->col_bars_area);
210    } else if (pd->mode == ELM_COLORSELECTOR_COMPONENTS) {
211       items = eina_list_append(items, pd->col_bars_area);
212    } else if (pd->mode == ELM_COLORSELECTOR_PALETTE) {
213       items = eina_list_merge(items, eina_list_clone(pd->items));
214    } else if (pd->mode == ELM_COLORSELECTOR_PICKER) {
215       items = eina_list_append(items, pd->picker);
216    }
217    efl_ui_focus_composition_elements_set(obj, items);
218 }
219 
220 enum Palette_Box_Direction
221 {
222    PALETTE_BOX_UP,
223    PALETTE_BOX_DOWN
224 };
225 
226 static const char *
_get_color_name(unsigned int R,unsigned int G,unsigned int B,unsigned int A)227 _get_color_name(unsigned int R, unsigned int G, unsigned int B, unsigned int A)
228 {
229    unsigned int low, mid, high;
230    unsigned int r, g, b;
231 
232    if (A != 255) return NULL;
233    low = 0;
234    high = EINA_C_ARRAY_LENGTH(_color_name) - 1;
235    while (low <= high)
236      {
237         mid = (low + high) / 2;
238 
239         r = _color_name[mid].color.r;
240         g = _color_name[mid].color.g;
241         b = _color_name[mid].color.b;
242 
243         if (r == R && g == G && B == b)
244           return _color_name[mid].name;
245 
246         if ((r < R) || ((r == R) && (g < G)) || ((r == R) && (g == G) && b < B))
247           low = mid + 1;
248         else
249           high = mid - 1;
250       }
251     return NULL;
252 }
253 
254 static void
_items_del(Elm_Colorselector_Data * sd)255 _items_del(Elm_Colorselector_Data *sd)
256 {
257    Elm_Object_Item *item;
258 
259    if (!sd->items) return;
260 
261    EINA_LIST_FREE(sd->items, item)
262      {
263         efl_del (item);
264      }
265 
266    sd->items = NULL;
267    sd->selected = NULL;
268    sd->focus_items = NULL;
269 }
270 
271 static void
_color_with_saturation(Elm_Colorselector_Data * sd,int * sr,int * sg,int * sb)272 _color_with_saturation(Elm_Colorselector_Data *sd, int *sr, int *sg, int *sb)
273 {
274    if (sd->er > 127)
275      *sr = 127 + (int)((double)(sd->er - 127) * sd->s);
276    else
277      *sr = 127 - (int)((double)(127 - sd->er) * sd->s);
278 
279    if (sd->eg > 127)
280      *sg = 127 + (int)((double)(sd->eg - 127) * sd->s);
281    else
282      *sg = 127 - (int)((double)(127 - sd->eg) * sd->s);
283 
284    if (sd->eb > 127)
285      *sb = 127 + (int)((double)(sd->eb - 127) * sd->s);
286    else
287      *sb = 127 - (int)((double)(127 - sd->eb) * sd->s);
288 }
289 
290 static void
_color_with_lightness(Elm_Colorselector_Data * sd,int * lr,int * lg,int * lb)291 _color_with_lightness(Elm_Colorselector_Data *sd, int *lr, int *lg, int *lb)
292 {
293    if (sd->l > 0.5)
294      {
295         *lr = sd->er + (int)((double)(255 - sd->er) * (sd->l - 0.5) * 2.0);
296         *lg = sd->eg + (int)((double)(255 - sd->eg) * (sd->l - 0.5) * 2.0);
297         *lb = sd->eb + (int)((double)(255 - sd->eb) * (sd->l - 0.5) * 2.0);
298      }
299    else if (sd->l < 0.5)
300      {
301         *lr = (double)sd->er * sd->l * 2.0;
302         *lg = (double)sd->eg * sd->l * 2.0;
303         *lb = (double)sd->eb * sd->l * 2.0;
304      }
305    else
306      {
307         *lr = sd->er;
308         *lg = sd->eg;
309         *lb = sd->eb;
310      }
311 }
312 
313 static void
_color_picker_init(Elm_Colorselector_Data * sd)314 _color_picker_init(Elm_Colorselector_Data *sd)
315 {
316    unsigned int *pixels;
317    unsigned int *copy;
318    int color;
319    int x, y, w, h;
320 
321    if (!evas_object_data_get(sd->spinners[0], "_changed"))
322      {
323         elm_spinner_value_set(sd->spinners[0], sd->r);
324      }
325    if (!evas_object_data_get(sd->spinners[1], "_changed"))
326      {
327         elm_spinner_value_set(sd->spinners[1], sd->g);
328      }
329    if (!evas_object_data_get(sd->spinners[2], "_changed"))
330      {
331         elm_spinner_value_set(sd->spinners[2], sd->b);
332      }
333    if (!evas_object_data_get(sd->spinners[3], "_changed"))
334      {
335         elm_spinner_value_set(sd->spinners[3], sd->a);
336      }
337 
338    color = (sd->a << 24) |
339      (((sd->r * sd->a) / 255) << 16) |
340      (((sd->g * sd->a) / 255) << 8) |
341      (((sd->b * sd->a) / 255));
342 
343    if (sd->a == 255)
344      evas_object_image_alpha_set(sd->picker_display, EINA_FALSE);
345    else
346      evas_object_image_alpha_set(sd->picker_display, EINA_TRUE);
347 
348    pixels = evas_object_image_data_get(sd->picker_display, EINA_TRUE);
349    copy = pixels;
350    for (y = 0; y < 17; y++)
351      {
352         for (x = 0; x < 17; x++)
353           {
354              *(pixels++) = color;
355           }
356      }
357    evas_object_image_data_set(sd->picker_display, copy);
358    evas_object_geometry_get(sd->picker_display, NULL, NULL, &w, &h);
359    evas_object_image_data_update_add(sd->picker_display, 0, 0, w, h);
360 }
361 
362 static void
_rgb_to_hsl(Elm_Colorselector_Data * sd)363 _rgb_to_hsl(Elm_Colorselector_Data *sd)
364 {
365    double r2, g2, b2;
366    double v, m, vm;
367    double r, g, b;
368 
369    r = sd->r;
370    g = sd->g;
371    b = sd->b;
372 
373    r /= 255.0;
374    g /= 255.0;
375    b /= 255.0;
376 
377    v = (r > g) ? r : g;
378    v = (v > b) ? v : b;
379 
380    m = (r < g) ? r : g;
381    m = (m < b) ? m : b;
382 
383    sd->h = 0.0;
384    sd->s = 0.0;
385    sd->l = 0.0;
386 
387    sd->l = (m + v) / 2.0;
388 
389    if (sd->l <= 0.0) return;
390 
391    vm = v - m;
392    sd->s = vm;
393 
394    if (sd->s > 0.0) sd->s /= (sd->l <= 0.5) ? (v + m) : (2.0 - v - m);
395    else return;
396 
397    r2 = (v - r) / vm;
398    g2 = (v - g) / vm;
399    b2 = (v - b) / vm;
400 
401    if (EINA_DBL_EQ(r, v)) sd->h = (EINA_DBL_EQ(g, m) ? 5.0 + b2 : 1.0 - g2);
402    else if (EINA_DBL_EQ(g, v))
403      sd->h = (EINA_DBL_EQ(b, m) ? 1.0 + r2 : 3.0 - b2);
404    else sd->h = (EINA_DBL_EQ(r, m) ? 3.0 + g2 : 5.0 - r2);
405 
406    sd->h *= 60.0;
407 }
408 
409 static Eina_Bool
_hsl_to_rgb(Elm_Colorselector_Data * sd)410 _hsl_to_rgb(Elm_Colorselector_Data *sd)
411 {
412    double sv, vsf, f, p, q, t, v;
413    double r = 0, g = 0, b = 0;
414    double _h, _s, _l;
415    int i = 0;
416 
417    _h = sd->h;
418    _s = sd->s;
419    _l = sd->l;
420 
421    if (EINA_DBL_EQ(_s, 0.0)) r = g = b = _l;
422    else
423      {
424         if (EINA_DBL_EQ(_h, 360.0)) _h = 0.0;
425         _h /= 60.0;
426 
427         v = (_l <= 0.5) ? (_l * (1.0 + _s)) : (_l + _s - (_l * _s));
428         p = _l + _l - v;
429 
430         if (EINA_DBL_NONZERO(v)) sv = (v - p) / v;
431         else sv = 0;
432 
433         i = (int)_h;
434         f = _h - i;
435 
436         vsf = v * sv * f;
437 
438         t = p + vsf;
439         q = v - vsf;
440 
441         switch (i)
442           {
443            case 0:
444              r = v;
445              g = t;
446              b = p;
447              break;
448 
449            case 1:
450              r = q;
451              g = v;
452              b = p;
453              break;
454 
455            case 2:
456              r = p;
457              g = v;
458              b = t;
459              break;
460 
461            case 3:
462              r = p;
463              g = q;
464              b = v;
465              break;
466 
467            case 4:
468              r = t;
469              g = p;
470              b = v;
471              break;
472 
473            case 5:
474              r = v;
475              g = p;
476              b = q;
477              break;
478           }
479      }
480    i = (int)(r * 255.0);
481    f = (r * 255.0) - i;
482    r = (f <= 0.5) ? i : (i + 1);
483 
484    i = (int)(g * 255.0);
485    f = (g * 255.0) - i;
486    g = (f <= 0.5) ? i : (i + 1);
487 
488    i = (int)(b * 255.0);
489    f = (b * 255.0) - i;
490    b = (f <= 0.5) ? i : (i + 1);
491 
492    if (EINA_DBL_EQ(sd->r, r) && EINA_DBL_EQ(sd->g, g) && EINA_DBL_EQ(sd->b, b)) return EINA_FALSE;
493 
494    sd->r = r;
495    sd->g = g;
496    sd->b = b;
497 
498    return EINA_TRUE;
499 }
500 
501 static void
_update_ergb(Elm_Colorselector_Data * sd,double x)502 _update_ergb(Elm_Colorselector_Data *sd, double x)
503 {
504    double one_six = 1.0 / 6.0;
505 
506    if (x < one_six)
507      {
508         sd->er = 255;
509         sd->eg = (255.0 * x * 6.0);
510         sd->eb = 0;
511      }
512    else if (x < 2 * one_six)
513      {
514         sd->er = 255 - (int)(255.0 * (x - one_six) * 6.0);
515         sd->eg = 255;
516         sd->eb = 0;
517      }
518    else if (x < 3 * one_six)
519      {
520         sd->er = 0;
521         sd->eg = 255;
522         sd->eb = (int)(255.0 * (x - (2.0 * one_six)) * 6.0);
523      }
524    else if (x < 4 * one_six)
525      {
526         sd->er = 0;
527         sd->eg = 255 - (int)(255.0 * (x - (3.0 * one_six)) * 6.0);
528         sd->eb = 255;
529      }
530    else if (x < 5 * one_six)
531      {
532         sd->er = 255.0 * (x - (4.0 * one_six)) * 6.0;
533         sd->eg = 0;
534         sd->eb = 255;
535      }
536    else
537      {
538         sd->er = 255;
539         sd->eg = 0;
540         sd->eb = 255 - (int)(255.0 * (x - (5.0 * one_six)) * 6.0);
541      }
542 }
543 
544 static void
_update_colorbars(Elm_Colorselector_Data * sd)545 _update_colorbars(Elm_Colorselector_Data *sd)
546 {
547    int r, g, b;
548    evas_object_color_set
549      (sd->cb_data[0]->arrow, sd->er, sd->eg, sd->eb, 255);
550    evas_object_color_set
551      (sd->cb_data[1]->bg_rect, sd->er, sd->eg, sd->eb, 255);
552    evas_object_color_set
553      (sd->cb_data[2]->bg_rect, sd->er, sd->eg, sd->eb, 255);
554    evas_object_color_set
555      (sd->cb_data[3]->bar, sd->er, sd->eg, sd->eb, 255);
556 
557    _color_with_saturation(sd, &r, &g, &b);
558    evas_object_color_set(sd->cb_data[1]->arrow, r, g, b, 255);
559 
560    _color_with_lightness(sd, &r, &g, &b);
561    evas_object_color_set(sd->cb_data[2]->arrow, r, g, b, 255);
562 
563    evas_object_color_set(sd->cb_data[3]->arrow,
564                          (sd->er * sd->a) / 255,
565                          (sd->eg * sd->a) / 255,
566                          (sd->eb * sd->a) / 255,
567                          sd->a);
568 }
569 
570 static void
_update_hsla_from_colorbar(Evas_Object * obj,Color_Type type,double x)571 _update_hsla_from_colorbar(Evas_Object *obj, Color_Type type, double x)
572 {
573    int ta;
574 
575    ELM_COLORSELECTOR_DATA_GET(obj, sd);
576 
577    switch (type)
578      {
579       case HUE:
580         sd->h = 360.0 * x;
581         _update_ergb(sd, x);
582         break;
583 
584       case SATURATION:
585         sd->s = 1.0 - x;
586         break;
587 
588       case LIGHTNESS:
589         sd->l = x;
590         break;
591 
592       case ALPHA:
593         ta = 255.0 * x;
594         if (ta == sd->a) return;
595         sd->a = ta;
596         break;
597 
598       default:
599         return;
600      }
601 
602    if (type != ALPHA && !_hsl_to_rgb(sd)) return;
603 
604    _update_colorbars(sd);
605    if ((sd->mode == ELM_COLORSELECTOR_ALL) || (sd->mode == ELM_COLORSELECTOR_PICKER))
606      _color_picker_init(sd);
607    evas_object_smart_callback_call(obj, "changed", NULL);
608    evas_object_smart_callback_call(obj, "changed,user", NULL);
609 }
610 
611 static void
_colors_set(Evas_Object * obj,int r,int g,int b,int a,Eina_Bool mode_change)612 _colors_set(Evas_Object *obj,
613             int r,
614             int g,
615             int b,
616             int a,
617             Eina_Bool mode_change)
618 {
619    double x, y;
620 
621    ELM_COLORSELECTOR_DATA_GET(obj, sd);
622 
623    if ((sd->r == r) && (sd->g == g) && (sd->b == b) && (sd->a == a) && !mode_change)
624      return;
625 
626    sd->r = r;
627    sd->g = g;
628    sd->b = b;
629    sd->a = a;
630 
631    if ((sd->mode == ELM_COLORSELECTOR_ALL) || (sd->mode == ELM_COLORSELECTOR_COMPONENTS)
632       || (sd->mode == ELM_COLORSELECTOR_BOTH))
633      {
634         _rgb_to_hsl(sd);
635 
636         edje_object_part_drag_value_get
637           (sd->cb_data[0]->colorbar, "elm.arrow", &x, &y);
638         x = sd->h / 360.0;
639         edje_object_part_drag_value_set
640           (sd->cb_data[0]->colorbar, "elm.arrow", x, y);
641         _update_ergb(sd, x);
642 
643         edje_object_part_drag_value_get
644           (sd->cb_data[1]->colorbar, "elm.arrow", &x, &y);
645         x = 1.0 - sd->s;
646         edje_object_part_drag_value_set
647           (sd->cb_data[1]->colorbar, "elm.arrow", x, y);
648 
649         edje_object_part_drag_value_get
650           (sd->cb_data[2]->colorbar, "elm.arrow", &x, &y);
651         x = sd->l;
652         edje_object_part_drag_value_set(sd->cb_data[2]->colorbar, "elm.arrow", x, y);
653 
654         edje_object_part_drag_value_get
655           (sd->cb_data[3]->colorbar, "elm.arrow", &x, &y);
656         x = sd->a / 255.0;
657         edje_object_part_drag_value_set
658           (sd->cb_data[3]->colorbar, "elm.arrow", x, y);
659 
660         _update_colorbars(sd);
661      }
662    if ((sd->mode == ELM_COLORSELECTOR_ALL) || (sd->mode == ELM_COLORSELECTOR_PICKER))
663      _color_picker_init(sd);
664    if (!mode_change)
665      evas_object_smart_callback_call(obj, "changed", NULL);
666 }
667 
668 static void
_unselect_selected_item(Elm_Colorselector_Data * sd)669 _unselect_selected_item(Elm_Colorselector_Data *sd)
670 {
671    Eo *eo_temp_item;
672 
673    if (sd->selected)
674      {
675         eo_temp_item = eina_list_data_get(sd->selected);
676         elm_obj_color_item_selected_set(eo_temp_item, EINA_FALSE);
677      }
678 }
679 
680 static void
_spinner_changed_cb(void * data,const Efl_Event * event)681 _spinner_changed_cb(void *data, const Efl_Event *event)
682 {
683    Elm_Colorselector_Data *sd = data;
684    Evas_Object *parent;
685    int i, v;
686 
687    _unselect_selected_item(sd);
688    for (i = 0; i < 4 && sd->spinners[i] != event->object; i++);
689 
690    parent = evas_object_data_get(event->object, "parent");
691    v = elm_spinner_value_get(event->object);
692    evas_object_data_set(event->object, "_changed", event->object);
693 
694    switch (i)
695      {
696       case 0:
697          _colors_set(parent, v, sd->g, sd->b, sd->a, EINA_FALSE);
698          break;
699       case 1:
700          _colors_set(parent, sd->r, v, sd->b, sd->a, EINA_FALSE);
701          break;
702       case 2:
703          _colors_set(parent, sd->r, sd->g, v, sd->a, EINA_FALSE);
704          break;
705       case 3:
706          _colors_set(parent, sd->r, sd->g, sd->b, v, EINA_FALSE);
707          break;
708      }
709    evas_object_data_del(event->object, "_changed");
710    evas_object_smart_callback_call(parent, "changed,user", NULL);
711 }
712 
713 #ifdef HAVE_ELEMENTARY_X
714 static Eina_Bool _mouse_grab_pixels(void *data, int type EINA_UNUSED, void *event EINA_UNUSED);
715 static Eina_Bool _key_up_cb(void *data, int type EINA_UNUSED, void *event EINA_UNUSED);
716 static Eina_Bool _mouse_up_cb(void *data, int type EINA_UNUSED, void *event EINA_UNUSED);
717 
718 static Ecore_X_Window
_x11_elm_widget_xwin_get(const Evas_Object * obj)719 _x11_elm_widget_xwin_get(const Evas_Object *obj)
720 {
721    Evas_Object *top;
722    Ecore_X_Window xwin = 0;
723 
724    top = elm_widget_top_get(obj);
725    if (!top) top = elm_widget_top_get(elm_widget_parent_widget_get(obj));
726    if (top) xwin = elm_win_xwindow_get(top);
727    if (!xwin)
728      {
729         Ecore_Evas *ee;
730         Evas *evas = evas_object_evas_get(obj);
731         if (!evas) return 0;
732         ee = ecore_evas_ecore_evas_get(evas);
733         if (!ee) return 0;
734         xwin = _elm_ee_xwin_get(ee);
735      }
736    return xwin;
737 }
738 
739 static void
_start_grab_pick_cb(void * data,Evas_Object * obj,void * event_info EINA_UNUSED)740 _start_grab_pick_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
741 {
742    Evas_Object *o = data;
743 
744    ELM_COLORSELECTOR_DATA_GET(o, sd);
745 
746    elm_object_disabled_set(obj, EINA_TRUE);
747 
748    sd->grab.mouse_motion = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _mouse_grab_pixels, o);
749    sd->grab.key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_up_cb, o);
750    sd->grab.mouse_up = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _mouse_up_cb, o);
751 
752    ecore_x_keyboard_grab(sd->grab.xroot);
753    ecore_x_pointer_grab(sd->grab.xroot);
754 }
755 
756 static Eina_Bool
_key_up_cb(void * data,int type EINA_UNUSED,void * event EINA_UNUSED)757 _key_up_cb(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
758 {
759    Evas_Object *o = data;
760 
761    /* key => cancel */
762    ELM_COLORSELECTOR_DATA_GET(o, sd);
763 
764    elm_object_disabled_set(sd->button, EINA_FALSE);
765    ecore_x_keyboard_ungrab();
766    ecore_x_pointer_ungrab();
767    ELM_SAFE_FREE(sd->grab.mouse_motion, ecore_event_handler_del);
768    ELM_SAFE_FREE(sd->grab.key_up, ecore_event_handler_del);
769    ELM_SAFE_FREE(sd->grab.mouse_up, ecore_event_handler_del);
770 
771    return EINA_TRUE;
772 }
773 
774 static Eina_Bool
_mouse_up_cb(void * data,int type EINA_UNUSED,void * event EINA_UNUSED)775 _mouse_up_cb(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
776 {
777    const unsigned int *pixels;
778    Evas_Object *o = data;
779    int r, g, b;
780 
781    /* mouse up => check it */
782    ELM_COLORSELECTOR_DATA_GET(o, sd);
783 
784    elm_object_disabled_set(sd->button, EINA_FALSE);
785    ecore_x_keyboard_ungrab();
786    ecore_x_pointer_ungrab();
787    ELM_SAFE_FREE(sd->grab.mouse_motion, ecore_event_handler_del);
788    ELM_SAFE_FREE(sd->grab.key_up, ecore_event_handler_del);
789    ELM_SAFE_FREE(sd->grab.mouse_up, ecore_event_handler_del);
790 
791    pixels = evas_object_image_data_get(sd->picker_display, EINA_FALSE);
792    r = (pixels[17 * 8 + 8] >> 16) & 0xFF;
793    g = (pixels[17 * 8 + 8] >> 8) & 0xFF;
794    b = pixels[17 * 8 + 8] & 0xFF;
795 
796    _unselect_selected_item(sd);
797    _colors_set(o, r, g, b, 0xFF, EINA_FALSE);
798    evas_object_smart_callback_call(o, "changed,user", NULL);
799 
800    return EINA_TRUE;
801 }
802 
803 static Eina_Bool
_mouse_grab_pixels(void * data,int type EINA_UNUSED,void * event EINA_UNUSED)804 _mouse_grab_pixels(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
805 {
806    Evas_Object *obj = data;
807    Ecore_X_Visual visual;
808    Ecore_X_Display *display;
809    Ecore_X_Screen *scr;
810    Ecore_X_Image *img;
811    Ecore_X_Window xwin;
812    int *src;
813    int bpl = 0, rows = 0, bpp = 0;
814    int x, y, w, h;
815 
816    ELM_COLORSELECTOR_DATA_GET(obj, sd);
817 
818    if (sd->grab.in) return EINA_TRUE;
819 
820    xwin = _x11_elm_widget_xwin_get(obj);
821    sd->grab.xroot = ecore_x_window_root_get(xwin);
822    ecore_x_pointer_xy_get(sd->grab.xroot, &x, &y);
823 
824    if (x < 8) x += 8;
825    if (y < 8) y += 8;
826 
827    if (sd->grab.x == x && sd->grab.y == y) return EINA_TRUE;
828    sd->grab.x = x;
829    sd->grab.y = y;
830 
831    evas_object_image_alpha_set(sd->picker_display, EINA_FALSE);
832 
833    display = ecore_x_display_get();
834    scr = ecore_x_default_screen_get();
835    visual = ecore_x_default_visual_get(display, scr);
836    img = ecore_x_image_new(17, 17, visual, ecore_x_window_depth_get(sd->grab.xroot));
837 
838    if (!img)
839      {
840         ERR("Failed to get an image from ecore_x_image_new()");
841         return EINA_TRUE;
842      }
843 
844    ecore_x_image_get(img, sd->grab.xroot, x - 8, y - 8, 0, 0, 17, 17);
845    src = ecore_x_image_data_get(img, &bpl, &rows, &bpp);
846    if (!ecore_x_image_is_argb32_get(img))
847      {
848         Ecore_X_Colormap colormap;
849         unsigned int *pixels;
850 
851         colormap = ecore_x_default_colormap_get(display, scr);
852         pixels = evas_object_image_data_get(sd->picker_display, EINA_TRUE);
853         ecore_x_image_to_argb_convert(src, bpp, bpl, colormap, visual,
854                                       0, 0, 17, 17,
855                                       pixels, (17 * sizeof(int)), 0, 0);
856      }
857    else
858      {
859         evas_object_image_data_copy_set(sd->picker_display, src);
860      }
861 
862    ecore_x_image_free(img);
863 
864    evas_object_geometry_get(sd->picker_display, NULL, NULL, &w, &h);
865    evas_object_image_data_update_add(sd->picker_display, 0, 0, w, h);
866 
867    return EINA_TRUE;
868 }
869 #endif
870 
871 static void
_mouse_in_canvas(void * data,Evas * e EINA_UNUSED,void * event_info EINA_UNUSED)872 _mouse_in_canvas(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
873 {
874    Evas_Object *obj = data;
875    ELM_COLORSELECTOR_DATA_GET(obj, sd);
876 
877    sd->grab.in = EINA_TRUE;
878 }
879 
880 static void
_mouse_out_canvas(void * data,Evas * e EINA_UNUSED,void * event_info EINA_UNUSED)881 _mouse_out_canvas(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
882 {
883    Evas_Object *obj = data;
884    ELM_COLORSELECTOR_DATA_GET(obj, sd);
885 
886    sd->grab.in = EINA_FALSE;
887 }
888 
889 static void
_create_colorpicker(Evas_Object * obj)890 _create_colorpicker(Evas_Object *obj)
891 {
892    Evas_Object *ed;
893    Evas_Object *im;
894    Evas_Object *spinner;
895    Evas_Object *bx;
896    Eina_Stringshare *style;
897    int i;
898 
899    ELM_COLORSELECTOR_DATA_GET(obj, sd);
900    if (sd->picker) return;
901 #ifdef HAVE_ELEMENTARY_X
902    Ecore_X_Window xwin;
903 
904    xwin = _x11_elm_widget_xwin_get(obj);
905    if (xwin)
906      {
907         sd->grab.xroot = ecore_x_window_root_get(xwin);
908         ecore_x_input_raw_select(sd->grab.xroot);
909      }
910 #endif
911    /* setup the color picker */
912    sd->picker = elm_layout_add(obj);
913    if (!elm_layout_theme_set(sd->picker, "colorselector", "picker/base", elm_widget_style_get(obj)))
914      CRI("Failed to set layout!");
915 
916    evas_object_size_hint_weight_set(sd->picker, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
917    evas_object_size_hint_align_set(sd->picker, EVAS_HINT_FILL, EVAS_HINT_FILL);
918    elm_widget_sub_object_add(obj, sd->picker);
919 
920    bx = elm_box_add(sd->picker);
921    evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
922    evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, EVAS_HINT_FILL);
923    elm_layout_content_set(sd->picker, "elm.swallow.picker", bx);
924    evas_object_show(bx);
925 
926    ed = edje_object_add(evas_object_evas_get(sd->picker));
927    elm_widget_theme_object_set(obj, ed, "colorselector", "picker", elm_widget_style_get(obj));
928    evas_object_size_hint_weight_set(ed, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
929    evas_object_size_hint_align_set(ed, EVAS_HINT_FILL, EVAS_HINT_FILL);
930    elm_box_pack_end(bx, ed);
931    evas_object_show(ed);
932 
933    style = eina_stringshare_printf("colorselector/%s", elm_widget_style_get(obj));
934 #ifdef HAVE_ELEMENTARY_X
935    if (xwin)
936      {
937         sd->button = elm_button_add(sd->picker);
938         elm_object_style_set(sd->button, style);
939         elm_object_text_set(sd->button, E_("Pick a color"));
940         evas_object_smart_callback_add(sd->button, "clicked", _start_grab_pick_cb, obj);
941         elm_box_pack_end(bx, sd->button);
942         evas_object_show(sd->button);
943      }
944 #endif
945 
946    im = evas_object_image_add(evas_object_evas_get(sd->picker));
947    evas_object_size_hint_aspect_set(im, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
948    evas_object_image_smooth_scale_set(im, EINA_FALSE);
949    evas_object_image_colorspace_set(im, EVAS_COLORSPACE_ARGB8888);
950    evas_object_image_size_set(im, 17, 17);
951    evas_object_image_alpha_set(im, EINA_TRUE);
952    evas_object_image_filled_set(im, EINA_TRUE);
953    edje_object_part_swallow(ed, "elm.picker", im);
954    elm_widget_sub_object_add(obj, im);
955 
956    sd->picker_display = im;
957 
958    for (i = 0; i < 4; i++)
959      {
960         spinner = elm_spinner_add(sd->picker);
961         elm_object_style_set(spinner, style);
962         evas_object_data_set(spinner, "parent", obj);
963         efl_event_callback_add
964               (spinner, ELM_SPINNER_EVENT_CHANGED, _spinner_changed_cb, sd);
965         elm_spinner_editable_set(spinner, EINA_TRUE);
966         elm_spinner_interval_set(spinner, 0.1);
967         elm_spinner_min_max_set(spinner, 0, 255);
968         evas_object_size_hint_weight_set(spinner, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
969         evas_object_size_hint_align_set(spinner, EVAS_HINT_FILL, EVAS_HINT_FILL);
970         evas_object_show(spinner);
971 
972         sd->spinners[i] = spinner;
973      }
974 
975    elm_layout_content_set(sd->picker, "elm.swallow.red", sd->spinners[0]);
976    elm_layout_text_set(sd->picker, "elm.label.red", E_("R:"));
977    elm_layout_content_set(sd->picker, "elm.swallow.green", sd->spinners[1]);
978    elm_layout_text_set(sd->picker, "elm.label.green", E_("G:"));
979    elm_layout_content_set(sd->picker, "elm.swallow.blue", sd->spinners[2]);
980    elm_layout_text_set(sd->picker, "elm.label.blue", E_("B:"));
981    elm_layout_content_set(sd->picker, "elm.swallow.alpha", sd->spinners[3]);
982    elm_layout_text_set(sd->picker, "elm.label.alpha", E_("A:"));
983 
984    evas_event_callback_add(evas_object_evas_get(obj), EVAS_CALLBACK_CANVAS_FOCUS_IN, _mouse_in_canvas, obj);
985    evas_event_callback_add(evas_object_evas_get(obj), EVAS_CALLBACK_CANVAS_FOCUS_OUT, _mouse_out_canvas, obj);
986 
987    eina_stringshare_del(style);
988 
989    _color_picker_init(sd);
990 }
991 
992 static void
_arrow_cb(void * data,Evas_Object * obj,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)993 _arrow_cb(void *data,
994           Evas_Object *obj,
995           const char *emission EINA_UNUSED,
996           const char *source EINA_UNUSED)
997 {
998    Color_Bar_Data *cb_data = data;
999    double x, y;
1000    ELM_COLORSELECTOR_DATA_GET(cb_data->parent, sd);
1001 
1002    _unselect_selected_item(sd);
1003    edje_object_part_drag_value_get(obj, "elm.arrow", &x, &y);
1004    _update_hsla_from_colorbar(cb_data->parent, cb_data->color_type, x);
1005 }
1006 
1007 static void
_colorbar_arrow_set(Color_Bar_Data * cb_data,int mouse_x)1008 _colorbar_arrow_set(Color_Bar_Data *cb_data, int mouse_x)
1009 {
1010    Evas_Coord x, y, w, h;
1011    double arrow_x = 0, arrow_y;
1012    ELM_COLORSELECTOR_DATA_GET(cb_data->parent, sd);
1013 
1014    evas_object_geometry_get(cb_data->bar, &x, &y, &w, &h);
1015    edje_object_part_drag_value_get
1016      (cb_data->colorbar, "elm.arrow", &arrow_x, &arrow_y);
1017 
1018    if (w > 0) arrow_x = (double)(mouse_x - x) / (double)w;
1019    if (arrow_x > 1) arrow_x = 1;
1020    else if (arrow_x < 0) arrow_x = 0;
1021    else _unselect_selected_item(sd);
1022 
1023    edje_object_part_drag_value_set
1024      (cb_data->colorbar, "elm.arrow", arrow_x, arrow_y);
1025 
1026    _update_hsla_from_colorbar(cb_data->parent, cb_data->color_type, arrow_x);
1027    sd->sel_color_type = cb_data->color_type;
1028    sd->focused = ELM_COLORSELECTOR_COMPONENTS;
1029 }
1030 
1031 static void
_colorbar_down_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1032 _colorbar_down_cb(void *data,
1033                   Evas *e EINA_UNUSED,
1034                   Evas_Object *obj EINA_UNUSED,
1035                   void *event_info)
1036 {
1037    Evas_Event_Mouse_Down *ev = event_info;
1038    Color_Bar_Data *cb_data = data;
1039 
1040    _colorbar_arrow_set(cb_data, ev->canvas.x);
1041 }
1042 
1043 static void
_colorbar_move_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1044 _colorbar_move_cb(void *data,
1045                   Evas *e EINA_UNUSED,
1046                   Evas_Object *obj EINA_UNUSED,
1047                   void *event_info)
1048 {
1049    Evas_Event_Mouse_Move *ev = event_info;
1050    Color_Bar_Data *cb_data = data;
1051 
1052    if (!ev->buttons)
1053      return;
1054 
1055    _colorbar_arrow_set(cb_data, ev->cur.canvas.x);
1056 }
1057 
1058 static void
_button_clicked_cb(void * data,const Efl_Event * event)1059 _button_clicked_cb(void *data, const Efl_Event *event)
1060 {
1061    Color_Bar_Data *cb_data = data;
1062    double x, y, step;
1063    ELM_COLORSELECTOR_DATA_GET(cb_data->parent, sd);
1064 
1065    if (event->object == cb_data->rbt) step = 1.0;
1066    else step = -1.0;
1067 
1068    edje_object_part_drag_value_get(cb_data->colorbar, "elm.arrow", &x, &y);
1069 
1070    switch (cb_data->color_type)
1071      {
1072       case HUE:
1073         x += step / HUE_STEP;
1074         break;
1075 
1076       case SATURATION:
1077         x += step / SAT_STEP;
1078         break;
1079 
1080       case LIGHTNESS:
1081         x += step / LIG_STEP;
1082         break;
1083 
1084       case ALPHA:
1085         x += step / ALP_STEP;
1086         break;
1087 
1088       default:
1089         break;
1090      }
1091 
1092    if (x > 1.0) x = 1.0;
1093    else if (x < 0.0) x = 0.0;
1094    else _unselect_selected_item(sd);
1095 
1096    edje_object_part_drag_value_set(cb_data->colorbar, "elm.arrow", x, y);
1097    _update_hsla_from_colorbar(cb_data->parent, cb_data->color_type, x);
1098    sd->sel_color_type = cb_data->color_type;
1099    sd->focused = ELM_COLORSELECTOR_COMPONENTS;
1100 }
1101 
1102 static void
_button_repeat_cb(void * data,Evas_Object * object,void * event_info EINA_UNUSED)1103 _button_repeat_cb(void *data, Evas_Object *object, void *event_info EINA_UNUSED)
1104 {
1105    Color_Bar_Data *cb_data = data;
1106    double x, y, step;
1107 
1108    if (object == cb_data->rbt) step = 1.0 / BASE_STEP;
1109    else step = -1.0 / BASE_STEP;
1110 
1111    edje_object_part_drag_value_get(cb_data->colorbar, "elm.arrow", &x, &y);
1112    x += step;
1113 
1114    if (x > 1.0) x = 1.0;
1115    else if (x < 0.0) x = 0.0;
1116 
1117    edje_object_part_drag_value_set(cb_data->colorbar, "elm.arrow", x, y);
1118    _update_hsla_from_colorbar(cb_data->parent, cb_data->color_type, x);
1119 }
1120 
1121 static void
_access_colorbar_register(Evas_Object * obj,Color_Bar_Data * cd,const char * part)1122 _access_colorbar_register(Evas_Object *obj,
1123                           Color_Bar_Data *cd,
1124                           const char* part)
1125 {
1126    Evas_Object *ao;
1127    Elm_Access_Info *ai;
1128    const char* colorbar_type = NULL;
1129 
1130    ao = _elm_access_edje_object_part_object_register(obj, cd->colorbar, part);
1131    ai = _elm_access_info_get(ao);
1132 
1133    switch (cd->color_type)
1134      {
1135       case HUE:
1136         colorbar_type = "hue color bar";
1137         break;
1138 
1139       case SATURATION:
1140         colorbar_type = "saturation color bar";
1141         break;
1142 
1143       case LIGHTNESS:
1144         colorbar_type = "lightness color bar";
1145         break;
1146 
1147       case ALPHA:
1148         colorbar_type = "alpha color bar";
1149         break;
1150 
1151       default:
1152         break;
1153      }
1154 
1155    _elm_access_text_set(ai, ELM_ACCESS_TYPE, colorbar_type);
1156 
1157    // this will be used in focus_next();
1158    cd->access_obj = ao;
1159 }
1160 
1161 static void
_color_bars_add(Evas_Object * obj)1162 _color_bars_add(Evas_Object *obj)
1163 {
1164    char colorbar_name[128];
1165    char colorbar_s[128];
1166    char buf[1024];
1167    int i = 0;
1168    Evas *e;
1169 
1170    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1171 
1172    e = evas_object_evas_get(obj);
1173 
1174    for (i = 0; i < 4; i++)
1175      {
1176         if (!sd->cb_data[i]) sd->cb_data[i] = ELM_NEW(Color_Bar_Data);
1177         sd->cb_data[i]->parent = obj;
1178 
1179         switch (i)
1180           {
1181            case 0:
1182              sd->cb_data[i]->color_type = HUE;
1183              break;
1184 
1185            case 1:
1186              sd->cb_data[i]->color_type = SATURATION;
1187              break;
1188 
1189            case 2:
1190              sd->cb_data[i]->color_type = LIGHTNESS;
1191              break;
1192 
1193            case 3:
1194              sd->cb_data[i]->color_type = ALPHA;
1195              break;
1196           }
1197 
1198         /* load colorbar area */
1199         if (!sd->cb_data[i]->colorbar) sd->cb_data[i]->colorbar = edje_object_add(e);
1200         elm_widget_theme_object_set
1201           (obj, sd->cb_data[i]->colorbar, "colorselector", "base",
1202           elm_widget_style_get(obj));
1203         snprintf(colorbar_name, sizeof(colorbar_name), "colorbar_%d", i);
1204         snprintf(colorbar_s, sizeof(colorbar_s), "elm.colorbar_%d", i);
1205         edje_object_signal_callback_add
1206           (sd->cb_data[i]->colorbar, "drag", "*", _arrow_cb, sd->cb_data[i]);
1207         elm_object_part_content_set(sd->col_bars_area,
1208                                     colorbar_s, sd->cb_data[i]->colorbar);
1209 
1210         /* load colorbar image */
1211         if (!sd->cb_data[i]->bar) sd->cb_data[i]->bar = edje_object_add(e);
1212         snprintf(buf, sizeof(buf), "%s/%s", colorbar_name,
1213                  elm_widget_style_get(obj));
1214         elm_widget_theme_object_set
1215           (obj, sd->cb_data[i]->bar, "colorselector", "image", buf);
1216         edje_object_part_swallow
1217           (sd->cb_data[i]->colorbar, "elm.bar", sd->cb_data[i]->bar);
1218         elm_widget_sub_object_add(sd->col_bars_area, sd->cb_data[i]->bar);
1219 
1220         /* provide expanded touch area */
1221         if (!sd->cb_data[i]->touch_area) sd->cb_data[i]->touch_area = evas_object_rectangle_add(e);
1222         evas_object_color_set(sd->cb_data[i]->touch_area, 0, 0, 0, 0);
1223         edje_object_part_swallow
1224           (sd->cb_data[i]->colorbar, "elm.arrow_bg",
1225           sd->cb_data[i]->touch_area);
1226         evas_object_event_callback_add
1227           (sd->cb_data[i]->touch_area, EVAS_CALLBACK_MOUSE_DOWN, _colorbar_down_cb, sd->cb_data[i]);
1228         evas_object_event_callback_add
1229           (sd->cb_data[i]->touch_area, EVAS_CALLBACK_MOUSE_MOVE, _colorbar_move_cb, sd->cb_data[i]);
1230         elm_widget_sub_object_add(sd->col_bars_area, sd->cb_data[i]->touch_area);
1231 
1232         // ACCESS
1233         if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
1234            _access_colorbar_register(obj, sd->cb_data[i], "elm.arrow_bg_access");
1235 
1236         /* load background rectangle of the colorbar. used for
1237            changing color of the opacity bar */
1238         if ((i == 1) || (i == 2))
1239           {
1240              if (!sd->cb_data[i]->bg_rect) sd->cb_data[i]->bg_rect = evas_object_rectangle_add(e);
1241              evas_object_color_set
1242                (sd->cb_data[i]->bg_rect, sd->er, sd->eg, sd->eb, 255);
1243              edje_object_part_swallow
1244                (sd->cb_data[i]->colorbar, "elm.bar_bg",
1245                sd->cb_data[i]->bg_rect);
1246 
1247              elm_widget_sub_object_add(sd->col_bars_area, sd->cb_data[i]->bg_rect);
1248           }
1249         if (i == 3)
1250           {
1251              if (!sd->cb_data[i]->bg_rect) sd->cb_data[i]->bg_rect = edje_object_add(e);
1252              snprintf(buf, sizeof(buf), "%s/%s", colorbar_name,
1253                       elm_widget_style_get(obj));
1254              elm_widget_theme_object_set
1255                (obj, sd->cb_data[i]->bg_rect, "colorselector", "bg_image",
1256                buf);
1257              edje_object_part_swallow
1258                (sd->cb_data[i]->colorbar, "elm.bar_bg",
1259                sd->cb_data[i]->bg_rect);
1260              elm_widget_sub_object_add(obj, sd->cb_data[i]->bg_rect);
1261              evas_object_color_set
1262                (sd->cb_data[i]->bar, sd->er, sd->eg, sd->eb, 255);
1263           }
1264 
1265         /* load arrow image, pointing the colorbar */
1266         if (!sd->cb_data[i]->arrow) sd->cb_data[i]->arrow = edje_object_add(e);
1267         elm_widget_theme_object_set
1268           (obj, sd->cb_data[i]->arrow, "colorselector", "arrow",
1269           elm_widget_style_get(obj));
1270         edje_object_part_swallow
1271           (sd->cb_data[i]->colorbar, "elm.arrow_icon",
1272           sd->cb_data[i]->arrow);
1273         elm_widget_sub_object_add(sd->col_bars_area, sd->cb_data[i]->arrow);
1274 
1275         if (i == 2)
1276           evas_object_color_set(sd->cb_data[i]->arrow, 0, 0, 0, 255);
1277         else
1278           evas_object_color_set
1279             (sd->cb_data[i]->arrow, sd->er, sd->eg, sd->eb, 255);
1280 
1281         /* load left button */
1282         if (!sd->cb_data[i]->lbt) sd->cb_data[i]->lbt = elm_button_add(sd->col_bars_area);
1283         snprintf(buf, sizeof(buf), "colorselector/left/%s",
1284                  elm_widget_style_get(obj));
1285         elm_object_style_set(sd->cb_data[i]->lbt, buf);
1286         elm_widget_sub_object_add(sd->col_bars_area, sd->cb_data[i]->lbt);
1287         edje_object_part_swallow
1288           (sd->cb_data[i]->colorbar, "elm.l_button", sd->cb_data[i]->lbt);
1289         efl_event_callback_add
1290           (sd->cb_data[i]->lbt, EFL_INPUT_EVENT_CLICKED, _button_clicked_cb, sd->cb_data[i]);
1291         elm_button_autorepeat_set(sd->cb_data[i]->lbt, EINA_TRUE);
1292         elm_button_autorepeat_initial_timeout_set
1293           (sd->cb_data[i]->lbt, _elm_config->longpress_timeout);
1294         elm_button_autorepeat_gap_timeout_set
1295           (sd->cb_data[i]->lbt, (1.0 / _elm_config->fps));
1296         evas_object_smart_callback_add
1297           (sd->cb_data[i]->lbt, "repeated", _button_repeat_cb, sd->cb_data[i]);
1298 
1299         /* load right button */
1300         if (!sd->cb_data[i]->rbt) sd->cb_data[i]->rbt = elm_button_add(sd->col_bars_area);
1301         snprintf(buf, sizeof(buf), "colorselector/right/%s",
1302                  elm_widget_style_get(obj));
1303         elm_object_style_set(sd->cb_data[i]->rbt, buf);
1304         elm_widget_sub_object_add(sd->col_bars_area, sd->cb_data[i]->rbt);
1305         edje_object_part_swallow
1306           (sd->cb_data[i]->colorbar, "elm.r_button", sd->cb_data[i]->rbt);
1307         efl_event_callback_add
1308           (sd->cb_data[i]->rbt, EFL_INPUT_EVENT_CLICKED, _button_clicked_cb, sd->cb_data[i]);
1309         elm_button_autorepeat_set(sd->cb_data[i]->rbt, EINA_TRUE);
1310         elm_button_autorepeat_initial_timeout_set
1311           (sd->cb_data[i]->rbt, _elm_config->longpress_timeout);
1312         elm_button_autorepeat_gap_timeout_set
1313           (sd->cb_data[i]->rbt, (1.0 / _elm_config->fps));
1314         evas_object_smart_callback_add
1315           (sd->cb_data[i]->lbt, "repeated", _button_repeat_cb, sd->cb_data[i]);
1316      }
1317 }
1318 
1319 EOLIAN static Eina_Error
_elm_colorselector_efl_ui_widget_theme_apply(Eo * obj,Elm_Colorselector_Data * sd)1320 _elm_colorselector_efl_ui_widget_theme_apply(Eo *obj, Elm_Colorselector_Data *sd)
1321 {
1322    int i;
1323    Eina_List *elist;
1324    Elm_Object_Item *eo_item;
1325    const char *hpadstr, *vpadstr;
1326    Eina_Stringshare *style;
1327    unsigned int h_pad = DEFAULT_HOR_PAD;
1328    unsigned int v_pad = DEFAULT_VER_PAD;
1329 
1330    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EFL_UI_THEME_APPLY_ERROR_GENERIC);
1331    Eina_Error int_ret = EFL_UI_THEME_APPLY_ERROR_GENERIC;
1332 
1333    int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
1334    if (int_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return int_ret;
1335 
1336    /* none of the below objects are created before finalize */
1337    if (!efl_finalized_get(obj)) return int_ret;
1338 
1339    if ((sd->mode == ELM_COLORSELECTOR_PALETTE) ||
1340        (sd->mode == ELM_COLORSELECTOR_ALL) ||
1341        (sd->mode == ELM_COLORSELECTOR_BOTH))
1342      {
1343         double scale;
1344 
1345         hpadstr = edje_object_data_get
1346             (wd->resize_obj, "horizontal_pad");
1347         if (hpadstr) h_pad = atoi(hpadstr);
1348         vpadstr = edje_object_data_get
1349             (wd->resize_obj, "vertical_pad");
1350         if (vpadstr) v_pad = atoi(vpadstr);
1351         scale = efl_gfx_entity_scale_get(obj) * elm_config_scale_get() / edje_object_base_scale_get(wd->resize_obj);
1352         elm_box_padding_set(sd->palette_box, h_pad * scale, v_pad * scale);
1353 
1354         EINA_LIST_FOREACH(sd->items, elist, eo_item)
1355           {
1356              ELM_COLOR_ITEM_DATA_GET(eo_item, item);
1357              if (!elm_layout_theme_set
1358                  (VIEW(item), "colorselector", "item", elm_widget_style_get(obj)))
1359                CRI("Failed to set layout!");
1360 
1361              elm_widget_theme_object_set
1362                (obj, item->color_obj, "colorselector", "item/color",
1363                elm_widget_style_get(obj));
1364           }
1365      }
1366 
1367    if ((sd->mode == ELM_COLORSELECTOR_COMPONENTS) ||
1368        (sd->mode == ELM_COLORSELECTOR_ALL) ||
1369        (sd->mode == ELM_COLORSELECTOR_BOTH))
1370      {
1371         if (!sd->col_bars_area) return EINA_FALSE;
1372 
1373         if (!elm_layout_theme_set(sd->col_bars_area, "colorselector", "bg",
1374                                   elm_widget_style_get(obj)))
1375           CRI("Failed to set layout!");
1376 
1377         for (i = 0; i < 4; i++)
1378           {
1379              if (sd->cb_data[i])
1380                {
1381                   ELM_SAFE_FREE(sd->cb_data[i]->colorbar, evas_object_del);
1382                   ELM_SAFE_FREE(sd->cb_data[i]->bar, evas_object_del);
1383                   ELM_SAFE_FREE(sd->cb_data[i]->lbt, evas_object_del);
1384                   ELM_SAFE_FREE(sd->cb_data[i]->rbt, evas_object_del);
1385                   if (i != 0)
1386                     ELM_SAFE_FREE(sd->cb_data[i]->bg_rect, evas_object_del);
1387                   ELM_SAFE_FREE(sd->cb_data[i]->arrow, evas_object_del);
1388                   ELM_SAFE_FREE(sd->cb_data[i]->touch_area, evas_object_del);
1389                }
1390           }
1391         _color_bars_add(obj);
1392         elm_colorselector_color_set(obj, sd->r, sd->g, sd->b, sd->a);
1393      }
1394 
1395    if ((sd->mode == ELM_COLORSELECTOR_PICKER) ||
1396        (sd->mode == ELM_COLORSELECTOR_ALL))
1397      {
1398         if (!elm_layout_theme_set(sd->picker, "colorselector", "picker/base",
1399                                   elm_widget_style_get(obj)))
1400           CRI("Failed to set layout!");
1401 
1402         style = eina_stringshare_printf("colorselector/%s", elm_widget_style_get(obj));
1403      #ifdef HAVE_ELEMENTARY_X
1404         elm_object_style_set(sd->button, style);
1405      #endif
1406         for (i = 0; i < 4; i++)
1407           elm_object_style_set(sd->spinners[i], style);
1408         eina_stringshare_del(style);
1409      }
1410 
1411    elm_layout_sizing_eval(obj);
1412    return int_ret;
1413 }
1414 
1415 static void
_sub_obj_size_hints_set(Evas_Object * sobj,int timesw,int timesh)1416 _sub_obj_size_hints_set(Evas_Object *sobj,
1417                         int timesw,
1418                         int timesh)
1419 {
1420    Evas_Coord minw = -1, minh = -1;
1421 
1422    elm_coords_finger_size_adjust(timesw, &minw, timesh, &minh);
1423    if (!efl_isa(sobj, EFL_CANVAS_LAYOUT_CLASS)) return;
1424    edje_object_size_min_restricted_calc(sobj, &minw, &minh, minw, minh);
1425    evas_object_size_hint_min_set(sobj, minw, minh);
1426    evas_object_size_hint_max_set(sobj, -1, -1);
1427 }
1428 
1429 static void
_item_sizing_eval(Elm_Color_Item_Data * item)1430 _item_sizing_eval(Elm_Color_Item_Data *item)
1431 {
1432    Evas_Coord minw = -1, minh = -1;
1433    Evas_Object *edje;
1434 
1435    if (!item) return;
1436    edje = elm_layout_edje_get(VIEW(item));
1437    if (!edje) return;
1438 
1439    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1440    edje_object_size_min_restricted_calc(edje, &minw, &minh, minw, minh);
1441    evas_object_size_hint_min_set(VIEW(item), minw, minh);
1442 }
1443 
1444 /* fix size hints of color palette items, so that the box gets it */
1445 static void
_palette_sizing_eval(Elm_Colorselector_Data * sd)1446 _palette_sizing_eval(Elm_Colorselector_Data *sd)
1447 {
1448    Eina_List *elist;
1449    Elm_Object_Item *eo_item;
1450 
1451    EINA_LIST_FOREACH(sd->items, elist, eo_item)
1452      {
1453         ELM_COLOR_ITEM_DATA_GET(eo_item, item);
1454         _item_sizing_eval(item);
1455      }
1456 }
1457 
1458 static void
_component_sizing_eval(Elm_Colorselector_Data * sd)1459 _component_sizing_eval(Elm_Colorselector_Data *sd)
1460 {
1461    Evas_Coord minw = -1, minh = -1;
1462    int i;
1463 
1464    for (i = 0; i < 4; i++)
1465      {
1466         if (sd->cb_data[i])
1467           {
1468              if (sd->cb_data[i]->bg_rect)
1469                _sub_obj_size_hints_set(sd->cb_data[i]->bg_rect, 1, 1);
1470 
1471              _sub_obj_size_hints_set(sd->cb_data[i]->bar, 1, 1);
1472              _sub_obj_size_hints_set(sd->cb_data[i]->rbt, 1, 1);
1473              _sub_obj_size_hints_set(sd->cb_data[i]->lbt, 1, 1);
1474              _sub_obj_size_hints_set(sd->cb_data[i]->colorbar, 4, 1);
1475           }
1476      }
1477 
1478    edje_object_size_min_restricted_calc
1479      (elm_layout_edje_get(sd->col_bars_area), &minw, &minh, minw, minh);
1480    evas_object_size_hint_min_set(sd->col_bars_area, minw, minh);
1481 }
1482 
1483 static void
_full_sizing_eval(Elm_Colorselector_Data * sd)1484 _full_sizing_eval(Elm_Colorselector_Data *sd)
1485 {
1486    _palette_sizing_eval(sd);
1487    _component_sizing_eval(sd);
1488 }
1489 
1490 static void
_picker_sizing_eval(Evas_Object * obj)1491 _picker_sizing_eval(Evas_Object *obj)
1492 {
1493    Evas_Coord minw = -1, minh = -1;
1494 
1495    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1496 
1497    evas_object_size_hint_combined_min_get(sd->picker, &minw, &minh);
1498    evas_object_size_hint_min_set(obj, minw, minh);
1499 }
1500 
1501 EOLIAN static void
_elm_colorselector_efl_canvas_group_group_calculate(Eo * obj,Elm_Colorselector_Data * sd)1502 _elm_colorselector_efl_canvas_group_group_calculate(Eo *obj, Elm_Colorselector_Data *sd)
1503 {
1504    Evas_Coord minw = -1, minh = -1;
1505 
1506    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1507    if (!efl_finalized_get(obj)) return; //not constructed yet
1508 
1509    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1510 
1511    switch (sd->mode)
1512      {
1513       case ELM_COLORSELECTOR_PALETTE:
1514         _palette_sizing_eval(sd);
1515         break;
1516 
1517       case ELM_COLORSELECTOR_COMPONENTS:
1518         _component_sizing_eval(sd);
1519         break;
1520 
1521       case ELM_COLORSELECTOR_BOTH:
1522         _full_sizing_eval(sd);
1523         break;
1524 
1525       case ELM_COLORSELECTOR_PICKER:
1526         _picker_sizing_eval(obj);
1527         break;
1528 
1529       case ELM_COLORSELECTOR_ALL:
1530         _full_sizing_eval(sd);
1531         break;
1532 
1533       default:
1534         return;
1535      }
1536 
1537    efl_canvas_group_calculate(sd->palette_box);
1538    edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
1539    evas_object_size_hint_min_set(obj, minw, minh);
1540 }
1541 
1542 static void
_on_resize(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)1543 _on_resize(void *data EINA_UNUSED, Evas *e EINA_UNUSED,
1544            Evas_Object *obj, void *event_info EINA_UNUSED)
1545 {
1546    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1547 
1548    if ((sd->mode == ELM_COLORSELECTOR_PALETTE) ||
1549        (sd->mode == ELM_COLORSELECTOR_BOTH))
1550      {
1551         Evas_Coord w = 0, h = 0, minw = -1;
1552 
1553         evas_object_size_hint_combined_min_get(obj, &minw, NULL);
1554         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1555         if ((w != sd->_w) && (w < minw))
1556           elm_layout_sizing_eval(obj);
1557         sd->_w = w;
1558         sd->_h = h;
1559      }
1560 }
1561 
1562 static Eina_Bool
_on_color_long_press(void * data)1563 _on_color_long_press(void *data)
1564 {
1565    Elm_Color_Item_Data *item = (Elm_Color_Item_Data *)data;
1566 
1567    ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd);
1568 
1569    sd->longpress_timer = NULL;
1570 
1571    evas_object_smart_callback_call(WIDGET(item), "color,item,longpressed", EO_OBJ(item));
1572 
1573    return ECORE_CALLBACK_CANCEL;
1574 }
1575 
1576 static void
_on_color_pressed(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1577 _on_color_pressed(void *data,
1578                   Evas *e EINA_UNUSED,
1579                   Evas_Object *obj EINA_UNUSED,
1580                   void *event_info)
1581 {
1582    Elm_Color_Item_Data *item = (Elm_Color_Item_Data *)data;
1583    Evas_Event_Mouse_Down *ev = event_info;
1584 
1585    if (!item) return;
1586 
1587    ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd);
1588 
1589    if (ev->button != 1) return;
1590 
1591    ecore_timer_del(sd->longpress_timer);
1592    sd->longpress_timer = ecore_timer_add
1593        (_elm_config->longpress_timeout, _on_color_long_press, data);
1594 
1595    item->still_in = EINA_TRUE;
1596 }
1597 
1598 static void
_on_color_moved(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1599 _on_color_moved(void *data,
1600                 Evas *e EINA_UNUSED,
1601                 Evas_Object *obj EINA_UNUSED,
1602                 void *event_info)
1603 {
1604    Elm_Color_Item_Data *item = (Elm_Color_Item_Data *)data;
1605    Evas_Event_Mouse_Move *ev = event_info;
1606    Evas_Coord x = 0, y = 0, w = 0, h = 0;
1607 
1608    if (!item) return;
1609 
1610    ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd);
1611 
1612    evas_object_geometry_get(item->color_obj, &x, &y, &w, &h);
1613 
1614    if (ELM_RECTS_POINT_OUT(x, y, w, h, ev->cur.canvas.x, ev->cur.canvas.y))
1615      {
1616         ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
1617         item->still_in = EINA_FALSE;
1618      }
1619 }
1620 
1621 static void
_on_color_released(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1622 _on_color_released(void *data,
1623                    Evas *e EINA_UNUSED,
1624                    Evas_Object *obj EINA_UNUSED,
1625                    void *event_info)
1626 {
1627    Elm_Color_Item_Data *item = (Elm_Color_Item_Data *)data;
1628    Eina_List *l;
1629    Elm_Object_Item *eo_temp_item;
1630    Evas_Event_Mouse_Down *ev = event_info;
1631 
1632    if (!item) return;
1633 
1634    ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd);
1635 
1636    if (ev->button != 1) return;
1637    ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
1638 
1639    if ((ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) || !item->still_in)
1640      return;
1641 
1642    elm_object_signal_emit(VIEW(item), "elm,state,selected", "elm");
1643    elm_colorselector_color_set(WIDGET(item), item->color->r, item->color->g,
1644                                item->color->b, item->color->a);
1645    evas_object_smart_callback_call(WIDGET(item), "color,item,selected", EO_OBJ(item));
1646 
1647    eo_temp_item = eina_list_data_get(sd->selected);
1648    if (eo_temp_item && (eo_temp_item != EO_OBJ(item)))
1649      {
1650         ELM_COLOR_ITEM_DATA_GET(eo_temp_item, temp_item);
1651         elm_object_signal_emit(VIEW(temp_item), "elm,state,unselected", "elm");
1652      }
1653 
1654    EINA_LIST_FOREACH(sd->items, l, eo_temp_item)
1655      {
1656         ELM_COLOR_ITEM_DATA_GET(eo_temp_item, temp_item);
1657         if (item == temp_item) sd->selected = l;
1658      }
1659    sd->focused = ELM_COLORSELECTOR_PALETTE;
1660 }
1661 
1662 static char *
_access_info_cb(void * data,Evas_Object * obj EINA_UNUSED)1663 _access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
1664 {
1665    char *ret;
1666    Eina_Strbuf *buf;
1667    const char *color_name = NULL;
1668    int r = 0, g = 0, b = 0, a = 0;
1669 
1670    Elm_Color_Item_Data *it = data;
1671    ELM_COLORSELECTOR_ITEM_CHECK_OR_RETURN(it, NULL);
1672 
1673    elm_colorselector_palette_item_color_get(EO_OBJ(it), &r, &g, &b, &a);
1674 
1675    buf = eina_strbuf_new();
1676    color_name = _get_color_name(r, g, b, a);
1677    if (color_name)
1678      eina_strbuf_append_printf(buf, "%s", color_name);
1679    else
1680      eina_strbuf_append_printf(buf, "red %d, green %d, blue %d, alpha %d", r, g, b, a);
1681    ret = eina_strbuf_string_steal(buf);
1682    eina_strbuf_free(buf);
1683    return ret;
1684 }
1685 
1686 static void
_access_activate_cb(void * data EINA_UNUSED,Evas_Object * part_obj EINA_UNUSED,Elm_Object_Item * eo_item)1687 _access_activate_cb(void *data EINA_UNUSED,
1688                     Evas_Object *part_obj EINA_UNUSED,
1689                     Elm_Object_Item *eo_item)
1690 {
1691    ELM_COLOR_ITEM_DATA_GET(eo_item, item);
1692    elm_object_item_signal_emit(eo_item, "elm,state,selected", "elm");
1693    _on_color_released(item, NULL, NULL, NULL);
1694 }
1695 
1696 EOLIAN static Evas_Object*
_elm_color_item_elm_widget_item_access_register(Eo * eo_it,Elm_Color_Item_Data * it)1697 _elm_color_item_elm_widget_item_access_register(Eo *eo_it, Elm_Color_Item_Data *it)
1698 {
1699    Elm_Access_Info *ai;
1700 
1701    Evas_Object *res;
1702    res = elm_wdg_item_access_register(efl_super(eo_it, ELM_COLOR_ITEM_CLASS));
1703 
1704    ai = _elm_access_info_get(it->base->access_obj);
1705 
1706    _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("color selector palette item"));
1707    _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1708    _elm_access_activate_callback_set(ai, _access_activate_cb,  EO_OBJ(it));
1709 
1710    return res;
1711 }
1712 
1713 static void
_item_resize(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)1714 _item_resize(void *data EINA_UNUSED,
1715              Evas *e EINA_UNUSED,
1716              Evas_Object *obj,
1717              void *event_info EINA_UNUSED)
1718 {
1719    elm_layout_sizing_eval(obj);
1720 }
1721 
1722 EOLIAN static void
_elm_color_item_elm_widget_item_signal_emit(Eo * eo_it EINA_UNUSED,Elm_Color_Item_Data * it,const char * emission,const char * source)1723 _elm_color_item_elm_widget_item_signal_emit(Eo *eo_it EINA_UNUSED,
1724                                             Elm_Color_Item_Data *it,
1725                                             const char *emission,
1726                                             const char *source)
1727 {
1728    elm_object_signal_emit(VIEW(it), emission, source);
1729 }
1730 
1731 static Eina_Bool
_item_action_activate(Evas_Object * obj,const char * params EINA_UNUSED)1732 _item_action_activate(Evas_Object *obj, const char *params EINA_UNUSED)
1733 {
1734    Eina_List *l;
1735    ELM_COLOR_ITEM_DATA_GET(obj, item);
1736    ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd);
1737 
1738    elm_object_signal_emit(VIEW(item), "elm,state,selected", "elm");
1739    if (_elm_config->atspi_mode)
1740      efl_access_state_changed_signal_emit(obj,
1741                                                               EFL_ACCESS_STATE_TYPE_CHECKED,
1742                                                               EINA_TRUE);
1743    elm_colorselector_color_set(WIDGET(item), item->color->r, item->color->g,
1744                                item->color->b, item->color->a);
1745    evas_object_smart_callback_call(WIDGET(item), SIG_COLOR_ITEM_SELECTED,
1746                                    EO_OBJ(item));
1747 
1748    Eo *eo_temp_item = eina_list_data_get(sd->selected);
1749    if (eo_temp_item && (eo_temp_item != EO_OBJ(item)))
1750      {
1751         ELM_COLOR_ITEM_DATA_GET(eo_temp_item, temp_item);
1752         elm_object_signal_emit(VIEW(temp_item), "elm,state,unselected", "elm");
1753      }
1754 
1755    EINA_LIST_FOREACH(sd->items, l, eo_temp_item)
1756      {
1757         ELM_COLOR_ITEM_DATA_GET(eo_temp_item, temp_item);
1758         if (item == temp_item) sd->selected = l;
1759      }
1760    sd->focused = ELM_COLORSELECTOR_PALETTE;
1761 
1762    return EINA_TRUE;
1763 }
1764 
1765 EOLIAN static Eo *
_elm_color_item_efl_object_constructor(Eo * eo_item,Elm_Color_Item_Data * item)1766 _elm_color_item_efl_object_constructor(Eo *eo_item, Elm_Color_Item_Data *item)
1767 {
1768    eo_item = efl_constructor(efl_super(eo_item, ELM_COLOR_ITEM_CLASS));
1769    item->base = efl_data_scope_get(eo_item, ELM_WIDGET_ITEM_CLASS);
1770 
1771    Evas_Object *obj;
1772    obj = efl_parent_get(eo_item);
1773    WIDGET(item) = obj;
1774    VIEW_SET(item, elm_layout_add(obj));
1775    if (!elm_layout_theme_set
1776        (VIEW(item), "colorselector", "item", elm_widget_style_get(obj)))
1777      CRI("Failed to set layout!");
1778    evas_object_size_hint_weight_set
1779      (VIEW(item), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1780    evas_object_size_hint_align_set(VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
1781    evas_object_event_callback_add
1782      (VIEW(item), EVAS_CALLBACK_RESIZE, _item_resize, NULL);
1783    _efl_ui_focus_event_redirector(VIEW(item), obj);
1784 
1785 
1786    item->color_obj = edje_object_add(evas_object_evas_get(obj));
1787    elm_widget_theme_object_set
1788      (obj, item->color_obj, "colorselector", "item/color",
1789      elm_widget_style_get(obj));
1790    evas_object_size_hint_weight_set
1791      (item->color_obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1792    evas_object_size_hint_align_set
1793      (item->color_obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
1794    evas_object_event_callback_add
1795      (item->color_obj, EVAS_CALLBACK_MOUSE_DOWN, _on_color_pressed, item);
1796    evas_object_event_callback_add
1797      (item->color_obj, EVAS_CALLBACK_MOUSE_MOVE, _on_color_moved, item);
1798    evas_object_event_callback_add
1799      (item->color_obj, EVAS_CALLBACK_MOUSE_UP, _on_color_released, item);
1800    if (!elm_layout_content_set(VIEW(item), "elm.swallow.color_obj", item->color_obj))
1801      elm_layout_content_set(VIEW(item), "color_obj", item->color_obj);
1802 
1803    _item_sizing_eval(item);
1804    evas_object_show(VIEW(item));
1805 
1806    // ACCESS
1807    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
1808      elm_wdg_item_access_register(eo_item);
1809 
1810    efl_access_object_role_set(eo_item, EFL_ACCESS_ROLE_RADIO_BUTTON);
1811 
1812    return eo_item;
1813 }
1814 
1815 EOLIAN static void
_elm_color_item_efl_object_destructor(Eo * obj,Elm_Color_Item_Data * item)1816 _elm_color_item_efl_object_destructor(Eo *obj, Elm_Color_Item_Data *item)
1817 {
1818    free(item->color);
1819    efl_destructor(efl_super(obj, ELM_COLOR_ITEM_CLASS));
1820 }
1821 
1822 static void
_colors_remove(Evas_Object * obj)1823 _colors_remove(Evas_Object *obj)
1824 {
1825    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1826 
1827    _items_del(sd);
1828    _elm_config_colors_free(sd->palette_name);
1829 }
1830 
1831 static void
_colors_save(Evas_Object * obj)1832 _colors_save(Evas_Object *obj)
1833 {
1834    Eina_List *elist;
1835    Elm_Object_Item *eo_item;
1836 
1837    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1838 
1839    _elm_config_colors_free(sd->palette_name);
1840    EINA_LIST_FOREACH(sd->items, elist, eo_item)
1841      {
1842         ELM_COLOR_ITEM_DATA_GET(eo_item, item);
1843         _elm_config_color_set(sd->palette_name, item->color->r, item->color->g,
1844               item->color->b, item->color->a);
1845      }
1846 }
1847 
1848 static void
_palette_colors_load(Evas_Object * obj)1849 _palette_colors_load(Evas_Object *obj)
1850 {
1851    Eina_List *elist;
1852    Eo *eo_item;
1853    Eina_List *color_list;
1854    Elm_Color_RGBA *color;
1855 
1856    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1857 
1858    color_list = _elm_config_color_list_get(sd->palette_name);
1859    if (!color_list) return;
1860 
1861    EINA_LIST_FOREACH(color_list, elist, color)
1862      {
1863         eo_item = efl_add(ELM_COLOR_ITEM_CLASS, obj);
1864         if (!eo_item) return;
1865 
1866         ELM_COLOR_ITEM_DATA_GET(eo_item, item);
1867 
1868         item->color = ELM_NEW(Elm_Color_RGBA);
1869         if (!item->color) return;
1870         item->color->r = color->r;
1871         item->color->g = color->g;
1872         item->color->b = color->b;
1873         item->color->a = color->a;
1874 
1875         elm_box_pack_end(sd->palette_box, VIEW(item));
1876         evas_object_color_set(item->color_obj,
1877                               (item->color->r * item->color->a) / 255,
1878                               (item->color->g * item->color->a) / 255,
1879                               (item->color->b * item->color->a) / 255,
1880                               item->color->a);
1881 
1882         sd->items = eina_list_append(sd->items, eo_item);
1883      }
1884 
1885    sd->config_load = EINA_TRUE;
1886 }
1887 
1888 static void
_create_colorpalette(Evas_Object * obj)1889 _create_colorpalette(Evas_Object *obj)
1890 {
1891    const char *hpadstr, *vpadstr;
1892    unsigned int h_pad = DEFAULT_HOR_PAD;
1893    unsigned int v_pad = DEFAULT_VER_PAD;
1894    double scale;
1895 
1896    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1897    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1898 
1899    if (sd->palette_box) return;
1900    sd->palette_box = elm_box_add(obj);
1901    elm_box_layout_set
1902      (sd->palette_box, evas_object_box_layout_flow_horizontal, NULL, NULL);
1903    elm_box_horizontal_set(sd->palette_box, EINA_TRUE);
1904    evas_object_size_hint_weight_set
1905      (sd->palette_box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1906    evas_object_size_hint_align_set
1907      (sd->palette_box, EVAS_HINT_FILL, EVAS_HINT_FILL);
1908    elm_box_homogeneous_set(sd->palette_box, EINA_TRUE);
1909 
1910    hpadstr = edje_object_data_get(wd->resize_obj, "horizontal_pad");
1911    if (hpadstr) h_pad = atoi(hpadstr);
1912    vpadstr = edje_object_data_get(wd->resize_obj, "vertical_pad");
1913    if (vpadstr) v_pad = atoi(vpadstr);
1914 
1915    scale = efl_gfx_entity_scale_get(obj) * elm_config_scale_get() / edje_object_base_scale_get(wd->resize_obj);
1916    elm_box_padding_set(sd->palette_box, h_pad * scale, v_pad * scale);
1917    elm_box_align_set(sd->palette_box, 0.0, 0.0);
1918    if (!elm_layout_content_set(obj, "elm.palette", sd->palette_box))
1919      elm_layout_content_set(obj, "palette", sd->palette_box);
1920    sd->palette_name = eina_stringshare_add("default");
1921    _palette_colors_load(obj);
1922 
1923    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _on_resize, NULL);
1924 }
1925 
1926 static void
_create_colorcomponents(Evas_Object * obj)1927 _create_colorcomponents(Evas_Object *obj)
1928 {
1929    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1930    if (sd->col_bars_area) return;
1931    sd->col_bars_area = elm_layout_add(obj);
1932    if (!elm_layout_theme_set
1933        (sd->col_bars_area, "colorselector", "bg", elm_widget_style_get(obj)))
1934      CRI("Failed to set layout!");
1935    if (!elm_layout_content_set(obj, "elm.selector", sd->col_bars_area))
1936      elm_layout_content_set(obj, "selector", sd->col_bars_area);
1937    _hsl_to_rgb(sd);
1938    _color_bars_add(obj);
1939 }
1940 
1941 EOLIAN static void
_elm_colorselector_efl_canvas_group_group_add(Eo * obj,Elm_Colorselector_Data * priv)1942 _elm_colorselector_efl_canvas_group_group_add(Eo *obj, Elm_Colorselector_Data *priv)
1943 {
1944    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1945 
1946    efl_canvas_group_add(efl_super(obj, MY_CLASS));
1947 
1948    if (!elm_layout_theme_set
1949        (obj, "colorselector", "palette", elm_object_style_get(obj)))
1950      CRI("Failed to set layout!");
1951 
1952    _create_colorpalette(obj);
1953 
1954    _create_colorcomponents(obj);
1955 
1956    elm_layout_signal_emit(obj, "elm,state,both", "elm");
1957 
1958    priv->mode = ELM_COLORSELECTOR_BOTH;
1959    priv->focused = ELM_COLORSELECTOR_PALETTE;
1960    priv->sel_color_type = HUE;
1961    priv->selected = NULL;
1962    priv->focus_items = NULL;
1963    priv->er = 255;
1964    priv->eg = 0;
1965    priv->eb = 0;
1966    priv->h = 0.0;
1967    priv->s = 1.0;
1968    priv->l = 0.0;
1969    priv->a = 255;
1970    priv->grab.x = -1;
1971    priv->grab.y = -1;
1972 #ifdef HAVE_ELEMENTARY_X
1973    priv->grab.xroot = -1;
1974 #endif
1975    priv->grab.in = EINA_TRUE;
1976    elm_layout_sizing_eval(obj);
1977    elm_widget_can_focus_set(obj, EINA_TRUE);
1978 
1979    _flush_color_children(obj, priv);
1980 }
1981 
1982 EOLIAN static void
_elm_colorselector_efl_canvas_group_group_del(Eo * obj,Elm_Colorselector_Data * sd)1983 _elm_colorselector_efl_canvas_group_group_del(Eo *obj, Elm_Colorselector_Data *sd)
1984 {
1985    int i = 0;
1986    void *tmp[4];
1987 
1988    evas_event_callback_del_full(evas_object_evas_get(obj), EVAS_CALLBACK_CANVAS_FOCUS_IN, _mouse_in_canvas, obj);
1989    evas_event_callback_del_full(evas_object_evas_get(obj), EVAS_CALLBACK_CANVAS_FOCUS_OUT, _mouse_out_canvas, obj);
1990 
1991    ecore_timer_del(sd->longpress_timer);
1992    eina_stringshare_del(sd->palette_name);
1993 
1994 #ifdef HAVE_ELEMENTARY_X
1995    ecore_event_handler_del(sd->grab.mouse_motion);
1996    ecore_event_handler_del(sd->grab.mouse_up);
1997    ecore_event_handler_del(sd->grab.key_up);
1998 #endif
1999 
2000    // We created the items with efl_add, they will be dead after this.
2001    sd->items = eina_list_free(sd->items);
2002    sd->selected = NULL;
2003    sd->focus_items = NULL;
2004 
2005    /* This cb_data are used during the destruction process of base.del */
2006    for (i = 0; i < 4; i++)
2007      tmp[i] = sd->cb_data[i];
2008    efl_canvas_group_del(efl_super(obj, MY_CLASS));
2009    for (i = 0; i < 4; i++)
2010      free(tmp[i]);
2011 }
2012 
2013 static Eina_List*
_palette_box_vertical_item_get(Eina_List * ref_item,enum Palette_Box_Direction dir)2014 _palette_box_vertical_item_get(Eina_List* ref_item, enum Palette_Box_Direction dir)
2015 {
2016    Evas_Coord basex, basey, x, y, dx, min_dx;
2017    Elm_Object_Item *eo_item;
2018    Eina_List* l;
2019    Eina_List* res = NULL;
2020    Eina_List* (*dir_func)(const Eina_List*);
2021 
2022    if (!ref_item) return NULL;
2023 
2024    switch (dir)
2025      {
2026         case PALETTE_BOX_UP:
2027           dir_func = eina_list_prev;
2028           break;
2029         case PALETTE_BOX_DOWN:
2030           dir_func = eina_list_next;
2031           break;
2032         default:
2033           return NULL;
2034      }
2035 
2036    eo_item = eina_list_data_get(ref_item);
2037    ELM_COLOR_ITEM_DATA_GET(eo_item, item);
2038    evas_object_geometry_get(VIEW(item), &basex, &basey, NULL, NULL);
2039 
2040    for (l = ref_item; l; l = dir_func(l))
2041      {
2042         eo_item = eina_list_data_get(l);
2043         item = efl_data_scope_get(eo_item, ELM_COLOR_ITEM_CLASS);
2044         evas_object_geometry_get(VIEW(item), &x, &y, NULL, NULL);
2045         if (basey != y) break;
2046      }
2047 
2048    basey = y;
2049    min_dx = -1;
2050 
2051    for (; l; l = dir_func(l))
2052      {
2053         eo_item = eina_list_data_get(l);
2054         item = efl_data_scope_get(eo_item, ELM_COLOR_ITEM_CLASS);
2055         evas_object_geometry_get(VIEW(item), &x, &y, NULL, NULL);
2056         if (basey != y) break;
2057 
2058         dx = abs(x - basex);
2059         if (dx < min_dx || min_dx < 0)
2060           {
2061              min_dx = dx;
2062              res = l;
2063           }
2064         else
2065           {
2066              break;
2067           }
2068       }
2069 
2070    return res;
2071 }
2072 
2073 static Eina_Bool
_key_action_move(Evas_Object * obj,const char * params)2074 _key_action_move(Evas_Object *obj, const char *params)
2075 {
2076    ELM_COLORSELECTOR_DATA_GET(obj, sd);
2077    Elm_Object_Item *eo_item = NULL;
2078    Eina_List *cl = NULL;
2079    char colorbar_s[128];
2080    const char *dir = params;
2081 
2082    if (!sd->selected) sd->selected = sd->items;
2083    if (!sd->focus_items) sd->focus_items = sd->items;
2084    _elm_widget_focus_auto_show(obj);
2085    if (!strcmp(dir, "left"))
2086      {
2087         if (sd->focused == ELM_COLORSELECTOR_PALETTE && sd->selected)
2088           {
2089              cl = eina_list_prev(sd->focus_items);
2090           }
2091         else if (sd->focused == ELM_COLORSELECTOR_COMPONENTS)
2092           {
2093              Efl_Event event = {};
2094              event.object = sd->cb_data[sd->sel_color_type]->lbt;
2095              _button_clicked_cb(sd->cb_data[sd->sel_color_type], &event);
2096           }
2097         else return EINA_FALSE;
2098      }
2099    else if (!strcmp(dir, "right"))
2100      {
2101         if (sd->focused == ELM_COLORSELECTOR_PALETTE && sd->selected)
2102           {
2103              cl = eina_list_next(sd->focus_items);
2104           }
2105         else if (sd->focused == ELM_COLORSELECTOR_COMPONENTS)
2106           {
2107              Efl_Event event = {};
2108              event.object = sd->cb_data[sd->sel_color_type]->rbt;
2109              _button_clicked_cb(sd->cb_data[sd->sel_color_type], &event);
2110           }
2111         else return EINA_FALSE;
2112      }
2113    else if (!strcmp(dir, "up"))
2114      {
2115         if (sd->focused == ELM_COLORSELECTOR_COMPONENTS)
2116           {
2117              sd->sel_color_type = sd->sel_color_type - 1;
2118              if (sd->sel_color_type < HUE)
2119                {
2120                   if (sd->mode == ELM_COLORSELECTOR_BOTH)
2121                     {
2122                        sd->focused = ELM_COLORSELECTOR_PALETTE;
2123                        /*when focus is shifted to palette start from
2124                         * first item*/
2125                        sd->selected = sd->items;
2126                        cl = sd->selected;
2127                     }
2128                   else
2129                     {
2130                        sd->sel_color_type = HUE;
2131                        return EINA_FALSE;
2132                     }
2133                }
2134           }
2135         else if (sd->focused == ELM_COLORSELECTOR_PALETTE)
2136           {
2137              cl = _palette_box_vertical_item_get(sd->focus_items, PALETTE_BOX_UP);
2138              if (!cl) cl = sd->focus_items;
2139           }
2140      }
2141    else if (!strcmp(dir, "down"))
2142      {
2143         if (sd->focused == ELM_COLORSELECTOR_PALETTE)
2144           {
2145              cl = _palette_box_vertical_item_get(sd->focus_items, PALETTE_BOX_DOWN);
2146              if (sd->mode == ELM_COLORSELECTOR_BOTH && !cl)
2147                {
2148                   sd->focused = ELM_COLORSELECTOR_COMPONENTS;
2149                   /*when focus is shifted to component start from
2150                    * first color type*/
2151                   sd->sel_color_type = HUE;
2152                }
2153           }
2154         else if (sd->focused == ELM_COLORSELECTOR_COMPONENTS)
2155           {
2156              snprintf(colorbar_s, sizeof(colorbar_s), "elm.colorbar_%d",
2157                       (sd->sel_color_type + 1));
2158              /*Append color type only if next color bar is available*/
2159              if (elm_object_part_content_get(sd->col_bars_area, colorbar_s))
2160                sd->sel_color_type = sd->sel_color_type + 1;
2161              else return EINA_FALSE;
2162           }
2163      }
2164    else return EINA_FALSE;
2165 
2166    if (cl)
2167      {
2168         eo_item = eina_list_data_get(cl);
2169         elm_object_item_focus_set(eo_item, EINA_TRUE);
2170      }
2171    else if (!cl && (sd->focused == ELM_COLORSELECTOR_PALETTE))
2172      return EINA_FALSE;
2173    else if (!cl && (sd->focused == ELM_COLORSELECTOR_COMPONENTS))
2174       _elm_widget_focus_highlight_start(obj);
2175 
2176    return EINA_TRUE;
2177 }
2178 
2179 
2180 static Eina_Bool
_key_action_activate(Evas_Object * obj,const char * params EINA_UNUSED)2181 _key_action_activate(Evas_Object *obj, const char *params EINA_UNUSED)
2182 {
2183    ELM_COLORSELECTOR_DATA_GET(obj, sd);
2184 
2185    if (!sd->selected) sd->selected = sd->items;
2186    if (!sd->focus_items) sd->focus_items = sd->items;
2187    if (sd->focused == ELM_COLORSELECTOR_PALETTE)
2188      {
2189         Elm_Object_Item *eo_item = NULL;
2190         eo_item = eina_list_data_get(sd->focus_items);
2191         elm_obj_color_item_selected_set(eo_item, EINA_TRUE);
2192 
2193         return EINA_TRUE;
2194      }
2195 
2196    return EINA_FALSE;
2197 }
2198 
2199 static Eina_Bool _elm_colorselector_smart_focus_next_enable = EINA_FALSE;
2200 
2201 static void
_access_obj_process(Evas_Object * obj,Eina_Bool is_access)2202 _access_obj_process(Evas_Object *obj, Eina_Bool is_access)
2203 {
2204    Eina_List *l;
2205    Elm_Object_Item *eo_it;
2206    int i = 0;
2207 
2208    ELM_COLORSELECTOR_DATA_GET(obj, sd);
2209 
2210    if ((sd->mode == ELM_COLORSELECTOR_PALETTE) ||
2211        (sd->mode == ELM_COLORSELECTOR_ALL) ||
2212        (sd->mode == ELM_COLORSELECTOR_BOTH))
2213      {
2214         if (is_access)
2215           {
2216              EINA_LIST_FOREACH(sd->items, l, eo_it)
2217                elm_wdg_item_access_register(eo_it);
2218           }
2219         else
2220           {
2221              EINA_LIST_FOREACH(sd->items, l, eo_it)
2222                elm_wdg_item_access_unregister(eo_it);
2223           }
2224      }
2225    if ((sd->mode == ELM_COLORSELECTOR_COMPONENTS) ||
2226        (sd->mode == ELM_COLORSELECTOR_ALL) ||
2227        (sd->mode == ELM_COLORSELECTOR_BOTH))
2228      {
2229         for (i = 0; i < 4; i++)
2230           {
2231              if (is_access)
2232                _access_colorbar_register(obj, sd->cb_data[i],
2233                                          "elm.arrow_bg_access");
2234              else
2235                _elm_access_edje_object_part_object_unregister(obj, sd->cb_data[i]->colorbar,
2236                                                               "elm.arrow_bg_access");
2237           }
2238      }
2239 }
2240 
2241 EOLIAN static Eina_Rect
_elm_colorselector_efl_ui_widget_focus_highlight_geometry_get(const Eo * obj EINA_UNUSED,Elm_Colorselector_Data * sd)2242 _elm_colorselector_efl_ui_widget_focus_highlight_geometry_get(const Eo *obj EINA_UNUSED, Elm_Colorselector_Data *sd)
2243 {
2244    if (sd->focused_item && (sd->focused == ELM_COLORSELECTOR_PALETTE))
2245      {
2246        ELM_COLOR_ITEM_DATA_GET(sd->focused_item, focus_it);
2247        return efl_gfx_entity_geometry_get(VIEW(focus_it));
2248      }
2249    else if(sd->focused == ELM_COLORSELECTOR_COMPONENTS)
2250      return efl_gfx_entity_geometry_get(sd->cb_data[sd->sel_color_type]->colorbar);
2251 
2252    return efl_gfx_entity_geometry_get(obj);
2253 }
2254 
2255 EOLIAN static void
_elm_colorselector_efl_ui_widget_on_access_update(Eo * obj,Elm_Colorselector_Data * _pd EINA_UNUSED,Eina_Bool acs)2256 _elm_colorselector_efl_ui_widget_on_access_update(Eo *obj, Elm_Colorselector_Data *_pd EINA_UNUSED, Eina_Bool acs)
2257 {
2258    _elm_colorselector_smart_focus_next_enable = acs;
2259    _access_obj_process(obj, _elm_colorselector_smart_focus_next_enable);
2260 }
2261 
2262 EAPI Evas_Object *
elm_colorselector_add(Evas_Object * parent)2263 elm_colorselector_add(Evas_Object *parent)
2264 {
2265    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
2266    return elm_legacy_add(MY_CLASS, parent);
2267 }
2268 
2269 EOLIAN static Eo *
_elm_colorselector_efl_object_constructor(Eo * obj,Elm_Colorselector_Data * _pd EINA_UNUSED)2270 _elm_colorselector_efl_object_constructor(Eo *obj, Elm_Colorselector_Data *_pd EINA_UNUSED)
2271 {
2272    obj = efl_constructor(efl_super(obj, MY_CLASS));
2273    efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
2274    evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
2275    efl_access_object_role_set(obj, EFL_ACCESS_ROLE_COLOR_CHOOSER);
2276    legacy_child_focus_handle(obj);
2277 
2278    return obj;
2279 }
2280 
2281 EOLIAN static void
_elm_colorselector_picked_color_set(Eo * obj,Elm_Colorselector_Data * _pd EINA_UNUSED,int r,int g,int b,int a)2282 _elm_colorselector_picked_color_set(Eo *obj, Elm_Colorselector_Data *_pd EINA_UNUSED, int r, int g, int b, int a)
2283 {
2284    _colors_set(obj, r, g, b, a, EINA_FALSE);
2285 }
2286 
2287 EOLIAN static void
_elm_colorselector_picked_color_get(const Eo * obj EINA_UNUSED,Elm_Colorselector_Data * sd,int * r,int * g,int * b,int * a)2288 _elm_colorselector_picked_color_get(const Eo *obj EINA_UNUSED, Elm_Colorselector_Data *sd, int *r, int *g, int *b, int *a)
2289 {
2290    if (r) *r = sd->r;
2291    if (g) *g = sd->g;
2292    if (b) *b = sd->b;
2293    if (a) *a = sd->a;
2294 }
2295 
2296 EOLIAN static void
_elm_colorselector_mode_set(Eo * obj,Elm_Colorselector_Data * sd,Elm_Colorselector_Mode mode)2297 _elm_colorselector_mode_set(Eo *obj, Elm_Colorselector_Data *sd, Elm_Colorselector_Mode mode)
2298 {
2299    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
2300    Evas_Object *o;
2301 
2302    if (sd->mode == mode) return;
2303    sd->mode = mode;
2304 
2305    o = elm_layout_content_unset(obj, "elm.selector");
2306    if (!o) o = elm_layout_content_unset(obj, "selector");
2307    if (o) evas_object_hide(o);
2308 
2309    o = elm_layout_content_unset(obj, "elm.palette");
2310    if (!o) o = elm_layout_content_unset(obj, "palette");
2311    if (o) evas_object_hide(o);
2312 
2313    o = elm_layout_content_unset(obj, "elm.picker");
2314    if (!o) o = elm_layout_content_unset(obj, "picker");
2315    if (o) evas_object_hide(o);
2316 
2317    switch (sd->mode)
2318      {
2319       case ELM_COLORSELECTOR_PALETTE:
2320         if (!elm_layout_content_set(obj, "elm.palette", sd->palette_box))
2321           elm_layout_content_set(obj, "palette", sd->palette_box);
2322         elm_layout_signal_emit(obj, "elm,state,palette", "elm");
2323         sd->focused = ELM_COLORSELECTOR_PALETTE;
2324         break;
2325 
2326       case ELM_COLORSELECTOR_COMPONENTS:
2327         if (!elm_layout_content_set(obj, "elm.selector", sd->col_bars_area))
2328           elm_layout_content_set(obj, "selector", sd->col_bars_area);
2329         elm_layout_signal_emit(obj, "elm,state,components", "elm");
2330         sd->focused = ELM_COLORSELECTOR_COMPONENTS;
2331         sd->sel_color_type = HUE;
2332         _unselect_selected_item(sd);
2333         break;
2334 
2335       case ELM_COLORSELECTOR_BOTH:
2336         if (!elm_layout_content_set(obj, "elm.palette", sd->palette_box))
2337           elm_layout_content_set(obj, "palette", sd->palette_box);
2338         if (!elm_layout_content_set(obj, "elm.selector", sd->col_bars_area))
2339           elm_layout_content_set(obj, "selector", sd->col_bars_area);
2340         elm_layout_signal_emit(obj, "elm,state,both", "elm");
2341         sd->focused = ELM_COLORSELECTOR_PALETTE;
2342         break;
2343 
2344       case ELM_COLORSELECTOR_PICKER:
2345         _create_colorpicker(obj);
2346         if (!elm_layout_content_set(obj, "elm.picker", sd->picker))
2347           elm_layout_content_set(obj, "picker", sd->picker);
2348         elm_layout_signal_emit(obj, "elm,state,picker", "elm");
2349         sd->focused = ELM_COLORSELECTOR_PICKER;
2350         _unselect_selected_item(sd);
2351         break;
2352 
2353       case ELM_COLORSELECTOR_ALL:
2354         _create_colorpicker(obj);
2355         if (!elm_layout_content_set(obj, "elm.palette", sd->palette_box))
2356           elm_layout_content_set(obj, "palette", sd->palette_box);
2357         if (!elm_layout_content_set(obj, "elm.selector", sd->col_bars_area))
2358           elm_layout_content_set(obj, "selector", sd->col_bars_area);
2359         if (!elm_layout_content_set(obj, "elm.picker", sd->picker))
2360           elm_layout_content_set(obj, "picker", sd->picker);
2361         elm_layout_signal_emit(obj, "elm,state,all", "elm");
2362         sd->focused = ELM_COLORSELECTOR_PALETTE;
2363         break;
2364 
2365       default:
2366         return;
2367      }
2368 
2369    edje_object_message_signal_process(wd->resize_obj);
2370 
2371    _colors_set(obj, sd->r, sd->g, sd->b, sd->a, EINA_TRUE);
2372    elm_layout_sizing_eval(obj);
2373    _flush_color_children(obj, sd);
2374 }
2375 
2376 EOLIAN static Elm_Colorselector_Mode
_elm_colorselector_mode_get(const Eo * obj EINA_UNUSED,Elm_Colorselector_Data * sd)2377 _elm_colorselector_mode_get(const Eo *obj EINA_UNUSED, Elm_Colorselector_Data *sd)
2378 {
2379    return sd->mode;
2380 }
2381 
2382 EAPI void
elm_colorselector_palette_item_color_get(const Elm_Object_Item * it,int * r,int * g,int * b,int * a)2383 elm_colorselector_palette_item_color_get(const Elm_Object_Item *it,
2384                                          int *r,
2385                                          int *g,
2386                                          int *b,
2387                                          int *a)
2388 {
2389    elm_obj_color_item_color_get(it, r, g, b, a);
2390 }
2391 
2392 EOLIAN static void
_elm_color_item_color_get(const Eo * eo_item EINA_UNUSED,Elm_Color_Item_Data * item,int * r,int * g,int * b,int * a)2393 _elm_color_item_color_get(const Eo *eo_item EINA_UNUSED,
2394                           Elm_Color_Item_Data *item,
2395                           int *r,
2396                           int *g,
2397                           int *b,
2398                           int *a)
2399 {
2400     if (r) *r = item->color->r;
2401     if (g) *g = item->color->g;
2402     if (b) *b = item->color->b;
2403     if (a) *a = item->color->a;
2404 }
2405 
2406 EAPI void
elm_colorselector_palette_item_color_set(Elm_Object_Item * it,int r,int g,int b,int a)2407 elm_colorselector_palette_item_color_set(Elm_Object_Item *it,
2408                                          int r,
2409                                          int g,
2410                                          int b,
2411                                          int a)
2412 {
2413    elm_obj_color_item_color_set(it, r, g, b, a);
2414 }
2415 
2416 EOLIAN static void
_elm_color_item_color_set(Eo * eo_item EINA_UNUSED,Elm_Color_Item_Data * item,int r,int g,int b,int a)2417 _elm_color_item_color_set(Eo *eo_item EINA_UNUSED,
2418                           Elm_Color_Item_Data *item,
2419                           int r,
2420                           int g,
2421                           int b,
2422                           int a)
2423 {
2424    item->color->r = r;
2425    item->color->g = g;
2426    item->color->b = b;
2427    item->color->a = a;
2428    evas_object_color_set(item->color_obj,
2429                          (item->color->r * item->color->a) / 255,
2430                          (item->color->g * item->color->a) / 255,
2431                          (item->color->b * item->color->a) / 255,
2432                          item->color->a);
2433    _colors_save(WIDGET(item));
2434 }
2435 
2436 EOLIAN static Elm_Object_Item*
_elm_colorselector_palette_color_add(Eo * obj,Elm_Colorselector_Data * sd,int r,int g,int b,int a)2437 _elm_colorselector_palette_color_add(Eo *obj, Elm_Colorselector_Data *sd, int r, int g, int b, int a)
2438 {
2439    Eo *eo_item;
2440 
2441    if (sd->config_load)
2442      {
2443         _items_del(sd);
2444         sd->config_load = EINA_FALSE;
2445      }
2446    eo_item = efl_add(ELM_COLOR_ITEM_CLASS, obj);
2447    if (!eo_item) return NULL;
2448 
2449    ELM_COLOR_ITEM_DATA_GET(eo_item, item);
2450    item->color = ELM_NEW(Elm_Color_RGBA);
2451    if (!item->color) return NULL;
2452 
2453    item->color->r = r;
2454    item->color->g = g;
2455    item->color->b = b;
2456    item->color->a = a;
2457 
2458    elm_box_pack_end(sd->palette_box, VIEW(item));
2459    evas_object_color_set(item->color_obj,
2460                          (item->color->r * item->color->a) / 255,
2461                          (item->color->g * item->color->a) / 255,
2462                          (item->color->b * item->color->a) / 255,
2463                          item->color->a);
2464 
2465    sd->items = eina_list_append(sd->items, eo_item);
2466 
2467    elm_layout_sizing_eval(obj);
2468 
2469    return eo_item;
2470 }
2471 
2472 EOLIAN static void
_elm_colorselector_palette_clear(Eo * obj,Elm_Colorselector_Data * sd)2473 _elm_colorselector_palette_clear(Eo *obj, Elm_Colorselector_Data *sd)
2474 {
2475 
2476    _colors_remove(obj);
2477    if (sd->mode == ELM_COLORSELECTOR_BOTH)
2478      sd->focused = ELM_COLORSELECTOR_COMPONENTS;
2479 }
2480 
2481 EOLIAN static const Eina_List*
_elm_colorselector_palette_items_get(const Eo * obj EINA_UNUSED,Elm_Colorselector_Data * sd)2482 _elm_colorselector_palette_items_get(const Eo *obj EINA_UNUSED, Elm_Colorselector_Data *sd)
2483 {
2484    return sd->items;
2485 }
2486 
2487 EAPI void
elm_colorselector_palette_item_selected_set(Elm_Object_Item * it,Eina_Bool selected)2488 elm_colorselector_palette_item_selected_set(Elm_Object_Item *it,
2489                               Eina_Bool selected)
2490 {
2491    elm_obj_color_item_selected_set(it, selected);
2492 }
2493 
2494 EOLIAN static void
_elm_color_item_selected_set(Eo * eo_item,Elm_Color_Item_Data * item,Eina_Bool selected)2495 _elm_color_item_selected_set(Eo *eo_item,
2496                              Elm_Color_Item_Data *item,
2497                              Eina_Bool selected)
2498 {
2499    Eo *eo_temp_item;
2500    Eina_List *l;
2501 
2502    ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd);
2503 
2504    eo_temp_item = eina_list_data_get(sd->selected);
2505    if (eo_item == eo_temp_item)
2506      {
2507         if (!selected)
2508           {
2509              elm_object_signal_emit(VIEW(item), "elm,state,unselected", "elm");
2510              sd->selected = NULL;
2511           }
2512 
2513         return;
2514      }
2515 
2516    if (selected)
2517      {
2518         elm_object_signal_emit(VIEW(item), "elm,state,selected", "elm");
2519         elm_colorselector_color_set(WIDGET(item), item->color->r, item->color->g,
2520                                     item->color->b, item->color->a);
2521         if (eo_temp_item)
2522           {
2523              ELM_COLOR_ITEM_DATA_GET(eo_temp_item, temp_item);
2524              elm_object_signal_emit(VIEW(temp_item), "elm,state,unselected", "elm");
2525           }
2526 
2527         EINA_LIST_FOREACH(sd->items, l, eo_temp_item)
2528           if (eo_item == eo_temp_item) sd->selected = l;
2529 
2530         elm_object_signal_emit(VIEW(item), "elm,anim,activate", "elm");
2531         evas_object_smart_callback_call(WIDGET(item), "color,item,selected", EO_OBJ(item));
2532      }
2533 }
2534 
2535 EAPI Eina_Bool
elm_colorselector_palette_item_selected_get(const Elm_Object_Item * it)2536 elm_colorselector_palette_item_selected_get(const Elm_Object_Item *it)
2537 {
2538    return elm_obj_color_item_selected_get(it);
2539 }
2540 
2541 EOLIAN static Eina_Bool
_elm_color_item_selected_get(const Eo * eo_item EINA_UNUSED,Elm_Color_Item_Data * item)2542 _elm_color_item_selected_get(const Eo *eo_item EINA_UNUSED, Elm_Color_Item_Data *item)
2543 {
2544    Eo *eo_temp_item;
2545 
2546    ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd);
2547 
2548    eo_temp_item = eina_list_data_get(sd->selected);
2549    if (eo_item == eo_temp_item) return EINA_TRUE;
2550    else return EINA_FALSE;
2551 }
2552 
2553 EOLIAN static Elm_Object_Item*
_elm_colorselector_palette_selected_item_get(const Eo * obj EINA_UNUSED,Elm_Colorselector_Data * sd)2554 _elm_colorselector_palette_selected_item_get(const Eo *obj EINA_UNUSED, Elm_Colorselector_Data *sd)
2555 {
2556    return eina_list_data_get(sd->selected);
2557 }
2558 
2559 EOLIAN static void
_elm_colorselector_palette_name_set(Eo * obj,Elm_Colorselector_Data * sd,const char * palette_name)2560 _elm_colorselector_palette_name_set(Eo *obj, Elm_Colorselector_Data *sd, const char *palette_name)
2561 {
2562    EINA_SAFETY_ON_NULL_RETURN(palette_name);
2563 
2564    if (!strcmp(sd->palette_name, palette_name)) return;
2565 
2566    _items_del(sd);
2567    eina_stringshare_replace(&sd->palette_name, palette_name);
2568    _palette_colors_load(obj);
2569 }
2570 
2571 EOLIAN static const char*
_elm_colorselector_palette_name_get(const Eo * obj EINA_UNUSED,Elm_Colorselector_Data * sd)2572 _elm_colorselector_palette_name_get(const Eo *obj EINA_UNUSED, Elm_Colorselector_Data *sd)
2573 {
2574    return sd->palette_name;
2575 }
2576 
2577 static void
_elm_colorselector_class_constructor(Efl_Class * klass)2578 _elm_colorselector_class_constructor(Efl_Class *klass)
2579 {
2580    evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
2581 
2582    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
2583       _elm_colorselector_smart_focus_next_enable = EINA_TRUE;
2584 }
2585 
2586 EOLIAN static const Efl_Access_Action_Data*
_elm_colorselector_efl_access_widget_action_elm_actions_get(const Eo * obj EINA_UNUSED,Elm_Colorselector_Data * sd EINA_UNUSED)2587 _elm_colorselector_efl_access_widget_action_elm_actions_get(const Eo *obj EINA_UNUSED, Elm_Colorselector_Data *sd EINA_UNUSED)
2588 {
2589    static Efl_Access_Action_Data atspi_actions[] = {
2590           { "move,left", "move", "left", _key_action_move},
2591           { "move,right", "move", "right", _key_action_move},
2592           { "move,up", "move", "up", _key_action_move},
2593           { "move,down", "move", "down", _key_action_move},
2594           { NULL, NULL, NULL, NULL }
2595    };
2596    return &atspi_actions[0];
2597 }
2598 
2599 EOLIAN static Eina_List*
_elm_colorselector_efl_access_object_access_children_get(const Eo * obj EINA_UNUSED,Elm_Colorselector_Data * sd)2600 _elm_colorselector_efl_access_object_access_children_get(const Eo *obj EINA_UNUSED, Elm_Colorselector_Data *sd)
2601 {
2602    Eina_List *ret = NULL;
2603 
2604    ret = efl_access_object_access_children_get(efl_super(obj, ELM_COLORSELECTOR_CLASS));
2605    // filter - out box contiainer
2606    ret = eina_list_remove(ret, sd->palette_box);
2607    // append items as colorselector children
2608    ret = eina_list_merge(ret, eina_list_clone(sd->items));
2609 
2610    return ret;
2611 }
2612 
2613 EOLIAN static Efl_Access_State_Set
_elm_color_item_efl_access_object_state_set_get(const Eo * obj,Elm_Color_Item_Data * sd EINA_UNUSED)2614 _elm_color_item_efl_access_object_state_set_get(const Eo *obj, Elm_Color_Item_Data *sd EINA_UNUSED)
2615 {
2616    Efl_Access_State_Set ret;
2617    Eina_Bool sel;
2618 
2619    ret = efl_access_object_state_set_get(efl_super(obj, ELM_COLOR_ITEM_CLASS));
2620 
2621    sel = elm_obj_color_item_selected_get(obj);
2622 
2623    if (sel)
2624      STATE_TYPE_SET(ret, EFL_ACCESS_STATE_TYPE_CHECKED);
2625 
2626    return ret;
2627 }
2628 
2629 EOLIAN static void
_elm_color_item_elm_widget_item_item_focus_set(Eo * eo_it,Elm_Color_Item_Data * it,Eina_Bool focused)2630 _elm_color_item_elm_widget_item_item_focus_set(Eo *eo_it, Elm_Color_Item_Data *it, Eina_Bool focused)
2631 {
2632    Evas_Object *obj = WIDGET(it);
2633    ELM_COLORSELECTOR_DATA_GET(obj, sd);
2634 
2635    if (focused)
2636      {
2637         if (eo_it != sd->focused_item)
2638           sd->focused_item = eo_it;
2639 
2640         Eina_List *l;
2641         Eo *eo_temp_item;
2642         EINA_LIST_FOREACH(sd->items, l, eo_temp_item)
2643           if (eo_it == eo_temp_item) sd->focus_items = l;
2644      }
2645    else
2646      {
2647         if (!efl_ui_focus_object_focus_get(obj))
2648           return;
2649         sd->focused_item = NULL;
2650      }
2651 
2652    _elm_widget_focus_highlight_start(obj);
2653 }
2654 
2655 EOLIAN static Eina_Bool
_elm_color_item_elm_widget_item_item_focus_get(const Eo * eo_it,Elm_Color_Item_Data * it)2656 _elm_color_item_elm_widget_item_item_focus_get(const Eo *eo_it, Elm_Color_Item_Data *it)
2657 {
2658    Evas_Object *obj = WIDGET(it);
2659    ELM_COLORSELECTOR_DATA_GET(obj, sd);
2660 
2661    if (eo_it == sd->focused_item)
2662      return EINA_TRUE;
2663    return EINA_FALSE;
2664 }
2665 
2666 EOLIAN static const Efl_Access_Action_Data*
_elm_color_item_efl_access_widget_action_elm_actions_get(const Eo * eo_it EINA_UNUSED,Elm_Color_Item_Data * it EINA_UNUSED)2667 _elm_color_item_efl_access_widget_action_elm_actions_get(const Eo *eo_it EINA_UNUSED, Elm_Color_Item_Data *it EINA_UNUSED)
2668 {
2669    static Efl_Access_Action_Data atspi_actions[] = {
2670           { "activate", "activate", NULL, _item_action_activate},
2671           { NULL, NULL, NULL, NULL }
2672    };
2673    return &atspi_actions[0];
2674 }
2675 
2676 EOLIAN static const char*
_elm_color_item_efl_access_object_i18n_name_get(const Eo * eo_it,Elm_Color_Item_Data * it)2677 _elm_color_item_efl_access_object_i18n_name_get(const Eo *eo_it, Elm_Color_Item_Data *it)
2678 {
2679    Eina_Strbuf *buf;
2680    const char *color_name = NULL;
2681    const char *name;
2682    char *accessible_name;
2683 
2684    name = efl_access_object_i18n_name_get(efl_super(eo_it, ELM_COLOR_ITEM_CLASS));
2685    if (name) return name;
2686 
2687    buf = eina_strbuf_new();
2688    color_name = _get_color_name(it->color->r, it->color->g, it->color->b, it->color->a);
2689    if (color_name)
2690      eina_strbuf_append_printf(buf, "%s", color_name);
2691    else
2692      eina_strbuf_append_printf(buf, "red %d, green %d, blue %d, alpha %d",
2693                                it->color->r, it->color->g, it->color->b, it->color->a);
2694    accessible_name = eina_strbuf_string_steal(buf);
2695    eina_strbuf_free(buf);
2696 
2697    eina_stringshare_del(it->base->accessible_name);
2698    it->base->accessible_name = eina_stringshare_add(accessible_name);
2699    free(accessible_name);
2700    return it->base->accessible_name;
2701 }
2702 
2703 EOLIAN static Eina_Rect
_elm_color_item_efl_ui_focus_object_focus_geometry_get(const Eo * obj EINA_UNUSED,Elm_Color_Item_Data * pd)2704 _elm_color_item_efl_ui_focus_object_focus_geometry_get(const Eo *obj EINA_UNUSED, Elm_Color_Item_Data *pd)
2705 {
2706    return efl_gfx_entity_geometry_get(pd->color_obj);
2707 }
2708 
2709 EOLIAN static void
_elm_color_item_efl_ui_focus_object_focus_set(Eo * obj,Elm_Color_Item_Data * pd,Eina_Bool focus)2710 _elm_color_item_efl_ui_focus_object_focus_set(Eo *obj, Elm_Color_Item_Data *pd, Eina_Bool focus)
2711 {
2712    efl_ui_focus_object_focus_set(efl_super(obj, ELM_COLOR_ITEM_CLASS), focus);
2713    evas_object_focus_set(pd->color_obj, focus);
2714    elm_object_item_focus_set(obj, focus);
2715 }
2716 
2717 EOLIAN static Efl_Ui_Focus_Object*
_elm_color_item_efl_ui_focus_object_focus_parent_get(const Eo * obj EINA_UNUSED,Elm_Color_Item_Data * pd)2718 _elm_color_item_efl_ui_focus_object_focus_parent_get(const Eo *obj EINA_UNUSED, Elm_Color_Item_Data *pd)
2719 {
2720    return WIDGET(pd);
2721 }
2722 
2723 EOLIAN static Efl_Ui_Focus_Manager*
_elm_color_item_efl_ui_focus_object_focus_manager_get(const Eo * obj EINA_UNUSED,Elm_Color_Item_Data * pd)2724 _elm_color_item_efl_ui_focus_object_focus_manager_get(const Eo *obj EINA_UNUSED, Elm_Color_Item_Data *pd)
2725 {
2726    return efl_ui_focus_object_focus_manager_get(WIDGET(pd));
2727 }
2728 
2729 
2730 /* Standard widget overrides */
2731 
2732 ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(elm_colorselector, Elm_Colorselector_Data)
2733 
2734 /* Internal EO APIs and hidden overrides */
2735 
2736 #define ELM_COLORSELECTOR_EXTRA_OPS \
2737    EFL_CANVAS_GROUP_CALC_OPS(elm_colorselector), \
2738    EFL_CANVAS_GROUP_ADD_DEL_OPS(elm_colorselector)
2739 
2740 #include "elm_colorselector_eo.c"
2741 #include "elm_color_item_eo.c"
2742