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