elemenatry/colorselector - finally first implementation going on
[framework/uifw/elementary.git] / src / lib / elm_colorselector.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 #define BASE_STEP 360.0
5 #define HUE_STEP 360.0
6 #define SAT_STEP 128.0
7 #define LIG_STEP 256.0
8 #define ALP_STEP 256.0
9 #define DEFAULT_HOR_PAD 10
10 #define DEFAULT_VER_PAD 10
11
12 typedef enum _Color_Type
13 {
14    HUE,
15    SATURATION,
16    LIGHTNESS,
17    ALPHA
18 } Color_Type;
19
20 typedef struct _Colorselector_Data Colorselector_Data;
21 struct _Colorselector_Data
22 {
23    Evas_Object *parent;
24    Evas_Object *colorbar;
25    Evas_Object *bar;
26    Evas_Object *lbt;
27    Evas_Object *rbt;
28    Evas_Object *bg_rect;
29    Evas_Object *arrow;
30    Evas_Object *touch_area;
31    Color_Type color_type;
32 };
33
34 typedef struct _Widget_Data Widget_Data;
35 typedef struct _Elm_Color_Item Elm_Color_Item;
36 struct _Widget_Data
37 {
38    Evas_Object *sel;
39    Evas_Object *base;
40    Evas_Object *box;
41    Eina_List *items;
42    Colorselector_Data *cp[4];
43    Ecore_Timer *longpress_timer;
44    const char *palette_name;
45    Evas_Coord _x, _y, _w, _h;
46    int r, g, b, a;
47    int er, eg, eb;
48    int sr, sg, sb;
49    int lr, lg, lb;
50    double h, s, l;
51    Elm_Colorselector_Mode mode;
52    Eina_Bool longpressed : 1;
53    Eina_Bool config_load: 1;
54 };
55
56 struct _Elm_Color_Item
57 {
58    ELM_WIDGET_ITEM;
59    Evas_Object *color_obj;
60    Elm_Color_RGBA *color;
61 };
62
63 static const char *widtype = NULL;
64
65 static void _del_hook(Evas_Object *obj);
66 static void _theme_hook(Evas_Object *obj);
67 static void _sizing_eval(Evas_Object *obj);
68 static void _resize_cb(void *data, Evas *a, Evas_Object *obj, void *event_info);
69 static void _rgb_to_hsl(void *data);
70 static void _hsl_to_rgb(void *data);
71 static void _color_with_saturation(void *data);
72 static void _color_with_lightness(void *data);
73 static void _draw_rects(void *data, double x);
74 static void _arrow_cb(void *data, Evas_Object *obj, const char *emission,
75                       const char *source);
76 static void _colorbar_cb(void *data, Evas *e, Evas_Object *obj,
77                          void *event_info);
78 static void _left_button_clicked_cb(void *data, Evas_Object * obj,
79                                     void *event_info);
80 static void _left_button_repeat_cb(void *data, Evas_Object * obj,
81                                    void *event_info);
82 static void _right_button_clicked_cb(void *data, Evas_Object * obj,
83                                      void *event_info);
84 static void _right_button_repeat_cb(void *data, Evas_Object * obj,
85                                     void *event_info);
86 static void _add_colorbar(Evas_Object *obj);
87 static void _set_color(Evas_Object *obj, int r, int g, int b, int a);
88 static Elm_Color_Item *_item_new(Evas_Object *obj);
89 static void _item_sizing_eval(Elm_Color_Item *item);
90 static void _item_highlight(void *data, Evas *e, Evas_Object *obj, void *event_info);
91 static void _item_unhighlight(void *data, Evas *e, Evas_Object *obj, void *event_info);
92 static Eina_Bool _long_press(void *data);
93 static void _remove_items(Widget_Data *wd);
94 static void _colors_remove(Evas_Object *obj);
95 static void _colors_save(Evas_Object *obj);
96 static void _colors_load_apply(Evas_Object *obj);
97
98 static const char SIG_CHANGED[] = "changed";
99 static const char SIG_COLOR_ITEM_SELECTED[] = "color,item,selected";
100 static const char SIG_COLOR_ITEM_LONGPRESSED[] = "color,item,longpressed";
101
102 static const Evas_Smart_Cb_Description _signals[] =
103 {
104    {SIG_COLOR_ITEM_SELECTED, ""},
105    {SIG_COLOR_ITEM_LONGPRESSED, ""},
106    {SIG_CHANGED, ""},
107    {NULL, NULL}
108 };
109
110 static void
111 _del_hook(Evas_Object *obj)
112 {
113    Widget_Data *wd = elm_widget_data_get(obj);
114    int i = 0;
115
116    if (!wd) return;
117    if (wd->longpress_timer) ecore_timer_del(wd->longpress_timer);
118    if (wd->palette_name) eina_stringshare_del(wd->palette_name);
119    _remove_items(wd);
120    for (i = 0; i < 4; i++) free(wd->cp[i]);
121    free(wd);
122 }
123
124 static void
125 _theme_hook(Evas_Object *obj)
126 {
127    Widget_Data *wd = elm_widget_data_get(obj);
128    Eina_List *elist;
129    Elm_Color_Item *item;
130    int i;
131
132    if ((!wd) || (!wd->sel)) return;
133
134    _elm_theme_object_set(obj, wd->base, "colorselector", "palette",
135                          elm_widget_style_get(obj));
136    _elm_theme_object_set(obj, wd->sel, "colorselector", "bg",
137                          elm_widget_style_get(obj));
138    EINA_LIST_FOREACH(wd->items, elist, item)
139      {
140         elm_layout_theme_set(VIEW(item), "colorselector", "item", elm_widget_style_get(obj));
141         _elm_theme_object_set(obj, item->color_obj, "colorselector", "item/color", elm_widget_style_get(obj));
142      }
143    for (i = 0; i < 4; i++)
144      {
145         evas_object_del(wd->cp[i]->colorbar);
146         wd->cp[i]->colorbar = NULL;
147         evas_object_del(wd->cp[i]->bar);
148         wd->cp[i]->bar = NULL;
149         evas_object_del(wd->cp[i]->lbt);
150         wd->cp[i]->lbt = NULL;
151         evas_object_del(wd->cp[i]->rbt);
152         wd->cp[i]->rbt = NULL;
153         if (i != 0)
154           {
155              evas_object_del(wd->cp[i]->bg_rect);
156              wd->cp[i]->bg_rect = NULL;
157           }
158         evas_object_del(wd->cp[i]->arrow);
159         wd->cp[i]->arrow = NULL;
160         evas_object_del(wd->cp[i]->touch_area);
161         wd->cp[i]->touch_area = NULL;
162      }
163
164    _add_colorbar(obj);
165    elm_colorselector_color_set(obj, wd->r, wd->g, wd->b, wd->a);
166    _sizing_eval(obj);
167 }
168
169 static void
170 _colorselector_set_size_hints(Evas_Object *obj, int timesw, int timesh)
171 {
172    Evas_Coord minw = -1, minh = -1;
173
174    elm_coords_finger_size_adjust(timesw, &minw, timesh, &minh);
175    edje_object_size_min_restricted_calc(obj, &minw, &minh,
176                                         minw, minh);
177    evas_object_size_hint_min_set(obj, minw, minh);
178    evas_object_size_hint_max_set(obj, -1, -1);
179 }
180
181 static void
182 _item_sizing_eval(Elm_Color_Item *item)
183 {
184    Evas_Coord minw = -1, minh = -1;
185
186    if (!item) return;
187
188    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
189    edje_object_size_min_restricted_calc(VIEW(item), &minw, &minh, minw,
190                                         minh);
191    evas_object_size_hint_min_set(VIEW(item), minw, minh);
192 }
193
194 static void _resize_cb(void *data, Evas *a __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
195 {
196    _sizing_eval(data);
197 }
198
199 static void
200 _sizing_eval_palette(Evas_Object *obj)
201 {
202    Widget_Data *wd = elm_widget_data_get(obj);
203    Eina_List *elist;
204    Elm_Color_Item *item;
205    Evas_Coord bw = 0, bh = 0;
206    Evas_Coord w = 0, h = 0;
207    if (!wd) return;
208
209    EINA_LIST_FOREACH(wd->items, elist, item)
210      {
211         _item_sizing_eval(item);
212      }
213    evas_object_size_hint_min_get(wd->box, &bw, &bh);
214    evas_object_size_hint_min_set(obj, bw, bh);
215    evas_object_size_hint_max_set(obj, -1, -1);
216    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
217    if (w < bw) w = bw;
218    if (h < bh) h = bh;
219    evas_object_resize(obj, w, h);
220 }
221
222 static void
223 _sizing_eval_selector(Evas_Object *obj)
224 {
225    Widget_Data *wd = elm_widget_data_get(obj);
226    Evas_Coord minw = -1, minh = -1;
227    Evas_Coord w = 0, h = 0;
228    int i;
229
230    if (!wd) return;
231    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
232    for (i = 0; i < 4; i++)
233      {
234         if (wd->cp[i]->bg_rect)
235           _colorselector_set_size_hints(wd->cp[i]->bg_rect, 1, 1);
236         _colorselector_set_size_hints(wd->cp[i]->bar, 1, 1);
237         _colorselector_set_size_hints(wd->cp[i]->rbt, 1, 1);
238         _colorselector_set_size_hints(wd->cp[i]->lbt, 1, 1);
239
240         _colorselector_set_size_hints(wd->cp[i]->colorbar, 4, 1);
241      }
242
243    elm_coords_finger_size_adjust(4, &minw, 4, &minh);
244    edje_object_size_min_restricted_calc(wd->sel, &minw, &minh, minw, minh);
245    evas_object_size_hint_min_set(obj, minw, minh);
246    evas_object_size_hint_max_set(obj, -1, -1);
247    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
248    if (w < minw) w = minw;
249    if (h < minh) h = minh;
250    evas_object_resize(obj, w, h);
251 }
252
253 static void
254 _sizing_eval_palette_selector(Evas_Object *obj)
255 {
256    Widget_Data *wd = elm_widget_data_get(obj);
257    Evas_Coord minw = -1, minh = -1;
258    Evas_Coord bw = 0, bh = 0;
259    Evas_Coord w = 0, h = 0;
260    int i;
261    if (!wd) return;
262    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
263    for (i = 0; i < 4; i++)
264      {
265         if (wd->cp[i]->bg_rect)
266           _colorselector_set_size_hints(wd->cp[i]->bg_rect, 1, 1);
267         _colorselector_set_size_hints(wd->cp[i]->bar, 1, 1);
268         _colorselector_set_size_hints(wd->cp[i]->rbt, 1, 1);
269         _colorselector_set_size_hints(wd->cp[i]->lbt, 1, 1);
270
271         _colorselector_set_size_hints(wd->cp[i]->colorbar, 4, 1);
272      }
273
274    elm_coords_finger_size_adjust(4, &minw, 4, &minh);
275    edje_object_size_min_restricted_calc(wd->sel, &minw, &minh, minw, minh);
276    evas_object_size_hint_min_get(wd->box, &bw, &bh);
277    evas_object_size_hint_min_set(obj, minw, minh+bh);
278    evas_object_size_hint_max_set(obj, -1, -1);
279    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
280    if (w < minw) w = minw;
281    if (h < (minh+bh)) h = (minh+bh);
282    evas_object_resize(obj, w, h);
283 }
284
285 static void
286 _sizing_eval(Evas_Object *obj)
287 {
288    Widget_Data *wd = elm_widget_data_get(obj);
289    if (!wd) return;
290    switch (wd->mode)
291      {
292         case ELM_COLORSELECTOR_PALETTE:
293            _sizing_eval_palette(obj);
294            break;
295         case ELM_COLORSELECTOR_COMPONENTS:
296            _sizing_eval_selector(obj);
297            break;
298         case ELM_COLORSELECTOR_BOTH:
299            _sizing_eval_palette_selector(obj);
300            break;
301         default:
302            break;
303      }
304 }
305
306 static Eina_Bool
307 _long_press(void *data)
308 {
309    Elm_Color_Item *item = (Elm_Color_Item *) data;
310    Widget_Data *wd = elm_widget_data_get(WIDGET(item));
311    if (!wd) return ECORE_CALLBACK_CANCEL;
312    wd->longpress_timer = NULL;
313    wd->longpressed = EINA_TRUE;
314    evas_object_smart_callback_call(WIDGET(item), SIG_COLOR_ITEM_LONGPRESSED, item);
315    return ECORE_CALLBACK_CANCEL;
316 }
317
318 static void
319 _item_highlight(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
320 {
321    Elm_Color_Item *item = (Elm_Color_Item *) data;
322    Evas_Event_Mouse_Down *ev = event_info;
323    if (!item) return;
324    Widget_Data *wd = elm_widget_data_get(WIDGET(item));
325    if (!wd) return;
326    if (ev->button != 1) return;
327    elm_object_signal_emit(VIEW(item), "elm,state,selected", "elm");
328    wd->longpressed = EINA_FALSE;
329    if (wd->longpress_timer) ecore_timer_del(wd->longpress_timer);
330    wd->longpress_timer = ecore_timer_add(_elm_config->longpress_timeout, _long_press, data);
331 }
332
333 static void
334 _item_unhighlight(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
335 {
336    Elm_Color_Item *item = (Elm_Color_Item *) data;
337    Evas_Event_Mouse_Down *ev = event_info;
338    if (!item) return;
339    Widget_Data *wd = elm_widget_data_get(WIDGET(item));
340    if (!wd) return;
341    if (ev->button != 1) return;
342    if (wd->longpress_timer)
343      {
344         ecore_timer_del(wd->longpress_timer);
345         wd->longpress_timer = NULL;
346      }
347    elm_object_signal_emit(VIEW(item), "elm,state,unselected", "elm");
348    if (!wd->longpressed)
349      {
350         evas_object_smart_callback_call(WIDGET(item), SIG_COLOR_ITEM_SELECTED, item);
351         elm_colorselector_color_set(WIDGET(item), item->color->r, item->color->g, item->color->b, item->color->a);
352      }
353 }
354
355 static void
356 _remove_items(Widget_Data *wd)
357 {
358    Elm_Color_Item *item;
359
360    if (!wd->items) return;
361
362    EINA_LIST_FREE(wd->items, item)
363      {
364         free(item->color);
365         elm_widget_item_free(item);
366      }
367
368    wd->items = NULL;
369 }
370
371 static Elm_Color_Item*
372 _item_new(Evas_Object *obj)
373 {
374    Elm_Color_Item *item;
375    Widget_Data *wd;
376
377    wd = elm_widget_data_get(obj);
378    if (!wd) return NULL;
379
380    item = elm_widget_item_new(obj, Elm_Color_Item);
381    if (!item) return NULL;
382
383    VIEW(item) = elm_layout_add(obj);
384    elm_layout_theme_set(VIEW(item), "colorselector", "item", elm_widget_style_get(obj));
385    evas_object_size_hint_weight_set(VIEW(item), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
386    evas_object_size_hint_align_set(VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
387    item->color_obj = edje_object_add(evas_object_evas_get(obj));
388    _elm_theme_object_set(obj, item->color_obj, "colorselector", "item/color", elm_widget_style_get(obj));
389    evas_object_size_hint_weight_set(item->color_obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
390    evas_object_size_hint_align_set(item->color_obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
391    evas_object_event_callback_add(item->color_obj, EVAS_CALLBACK_MOUSE_DOWN, _item_highlight, item);
392    evas_object_event_callback_add(item->color_obj, EVAS_CALLBACK_MOUSE_UP, _item_unhighlight, item);
393    elm_object_part_content_set(VIEW(item), "color_obj", item->color_obj);
394    _item_sizing_eval(item);
395    evas_object_show(VIEW(item));
396
397    return item;
398 }
399
400 static void
401 _colors_remove(Evas_Object *obj)
402 {
403    Widget_Data *wd = elm_widget_data_get(obj);
404
405    _remove_items(wd);
406    _elm_config_colors_free(wd->palette_name);
407 }
408
409 static void _colors_save(Evas_Object *obj)
410 {
411    Eina_List *elist;
412    Widget_Data *wd = elm_widget_data_get(obj);
413    Elm_Color_Item *item;
414    _elm_config_colors_free(wd->palette_name);
415    EINA_LIST_FOREACH(wd->items, elist, item)
416      {
417         _elm_config_color_set(wd->palette_name, item->color->r, item->color->g,
418                               item->color->b, item->color->a);
419      }
420 }
421
422 static void
423 _colors_load_apply(Evas_Object *obj)
424 {
425    Elm_Color_RGBA *color;
426    Eina_List *elist;
427    Eina_List *color_list;
428    Elm_Color_Item *item;
429    Widget_Data *wd = elm_widget_data_get(obj);
430    color_list = _elm_config_color_list_get(wd->palette_name);
431    if (!color_list) return;
432    EINA_LIST_FOREACH(color_list, elist, color)
433      {
434         item = _item_new(obj);
435         if (!item) return;
436         item->color = ELM_NEW(Elm_Color_RGBA);
437         if (!item->color) return;
438         item->color->r = color->r;
439         item->color->g = color->g;
440         item->color->b = color->b;
441         item->color->a = color->a;
442         elm_box_pack_end(wd->box, VIEW(item));
443         evas_object_color_set(item->color_obj, item->color->r, item->color->g,
444                               item->color->b, item->color->a);
445         wd->items = eina_list_append(wd->items, item);
446         _sizing_eval_palette(obj);
447      }
448    wd->config_load = EINA_TRUE;
449 }
450
451 static void
452 _rgb_to_hsl(void *data)
453 {
454    Widget_Data *wd = data;
455    double r, g, b;
456    double v, m, vm;
457    double r2, g2, b2;
458
459    r = wd->r;
460    g = wd->g;
461    b = wd->b;
462
463    r /= 255.0;
464    g /= 255.0;
465    b /= 255.0;
466
467    v = (r > g) ? r : g;
468    v = (v > b) ? v : b;
469
470    m = (r < g) ? r : g;
471    m = (m < b) ? m : b;
472
473    wd->h = 0.0;
474    wd->s = 0.0;
475    wd->l = 0.0;
476
477    wd->l = (m + v) / 2.0;
478
479    if (wd->l <= 0.0) return;
480
481    vm = v - m;
482    wd->s = vm;
483
484    if (wd->s > 0.0) wd->s /= (wd->l <= 0.5) ? (v + m) : (2.0 - v - m);
485    else return;
486
487    r2 = (v - r) / vm;
488    g2 = (v - g) / vm;
489    b2 = (v - b) / vm;
490
491    if (r == v) wd->h = (g == m ? 5.0 + b2 : 1.0 - g2);
492    else if (g == v) wd->h = (b == m ? 1.0 + r2 : 3.0 - b2);
493    else wd->h = (r == m ? 3.0 + g2 : 5.0 - r2);
494
495    wd->h *= 60.0;
496 }
497
498 static void
499 _hsl_to_rgb(void *data)
500 {
501    Widget_Data *wd = data;
502    double r = 0, g = 0, b = 0;
503    double _h, _s, _l;
504    int i = 0;
505    double sv, vsf, f, p, q, t, v;
506
507    _h = wd->h;
508    _s = wd->s;
509    _l = wd->l;
510
511    if (_s == 0.0) r = g = b = _l;
512    else
513      {
514         if (_h == 360.0) _h = 0.0;
515         _h /= 60.0;
516
517         v = (_l <= 0.5) ? (_l * (1.0 + _s)) : (_l + _s - (_l * _s));
518         p = _l + _l - v;
519
520         if (v) sv = (v - p) / v;
521         else sv = 0;
522
523         i = (int)_h;
524         f = _h - i;
525
526         vsf = v * sv * f;
527
528         t = p + vsf;
529         q = v - vsf;
530
531         switch (i)
532           {
533            case 0:
534               r = v;
535               g = t;
536               b = p;
537               break;
538            case 1:
539               r = q;
540               g = v;
541               b = p;
542               break;
543            case 2:
544               r = p;
545               g = v;
546               b = t;
547               break;
548            case 3:
549               r = p;
550               g = q;
551               b = v;
552               break;
553            case 4:
554               r = t;
555               g = p;
556               b = v;
557               break;
558            case 5:
559               r = v;
560               g = p;
561               b = q;
562               break;
563           }
564      }
565    i = (int)(r * 255.0);
566    f = (r * 255.0) - i;
567    wd->r = (f <= 0.5) ? i : (i + 1);
568
569    i = (int)(g * 255.0);
570    f = (g * 255.0) - i;
571    wd->g = (f <= 0.5) ? i : (i + 1);
572
573    i = (int)(b * 255.0);
574    f = (b * 255.0) - i;
575    wd->b = (f <= 0.5) ? i : (i + 1);
576 }
577
578 static void
579 _color_with_saturation(void *data)
580 {
581    Widget_Data *wd = data;
582
583    if (wd->er > 127)
584      wd->sr = 127 + (int)((double)(wd->er - 127) * wd->s);
585    else
586      wd->sr = 127 - (int)((double)(127 - wd->er) * wd->s);
587
588    if (wd->eg > 127)
589      wd->sg = 127 + (int)((double)(wd->eg - 127) * wd->s);
590    else
591      wd->sg = 127 - (int)((double)(127 - wd->eg) * wd->s);
592
593    if (wd->eb > 127)
594      wd->sb = 127 + (int)((double)(wd->eb - 127) * wd->s);
595    else
596      wd->sb = 127 - (int)((double)(127 - wd->eb) * wd->s);
597 }
598
599 static void
600 _color_with_lightness(void *data)
601 {
602    Widget_Data *wd = data;
603
604    if (wd->l > 0.5)
605      {
606         wd->lr = wd->er + (int)((double)(255 - wd->er) * (wd->l - 0.5) * 2.0);
607         wd->lg = wd->eg + (int)((double)(255 - wd->eg) * (wd->l - 0.5) * 2.0);
608         wd->lb = wd->eb + (int)((double)(255 - wd->eb) * (wd->l - 0.5) * 2.0);
609      }
610    else if (wd->l < 0.5)
611      {
612         wd->lr = (double)wd->er * wd->l * 2.0;
613         wd->lg = (double)wd->eg * wd->l * 2.0;
614         wd->lb = (double)wd->eb * wd->l * 2.0;
615      }
616    else
617      {
618         wd->lr = wd->er;
619         wd->lg = wd->eg;
620         wd->lb = wd->eb;
621      }
622 }
623
624 static void
625 _draw_rects(void *data, double x)
626 {
627    Colorselector_Data *cp = data;
628    Widget_Data *wd = elm_widget_data_get(cp->parent);
629    double one_six = 1.0 / 6.0;
630
631    switch (cp->color_type)
632      {
633       case HUE:
634          wd->h = 360.0 * x;
635
636          if (x < one_six)
637            {
638               wd->er = 255;
639               wd->eg = (255.0 * x * 6.0);
640               wd->eb = 0;
641            }
642          else if (x < 2 * one_six)
643            {
644               wd->er = 255 - (int)(255.0 * (x - one_six) * 6.0);
645               wd->eg = 255;
646               wd->eb = 0;
647            }
648          else if (x < 3 * one_six)
649            {
650               wd->er = 0;
651               wd->eg = 255;
652               wd->eb = (int)(255.0 * (x - (2.0 * one_six)) * 6.0);
653            }
654          else if (x < 4 * one_six)
655            {
656               wd->er = 0;
657               wd->eg = 255 - (int)(255.0 * (x - (3.0 * one_six)) * 6.0);
658               wd->eb = 255;
659            }
660          else if (x < 5 * one_six)
661            {
662               wd->er = 255.0 * (x - (4.0 * one_six)) * 6.0;
663               wd->eg = 0;
664               wd->eb = 255;
665            }
666          else
667            {
668               wd->er = 255;
669               wd->eg = 0;
670               wd->eb = 255 - (int)(255.0 * (x - (5.0 * one_six)) * 6.0);
671            }
672
673          evas_object_color_set(wd->cp[0]->arrow, wd->er, wd->eg, wd->eb, 255);
674          evas_object_color_set(wd->cp[1]->bg_rect, wd->er, wd->eg, wd->eb, 255);
675          evas_object_color_set(wd->cp[2]->bg_rect, wd->er, wd->eg, wd->eb, 255);
676          evas_object_color_set(wd->cp[3]->bar, wd->er, wd->eg, wd->eb, 255);
677
678          _color_with_saturation(wd);
679          evas_object_color_set(wd->cp[1]->arrow, wd->sr, wd->sg, wd->sb, 255);
680
681          _color_with_lightness(wd);
682          evas_object_color_set(wd->cp[2]->arrow, wd->lr, wd->lg, wd->lb, 255);
683
684          evas_object_color_set(wd->cp[3]->arrow,
685                                (wd->er * wd->a) / 255,
686                                (wd->eg * wd->a) / 255,
687                                (wd->eb * wd->a) / 255,
688                                wd->a);
689          break;
690       case SATURATION:
691          wd->s = 1.0 - x;
692          _color_with_saturation(wd);
693          evas_object_color_set(wd->cp[1]->arrow, wd->sr, wd->sg, wd->sb, 255);
694          break;
695       case LIGHTNESS:
696          wd->l = x;
697          _color_with_lightness(wd);
698          evas_object_color_set(wd->cp[2]->arrow, wd->lr, wd->lg, wd->lb, 255);
699          break;
700       case ALPHA:
701          wd->a = 255.0 * x;
702          evas_object_color_set(wd->cp[3]->arrow,
703                                (wd->er * wd->a) / 255,
704                                (wd->eg * wd->a) / 255,
705                                (wd->eb * wd->a) / 255,
706                                wd->a);
707          break;
708       default:
709          break;
710      }
711    _hsl_to_rgb(wd);
712 }
713
714 static void
715 _arrow_cb(void *data, Evas_Object *obj, const char *emission __UNUSED__,
716           const char *source __UNUSED__)
717 {
718    Colorselector_Data *cp = data;
719    double x, y;
720
721    edje_object_part_drag_value_get(obj, "elm.arrow", &x, &y);
722    _draw_rects(data, x);
723    evas_object_smart_callback_call(cp->parent, SIG_CHANGED, NULL);
724 }
725
726 static void
727 _colorbar_cb(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
728 {
729    Colorselector_Data *cp = data;
730    Evas_Event_Mouse_Down *ev = event_info;
731    Evas_Coord x, y, w, h;
732    double arrow_x = 0, arrow_y;
733
734    evas_object_geometry_get(cp->bar, &x, &y, &w, &h);
735    edje_object_part_drag_value_get(cp->colorbar, "elm.arrow",
736                                    &arrow_x, &arrow_y);
737    if (w > 0) arrow_x = (double)(ev->canvas.x - x) / (double)w;
738    if (arrow_x > 1) arrow_x = 1;
739    if (arrow_x < 0) arrow_x = 0;
740    edje_object_part_drag_value_set(cp->colorbar, "elm.arrow", arrow_x, arrow_y);
741    _draw_rects(data, arrow_x);
742    evas_object_smart_callback_call(cp->parent, SIG_CHANGED, NULL);
743    evas_event_feed_mouse_cancel(e, 0, NULL);
744    evas_event_feed_mouse_down(e, 1, EVAS_BUTTON_NONE, 0, NULL);
745 }
746
747 static void
748 _left_button_clicked_cb(void *data, Evas_Object * obj __UNUSED__,
749                         void *event_info __UNUSED__)
750 {
751    Colorselector_Data *cp = data;
752    double x, y;
753
754    edje_object_signal_emit(cp->lbt, "elm,state,left,button,down",
755                            "left_button");
756    edje_object_part_drag_value_get(cp->colorbar, "elm.arrow", &x, &y);
757
758    switch(cp->color_type)
759      {
760       case HUE :
761          x -= 1.0 / HUE_STEP;
762          break;
763       case SATURATION :
764          x -= 1.0 / SAT_STEP;
765          break;
766       case LIGHTNESS :
767          x -= 1.0 / LIG_STEP;
768          break;
769       case ALPHA :
770          x -= 1.0 / ALP_STEP;
771          break;
772       default :
773          break;
774      }
775
776    if (x < 0.0) x = 0.0;
777
778    edje_object_part_drag_value_set(cp->colorbar, "elm.arrow", x, y);
779    _draw_rects(data, x);
780    evas_object_smart_callback_call(cp->parent, SIG_CHANGED, NULL);
781 }
782
783 static void
784 _left_button_repeat_cb(void *data, Evas_Object * obj __UNUSED__,
785                        void *event_info __UNUSED__)
786 {
787    Colorselector_Data *cp = data;
788    double x, y;
789
790    edje_object_part_drag_value_get(cp->colorbar, "elm.arrow", &x, &y);
791    x -= 1.0 / BASE_STEP;
792    if (x < 0.0) x = 0.0;
793    edje_object_part_drag_value_set(cp->colorbar, "elm.arrow", x, y);
794    _draw_rects(data, x);
795    evas_object_smart_callback_call(cp->parent, SIG_CHANGED, NULL);
796
797 }
798
799 static void
800 _right_button_clicked_cb(void *data, Evas_Object * obj __UNUSED__,
801                          void *event_info __UNUSED__)
802 {
803    Colorselector_Data *cp = data;
804    double x, y;
805
806    edje_object_signal_emit(cp->rbt, "elm,state,right,button,down",
807                            "right_button");
808    edje_object_part_drag_value_get(cp->colorbar, "elm.arrow", &x, &y);
809
810    switch(cp->color_type)
811      {
812       case HUE :
813          x += 1.0 / HUE_STEP;
814          break;
815       case SATURATION :
816          x += 1.0 / SAT_STEP;
817          break;
818       case LIGHTNESS :
819          x += 1.0 / LIG_STEP;
820          break;
821       case ALPHA :
822          x += 1.0 / ALP_STEP;
823          break;
824       default :
825          break;
826      }
827
828    if (x > 1.0) x = 1.0;
829
830    edje_object_part_drag_value_set(cp->colorbar, "elm.arrow", x, y);
831    _draw_rects(data, x);
832    evas_object_smart_callback_call(cp->parent, SIG_CHANGED, NULL);
833 }
834
835 static void
836 _right_button_repeat_cb(void *data, Evas_Object * obj __UNUSED__,
837                         void *event_info __UNUSED__)
838 {
839    Colorselector_Data *cp = data;
840    double x, y;
841
842    edje_object_part_drag_value_get(cp->colorbar, "elm.arrow", &x, &y);
843    x += 1.0 / BASE_STEP;
844    if (x > 1.0) x = 1.0;
845    edje_object_part_drag_value_set(cp->colorbar, "elm.arrow", x, y);
846    _draw_rects(data, x);
847    evas_object_smart_callback_call(cp->parent, SIG_CHANGED, NULL);
848 }
849
850 static void
851 _add_colorbar(Evas_Object *obj)
852 {
853    char colorbar_name[128];
854    char colorbar_s[128];
855    Widget_Data *wd;
856    Evas *e;
857    int i = 0;
858    char buf[1024];
859
860    wd = elm_widget_data_get(obj);
861    if (!wd) return;
862
863    e = evas_object_evas_get(obj);
864
865    for (i = 0; i < 4; i++)
866      {
867         wd->cp[i] = ELM_NEW(Colorselector_Data);
868         wd->cp[i]->parent = obj;
869         switch(i)
870           {
871            case 0 :
872               wd->cp[i]->color_type = HUE;
873               break;
874            case 1 :
875               wd->cp[i]->color_type = SATURATION;
876               break;
877            case 2 :
878               wd->cp[i]->color_type = LIGHTNESS;
879               break;
880            case 3 :
881               wd->cp[i]->color_type = ALPHA;
882               break;
883            default :
884               break;
885           }
886         /* load colorbar area */
887         wd->cp[i]->colorbar = edje_object_add(e);
888         _elm_theme_object_set(obj, wd->cp[i]->colorbar, "colorselector", "base",
889                               elm_widget_style_get(obj));
890         snprintf(colorbar_name, sizeof(colorbar_name), "colorbar_%d", i);
891         snprintf(colorbar_s, sizeof(colorbar_s), "elm.colorbar_%d", i);
892         edje_object_signal_callback_add(wd->cp[i]->colorbar, "drag", "*",
893                                         _arrow_cb, wd->cp[i]);
894         edje_object_part_swallow(wd->sel, colorbar_s, wd->cp[i]->colorbar);
895         elm_widget_sub_object_add(obj, wd->cp[i]->colorbar);
896
897         /* load colorbar image */
898         wd->cp[i]->bar = edje_object_add(e);
899         snprintf(buf, sizeof(buf), "%s/%s", colorbar_name,
900                  elm_widget_style_get(obj));
901         _elm_theme_object_set(obj, wd->cp[i]->bar, "colorselector", "image",
902                               buf);
903         edje_object_part_swallow(wd->cp[i]->colorbar, "elm.bar",
904                                  wd->cp[i]->bar);
905         elm_widget_sub_object_add(obj, wd->cp[i]->bar);
906
907         /* provide expanded touch area */
908         wd->cp[i]->touch_area = evas_object_rectangle_add(e);
909         evas_object_color_set(wd->cp[i]->touch_area, 0, 0, 0, 0);
910         edje_object_part_swallow(wd->cp[i]->colorbar, "elm.arrow_bg",
911                                  wd->cp[i]->touch_area);
912         evas_object_event_callback_add(wd->cp[i]->touch_area,
913                                        EVAS_CALLBACK_MOUSE_DOWN, _colorbar_cb,
914                                        wd->cp[i]);
915         elm_widget_sub_object_add(obj, wd->cp[i]->touch_area);
916
917         /* load background rectangle of the colorbar. used for
918            changing color of the opacity bar */
919         if ((i == 1) || (i == 2))
920           {
921              wd->cp[i]->bg_rect = evas_object_rectangle_add(e);
922              evas_object_color_set(wd->cp[i]->bg_rect, wd->er, wd->eg, wd->eb,
923                                    255);
924              edje_object_part_swallow(wd->cp[i]->colorbar, "elm.bar_bg",
925                                       wd->cp[i]->bg_rect);
926
927              elm_widget_sub_object_add(obj, wd->cp[i]->bg_rect);
928           }
929         if (i == 3)
930           {
931              wd->cp[i]->bg_rect = edje_object_add(e);
932              snprintf(buf, sizeof(buf), "%s/%s", colorbar_name,
933                       elm_widget_style_get(obj));
934              _elm_theme_object_set(obj, wd->cp[i]->bg_rect, "colorselector",
935                                    "bg_image", buf);
936              edje_object_part_swallow(wd->cp[i]->colorbar, "elm.bar_bg",
937                                       wd->cp[i]->bg_rect);
938              elm_widget_sub_object_add(obj, wd->cp[i]->bg_rect);
939              evas_object_color_set(wd->cp[i]->bar, wd->er, wd->eg, wd->eb, 255);
940           }
941         /* load arrow image, pointing the colorbar */
942         wd->cp[i]->arrow = edje_object_add(e);
943         _elm_theme_object_set(obj, wd->cp[i]->arrow, "colorselector", "arrow",
944                               elm_widget_style_get(obj));
945         edje_object_part_swallow(wd->cp[i]->colorbar, "elm.arrow_icon",
946                                  wd->cp[i]->arrow);
947         elm_widget_sub_object_add(obj, wd->cp[i]->arrow);
948         if (i == 2)
949           evas_object_color_set(wd->cp[i]->arrow, 0, 0, 0, 255);
950         else
951           evas_object_color_set(wd->cp[i]->arrow, wd->er, wd->eg, wd->eb, 255);
952
953         /* load left button */
954         wd->cp[i]->lbt = elm_button_add(obj);
955         snprintf(buf, sizeof(buf), "colorselector/left/%s",
956                  elm_widget_style_get(obj));
957         elm_object_style_set(wd->cp[i]->lbt, buf);
958         elm_widget_sub_object_add(obj, wd->cp[i]->lbt);
959         edje_object_part_swallow(wd->cp[i]->colorbar, "elm.l_button",
960                                  wd->cp[i]->lbt);
961         evas_object_smart_callback_add(wd->cp[i]->lbt, "clicked",
962                                        _left_button_clicked_cb, wd->cp[i]);
963         elm_button_autorepeat_set(wd->cp[i]->lbt, EINA_TRUE);
964         elm_button_autorepeat_initial_timeout_set(wd->cp[i]->lbt,
965                                                   _elm_config->longpress_timeout);
966         elm_button_autorepeat_gap_timeout_set(wd->cp[i]->lbt,
967                                               (1.0 / _elm_config->fps));
968         evas_object_smart_callback_add(wd->cp[i]->lbt, "repeated",
969                                        _left_button_repeat_cb, wd->cp[i]);
970
971         /* load right button */
972         wd->cp[i]->rbt = elm_button_add(obj);
973         snprintf(buf, sizeof(buf), "colorselector/right/%s",
974                  elm_widget_style_get(obj));
975         elm_object_style_set(wd->cp[i]->rbt, buf);
976         elm_widget_sub_object_add(obj, wd->cp[i]->rbt);
977         edje_object_part_swallow(wd->cp[i]->colorbar, "elm.r_button",
978                                  wd->cp[i]->rbt);
979         evas_object_smart_callback_add(wd->cp[i]->rbt, "clicked",
980                                        _right_button_clicked_cb, wd->cp[i]);
981         elm_button_autorepeat_set(wd->cp[i]->rbt, EINA_TRUE);
982         elm_button_autorepeat_initial_timeout_set(wd->cp[i]->rbt,
983                                                   _elm_config->longpress_timeout);
984         elm_button_autorepeat_gap_timeout_set(wd->cp[i]->rbt,
985                                               (1.0 / _elm_config->fps));
986         evas_object_smart_callback_add(wd->cp[i]->rbt, "repeated",
987                                        _right_button_repeat_cb, wd->cp[i]);
988      }
989 }
990
991 static void
992 _set_color(Evas_Object *obj, int r, int g, int b, int a)
993 {
994    Widget_Data *wd = elm_widget_data_get(obj);
995    double x, y;
996
997    wd->r = r;
998    wd->g = g;
999    wd->b = b;
1000    wd->a = a;
1001
1002    _rgb_to_hsl(wd);
1003
1004    edje_object_part_drag_value_get(wd->cp[0]->colorbar, "elm.arrow", &x, &y);
1005    x = wd->h / 360.0;
1006    edje_object_part_drag_value_set(wd->cp[0]->colorbar, "elm.arrow", x, y);
1007    _draw_rects(wd->cp[0], x);
1008
1009    edje_object_part_drag_value_get(wd->cp[1]->colorbar, "elm.arrow", &x, &y);
1010    x = 1.0 - wd->s;
1011    edje_object_part_drag_value_set(wd->cp[1]->colorbar, "elm.arrow", x, y);
1012    _draw_rects(wd->cp[1], x);
1013
1014    edje_object_part_drag_value_get(wd->cp[2]->colorbar, "elm.arrow", &x, &y);
1015    x = wd->l;
1016    edje_object_part_drag_value_set(wd->cp[2]->colorbar, "elm.arrow", x, y);
1017    _draw_rects(wd->cp[2], x);
1018
1019    edje_object_part_drag_value_get(wd->cp[3]->colorbar, "elm.arrow", &x, &y);
1020    x = wd->a / 255.0;
1021    edje_object_part_drag_value_set(wd->cp[3]->colorbar, "elm.arrow", x, y);
1022    _draw_rects(wd->cp[3], x);
1023 }
1024
1025 EAPI Evas_Object *
1026 elm_colorselector_add(Evas_Object *parent)
1027 {
1028    Evas_Object *obj = NULL;
1029    Widget_Data *wd = NULL;
1030    Evas *e;
1031    const char *hpadstr, *vpadstr;
1032    unsigned int h_pad = DEFAULT_HOR_PAD;
1033    unsigned int v_pad = DEFAULT_VER_PAD;
1034
1035    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1036
1037    ELM_SET_WIDTYPE(widtype, "colorselector");
1038    elm_widget_type_set(obj, "colorselector");
1039    elm_widget_sub_object_add(parent, obj);
1040    elm_widget_data_set(obj, wd);
1041    elm_widget_del_hook_set(obj, _del_hook);
1042    elm_widget_theme_hook_set(obj, _theme_hook);
1043    evas_object_smart_callbacks_descriptions_set(obj, _signals);
1044
1045    /* load background edj */
1046    wd->base = edje_object_add(e);
1047    _elm_theme_object_set(obj, wd->base, "colorselector", "palette", "default");
1048    elm_widget_resize_object_set(obj, wd->base);
1049    evas_object_event_callback_add(wd->base, EVAS_CALLBACK_RESIZE,
1050                                   _resize_cb, obj);
1051
1052    wd->box = elm_box_add(obj);
1053    elm_box_layout_set(wd->box, evas_object_box_layout_flow_horizontal,
1054                       NULL, NULL);
1055    elm_box_horizontal_set(wd->box, EINA_TRUE);
1056    evas_object_size_hint_weight_set(wd->box, EVAS_HINT_EXPAND,
1057                                     0);
1058    evas_object_size_hint_align_set(wd->box, EVAS_HINT_FILL, 0);
1059    elm_box_homogeneous_set(wd->box, EINA_TRUE);
1060    hpadstr = edje_object_data_get(wd->sel, "horizontal_pad");
1061    if (hpadstr) h_pad = atoi(hpadstr);
1062    vpadstr = edje_object_data_get(wd->sel, "vertical_pad");
1063    if (vpadstr) v_pad = atoi(vpadstr);
1064    elm_box_padding_set(wd->box, h_pad, v_pad);
1065    elm_box_align_set(wd->box, 0.5, 0.5);
1066    elm_widget_sub_object_add(obj, wd->box);
1067    evas_object_show(wd->box);
1068    edje_object_part_swallow(wd->base, "palette", wd->box);
1069    wd->palette_name = eina_stringshare_add("default");
1070    _colors_load_apply(obj);
1071
1072    /* load background edj */
1073     wd->sel = edje_object_add(e);
1074     _elm_theme_object_set(obj, wd->sel, "colorselector", "bg", "default");
1075     edje_object_part_swallow(wd->base, "selector", wd->sel);
1076     wd->mode = ELM_COLORSELECTOR_BOTH;
1077
1078    wd->er = 255;
1079    wd->eg = 0;
1080    wd->eb = 0;
1081    wd->h = 0.0;
1082    wd->s = 1.0;
1083    wd->l = 0.0;
1084    wd->a = 255;
1085
1086    _hsl_to_rgb(wd);
1087    _add_colorbar(obj);
1088    _sizing_eval(obj);
1089
1090    return obj;
1091 }
1092
1093 EAPI void
1094 elm_colorselector_color_set(Evas_Object *obj, int r, int g, int b, int a)
1095 {
1096    ELM_CHECK_WIDTYPE(obj, widtype);
1097    _set_color(obj, r, g, b, a);
1098 }
1099
1100 EAPI void
1101 elm_colorselector_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a)
1102 {
1103    ELM_CHECK_WIDTYPE(obj, widtype);
1104    Widget_Data *wd = elm_widget_data_get(obj);
1105
1106    if (r) *r = wd->r;
1107    if (g) *g = wd->g;
1108    if (b) *b = wd->b;
1109    if (a) *a = wd->a;
1110 }
1111
1112 EAPI void
1113 elm_colorselector_mode_set(Evas_Object *obj, Elm_Colorselector_Mode mode)
1114 {
1115    ELM_CHECK_WIDTYPE(obj, widtype);
1116    Widget_Data *wd = elm_widget_data_get(obj);
1117    if (!wd) return;
1118    if (wd->mode == mode) return;
1119    wd->mode = mode;
1120    switch (wd->mode)
1121      {
1122         case ELM_COLORSELECTOR_PALETTE:
1123            if (edje_object_part_swallow_get(wd->base, "selector"))
1124              {
1125                 edje_object_part_unswallow(wd->base, wd->sel);
1126                 evas_object_hide(wd->sel);
1127              }
1128            if (!edje_object_part_swallow_get(wd->base, "palette"))
1129              {
1130                 edje_object_part_swallow(wd->base, "palette", wd->box);
1131                 evas_object_show(wd->box);
1132              }
1133            break;
1134         case ELM_COLORSELECTOR_COMPONENTS:
1135            if (edje_object_part_swallow_get(wd->base, "palette"))
1136              {
1137                 edje_object_part_unswallow(wd->base, wd->box);
1138                 evas_object_hide(wd->box);
1139              }
1140            if (!edje_object_part_swallow_get(wd->base, "selector"))
1141              {
1142                 edje_object_part_swallow(wd->base, "selector", wd->sel);
1143                 evas_object_show(wd->sel);
1144              }
1145            break;
1146         case ELM_COLORSELECTOR_BOTH:
1147            if (!edje_object_part_swallow_get(wd->base, "palette"))
1148              {
1149                 edje_object_part_swallow(wd->base, "palette", wd->box);
1150                 evas_object_show(wd->box);
1151              }
1152            if (!edje_object_part_swallow_get(wd->base, "selector"))
1153              {
1154                 edje_object_part_swallow(wd->base, "selector", wd->sel);
1155                 evas_object_show(wd->sel);
1156              }
1157            break;
1158         default:
1159            return;
1160      }
1161    _sizing_eval(obj);
1162 }
1163
1164 EAPI Elm_Colorselector_Mode
1165 elm_colorselector_mode_get(const Evas_Object *obj)
1166 {
1167    ELM_CHECK_WIDTYPE(obj, widtype) ELM_COLORSELECTOR_BOTH;
1168    Widget_Data *wd = elm_widget_data_get(obj);
1169    if (!wd) return ELM_COLORSELECTOR_BOTH;
1170    return wd->mode;
1171 }
1172
1173 EAPI void
1174 elm_colorselector_palette_item_color_get(const Elm_Object_Item *it, int *r __UNUSED__, int *g __UNUSED__, int *b __UNUSED__, int*a __UNUSED__)
1175 {
1176    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1177    Elm_Color_Item *item;
1178    item = (Elm_Color_Item *) it;
1179    if (item)
1180      {
1181         if(r) *r = item->color->r;
1182         if(g) *g = item->color->g;
1183         if(b) *b = item->color->b;
1184         if(a) *a = item->color->a;
1185      }
1186 }
1187
1188 EAPI void
1189 elm_colorselector_palette_item_color_set(Elm_Object_Item *it, int r __UNUSED__, int g __UNUSED__, int b __UNUSED__, int a __UNUSED__)
1190 {
1191    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1192    Elm_Color_Item *item;
1193    item = (Elm_Color_Item *) it;
1194    item->color->r = r;
1195    item->color->g = g;
1196    item->color->b = b;
1197    item->color->a = a;
1198    evas_object_color_set(item->color_obj, item->color->r, item->color->g, item->color->b, item->color->a);
1199    _colors_save(WIDGET(it));
1200 }
1201
1202 EAPI Elm_Object_Item *
1203 elm_colorselector_palette_color_add(Evas_Object *obj, int r, int g, int b, int a)
1204 {
1205    Elm_Color_Item *item;
1206    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1207    Widget_Data *wd = elm_widget_data_get(obj);
1208    if (!wd) return NULL;
1209    if (wd->config_load)
1210      {
1211         _colors_remove(obj);
1212         wd->config_load = EINA_FALSE;
1213      }
1214    item = _item_new(obj);
1215    if (!item) return NULL;
1216    item->color = ELM_NEW(Elm_Color_RGBA);
1217    if (!item->color) return NULL;
1218    item->color->r = r;
1219    item->color->g = g;
1220    item->color->b = b;
1221    item->color->a = a;
1222    _elm_config_color_set(wd->palette_name, item->color->r, item->color->g,
1223                          item->color->b, item->color->a);
1224    elm_box_pack_end(wd->box, VIEW(item));
1225    evas_object_color_set(item->color_obj, item->color->r, item->color->g,
1226                          item->color->b, item->color->a);
1227    wd->items = eina_list_append(wd->items, item);
1228    _sizing_eval(obj);
1229    return (Elm_Object_Item *) item;
1230 }
1231
1232 EAPI void
1233 elm_colorselector_palette_clear(Evas_Object *obj)
1234 {
1235    ELM_CHECK_WIDTYPE(obj, widtype);
1236    Widget_Data *wd = elm_widget_data_get(obj);
1237    if (!wd) return;
1238    _colors_remove(obj);
1239 }
1240
1241 EAPI void
1242 elm_colorselector_palette_name_set(Evas_Object *obj, const char *palette_name)
1243 {
1244    ELM_CHECK_WIDTYPE(obj, widtype);
1245    Widget_Data *wd = elm_widget_data_get(obj);
1246    if (!wd) return;
1247    if (!strcmp(wd->palette_name, palette_name)) return;
1248    if (palette_name)
1249      {
1250         _colors_remove(obj);
1251         eina_stringshare_replace(&wd->palette_name, palette_name);
1252         _colors_load_apply(obj);
1253      }
1254 }
1255
1256 EAPI const char*
1257 elm_colorselector_palette_name_get(const Evas_Object *obj)
1258 {
1259    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1260    Widget_Data *wd = elm_widget_data_get(obj);
1261    if (!wd) return NULL;
1262    return wd->palette_name;
1263 }