[Scroller] Fix the calculation double type number. Round off to the nearest whole...
[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
930         /* load colorbar area */
931         sd->cb_data[i]->colorbar = edje_object_add(e);
932         elm_widget_theme_object_set
933           (obj, sd->cb_data[i]->colorbar, "colorselector", "base",
934           elm_widget_style_get(obj));
935         snprintf(colorbar_name, sizeof(colorbar_name), "colorbar_%d", i);
936         snprintf(colorbar_s, sizeof(colorbar_s), "elm.colorbar_%d", i);
937         edje_object_signal_callback_add
938           (sd->cb_data[i]->colorbar, "drag", "*", _arrow_cb, sd->cb_data[i]);
939         edje_object_part_swallow
940           (sd->col_bars_area, colorbar_s, sd->cb_data[i]->colorbar);
941         elm_widget_sub_object_add(obj, sd->cb_data[i]->colorbar);
942
943         /* load colorbar image */
944         sd->cb_data[i]->bar = edje_object_add(e);
945         snprintf(buf, sizeof(buf), "%s/%s", colorbar_name,
946                  elm_widget_style_get(obj));
947         elm_widget_theme_object_set
948           (obj, sd->cb_data[i]->bar, "colorselector", "image", buf);
949         edje_object_part_swallow
950           (sd->cb_data[i]->colorbar, "elm.bar", sd->cb_data[i]->bar);
951         elm_widget_sub_object_add(obj, sd->cb_data[i]->bar);
952
953         /* provide expanded touch area */
954         sd->cb_data[i]->touch_area = evas_object_rectangle_add(e);
955         evas_object_color_set(sd->cb_data[i]->touch_area, 0, 0, 0, 0);
956         edje_object_part_swallow
957           (sd->cb_data[i]->colorbar, "elm.arrow_bg",
958           sd->cb_data[i]->touch_area);
959         evas_object_event_callback_add
960           (sd->cb_data[i]->touch_area, EVAS_CALLBACK_MOUSE_DOWN, _colorbar_cb,
961           sd->cb_data[i]);
962         elm_widget_sub_object_add(obj, sd->cb_data[i]->touch_area);
963
964         // ACCESS
965         if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
966            _access_colorbar_register(obj, sd->cb_data[i], "elm.arrow_bg_access");
967
968         /* load background rectangle of the colorbar. used for
969            changing color of the opacity bar */
970         if ((i == 1) || (i == 2))
971           {
972              sd->cb_data[i]->bg_rect = evas_object_rectangle_add(e);
973              evas_object_color_set
974                (sd->cb_data[i]->bg_rect, sd->er, sd->eg, sd->eb, 255);
975              edje_object_part_swallow
976                (sd->cb_data[i]->colorbar, "elm.bar_bg",
977                sd->cb_data[i]->bg_rect);
978
979              elm_widget_sub_object_add(obj, sd->cb_data[i]->bg_rect);
980           }
981         if (i == 3)
982           {
983              sd->cb_data[i]->bg_rect = edje_object_add(e);
984              snprintf(buf, sizeof(buf), "%s/%s", colorbar_name,
985                       elm_widget_style_get(obj));
986              elm_widget_theme_object_set
987                (obj, sd->cb_data[i]->bg_rect, "colorselector", "bg_image",
988                buf);
989              edje_object_part_swallow
990                (sd->cb_data[i]->colorbar, "elm.bar_bg",
991                sd->cb_data[i]->bg_rect);
992              elm_widget_sub_object_add(obj, sd->cb_data[i]->bg_rect);
993              evas_object_color_set
994                (sd->cb_data[i]->bar, sd->er, sd->eg, sd->eb, 255);
995           }
996
997         /* load arrow image, pointing the colorbar */
998         sd->cb_data[i]->arrow = edje_object_add(e);
999         elm_widget_theme_object_set
1000           (obj, sd->cb_data[i]->arrow, "colorselector", "arrow",
1001           elm_widget_style_get(obj));
1002         edje_object_part_swallow
1003           (sd->cb_data[i]->colorbar, "elm.arrow_icon",
1004           sd->cb_data[i]->arrow);
1005         elm_widget_sub_object_add(obj, sd->cb_data[i]->arrow);
1006
1007         if (i == 2)
1008           evas_object_color_set(sd->cb_data[i]->arrow, 0, 0, 0, 255);
1009         else
1010           evas_object_color_set
1011             (sd->cb_data[i]->arrow, sd->er, sd->eg, sd->eb, 255);
1012
1013         /* load left button */
1014         sd->cb_data[i]->lbt = elm_button_add(obj);
1015         snprintf(buf, sizeof(buf), "colorselector/left/%s",
1016                  elm_widget_style_get(obj));
1017         elm_object_style_set(sd->cb_data[i]->lbt, buf);
1018         elm_widget_sub_object_add(obj, sd->cb_data[i]->lbt);
1019         edje_object_part_swallow
1020           (sd->cb_data[i]->colorbar, "elm.l_button", sd->cb_data[i]->lbt);
1021         evas_object_smart_callback_add
1022           (sd->cb_data[i]->lbt, "clicked", _button_clicked_cb,
1023           sd->cb_data[i]);
1024         elm_button_autorepeat_set(sd->cb_data[i]->lbt, EINA_TRUE);
1025         elm_button_autorepeat_initial_timeout_set
1026           (sd->cb_data[i]->lbt, _elm_config->longpress_timeout);
1027         elm_button_autorepeat_gap_timeout_set
1028           (sd->cb_data[i]->lbt, (1.0 / _elm_config->fps));
1029         evas_object_smart_callback_add
1030           (sd->cb_data[i]->lbt, "repeated", _button_repeat_cb,
1031           sd->cb_data[i]);
1032
1033         /* load right button */
1034         sd->cb_data[i]->rbt = elm_button_add(obj);
1035         snprintf(buf, sizeof(buf), "colorselector/right/%s",
1036                  elm_widget_style_get(obj));
1037         elm_object_style_set(sd->cb_data[i]->rbt, buf);
1038         elm_widget_sub_object_add(obj, sd->cb_data[i]->rbt);
1039         edje_object_part_swallow
1040           (sd->cb_data[i]->colorbar, "elm.r_button", sd->cb_data[i]->rbt);
1041         evas_object_smart_callback_add
1042           (sd->cb_data[i]->rbt, "clicked", _button_clicked_cb,
1043           sd->cb_data[i]);
1044         elm_button_autorepeat_set(sd->cb_data[i]->rbt, EINA_TRUE);
1045         elm_button_autorepeat_initial_timeout_set
1046           (sd->cb_data[i]->rbt, _elm_config->longpress_timeout);
1047         elm_button_autorepeat_gap_timeout_set
1048           (sd->cb_data[i]->rbt, (1.0 / _elm_config->fps));
1049         evas_object_smart_callback_add
1050           (sd->cb_data[i]->rbt, "repeated", _button_repeat_cb,
1051           sd->cb_data[i]);
1052      }
1053 }
1054
1055 static Eina_Bool
1056 _elm_colorselector_smart_theme(Evas_Object *obj)
1057 {
1058    int i;
1059    Eina_List *elist;
1060    Elm_Color_Item *item;
1061    const char *hpadstr, *vpadstr;
1062    unsigned int h_pad = DEFAULT_HOR_PAD;
1063    unsigned int v_pad = DEFAULT_VER_PAD;
1064
1065    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1066
1067    if (!ELM_WIDGET_CLASS(_elm_colorselector_parent_sc)->theme(obj))
1068      return EINA_FALSE;
1069
1070    if (!sd->col_bars_area) return EINA_FALSE;
1071
1072    elm_widget_theme_object_set
1073      (obj, sd->col_bars_area, "colorselector", "bg",
1074      elm_widget_style_get(obj));
1075
1076    hpadstr = edje_object_data_get
1077        (ELM_WIDGET_DATA(sd)->resize_obj, "horizontal_pad");
1078    if (hpadstr) h_pad = atoi(hpadstr);
1079    vpadstr = edje_object_data_get
1080        (ELM_WIDGET_DATA(sd)->resize_obj, "vertical_pad");
1081    if (vpadstr) v_pad = atoi(vpadstr);
1082
1083    elm_box_padding_set
1084      (sd->palette_box,
1085      (h_pad * elm_widget_scale_get(obj) * elm_config_scale_get()),
1086      (v_pad * elm_widget_scale_get(obj) * elm_config_scale_get()));
1087
1088    EINA_LIST_FOREACH(sd->items, elist, item)
1089      {
1090         elm_layout_theme_set
1091           (VIEW(item), "colorselector", "item", elm_widget_style_get(obj));
1092         elm_widget_theme_object_set
1093           (obj, item->color_obj, "colorselector", "item/color",
1094           elm_widget_style_get(obj));
1095      }
1096    for (i = 0; i < 4; i++)
1097      {
1098         if (sd->cb_data[i])
1099           {
1100              evas_object_del(sd->cb_data[i]->colorbar);
1101              sd->cb_data[i]->colorbar = NULL;
1102              evas_object_del(sd->cb_data[i]->bar);
1103              sd->cb_data[i]->bar = NULL;
1104              evas_object_del(sd->cb_data[i]->lbt);
1105              sd->cb_data[i]->lbt = NULL;
1106              evas_object_del(sd->cb_data[i]->rbt);
1107              sd->cb_data[i]->rbt = NULL;
1108              if (i != 0)
1109                {
1110                   evas_object_del(sd->cb_data[i]->bg_rect);
1111                   sd->cb_data[i]->bg_rect = NULL;
1112                }
1113              evas_object_del(sd->cb_data[i]->arrow);
1114              sd->cb_data[i]->arrow = NULL;
1115              evas_object_del(sd->cb_data[i]->touch_area);
1116              sd->cb_data[i]->touch_area = NULL;
1117           }
1118      }
1119
1120    _color_bars_add(obj);
1121    elm_colorselector_color_set(obj, sd->r, sd->g, sd->b, sd->a);
1122
1123    elm_layout_sizing_eval(obj);
1124
1125    return EINA_TRUE;
1126 }
1127
1128 static void
1129 _sub_obj_size_hints_set(Evas_Object *sobj,
1130                         int timesw,
1131                         int timesh)
1132 {
1133    Evas_Coord minw = -1, minh = -1;
1134
1135    elm_coords_finger_size_adjust(timesw, &minw, timesh, &minh);
1136    edje_object_size_min_restricted_calc(sobj, &minw, &minh, minw, minh);
1137    evas_object_size_hint_min_set(sobj, minw, minh);
1138    evas_object_size_hint_max_set(sobj, -1, -1);
1139 }
1140
1141 static void
1142 _item_sizing_eval(Elm_Color_Item *item)
1143 {
1144    Evas_Coord minw = -1, minh = -1;
1145
1146    if (!item) return;
1147
1148    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1149    edje_object_size_min_restricted_calc(VIEW(item), &minw, &minh, minw, minh);
1150    evas_object_size_hint_min_set(VIEW(item), minw, minh);
1151 }
1152
1153 /* fix size hints of color palette items, so that the box gets it */
1154 static void
1155 _palette_sizing_eval(Evas_Object *obj)
1156 {
1157    Eina_List *elist;
1158    Elm_Color_Item *item;
1159
1160    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1161
1162    EINA_LIST_FOREACH(sd->items, elist, item)
1163      _item_sizing_eval(item);
1164 }
1165
1166 static void
1167 _component_sizing_eval(Evas_Object *obj)
1168 {
1169    Evas_Coord minw = -1, minh = -1;
1170    int i;
1171
1172    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1173
1174    for (i = 0; i < 4; i++)
1175      {
1176         if (sd->cb_data[i])
1177           {
1178              if (sd->cb_data[i]->bg_rect)
1179                _sub_obj_size_hints_set(sd->cb_data[i]->bg_rect, 1, 1);
1180
1181              _sub_obj_size_hints_set(sd->cb_data[i]->bar, 1, 1);
1182              _sub_obj_size_hints_set(sd->cb_data[i]->rbt, 1, 1);
1183              _sub_obj_size_hints_set(sd->cb_data[i]->lbt, 1, 1);
1184              _sub_obj_size_hints_set(sd->cb_data[i]->colorbar, 4, 1);
1185           }
1186      }
1187
1188    edje_object_size_min_restricted_calc
1189      (sd->col_bars_area, &minw, &minh, minw, minh);
1190    evas_object_size_hint_min_set(sd->col_bars_area, minw, minh);
1191 }
1192
1193 static void
1194 _full_sizing_eval(Evas_Object *obj)
1195 {
1196    _palette_sizing_eval(obj);
1197    _component_sizing_eval(obj);
1198 }
1199
1200 static void
1201 _elm_colorselector_smart_sizing_eval(Evas_Object *obj)
1202 {
1203    Evas_Coord minw = -1, minh = -1;
1204
1205    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1206
1207    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1208
1209    switch (sd->mode)
1210      {
1211       case ELM_COLORSELECTOR_PALETTE:
1212         _palette_sizing_eval(obj);
1213         break;
1214
1215       case ELM_COLORSELECTOR_COMPONENTS:
1216         _component_sizing_eval(obj);
1217         break;
1218
1219       case ELM_COLORSELECTOR_BOTH:
1220         _full_sizing_eval(obj);
1221         break;
1222
1223       default:
1224         return;
1225      }
1226
1227    edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
1228    evas_object_size_hint_min_set(obj, minw, minh);
1229    evas_object_size_hint_max_set(obj, -1, -1);
1230 }
1231
1232 static Eina_Bool
1233 _on_color_long_press(void *data)
1234 {
1235    Elm_Color_Item *item = (Elm_Color_Item *)data;
1236
1237    ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd);
1238
1239    sd->longpress_timer = NULL;
1240    sd->longpressed = EINA_TRUE;
1241    evas_object_smart_callback_call
1242      (WIDGET(item), SIG_COLOR_ITEM_LONGPRESSED, item);
1243
1244    return ECORE_CALLBACK_CANCEL;
1245 }
1246
1247 static void
1248 _on_color_pressed(void *data,
1249                   Evas *e __UNUSED__,
1250                   Evas_Object *obj __UNUSED__,
1251                   void *event_info __UNUSED__)
1252 {
1253    Elm_Color_Item *item = (Elm_Color_Item *)data;
1254    Evas_Event_Mouse_Down *ev = event_info;
1255
1256    if (!item) return;
1257
1258    ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd);
1259
1260    if (ev->button != 1) return;
1261    elm_object_signal_emit(VIEW(item), "elm,state,selected", "elm");
1262    sd->longpressed = EINA_FALSE;
1263
1264    if (sd->longpress_timer) ecore_timer_del(sd->longpress_timer);
1265    sd->longpress_timer = ecore_timer_add
1266        (_elm_config->longpress_timeout, _on_color_long_press, data);
1267 }
1268
1269 static void
1270 _on_color_released(void *data,
1271                    Evas *e __UNUSED__,
1272                    Evas_Object *obj __UNUSED__,
1273                    void *event_info __UNUSED__)
1274 {
1275    Elm_Color_Item *item = (Elm_Color_Item *)data;
1276    Eina_List *l;
1277    Elm_Color_Item *temp_item;
1278    Evas_Event_Mouse_Down *ev = event_info;
1279    if (!item) return;
1280
1281    ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd);
1282
1283    if (ev->button != 1) return;
1284    if (sd->longpress_timer)
1285      {
1286         ecore_timer_del(sd->longpress_timer);
1287         sd->longpress_timer = NULL;
1288      }
1289    elm_object_signal_emit(VIEW(item), "elm,state,unselected", "elm");
1290    if (!sd->longpressed)
1291      {
1292         evas_object_smart_callback_call
1293           (WIDGET(item), SIG_COLOR_ITEM_SELECTED, item);
1294         elm_colorselector_color_set
1295           (WIDGET(item), item->color->r, item->color->g, item->color->b,
1296           item->color->a);
1297      }
1298    EINA_LIST_FOREACH(sd->items, l, temp_item)
1299      if (item == temp_item) sd->selected = l;
1300    sd->focused = ELM_COLORSELECTOR_PALETTE;
1301 }
1302
1303 static char *
1304 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
1305 {
1306    char *ret;
1307    Eina_Strbuf *buf;
1308    int r = 0, g = 0, b = 0 ,a = 0;
1309
1310    Elm_Color_Item *it = data;
1311    ELM_COLORSELECTOR_ITEM_CHECK_OR_RETURN(it, NULL);
1312
1313    elm_colorselector_palette_item_color_get((Elm_Object_Item *)it, &r, &g, &b, &a);
1314
1315    buf = eina_strbuf_new();
1316    eina_strbuf_append_printf(buf, "red %d, green %d, blue %d, alpha %d", r, g, b, a);
1317    ret = eina_strbuf_string_steal(buf);
1318    eina_strbuf_free(buf);
1319    return ret;
1320 }
1321
1322 static void
1323 _access_widget_item_register(Elm_Color_Item *it)
1324 {
1325    Elm_Access_Info *ai;
1326
1327    _elm_access_widget_item_register((Elm_Widget_Item *)it);
1328
1329    ai = _elm_access_object_get(it->base.access_obj);
1330
1331    _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("color selector palette item"));
1332    _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1333 }
1334
1335 static void
1336 _item_resize(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
1337              void *event_info __UNUSED__)
1338 {
1339    elm_layout_sizing_eval(obj);
1340 }
1341
1342 static Elm_Color_Item *
1343 _item_new(Evas_Object *obj)
1344 {
1345    Elm_Color_Item *item;
1346
1347    item = elm_widget_item_new(obj, Elm_Color_Item);
1348    if (!item) return NULL;
1349
1350    VIEW(item) = elm_layout_add(obj);
1351    elm_layout_theme_set
1352      (VIEW(item), "colorselector", "item", elm_widget_style_get(obj));
1353    evas_object_size_hint_weight_set
1354      (VIEW(item), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1355    evas_object_size_hint_align_set(VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
1356    evas_object_event_callback_add
1357      (VIEW(item), EVAS_CALLBACK_RESIZE, _item_resize, NULL);
1358
1359    item->color_obj = edje_object_add(evas_object_evas_get(obj));
1360    elm_widget_theme_object_set
1361      (obj, item->color_obj, "colorselector", "item/color",
1362      elm_widget_style_get(obj));
1363    evas_object_size_hint_weight_set
1364      (item->color_obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1365    evas_object_size_hint_align_set
1366      (item->color_obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
1367    evas_object_event_callback_add
1368      (item->color_obj, EVAS_CALLBACK_MOUSE_DOWN, _on_color_pressed, item);
1369    evas_object_event_callback_add
1370      (item->color_obj, EVAS_CALLBACK_MOUSE_UP, _on_color_released, item);
1371    elm_object_part_content_set(VIEW(item), "color_obj", item->color_obj);
1372
1373    _item_sizing_eval(item);
1374    evas_object_show(VIEW(item));
1375
1376    // ACCESS
1377    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
1378      _access_widget_item_register(item);
1379
1380    return item;
1381 }
1382
1383 static void
1384 _colors_remove(Evas_Object *obj)
1385 {
1386    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1387
1388    _items_del(sd);
1389    _elm_config_colors_free(sd->palette_name);
1390 }
1391
1392 static void
1393 _colors_save(Evas_Object *obj)
1394 {
1395    Eina_List *elist;
1396    Elm_Color_Item *item;
1397
1398    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1399
1400    _elm_config_colors_free(sd->palette_name);
1401    EINA_LIST_FOREACH(sd->items, elist, item)
1402      _elm_config_color_set(sd->palette_name, item->color->r, item->color->g,
1403                            item->color->b, item->color->a);
1404 }
1405
1406 static void
1407 _palette_colors_load(Evas_Object *obj)
1408 {
1409    Eina_List *elist;
1410    Elm_Color_Item *item;
1411    Eina_List *color_list;
1412    Elm_Color_RGBA *color;
1413
1414    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1415
1416    color_list = _elm_config_color_list_get(sd->palette_name);
1417    if (!color_list) return;
1418
1419    EINA_LIST_FOREACH(color_list, elist, color)
1420      {
1421         item = _item_new(obj);
1422         if (!item) return;
1423
1424         item->color = ELM_NEW(Elm_Color_RGBA);
1425         if (!item->color) return;
1426         item->color->r = color->r;
1427         item->color->g = color->g;
1428         item->color->b = color->b;
1429         item->color->a = color->a;
1430
1431         elm_box_pack_end(sd->palette_box, VIEW(item));
1432         evas_object_color_set
1433           (item->color_obj, item->color->r, item->color->g, item->color->b,
1434           item->color->a);
1435
1436         sd->items = eina_list_append(sd->items, item);
1437      }
1438
1439    sd->config_load = EINA_TRUE;
1440 }
1441
1442 static void
1443 _elm_colorselector_smart_add(Evas_Object *obj)
1444 {
1445    const char *hpadstr, *vpadstr;
1446    unsigned int h_pad = DEFAULT_HOR_PAD;
1447    unsigned int v_pad = DEFAULT_VER_PAD;
1448
1449    EVAS_SMART_DATA_ALLOC(obj, Elm_Colorselector_Smart_Data);
1450
1451    ELM_WIDGET_CLASS(_elm_colorselector_parent_sc)->base.add(obj);
1452
1453    elm_layout_theme_set
1454      (obj, "colorselector", "palette", elm_object_style_get(obj));
1455
1456    priv->palette_box = elm_box_add(obj);
1457    elm_box_layout_set
1458      (priv->palette_box, evas_object_box_layout_flow_horizontal, NULL, NULL);
1459    elm_box_horizontal_set(priv->palette_box, EINA_TRUE);
1460    evas_object_size_hint_weight_set
1461      (priv->palette_box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1462    evas_object_size_hint_align_set
1463      (priv->palette_box, EVAS_HINT_FILL, EVAS_HINT_FILL);
1464    elm_box_homogeneous_set(priv->palette_box, EINA_TRUE);
1465
1466    hpadstr =
1467      edje_object_data_get(ELM_WIDGET_DATA(priv)->resize_obj, "horizontal_pad");
1468    if (hpadstr) h_pad = atoi(hpadstr);
1469    vpadstr = edje_object_data_get
1470        (ELM_WIDGET_DATA(priv)->resize_obj, "vertical_pad");
1471    if (vpadstr) v_pad = atoi(vpadstr);
1472
1473    elm_box_padding_set
1474      (priv->palette_box,
1475      (h_pad * elm_widget_scale_get(obj) * elm_config_scale_get()),
1476      (v_pad * elm_widget_scale_get(obj) * elm_config_scale_get()));
1477
1478    elm_box_align_set(priv->palette_box, 0.5, 0.5);
1479    elm_layout_content_set(obj, "palette", priv->palette_box);
1480    priv->palette_name = eina_stringshare_add("default");
1481    _palette_colors_load(obj);
1482
1483    /* load background edj */
1484    priv->col_bars_area = edje_object_add(evas_object_evas_get(obj));
1485    elm_widget_theme_object_set
1486      (obj, priv->col_bars_area, "colorselector", "bg",
1487      elm_widget_style_get(obj));
1488    elm_layout_content_set(obj, "selector", priv->col_bars_area);
1489
1490    /* setup the color picker */
1491    priv->picker = elm_box_add(obj);
1492    elm_box_horizontal_set(priv->picker, EINA_TRUE);
1493    evas_object_size_hint_weight_set(priv->picker, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1494    evas_object_size_hint_align_set(priv->picker, EVAS_HINT_FILL, EVAS_HINT_FILL);
1495
1496    elm_box_padding_set(priv->picker,
1497                        (h_pad * elm_widget_scale_get(obj) * elm_config_scale_get()),
1498                        (v_pad * elm_widget_scale_get(obj) * elm_config_scale_get()));
1499    elm_box_align_set(priv->palette_box, 0.5, 0.5);
1500
1501    priv->mode = ELM_COLORSELECTOR_BOTH;
1502    priv->focused = ELM_COLORSELECTOR_PALETTE;
1503    priv->sel_color_type = HUE;
1504    priv->selected = priv->items;
1505    priv->er = 255;
1506    priv->eg = 0;
1507    priv->eb = 0;
1508    priv->h = 0.0;
1509    priv->s = 1.0;
1510    priv->l = 0.0;
1511    priv->a = 255;
1512    priv->grab.x = -1;
1513    priv->grab.y = -1;
1514    priv->grab.xroot = -1;
1515    priv->grab.mouse_motion = NULL;
1516    priv->grab.mouse_up = NULL;
1517    priv->grab.key_up = NULL;
1518    priv->grab.in = EINA_TRUE;
1519
1520    _hsl_to_rgb(priv);
1521    _color_bars_add(obj);
1522    _color_picker_add(obj, priv);
1523
1524    elm_layout_sizing_eval(obj);
1525    elm_widget_can_focus_set(obj, EINA_TRUE);
1526 }
1527
1528 static void
1529 _elm_colorselector_smart_del(Evas_Object *obj)
1530 {
1531    int i = 0;
1532    void *tmp[4];
1533
1534    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1535
1536    evas_event_callback_del_full(evas_object_evas_get(obj), EVAS_CALLBACK_CANVAS_FOCUS_IN, _mouse_in_canvas, obj);
1537    evas_event_callback_del_full(evas_object_evas_get(obj), EVAS_CALLBACK_CANVAS_FOCUS_OUT, _mouse_out_canvas, obj);
1538
1539    if (sd->longpress_timer) ecore_timer_del(sd->longpress_timer);
1540    if (sd->palette_name) eina_stringshare_del(sd->palette_name);
1541    if (sd->grab.mouse_motion) ecore_event_handler_del(sd->grab.mouse_motion);
1542    if (sd->grab.mouse_up) ecore_event_handler_del(sd->grab.mouse_up);
1543    if (sd->grab.key_up) ecore_event_handler_del(sd->grab.key_up);
1544
1545    _items_del(sd);
1546    /* This cb_data are used during the destruction process of base.del */
1547    for (i = 0; i < 4; i++)
1548      tmp[i] = sd->cb_data[i];
1549    ELM_WIDGET_CLASS(_elm_colorselector_parent_sc)->base.del(obj);
1550    for (i = 0; i < 4; i++)
1551      free(tmp[i]);
1552 }
1553
1554 static Eina_Bool
1555 _elm_colorselector_smart_event(Evas_Object *obj,
1556                                Evas_Object *src __UNUSED__,
1557                                Evas_Callback_Type type,
1558                                void *event_info)
1559 {
1560    Eina_List *cl = NULL;
1561    Elm_Color_Item *item = NULL;
1562    char colorbar_s[128];
1563    if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
1564    Evas_Event_Key_Down *ev = event_info;
1565    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1566
1567    if (!sd) return EINA_FALSE;
1568    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
1569    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
1570    if (!sd->selected) sd->selected = sd->items;
1571
1572    if ((!strcmp(ev->keyname, "Left")) ||
1573        ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
1574      {
1575         if (sd->focused == ELM_COLORSELECTOR_PALETTE && sd->selected)
1576           cl = eina_list_prev(sd->selected);
1577         else if (sd->focused == ELM_COLORSELECTOR_COMPONENTS)
1578           _button_clicked_cb(sd->cb_data[sd->sel_color_type], sd->cb_data[sd->sel_color_type]->lbt, NULL);
1579         else return EINA_FALSE;
1580      }
1581    else if ((!strcmp(ev->keyname, "Right")) ||
1582             ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
1583      {
1584         if (sd->focused == ELM_COLORSELECTOR_PALETTE && sd->selected)
1585           cl = eina_list_next(sd->selected);
1586         else if (sd->focused == ELM_COLORSELECTOR_COMPONENTS)
1587           _button_clicked_cb(sd->cb_data[sd->sel_color_type], sd->cb_data[sd->sel_color_type]->rbt, NULL);
1588         else return EINA_FALSE;
1589      }
1590    else if ((!strcmp(ev->keyname, "Up")) ||
1591             ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
1592      {
1593         if (sd->focused == ELM_COLORSELECTOR_COMPONENTS)
1594           {
1595              sd->sel_color_type = sd->sel_color_type - 1;
1596              if (sd->sel_color_type < HUE)
1597                {
1598                   if (sd->mode == ELM_COLORSELECTOR_BOTH)
1599                     {
1600                        sd->focused = ELM_COLORSELECTOR_PALETTE;
1601                        /*when focus is shifted to palette start from
1602                         * first item*/
1603                        sd->selected = sd->items;
1604                        cl = sd->selected;
1605                     }
1606                   else
1607                     {
1608                        sd->sel_color_type = HUE;
1609                        return EINA_FALSE;
1610                     }
1611                }
1612           }
1613         else if (sd->focused == ELM_COLORSELECTOR_PALETTE)
1614           return EINA_FALSE;
1615      }
1616    else if ((!strcmp(ev->keyname, "Down")) ||
1617             ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
1618      {
1619         if (sd->focused == ELM_COLORSELECTOR_PALETTE)
1620           {
1621              if (sd->mode == ELM_COLORSELECTOR_BOTH)
1622                {
1623                   sd->focused = ELM_COLORSELECTOR_COMPONENTS;
1624                   /*when focus is shifted to component start from
1625                    * first color type*/
1626                   sd->sel_color_type = HUE;
1627                }
1628              else return EINA_FALSE;
1629           }
1630         else if (sd->focused == ELM_COLORSELECTOR_COMPONENTS)
1631           {
1632              snprintf(colorbar_s, sizeof(colorbar_s), "elm.colorbar_%d",
1633                       (sd->sel_color_type + 1));
1634              /*Append color type only if next color bar is available*/
1635              if (edje_object_part_swallow_get(sd->col_bars_area, colorbar_s))
1636                sd->sel_color_type = sd->sel_color_type + 1;
1637              else return EINA_FALSE;
1638           }
1639      }
1640    else return EINA_FALSE;
1641    if (cl)
1642      {
1643         item = eina_list_data_get(cl);
1644         elm_object_signal_emit(VIEW(item), "elm,anim,activate", "elm");
1645         evas_object_smart_callback_call
1646           (WIDGET(item), SIG_COLOR_ITEM_SELECTED, item);
1647         elm_colorselector_color_set
1648           (WIDGET(item), item->color->r, item->color->g, item->color->b,
1649           item->color->a);
1650         sd->selected = cl;
1651      }
1652    else if (!cl && sd->focused == ELM_COLORSELECTOR_PALETTE)
1653      return EINA_FALSE;
1654    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1655    return EINA_TRUE;
1656 }
1657
1658 static Eina_Bool
1659 _elm_colorselector_smart_focus_next(const Evas_Object *obj,
1660                                     Elm_Focus_Direction dir,
1661                                     Evas_Object **next)
1662 {
1663    Eina_List *items = NULL;
1664    Eina_List *l;
1665    Elm_Widget_Item *item;
1666    int i = 0;
1667
1668    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1669    if (!sd) return EINA_FALSE;
1670
1671    if (!sd->items) return EINA_FALSE;
1672
1673    EINA_LIST_FOREACH(sd->items, l, item)
1674      items = eina_list_append(items, item->access_obj);
1675
1676    for (i = 0; i < 4; i++)
1677      {
1678         items = eina_list_append(items, sd->cb_data[i]->lbt);
1679         items = eina_list_append(items, sd->cb_data[i]->access_obj);
1680         items = eina_list_append(items, sd->cb_data[i]->rbt);
1681      }
1682
1683    return elm_widget_focus_list_next_get
1684             (obj, items, eina_list_data_get, dir, next);
1685 }
1686
1687 static void
1688 _access_obj_process(Evas_Object *obj, Eina_Bool is_access)
1689 {
1690    Eina_List *l;
1691    Elm_Color_Item *it;
1692    int i = 0;
1693
1694    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1695
1696    if (is_access)
1697      {
1698         EINA_LIST_FOREACH(sd->items, l, it)
1699           _access_widget_item_register(it);
1700
1701         for (i = 0; i < 4; i++)
1702           _access_colorbar_register(obj, sd->cb_data[i],
1703                                     "elm.arrow_bg_access");
1704      }
1705    else
1706      {
1707         EINA_LIST_FOREACH(sd->items, l, it)
1708           _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
1709
1710         //TODO: _elm_access_edje_object_part_object_unregister() ?
1711      }
1712 }
1713
1714 static void
1715 _access_hook(Evas_Object *obj, Eina_Bool is_access)
1716 {
1717    ELM_COLORSELECTOR_CHECK(obj);
1718    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1719
1720    if (is_access)
1721      ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
1722        _elm_colorselector_smart_focus_next;
1723    else
1724      ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
1725
1726    _access_obj_process(obj, is_access);
1727 }
1728
1729 static void
1730 _elm_colorselector_smart_set_user(Elm_Colorselector_Smart_Class *sc)
1731 {
1732    ELM_WIDGET_CLASS(sc)->base.add = _elm_colorselector_smart_add;
1733    ELM_WIDGET_CLASS(sc)->base.del = _elm_colorselector_smart_del;
1734
1735    /* not a 'focus chain manager' */
1736    ELM_WIDGET_CLASS(sc)->focus_next = NULL;
1737    ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
1738
1739    ELM_WIDGET_CLASS(sc)->theme = _elm_colorselector_smart_theme;
1740    ELM_WIDGET_CLASS(sc)->event = _elm_colorselector_smart_event;
1741
1742    ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_colorselector_smart_sizing_eval;
1743
1744    // ACCESS
1745    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
1746       ELM_WIDGET_CLASS(sc)->focus_next = _elm_colorselector_smart_focus_next;
1747
1748    ELM_WIDGET_CLASS(sc)->access = _access_hook;
1749 }
1750
1751 EAPI const Elm_Colorselector_Smart_Class *
1752 elm_colorselector_smart_class_get(void)
1753 {
1754    static Elm_Colorselector_Smart_Class _sc =
1755      ELM_COLORSELECTOR_SMART_CLASS_INIT_NAME_VERSION
1756        (ELM_COLORSELECTOR_SMART_NAME);
1757    static const Elm_Colorselector_Smart_Class *class = NULL;
1758    Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
1759
1760    if (class)
1761      return class;
1762
1763    _elm_colorselector_smart_set(&_sc);
1764    esc->callbacks = _smart_callbacks;
1765    class = &_sc;
1766
1767    return class;
1768 }
1769
1770 EAPI Evas_Object *
1771 elm_colorselector_add(Evas_Object *parent)
1772 {
1773    Evas_Object *obj;
1774
1775    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
1776
1777    obj = elm_widget_add(_elm_colorselector_smart_class_new(), parent);
1778    if (!obj) return NULL;
1779
1780    if (!elm_widget_sub_object_add(parent, obj))
1781      ERR("could not add %p as sub object of %p", obj, parent);
1782
1783    return obj;
1784 }
1785
1786 EAPI void
1787 elm_colorselector_color_set(Evas_Object *obj,
1788                             int r,
1789                             int g,
1790                             int b,
1791                             int a)
1792 {
1793    ELM_COLORSELECTOR_CHECK(obj);
1794
1795    _colors_set(obj, r, g, b, a);
1796 }
1797
1798 EAPI void
1799 elm_colorselector_color_get(const Evas_Object *obj,
1800                             int *r,
1801                             int *g,
1802                             int *b,
1803                             int *a)
1804 {
1805    ELM_COLORSELECTOR_CHECK(obj);
1806    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1807
1808    if (r) *r = sd->r;
1809    if (g) *g = sd->g;
1810    if (b) *b = sd->b;
1811    if (a) *a = sd->a;
1812 }
1813
1814 EAPI void
1815 elm_colorselector_mode_set(Evas_Object *obj,
1816                            Elm_Colorselector_Mode mode)
1817 {
1818    ELM_COLORSELECTOR_CHECK(obj);
1819    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1820
1821    if (sd->mode == mode) return;
1822    sd->mode = mode;
1823
1824    evas_object_hide(elm_layout_content_unset(obj, "selector"));
1825    evas_object_hide(elm_layout_content_unset(obj, "palette"));
1826    evas_object_hide(elm_layout_content_unset(obj, "picker"));
1827
1828    switch (sd->mode)
1829      {
1830       case ELM_COLORSELECTOR_PALETTE:
1831         elm_layout_content_set(obj, "palette", sd->palette_box);
1832         elm_layout_signal_emit(obj, "elm,state,palette", "elm");
1833         sd->focused = ELM_COLORSELECTOR_PALETTE;
1834         sd->selected = sd->items;
1835         break;
1836
1837       case ELM_COLORSELECTOR_COMPONENTS:
1838         elm_layout_content_set(obj, "selector", sd->col_bars_area);
1839         elm_layout_signal_emit(obj, "elm,state,components", "elm");
1840         sd->focused = ELM_COLORSELECTOR_COMPONENTS;
1841         sd->sel_color_type = HUE;
1842         break;
1843
1844       case ELM_COLORSELECTOR_BOTH:
1845         elm_layout_content_set(obj, "palette", sd->palette_box);
1846         elm_layout_content_set(obj, "selector", sd->col_bars_area);
1847         elm_layout_signal_emit(obj, "elm,state,both", "elm");
1848         sd->focused = ELM_COLORSELECTOR_PALETTE;
1849         sd->selected = sd->items;
1850         break;
1851
1852       case ELM_COLORSELECTOR_PICKER:
1853         elm_layout_content_set(obj, "picker", sd->picker);
1854         elm_layout_signal_emit(obj, "elm,state,picker", "elm");
1855         sd->focused = ELM_COLORSELECTOR_PICKER;
1856         break;
1857          
1858       case ELM_COLORSELECTOR_ALL:
1859         elm_layout_content_set(obj, "picker", sd->picker);
1860         elm_layout_content_set(obj, "palette", sd->palette_box);
1861         elm_layout_content_set(obj, "selector", sd->col_bars_area);
1862         elm_layout_signal_emit(obj, "elm,state,all", "elm");
1863         sd->focused = ELM_COLORSELECTOR_PALETTE;
1864         sd->selected = sd->items;
1865         break;
1866
1867       default:
1868         return;
1869      }
1870
1871    edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
1872
1873    elm_layout_sizing_eval(obj);
1874 }
1875
1876 EAPI Elm_Colorselector_Mode
1877 elm_colorselector_mode_get(const Evas_Object *obj)
1878 {
1879    ELM_COLORSELECTOR_CHECK(obj) ELM_COLORSELECTOR_BOTH;
1880    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1881
1882    return sd->mode;
1883 }
1884
1885 EAPI void
1886 elm_colorselector_palette_item_color_get(const Elm_Object_Item *it,
1887                                          int *r,
1888                                          int *g,
1889                                          int *b,
1890                                          int *a)
1891 {
1892    Elm_Color_Item *item;
1893
1894    ELM_COLORSELECTOR_ITEM_CHECK_OR_RETURN(it);
1895
1896    item = (Elm_Color_Item *)it;
1897    if (item)
1898      {
1899         if (r) *r = item->color->r;
1900         if (g) *g = item->color->g;
1901         if (b) *b = item->color->b;
1902         if (a) *a = item->color->a;
1903      }
1904 }
1905
1906 EAPI void
1907 elm_colorselector_palette_item_color_set(Elm_Object_Item *it,
1908                                          int r,
1909                                          int g,
1910                                          int b,
1911                                          int a)
1912 {
1913    Elm_Color_Item *item;
1914
1915    ELM_COLORSELECTOR_ITEM_CHECK_OR_RETURN(it);
1916
1917    item = (Elm_Color_Item *)it;
1918    item->color->r = r;
1919    item->color->g = g;
1920    item->color->b = b;
1921    item->color->a = a;
1922    evas_object_color_set
1923      (item->color_obj, item->color->r, item->color->g, item->color->b,
1924      item->color->a);
1925
1926    _colors_save(WIDGET(it));
1927 }
1928
1929 EAPI Elm_Object_Item *
1930 elm_colorselector_palette_color_add(Evas_Object *obj,
1931                                     int r,
1932                                     int g,
1933                                     int b,
1934                                     int a)
1935 {
1936    Elm_Color_Item *item;
1937
1938    ELM_COLORSELECTOR_CHECK(obj) NULL;
1939    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1940
1941    if (sd->config_load)
1942      {
1943         _colors_remove(obj);
1944         sd->config_load = EINA_FALSE;
1945      }
1946    item = _item_new(obj);
1947    if (!item) return NULL;
1948
1949    item->color = ELM_NEW(Elm_Color_RGBA);
1950    if (!item->color) return NULL;
1951
1952    item->color->r = r;
1953    item->color->g = g;
1954    item->color->b = b;
1955    item->color->a = a;
1956    _elm_config_color_set
1957      (sd->palette_name, item->color->r, item->color->g, item->color->b,
1958      item->color->a);
1959
1960    elm_box_pack_end(sd->palette_box, VIEW(item));
1961    evas_object_color_set
1962      (item->color_obj, item->color->r, item->color->g, item->color->b,
1963      item->color->a);
1964
1965    sd->items = eina_list_append(sd->items, item);
1966
1967    elm_layout_sizing_eval(obj);
1968
1969    return (Elm_Object_Item *)item;
1970 }
1971
1972 EAPI void
1973 elm_colorselector_palette_clear(Evas_Object *obj)
1974 {
1975    ELM_COLORSELECTOR_CHECK(obj);
1976    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1977
1978    _colors_remove(obj);
1979    if (sd->mode == ELM_COLORSELECTOR_BOTH)
1980      sd->focused = ELM_COLORSELECTOR_COMPONENTS;
1981 }
1982
1983 EAPI void
1984 elm_colorselector_palette_name_set(Evas_Object *obj,
1985                                    const char *palette_name)
1986 {
1987    ELM_COLORSELECTOR_CHECK(obj);
1988    ELM_COLORSELECTOR_DATA_GET(obj, sd);
1989    EINA_SAFETY_ON_NULL_RETURN(palette_name);
1990
1991    if (!strcmp(sd->palette_name, palette_name)) return;
1992
1993    _colors_remove(obj);
1994    eina_stringshare_replace(&sd->palette_name, palette_name);
1995    _palette_colors_load(obj);
1996 }
1997
1998 EAPI const char *
1999 elm_colorselector_palette_name_get(const Evas_Object *obj)
2000 {
2001    ELM_COLORSELECTOR_CHECK(obj) NULL;
2002    ELM_COLORSELECTOR_DATA_GET(obj, sd);
2003
2004    return sd->palette_name;
2005 }