modify doxygen
[framework/uifw/elementary.git] / src / lib / elm_actionslider.c
1 /*
2  * SLP
3  * Copyright (c) 2009 Samsung Electronics, Inc.
4  * All rights reserved.
5  *
6  * This software is a confidential and proprietary information
7  * of Samsung Electronics, Inc. ("Confidential Information").  You
8  * shall not disclose such Confidential Information and shall use
9  * it only in accordance with the terms of the license agreement
10  * you entered into with Samsung Electronics.
11  */
12
13 /**
14  *
15  * @defgroup Actionslider Actionslider
16  * @ingroup Elementary
17  *
18  * This is an actionslider.
19  */
20
21 #include <Elementary.h>
22 #include <math.h>
23 #include "elm_priv.h"
24
25 /**
26  * internal data structure of actionslider object
27  */
28 typedef struct _Widget_Data Widget_Data;
29
30 struct _Widget_Data
31 {
32         Evas_Object     *as;            // actionslider
33         Evas_Object     *icon;          // an icon for a button or a bar
34
35         // setting
36         Elm_Actionslider_Magnet_Pos     magnet_position;
37         const char *text_left, *text_right, *text_center;
38
39         // status
40         Eina_Bool       mouse_down;
41         Eina_Bool       mouse_hold;
42
43         // icon animation
44         Ecore_Animator  *icon_animator;
45         double          final_position;
46 };
47
48 static void _del_hook(Evas_Object *obj);
49 static void _theme_hook(Evas_Object *obj);
50 static void _disable_hook(Evas_Object *obj);
51 static void _sizing_eval(Evas_Object *obj);
52 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
53
54 /*
55  * callback functions
56  */
57 static void _icon_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
58 static void _icon_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
59 static void _icon_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
60
61 /*
62  * internal functions
63  */
64 static int _icon_animation(void *data);
65
66 static void
67 _del_hook(Evas_Object *obj)
68 {
69         Widget_Data *wd = elm_widget_data_get(obj);
70
71         if(wd->icon) {
72                 evas_object_del(wd->icon);
73                 wd->icon = NULL;
74         }
75         if (wd->text_left) {
76                 eina_stringshare_del(wd->text_left);
77         }
78         if (wd->text_right) {
79                 eina_stringshare_del(wd->text_right);
80         }
81         if (wd->text_center) {
82                 eina_stringshare_del(wd->text_center);
83         }
84         if(wd->as) {
85                 evas_object_smart_member_del(wd->as);
86                 evas_object_del(wd->as);
87                 wd->as = NULL;
88         }
89         free(wd);
90 }
91
92 static void
93 _theme_hook(Evas_Object *obj)
94 {
95         Widget_Data *wd = elm_widget_data_get(obj);
96
97         if (edje_object_part_swallow_get(wd->as, "elm.swallow.icon") == NULL) {
98                 edje_object_part_unswallow(wd->as, wd->icon);
99         }
100
101         _elm_theme_object_set(obj, wd->as, "actionslider", "base", elm_widget_style_get(obj));
102         _elm_theme_object_set(obj, wd->icon, "actionslider", "icon", elm_widget_style_get(obj));
103         edje_object_part_swallow(wd->as, "elm.swallow.icon", wd->icon);
104         edje_object_part_text_set(wd->as, "elm.text.left", wd->text_left);
105         edje_object_part_text_set(wd->as, "elm.text.right", wd->text_right);
106         edje_object_part_text_set(wd->as, "elm.text.center", wd->text_center);
107         edje_object_message_signal_process(wd->as);
108         //edje_object_scale_set(wd->as, elm_widget_scale_get(obj) * _elm_config->scale);
109         _sizing_eval(obj);
110 }
111
112 static void
113 _disable_hook(Evas_Object *obj)
114 {
115         Widget_Data *wd = elm_widget_data_get(obj);
116 /*
117            TODO
118    if (elm_widget_disabled_get(obj))
119      edje_object_signal_emit(wd->btn, "elm,state,disabled", "elm");
120    else
121      edje_object_signal_emit(wd->btn, "elm,state,enabled", "elm");
122 */
123 }
124
125 static void
126 _sizing_eval(Evas_Object *obj)
127 {
128         Widget_Data *wd = elm_widget_data_get(obj);
129
130 }
131
132 static void
133 _sub_del(void *data, Evas_Object *obj, void *event_info)
134 {
135         Widget_Data *wd = elm_widget_data_get(obj);
136         Evas_Object *sub = event_info;
137 }
138
139 static void
140 _icon_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
141 {
142         Widget_Data *wd = elm_widget_data_get((Evas_Object *)data);
143
144         wd->mouse_down = EINA_TRUE;
145 }
146
147 static void
148 _icon_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
149 {
150         Evas_Object *as = (Evas_Object *)data;
151         Widget_Data *wd = elm_widget_data_get(as);
152         double pos = 0.0;
153
154         elm_actionslider_hold(as, EINA_FALSE);
155         if (wd->mouse_down == EINA_FALSE) return;
156
157         edje_object_part_drag_value_get(wd->as, "elm.swallow.icon", &pos, NULL);
158
159         if (pos == 0.0) {
160                 evas_object_smart_callback_call(as, "position", "left");
161         } else if (pos == 1.0) {
162                 evas_object_smart_callback_call(as, "position", "right");
163
164         } else if (pos >= 0.495 && pos <= 0.505) {
165                 evas_object_smart_callback_call(as, "position", "center");
166         }
167
168         /*
169          * TODO
170         if (    wd->type == ELM_ACTIONSLIDER_TYPE_BAR_GREEN ||
171                 wd->type == ELM_ACTIONSLIDER_TYPE_BAR_RED ) {
172                 if (pos == 1.0) {
173                         //edje_object_signal_emit(wd->as, "elm,show,bar,text,center", "elm");
174                         edje_object_signal_emit(wd->as, "elm,show,text,center", "elm");
175                 } else {
176                         //edje_object_signal_emit(wd->as, "elm,hide,bar,text,center", "elm");
177                         edje_object_signal_emit(wd->as, "elm,hide,text,center", "elm");
178                 }
179         }
180         */
181 }
182
183 static void
184 _icon_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
185 {
186         Widget_Data *wd = elm_widget_data_get((Evas_Object *)data);
187         double position = 0.0;
188
189         wd->mouse_down = EINA_FALSE;
190
191         if (wd->mouse_hold == EINA_FALSE) {
192                 if (wd->magnet_position == ELM_ACTIONSLIDER_MAGNET_LEFT) {
193                         wd->final_position = 0.0;
194                 } else if (wd->magnet_position == ELM_ACTIONSLIDER_MAGNET_RIGHT) {
195                         wd->final_position = 1.0;
196                 } else if (wd->magnet_position == ELM_ACTIONSLIDER_MAGNET_CENTER) {
197                         wd->final_position = 0.5;
198                 } else if ( wd->magnet_position == ELM_ACTIONSLIDER_MAGNET_BOTH) {
199                         edje_object_part_drag_value_get(wd->as, "elm.swallow.icon", &position, NULL);
200                         if (position <= 0.5) {
201                                 wd->final_position = 0.0;
202                         } else {
203                                 wd->final_position = 1.0;
204                         }
205                 }
206
207                 wd->icon_animator = ecore_animator_add(_icon_animation, wd);
208         }
209 }
210
211 static int
212 _icon_animation(void *data)
213 {
214         Widget_Data *wd = (Widget_Data *)data;
215         double cur_position = 0.0, new_position = 0.0;
216         double move_amount = 0.05;
217         Eina_Bool flag_finish_animation = EINA_FALSE;
218
219         edje_object_part_drag_value_get(wd->as, "elm.swallow.icon", &cur_position, NULL);
220
221         if (    (wd->final_position == 0.0) ||
222                 (wd->final_position == 0.5 && cur_position >= wd->final_position) ) {
223                 new_position = cur_position - move_amount;
224                 if (new_position <= wd->final_position) {
225                         new_position = wd->final_position;
226                         flag_finish_animation = EINA_TRUE;
227                 }
228         } else if (     (wd->final_position == 1.0) ||
229                         (wd->final_position == 0.5 && cur_position < wd->final_position) ) {
230                 new_position = cur_position + move_amount;
231                 if (new_position >= wd->final_position) {
232                         new_position = wd->final_position;
233                         flag_finish_animation = EINA_TRUE;
234                         /*
235                         // TODO
236                         if (wd->type == ELM_ACTIONSLIDER_TYPE_BAR_GREEN ||
237                                 wd->type == ELM_ACTIONSLIDER_TYPE_BAR_RED ) {
238                                 edje_object_signal_emit(wd->as, "elm,show,bar,text,center", "elm");
239                         }
240                         */
241                 }
242         }
243
244         edje_object_part_drag_value_set(wd->as, "elm.swallow.icon", new_position, 0.5);
245
246         if (flag_finish_animation == EINA_TRUE) {
247                 return 0;
248         } else {
249                 return 1;
250         }
251 }
252
253 /**
254  * Add a new actionslider to the parent.
255  *
256  * @param parent The parent object
257  * @return The new actionslider object or NULL if it cannot be created
258  *
259  * @ingroup Actionslider
260  */
261 EAPI Evas_Object *
262 elm_actionslider_add(Evas_Object *parent)
263 {
264         Evas_Object *obj;
265         Evas *e;
266         Widget_Data *wd = NULL;
267
268         wd = ELM_NEW(Widget_Data);
269         e = evas_object_evas_get(parent);
270         if (e == NULL) return NULL;
271         obj = elm_widget_add(e);
272         elm_widget_type_set(obj, "actionslider");
273         elm_widget_sub_object_add(parent, obj);
274         elm_widget_data_set(obj, wd);
275
276         elm_widget_del_hook_set(obj, _del_hook);
277         elm_widget_theme_hook_set(obj, _theme_hook);
278         elm_widget_disable_hook_set(obj, _disable_hook);
279
280         wd->mouse_down = EINA_FALSE;
281         wd->mouse_hold = EINA_FALSE;
282
283         // load background edj
284         wd->as = edje_object_add(e);
285         if(wd->as == NULL) {
286                 printf("Cannot load actionslider edj!\n");
287                 return NULL;
288         }
289         _elm_theme_object_set(obj, wd->as, "actionslider", "base", "default");
290         elm_widget_resize_object_set(obj, wd->as);
291
292         // load icon
293         wd->icon = edje_object_add(e);
294         if (wd->icon == NULL) {
295                 printf("Cannot load acitionslider icon!\n");
296                 return NULL;
297         }
298         evas_object_smart_member_add(wd->icon, obj);
299         _elm_theme_object_set(obj, wd->icon, "actionslider", "icon", "default");
300         edje_object_part_swallow(wd->as, "elm.swallow.icon", wd->icon);
301
302         // event callbacks
303         evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
304         evas_object_event_callback_add(wd->icon, EVAS_CALLBACK_MOUSE_DOWN, _icon_down_cb, obj);
305         evas_object_event_callback_add(wd->icon, EVAS_CALLBACK_MOUSE_MOVE, _icon_move_cb, obj);
306         evas_object_event_callback_add(wd->icon, EVAS_CALLBACK_MOUSE_UP, _icon_up_cb, obj);
307
308         return obj;
309 }
310
311 /*
312 EAPI Evas_Object *
313 elm_actionslider_add_with_set(Evas_Object *parent, Elm_Actionslider_Icon_Pos pos, Elm_Actionslider_Magnet_Pos magnet, const char* label_left, const char* label_center, const char* label_right)
314 {
315         Evas_Object *obj;
316
317         obj = elm_actionslider_add(parent);
318
319         elm_actionslider_icon_set(obj, pos);
320         elm_actionslider_magnet_set(obj, magnet);
321         if (label_left != NULL)
322                 elm_actionslider_label_set(obj, ELM_ACTIONSLIDER_LABEL_LEFT, label_left);
323         if (label_center != NULL)
324                 elm_actionslider_label_set(obj, ELM_ACTIONSLIDER_LABEL_CENTER, label_center);
325         if (label_right != NULL)
326                 elm_actionslider_label_set(obj, ELM_ACTIONSLIDER_LABEL_RIGHT, label_right);
327
328         return obj;
329 }
330 */
331
332 /**
333  * Set actionslider indicator position. 
334  *
335  * @param obj The actionslider object. 
336  * @param pos The position of the indicator.
337  * (ELM_ACTIONSLIDER_INDICATOR_LEFT, ELM_ACTIONSLIDER_INDICATOR_RIGHT,
338  *  ELM_ACTIONSLIDER_INDICATOR_CENTER)
339  *
340  * @ingroup Actionslider
341  */
342 EAPI void
343 elm_actionslider_indicator_pos_set(Evas_Object *obj, Elm_Actionslider_Indicator_Pos pos)
344 {
345         Widget_Data *wd = elm_widget_data_get(obj);
346         double position = 0.0;
347
348         if (pos == ELM_ACTIONSLIDER_INDICATOR_LEFT) {
349                 position = 0.0;
350         } else if (pos == ELM_ACTIONSLIDER_INDICATOR_RIGHT) {
351                 position = 1.0;
352         } else if (pos == ELM_ACTIONSLIDER_INDICATOR_CENTER) {
353                 position = 0.5;
354         } else {
355                 position = 0.0;
356         }
357
358         edje_object_part_drag_value_set(wd->as, "elm.swallow.icon", position, 0.5);
359 }
360
361 /**
362  * Set actionslider magnet position. 
363  *
364  * @param obj The actionslider object. 
365  * @param pos The position of the magnet.
366  * (ELM_ACTIONSLIDER_MAGNET_LEFT, ELM_ACTIONSLIDER_MAGNET_RIGHT,
367  *  ELM_ACTIONSLIDER_MAGNET_BOTH, ELM_ACTIONSLIDER_MAGNET_CENTER)
368  *
369  * @ingroup Actionslider
370  */
371 EAPI void
372 elm_actionslider_magnet_pos_set(Evas_Object *obj, Elm_Actionslider_Magnet_Pos pos)
373 {
374         Widget_Data *wd = elm_widget_data_get(obj);
375
376         wd->magnet_position = pos;
377 }
378
379 /**
380  * Set actionslider label.
381  *
382  * @param obj The actionslider object
383  * @param pos The position of the label.
384  * (ELM_ACTIONSLIDER_LABEL_LEFT, ELM_ACTIONSLIDER_LABEL_RIGHT)
385  * @param label The label which is going to be set.
386  *
387  * @ingroup Actionslider
388  */
389 EAPI int
390 elm_actionslider_label_set(Evas_Object *obj, Elm_Actionslider_Label_Pos pos, const char *label)
391 {
392         Widget_Data *wd = elm_widget_data_get(obj);
393
394         if(label == NULL) {
395                 label = "";
396         }
397
398         if (pos == ELM_ACTIONSLIDER_LABEL_RIGHT) {
399                 if (wd->text_right) {
400                         eina_stringshare_del(wd->text_right);
401                 }
402                 wd->text_right = eina_stringshare_add(label);
403                 edje_object_part_text_set(wd->as, "elm.text.right", label);
404         } else if (pos == ELM_ACTIONSLIDER_LABEL_LEFT) {
405                 if (wd->text_left) {
406                         eina_stringshare_del(wd->text_left);
407                 }
408                 wd->text_left = eina_stringshare_add(label);
409                 edje_object_part_text_set(wd->as, "elm.text.left", label);
410         } else if (pos == ELM_ACTIONSLIDER_LABEL_CENTER) {
411                 if (wd->text_center) {
412                         eina_stringshare_del(wd->text_center);
413                 }
414                 wd->text_center = eina_stringshare_add(label);
415                 edje_object_part_text_set(wd->as, "elm.text.center", label);
416         }
417
418         return 0;
419 }
420
421 /**
422  * Hold actionslider object movement.
423  *
424  * @param obj The actionslider object
425  * @param flag Actionslider hold/release
426  * (EINA_TURE = hold/EIN_FALSE = release)
427  *
428  * @ingroup Actionslider
429  */
430 EAPI int
431 elm_actionslider_hold(Evas_Object *obj, Eina_Bool flag)
432 {
433         Widget_Data *wd = elm_widget_data_get(obj);
434
435         wd->mouse_hold = flag;
436
437         return 0;
438 }