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