[WM_ROT] Fixed floating mode window rotation bug that window doesn't send ROTATION_DO...
[platform/core/uifw/e17.git] / src / bin / e_spectrum.c
1 #include "e.h"
2
3 Evas_Smart *_e_spectrum_smart = NULL;
4
5 typedef struct _E_Spectrum E_Spectrum;
6
7 struct _E_Spectrum
8 {
9   Evas_Object *o_spectrum;
10   Evas_Object *o_event;
11   Evas_Object *o_cursor;
12
13   int iw, ih; /* square image width/height */
14   E_Color_Component mode;
15
16   E_Color *cv;
17   Ecore_Timer *draw_timer;
18 };
19
20 static Eina_Bool _e_spectrum_redraw(void *d);
21
22 static void
23 _e_spectrum_smart_add(Evas_Object *o)
24 {
25   E_Spectrum *sp;
26   sp = E_NEW(E_Spectrum, 1);
27
28   if (!sp) return;
29
30   evas_object_smart_data_set(o, sp);
31
32   sp->mode = E_COLOR_COMPONENT_R;
33
34   sp->o_spectrum = evas_object_image_add(evas_object_evas_get(o));
35   sp->iw = sp->ih = 255;
36   evas_object_image_size_set(sp->o_spectrum, sp->iw, sp->ih);
37   evas_object_image_alpha_set(sp->o_spectrum, 1);
38
39   evas_object_smart_member_add(sp->o_spectrum, o);
40 }
41
42 static void
43 _e_spectrum_smart_del(Evas_Object *o)
44 {
45   E_Spectrum *sp;
46
47   sp = evas_object_smart_data_get(o);
48   if (!sp) return;
49
50   evas_object_del(sp->o_spectrum);
51   evas_object_del(sp->o_event);
52   evas_object_del(sp->o_cursor);
53
54   if (sp->draw_timer) ecore_timer_del(sp->draw_timer);
55
56   E_FREE(sp);
57 }
58
59 static void
60 _e_spectrum_smart_show(Evas_Object *o)
61 {
62   E_Spectrum *sp;
63
64   sp = evas_object_smart_data_get(o);
65   if (!sp) return;
66
67   evas_object_show(sp->o_spectrum);
68   evas_object_show(sp->o_event);
69   evas_object_show(sp->o_cursor);
70 }
71
72 static void
73 _e_spectrum_smart_hide(Evas_Object *o)
74 {
75   E_Spectrum *sp;
76
77   sp = evas_object_smart_data_get(o);
78   if (!sp) return;
79
80   evas_object_hide(sp->o_spectrum);
81   evas_object_hide(sp->o_event);
82   evas_object_hide(sp->o_cursor);
83 }
84
85 static void
86 _e_spectrum_smart_move(Evas_Object *o, Evas_Coord x, Evas_Coord y)
87 {
88   E_Spectrum *sp;
89
90   sp = evas_object_smart_data_get(o);
91   if (!sp) return;
92
93   evas_object_move(sp->o_spectrum, x, y);
94   evas_object_move(sp->o_event, x, y);
95   evas_object_move(sp->o_cursor, x, y);
96 }
97
98 static void
99 _e_spectrum_smart_resize(Evas_Object *o, Evas_Coord w, Evas_Coord h)
100 {
101   E_Spectrum *sp;
102
103   sp = evas_object_smart_data_get(o);
104   if (!sp) return;
105
106   evas_object_image_fill_set(sp->o_spectrum, 0, 0, w, h);
107
108   evas_object_resize(sp->o_spectrum, w, h);
109   evas_object_resize(sp->o_event, w, h);
110   evas_object_resize(sp->o_cursor, w, h);
111 }
112
113 static void
114 _e_spectrum_smart_color_set(Evas_Object *o, int r, int g, int b, int a)
115 {
116   E_Spectrum *sp;
117
118   sp = evas_object_smart_data_get(o);
119   if (!sp) return;
120   evas_object_color_set(sp->o_spectrum, r, g, b, a);
121   evas_object_color_set(sp->o_event, r, g, b, a);
122   evas_object_color_set(sp->o_cursor, r, g, b, a);
123 }
124
125 static void
126 _e_spectrum_smart_clip_set(Evas_Object *o, Evas_Object *o_clip)
127 {
128   E_Spectrum *sp;
129
130   sp = evas_object_smart_data_get(o);
131   if (!sp) return;
132   evas_object_clip_set(sp->o_spectrum, o_clip);
133   evas_object_clip_set(sp->o_event, o_clip);
134   evas_object_clip_set(sp->o_cursor, o_clip);
135 }
136
137 static void
138 _e_spectrum_smart_clip_unset(Evas_Object *o)
139 {
140   E_Spectrum *sp;
141
142   sp = evas_object_smart_data_get(o);
143   if (!sp) return;
144   evas_object_clip_unset(sp->o_spectrum);
145   evas_object_clip_unset(sp->o_event);
146   evas_object_clip_unset(sp->o_cursor);
147 }
148
149 static void
150 _e_spectrum_smart_init(void)
151 {
152    if (_e_spectrum_smart) return;
153      {
154         static const Evas_Smart_Class sc =
155           {
156              "e_spectrum",
157                EVAS_SMART_CLASS_VERSION,
158                _e_spectrum_smart_add,
159                _e_spectrum_smart_del,
160                _e_spectrum_smart_move,
161                _e_spectrum_smart_resize,
162                _e_spectrum_smart_show,
163                _e_spectrum_smart_hide,
164                _e_spectrum_smart_color_set,
165                _e_spectrum_smart_clip_set,
166                _e_spectrum_smart_clip_unset,
167                NULL,
168                NULL,
169                NULL,
170                NULL,
171                NULL,
172                NULL,
173                NULL
174           };
175         _e_spectrum_smart = evas_smart_class_new(&sc);
176      }
177 }
178
179 void
180 _e_spectrum_color_calc(E_Spectrum *sp, float vx, float vy, float vz, int *r, int *g, int *b)
181 {
182    switch (sp->mode)
183      {
184       case E_COLOR_COMPONENT_R:
185          *r = 255 * vz;
186          *g = 255 * vy;
187          *b = 255 * vx;
188          break;
189       case E_COLOR_COMPONENT_G:
190          *r = 255 * vx;
191          *g = 255 * vz;
192          *b = 255 * vy;
193          break;
194       case E_COLOR_COMPONENT_B:
195          *r = 255 * vy;
196          *g = 255 * vx;
197          *b = 255 * vz;
198          break;
199       case E_COLOR_COMPONENT_H:
200          evas_color_hsv_to_rgb(vz * 360.0, vy, vx, r, g, b);
201          break;
202       case E_COLOR_COMPONENT_S:
203          evas_color_hsv_to_rgb(vx * 360.0, vz, vy, r, g, b);
204          break;
205       case E_COLOR_COMPONENT_V:
206          evas_color_hsv_to_rgb(vy * 360.0, vx, vz, r, g, b);
207          break;
208       default:
209          break;
210      }
211 }
212
213 void
214 _e_spectrum_2d_color_at(E_Spectrum *sp, int x, int y, int *r, int *g, int *b)
215 {
216   int rr, gg, bb;
217   float h, s, v;
218
219   if (!sp || !sp->cv) return;
220
221   switch (sp->mode)
222     {
223      case E_COLOR_COMPONENT_R:
224         rr = sp->cv->r;
225         gg = (1 - (y / (double)(sp->ih))) * 255;
226         bb = (x / (double)(sp->iw)) * 255;
227         break;
228      case E_COLOR_COMPONENT_G:
229         rr = (x / (double)(sp->iw)) * 255;
230         gg = sp->cv->g;
231         bb = (1 - (y / (double)(sp->ih))) * 255;
232         break;
233      case E_COLOR_COMPONENT_B:
234         rr = (1 - (y / (double)(sp->ih))) * 255;
235         gg = (x / (double)(sp->iw)) * 255;
236         bb = sp->cv->b;
237         break;
238      case E_COLOR_COMPONENT_H:
239         h = sp->cv->h;
240         s = 1 - (y / (double)(sp->ih));
241         v = x / (double)(sp->iw);
242         evas_color_hsv_to_rgb(h, s, v, &rr, &gg, &bb);
243         break;
244      case E_COLOR_COMPONENT_S:
245         s = sp->cv->s;
246         v = 1 - (y / (double)(sp->ih));
247         h = x / (double)(sp->iw) * 360;
248         evas_color_hsv_to_rgb(h, s, v, &rr, &gg, &bb);
249         break;
250      case E_COLOR_COMPONENT_V:
251         v = sp->cv->v;
252         h = (1 - (y / (double)(sp->ih))) * 360;
253         s = x / (double)(sp->iw);
254         evas_color_hsv_to_rgb(h, s, v, &rr, &gg, &bb);
255         break;
256      case E_COLOR_COMPONENT_MAX:
257      default:
258         return;
259     }
260
261   if (r) *r = rr;
262   if (g) *g = gg;
263   if (b) *b = bb;
264 }
265
266 static Eina_Bool
267 _e_spectrum_redraw(void *d)
268 {
269   E_Spectrum *sp = d;
270   int *data;
271   int i, j;
272   int r, g, b;
273   float vx, vy, vz = 0;
274
275   data = evas_object_image_data_get(sp->o_spectrum, 1);
276   if (!data)
277     {
278        sp->draw_timer = NULL;
279        return ECORE_CALLBACK_CANCEL;
280     }
281
282   switch (sp->mode)
283     {
284      case E_COLOR_COMPONENT_R:
285         vz = (float)sp->cv->r / 255;
286         break;
287      case E_COLOR_COMPONENT_G:
288         vz = (float)sp->cv->g / 255;
289         break;
290      case E_COLOR_COMPONENT_B:
291         vz = (float)sp->cv->b / 255;
292         break;
293      case E_COLOR_COMPONENT_H:
294         vz = sp->cv->h / 360;
295         break;
296      case E_COLOR_COMPONENT_S:
297         vz = sp->cv->s;
298         break;
299      case E_COLOR_COMPONENT_V:
300         vz = sp->cv->v;
301         break;
302      case E_COLOR_COMPONENT_MAX:
303         break;
304     }
305
306   for (i = 0; i < sp->ih; i++)
307     {
308        vy = (float)i / sp->ih;
309        for (j = 0; j < sp->iw; j++)
310          {
311             vx = (float)j / sp->iw;
312             _e_spectrum_color_calc(sp, vx, vy, vz, &r, &g, &b);
313             data[(i * sp->iw) + j] =
314               (sp->cv->a << 24) |
315               (((r * sp->cv->a) / 255) << 16) |
316               (((g * sp->cv->a) / 255) <<  8) |
317               (((b * sp->cv->a) / 255)      );
318          }
319     }
320
321   evas_object_image_data_set(sp->o_spectrum, data);
322   evas_object_image_data_update_add(sp->o_spectrum, 0, 0, sp->iw, sp->ih);
323   sp->draw_timer = NULL;
324   return ECORE_CALLBACK_CANCEL;
325 }
326
327 static void
328 _e_spectrum_update(E_Spectrum *sp)
329 {
330   if (!sp || !sp->cv) return;
331
332   if (sp->draw_timer) ecore_timer_del(sp->draw_timer);
333   sp->draw_timer = ecore_timer_add(.001, _e_spectrum_redraw, sp);
334 }
335
336 Evas_Object *
337 e_spectrum_add(Evas *e)
338 {
339    _e_spectrum_smart_init();
340    return evas_object_smart_add(e, _e_spectrum_smart);
341 }
342
343 void
344 e_spectrum_mode_set(Evas_Object *o, E_Color_Component mode)
345 {
346   E_Spectrum *sp;
347
348    if (evas_object_smart_smart_get(o) != _e_spectrum_smart) SMARTERRNR();
349   sp = evas_object_smart_data_get(o);
350   if (!sp) return;
351
352   if (sp->mode == mode) return;
353   sp->mode = mode;
354   _e_spectrum_update(sp);
355 }
356
357 E_Color_Component
358 e_spectrum_mode_get(Evas_Object *o)
359 {
360   E_Spectrum *sp;
361
362    if (evas_object_smart_smart_get(o) != _e_spectrum_smart) SMARTERR(0);
363   sp = evas_object_smart_data_get(o);
364   if (!sp) return -1;
365
366   return sp->mode;
367 }
368
369 void
370 e_spectrum_color_value_set(Evas_Object *o, E_Color *cv)
371 {
372   E_Spectrum *sp;
373
374    if (evas_object_smart_smart_get(o) != _e_spectrum_smart) SMARTERRNR();
375   sp = evas_object_smart_data_get(o);
376   if (!sp) return;
377
378   sp->cv = cv;
379   _e_spectrum_update(sp);
380 }
381
382 void
383 e_spectrum_update(Evas_Object *o)
384 {
385   E_Spectrum *sp;
386
387    if (evas_object_smart_smart_get(o) != _e_spectrum_smart) SMARTERRNR();
388   sp = evas_object_smart_data_get(o);
389   if (!sp) return;
390
391   _e_spectrum_update(sp);
392 }