[WM_ROT] support for rotating prediction window without virtual keyboard
[platform/core/uifw/e17.git] / src / bin / e_widget_cslider.c
1 #include "e.h"
2
3 typedef struct _E_Widget_Data E_Widget_Data;
4
5 struct _E_Widget_Data
6 {
7    Evas_Object *o_cslider;
8    Evas_Object *o_grad;
9    Evas_Object *o_event;
10
11    Eina_List *o_hgrad;
12
13    Evas_Coord x, y, w, h;
14
15    int vertical;
16    int fixed;
17    E_Color_Component mode;
18    int valnum;
19    E_Color *color;
20    E_Color *prev;
21
22    int dragging;
23 };
24
25 static void _e_wid_del_hook(Evas_Object *obj);
26 static void _e_wid_focus_hook(Evas_Object *obj);
27 static void _e_wid_disable_hook(Evas_Object *obj);
28 static void _e_wid_focus_steal(void *data, Evas *e, Evas_Object *obj, void *event_info);
29 static void _e_wid_value_set(Evas_Object *obj, double vx);
30 static void _e_wid_update(E_Widget_Data *wd);
31 static void _e_wid_update_standard(E_Widget_Data *wd);
32 static void _e_wid_update_fixed(E_Widget_Data *wd);
33
34 static void _e_wid_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
35 static void _e_wid_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
36 static void _e_wid_cb_drag_start(void *data, Evas_Object *obj, const char *emission, const char *source);
37 static void _e_wid_cb_drag_stop(void *data, Evas_Object *obj, const char *emission, const char *source);
38 static void _e_wid_cb_drag(void *data, Evas_Object *obj, const char *emission, const char *source);
39
40 /* static void _e_wid_cb_down(void *data, Evas *e, Evas_Object *obj, void *event_info); */
41 /* static void _e_wid_cb_move(void *data, Evas *e, Evas_Object *obj, void *event_info); */
42 /* static void _e_wid_cb_up(void *data, Evas *e, Evas_Object *obj, void *event_info); */
43
44 Evas_Object *
45 e_widget_cslider_add(Evas *evas, E_Color_Component mode, E_Color *color, int vertical, int fixed)
46 {
47    Evas_Object *obj, *o;
48    E_Widget_Data *wd;
49    Evas_Coord mw, mh;
50
51    obj = e_widget_add(evas);
52
53    e_widget_del_hook_set(obj, _e_wid_del_hook);
54    e_widget_focus_hook_set(obj, _e_wid_focus_hook);
55    e_widget_disable_hook_set(obj, _e_wid_disable_hook);
56    wd = calloc(1, sizeof(E_Widget_Data));
57    e_widget_data_set(obj, wd);
58
59    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _e_wid_resize, wd);
60
61    wd->vertical = vertical;
62    wd->fixed = fixed;
63    wd->mode = mode;
64    wd->color = color;
65    wd->prev = calloc(1, sizeof (E_Color));
66    wd->o_hgrad = NULL;
67
68    o = edje_object_add(evas);
69    wd->o_cslider = o;
70    e_theme_edje_object_set(o, "base/theme/widgets",
71                            "e/widgets/cslider");
72    if (wd->vertical)
73      edje_object_signal_emit(o, "e,state,direction,v", "e");
74    else
75      edje_object_signal_emit(o, "e,state,direction,h", "e");
76    evas_object_show(o);
77    edje_object_size_min_calc(o, &mw, &mh);
78    e_widget_size_min_set(obj, mw, mh);
79
80    edje_object_signal_callback_add(wd->o_cslider, "drag,start", "*", _e_wid_cb_drag_start, obj);
81    edje_object_signal_callback_add(wd->o_cslider, "drag", "*", _e_wid_cb_drag, obj);
82    edje_object_signal_callback_add(wd->o_cslider, "drag,stop", "*", _e_wid_cb_drag_stop, obj);
83
84    e_widget_sub_object_add(obj, o);
85    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _e_wid_focus_steal, obj);
86    e_widget_resize_object_set(obj, o);
87
88    /* add gradient obj */
89    o = evas_object_rectangle_add(evas);
90    e_widget_sub_object_add(obj, o);
91    /* evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _e_wid_cb_down, obj); */
92    /* evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, _e_wid_cb_move, obj); */
93    /* evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _e_wid_cb_up, obj); */
94    evas_object_color_set(o, 255, 255, 255, 255);
95    wd->o_grad = o;
96
97    edje_object_part_swallow(wd->o_cslider, "e.swallow.content", o);
98
99    o = evas_object_rectangle_add(evas);
100    e_widget_sub_object_add(obj, o);
101    evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_wid_move, wd);
102    evas_object_show(o);
103    evas_object_color_set(o, 0, 0, 0, 0);
104    wd->o_event = o;
105
106    _e_wid_update(wd);
107
108    return obj;
109 }
110
111 static void
112 _e_wid_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
113 {
114    E_Widget_Data *wd;
115    /* Evas_Coord x, y; */
116
117    wd = data;
118    /* evas_object_geometry_get(obj, &x, &y, NULL, NULL); */
119    /* evas_object_move(wd->o_grad, x, y); */
120    _e_wid_update(wd);
121 }
122
123 static void
124 _e_wid_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
125 {
126    E_Widget_Data *wd;
127    /* Evas_Coord w, h; */
128    
129    wd = data;
130    /* evas_object_geometry_get(obj, NULL, NULL, &w, &h); */
131    /* evas_object_resize(wd->o_grad, w, h); */
132    _e_wid_update(wd);
133 }
134
135 static void
136 _e_wid_value_set(Evas_Object *o, double vx)
137 {
138    E_Widget_Data *wd;
139
140    wd = e_widget_data_get(o);
141    switch (wd->mode)
142      {
143       case E_COLOR_COMPONENT_R:
144          wd->color->r = 255 * vx;
145          e_color_update_rgb(wd->color);
146          break;
147       case E_COLOR_COMPONENT_G:
148          wd->color->g = 255 * vx;
149          e_color_update_rgb(wd->color);
150          break;
151       case E_COLOR_COMPONENT_B:
152          wd->color->b = 255 * vx;
153          e_color_update_rgb(wd->color);
154          break;
155       case E_COLOR_COMPONENT_H:
156          wd->color->h = 360 * vx;
157          e_color_update_hsv(wd->color);
158          break;
159       case E_COLOR_COMPONENT_S:
160          wd->color->s = vx;
161          e_color_update_hsv(wd->color);
162          break;
163       case E_COLOR_COMPONENT_V:
164          wd->color->v = vx;
165          e_color_update_hsv(wd->color);
166          break;
167       case E_COLOR_COMPONENT_MAX:
168          break;
169      }
170
171    _e_wid_update(wd);
172    e_widget_change(o);
173 }
174
175 void
176 e_widget_cslider_color_value_set(Evas_Object *obj, E_Color *val)
177 {
178    E_Widget_Data *wd;
179
180    wd = e_widget_data_get(obj);
181    wd->color = val;
182    _e_wid_update(wd);
183 }
184
185 void
186 e_widget_cslider_update(Evas_Object *obj)
187 {
188    E_Widget_Data *wd;
189
190    wd = e_widget_data_get(obj);
191    _e_wid_update(wd);
192 }
193
194 void
195 e_widget_cslider_mode_set(Evas_Object *obj, E_Color_Component mode)
196 {
197    E_Widget_Data *wd;
198
199    wd = e_widget_data_get(obj);
200    if (wd->mode == mode) return;
201    wd->mode = mode;
202    _e_wid_update(wd);
203 }
204
205 static void
206 _e_wid_update(E_Widget_Data *wd)
207 {
208    Evas_Coord x, y, w, h;
209    Eina_Bool changed = EINA_FALSE;
210
211    evas_object_geometry_get(wd->o_event, &x, &y, &w, &h);
212    if (x != wd->x || y != wd->y || w != wd->w || h != wd->h)
213      changed = EINA_TRUE;
214
215    if (memcmp(wd->color, wd->prev, sizeof (E_Color)))
216      changed = EINA_TRUE;
217
218    if (changed)
219      {
220         Evas_Object *o;
221
222         if (wd->fixed)
223           _e_wid_update_fixed(wd);
224         else
225           _e_wid_update_standard(wd);
226
227         wd->x = x; wd->y = y;
228         wd->w = w; wd->h = h;
229         memcpy(wd->prev, wd->color, sizeof (E_Color));
230
231         if (wd->mode != E_COLOR_COMPONENT_H)
232           {
233              EINA_LIST_FREE(wd->o_hgrad, o)
234                evas_object_del(o);
235              evas_object_show(wd->o_grad);
236           }
237         else
238           {
239              evas_object_hide(wd->o_grad);
240           }
241      }
242 }
243
244 static void
245 _e_wid_gradient_set(Evas_Object *o, Eina_Bool orientation,
246                     int rf, int gf, int bf,
247                     int rt, int gt, int bt)
248 {
249    static Evas_Map *m = NULL;
250
251    if (!m) m = evas_map_new(4);
252    evas_map_util_points_populate_from_object(m, o);
253
254    if (orientation)
255      {
256         evas_map_point_color_set(m, 0, rf, gf, bf, 255);
257         evas_map_point_color_set(m, 1, rf, gf, bf, 255);
258         evas_map_point_color_set(m, 2, rt, gt, bt, 255);
259         evas_map_point_color_set(m, 3, rt, gt, bt, 255);
260      }
261    else
262      {
263         /* Rotate by 270° */
264         evas_map_point_color_set(m, 0, rf, gf, bf, 255);
265         evas_map_point_color_set(m, 1, rt, gt, bt, 255);
266         evas_map_point_color_set(m, 2, rt, gt, bt, 255);
267         evas_map_point_color_set(m, 3, rf, gf, bf, 255);
268      }
269
270    evas_object_map_enable_set(o, 1);
271    evas_object_map_set(o, m);
272 }
273
274 static void
275 _e_wid_update_standard(E_Widget_Data *wd)
276 {
277    Evas_Object *o;
278    Eina_List *l;
279    Evas_Coord x, y, w, h;
280    int r, g, b;
281    int rd, gd, bd;
282    int max, min;
283    unsigned int i;
284    float vx = 0;
285    int *grad[7][3] = {
286      { &max, &min, &min },
287      { &max, &max, &min },
288      { &min, &max, &min },
289      { &min, &max, &max },
290      { &min, &min, &max },
291      { &max, &min, &max },
292      { &max, &min, &min }
293    };
294
295    if (!wd->color) return;
296
297    switch (wd->mode)
298      {
299       case E_COLOR_COMPONENT_R:
300          _e_wid_gradient_set(wd->o_grad, wd->vertical,
301                              0, wd->color->g, wd->color->b,
302                              255, wd->color->g, wd->color->b);
303          vx = wd->color->r / 255.0;
304          break;
305       case E_COLOR_COMPONENT_G:
306          _e_wid_gradient_set(wd->o_grad, wd->vertical,
307                              wd->color->r, 0, wd->color->b,
308                              wd->color->r, 255, wd->color->b);
309          vx = wd->color->g / 255.0;
310          break;
311       case E_COLOR_COMPONENT_B:
312          _e_wid_gradient_set(wd->o_grad, wd->vertical,
313                              wd->color->r, wd->color->g, 0,
314                              wd->color->r, wd->color->g, 255);
315          vx = wd->color->b / 255.0;
316          break;
317       case E_COLOR_COMPONENT_H:
318          evas_color_hsv_to_rgb(0, wd->color->s, wd->color->v, &max, &min, NULL);
319
320          if (!wd->o_hgrad)
321            {
322               Evas *e;
323
324               e = evas_object_evas_get(wd->o_grad);
325               for (i = 0; i < 6; ++i)
326                 wd->o_hgrad = eina_list_append(wd->o_hgrad,
327                                                evas_object_rectangle_add(e));
328            }
329
330          evas_object_geometry_get(wd->o_grad, &x, &y, &w, &h);
331          evas_object_hide(wd->o_grad);
332
333          i = 0;
334          EINA_LIST_FOREACH(wd->o_hgrad, l, o)
335            {
336               if (wd->vertical)
337                 {
338                    evas_object_move(o, x, y + (i * h) / 6);
339                    evas_object_resize(o, w, h / 6);
340                 }
341               else
342                 {
343                    evas_object_move(o, x + (i * w) / 6, y);
344                    evas_object_resize(o, w / 6, h);
345                 }
346
347               _e_wid_gradient_set(o, wd->vertical,
348                                   *grad[i][0], *grad[i][1], *grad[i][2],
349                                   *grad[i + 1][0], *grad[i + 1][1], *grad[i + 1][2]);
350               evas_object_show(o);
351               i++;
352            }
353          vx = wd->color->h / 360.0;
354          break;
355       case E_COLOR_COMPONENT_S:
356          evas_color_hsv_to_rgb(wd->color->h, 0, wd->color->v, &r, &g, &b);
357          evas_color_hsv_to_rgb(wd->color->h, 1, wd->color->v, &rd, &gd, &bd);
358
359          _e_wid_gradient_set(wd->o_grad, wd->vertical,
360                              r, g, b,
361                              rd, gd, bd);
362          vx = wd->color->s;
363          break;
364       case E_COLOR_COMPONENT_V:
365          evas_color_hsv_to_rgb(wd->color->h, wd->color->s, 0, &r, &g, &b);
366          evas_color_hsv_to_rgb(wd->color->h, wd->color->s, 1, &rd, &gd, &bd);
367
368          _e_wid_gradient_set(wd->o_grad, wd->vertical,
369                              r, g, b,
370                              rd, gd, bd);
371          vx = wd->color->v;
372          break;
373       case E_COLOR_COMPONENT_MAX:
374          break;
375      }
376
377    edje_object_part_drag_value_set(wd->o_cslider, "e.dragable.cursor", vx, vx);
378    edje_object_message_signal_process(wd->o_cslider); /* really needed or go in infinite loop */
379 }
380
381 void
382 _e_wid_update_fixed(E_Widget_Data *wd)
383 {
384 #define GMAX 255
385 #define GMIN 0
386
387    Evas_Object *o;
388    Eina_List *l;
389    Evas_Coord x, y, w, h;
390    unsigned int i;
391    float vx = 0;
392    int grad[7][3] = {
393      { GMAX, GMIN, GMIN },
394      { GMAX, GMIN, GMAX },
395      { GMIN, GMIN, GMAX },
396      { GMIN, GMAX, GMAX },
397      { GMIN, GMAX, GMIN },
398      { GMAX, GMAX, GMIN },
399      { GMAX, GMIN, GMIN }
400    };
401
402    if (!wd) return;
403
404    switch (wd->mode)
405     {
406      case E_COLOR_COMPONENT_R:
407         _e_wid_gradient_set(wd->o_grad, wd->vertical,
408                             255, 0, 0,
409                             0, 0, 0);
410         vx = wd->color->r / 255.0;
411         break;
412      case E_COLOR_COMPONENT_G:
413         _e_wid_gradient_set(wd->o_grad, wd->vertical,
414                             0, 255, 0,
415                             0, 0, 0);
416         vx = wd->color->g / 255.0;
417         break;
418      case E_COLOR_COMPONENT_B:
419         _e_wid_gradient_set(wd->o_grad, wd->vertical,
420                             0, 0, 255,
421                             0, 0, 0);
422         vx = wd->color->b / 255.0;
423         break;
424      case E_COLOR_COMPONENT_H:
425         /*
426          * Color Stops:
427          *   0 x n n
428          *  60 x x n
429          * 120 n x n
430          * 180 n x x
431          * 240 n n x
432          * 300 x n x
433          * 360 x n n
434          */
435
436         if (!wd->o_hgrad)
437           {
438              Evas *e;
439
440              e = evas_object_evas_get(wd->o_grad);
441              for (i = 0; i < 6; ++i)
442                wd->o_hgrad = eina_list_append(wd->o_hgrad,
443                                               evas_object_rectangle_add(e));
444           }
445
446         evas_object_geometry_get(wd->o_grad, &x, &y, &w, &h);
447         evas_object_hide(wd->o_grad);
448
449         i = 0;
450         EINA_LIST_FOREACH(wd->o_hgrad, l, o)
451           {
452              if (wd->vertical)
453                {
454                   evas_object_move(o, x, y + (i * h) / 6);
455                   evas_object_resize(o, w, h / 6);
456                }
457              else
458                {
459                   evas_object_move(o, x + (i * w) / 6, y);
460                   evas_object_resize(o, w / 6, h);
461                }
462
463              _e_wid_gradient_set(o, wd->vertical,
464                                  grad[i][0], grad[i][1], grad[i][2],
465                                  grad[i + 1][0], grad[i + 1][1], grad[i + 1][2]);
466              evas_object_show(o);
467              i++;
468           }
469         vx = wd->color->h / 360.0;
470         break;
471      case E_COLOR_COMPONENT_S:
472         _e_wid_gradient_set(wd->o_grad, wd->vertical,
473                             255, 255, 255,
474                             0, 0, 0);
475         vx = wd->color->s;
476         break;
477      case E_COLOR_COMPONENT_V:
478         _e_wid_gradient_set(wd->o_grad, wd->vertical,
479                             255, 255, 255,
480                             0, 0, 0);
481         vx = wd->color->v;
482         break;
483      case E_COLOR_COMPONENT_MAX:
484         break;
485     }
486
487    edje_object_part_drag_value_set(wd->o_cslider, "e.dragable.cursor", vx, vx);
488
489 #undef GMAX
490 #undef GMIN
491 }
492
493 static void
494 _e_wid_del_hook(Evas_Object *obj)
495 {
496    E_Widget_Data *wd;
497
498    wd = e_widget_data_get(obj);
499    free(wd);
500 }
501
502 static void
503 _e_wid_focus_hook(Evas_Object *obj)
504 {
505    E_Widget_Data *wd;
506
507    wd = e_widget_data_get(obj);
508    if (e_widget_focus_get(obj))
509      {
510         edje_object_signal_emit(wd->o_cslider, "e,state,focused", "e");
511         evas_object_focus_set(wd->o_cslider, 1);
512      }
513    else
514      {
515         edje_object_signal_emit(wd->o_cslider, "e,state,unfocused", "e");
516         evas_object_focus_set(wd->o_cslider, 0);
517      }
518 }
519
520 static void
521 _e_wid_disable_hook(Evas_Object *obj)
522 {
523    E_Widget_Data *wd;
524
525    wd = e_widget_data_get(obj);
526    if (e_widget_disabled_get(obj))
527      edje_object_signal_emit(wd->o_cslider, "e,state,disabled", "e");
528    else
529      edje_object_signal_emit(wd->o_cslider, "e,state,enabled", "e");
530 }
531
532 static void
533 _e_wid_focus_steal(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
534 {
535    e_widget_focus_steal(data);
536 }
537
538 static void
539 _e_wid_cb_drag_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
540 {
541    Evas_Object *o_wid;
542    E_Widget_Data *wd;
543    double val, valx, valy;
544
545    o_wid = data;
546    wd = e_widget_data_get(o_wid);
547    wd->dragging = 1;
548
549    edje_object_part_drag_value_get(wd->o_cslider, "e.dragable.cursor",
550                                    &valx, &valy);
551    if (wd->vertical) val = valy;
552    else val = valx;
553    if (val > 1) val = 1;
554    if (val < 0) val = 0;
555    _e_wid_value_set(o_wid, val);
556 }
557
558 static void
559 _e_wid_cb_drag_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
560 {
561    Evas_Object *o_wid;
562    E_Widget_Data *wd;
563
564    o_wid = data;
565    wd = e_widget_data_get(o_wid);
566    wd->dragging = 0;
567 }
568
569 static void
570 _e_wid_cb_drag(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
571 {
572    Evas_Object *o_wid;
573    E_Widget_Data *wd;
574
575    o_wid = data;
576    wd = e_widget_data_get(o_wid);
577
578    if (wd->dragging == 1)
579      {
580         double val, valx, valy;
581
582         edje_object_part_drag_value_get(wd->o_cslider, "e.dragable.cursor",
583                                         &valx, &valy);
584         if (wd->vertical) val = valy;
585         else val = valx;
586         if (val > 1) val = 1;
587         if (val < 0) val = 0;
588         _e_wid_value_set(o_wid, val);
589      }
590 }