Merge remote-tracking branch 'remotes/origin/upstream'
[framework/uifw/elementary.git] / src / lib / elm_flipselector.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /* TODO: ideally, the default theme would use map{} blocks on the TEXT
5    parts to implement their fading in/out propertly (as in the clock
6    widget) */
7 /* TODO: if one ever wants to extend it to receiving generic widgets
8    as items, be my guest. in this case, remember to implement the
9    items tooltip infra. */
10 <<<<<<< HEAD
11 /* TODO: implement disabled mode -- disable_hook() and stuff. */
12 =======
13 >>>>>>> remotes/origin/upstream
14 /* TODO: fix default theme image borders for looong strings as item
15    labels. */
16 /* TODO: set text elipsis on labels if one enforces mininum size on
17  * the overall widget less the required for displaying it. */
18 /* TODO: find a way to, in the default theme, to detect we are
19  * bootstrapping (receiving the 1st message) and populate the downmost
20  * TEXT parts with the same text as the upmost, where appropriate. */
21
22 #define FLIP_FIRST_INTERVAL (0.85)
23 #define FLIP_MIN_INTERVAL (0.1)
24 #define MSG_FLIP_DOWN (1)
25 #define MSG_FLIP_UP (2)
26 #define MAX_LEN_DEFAULT (50)
27
28 #define DATA_GET eina_list_data_get
29
30 struct _Elm_Flipselector_Item
31 {
32    ELM_WIDGET_ITEM;
33    const char *label;
34    Evas_Smart_Cb func;
35    void *data;
36    int deleted : 1;
37 };
38
39 typedef struct _Widget_Data Widget_Data;
40 typedef struct _Elm_Flipselector_Item Elm_Flipselector_Item;
41
42 struct _Widget_Data
43 {
44    Evas_Object *self;
45    Evas_Object *base;
46    Eina_List *items;
47    Eina_List *current;
48    Eina_List *sentinel; /* item containing the largest label string */
49    int walking;
50    unsigned int max_len;
51    Ecore_Timer *spin;
52    double interval, first_interval;
53 };
54
55 static const char *widtype = NULL;
56 static void _del_hook(Evas_Object *obj);
57 static void _theme_hook(Evas_Object *obj);
58 static void _sizing_eval(Evas_Object *obj);
59 static void _update_view(Evas_Object *obj);
60 static void _callbacks_set(Evas_Object *obj);
61 static void _flip_up(Widget_Data *wd);
62 static void _flip_down(Widget_Data *wd);
63 static Eina_Bool _item_del_pre_hook(Elm_Object_Item *it);
64
65 static const char SIG_SELECTED[] = "selected";
66 static const char SIG_UNDERFLOWED[] = "underflowed";
67 static const char SIG_OVERFLOWED[] = "overflowed";
68 static const Evas_Smart_Cb_Description _signals[] = {
69   {SIG_SELECTED, ""},
70   {SIG_UNDERFLOWED, ""},
71   {SIG_OVERFLOWED, ""},
72   {NULL, NULL}
73 };
74
75 static void
76 _item_text_set_hook(Elm_Object_Item *it,
77                     const char *part,
78                     const char *label)
79 {
80 <<<<<<< HEAD
81    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
82
83 =======
84 >>>>>>> remotes/origin/upstream
85    Widget_Data *wd;
86    Eina_List *l;
87    Elm_Flipselector_Item *item;
88
89    if (!label) return;
90
91    if (part && strcmp(part ,"default")) return;
92
93 <<<<<<< HEAD
94    item = (Elm_Flipselector_Item *) it;
95 =======
96    item = (Elm_Flipselector_Item *)it;
97 >>>>>>> remotes/origin/upstream
98    wd = elm_widget_data_get(WIDGET(item));
99    if ((!wd) || (!wd->items)) return;
100
101    l = eina_list_data_find_list(wd->items, item);
102    if (!l) return;
103
104    eina_stringshare_del(item->label);
105    item->label = eina_stringshare_add_length(label, wd->max_len);
106
107    if (strlen(label) > strlen(elm_object_item_text_get(DATA_GET(wd->sentinel))))
108      wd->sentinel = l;
109
110    if (wd->current == l)
111      {
112         _update_view(WIDGET(item));
113         _sizing_eval(wd->self);
114      }
115 }
116
117 static const char *
118 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
119 {
120 <<<<<<< HEAD
121    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
122
123    Elm_Flipselector_Item *item, *_item;
124    Widget_Data *wd;
125    Eina_List *l;
126
127    if (part && strcmp(part ,"default")) return NULL;
128
129    item = (Elm_Flipselector_Item *) it;
130    wd = elm_widget_data_get(WIDGET(item));
131    if ((!wd) || (!wd->items)) return NULL;
132
133    EINA_LIST_FOREACH(wd->items, l, _item)
134      if (_item == item) return item->label;
135    return NULL;
136 =======
137    if (part && strcmp(part ,"default")) return NULL;
138
139    return ((Elm_Flipselector_Item *)it)->label;
140 >>>>>>> remotes/origin/upstream
141 }
142
143 static void
144 _item_signal_emit_hook(Elm_Object_Item *it,
145                        const char *emission,
146                        const char *source)
147 {
148 <<<<<<< HEAD
149    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
150    Elm_Flipselector_Item *item = (Elm_Flipselector_Item *) it;
151 =======
152    Elm_Flipselector_Item *item = (Elm_Flipselector_Item *)it;
153 >>>>>>> remotes/origin/upstream
154    edje_object_signal_emit(VIEW(item), emission, source);
155 }
156
157 static Elm_Flipselector_Item *
158 _item_new(Evas_Object *obj, const char *label, Evas_Smart_Cb func, const void *data)
159 {
160    unsigned int len;
161    Elm_Flipselector_Item *it;
162    Widget_Data *wd = elm_widget_data_get(obj);
163
164    it = elm_widget_item_new(obj, Elm_Flipselector_Item);
165    if (!it) return NULL;
166
167    elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
168    elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
169    elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
170    elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
171
172    len = strlen(label);
173    if (len > wd->max_len)
174      len = wd->max_len;
175
176    it->label = eina_stringshare_add_length(label, len);
177    it->func = func;
178    it->base.data = data;
179
180    /* TODO: no view here, but if one desires general contents in the
181     * future... */
182    return it;
183 }
184
185 static inline void
186 _item_free(Elm_Flipselector_Item *it)
187 {
188    eina_stringshare_del(it->label);
189    elm_widget_item_free(it);
190 }
191
192 static void
193 _del_hook(Evas_Object *obj)
194 {
195    Elm_Flipselector_Item *item;
196
197    Widget_Data *wd = elm_widget_data_get(obj);
198    if (!wd) return;
199
200    if (wd->walking) ERR("flipselector deleted while walking.\n");
201
202    EINA_LIST_FREE(wd->items, item)
203      _item_free(item);
204
205    if (wd->spin) ecore_timer_del(wd->spin);
206    free(wd);
207 }
208
209 static void
210 <<<<<<< HEAD
211 =======
212 _disable_hook(Evas_Object *obj)
213 {
214    Widget_Data *wd = elm_widget_data_get(obj);
215    if (!wd) return;
216
217    if (elm_widget_disabled_get(obj))
218      edje_object_signal_emit(wd->base, "elm,state,disabled", "elm");
219    else
220      edje_object_signal_emit(wd->base, "elm,state,enabled", "elm");
221 }
222
223 static void
224 >>>>>>> remotes/origin/upstream
225 _theme_hook(Evas_Object *obj)
226 {
227    Widget_Data *wd;
228    const char *max_len;
229
230    wd = elm_widget_data_get(obj);
231    if (!wd) return;
232
233    _elm_theme_object_set(obj, wd->base, "flipselector", "base",
234                          elm_widget_style_get(obj));
235    edje_object_scale_set(wd->base,
236                          elm_widget_scale_get(obj) * _elm_config->scale);
237
238    max_len = edje_object_data_get(wd->base, "max_len");
239    if (!max_len)
240      wd->max_len = MAX_LEN_DEFAULT;
241    else
242      {
243         wd->max_len = atoi(max_len);
244         if (!wd->max_len)
245           wd->max_len = MAX_LEN_DEFAULT;
246      }
247
248    _update_view(obj);
249    _sizing_eval(obj);
250 }
251
252 static void
253 _sentinel_eval(Widget_Data *wd)
254 {
255    Elm_Flipselector_Item *it;
256    Eina_List *l;
257
258    if (!wd->items)
259      {
260         wd->sentinel = NULL;
261         return;
262      }
263
264    wd->sentinel = wd->items;
265
266    EINA_LIST_FOREACH(wd->items, l, it)
267      {
268 <<<<<<< HEAD
269         if (strlen(elm_object_item_text_get((Elm_Object_Item *) it)) >
270 =======
271         if (strlen(elm_object_item_text_get((Elm_Object_Item *)it)) >
272 >>>>>>> remotes/origin/upstream
273             strlen(elm_object_item_text_get(DATA_GET(wd->sentinel))))
274           wd->sentinel = l;
275      }
276 }
277
278 /* TODO: create a flag to avoid looping here all times */
279 static void
280 _flipselector_process_deletions(Widget_Data *wd)
281 {
282    Elm_Flipselector_Item *it;
283    Eina_List *l;
284    Eina_Bool skip = EINA_TRUE;
285    Eina_Bool sentinel_eval = EINA_FALSE;
286
287    wd->walking++; /* avoid nested deletions */
288
289    EINA_LIST_FOREACH(wd->items, l, it)
290      {
291         if (!it->deleted) continue;
292
293         if (wd->current == l)
294           {
295              if (wd->current == wd->sentinel)
296                sentinel_eval = EINA_TRUE;
297              wd->current = eina_list_prev(wd->current);
298           }
299         wd->items = eina_list_remove(wd->items, it);
300
301         if (!wd->current)
302           wd->current = wd->items;
303
304         _item_free(it);
305         skip = EINA_FALSE;
306
307         if (eina_list_count(wd->items) <= 1)
308           edje_object_signal_emit(wd->base, "elm,state,button,hidden", "elm");
309         else
310           edje_object_signal_emit(wd->base, "elm,state,button,visible", "elm");
311      }
312
313    if (!skip)
314      _update_view(wd->self);
315
316    if (sentinel_eval)
317      _sentinel_eval(wd);
318
319    wd->walking--;
320 }
321
322 static inline void
323 _flipselector_walk(Widget_Data *wd)
324 {
325    if (wd->walking < 0)
326      {
327         ERR("walking was negative. fixed!\n");
328         wd->walking = 0;
329      }
330    wd->walking++;
331 }
332
333 static inline void
334 _flipselector_unwalk(Widget_Data *wd)
335 {
336    wd->walking--;
337    if (wd->walking < 0)
338      {
339         ERR("walking became negative. fixed!\n");
340         wd->walking = 0;
341      }
342    if (wd->walking) return;
343
344    _flipselector_process_deletions(wd);
345 }
346
347 static Eina_Bool
348 _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
349 {
350    Evas_Event_Key_Down *ev;
351    Widget_Data *wd;
352    Eina_Bool is_up = EINA_TRUE;
353
354    if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
355
356    wd = elm_widget_data_get(obj);
357    if (!wd) return EINA_FALSE;
358
359    ev = event_info;
360    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
361
362    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
363
364    if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
365      is_up = EINA_FALSE;
366    else if ((strcmp(ev->keyname, "Up")) && (strcmp(ev->keyname, "KP_Up")))
367      return EINA_FALSE;
368
369    if (wd->spin) ecore_timer_del(wd->spin);
370
371    /* TODO: if direction setting via API is not coming in, replace
372       these calls by flip_{next,prev} */
373    _flipselector_walk(wd);
374    if (is_up) _flip_up(wd);
375    else _flip_down(wd);
376    _flipselector_unwalk(wd);
377
378    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
379    return EINA_TRUE;
380 }
381
382 static void
383 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
384 {
385    Widget_Data *wd = elm_widget_data_get(obj);
386    if (!wd) return;
387
388    /* FIXME: no treatment of this signal so far */
389    if (elm_widget_focus_get(obj))
390      {
391         edje_object_signal_emit(wd->base, "elm,action,focus", "elm");
392         evas_object_focus_set(wd->base, EINA_TRUE);
393      }
394    else
395      {
396         edje_object_signal_emit(wd->base, "elm,action,unfocus", "elm");
397         evas_object_focus_set(wd->base, EINA_FALSE);
398      }
399 }
400
401 static void
402 _sizing_eval(Evas_Object *obj)
403 {
404    Widget_Data *wd;
405    const char *tmp = NULL;
406    Evas_Coord minw = -1, minh = -1, w, h;
407
408    wd = elm_widget_data_get(obj);
409    if (!wd) return;
410
411    elm_coords_finger_size_adjust(1, &minw, 2, &minh);
412
413    if (wd->sentinel)
414      {
415         const char *label = elm_object_item_text_get(DATA_GET(wd->sentinel));
416         tmp = edje_object_part_text_get(wd->base, "top");
417         edje_object_part_text_set(wd->base, "top", label);
418      }
419
420    edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh);
421    elm_coords_finger_size_adjust(1, &minw, 2, &minh);
422    evas_object_size_hint_min_get(obj, &w, &h);
423
424    if (wd->sentinel) edje_object_part_text_set(wd->base, "top", tmp);
425
426    if (w > minw) minw = w;
427    if (h > minh) minh = h;
428
429    evas_object_size_hint_min_set(obj, minw, minh);
430 }
431
432 static void
433 _update_view(Evas_Object *obj)
434 {
435    Widget_Data *wd;
436    const char *label;
437    Elm_Flipselector_Item *item;
438
439    wd = elm_widget_data_get(obj);
440    if (!wd) return;
441
442    label = NULL;
443    item = DATA_GET(wd->current);
444    if (item) label = item->label;
445
446    edje_object_part_text_set(wd->base, "top", label ? label : "");
447    edje_object_part_text_set(wd->base, "bottom", label ? label : "");
448    edje_object_message_signal_process(wd->base);
449 }
450
451 static void
452 _changed(Widget_Data *wd)
453 {
454    Elm_Flipselector_Item *item;
455
456    item = DATA_GET(wd->current);
457    if (!item) return;
458
459    if (item->func)
460      item->func((void *)item->base.data, WIDGET(item), item);
461    if (!item->deleted)
462      evas_object_smart_callback_call(wd->self, SIG_SELECTED, item);
463 }
464
465 static void
466 _send_msg(Widget_Data *wd, int flipside, char *label)
467 {
468    Edje_Message_String msg;
469
470    msg.str = label;
471    edje_object_message_send(wd->base, EDJE_MESSAGE_STRING, flipside, &msg);
472    edje_object_message_signal_process(wd->base);
473
474    _changed(wd);
475 }
476
477 static void
478 _flip_up(Widget_Data *wd)
479 {
480    Elm_Flipselector_Item *item;
481
482    if (!wd->current) return;
483
484    if (wd->current == wd->items)
485      {
486         wd->current = eina_list_last(wd->items);
487         evas_object_smart_callback_call(wd->self, SIG_UNDERFLOWED, NULL);
488      }
489    else
490      wd->current = eina_list_prev(wd->current);
491
492    item = DATA_GET(wd->current);
493    if (!item) return;
494
495    _send_msg(wd, MSG_FLIP_UP, (char *)item->label);
496 }
497
498 static Eina_Bool
499 _signal_val_up(void *data)
500 {
501    Widget_Data *wd = elm_widget_data_get(data);
502
503    if (!wd) goto val_up_exit_on_error;
504
505    _flipselector_walk(wd);
506
507    if (wd->interval > FLIP_MIN_INTERVAL)
508      wd->interval = wd->interval / 1.05;
509
510    ecore_timer_interval_set(wd->spin, wd->interval);
511
512    _flip_up(wd);
513
514    _flipselector_unwalk(wd);
515
516    return ECORE_CALLBACK_RENEW;
517
518 val_up_exit_on_error:
519    return ECORE_CALLBACK_CANCEL;
520 }
521
522 static void
523 _signal_val_up_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
524 {
525    Widget_Data *wd = elm_widget_data_get(data);
526    if (!wd) return;
527
528    wd->interval = wd->first_interval;
529
530    if (wd->spin) ecore_timer_del(wd->spin);
531    wd->spin = ecore_timer_add(wd->interval, _signal_val_up, data);
532
533    _signal_val_up(data);
534 }
535
536 static void
537 _flip_down(Widget_Data *wd)
538 {
539    Elm_Flipselector_Item *item;
540
541    if (!wd->current) return;
542
543    wd->current = eina_list_next(wd->current);
544    if (!wd->current)
545      {
546         wd->current = wd->items;
547         evas_object_smart_callback_call(wd->self, SIG_OVERFLOWED, NULL);
548      }
549
550    item = DATA_GET(wd->current);
551    if (!item) return;
552
553    _send_msg(wd, MSG_FLIP_DOWN, (char *)item->label);
554 }
555
556 static Eina_Bool
557 _signal_val_down(void *data)
558 {
559    Widget_Data *wd = elm_widget_data_get(data);
560
561    if (!wd) goto val_down_exit_on_error;
562
563    _flipselector_walk(wd);
564
565    if (wd->interval > FLIP_MIN_INTERVAL)
566      wd->interval = wd->interval / 1.05;
567    ecore_timer_interval_set(wd->spin, wd->interval);
568
569    _flip_down(wd);
570
571    _flipselector_unwalk(wd);
572
573    return ECORE_CALLBACK_RENEW;
574
575 val_down_exit_on_error:
576    return ECORE_CALLBACK_CANCEL;
577 }
578
579 static void
580 _signal_val_down_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
581 {
582    Widget_Data *wd = elm_widget_data_get(data);
583    if (!wd) return;
584
585    wd->interval = wd->first_interval;
586
587    if (wd->spin) ecore_timer_del(wd->spin);
588    wd->spin = ecore_timer_add(wd->interval, _signal_val_down, data);
589
590    _signal_val_down(data);
591 }
592
593 static void
594 _signal_val_change_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
595 {
596    Widget_Data *wd = elm_widget_data_get(data);
597    if (!wd) return;
598
599    if (wd->spin) ecore_timer_del(wd->spin);
600    wd->spin = NULL;
601 }
602
603 static void
604 _callbacks_set(Evas_Object *obj)
605 {
606    Widget_Data *wd = elm_widget_data_get(obj);
607
608    edje_object_signal_callback_add(wd->base, "elm,action,up,start",
609                                    "", _signal_val_up_start, obj);
610    edje_object_signal_callback_add(wd->base, "elm,action,up,stop",
611                                    "", _signal_val_change_stop, obj);
612    edje_object_signal_callback_add(wd->base, "elm,action,down,start",
613                                    "", _signal_val_down_start, obj);
614    edje_object_signal_callback_add(wd->base, "elm,action,down,stop",
615                                    "", _signal_val_change_stop, obj);
616 }
617
618 static Eina_Bool
619 _item_del_pre_hook(Elm_Object_Item *it)
620 {
621 <<<<<<< HEAD
622    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
623 =======
624 >>>>>>> remotes/origin/upstream
625    Widget_Data *wd;
626    Elm_Flipselector_Item *item, *item2;
627    Eina_List *l;
628
629 <<<<<<< HEAD
630    item = (Elm_Flipselector_Item *) it;
631 =======
632    item = (Elm_Flipselector_Item *)it;
633 >>>>>>> remotes/origin/upstream
634    wd = elm_widget_data_get(WIDGET(item));
635    if (!wd) return EINA_FALSE;
636
637    if (wd->walking > 0)
638      {
639         item->deleted = EINA_TRUE;
640         return EINA_FALSE;
641      }
642
643    _flipselector_walk(wd);
644
645    EINA_LIST_FOREACH(wd->items, l, item2)
646      {
647         if (item2 == item)
648           {
649              wd->items = eina_list_remove_list(wd->items, l);
650              if (wd->current == l)
651                {
652                   wd->current = l->prev;
653                   if (!wd->current) wd->current = l->next;
654                   if (wd->current)
655                     {
656                        item2 = wd->current->data;
657                        _send_msg(wd, MSG_FLIP_DOWN, (char *)item2->label);
658                     }
659                   else
660                      _send_msg(wd, MSG_FLIP_DOWN, "");
661                }
662              break;
663           }
664      }
665    eina_stringshare_del(item->label);
666    _sentinel_eval(wd);
667    _flipselector_unwalk(wd);
668
669    return EINA_TRUE;
670 }
671
672 EAPI Evas_Object *
673 elm_flipselector_add(Evas_Object *parent)
674 {
675    Evas_Object *obj;
676    Evas *e;
677    Widget_Data *wd;
678
679    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
680
681    ELM_SET_WIDTYPE(widtype, "flipselector");
682    elm_widget_type_set(obj, "flipselector");
683    elm_widget_sub_object_add(parent, obj);
684    elm_widget_data_set(obj, wd);
685
686    wd->self = obj;
687    elm_widget_del_hook_set(obj, _del_hook);
688    elm_widget_theme_hook_set(obj, _theme_hook);
689 <<<<<<< HEAD
690    /* TODO: elm_widget_disable_hook_set(obj, _disable_hook); */
691 =======
692    elm_widget_disable_hook_set(obj, _disable_hook);
693 >>>>>>> remotes/origin/upstream
694
695    elm_widget_can_focus_set(obj, EINA_TRUE);
696    elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
697    elm_widget_event_hook_set(obj, _event_hook);
698
699    wd->base = edje_object_add(e);
700    elm_widget_resize_object_set(obj, wd->base);
701
702    _callbacks_set(obj);
703
704    wd->first_interval = FLIP_FIRST_INTERVAL;
705
706    _theme_hook(obj);
707
708    evas_object_smart_callbacks_descriptions_set(obj, _signals);
709    return obj;
710 }
711
712 EAPI void
713 elm_flipselector_flip_next(Evas_Object *obj)
714 {
715    ELM_CHECK_WIDTYPE(obj, widtype);
716
717    Widget_Data *wd = elm_widget_data_get(obj);
718    if (!wd) return;
719
720    if (wd->spin) ecore_timer_del(wd->spin);
721
722    _flipselector_walk(wd);
723    _flip_down(wd);
724    _flipselector_unwalk(wd);
725 }
726
727 EAPI void
728 elm_flipselector_flip_prev(Evas_Object *obj)
729 {
730    ELM_CHECK_WIDTYPE(obj, widtype);
731
732    Widget_Data *wd = elm_widget_data_get(obj);
733    if (!wd) return;
734
735    if (wd->spin) ecore_timer_del(wd->spin);
736
737    _flipselector_walk(wd);
738    _flip_up(wd);
739    _flipselector_unwalk(wd);
740 }
741
742 EAPI Elm_Object_Item *
743 elm_flipselector_item_append(Evas_Object *obj, const char *label, void (*func)(void *data, Evas_Object *obj, void *event_info), void *data)
744 {
745    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
746
747    Elm_Flipselector_Item *item;
748    Widget_Data *wd;
749
750    wd = elm_widget_data_get(obj);
751    if (!wd) return NULL;
752
753    item = _item_new(obj, label, func, data);
754    if (!item) return NULL;
755
756    wd->items = eina_list_append(wd->items, item);
757    if (!wd->current)
758      {
759         wd->current = wd->items;
760         _update_view(obj);
761      }
762
763    if (!wd->sentinel ||
764 <<<<<<< HEAD
765        (strlen(elm_object_item_text_get((Elm_Object_Item *) item)) >
766 =======
767        (strlen(elm_object_item_text_get((Elm_Object_Item *)item)) >
768 >>>>>>> remotes/origin/upstream
769         strlen(elm_object_item_text_get(DATA_GET(wd->sentinel)))))
770      {
771         wd->sentinel = eina_list_last(wd->items);
772         _sizing_eval(obj);
773      }
774
775    if (eina_list_count(wd->items) >= 2)
776      edje_object_signal_emit(wd->base, "elm,state,button,visible", "elm");
777
778 <<<<<<< HEAD
779    return (Elm_Object_Item *) item;
780 =======
781    return (Elm_Object_Item *)item;
782 >>>>>>> remotes/origin/upstream
783 }
784
785 EAPI Elm_Object_Item *
786 elm_flipselector_item_prepend(Evas_Object *obj, const char *label, void (*func)(void *data, Evas_Object *obj, void *event_info), void *data)
787 {
788    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
789
790    Elm_Flipselector_Item *item;
791    Widget_Data *wd;
792
793    wd = elm_widget_data_get(obj);
794    if (!wd) return NULL;
795
796    item = _item_new(obj, label, func, data);
797    if (!item) return NULL;
798
799    wd->items = eina_list_prepend(wd->items, item);
800    if (!wd->current)
801      {
802         wd->current = wd->items;
803         _update_view(obj);
804      }
805
806    if (!wd->sentinel ||
807 <<<<<<< HEAD
808        (strlen(elm_object_item_text_get((Elm_Object_Item *) item)) >
809 =======
810        (strlen(elm_object_item_text_get((Elm_Object_Item *)item)) >
811 >>>>>>> remotes/origin/upstream
812         strlen(elm_object_item_text_get(DATA_GET(wd->sentinel)))))
813      {
814         wd->sentinel = wd->items;
815         _sizing_eval(obj);
816      }
817
818    if (eina_list_count(wd->items) >= 2)
819      edje_object_signal_emit(wd->base, "elm,state,button,visible", "elm");
820
821 <<<<<<< HEAD
822    return (Elm_Object_Item *) item;
823 }
824
825 /* TODO: account for deleted items?  */
826 =======
827    return (Elm_Object_Item *)item;
828 }
829
830 >>>>>>> remotes/origin/upstream
831 EAPI const Eina_List *
832 elm_flipselector_items_get(const Evas_Object *obj)
833 {
834    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
835
836    Widget_Data *wd = elm_widget_data_get(obj);
837    if (!wd) return NULL;
838    return wd->items;
839 }
840
841 EAPI Elm_Object_Item *
842 elm_flipselector_first_item_get(const Evas_Object *obj)
843 {
844    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
845
846    Elm_Flipselector_Item *it;
847    Widget_Data *wd;
848    Eina_List *l;
849
850    wd = elm_widget_data_get(obj);
851    if (!wd || !wd->items) return NULL;
852
853    EINA_LIST_FOREACH(wd->items, l, it)
854      {
855         if (it->deleted) continue;
856 <<<<<<< HEAD
857         return (Elm_Object_Item *) it;
858 =======
859         return (Elm_Object_Item *)it;
860 >>>>>>> remotes/origin/upstream
861      }
862    return NULL;
863 }
864
865 EAPI Elm_Object_Item *
866 elm_flipselector_last_item_get(const Evas_Object *obj)
867 {
868    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
869
870    Elm_Flipselector_Item *it;
871    Widget_Data *wd;
872    Eina_List *l;
873
874    wd = elm_widget_data_get(obj);
875    if (!wd || !wd->items) return NULL;
876
877    EINA_LIST_REVERSE_FOREACH(wd->items, l, it)
878      {
879         if (it->deleted) continue;
880 <<<<<<< HEAD
881         return (Elm_Object_Item *) it;
882 =======
883         return (Elm_Object_Item *)it;
884 >>>>>>> remotes/origin/upstream
885      }
886    return NULL;
887 }
888
889 EAPI Elm_Object_Item *
890 elm_flipselector_selected_item_get(const Evas_Object *obj)
891 {
892    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
893
894    Widget_Data *wd = elm_widget_data_get(obj);
895 <<<<<<< HEAD
896    if (!wd || !wd->current) return NULL;
897 =======
898    if (!wd) return NULL;
899 >>>>>>> remotes/origin/upstream
900    return DATA_GET(wd->current);
901 }
902
903 EAPI void
904 elm_flipselector_item_selected_set(Elm_Object_Item *it, Eina_Bool selected)
905 {
906    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
907
908    Elm_Flipselector_Item *item, *_item, *cur;
909    int flipside = MSG_FLIP_UP;
910    Widget_Data *wd;
911    Eina_List *l;
912
913 <<<<<<< HEAD
914    item = (Elm_Flipselector_Item *) it;
915 =======
916    item = (Elm_Flipselector_Item *)it;
917 >>>>>>> remotes/origin/upstream
918    wd = elm_widget_data_get(WIDGET(item));
919    if (!wd) return;
920
921    cur = DATA_GET(wd->current);
922    if ((selected) && (cur == item)) return;
923
924    _flipselector_walk(wd);
925
926    if ((!selected) && (cur == item))
927      {
928         EINA_LIST_FOREACH(wd->items, l, _item)
929           {
930              if (!_item->deleted)
931                {
932                   wd->current = l;
933                   _send_msg(wd, MSG_FLIP_UP, (char *)_item->label);
934                   break;
935                }
936           }
937         _flipselector_unwalk(wd);
938         return;
939      }
940
941    EINA_LIST_FOREACH(wd->items, l, _item)
942      {
943         if (_item == cur) flipside = MSG_FLIP_DOWN;
944
945         if (_item == item)
946           {
947              wd->current = l;
948              _send_msg(wd, flipside, (char *)item->label);
949              break;
950           }
951      }
952
953    _flipselector_unwalk(wd);
954 }
955
956 EAPI Eina_Bool
957 elm_flipselector_item_selected_get(const Elm_Object_Item *it)
958 {
959    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
960    Widget_Data *wd;
961    Elm_Flipselector_Item *item;
962
963 <<<<<<< HEAD
964    item = (Elm_Flipselector_Item *) it;
965 =======
966    item = (Elm_Flipselector_Item *)it;
967 >>>>>>> remotes/origin/upstream
968    wd = elm_widget_data_get(WIDGET(item));
969    if (!wd) return EINA_FALSE;
970    return (eina_list_data_get(wd->current) == item);
971 }
972
973 <<<<<<< HEAD
974 EAPI void
975 elm_flipselector_item_del(Elm_Object_Item *it)
976 {
977    elm_object_item_del(it);
978 }
979
980 EAPI const char *
981 elm_flipselector_item_label_get(const Elm_Object_Item *it)
982 {
983    return _item_text_get_hook(it, NULL);
984 }
985
986 EAPI void
987 elm_flipselector_item_label_set(Elm_Object_Item *it, const char *label)
988 {
989    _item_text_set_hook(it, NULL, label);
990 }
991
992 EAPI Elm_Object_Item *
993 elm_flipselector_item_prev_get(Elm_Object_Item *it)
994 {
995    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
996
997    Elm_Flipselector_Item *item, *_item;
998    Widget_Data *wd;
999    Eina_List *l;
1000
1001    item = (Elm_Flipselector_Item *) it;
1002    wd = elm_widget_data_get(WIDGET(item));
1003    if ((!wd) || (!wd->items)) return NULL;
1004
1005    EINA_LIST_FOREACH(wd->items, l, _item)
1006      if (_item == item)
1007        {
1008           l = eina_list_prev(l);
1009           if (!l) return NULL;
1010           return DATA_GET(l);
1011        }
1012 =======
1013 EAPI Elm_Object_Item *
1014 elm_flipselector_item_prev_get(const Elm_Object_Item *it)
1015 {
1016    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1017
1018    Widget_Data *wd;
1019    Eina_List *l;
1020    Elm_Flipselector_Item *item = (Elm_Flipselector_Item *)it;
1021
1022    wd = elm_widget_data_get(WIDGET(item));
1023    if ((!wd) || (!wd->items)) return NULL;
1024
1025    l = eina_list_data_find_list(wd->items, it);
1026    if (l && l->prev) return DATA_GET(l->prev);
1027
1028 >>>>>>> remotes/origin/upstream
1029    return NULL;
1030 }
1031
1032 EAPI Elm_Object_Item *
1033 <<<<<<< HEAD
1034 elm_flipselector_item_next_get(Elm_Object_Item *it)
1035 {
1036    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1037
1038    Elm_Flipselector_Item *item, *_item;
1039    Widget_Data *wd;
1040    Eina_List *l;
1041
1042    item = (Elm_Flipselector_Item *) it;
1043    wd = elm_widget_data_get(WIDGET(item));
1044    if ((!wd) || (!wd->items)) return NULL;
1045
1046    EINA_LIST_FOREACH(wd->items, l, _item)
1047      if (_item == item)
1048        {
1049           l = eina_list_next(l);
1050           if (!l) return NULL;
1051           return DATA_GET(l);
1052        }
1053 =======
1054 elm_flipselector_item_next_get(const Elm_Object_Item *it)
1055 {
1056    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1057
1058    Widget_Data *wd;
1059    Eina_List *l;
1060    Elm_Flipselector_Item *item = (Elm_Flipselector_Item *)it;
1061
1062    wd = elm_widget_data_get(WIDGET(item));
1063    if ((!wd) || (!wd->items)) return NULL;
1064
1065    l = eina_list_data_find_list(wd->items, it);
1066    if (l && l->next) return DATA_GET(l->next);
1067
1068 >>>>>>> remotes/origin/upstream
1069    return NULL;
1070 }
1071
1072 EAPI void
1073 <<<<<<< HEAD
1074 elm_flipselector_interval_set(Evas_Object *obj, double interval)
1075 =======
1076 elm_flipselector_first_interval_set(Evas_Object *obj, double interval)
1077 >>>>>>> remotes/origin/upstream
1078 {
1079    ELM_CHECK_WIDTYPE(obj, widtype);
1080
1081    Widget_Data *wd = elm_widget_data_get(obj);
1082    if (!wd) return;
1083    wd->first_interval = interval;
1084 }
1085
1086 EAPI double
1087 <<<<<<< HEAD
1088 elm_flipselector_interval_get(const Evas_Object *obj)
1089 {
1090    ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
1091 =======
1092 elm_flipselector_first_interval_get(const Evas_Object *obj)
1093 {
1094    ELM_CHECK_WIDTYPE(obj, widtype) 0;
1095 >>>>>>> remotes/origin/upstream
1096
1097    Widget_Data *wd = elm_widget_data_get(obj);
1098    if (!wd) return 0;
1099    return wd->first_interval;
1100 }
1101 <<<<<<< HEAD
1102 =======
1103
1104 EINA_DEPRECATED EAPI void
1105 elm_flipselector_interval_set(Evas_Object *obj, double interval)
1106 {
1107    elm_flipselector_first_interval_set(obj, interval);
1108 }
1109
1110 EINA_DEPRECATED EAPI double
1111 elm_flipselector_interval_get(const Evas_Object *obj)
1112 {
1113    return elm_flipselector_first_interval_get(obj);
1114 }
1115
1116 >>>>>>> remotes/origin/upstream