bc5bf0f9c43c1aed755a2e4324b517e73fdbacf6
[framework/uifw/elementary.git] / src / lib / elm_colorpalette.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include <Ecore.h>
4
5 /**
6  * @defgroup Colorpalette Colorpalette
7  * @ingroup Elementary
8  *
9  * Using colorpalette, you can select a color by clicking
10  * a color rectangle on the colorpalette.
11  */
12
13
14 #define MAX_NUM_COLORS 30
15
16 typedef struct _Colorpalette_Item Colorpalette_Item;
17 struct _Colorpalette_Item
18 {
19    Evas_Object *parent;
20    Evas_Object *lo;
21    Evas_Object *cr;
22    unsigned int r, g, b;
23 };
24
25
26 typedef struct _Widget_Data Widget_Data;
27 struct _Widget_Data
28 {
29    Evas_Object *parent;
30    Evas_Object *lay;
31    Evas_Object *tab;
32
33    Evas_Coord x, y, w, h;
34    Evas_Coord tab_w, tab_h;
35    Evas_Coord rect_w, rect_h;
36
37    unsigned int row, col;
38    Elm_Colorpalette_Color *color;
39
40    Eina_List *items;
41
42    unsigned int num;
43 };
44
45 static void _del_hook(Evas_Object *obj);
46 static void _theme_hook(Evas_Object *obj);
47 static void _sizing_eval(Evas_Object *obj);
48 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
49
50
51 static void _colorpalette_object_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
52 static void _colorpalette_object_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
53 static void _colorpalette_object_show(void *data, Evas *e, Evas_Object *obj, void *event_info);
54 static void _colorpalette_object_hide(void *data, Evas *e, Evas_Object *obj, void *event_info);
55
56 static void _color_select_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
57 static void _color_release_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
58 static void _color_table_delete(Evas_Object *obj);
59 static void _color_table_update(Evas_Object *obj, int row, int col, int color_num, Elm_Colorpalette_Color *color);
60
61 static void
62 _del_hook(Evas_Object *obj)
63 {
64    Widget_Data *wd = elm_widget_data_get(obj);
65
66    if (!wd) return;
67
68    _color_table_delete(obj);
69
70    if (wd->color){
71         free(wd->color);
72    }
73
74    if (wd->lay){
75         evas_object_smart_member_del(wd->lay);
76         evas_object_del(wd->lay);
77         wd->lay = NULL;
78    }
79    free(wd);
80 }
81
82 static void
83 _theme_hook(Evas_Object *obj)
84 {
85    Widget_Data *wd = elm_widget_data_get(obj);
86    if (!wd)
87       return;
88
89    _elm_theme_object_set(obj, wd->lay, "colorpalette", "bg", elm_widget_style_get(obj));
90    _color_table_update(obj, wd->row, wd->col, wd->num, wd->color);
91    _sizing_eval(obj);
92
93 }
94
95
96 static void
97 _sub_del(void *data, Evas_Object *obj, void *event_info)
98 {
99    Widget_Data *wd = elm_widget_data_get(obj);
100    if (!wd) return;
101 }
102
103 static void
104 _sizing_eval(Evas_Object *obj)
105 {
106    Widget_Data *wd = elm_widget_data_get(obj);
107
108    if (!wd)
109       return;
110
111    _colorpalette_object_move(obj, NULL, obj, NULL);
112    _colorpalette_object_resize(obj, NULL, obj, NULL);
113 }
114
115
116 static void _colorpalette_object_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
117 {
118    DBG("%s", __func__);
119
120    Widget_Data *wd;
121    Evas_Coord x, y;
122
123    if(!data)
124       return;
125
126    wd = elm_widget_data_get((Evas_Object *)data);
127
128    if(!wd)
129       return;
130
131    evas_object_geometry_get(wd->lay, &x, &y, NULL, NULL);
132
133    wd->x = x;
134    wd->y = y;
135
136    evas_object_move(wd->lay, x, y);
137 }
138
139
140 static void _colorpalette_object_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
141 {
142    Widget_Data *wd;
143    Colorpalette_Item *item = NULL;
144    Evas_Coord w, h;
145    Evas_Coord tab_w, tab_h;
146    double pad_x, pad_y;
147
148    if(!data)
149       return;
150
151    wd = elm_widget_data_get((Evas_Object *)data);
152
153    if(!wd)
154       return;
155
156    evas_object_geometry_get(wd->lay, NULL, NULL, &w, &h);
157    wd->w = w;
158    wd->h = h;
159
160    evas_object_geometry_get(wd->tab, NULL, NULL, &tab_w, &tab_h);
161    if (tab_w > 0 && tab_h > 0) {
162         wd->tab_w = tab_w;
163         wd->tab_h = tab_h;
164    }
165
166    if (wd->items)
167       item = wd->items->data;
168
169    edje_object_part_geometry_get(elm_layout_edje_get(item->lo),"bg" ,NULL, NULL, &wd->rect_w, &wd->rect_h);
170
171    pad_x = ((double)wd->tab_w - (double)wd->rect_w * (double)wd->col) / (double)(wd->col - 1);
172    pad_y = ((double)wd->tab_h - (double)wd->rect_h * (double)wd->row) / (double)(wd->row - 1);
173
174    if (pad_x < 0.0 )
175       pad_x = 0;
176    if (pad_y < 0.0 )
177       pad_y = 0;
178
179    elm_table_padding_set(wd->tab, (int)pad_x , (int)pad_y);
180
181    if(!wd->lay)
182       return;
183
184    evas_object_resize(wd->lay, w, h);
185 }
186
187
188 static void _colorpalette_object_show(void *data, Evas *e, Evas_Object *obj, void *event_info)
189 {
190    DBG("%s", __func__);
191
192    Widget_Data *wd = NULL;
193
194    if(data == NULL)
195       return;
196
197    wd = elm_widget_data_get((Evas_Object *)data);
198
199
200    if(wd == NULL)
201       return;
202
203    if (wd->lay) {
204         evas_object_show(wd->lay);
205    }
206 }
207
208 static void _colorpalette_object_hide(void *data, Evas *e, Evas_Object *obj, void *event_info)
209 {
210    DBG("%s", __func__);
211
212    Widget_Data *wd = NULL;
213
214    if(data == NULL)
215       return;
216
217    wd = elm_widget_data_get((Evas_Object *)data);
218
219    if(wd == NULL)
220       return;
221
222    if (wd->lay) {
223         evas_object_hide(wd->lay);
224    }
225 }
226
227 static void _color_select_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
228 {
229    Colorpalette_Item *item = (Colorpalette_Item *) data;
230    Elm_Colorpalette_Color *color;
231
232    color = ELM_NEW(Elm_Colorpalette_Color);
233
234    color->r = item->r;
235    color->g = item->g;
236    color->b = item->b;
237
238    evas_object_smart_callback_call(item->parent, "clicked", color);
239
240    edje_object_signal_emit(elm_layout_edje_get(item->lo), "focus_visible", "elm");
241 }
242
243
244 static void _color_release_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
245 {
246    Colorpalette_Item *item = (Colorpalette_Item *) data;
247    edje_object_signal_emit(elm_layout_edje_get(item->lo), "focus_invisible", "elm");
248 }
249
250
251 static void _color_table_delete(Evas_Object *obj)
252 {
253    Widget_Data *wd = NULL;
254    Colorpalette_Item *item;
255    wd = elm_widget_data_get(obj);
256
257    if (!wd) return;
258
259    if (wd->items) {
260         EINA_LIST_FREE(wd->items, item) {
261              if (item->lo){
262                   evas_object_del(item->lo);
263                   item->lo = NULL;
264              }
265              if (item->cr){
266                   evas_object_del(item->cr);
267                   item->cr = NULL;
268              }
269              free(item);
270         }
271    }
272
273    if (wd->tab) {
274         edje_object_part_unswallow(wd->lay, wd->tab);
275         evas_object_del(wd->tab);
276    }
277 }
278
279
280 static void _color_table_update(Evas_Object *obj, int row, int col, int color_num, Elm_Colorpalette_Color *color)
281 {
282    Widget_Data *wd = elm_widget_data_get(obj);
283    Colorpalette_Item *item;
284    Evas_Object *lo;
285    Evas_Object *cr;
286    Evas *e;
287    int i, j, count;
288
289    if ( !wd )
290       return;
291
292    count = 0;
293    
294    e = evas_object_evas_get(wd->parent);
295
296    _color_table_delete(obj);
297
298    wd->row = row;
299    wd->col = col;
300    wd->num = color_num;
301
302    wd->tab = elm_table_add(obj);
303
304    evas_object_size_hint_weight_set(wd->tab, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
305    evas_object_size_hint_align_set(wd->tab, EVAS_HINT_FILL, EVAS_HINT_FILL);
306
307    edje_object_part_swallow(wd->lay, "palette", wd->tab);
308    evas_object_show(wd->tab);
309
310    for ( i = 0 ; i < row ; i++) {
311         for ( j = 0 ; j < col ; j++ ) {
312              item = ELM_NEW(Colorpalette_Item);
313              if (item){
314                   lo = elm_layout_add(obj);
315                   elm_layout_theme_set(lo, "colorpalette", "base", "bg");
316                   evas_object_size_hint_weight_set(lo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
317                   evas_object_size_hint_align_set(lo, EVAS_HINT_FILL, EVAS_HINT_FILL);
318                   evas_object_show(lo);
319                   elm_table_pack(wd->tab, lo, j, i, 1, 1);
320
321                   item->parent = obj;
322                   item->lo = lo;
323
324                   if (count < color_num){
325                        cr =  edje_object_add(e);
326                        _elm_theme_object_set(obj, cr, "colorpalette", "base", "color");
327                        evas_object_color_set(cr, color[count].r, color[count].g, color[count].b, 255);
328                        evas_object_size_hint_weight_set(cr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
329                        evas_object_size_hint_align_set(cr, EVAS_HINT_FILL, EVAS_HINT_FILL);
330
331                        evas_object_event_callback_add(cr, EVAS_CALLBACK_MOUSE_DOWN, _color_select_cb, item);
332                        evas_object_event_callback_add(cr, EVAS_CALLBACK_MOUSE_UP, _color_release_cb, item);
333
334                        evas_object_show(cr);
335                        edje_object_part_swallow(elm_layout_edje_get(lo), "color_rect", cr);
336
337                        item->cr = cr;
338                        item->r = color[count].r;
339                        item->g = color[count].g;
340                        item->b = color[count].b;
341                   }
342                   wd->items = eina_list_append(wd->items, item);
343                   count ++;
344              }
345         }
346    }
347 }
348
349
350 /**
351  * Add a new colorpalette to the parent.
352  *
353  * @param parent The parent object
354  * @return The new object or NULL if it cannot be created
355  *
356  * @ingroup Colorpalette
357  */
358 EAPI Evas_Object *elm_colorpalette_add(Evas_Object *parent)
359 {
360    Evas_Object *obj = NULL;
361    Widget_Data *wd = NULL;
362    Evas *e;
363
364    e = evas_object_evas_get(parent);
365    if (e == NULL) return NULL;
366    wd = ELM_NEW(Widget_Data);
367    obj = elm_widget_add(e);
368    elm_widget_type_set(obj, "colorpalette");
369    elm_widget_sub_object_add(parent, obj);
370    elm_widget_data_set(obj, wd);
371    elm_widget_del_hook_set(obj, _del_hook);
372    elm_widget_theme_hook_set(obj, _theme_hook);
373
374    wd->parent = parent;
375    wd->lay = edje_object_add(e);
376    _elm_theme_object_set(obj, wd->lay, "colorpalette", "bg", "default");
377
378    evas_object_size_hint_weight_set(wd->lay, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
379    if(wd->lay == NULL) {
380         printf("Cannot load bg edj\n");
381         return NULL;
382    }
383
384    wd->color = (Elm_Colorpalette_Color*) calloc (10, sizeof(Elm_Colorpalette_Color));
385
386    wd->color[0].r = 55; wd->color[0].g = 90; wd->color[0].b = 18;
387    wd->color[1].r = 255; wd->color[1].g = 213; wd->color[1].b = 0;
388    wd->color[2].r = 146; wd->color[2].g = 255; wd->color[2].b = 11;
389    wd->color[3].r = 9; wd->color[3].g = 186; wd->color[3].b = 10;
390    wd->color[4].r = 86; wd->color[4].g = 201; wd->color[4].b = 242;
391    wd->color[5].r = 18; wd->color[5].g = 83; wd->color[5].b = 128;
392    wd->color[6].r = 140; wd->color[6].g = 53; wd->color[6].b = 238;
393    wd->color[7].r = 255; wd->color[7].g = 145; wd->color[7].b = 145;
394    wd->color[8].r = 255; wd->color[8].g = 59; wd->color[8].b = 119;
395    wd->color[9].r = 133; wd->color[9].g = 100; wd->color[9].b = 69;
396
397    _color_table_update(obj, 2, 5, 10, wd->color);
398
399    elm_widget_resize_object_set(obj, wd->lay);
400    evas_object_event_callback_add(wd->lay, EVAS_CALLBACK_RESIZE, _colorpalette_object_resize, obj);
401    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _colorpalette_object_move, obj);
402    evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _colorpalette_object_show, obj);
403    evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _colorpalette_object_hide, obj);
404
405    return obj;
406 }
407
408
409 /**
410  * Set colors to the colorpalette.
411  *
412  * @param obj   Colorpalette object
413  * @param color_num     number of the colors on the colorpalette
414  * @param color     Color lists
415  *
416  * @ingroup Colorpalette
417  */
418 EAPI void elm_colorpalette_color_set(Evas_Object *obj, int color_num, Elm_Colorpalette_Color *color)
419 {
420    Widget_Data *wd = elm_widget_data_get(obj);
421    int i;
422
423    if (color_num > MAX_NUM_COLORS) return;
424
425    if (!wd) return;
426
427    if (wd->color) {
428         free(wd->color);
429         wd->color = NULL;
430    }
431
432    wd->color = (Elm_Colorpalette_Color*) calloc (color_num, sizeof(Elm_Colorpalette_Color));
433
434    for ( i = 0 ; i < color_num ; i++) {
435         wd->color[i].r = color[i].r;
436         wd->color[i].g = color[i].g;
437         wd->color[i].b = color[i].b;
438    }
439
440    _color_table_update(obj, wd->row, wd->col, color_num, wd->color);
441    _sizing_eval(obj);
442 }
443
444 /**
445  * Set row/column value for the colorpalette.
446  *
447  * @param obj   Colorpalette object
448  * @param row   row value for the colorpalette
449  * @param col   column value for the colorpalette
450  *
451  * @ingroup Colorpalette
452  */
453 EAPI void elm_colorpalette_row_column_set(Evas_Object *obj, int row, int col)
454 {
455    Widget_Data *wd = elm_widget_data_get(obj);
456
457    if (!wd) return ;
458
459    _color_table_update(obj, row, col, wd->num, wd->color);
460    _sizing_eval(obj);
461 }
462
463 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/