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