check, colorselector, calendar, diskselector: apply key binding
[platform/upstream/elementary.git] / src / lib / elm_colorselector.c
1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #include <Elementary.h>
6 #include "elm_priv.h"
7 #include "elm_widget_colorselector.h"
8
9 #define MY_CLASS ELM_OBJ_COLORSELECTOR_CLASS
10
11 #define MY_CLASS_NAME "Elm_Colorselector"
12 #define MY_CLASS_NAME_LEGACY "elm_colorselector"
13
14 #define BASE_STEP       360.0
15 #define HUE_STEP        360.0
16 #define SAT_STEP        128.0
17 #define LIG_STEP        256.0
18 #define ALP_STEP        256.0
19 #define DEFAULT_HOR_PAD 10
20 #define DEFAULT_VER_PAD 10
21
22 static const char SIG_CHANGED[] = "changed";
23 static const char SIG_COLOR_ITEM_SELECTED[] = "color,item,selected";
24 static const char SIG_COLOR_ITEM_LONGPRESSED[] = "color,item,longpressed";
25 static const Evas_Smart_Cb_Description _smart_callbacks[] =
26 {
27    {SIG_COLOR_ITEM_SELECTED, ""},
28    {SIG_COLOR_ITEM_LONGPRESSED, ""},
29    {SIG_CHANGED, ""},
30    {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
31    {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
32    {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
33    {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
34    {NULL, NULL}
35 };
36
37 static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
38
39 static const Elm_Action key_actions[] = {
40    {"move", _key_action_move},
41    {NULL, NULL}
42 };
43
44 enum Palette_Box_Direction
45 {
46    PALETTE_BOX_UP,
47    PALETTE_BOX_DOWN
48 };
49
50 static void
51 _items_del(Elm_Colorselector_Data *sd)
52 {
53    Elm_Color_Item *item;
54
55    if (!sd->items) return;
56
57    EINA_LIST_FREE(sd->items, item)
58      {
59         free(item->color);
60         elm_widget_item_free(item);
61      }
62
63    sd->items = NULL;
64    sd->selected = NULL;
65 }
66
67 static void
68 _color_with_saturation(Elm_Colorselector_Data *sd, int *sr, int *sg, int *sb)
69 {
70    if (sd->er > 127)
71      *sr = 127 + (int)((double)(sd->er - 127) * sd->s);
72    else
73      *sr = 127 - (int)((double)(127 - sd->er) * sd->s);
74
75    if (sd->eg > 127)
76      *sg = 127 + (int)((double)(sd->eg - 127) * sd->s);
77    else
78      *sg = 127 - (int)((double)(127 - sd->eg) * sd->s);
79
80    if (sd->eb > 127)
81      *sb = 127 + (int)((double)(sd->eb - 127) * sd->s);
82    else
83      *sb = 127 - (int)((double)(127 - sd->eb) * sd->s);
84 }
85
86 static void
87 _color_with_lightness(Elm_Colorselector_Data *sd, int *lr, int *lg, int *lb)
88 {
89    if (sd->l > 0.5)
90      {
91         *lr = sd->er + (int)((double)(255 - sd->er) * (sd->l - 0.5) * 2.0);
92         *lg = sd->eg + (int)((double)(255 - sd->eg) * (sd->l - 0.5) * 2.0);
93         *lb = sd->eb + (int)((double)(255 - sd->eb) * (sd->l - 0.5) * 2.0);
94      }
95    else if (sd->l < 0.5)
96      {
97         *lr = (double)sd->er * sd->l * 2.0;
98         *lg = (double)sd->eg * sd->l * 2.0;
99         *lb = (double)sd->eb * sd->l * 2.0;
100      }
101    else
102      {
103         *lr = sd->er;
104         *lg = sd->eg;
105         *lb = sd->eb;
106      }
107 }
108
109 static void
110 _color_picker_init(Elm_Colorselector_Data *sd)
111 {
112    char buf[12];
113    unsigned int *pixels;
114    unsigned int *copy;
115    int color;
116    int x, y, w, h;
117
118    if (!evas_object_data_get(sd->entries[0], "_changed"))
119      {
120         snprintf(buf, 12, "%i", sd->r);
121         elm_object_text_set(sd->entries[0], buf);
122      }
123    if (!evas_object_data_get(sd->entries[1], "_changed"))
124      {
125         snprintf(buf, 12, "%i", sd->g);
126         elm_object_text_set(sd->entries[1], buf);
127      }
128    if (!evas_object_data_get(sd->entries[2], "_changed"))
129      {
130         snprintf(buf, 12, "%i", sd->b);
131         elm_object_text_set(sd->entries[2], buf);
132      }
133    if (!evas_object_data_get(sd->entries[3], "_changed"))
134      {
135         snprintf(buf, 12, "%i", sd->a);
136         elm_object_text_set(sd->entries[3], buf);
137      }
138
139    color = (sd->a << 24) |
140      (((sd->r * sd->a) / 255) << 16) |
141      (((sd->g * sd->a) / 255) << 8) |
142      (((sd->b * sd->a) / 255));
143
144    if (sd->a == 255)
145      evas_object_image_alpha_set(sd->picker_display, EINA_FALSE);
146    else
147      evas_object_image_alpha_set(sd->picker_display, EINA_TRUE);
148
149    pixels = evas_object_image_data_get(sd->picker_display, EINA_TRUE);
150    copy = pixels;
151    for (y = 0; y < 17; y++)
152      {
153         for (x = 0; x < 17; x++)
154           {
155              *(pixels++) = color;
156           }
157      }
158    evas_object_image_data_set(sd->picker_display, copy);
159    evas_object_geometry_get(sd->picker_display, NULL, NULL, &w, &h);
160    evas_object_image_data_update_add(sd->picker_display, 0, 0, w, h);
161 }
162
163 static void
164 _rgb_to_hsl(Elm_Colorselector_Data *sd)
165 {
166    double r2, g2, b2;
167    double v, m, vm;
168    double r, g, b;
169
170    r = sd->r;
171    g = sd->g;
172    b = sd->b;
173
174    r /= 255.0;
175    g /= 255.0;
176    b /= 255.0;
177
178    v = (r > g) ? r : g;
179    v = (v > b) ? v : b;
180
181    m = (r < g) ? r : g;
182    m = (m < b) ? m : b;
183
184    sd->h = 0.0;
185    sd->s = 0.0;
186    sd->l = 0.0;
187
188    sd->l = (m + v) / 2.0;
189
190    if (sd->l <= 0.0) return;
191
192    vm = v - m;
193    sd->s = vm;
194
195    if (sd->s > 0.0) sd->s /= (sd->l <= 0.5) ? (v + m) : (2.0 - v - m);
196    else return;
197
198    r2 = (v - r) / vm;
199    g2 = (v - g) / vm;
200    b2 = (v - b) / vm;
201
202    if (r == v) sd->h = (g == m ? 5.0 + b2 : 1.0 - g2);
203    else if (g == v)
204      sd->h = (b == m ? 1.0 + r2 : 3.0 - b2);
205    else sd->h = (r == m ? 3.0 + g2 : 5.0 - r2);
206
207    sd->h *= 60.0;
208 }
209
210 static Eina_Bool
211 _hsl_to_rgb(Elm_Colorselector_Data *sd)
212 {
213    double sv, vsf, f, p, q, t, v;
214    double r = 0, g = 0, b = 0;
215    double _h, _s, _l;
216    int i = 0;
217
218    _h = sd->h;
219    _s = sd->s;
220    _l = sd->l;
221
222    if (_s == 0.0) r = g = b = _l;
223    else
224      {
225         if (_h == 360.0) _h = 0.0;
226         _h /= 60.0;
227
228         v = (_l <= 0.5) ? (_l * (1.0 + _s)) : (_l + _s - (_l * _s));
229         p = _l + _l - v;
230
231         if (v) sv = (v - p) / v;
232         else sv = 0;
233
234         i = (int)_h;
235         f = _h - i;
236
237         vsf = v * sv * f;
238
239         t = p + vsf;
240         q = v - vsf;
241
242         switch (i)
243           {
244            case 0:
245              r = v;
246              g = t;
247              b = p;
248              break;
249
250            case 1:
251              r = q;
252              g = v;
253              b = p;
254              break;
255
256            case 2:
257              r = p;
258              g = v;
259              b = t;
260              break;
261
262            case 3:
263              r = p;
264              g = q;
265              b = v;
266              break;
267
268            case 4:
269              r = t;
270              g = p;
271              b = v;
272              break;
273
274            case 5:
275              r = v;
276              g = p;
277              b = q;
278              break;
279           }
280      }
281    i = (int)(r * 255.0);
282    f = (r * 255.0) - i;
283    r = (f <= 0.5) ? i : (i + 1);
284
285    i = (int)(g * 255.0);
286    f = (g * 255.0) - i;
287    g = (f <= 0.5) ? i : (i + 1);
288
289    i = (int)(b * 255.0);
290    f = (b * 255.0) - i;
291    b = (f <= 0.5) ? i : (i + 1);
292
293    if (sd->r == r && sd->g == g && sd->b == b) return EINA_FALSE;
294
295    sd->r = r;
296    sd->g = g;
297    sd->b = b;
298
299    return EINA_TRUE;
300 }
301
302 static void
303 _update_ergb(Elm_Colorselector_Data *sd, double x)
304 {
305    double one_six = 1.0 / 6.0;
306
307    if (x < one_six)
308      {
309         sd->er = 255;
310         sd->eg = (255.0 * x * 6.0);
311         sd->eb = 0;
312      }
313    else if (x < 2 * one_six)
314      {
315         sd->er = 255 - (int)(255.0 * (x - one_six) * 6.0);
316         sd->eg = 255;
317         sd->eb = 0;
318      }
319    else if (x < 3 * one_six)
320      {
321         sd->er = 0;
322         sd->eg = 255;
323         sd->eb = (int)(255.0 * (x - (2.0 * one_six)) * 6.0);
324      }
325    else if (x < 4 * one_six)
326      {
327         sd->er = 0;
328         sd->eg = 255 - (int)(255.0 * (x - (3.0 * one_six)) * 6.0);
329         sd->eb = 255;
330      }
331    else if (x < 5 * one_six)
332      {
333         sd->er = 255.0 * (x - (4.0 * one_six)) * 6.0;
334         sd->eg = 0;
335         sd->eb = 255;
336      }
337    else
338      {
339         sd->er = 255;
340         sd->eg = 0;
341         sd->eb = 255 - (int)(255.0 * (x - (5.0 * one_six)) * 6.0);
342      }
343 }
344
345 static void
346 _update_colorbars(Elm_Colorselector_Data *sd)
347 {
348    int r, g, b;
349    evas_object_color_set
350      (sd->cb_data[0]->arrow, sd->er, sd->eg, sd->eb, 255);
351    evas_object_color_set
352      (sd->cb_data[1]->bg_rect, sd->er, sd->eg, sd->eb, 255);
353    evas_object_color_set
354      (sd->cb_data[2]->bg_rect, sd->er, sd->eg, sd->eb, 255);
355    evas_object_color_set
356      (sd->cb_data[3]->bar, sd->er, sd->eg, sd->eb, 255);
357
358    _color_with_saturation(sd, &r, &g, &b);
359    evas_object_color_set(sd->cb_data[1]->arrow, r, g, b, 255);
360
361    _color_with_lightness(sd, &r, &g, &b);
362    evas_object_color_set(sd->cb_data[2]->arrow, r, g, b, 255);
363
364    evas_object_color_set(sd->cb_data[3]->arrow,
365                          (sd->er * sd->a) / 255,
366                          (sd->eg * sd->a) / 255,
367                          (sd->eb * sd->a) / 255,
368                          sd->a);
369 }
370
371 static void
372 _update_hsla_from_colorbar(Evas_Object *obj, Color_Type type, double x)
373 {
374    int ta;
375
376    ELM_COLORSELECTOR_DATA_GET(obj, sd);
377
378    switch (type)
379      {
380       case HUE:
381         sd->h = 360.0 * x;
382         _update_ergb(sd, x);
383         break;
384
385       case SATURATION:
386         sd->s = 1.0 - x;
387         break;
388
389       case LIGHTNESS:
390         sd->l = x;
391         break;
392
393       case ALPHA:
394         ta = 255.0 * x;
395         if (ta == sd->a) return;
396         sd->a = ta;
397         break;
398
399       default:
400         return;
401      }
402
403    if (type != ALPHA && !_hsl_to_rgb(sd)) return;
404
405    _update_colorbars(sd);
406    _color_picker_init(sd);
407    evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);
408 }
409
410 static void
411 _colors_set(Evas_Object *obj,
412             int r,
413             int g,
414             int b,
415             int a)
416 {
417    double x, y;
418
419    ELM_COLORSELECTOR_DATA_GET(obj, sd);
420
421    if ((sd->r == r) && (sd->g == g) && (sd->b == b) && (sd->a == a))
422      return;
423
424    sd->r = r;
425    sd->g = g;
426    sd->b = b;
427    sd->a = a;
428
429    _rgb_to_hsl(sd);
430
431    edje_object_part_drag_value_get
432      (sd->cb_data[0]->colorbar, "elm.arrow", &x, &y);
433    x = sd->h / 360.0;
434    edje_object_part_drag_value_set
435      (sd->cb_data[0]->colorbar, "elm.arrow", x, y);
436    _update_ergb(sd, x);
437
438    edje_object_part_drag_value_get
439      (sd->cb_data[1]->colorbar, "elm.arrow", &x, &y);
440    x = 1.0 - sd->s;
441    edje_object_part_drag_value_set
442      (sd->cb_data[1]->colorbar, "elm.arrow", x, y);
443
444    edje_object_part_drag_value_get
445      (sd->cb_data[2]->colorbar, "elm.arrow", &x, &y);
446    x = sd->l;
447    edje_object_part_drag_value_set(sd->cb_data[2]->colorbar, "elm.arrow", x, y);
448
449    edje_object_part_drag_value_get
450      (sd->cb_data[3]->colorbar, "elm.arrow", &x, &y);
451    x = sd->a / 255.0;
452    edje_object_part_drag_value_set
453      (sd->cb_data[3]->colorbar, "elm.arrow", x, y);
454
455    _update_colorbars(sd);
456    _color_picker_init(sd);
457    evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);
458 }
459
460 static void
461 _entry_changed_cb(void *data,
462                   Evas_Object *obj,
463                   void *event_info EINA_UNUSED)
464 {
465    Elm_Colorselector_Data *sd = data;
466    Evas_Object *parent;
467    const char *text;
468    int i, v;
469
470    for (i = 0; i < 4 && sd->entries[i] != obj; i++);
471
472    parent = evas_object_data_get(obj, "parent");
473    text = elm_object_text_get(obj);
474    v = atoi(text);
475    if (v > 255) v = 255;
476    else if (v < 0) v = 0;
477    evas_object_data_set(obj, "_changed", obj);
478
479    switch (i)
480      {
481       case 0:
482          _colors_set(parent, v, sd->g, sd->b, sd->a);
483          break;
484       case 1:
485          _colors_set(parent, sd->r, v, sd->b, sd->a);
486          break;
487       case 2:
488          _colors_set(parent, sd->r, sd->g, v, sd->a);
489          break;
490       case 3:
491          _colors_set(parent, sd->r, sd->g, sd->b, v);
492          break;
493      }
494    evas_object_data_del(obj, "_changed");
495 }
496
497 #ifdef HAVE_ELEMENTARY_X
498 static Eina_Bool _mouse_grab_pixels(void *data, int type EINA_UNUSED, void *event EINA_UNUSED);
499 static Eina_Bool _key_up_cb(void *data, int type EINA_UNUSED, void *event EINA_UNUSED);
500 static Eina_Bool _mouse_up_cb(void *data, int type EINA_UNUSED, void *event EINA_UNUSED);
501
502 static Ecore_X_Window
503 _x11_elm_widget_xwin_get(const Evas_Object *obj)
504 {
505    Evas_Object *top;
506    Ecore_X_Window xwin = 0;
507
508    top = elm_widget_top_get(obj);
509    if (!top) top = elm_widget_top_get(elm_widget_parent_widget_get(obj));
510    if (top) xwin = elm_win_xwindow_get(top);
511    if (!xwin)
512      {
513         Ecore_Evas *ee;
514         Evas *evas = evas_object_evas_get(obj);
515         if (!evas) return 0;
516         ee = ecore_evas_ecore_evas_get(evas);
517         if (!ee) return 0;
518         xwin = _elm_ee_xwin_get(ee);
519      }
520    return xwin;
521 }
522
523 static void
524 _start_grab_pick_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
525 {
526    Evas_Object *o = data;
527
528    ELM_COLORSELECTOR_DATA_GET(o, sd);
529
530    elm_object_disabled_set(obj, EINA_TRUE);
531
532    sd->grab.mouse_motion = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _mouse_grab_pixels, o);
533    sd->grab.key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_up_cb, o);
534    sd->grab.mouse_up = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _mouse_up_cb, o);
535
536    ecore_x_keyboard_grab(sd->grab.xroot);
537    ecore_x_pointer_grab(sd->grab.xroot);
538 }
539
540 static Eina_Bool
541 _key_up_cb(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
542 {
543    Evas_Object *o = data;
544
545    /* key => cancel */
546    ELM_COLORSELECTOR_DATA_GET(o, sd);
547
548    elm_object_disabled_set(sd->button, EINA_FALSE);
549    ecore_x_keyboard_ungrab();
550    ecore_x_pointer_ungrab();
551    ELM_SAFE_FREE(sd->grab.mouse_motion, ecore_event_handler_del);
552    ELM_SAFE_FREE(sd->grab.key_up, ecore_event_handler_del);
553    ELM_SAFE_FREE(sd->grab.mouse_up, ecore_event_handler_del);
554
555    return EINA_TRUE;
556 }
557
558 static Eina_Bool
559 _mouse_up_cb(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
560 {
561    const unsigned int *pixels;
562    Evas_Object *o = data;
563    int r, g, b;
564
565    /* mouse up => check it */
566    ELM_COLORSELECTOR_DATA_GET(o, sd);
567
568    elm_object_disabled_set(sd->button, EINA_FALSE);
569    ecore_x_keyboard_ungrab();
570    ecore_x_pointer_ungrab();
571    ELM_SAFE_FREE(sd->grab.mouse_motion, ecore_event_handler_del);
572    ELM_SAFE_FREE(sd->grab.key_up, ecore_event_handler_del);
573    ELM_SAFE_FREE(sd->grab.mouse_up, ecore_event_handler_del);
574
575    pixels = evas_object_image_data_get(sd->picker_display, EINA_FALSE);
576    r = (pixels[17 * 9 + 9] >> 16) & 0xFF;
577    g = (pixels[17 * 9 + 9] >> 8) & 0xFF;
578    b = pixels[17 * 9 + 9] & 0xFF;
579
580    _colors_set(o, r, g, b, 0xFF);
581
582    return EINA_TRUE;
583 }
584
585 static Eina_Bool
586 _mouse_grab_pixels(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
587 {
588    Evas_Object *obj = data;
589    Ecore_X_Visual visual;
590    Ecore_X_Display *display;
591    Ecore_X_Screen *scr;
592    Ecore_X_Image *img;
593    Ecore_X_Window xwin;
594    int *src;
595    int bpl = 0, rows = 0, bpp = 0;
596    int x, y, w, h;
597
598    ELM_COLORSELECTOR_DATA_GET(obj, sd);
599
600    if (sd->grab.in) return EINA_TRUE;
601
602    xwin = _x11_elm_widget_xwin_get(obj);
603    sd->grab.xroot = ecore_x_window_root_get(xwin);
604    ecore_x_pointer_xy_get(sd->grab.xroot, &x, &y);
605
606    if (x < 8) x += 8;
607    if (y < 8) y += 8;
608
609    if (sd->grab.x == x && sd->grab.y == y) return EINA_TRUE;
610    sd->grab.x = x;
611    sd->grab.y = y;
612
613    evas_object_image_alpha_set(sd->picker_display, EINA_FALSE);
614
615    display = ecore_x_display_get();
616    scr = ecore_x_default_screen_get();
617    visual = ecore_x_default_visual_get(display, scr);
618    img = ecore_x_image_new(17, 17, visual, ecore_x_window_depth_get(sd->grab.xroot));
619    ecore_x_image_get(img, sd->grab.xroot, x - 8, y - 8, 0, 0, 17, 17);
620    src = ecore_x_image_data_get(img, &bpl, &rows, &bpp);
621    if (!ecore_x_image_is_argb32_get(img))
622      {
623         Ecore_X_Colormap colormap;
624         unsigned int *pixels;
625
626         colormap = ecore_x_default_colormap_get(display, scr);
627         pixels = evas_object_image_data_get(sd->picker_display, EINA_TRUE);
628         ecore_x_image_to_argb_convert(src, bpp, bpl, colormap, visual,
629                                       0, 0, 17, 17,
630                                       pixels, (17 * sizeof(int)), 0, 0);
631      }
632    else
633      {
634         evas_object_image_data_copy_set(sd->picker_display, src);
635      }
636
637    ecore_x_image_free(img);
638
639    evas_object_geometry_get(sd->picker_display, NULL, NULL, &w, &h);
640    evas_object_image_data_update_add(sd->picker_display, 0, 0, w, h);
641
642    return EINA_TRUE;
643 }
644 #endif
645
646 static void
647 _mouse_in_canvas(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
648 {
649    Evas_Object *obj = data;
650    ELM_COLORSELECTOR_DATA_GET(obj, sd);
651
652    sd->grab.in = EINA_TRUE;
653 }
654
655 static void
656 _mouse_out_canvas(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
657 {
658    Evas_Object *obj = data;
659    ELM_COLORSELECTOR_DATA_GET(obj, sd);
660
661    sd->grab.in = EINA_FALSE;
662 }
663
664 static void
665 _color_picker_add(Evas_Object *obj, Elm_Colorselector_Data *sd)
666 {
667    Evas_Object *ed;
668    Evas_Object *im;
669    Evas_Object *label;
670    Evas_Object *entry;
671    Evas_Object *table;
672    Evas_Object *bx;
673    static const char *labels[4] = { "R:", "G:", "B:", "A:" };
674    int i;
675 #ifdef HAVE_ELEMENTARY_X
676    Ecore_X_Window xwin;
677
678    xwin = _x11_elm_widget_xwin_get(obj);
679    if (xwin)
680      {
681         sd->grab.xroot = ecore_x_window_root_get(xwin);
682         ecore_x_input_raw_select(sd->grab.xroot);
683      }
684 #endif
685
686    bx = elm_box_add(sd->picker);
687    evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
688    evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, EVAS_HINT_FILL);
689    elm_box_pack_end(sd->picker, bx);
690    evas_object_show(bx);
691
692    ed = edje_object_add(evas_object_evas_get(sd->picker));
693    elm_widget_theme_object_set(obj, ed, "colorselector", "picker", elm_widget_style_get(obj));
694    evas_object_size_hint_weight_set(ed, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
695    evas_object_size_hint_align_set(ed, EVAS_HINT_FILL, EVAS_HINT_FILL);
696    elm_box_pack_end(bx, ed);
697    evas_object_show(ed);
698
699 #ifdef HAVE_ELEMENTARY_X
700    if (xwin)
701      {
702         sd->button = elm_button_add(sd->picker);
703         elm_object_text_set(sd->button, "Pick a color");
704         evas_object_smart_callback_add(sd->button, "clicked", _start_grab_pick_cb, obj);
705         elm_box_pack_end(bx, sd->button);
706         evas_object_show(sd->button);
707      }
708 #endif
709
710    im = evas_object_image_add(evas_object_evas_get(sd->picker));
711    evas_object_size_hint_aspect_set(im, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
712    evas_object_image_smooth_scale_set(im, EINA_FALSE);
713    evas_object_image_colorspace_set(im, EVAS_COLORSPACE_ARGB8888);
714    evas_object_image_size_set(im, 17, 17);
715    evas_object_image_alpha_set(im, EINA_TRUE);
716    evas_object_image_filled_set(im, EINA_TRUE);
717    edje_object_part_swallow(ed, "elm.picker", im);
718    elm_widget_sub_object_add(obj, im);
719
720    sd->picker_display = im;
721
722    table = elm_table_add(sd->picker);
723    evas_object_size_hint_weight_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
724    evas_object_size_hint_align_set(table, EVAS_HINT_FILL, EVAS_HINT_FILL);
725    elm_box_pack_end(sd->picker, table);
726    evas_object_show(table);
727
728    for (i = 0; i < 4; i++)
729      {
730         static Elm_Entry_Filter_Accept_Set accept_set = {
731           .accepted = "0123456789",
732           .rejected = NULL
733         };
734
735         label = elm_label_add(table);
736         elm_object_text_set(label, labels[i]);
737         evas_object_size_hint_weight_set(label, 0.0, EVAS_HINT_EXPAND);
738         evas_object_size_hint_align_set(label, 0.0, EVAS_HINT_FILL);
739         elm_table_pack(table, label, 0, i, 1, 1);
740         evas_object_show(label);
741
742         entry = elm_entry_add(table);
743         elm_entry_markup_filter_append(entry, elm_entry_filter_accept_set, &accept_set);
744         elm_entry_single_line_set(entry, EINA_TRUE);
745         elm_entry_scrollable_set(entry, EINA_TRUE);
746         evas_object_data_set(entry, "parent", obj);
747         evas_object_smart_callback_add(entry, "changed", _entry_changed_cb, sd);
748         evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
749         evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
750         elm_table_pack(table, entry, 1, i, 1, 1);
751         evas_object_show(entry);
752
753         sd->entries[i] = entry;
754      }
755
756    evas_event_callback_add(evas_object_evas_get(obj), EVAS_CALLBACK_CANVAS_FOCUS_IN, _mouse_in_canvas, obj);
757    evas_event_callback_add(evas_object_evas_get(obj), EVAS_CALLBACK_CANVAS_FOCUS_OUT, _mouse_out_canvas, obj);
758
759    _color_picker_init(sd);
760 }
761
762 static void
763 _arrow_cb(void *data,
764           Evas_Object *obj,
765           const char *emission EINA_UNUSED,
766           const char *source EINA_UNUSED)
767 {
768    Color_Bar_Data *cb_data = data;
769    double x, y;
770
771    edje_object_part_drag_value_get(obj, "elm.arrow", &x, &y);
772    _update_hsla_from_colorbar(cb_data->parent, cb_data->color_type, x);
773 }
774
775 static void
776 _colorbar_cb(void *data,
777              Evas *e,
778              Evas_Object *obj EINA_UNUSED,
779              void *event_info)
780 {
781    Evas_Event_Mouse_Down *ev = event_info;
782    Color_Bar_Data *cb_data = data;
783    double arrow_x = 0, arrow_y;
784    Evas_Coord x, y, w, h;
785    ELM_COLORSELECTOR_DATA_GET(cb_data->parent, sd);
786
787    evas_object_geometry_get(cb_data->bar, &x, &y, &w, &h);
788    edje_object_part_drag_value_get
789      (cb_data->colorbar, "elm.arrow", &arrow_x, &arrow_y);
790
791    if (w > 0) arrow_x = (double)(ev->canvas.x - x) / (double)w;
792    if (arrow_x > 1) arrow_x = 1;
793    if (arrow_x < 0) arrow_x = 0;
794    edje_object_part_drag_value_set
795      (cb_data->colorbar, "elm.arrow", arrow_x, arrow_y);
796
797    _update_hsla_from_colorbar(cb_data->parent, cb_data->color_type, arrow_x);
798    evas_event_feed_mouse_cancel(e, 0, NULL);
799    evas_event_feed_mouse_down(e, 1, EVAS_BUTTON_NONE, 0, NULL);
800    sd->sel_color_type = cb_data->color_type;
801    sd->focused = ELM_COLORSELECTOR_COMPONENTS;
802 }
803
804 static void
805 _button_clicked_cb(void *data,
806                    Evas_Object *obj,
807                    void *event_info EINA_UNUSED)
808 {
809    Color_Bar_Data *cb_data = data;
810    double x, y, step;
811    ELM_COLORSELECTOR_DATA_GET(cb_data->parent, sd);
812
813    if (obj == cb_data->rbt) step = 1.0;
814    else step = -1.0;
815
816    edje_object_part_drag_value_get(cb_data->colorbar, "elm.arrow", &x, &y);
817
818    switch (cb_data->color_type)
819      {
820       case HUE:
821         x += step / HUE_STEP;
822         break;
823
824       case SATURATION:
825         x += step / SAT_STEP;
826         break;
827
828       case LIGHTNESS:
829         x += step / LIG_STEP;
830         break;
831
832       case ALPHA:
833         x += step / ALP_STEP;
834         break;
835
836       default:
837         break;
838      }
839
840    if (x > 1.0) x = 1.0;
841    else if (x < 0.0) x = 0.0;
842
843    edje_object_part_drag_value_set(cb_data->colorbar, "elm.arrow", x, y);
844    _update_hsla_from_colorbar(cb_data->parent, cb_data->color_type, x);
845    sd->sel_color_type = cb_data->color_type;
846    sd->focused = ELM_COLORSELECTOR_COMPONENTS;
847 }
848
849 static void
850 _button_repeat_cb(void *data,
851                   Evas_Object *obj EINA_UNUSED,
852                   void *event_info EINA_UNUSED)
853 {
854    Color_Bar_Data *cb_data = data;
855    double x, y, step;
856
857    if (obj == cb_data->rbt) step = 1.0 / BASE_STEP;
858    else step = -1.0 / BASE_STEP;
859
860    edje_object_part_drag_value_get(cb_data->colorbar, "elm.arrow", &x, &y);
861    x += step;
862
863    if (x > 1.0) x = 1.0;
864    else if (x < 0.0) x = 0.0;
865
866    edje_object_part_drag_value_set(cb_data->colorbar, "elm.arrow", x, y);
867    _update_hsla_from_colorbar(cb_data->parent, cb_data->color_type, x);
868 }
869
870 static void
871 _access_colorbar_register(Evas_Object *obj,
872                           Color_Bar_Data *cd,
873                           const char* part)
874 {
875    Evas_Object *ao;
876    Elm_Access_Info *ai;
877    const char* colorbar_type = NULL;
878
879    ao = _elm_access_edje_object_part_object_register(obj, cd->colorbar, part);
880    ai = _elm_access_info_get(ao);
881
882    switch (cd->color_type)
883      {
884       case HUE:
885         colorbar_type = "hue color bar";
886         break;
887
888       case SATURATION:
889         colorbar_type = "saturation color bar";
890         break;
891
892       case LIGHTNESS:
893         colorbar_type = "lightness color bar";
894         break;
895
896       case ALPHA:
897         colorbar_type = "alpha color bar";
898         break;
899
900       default:
901         break;
902      }
903
904    _elm_access_text_set(ai, ELM_ACCESS_TYPE, colorbar_type);
905
906    // this will be used in focus_next();
907    cd->access_obj = ao;
908 }
909
910 static void
911 _color_bars_add(Evas_Object *obj)
912 {
913    char colorbar_name[128];
914    char colorbar_s[128];
915    char buf[1024];
916    int i = 0;
917    Evas *e;
918
919    ELM_COLORSELECTOR_DATA_GET(obj, sd);
920
921    e = evas_object_evas_get(obj);
922
923    for (i = 0; i < 4; i++)
924      {
925         sd->cb_data[i] = ELM_NEW(Color_Bar_Data);
926         sd->cb_data[i]->parent = obj;
927
928         switch (i)
929           {
930            case 0:
931              sd->cb_data[i]->color_type = HUE;
932              break;
933
934            case 1:
935              sd->cb_data[i]->color_type = SATURATION;
936              break;
937
938            case 2:
939              sd->cb_data[i]->color_type = LIGHTNESS;
940              break;
941
942            case 3:
943              sd->cb_data[i]->color_type = ALPHA;
944              break;
945           }
946
947         /* load colorbar area */
948         sd->cb_data[i]->colorbar = edje_object_add(e);
949         elm_widget_theme_object_set
950           (obj, sd->cb_data[i]->colorbar, "colorselector", "base",
951           elm_widget_style_get(obj));
952         snprintf(colorbar_name, sizeof(colorbar_name), "colorbar_%d", i);
953         snprintf(colorbar_s, sizeof(colorbar_s), "elm.colorbar_%d", i);
954         edje_object_signal_callback_add
955           (sd->cb_data[i]->colorbar, "drag", "*", _arrow_cb, sd->cb_data[i]);
956         edje_object_part_swallow
957           (sd->col_bars_area, colorbar_s, sd->cb_data[i]->colorbar);
958         elm_widget_sub_object_add(obj, sd->cb_data[i]->colorbar);
959
960         /* load colorbar image */
961         sd->cb_data[i]->bar = edje_object_add(e);
962         snprintf(buf, sizeof(buf), "%s/%s", colorbar_name,
963                  elm_widget_style_get(obj));
964         elm_widget_theme_object_set
965           (obj, sd->cb_data[i]->bar, "colorselector", "image", buf);
966         edje_object_part_swallow
967           (sd->cb_data[i]->colorbar, "elm.bar", sd->cb_data[i]->bar);
968         elm_widget_sub_object_add(obj, sd->cb_data[i]->bar);
969
970         /* provide expanded touch area */
971         sd->cb_data[i]->touch_area = evas_object_rectangle_add(e);
972         evas_object_color_set(sd->cb_data[i]->touch_area, 0, 0, 0, 0);
973         edje_object_part_swallow
974           (sd->cb_data[i]->colorbar, "elm.arrow_bg",
975           sd->cb_data[i]->touch_area);
976         evas_object_event_callback_add
977           (sd->cb_data[i]->touch_area, EVAS_CALLBACK_MOUSE_DOWN, _colorbar_cb,
978           sd->cb_data[i]);
979         elm_widget_sub_object_add(obj, sd->cb_data[i]->touch_area);
980
981         // ACCESS
982         if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
983            _access_colorbar_register(obj, sd->cb_data[i], "elm.arrow_bg_access");
984
985         /* load background rectangle of the colorbar. used for
986            changing color of the opacity bar */
987         if ((i == 1) || (i == 2))
988           {
989              sd->cb_data[i]->bg_rect = evas_object_rectangle_add(e);
990              evas_object_color_set
991                (sd->cb_data[i]->bg_rect, sd->er, sd->eg, sd->eb, 255);
992              edje_object_part_swallow
993                (sd->cb_data[i]->colorbar, "elm.bar_bg",
994                sd->cb_data[i]->bg_rect);
995
996              elm_widget_sub_object_add(obj, sd->cb_data[i]->bg_rect);
997           }
998         if (i == 3)
999           {
1000              sd->cb_data[i]->bg_rect = edje_object_add(e);
1001              snprintf(buf, sizeof(buf), "%s/%s", colorbar_name,
1002                       elm_widget_style_get(obj));
1003              elm_widget_theme_object_set
1004                (obj, sd->cb_data[i]->bg_rect, "colorselector", "bg_image",
1005                buf);
1006              edje_object_part_swallow
1007                (sd->cb_data[i]->colorbar, "elm.bar_bg",
1008                sd->cb_data[i]->bg_rect);
1009              elm_widget_sub_object_add(obj, sd->cb_data[i]->bg_rect);
1010              evas_object_color_set
1011                (sd->cb_data[i]->bar, sd->er, sd->eg, sd->eb, 255);
1012           }
1013
1014         /* load arrow image, pointing the colorbar */
1015         sd->cb_data[i]->arrow = edje_object_add(e);
1016         elm_widget_theme_object_set
1017           (obj, sd->cb_data[i]->arrow, "colorselector", "arrow",
1018           elm_widget_style_get(obj));
1019         edje_object_part_swallow
1020           (sd->cb_data[i]->colorbar, "elm.arrow_icon",
1021           sd->cb_data[i]->arrow);
1022         elm_widget_sub_object_add(obj, sd->cb_data[i]->arrow);
1023
1024         if (i == 2)
1025           evas_object_color_set(sd->cb_data[i]->arrow, 0, 0, 0, 255);
1026         else
1027           evas_object_color_set
1028             (sd->cb_data[i]->arrow, sd->er, sd->eg, sd->eb, 255);
1029
1030         /* load left button */
1031         sd->cb_data[i]->lbt = elm_button_add(obj);
1032         snprintf(buf, sizeof(buf), "colorselector/left/%s",
1033                  elm_widget_style_get(obj));
1034         elm_object_style_set(sd->cb_data[i]->lbt, buf);
1035         elm_widget_sub_object_add(obj, sd->cb_data[i]->lbt);
1036         edje_object_part_swallow
1037           (sd->cb_data[i]->colorbar, "elm.l_button", sd->cb_data[i]->lbt);
1038         evas_object_smart_callback_add
1039           (sd->cb_data[i]->lbt, "clicked", _button_clicked_cb,
1040           sd->cb_data[i]);
1041         elm_button_autorepeat_set(sd->cb_data[i]->lbt, EINA_TRUE);
1042         elm_button_autorepeat_initial_timeout_set
1043           (sd->cb_data[i]->lbt, _elm_config->longpress_timeout);
1044         elm_button_autorepeat_gap_timeout_set
1045           (sd->cb_data[i]->lbt, (1.0 / _elm_config->fps));
1046         evas_object_smart_callback_add
1047           (sd->cb_data[i]->lbt, "repeated", _button_repeat_cb,
1048           sd->cb_data[i]);
1049
1050         /* load right button */
1051         sd->cb_data[i]->rbt = elm_button_add(obj);
1052         snprintf(buf, sizeof(buf), "colorselector/right/%s",
1053                  elm_widget_style_get(obj));
1054         elm_object_style_set(sd->cb_data[i]->rbt, buf);
1055         elm_widget_sub_object_add(obj, sd->cb_data[i]->rbt);
1056         edje_object_part_swallow
1057           (sd->cb_data[i]->colorbar, "elm.r_button", sd->cb_data[i]->rbt);
1058         evas_object_smart_callback_add
1059           (sd->cb_data[i]->rbt, "clicked", _button_clicked_cb,
1060           sd->cb_data[i]);
1061         elm_button_autorepeat_set(sd->cb_data[i]->rbt, EINA_TRUE);
1062         elm_button_autorepeat_initial_timeout_set
1063           (sd->cb_data[i]->rbt, _elm_config->longpress_timeout);
1064         elm_button_autorepeat_gap_timeout_set
1065           (sd->cb_data[i]->rbt, (1.0 / _elm_config->fps));
1066         evas_object_smart_callback_add
1067           (sd->cb_data[i]->rbt, "repeated", _button_repeat_cb,
1068           sd->cb_data[i]);
1069      }
1070 }
1071
1072 EOLIAN static Eina_Bool
1073 _elm_colorselector_elm_widget_theme_apply(Eo *obj, Elm_Colorselector_Data *sd)
1074 {
1075    int i;
1076    Eina_List *elist;
1077    Elm_Color_Item *item;
1078    const char *hpadstr, *vpadstr;
1079    unsigned int h_pad = DEFAULT_HOR_PAD;
1080    unsigned int v_pad = DEFAULT_VER_PAD;
1081
1082    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1083    Eina_Bool int_ret = EINA_FALSE;
1084
1085    eo_do_super(obj, MY_CLASS, elm_obj_widget_theme_apply(&int_ret));
1086    if (!int_ret) return EINA_FALSE;
1087
1088    if (!sd->col_bars_area) return EINA_FALSE;
1089
1090    elm_widget_theme_object_set
1091      (obj, sd->col_bars_area, "colorselector", "bg",
1092      elm_widget_style_get(obj));
1093
1094    hpadstr = edje_object_data_get
1095        (wd->resize_obj, "horizontal_pad");
1096    if (hpadstr) h_pad = atoi(hpadstr);
1097    vpadstr = edje_object_data_get
1098        (wd->resize_obj, "vertical_pad");
1099    if (vpadstr) v_pad = atoi(vpadstr);
1100
1101    elm_box_padding_set
1102      (sd->palette_box,
1103      (h_pad * elm_widget_scale_get(obj) * elm_config_scale_get()),
1104      (v_pad * elm_widget_scale_get(obj) * elm_config_scale_get()));
1105
1106    EINA_LIST_FOREACH(sd->items, elist, item)
1107      {
1108         if (!elm_layout_theme_set
1109             (VIEW(item), "colorselector", "item", elm_widget_style_get(obj)))
1110           CRI("Failed to set layout!");
1111
1112         elm_widget_theme_object_set
1113           (obj, item->color_obj, "colorselector", "item/color",
1114           elm_widget_style_get(obj));
1115      }
1116    for (i = 0; i < 4; i++)
1117      {
1118         if (sd->cb_data[i])
1119           {
1120              ELM_SAFE_FREE(sd->cb_data[i]->colorbar, evas_object_del);
1121              ELM_SAFE_FREE(sd->cb_data[i]->bar, evas_object_del);
1122              ELM_SAFE_FREE(sd->cb_data[i]->lbt, evas_object_del);
1123              ELM_SAFE_FREE(sd->cb_data[i]->rbt, evas_object_del);
1124              if (i != 0)
1125                ELM_SAFE_FREE(sd->cb_data[i]->bg_rect, evas_object_del);
1126              ELM_SAFE_FREE(sd->cb_data[i]->arrow, evas_object_del);
1127              ELM_SAFE_FREE(sd->cb_data[i]->touch_area, evas_object_del);
1128           }
1129      }
1130
1131    _color_bars_add(obj);
1132    elm_colorselector_color_set(obj, sd->r, sd->g, sd->b, sd->a);
1133
1134    elm_layout_sizing_eval(obj);
1135
1136    return EINA_TRUE;
1137 }
1138
1139 static void
1140 _sub_obj_size_hints_set(Evas_Object *sobj,
1141                         int timesw,
1142                         int timesh)
1143 {
1144    Evas_Coord minw = -1, minh = -1;
1145
1146    elm_coords_finger_size_adjust(timesw, &minw, timesh, &minh);
1147    if (sobj && eo_isa(sobj, EDJE_OBJ_CLASS))
1148      edje_object_size_min_restricted_calc(sobj, &minw, &minh, minw, minh);
1149    evas_object_size_hint_min_set(sobj, minw, minh);
1150    evas_object_size_hint_max_set(sobj, -1, -1);
1151 }
1152
1153 static void
1154 _item_sizing_eval(Elm_Color_Item *item)
1155 {
1156    Evas_Coord minw = -1, minh = -1;
1157    Evas_Object *edje;
1158
1159    if (!item) return;
1160    edje = elm_layout_edje_get(VIEW(item));
1161    if (!edje) return;
1162
1163    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1164    edje_object_size_min_restricted_calc(edje, &minw, &minh, minw, minh);
1165    evas_object_size_hint_min_set(VIEW(item), minw, minh);
1166 }
1167
1168 /* fix size hints of color palette items, so that the box gets it */
1169 static void
1170 _palette_sizing_eval(Evas_Object *obj)
1171 {
1172    Eina_List *elist;
1173    Elm_Color_Item *item;
1174
1175    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1176
1177    EINA_LIST_FOREACH(sd->items, elist, item)
1178      _item_sizing_eval(item);
1179 }
1180
1181 static void
1182 _component_sizing_eval(Evas_Object *obj)
1183 {
1184    Evas_Coord minw = -1, minh = -1;
1185    int i;
1186
1187    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1188
1189    for (i = 0; i < 4; i++)
1190      {
1191         if (sd->cb_data[i])
1192           {
1193              if (sd->cb_data[i]->bg_rect)
1194                _sub_obj_size_hints_set(sd->cb_data[i]->bg_rect, 1, 1);
1195
1196              _sub_obj_size_hints_set(sd->cb_data[i]->bar, 1, 1);
1197              _sub_obj_size_hints_set(sd->cb_data[i]->rbt, 1, 1);
1198              _sub_obj_size_hints_set(sd->cb_data[i]->lbt, 1, 1);
1199              _sub_obj_size_hints_set(sd->cb_data[i]->colorbar, 4, 1);
1200           }
1201      }
1202
1203    edje_object_size_min_restricted_calc
1204      (sd->col_bars_area, &minw, &minh, minw, minh);
1205    evas_object_size_hint_min_set(sd->col_bars_area, minw, minh);
1206 }
1207
1208 static void
1209 _full_sizing_eval(Evas_Object *obj)
1210 {
1211    _palette_sizing_eval(obj);
1212    _component_sizing_eval(obj);
1213 }
1214
1215 EOLIAN static void
1216 _elm_colorselector_elm_layout_sizing_eval(Eo *obj, Elm_Colorselector_Data *sd)
1217 {
1218    Evas_Coord minw = -1, minh = -1;
1219
1220    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1221
1222    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1223
1224    switch (sd->mode)
1225      {
1226       case ELM_COLORSELECTOR_PALETTE:
1227         _palette_sizing_eval(obj);
1228         break;
1229
1230       case ELM_COLORSELECTOR_COMPONENTS:
1231         _component_sizing_eval(obj);
1232         break;
1233
1234       case ELM_COLORSELECTOR_BOTH:
1235         _full_sizing_eval(obj);
1236         break;
1237
1238       default:
1239         return;
1240      }
1241
1242    evas_object_resize(sd->palette_box, minw, minh);
1243    evas_object_smart_calculate(sd->palette_box);
1244    edje_object_size_min_calc(wd->resize_obj, &minw, &minh);
1245    evas_object_size_hint_min_set(obj, minw, minh);
1246    evas_object_size_hint_max_set(obj, -1, -1);
1247 }
1248
1249 static void
1250 _on_resize(void *data EINA_UNUSED, Evas *e EINA_UNUSED,
1251            Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
1252 {
1253    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1254
1255    if ((sd->mode == ELM_COLORSELECTOR_PALETTE) ||
1256        (sd->mode == ELM_COLORSELECTOR_BOTH))
1257      {
1258         Evas_Coord w = 0, h = 0, minw = -1;
1259
1260         evas_object_size_hint_min_get(obj, &minw, NULL);
1261         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1262         if ((w != sd->_w) && (w < minw))
1263           elm_layout_sizing_eval(obj);
1264         sd->_w = w;
1265         sd->_h = h;
1266      }
1267 }
1268
1269 static Eina_Bool
1270 _on_color_long_press(void *data)
1271 {
1272    Elm_Color_Item *item = (Elm_Color_Item *)data;
1273
1274    ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd);
1275
1276    sd->longpress_timer = NULL;
1277
1278    evas_object_smart_callback_call
1279      (WIDGET(item), SIG_COLOR_ITEM_LONGPRESSED, item);
1280
1281    return ECORE_CALLBACK_CANCEL;
1282 }
1283
1284 static void
1285 _on_color_pressed(void *data,
1286                   Evas *e EINA_UNUSED,
1287                   Evas_Object *obj EINA_UNUSED,
1288                   void *event_info EINA_UNUSED)
1289 {
1290    Elm_Color_Item *item = (Elm_Color_Item *)data;
1291    Evas_Event_Mouse_Down *ev = event_info;
1292
1293    if (!item) return;
1294
1295    ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd);
1296
1297    if (ev->button != 1) return;
1298
1299    ecore_timer_del(sd->longpress_timer);
1300    sd->longpress_timer = ecore_timer_add
1301        (_elm_config->longpress_timeout, _on_color_long_press, data);
1302 }
1303
1304 static void
1305 _on_color_released(void *data,
1306                    Evas *e EINA_UNUSED,
1307                    Evas_Object *obj EINA_UNUSED,
1308                    void *event_info EINA_UNUSED)
1309 {
1310    Elm_Color_Item *item = (Elm_Color_Item *)data;
1311    Eina_List *l;
1312    Elm_Color_Item *temp_item;
1313    Evas_Event_Mouse_Down *ev = event_info;
1314    if (!item) return;
1315
1316    ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd);
1317
1318    if (ev->button != 1) return;
1319    ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
1320
1321    elm_object_signal_emit(VIEW(item), "elm,state,selected", "elm");
1322    elm_colorselector_color_set(WIDGET(item), item->color->r, item->color->g,
1323                                item->color->b, item->color->a);
1324    evas_object_smart_callback_call(WIDGET(item), SIG_COLOR_ITEM_SELECTED,
1325                                    item);
1326
1327    temp_item = eina_list_data_get(sd->selected);
1328    if (temp_item && (temp_item != item))
1329      elm_object_signal_emit(VIEW(temp_item), "elm,state,unselected", "elm");
1330
1331    EINA_LIST_FOREACH(sd->items, l, temp_item)
1332      if (item == temp_item) sd->selected = l;
1333    sd->focused = ELM_COLORSELECTOR_PALETTE;
1334 }
1335
1336 static char *
1337 _access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
1338 {
1339    char *ret;
1340    Eina_Strbuf *buf;
1341    int r = 0, g = 0, b = 0 ,a = 0;
1342
1343    Elm_Color_Item *it = data;
1344    ELM_COLORSELECTOR_ITEM_CHECK_OR_RETURN(it, NULL);
1345
1346    elm_colorselector_palette_item_color_get((Elm_Object_Item *)it, &r, &g, &b, &a);
1347
1348    buf = eina_strbuf_new();
1349    eina_strbuf_append_printf(buf, "red %d, green %d, blue %d, alpha %d", r, g, b, a);
1350    ret = eina_strbuf_string_steal(buf);
1351    eina_strbuf_free(buf);
1352    return ret;
1353 }
1354
1355 static void
1356 _access_widget_item_register(Elm_Color_Item *it)
1357 {
1358    Elm_Access_Info *ai;
1359
1360    _elm_access_widget_item_register((Elm_Widget_Item *)it);
1361
1362    ai = _elm_access_info_get(it->base.access_obj);
1363
1364    _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("color selector palette item"));
1365    _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1366 }
1367
1368 static void
1369 _item_resize(void *data EINA_UNUSED,
1370              Evas *e EINA_UNUSED,
1371              Evas_Object *obj,
1372              void *event_info EINA_UNUSED)
1373 {
1374    elm_layout_sizing_eval(obj);
1375 }
1376
1377 static void
1378 _item_signal_emit_hook(Elm_Object_Item *it,
1379                        const char *emission,
1380                        const char *source)
1381 {
1382    elm_object_signal_emit(VIEW(it), emission, source);
1383 }
1384
1385 static Elm_Color_Item *
1386 _item_new(Evas_Object *obj)
1387 {
1388    Elm_Color_Item *item;
1389
1390    item = elm_widget_item_new(obj, Elm_Color_Item);
1391    if (!item) return NULL;
1392
1393    VIEW(item) = elm_layout_add(obj);
1394    if (!elm_layout_theme_set
1395        (VIEW(item), "colorselector", "item", elm_widget_style_get(obj)))
1396      CRI("Failed to set layout!");
1397    evas_object_size_hint_weight_set
1398      (VIEW(item), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1399    evas_object_size_hint_align_set(VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
1400    evas_object_event_callback_add
1401      (VIEW(item), EVAS_CALLBACK_RESIZE, _item_resize, NULL);
1402
1403    item->color_obj = edje_object_add(evas_object_evas_get(obj));
1404    elm_widget_theme_object_set
1405      (obj, item->color_obj, "colorselector", "item/color",
1406      elm_widget_style_get(obj));
1407    evas_object_size_hint_weight_set
1408      (item->color_obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1409    evas_object_size_hint_align_set
1410      (item->color_obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
1411    evas_object_event_callback_add
1412      (item->color_obj, EVAS_CALLBACK_MOUSE_DOWN, _on_color_pressed, item);
1413    evas_object_event_callback_add
1414      (item->color_obj, EVAS_CALLBACK_MOUSE_UP, _on_color_released, item);
1415    elm_object_part_content_set(VIEW(item), "color_obj", item->color_obj);
1416
1417    elm_widget_item_signal_emit_hook_set(item, _item_signal_emit_hook);
1418
1419    _item_sizing_eval(item);
1420    evas_object_show(VIEW(item));
1421
1422    // ACCESS
1423    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
1424      _access_widget_item_register(item);
1425
1426    return item;
1427 }
1428
1429 static void
1430 _colors_remove(Evas_Object *obj)
1431 {
1432    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1433
1434    _items_del(sd);
1435    _elm_config_colors_free(sd->palette_name);
1436 }
1437
1438 static void
1439 _colors_save(Evas_Object *obj)
1440 {
1441    Eina_List *elist;
1442    Elm_Color_Item *item;
1443
1444    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1445
1446    _elm_config_colors_free(sd->palette_name);
1447    EINA_LIST_FOREACH(sd->items, elist, item)
1448      _elm_config_color_set(sd->palette_name, item->color->r, item->color->g,
1449                            item->color->b, item->color->a);
1450 }
1451
1452 static void
1453 _palette_colors_load(Evas_Object *obj)
1454 {
1455    Eina_List *elist;
1456    Elm_Color_Item *item;
1457    Eina_List *color_list;
1458    Elm_Color_RGBA *color;
1459
1460    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1461
1462    color_list = _elm_config_color_list_get(sd->palette_name);
1463    if (!color_list) return;
1464
1465    EINA_LIST_FOREACH(color_list, elist, color)
1466      {
1467         item = _item_new(obj);
1468         if (!item) return;
1469
1470         item->color = ELM_NEW(Elm_Color_RGBA);
1471         if (!item->color) return;
1472         item->color->r = color->r;
1473         item->color->g = color->g;
1474         item->color->b = color->b;
1475         item->color->a = color->a;
1476
1477         elm_box_pack_end(sd->palette_box, VIEW(item));
1478         evas_object_color_set(item->color_obj,
1479                               (item->color->r * item->color->a) / 255,
1480                               (item->color->g * item->color->a) / 255,
1481                               (item->color->b * item->color->a) / 255,
1482                               item->color->a);
1483
1484         sd->items = eina_list_append(sd->items, item);
1485      }
1486
1487    sd->config_load = EINA_TRUE;
1488 }
1489
1490 EOLIAN static void
1491 _elm_colorselector_evas_smart_add(Eo *obj, Elm_Colorselector_Data *priv)
1492 {
1493    const char *hpadstr, *vpadstr;
1494    unsigned int h_pad = DEFAULT_HOR_PAD;
1495    unsigned int v_pad = DEFAULT_VER_PAD;
1496
1497    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1498
1499    eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
1500    elm_widget_sub_object_parent_add(obj);
1501
1502    if (!elm_layout_theme_set
1503        (obj, "colorselector", "palette", elm_object_style_get(obj)))
1504      CRI("Failed to set layout!");
1505
1506    priv->palette_box = elm_box_add(obj);
1507    elm_box_layout_set
1508      (priv->palette_box, evas_object_box_layout_flow_horizontal, NULL, NULL);
1509    elm_box_horizontal_set(priv->palette_box, EINA_TRUE);
1510    evas_object_size_hint_weight_set
1511      (priv->palette_box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1512    evas_object_size_hint_align_set
1513      (priv->palette_box, EVAS_HINT_FILL, EVAS_HINT_FILL);
1514    elm_box_homogeneous_set(priv->palette_box, EINA_TRUE);
1515
1516    hpadstr = edje_object_data_get(wd->resize_obj, "horizontal_pad");
1517    if (hpadstr) h_pad = atoi(hpadstr);
1518    vpadstr = edje_object_data_get(wd->resize_obj, "vertical_pad");
1519    if (vpadstr) v_pad = atoi(vpadstr);
1520
1521    elm_box_padding_set
1522      (priv->palette_box,
1523      (h_pad * elm_widget_scale_get(obj) * elm_config_scale_get()),
1524      (v_pad * elm_widget_scale_get(obj) * elm_config_scale_get()));
1525
1526    elm_box_align_set(priv->palette_box, 0.5, 0.5);
1527    if (!elm_layout_content_set(obj, "elm.palette", priv->palette_box))
1528      elm_layout_content_set(obj, "palette", priv->palette_box);
1529    priv->palette_name = eina_stringshare_add("default");
1530    _palette_colors_load(obj);
1531
1532    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _on_resize, NULL);
1533
1534    /* load background edj */
1535    priv->col_bars_area = edje_object_add(evas_object_evas_get(obj));
1536    elm_widget_theme_object_set
1537      (obj, priv->col_bars_area, "colorselector", "bg",
1538          elm_widget_style_get(obj));
1539    if (!elm_layout_content_set(obj, "elm.selector", priv->col_bars_area))
1540      elm_layout_content_set(obj, "selector", priv->col_bars_area);
1541
1542    elm_layout_signal_emit(obj, "elm,state,both", "elm");
1543
1544    /* setup the color picker */
1545    priv->picker = elm_box_add(obj);
1546    elm_box_horizontal_set(priv->picker, EINA_TRUE);
1547    evas_object_size_hint_weight_set(priv->picker, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1548    evas_object_size_hint_align_set(priv->picker, EVAS_HINT_FILL, EVAS_HINT_FILL);
1549
1550    elm_box_padding_set(priv->picker,
1551                        (h_pad * elm_widget_scale_get(obj) * elm_config_scale_get()),
1552                        (v_pad * elm_widget_scale_get(obj) * elm_config_scale_get()));
1553    elm_box_align_set(priv->palette_box, 0.5, 0.5);
1554
1555    priv->mode = ELM_COLORSELECTOR_BOTH;
1556    priv->focused = ELM_COLORSELECTOR_PALETTE;
1557    priv->sel_color_type = HUE;
1558    priv->selected = priv->items;
1559    priv->er = 255;
1560    priv->eg = 0;
1561    priv->eb = 0;
1562    priv->h = 0.0;
1563    priv->s = 1.0;
1564    priv->l = 0.0;
1565    priv->a = 255;
1566    priv->grab.x = -1;
1567    priv->grab.y = -1;
1568 #ifdef HAVE_ELEMENTARY_X
1569    priv->grab.xroot = -1;
1570 #endif
1571    priv->grab.in = EINA_TRUE;
1572
1573    _hsl_to_rgb(priv);
1574    _color_bars_add(obj);
1575    _color_picker_add(obj, priv);
1576
1577    elm_layout_sizing_eval(obj);
1578    elm_widget_can_focus_set(obj, EINA_TRUE);
1579 }
1580
1581 EOLIAN static void
1582 _elm_colorselector_evas_smart_del(Eo *obj, Elm_Colorselector_Data *sd)
1583 {
1584    int i = 0;
1585    void *tmp[4];
1586
1587
1588    evas_event_callback_del_full(evas_object_evas_get(obj), EVAS_CALLBACK_CANVAS_FOCUS_IN, _mouse_in_canvas, obj);
1589    evas_event_callback_del_full(evas_object_evas_get(obj), EVAS_CALLBACK_CANVAS_FOCUS_OUT, _mouse_out_canvas, obj);
1590
1591    ecore_timer_del(sd->longpress_timer);
1592    eina_stringshare_del(sd->palette_name);
1593
1594 #ifdef HAVE_ELEMENTARY_X
1595    ecore_event_handler_del(sd->grab.mouse_motion);
1596    ecore_event_handler_del(sd->grab.mouse_up);
1597    ecore_event_handler_del(sd->grab.key_up);
1598 #endif
1599
1600    _items_del(sd);
1601    /* This cb_data are used during the destruction process of base.del */
1602    for (i = 0; i < 4; i++)
1603      tmp[i] = sd->cb_data[i];
1604    eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
1605    for (i = 0; i < 4; i++)
1606      free(tmp[i]);
1607 }
1608
1609 static Eina_List*
1610 _palette_box_vertical_item_get(Eina_List* ref_item, enum Palette_Box_Direction dir)
1611 {
1612    Evas_Coord basex, basey, x, y, dx, min_dx;
1613    Elm_Color_Item *item;
1614    Eina_List* l;
1615    Eina_List* res = NULL;
1616    Eina_List* (*dir_func)(const Eina_List*);
1617
1618    if (!ref_item) return NULL;
1619
1620    switch(dir)
1621      {
1622         case PALETTE_BOX_UP:
1623           dir_func = eina_list_prev;
1624           break;
1625         case PALETTE_BOX_DOWN:
1626           dir_func = eina_list_next;
1627           break;
1628         default:
1629           return NULL;
1630      }
1631
1632    item = eina_list_data_get(ref_item);
1633    evas_object_geometry_get(VIEW(item), &basex, &basey, NULL, NULL);
1634
1635    for (l = ref_item; l; l = dir_func(l))
1636      {
1637         item = eina_list_data_get(l);
1638         evas_object_geometry_get(VIEW(item), &x, &y, NULL, NULL);
1639         if (basey != y) break;
1640      }
1641
1642    basey = y;
1643    min_dx = -1;
1644
1645    for (; l; l = dir_func(l))
1646      {
1647         item = eina_list_data_get(l);
1648         evas_object_geometry_get(VIEW(item), &x, &y, NULL, NULL);
1649         if (basey != y) break;
1650
1651         dx = abs(x - basex);
1652         if (dx < min_dx || min_dx < 0)
1653           {
1654              min_dx = dx;
1655              res = l;
1656           }
1657         else
1658           {
1659              break;
1660           }
1661       }
1662
1663    return res;
1664 }
1665
1666 static Eina_Bool
1667 _key_action_move(Evas_Object *obj, const char *params)
1668 {
1669    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1670    Eina_List *cl = NULL;
1671    Elm_Color_Item *item = NULL;
1672    char colorbar_s[128];
1673    char *dir = params;
1674
1675    if (!strcmp(dir, "left"))
1676      {
1677         if (sd->focused == ELM_COLORSELECTOR_PALETTE && sd->selected)
1678           cl = eina_list_prev(sd->selected);
1679                   else if (sd->focused == ELM_COLORSELECTOR_COMPONENTS)
1680           _button_clicked_cb(sd->cb_data[sd->sel_color_type],
1681                              sd->cb_data[sd->sel_color_type]->lbt, NULL);
1682         else return EINA_FALSE;
1683      }
1684    else if (!strcmp(dir, "right"))
1685      {
1686         if (sd->focused == ELM_COLORSELECTOR_PALETTE && sd->selected)
1687           cl = eina_list_next(sd->selected);
1688         else if (sd->focused == ELM_COLORSELECTOR_COMPONENTS)
1689           _button_clicked_cb(sd->cb_data[sd->sel_color_type],
1690                              sd->cb_data[sd->sel_color_type]->rbt, NULL);
1691         else return EINA_FALSE;
1692      }
1693    else if (!strcmp(dir, "up"))
1694      {
1695         if (sd->focused == ELM_COLORSELECTOR_COMPONENTS)
1696           {
1697              sd->sel_color_type = sd->sel_color_type - 1;
1698              if (sd->sel_color_type < HUE)
1699                {
1700                   if (sd->mode == ELM_COLORSELECTOR_BOTH)
1701                     {
1702                        sd->focused = ELM_COLORSELECTOR_PALETTE;
1703                        /*when focus is shifted to palette start from
1704                         * first item*/
1705                        sd->selected = sd->items;
1706                        cl = sd->selected;
1707                     }
1708                   else
1709                     {
1710                        sd->sel_color_type = HUE;
1711                        return EINA_FALSE;
1712                     }
1713                }
1714           }
1715         else if (sd->focused == ELM_COLORSELECTOR_PALETTE)
1716         {
1717             cl = _palette_box_vertical_item_get(sd->selected, PALETTE_BOX_UP);
1718             if (!cl) cl = sd->selected;
1719         }
1720      }
1721    else if (!strcmp(dir, "down"))
1722      {
1723         if (sd->focused == ELM_COLORSELECTOR_PALETTE)
1724           {
1725              cl = _palette_box_vertical_item_get(sd->selected, PALETTE_BOX_DOWN);
1726              if (sd->mode == ELM_COLORSELECTOR_BOTH && !cl)
1727                {
1728                   sd->focused = ELM_COLORSELECTOR_COMPONENTS;
1729                   /*when focus is shifted to component start from
1730                    * first color type*/
1731                   sd->sel_color_type = HUE;
1732                }
1733           }
1734         else if (sd->focused == ELM_COLORSELECTOR_COMPONENTS)
1735           {
1736              snprintf(colorbar_s, sizeof(colorbar_s), "elm.colorbar_%d",
1737                       (sd->sel_color_type + 1));
1738              /*Append color type only if next color bar is available*/
1739              if (edje_object_part_swallow_get(sd->col_bars_area, colorbar_s))
1740                sd->sel_color_type = sd->sel_color_type + 1;
1741              else return EINA_FALSE;
1742           }
1743      }
1744    else return EINA_FALSE;
1745
1746    if (cl)
1747      {
1748         item = eina_list_data_get(cl);
1749         elm_object_signal_emit(VIEW(item), "elm,anim,activate", "elm");
1750         elm_colorselector_color_set
1751           (WIDGET(item), item->color->r, item->color->g, item->color->b,
1752           item->color->a);
1753         evas_object_smart_callback_call
1754           (WIDGET(item), SIG_COLOR_ITEM_SELECTED, item);
1755         sd->selected = cl;
1756      }
1757    else if (!cl && sd->focused == ELM_COLORSELECTOR_PALETTE)
1758      return EINA_FALSE;
1759
1760    return EINA_TRUE;
1761 }
1762
1763 EOLIAN static Eina_Bool
1764 _elm_colorselector_elm_widget_event(Eo *obj, Elm_Colorselector_Data *sd, Evas_Object *src, Evas_Callback_Type type, void *event_info)
1765 {
1766    Evas_Event_Key_Down *ev = event_info;
1767    Eina_List *cl = NULL;
1768    Elm_Color_Item *item = NULL;
1769    char colorbar_s[128];
1770
1771    (void) src;
1772
1773    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
1774    if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
1775    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
1776    if (!sd) return EINA_FALSE;
1777    if (!sd->selected) sd->selected = sd->items;
1778
1779    if (!_elm_config_key_binding_call(obj, ev, key_actions))
1780      return EINA_FALSE;
1781
1782    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1783    return EINA_TRUE;
1784 }
1785
1786 static Eina_Bool _elm_colorselector_smart_focus_next_enable = EINA_FALSE;
1787
1788 EOLIAN static Eina_Bool
1789 _elm_colorselector_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Colorselector_Data *_pd EINA_UNUSED)
1790 {
1791    return EINA_FALSE;
1792 }
1793
1794 EOLIAN static Eina_Bool
1795 _elm_colorselector_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Colorselector_Data *_pd EINA_UNUSED)
1796 {
1797    return _elm_colorselector_smart_focus_next_enable;
1798 }
1799
1800 EOLIAN static Eina_Bool
1801 _elm_colorselector_elm_widget_focus_next(Eo *obj, Elm_Colorselector_Data *sd, Elm_Focus_Direction dir, Evas_Object **next)
1802 {
1803    Eina_List *items = NULL;
1804    Eina_List *l;
1805    Elm_Widget_Item *item;
1806    int i = 0;
1807
1808    if (!sd) return EINA_FALSE;
1809
1810    if (!sd->items) return EINA_FALSE;
1811
1812    EINA_LIST_FOREACH(sd->items, l, item)
1813      items = eina_list_append(items, item->access_obj);
1814
1815    for (i = 0; i < 4; i++)
1816      {
1817         items = eina_list_append(items, sd->cb_data[i]->lbt);
1818         items = eina_list_append(items, sd->cb_data[i]->access_obj);
1819         items = eina_list_append(items, sd->cb_data[i]->rbt);
1820      }
1821
1822    return elm_widget_focus_list_next_get
1823             (obj, items, eina_list_data_get, dir, next);
1824 }
1825
1826 static void
1827 _access_obj_process(Evas_Object *obj, Eina_Bool is_access)
1828 {
1829    Eina_List *l;
1830    Elm_Color_Item *it;
1831    int i = 0;
1832
1833    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1834
1835    if (is_access)
1836      {
1837         EINA_LIST_FOREACH(sd->items, l, it)
1838           _access_widget_item_register(it);
1839
1840         for (i = 0; i < 4; i++)
1841           _access_colorbar_register(obj, sd->cb_data[i],
1842                                     "elm.arrow_bg_access");
1843      }
1844    else
1845      {
1846         EINA_LIST_FOREACH(sd->items, l, it)
1847           _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
1848
1849         //TODO: _elm_access_edje_object_part_object_unregister() ?
1850      }
1851 }
1852
1853 EOLIAN static void
1854 _elm_colorselector_elm_widget_access(Eo *obj, Elm_Colorselector_Data *_pd EINA_UNUSED, Eina_Bool acs)
1855 {
1856    _elm_colorselector_smart_focus_next_enable = acs;
1857    _access_obj_process(obj, _elm_colorselector_smart_focus_next_enable);
1858 }
1859
1860 EAPI Evas_Object *
1861 elm_colorselector_add(Evas_Object *parent)
1862 {
1863    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
1864    Evas_Object *obj = eo_add(MY_CLASS, parent);
1865    eo_unref(obj);
1866    return obj;
1867 }
1868
1869 EOLIAN static void
1870 _elm_colorselector_eo_base_constructor(Eo *obj, Elm_Colorselector_Data *_pd EINA_UNUSED)
1871 {
1872    eo_do_super(obj, MY_CLASS, eo_constructor());
1873    eo_do(obj,
1874          evas_obj_type_set(MY_CLASS_NAME_LEGACY),
1875          evas_obj_smart_callbacks_descriptions_set(_smart_callbacks, NULL));
1876 }
1877
1878 EOLIAN static void
1879 _elm_colorselector_color_set(Eo *obj, Elm_Colorselector_Data *_pd EINA_UNUSED, int r, int g, int b, int a)
1880 {
1881    _colors_set(obj, r, g, b, a);
1882 }
1883
1884 EOLIAN static void
1885 _elm_colorselector_color_get(Eo *obj EINA_UNUSED, Elm_Colorselector_Data *sd, int *r, int *g, int *b, int *a)
1886 {
1887    if (r) *r = sd->r;
1888    if (g) *g = sd->g;
1889    if (b) *b = sd->b;
1890    if (a) *a = sd->a;
1891 }
1892
1893 EOLIAN static void
1894 _elm_colorselector_mode_set(Eo *obj, Elm_Colorselector_Data *sd, Elm_Colorselector_Mode mode)
1895 {
1896    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1897    Evas_Object *o;
1898
1899    if (sd->mode == mode) return;
1900    sd->mode = mode;
1901
1902    o = elm_layout_content_unset(obj, "elm.selector");
1903    if (!o) o = elm_layout_content_unset(obj, "selector");
1904    if (o) evas_object_hide(o);
1905
1906    o = elm_layout_content_unset(obj, "elm.palette");
1907    if (!o) o = elm_layout_content_unset(obj, "palette");
1908    if (o) evas_object_hide(o);
1909
1910    o = elm_layout_content_unset(obj, "elm.picker");
1911    if (!o) o = elm_layout_content_unset(obj, "picker");
1912    if (o) evas_object_hide(o);
1913
1914    switch (sd->mode)
1915      {
1916       case ELM_COLORSELECTOR_PALETTE:
1917         if (!elm_layout_content_set(obj, "elm.palette", sd->palette_box))
1918           elm_layout_content_set(obj, "palette", sd->palette_box);
1919         elm_layout_signal_emit(obj, "elm,state,palette", "elm");
1920         sd->focused = ELM_COLORSELECTOR_PALETTE;
1921         sd->selected = sd->items;
1922         break;
1923
1924       case ELM_COLORSELECTOR_COMPONENTS:
1925         if (!elm_layout_content_set(obj, "elm.selector", sd->col_bars_area))
1926           elm_layout_content_set(obj, "selector", sd->col_bars_area);
1927         elm_layout_signal_emit(obj, "elm,state,components", "elm");
1928         sd->focused = ELM_COLORSELECTOR_COMPONENTS;
1929         sd->sel_color_type = HUE;
1930         break;
1931
1932       case ELM_COLORSELECTOR_BOTH:
1933         if (!elm_layout_content_set(obj, "elm.palette", sd->palette_box))
1934           elm_layout_content_set(obj, "palette", sd->palette_box);
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         elm_layout_signal_emit(obj, "elm,state,both", "elm");
1938         sd->focused = ELM_COLORSELECTOR_PALETTE;
1939         sd->selected = sd->items;
1940         break;
1941
1942       case ELM_COLORSELECTOR_PICKER:
1943         if (!elm_layout_content_set(obj, "elm.picker", sd->picker))
1944           elm_layout_content_set(obj, "picker", sd->picker);
1945         elm_layout_signal_emit(obj, "elm,state,picker", "elm");
1946         sd->focused = ELM_COLORSELECTOR_PICKER;
1947         break;
1948
1949       case ELM_COLORSELECTOR_ALL:
1950         if (!elm_layout_content_set(obj, "elm.palette", sd->palette_box))
1951           elm_layout_content_set(obj, "palette", sd->palette_box);
1952         if (!elm_layout_content_set(obj, "elm.selector", sd->col_bars_area))
1953           elm_layout_content_set(obj, "selector", sd->col_bars_area);
1954         if (!elm_layout_content_set(obj, "elm.picker", sd->picker))
1955           elm_layout_content_set(obj, "picker", sd->picker);
1956         elm_layout_signal_emit(obj, "elm,state,all", "elm");
1957         sd->focused = ELM_COLORSELECTOR_PALETTE;
1958         sd->selected = sd->items;
1959         break;
1960
1961       default:
1962         return;
1963      }
1964
1965    edje_object_message_signal_process(wd->resize_obj);
1966
1967    elm_layout_sizing_eval(obj);
1968 }
1969
1970 EOLIAN static Elm_Colorselector_Mode
1971 _elm_colorselector_mode_get(Eo *obj EINA_UNUSED, Elm_Colorselector_Data *sd)
1972 {
1973    return sd->mode;
1974 }
1975
1976 EAPI void
1977 elm_colorselector_palette_item_color_get(const Elm_Object_Item *it,
1978                                          int *r,
1979                                          int *g,
1980                                          int *b,
1981                                          int *a)
1982 {
1983    Elm_Color_Item *item;
1984
1985    ELM_COLORSELECTOR_ITEM_CHECK_OR_RETURN(it);
1986
1987    item = (Elm_Color_Item *)it;
1988    if (item)
1989      {
1990         if (r) *r = item->color->r;
1991         if (g) *g = item->color->g;
1992         if (b) *b = item->color->b;
1993         if (a) *a = item->color->a;
1994      }
1995 }
1996
1997 EAPI void
1998 elm_colorselector_palette_item_color_set(Elm_Object_Item *it,
1999                                          int r,
2000                                          int g,
2001                                          int b,
2002                                          int a)
2003 {
2004    Elm_Color_Item *item;
2005
2006    ELM_COLORSELECTOR_ITEM_CHECK_OR_RETURN(it);
2007
2008    item = (Elm_Color_Item *)it;
2009    item->color->r = r;
2010    item->color->g = g;
2011    item->color->b = b;
2012    item->color->a = a;
2013    evas_object_color_set(item->color_obj,
2014                          (item->color->r * item->color->a) / 255,
2015                          (item->color->g * item->color->a) / 255,
2016                          (item->color->b * item->color->a) / 255,
2017                          item->color->a);
2018    _colors_save(WIDGET(it));
2019 }
2020
2021 EOLIAN static Elm_Object_Item*
2022 _elm_colorselector_palette_color_add(Eo *obj, Elm_Colorselector_Data *sd, int r, int g, int b, int a)
2023 {
2024    Elm_Color_Item *item;
2025
2026    if (sd->config_load)
2027      {
2028         _items_del(sd);
2029         sd->config_load = EINA_FALSE;
2030      }
2031    item = _item_new(obj);
2032    if (!item) return NULL;
2033
2034    item->color = ELM_NEW(Elm_Color_RGBA);
2035    if (!item->color) return NULL;
2036
2037    item->color->r = r;
2038    item->color->g = g;
2039    item->color->b = b;
2040    item->color->a = a;
2041
2042    elm_box_pack_end(sd->palette_box, VIEW(item));
2043    evas_object_color_set(item->color_obj,
2044                          (item->color->r * item->color->a) / 255,
2045                          (item->color->g * item->color->a) / 255,
2046                          (item->color->b * item->color->a) / 255,
2047                          item->color->a);
2048
2049    sd->items = eina_list_append(sd->items, item);
2050
2051    elm_layout_sizing_eval(obj);
2052
2053    return (Elm_Object_Item *)item;
2054 }
2055
2056 EOLIAN static void
2057 _elm_colorselector_palette_clear(Eo *obj, Elm_Colorselector_Data *sd)
2058 {
2059
2060    _colors_remove(obj);
2061    if (sd->mode == ELM_COLORSELECTOR_BOTH)
2062      sd->focused = ELM_COLORSELECTOR_COMPONENTS;
2063 }
2064
2065 EOLIAN static const Eina_List*
2066 _elm_colorselector_palette_items_get(Eo *obj EINA_UNUSED, Elm_Colorselector_Data *sd)
2067 {
2068    return sd->items;
2069 }
2070
2071 EAPI void
2072 elm_colorselector_palette_item_selected_set(Elm_Object_Item *it,
2073                               Eina_Bool selected)
2074 {
2075    Elm_Color_Item *temp_item, *item;
2076    item = (Elm_Color_Item *)it;
2077    Eina_List *l;
2078
2079    ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd);
2080    ELM_COLORSELECTOR_ITEM_CHECK_OR_RETURN(it);
2081
2082    if (selected)
2083      {
2084         temp_item = eina_list_data_get(sd->selected);
2085         if (item == temp_item) return;
2086         elm_object_signal_emit(VIEW(item), "elm,state,selected", "elm");
2087         elm_colorselector_color_set(WIDGET(item), item->color->r, item->color->g,
2088                                     item->color->b, item->color->a);
2089         if (temp_item)
2090           elm_object_signal_emit(VIEW(temp_item), "elm,state,unselected", "elm");
2091
2092         EINA_LIST_FOREACH(sd->items, l, temp_item)
2093           if (item == temp_item) sd->selected = l;
2094      }
2095    else
2096      {
2097         elm_object_signal_emit(VIEW(item), "elm,state,unselected", "elm");
2098         sd->selected = NULL;
2099      }
2100 }
2101
2102 EAPI Eina_Bool
2103 elm_colorselector_palette_item_selected_get(const Elm_Object_Item *it)
2104 {
2105    Elm_Color_Item *temp_item, *item;
2106    item = (Elm_Color_Item *)it;
2107    ELM_COLORSELECTOR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
2108    ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd);
2109
2110    temp_item = eina_list_data_get(sd->selected);
2111    if (item == temp_item) return EINA_TRUE;
2112    else return EINA_FALSE;
2113 }
2114
2115 EOLIAN static Elm_Object_Item*
2116 _elm_colorselector_palette_selected_item_get(Eo *obj EINA_UNUSED, Elm_Colorselector_Data *sd)
2117 {
2118    return eina_list_data_get(sd->selected);
2119 }
2120
2121 EOLIAN static void
2122 _elm_colorselector_palette_name_set(Eo *obj, Elm_Colorselector_Data *sd, const char *palette_name)
2123 {
2124    EINA_SAFETY_ON_NULL_RETURN(palette_name);
2125
2126    if (!strcmp(sd->palette_name, palette_name)) return;
2127
2128    _items_del(sd);
2129    eina_stringshare_replace(&sd->palette_name, palette_name);
2130    _palette_colors_load(obj);
2131 }
2132
2133 EOLIAN static const char*
2134 _elm_colorselector_palette_name_get(Eo *obj EINA_UNUSED, Elm_Colorselector_Data *sd)
2135 {
2136    return sd->palette_name;
2137 }
2138
2139 static void
2140 _elm_colorselector_class_constructor(Eo_Class *klass)
2141 {
2142    evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
2143
2144    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
2145       _elm_colorselector_smart_focus_next_enable = EINA_TRUE;
2146 }
2147
2148 #include "elm_colorselector.eo.c"