1 #include <Elementary.h>
3 #include "elm_widget_multibuttonentry.h"
9 #define TRANSIT_DURATION 0.167
10 #define ANIMATE_FRAME 10
13 EAPI const char ELM_MULTIBUTTONENTRY_SMART_NAME[] = "elm_multibuttonentry";
16 static const char SIG_ITEM_SELECTED[] = "item,selected";
17 static const char SIG_ITEM_ADDED[] = "item,added";
18 static const char SIG_ITEM_DELETED[] = "item,deleted";
19 static const char SIG_ITEM_CLICKED[] = "item,clicked";
20 static const char SIG_CLICKED[] = "clicked";
21 static const char SIG_FOCUSED[] = "focused";
22 static const char SIG_UNFOCUSED[] = "unfocused";
23 static const char SIG_EXPANDED[] = "expanded";
24 static const char SIG_CONTRACTED[] = "contracted";
25 static const char SIG_EXPAND_STATE_CHANGED[] = "expand,state,changed";
26 static const char SIG_LONGPRESSED[] = "longpressed";
28 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
29 {SIG_ITEM_SELECTED, ""},
31 {SIG_ITEM_DELETED, ""},
32 {SIG_ITEM_CLICKED, ""},
38 {SIG_EXPAND_STATE_CHANGED, ""},
39 {SIG_LONGPRESSED, ""},
43 EVAS_SMART_SUBCLASS_NEW
44 (ELM_MULTIBUTTONENTRY_SMART_NAME, _elm_multibuttonentry,
45 Elm_Multibuttonentry_Smart_Class, Elm_Layout_Smart_Class,
46 elm_layout_smart_class_get, _smart_callbacks);
49 _elm_multibuttonentry_smart_focus_next(const Evas_Object *obj,
50 Elm_Focus_Direction dir,
53 Eina_List *items = NULL;
54 Eina_List *elist = NULL;
55 Elm_Multibuttonentry_Item *it;
57 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
62 if (!elm_widget_focus_next_get(sd->box, dir, next))
64 elm_widget_focused_object_clear(sd->box);
65 elm_widget_focus_next_get(sd->box, dir, next);
68 EINA_LIST_FOREACH(sd->items, elist, it)
69 items = eina_list_append(items, it->base.access_obj);
71 return elm_widget_focus_list_next_get
72 (obj, items, eina_list_data_get, dir, next);
76 _access_label_info_cb(void *data, Evas_Object *obj __UNUSED__)
78 Evas_Object *mbe = (Evas_Object *)data;
79 const char *txt = NULL;
81 ELM_MULTIBUTTONENTRY_DATA_GET(mbe, sd);
83 if (!mbe) return NULL;
87 txt = elm_object_part_text_get(sd->label, "mbe.label");
90 else return strdup(txt);
96 _access_shrink_info_cb(void *data, Evas_Object *obj __UNUSED__)
98 Evas_Object *mbe = (Evas_Object *)data;
99 const char *txt = NULL;
100 Eina_Strbuf *buf = NULL;
103 ELM_MULTIBUTTONENTRY_DATA_GET(mbe, sd);
105 if (!mbe) return NULL;
107 if (!txt) txt = elm_object_text_get(sd->end);
110 buf = eina_strbuf_new();
111 eina_strbuf_append(buf, E_("And "));
112 eina_strbuf_append(buf, txt);
113 eina_strbuf_append(buf, E_(" more"));
114 str = eina_strbuf_string_steal(buf);
115 eina_strbuf_free(buf);
122 _guide_packed(Evas_Object *obj)
126 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
128 if (!sd->guide) return EINA_FALSE;
130 children = elm_box_children_get(sd->box);
131 if (sd->guide == eina_list_data_get(eina_list_last(children)))
133 eina_list_free(children);
138 eina_list_free(children);
144 _label_packed(Evas_Object *obj)
148 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
150 if (!sd->label) return EINA_FALSE;
152 children = elm_box_children_get(sd->box);
153 if (sd->label == eina_list_data_get(children))
155 eina_list_free(children);
160 eina_list_free(children);
166 _guide_set(Evas_Object *obj,
169 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
171 if (!sd->guide && !strlen(text)) return;
175 sd->guide = elm_layout_add(obj);
177 (sd->guide, "multibuttonentry", "guidetext", elm_widget_style_get(obj));
178 evas_object_size_hint_weight_set
179 (sd->guide, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
180 evas_object_size_hint_align_set
181 (sd->guide, EVAS_HINT_FILL, EVAS_HINT_FILL);
183 elm_object_text_set(sd->guide, text);
185 if (!sd->items && !elm_object_focus_get(obj) && !_guide_packed(obj))
189 elm_box_unpack(sd->box, sd->entry);
190 evas_object_hide(sd->entry);
193 elm_box_pack_end(sd->box, sd->guide);
194 evas_object_show(sd->guide);
199 _label_set(Evas_Object *obj,
202 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
204 if (!sd->label && !strlen(text)) return;
208 sd->label = elm_layout_add(obj);
210 (sd->label, "multibuttonentry", "label", elm_widget_style_get(obj));
212 elm_object_part_text_set(sd->label, "mbe.label", text);
214 if (strlen(text) && !_label_packed(obj))
216 elm_box_pack_start(sd->box, sd->label);
217 evas_object_show(sd->label);
219 else if (!strlen(text) && _label_packed(obj))
221 elm_box_unpack(sd->box, sd->label);
222 evas_object_hide(sd->label);
226 if (_elm_config->access_mode)
228 _elm_access_object_register(obj, ELM_WIDGET_DATA(sd)->resize_obj);
229 _elm_access_callback_set(_elm_access_object_get(obj), ELM_ACCESS_INFO, _access_label_info_cb, obj);
235 _box_layout_pre_calculate(Evas_Object *obj,
236 Elm_Multibuttonentry_Item *except_it,
237 Evas_Coord *minh_wo_entry,
240 Evas_Coord mnw, mnh, x, w, hpad = 0, vpad = 0;
241 Evas_Coord linew = 0, lineh = 0;
244 Elm_Multibuttonentry_Item *it;
246 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
248 evas_object_geometry_get(sd->box, &x, NULL, &w, NULL);
249 elm_box_padding_get(sd->box, &hpad, &vpad);
253 if (sd->label && _label_packed(obj))
255 evas_object_size_hint_min_get(sd->label, &mnw, &mnh);
262 EINA_LIST_FOREACH(sd->items, l, it)
264 if (it == except_it) continue;
266 evas_object_size_hint_min_get(VIEW(it), &mnw, &mnh);
269 if (lineh < mnh) lineh = mnh;
282 *minh_wo_entry = lineh * line_num + (line_num - 1) * vpad;
286 // get entry size after text is reset
287 elm_object_text_set(sd->entry, "");
288 elm_layout_sizing_eval(sd->entry);
289 evas_object_size_hint_min_get(sd->entry, &mnw, &mnh);
292 if (lineh < mnh) lineh = mnh;
294 if (linew > w) line_num++;
298 *minh = lineh * line_num + (line_num - 1) * vpad;
302 _on_item_expanding_transit_del(void *data,
303 Elm_Transit *transit __UNUSED__)
305 Elm_Multibuttonentry_Item *it = data;
307 evas_object_data_set(VIEW(it), "transit", NULL);
308 evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_ADDED, it);
312 _after_rect_expand(Evas_Object *rect,
313 Elm_Multibuttonentry_Item *it)
316 Elm_Multibuttonentry_Item *last_item;
318 ELM_MULTIBUTTONENTRY_DATA_GET(WIDGET(it), sd);
320 evas_object_del(rect);
321 evas_object_data_set(VIEW(it), "effect_rect", NULL);
323 // if last item is unpacked, add it
324 children = elm_box_children_get(sd->box);
325 last_item = eina_list_data_get(eina_list_last(sd->items));
326 if (VIEW(last_item) != eina_list_data_get(eina_list_last(children)))
328 elm_box_pack_end(sd->box, VIEW(last_item));
329 evas_object_show(VIEW(last_item));
331 eina_list_free(children);
335 elm_box_pack_end(sd->box, sd->entry);
336 evas_object_show(sd->entry);
337 if (elm_object_focus_get(WIDGET(it)))
338 elm_object_focus_set(sd->entry, EINA_TRUE);
343 _rect_expanding_animate(void *data)
347 Elm_Multibuttonentry_Item *it = data;
349 ELM_MULTIBUTTONENTRY_DATA_GET(WIDGET(it), sd);
351 rect = (Evas_Object *)evas_object_data_get(VIEW(it), "effect_rect");
352 if (!rect) return ECORE_CALLBACK_CANCEL;
354 evas_object_geometry_get(sd->entry, NULL, NULL, NULL, &eh);
355 evas_object_size_hint_min_get(rect, &w, &h);
359 _after_rect_expand(rect, it);
360 return ECORE_CALLBACK_CANCEL;
363 evas_object_size_hint_min_set(rect, w, h + eh / ANIMATE_FRAME);
365 return ECORE_CALLBACK_RENEW;
369 _item_adding_effect_add(Evas_Object *obj,
370 Elm_Multibuttonentry_Item *it)
373 Evas_Coord minh_wo_entry, minh;
374 Eina_Bool floating = EINA_FALSE;;
376 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
378 _box_layout_pre_calculate(obj, NULL, &minh_wo_entry, &minh);
380 // if box will be expanded, add resizing effect
383 Evas_Coord bx, by, bw, bh;
385 Ecore_Animator *anim;
387 evas_object_geometry_get(sd->box, &bx, &by, &bw, &bh);
389 // if box will be expanded with item and entry
390 if (minh_wo_entry == minh)
392 Elm_Multibuttonentry_Item *last_it;
394 last_it = eina_list_data_get(eina_list_last(sd->items));
397 Evas_Coord iw, ih, vpad;
399 evas_object_size_hint_min_get(VIEW(it), &iw, &ih);
400 elm_box_padding_get(sd->box, NULL, &vpad);
402 evas_object_move(VIEW(it), bx, by + bh + vpad);
403 evas_object_resize(VIEW(it), iw, ih);
404 evas_object_show(VIEW(it));
406 floating = EINA_TRUE;
410 elm_box_unpack(sd->box, VIEW(last_it));
411 evas_object_hide(VIEW(last_it));
417 if (elm_object_focus_get(sd->entry))
418 elm_object_focus_set(sd->entry, EINA_FALSE);
419 elm_box_unpack(sd->box, sd->entry);
420 evas_object_hide(sd->entry);
421 elm_entry_input_panel_show(sd->entry);
424 rect = evas_object_rectangle_add(evas_object_evas_get(obj));
425 evas_object_color_set(rect, 0, 0, 0, 0);
427 evas_object_size_hint_min_set(rect, bw, 0);
428 evas_object_data_set(VIEW(it), "effect_rect", rect);
429 elm_box_pack_end(sd->box, rect);
430 evas_object_show(rect);
432 anim = ecore_animator_add(_rect_expanding_animate, it);
433 evas_object_data_set(rect, "animator", anim);
436 evas_object_geometry_get(sd->entry, NULL, NULL, NULL, &eh);
438 evas_object_size_hint_min_set(rect, bw, eh);
439 evas_object_data_set(VIEW(it), "effect_rect", rect);
440 elm_box_pack_end(sd->box, rect);
441 evas_object_show(rect);
443 _after_rect_expand(rect, it);
451 cur = eina_list_data_find_list(sd->items, it);
452 if (cur == sd->items)
454 if (sd->label && _label_packed(obj))
455 elm_box_pack_after(sd->box, VIEW(it), sd->label);
457 elm_box_pack_start(sd->box, VIEW(it));
461 Elm_Multibuttonentry_Item *prev_it;
462 prev_it = eina_list_data_get(eina_list_prev(cur));
463 elm_box_pack_after(sd->box, VIEW(it), VIEW(prev_it));
465 evas_object_show(VIEW(it));
468 trans = elm_transit_add();
469 elm_transit_object_add(trans, VIEW(it));
470 elm_transit_effect_zoom_add(trans, 0.9, 1.0);
471 elm_transit_effect_color_add(trans, 0, 0, 0, 0, 255, 255, 255, 255);
472 elm_transit_del_cb_set(trans, _on_item_expanding_transit_del, it);
473 elm_transit_duration_set(trans, TRANSIT_DURATION);
474 evas_object_data_set(VIEW(it), "transit", trans);
475 elm_transit_go(trans);
479 _on_item_contracting_transit_del(void *data,
480 Elm_Transit *transit __UNUSED__)
483 Elm_Multibuttonentry_Item *it = data;
485 ELM_MULTIBUTTONENTRY_DATA_GET(WIDGET(it), sd);
487 evas_object_data_set(VIEW(it), "transit", NULL);
489 rect = (Evas_Object *)evas_object_data_get(VIEW(it), "effect_rect");
492 evas_object_hide(VIEW(it));
496 // delete item and set focus to entry
497 if (sd->editable && elm_object_focus_get(WIDGET(it)))
498 elm_object_focus_set(sd->entry, EINA_TRUE);
500 elm_object_item_del((Elm_Object_Item *)it);
504 _after_rect_contract(Evas_Object *rect,
505 Elm_Multibuttonentry_Item *it)
507 Elm_Multibuttonentry_Item *last_item;
509 ELM_MULTIBUTTONENTRY_DATA_GET(WIDGET(it), sd);
511 evas_object_del(rect);
512 evas_object_data_set(VIEW(it), "effect_rect", NULL);
514 // if last item is unpacked, add it
515 last_item = eina_list_data_get(eina_list_last(sd->items));
518 if (!evas_object_visible_get(VIEW(last_item)))
520 elm_box_pack_end(sd->box, VIEW(last_item));
521 evas_object_show(VIEW(last_item));
527 elm_box_pack_end(sd->box, sd->entry);
528 evas_object_show(sd->entry);
529 if (elm_object_focus_get(WIDGET(it)))
530 elm_object_focus_set(sd->entry, EINA_TRUE);
535 _rect_contracting_animate(void *data)
539 Elm_Multibuttonentry_Item *it = data;
541 ELM_MULTIBUTTONENTRY_DATA_GET(WIDGET(it), sd);
543 rect = (Evas_Object *)evas_object_data_get(VIEW(it), "effect_rect");
544 if (!rect) return ECORE_CALLBACK_CANCEL;
546 evas_object_geometry_get(sd->entry, NULL, NULL, NULL, &eh);
547 evas_object_size_hint_min_get(rect, &w, &h);
552 _after_rect_contract(rect, it);
555 trans = (Elm_Transit *)evas_object_data_get(VIEW(it), "transit");
557 _on_item_contracting_transit_del(it, NULL);
559 return ECORE_CALLBACK_CANCEL;
562 evas_object_size_hint_min_set(rect, w, h - eh / ANIMATE_FRAME);
564 return ECORE_CALLBACK_RENEW;
568 _item_deleting_effect_add(Evas_Object *obj,
569 Elm_Multibuttonentry_Item *it)
574 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
576 _box_layout_pre_calculate(obj, it, NULL, &minh);
578 // if box will be contracted, add resizing effect
581 Evas_Coord bx, bw, ix, eh;
582 Ecore_Animator *anim;
584 Elm_Multibuttonentry_Item *last_it;
586 last_it = eina_list_data_get(eina_list_last(sd->items));
587 evas_object_geometry_get(sd->box, &bx, NULL, &bw, NULL);
588 evas_object_geometry_get(VIEW(last_it), &ix, NULL, NULL, NULL);
590 // if box will be contracted with item and entry
594 elm_box_unpack(sd->box, VIEW(it));
597 elm_box_unpack(sd->box, VIEW(last_it));
598 evas_object_hide(VIEW(last_it));
604 if (elm_object_focus_get(sd->entry))
605 elm_object_focus_set(sd->entry, EINA_FALSE);
606 elm_box_unpack(sd->box, sd->entry);
607 evas_object_hide(sd->entry);
608 elm_entry_input_panel_show(sd->entry);
611 rect = evas_object_rectangle_add(evas_object_evas_get(obj));
612 evas_object_color_set(rect, 0, 0, 0, 0);
614 evas_object_geometry_get(sd->entry, NULL, NULL, NULL, &eh);
615 evas_object_size_hint_min_set(rect, bw, eh);
616 evas_object_data_set(VIEW(it), "effect_rect", rect);
617 elm_box_pack_end(sd->box, rect);
618 evas_object_show(rect);
620 anim = ecore_animator_add(_rect_contracting_animate, it);
621 evas_object_data_set(rect, "animator", anim);
623 evas_object_size_hint_min_set(rect, bw, 0);
624 evas_object_data_set(VIEW(it), "effect_rect", rect);
625 elm_box_pack_end(sd->box, rect);
626 evas_object_show(rect);
628 _after_rect_contract(rect, it);
632 trans = elm_transit_add();
633 elm_transit_object_add(trans, VIEW(it));
634 elm_transit_effect_zoom_add(trans, 1.0, 0.9);
635 elm_transit_effect_color_add(trans, 255, 255, 255, 255, 0, 0, 0, 0);
636 elm_transit_del_cb_set(trans, _on_item_contracting_transit_del, it);
637 elm_transit_duration_set(trans, TRANSIT_DURATION);
638 evas_object_data_set(VIEW(it), "transit", trans);
639 elm_transit_go(trans);
645 _layout_expand(Evas_Object *obj)
647 int count, items_count, i;
649 Elm_Multibuttonentry_Item *it;
651 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
653 if (!sd->items) return;
654 if (sd->expanded_state) return;
656 children = elm_box_children_get(sd->box);
657 count = eina_list_count(children);
660 evas_object_del(sd->end);
664 if (sd->label && _label_packed(obj)) count--;
665 eina_list_free(children);
667 items_count = eina_list_count(sd->items);
668 for (i = count; i < items_count; i++)
670 it = eina_list_nth(sd->items, i);
671 elm_box_pack_end(sd->box, VIEW(it));
672 evas_object_show(VIEW(it));
677 elm_box_pack_end(sd->box, sd->entry);
678 evas_object_show(sd->entry);
681 sd->expanded_state = EINA_TRUE;
682 evas_object_smart_callback_call(obj, SIG_EXPAND_STATE_CHANGED, NULL);
686 _layout_shrink(Evas_Object *obj,
689 Evas_Coord w, mnw, linew = 0, hpad = 0;
690 int count = 0, items_count, i;
691 Eina_List *l, *children;
693 Elm_Multibuttonentry_Item *it;
697 Ecore_Animator *anim;
700 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
702 if (!sd->items) return;
703 if (!sd->expanded_state && !force) return;
705 evas_object_geometry_get(sd->box, NULL, NULL, &w, NULL);
706 elm_box_padding_get(sd->box, &hpad, NULL);
708 if (sd->label && _label_packed(obj))
710 evas_object_size_hint_min_get(sd->label, &mnw, NULL);
715 EINA_LIST_FOREACH(sd->items, l, it)
717 evas_object_size_hint_min_get(VIEW(it), &mnw, NULL);
732 items_count = eina_list_count(sd->items);
733 if (count < items_count)
735 const char *str = NULL;
738 str = elm_layout_data_get(obj, "closed_button_type");
741 sd->end = elm_layout_add(obj);
742 if (str && !strcmp(str, "image"))
743 elm_layout_theme_set(sd->end, "multibuttonentry",
744 "closedbutton", elm_widget_style_get(obj));
746 elm_layout_theme_set(sd->end, "multibuttonentry",
747 "number", elm_widget_style_get(obj));
749 if (!str || strcmp(str, "image"))
751 snprintf(buf, sizeof(buf), "+%d", items_count - count);
752 elm_object_text_set(sd->end, buf);
755 if (_elm_config->access_mode && sd->end)
757 _elm_access_object_register(obj, ELM_WIDGET_DATA(sd)->resize_obj);
758 _elm_access_callback_set(_elm_access_object_get(obj), ELM_ACCESS_INFO, _access_shrink_info_cb, obj);
761 evas_object_smart_calculate(sd->end);
762 evas_object_size_hint_min_get(sd->end, &mnw, NULL);
768 if (!str || strcmp(str, "image"))
770 snprintf(buf, sizeof(buf), "+%d", items_count - count);
771 elm_object_text_set(sd->end, buf);
774 if (_elm_config->access_mode && sd->end)
776 _elm_access_object_register(obj, ELM_WIDGET_DATA(sd)->resize_obj);
777 _elm_access_callback_set(_elm_access_object_get(obj), ELM_ACCESS_INFO, _access_shrink_info_cb, obj);
785 // reset last inserted item's effect_rect
786 it = eina_list_nth(sd->items, count - 1);
787 rect = (Evas_Object *)evas_object_data_get(VIEW(it), "effect_rect");
790 anim = (Ecore_Animator*)evas_object_data_get(rect, "animator");
791 if (anim) ecore_animator_del(anim);
793 evas_object_del(rect);
794 evas_object_data_set(VIEW(it), "effect_rect", NULL);
798 for (i = count; i < items_count; i++)
800 it = eina_list_nth(sd->items, i);
803 trans = (Elm_Transit *)evas_object_data_get(VIEW(it), "transit");
804 if (trans) elm_transit_del(trans);
806 rect = (Evas_Object *)evas_object_data_get(VIEW(it), "effect_rect");
809 anim = (Ecore_Animator*)evas_object_data_get(rect, "animator");
810 if (anim) ecore_animator_del(anim);
812 evas_object_del(rect);
813 evas_object_data_set(VIEW(it), "effect_rect", NULL);
816 elm_box_unpack(sd->box, VIEW(it));
817 evas_object_hide(VIEW(it));
822 elm_box_unpack(sd->box, sd->entry);
823 evas_object_hide(sd->entry);
828 // if it is called from item_append_xxx, item_del functions,
829 // all items are unpacked and packed again
831 // reset last inserted item's effect_rect
832 it = eina_list_nth(sd->items, count - 1);
833 rect = (Evas_Object *)evas_object_data_get(VIEW(it), "effect_rect");
836 anim = (Ecore_Animator*)evas_object_data_get(rect, "animator");
837 if (anim) ecore_animator_del(anim);
839 evas_object_del(rect);
840 evas_object_data_set(VIEW(it), "effect_rect", NULL);
843 for (i = count; i < items_count; i++)
845 it = eina_list_nth(sd->items, i);
847 trans = (Elm_Transit *)evas_object_data_get(VIEW(it), "transit");
848 if (trans) elm_transit_del(trans);
850 rect = (Evas_Object *)evas_object_data_get(VIEW(it), "effect_rect");
853 anim = (Ecore_Animator*)evas_object_data_get(rect, "animator");
854 if (anim) ecore_animator_del(anim);
856 evas_object_del(rect);
857 evas_object_data_set(VIEW(it), "effect_rect", NULL);
862 children = elm_box_children_get(sd->box);
863 EINA_LIST_FREE(children, child)
865 if (child != sd->label)
867 elm_box_unpack(sd->box, child);
868 evas_object_hide(child);
872 for (i = 0; i < count; i++)
874 it = eina_list_nth(sd->items, i);
875 elm_box_pack_end(sd->box, VIEW(it));
876 evas_object_show(VIEW(it));
880 elm_box_pack_end(sd->box, sd->end);
881 evas_object_show(sd->end);
883 sd->expanded_state = EINA_FALSE;
890 // reset last inserted item's effect_rect
891 it = eina_list_nth(sd->items, count - 1);
892 rect = (Evas_Object *)evas_object_data_get(VIEW(it), "effect_rect");
895 anim = (Ecore_Animator*)evas_object_data_get(rect, "animator");
896 if (anim) ecore_animator_del(anim);
898 evas_object_del(rect);
899 evas_object_data_set(VIEW(it), "effect_rect", NULL);
903 elm_box_pack_end(sd->box, sd->entry);
904 evas_object_show(sd->entry);
905 if (elm_object_focus_get(WIDGET(it)))
906 elm_object_focus_set(sd->entry, EINA_TRUE);
912 evas_object_size_hint_min_get(sd->entry, &mnw, NULL);
914 if (linew > (w * (2 / 3)))
916 elm_box_unpack(sd->box, sd->entry);
917 evas_object_hide(sd->entry);
918 sd->expanded_state = EINA_FALSE;
926 evas_object_del(sd->end);
930 // if it is called from item_append_xxx, item_del functions,
931 // all items are unpacked and packed again
933 // reset last inserted item's effect_rect
934 it = eina_list_nth(sd->items, count - 1);
935 rect = (Evas_Object *)evas_object_data_get(VIEW(it), "effect_rect");
938 anim = (Ecore_Animator*)evas_object_data_get(rect, "animator");
939 if (anim) ecore_animator_del(anim);
941 evas_object_del(rect);
942 evas_object_data_set(VIEW(it), "effect_rect", NULL);
946 children = elm_box_children_get(sd->box);
947 EINA_LIST_FREE(children, child)
949 if (child != sd->label)
951 elm_box_unpack(sd->box, child);
952 evas_object_hide(child);
956 for (i = 0; i < count; i++)
958 it = eina_list_nth(sd->items, i);
959 elm_box_pack_end(sd->box, VIEW(it));
960 evas_object_show(VIEW(it));
963 sd->expanded_state = EINA_TRUE;
967 evas_object_size_hint_min_get(sd->entry, &mnw, NULL);
970 sd->expanded_state = EINA_FALSE;
973 elm_box_pack_end(sd->box, sd->entry);
974 evas_object_show(sd->entry);
980 if (!sd->expanded_state && !force)
981 evas_object_smart_callback_call(obj, SIG_EXPAND_STATE_CHANGED, NULL);
985 _box_min_size_calculate(Evas_Object *box,
986 Evas_Object_Box_Data *priv,
990 Evas_Coord mnw, mnh, w, minw, minh = 0, linew = 0, lineh = 0;
993 Evas_Object_Box_Option *opt;
995 ELM_MULTIBUTTONENTRY_DATA_GET(data, sd);
997 evas_object_geometry_get(box, NULL, NULL, &w, NULL);
998 evas_object_size_hint_min_get(box, &minw, NULL);
999 if (!w) return EINA_FALSE;
1002 EINA_LIST_FOREACH(priv->children, l, opt)
1004 evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
1008 !strcmp(evas_object_type_get(opt->obj), "rectangle"))
1013 if (lineh < mnh) lineh = mnh;
1020 else if (linew > w * 2 / 3)
1022 // if linew is larger than 2/3 of boxw, box should be larger.
1025 // whether there is "+%d" at the end of the box or entry is invisible,
1026 // box doesn't have to be larger.
1027 if (sd->end || !evas_object_visible_get(sd->entry))
1031 if (l != eina_list_last(priv->children))
1032 linew += priv->pad.h;
1035 minh = lineh * line_num + (line_num - 1) * priv->pad.v;
1038 // if last item is effect_rect
1039 if (opt && opt->obj && mnw == w &&
1040 !strcmp(evas_object_type_get(opt->obj), "rectangle"))
1042 minh += priv->pad.v;
1047 evas_object_size_hint_min_set(box, minw, minh);
1048 *line_height = lineh;
1054 _box_layout(Evas_Object *o,
1055 Evas_Object_Box_Data *priv,
1058 Evas_Coord x, y, w, h, xx, yy, xxx, yyy;
1059 Evas_Coord minw, minh, linew = 0, lineh = 0, lineww = 0;
1064 Evas_Object_Box_Option *opt;
1066 ELM_MULTIBUTTONENTRY_DATA_GET(data, sd);
1068 if (!_box_min_size_calculate(o, priv, &lineh, data)) return;
1070 evas_object_geometry_get(o, &x, &y, &w, &h);
1071 evas_object_size_hint_min_get(o, &minw, &minh);
1072 evas_object_size_hint_align_get(o, &ax, &ay);
1074 rtl = elm_widget_mirrored_get(data);
1075 if (rtl) ax = 1.0 - ax;
1079 x = x + ((w - minw) * (1.0 - ax));
1084 y = y + ((h - minh) * (1.0 - ay));
1090 EINA_LIST_FOREACH(priv->children, l, opt)
1092 Evas_Coord mnw, mnh, ww, hh, ow, oh;
1094 Eina_Bool fw, fh, xw, xh;
1097 evas_object_size_hint_align_get(obj, &ax, &ay);
1098 evas_object_size_hint_weight_get(obj, &wx, &wy);
1099 evas_object_size_hint_min_get(obj, &mnw, &mnh);
1101 fw = fh = EINA_FALSE;
1102 xw = xh = EINA_FALSE;
1103 if (ax == -1.0) {fw = EINA_TRUE; ax = 0.5;}
1104 if (ay == -1.0) {fh = EINA_TRUE; ay = 0.5;}
1105 if (rtl) ax = 1.0 - ax;
1106 if (wx > 0.0) xw = EINA_TRUE;
1107 if (wy > 0.0) xh = EINA_TRUE;
1112 if (ww <= w - linew) ww = w - linew;
1123 if (linew > w && l != priv->children)
1130 linew += priv->pad.h;
1132 evas_object_move(obj,
1133 ((!rtl) ? (xx) : (x + (w - (xx - x) - ww)))
1134 + (Evas_Coord)(((double)(ww - ow)) * ax),
1135 yy + (Evas_Coord)(((double)(hh - oh)) * ay));
1136 evas_object_resize(obj, ow, oh);
1144 // if linew is bigger than 2/3 of boxw, entry goes to next line.
1145 if (linew > w * 2 / 3)
1153 // whether there is "+%d" at the end of the box or entry is invisible,
1154 // box doesn't have to be larger.
1155 if (sd->end || !evas_object_visible_get(sd->entry))
1165 _on_box_resize(void *data,
1168 void *event_info __UNUSED__)
1172 ELM_MULTIBUTTONENTRY_DATA_GET(data, sd);
1174 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1177 evas_object_smart_callback_call(data, SIG_EXPANDED, NULL);
1178 else if (sd->boxh > h)
1179 evas_object_smart_callback_call(data, SIG_CONTRACTED, NULL);
1181 // on rotation, items should be packed again in the shrinked layout
1182 if (sd->boxw && sd->boxw != w)
1184 if (!elm_object_focus_get(data) && !sd->expanded)
1185 _layout_shrink(data, EINA_TRUE);
1192 static Elm_Multibuttonentry_Item_Filter *
1193 _filter_new(Elm_Multibuttonentry_Item_Filter_Cb func,
1196 Elm_Multibuttonentry_Item_Filter *ft;
1198 ft = ELM_NEW(Elm_Multibuttonentry_Item_Filter);
1199 if (!ft) return NULL;
1208 _on_item_clicked(void *data,
1209 Evas_Object *obj __UNUSED__,
1210 const char *emission __UNUSED__,
1211 const char *source __UNUSED__)
1213 Elm_Multibuttonentry_Item *it = data;
1215 ELM_MULTIBUTTONENTRY_DATA_GET(WIDGET(it), sd);
1217 evas_object_focus_set(elm_layout_edje_get(VIEW(it)), EINA_TRUE);
1219 // handles input panel because it can be hidden by user
1221 elm_entry_input_panel_show(sd->entry);
1223 evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_CLICKED, it);
1227 _on_item_selected(void *data,
1228 Evas_Object *obj __UNUSED__,
1229 const char *emission __UNUSED__,
1230 const char *source __UNUSED__)
1232 Elm_Multibuttonentry_Item *it = data;
1234 if (it->func) it->func((void *)it->base.data, WIDGET(it), it);
1236 evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_SELECTED, it);
1240 _on_item_focus(void *data,
1243 void *event_info __UNUSED__)
1245 Elm_Multibuttonentry_Item *it = data;
1247 ELM_MULTIBUTTONENTRY_DATA_GET(WIDGET(it), sd);
1249 if (evas_object_focus_get(obj))
1251 if (elm_object_focus_get(sd->entry))
1252 elm_object_focus_set(sd->entry, EINA_FALSE);
1254 sd->selected_item = (Elm_Object_Item *)it;
1255 elm_layout_signal_emit(VIEW(it), "focused", "");
1258 elm_entry_input_panel_show(sd->entry);
1262 sd->selected_item = NULL;
1263 elm_layout_signal_emit(VIEW(it), "default", "");
1266 elm_entry_input_panel_hide(sd->entry);
1271 _long_press_cb(void *data)
1273 Elm_Multibuttonentry_Item *it = data;
1275 ELM_MULTIBUTTONENTRY_DATA_GET(WIDGET(it), sd);
1277 sd->longpress_timer = NULL;
1278 sd->long_pressed = EINA_TRUE;
1280 evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1282 return ECORE_CALLBACK_CANCEL;
1286 _mouse_down_cb(Elm_Multibuttonentry_Item *it,
1287 Evas *evas __UNUSED__,
1288 Evas_Object *obj __UNUSED__,
1289 Evas_Event_Mouse_Down *ev)
1291 ELM_MULTIBUTTONENTRY_DATA_GET(WIDGET(it), sd);
1293 if (ev->button != 1) return;
1295 sd->long_pressed = EINA_FALSE;
1297 if (sd->longpress_timer) ecore_timer_del(sd->longpress_timer);
1298 sd->longpress_timer = ecore_timer_add
1299 (_elm_config->longpress_timeout, _long_press_cb, it);
1303 _mouse_up_cb(Elm_Multibuttonentry_Item *it,
1304 Evas *evas __UNUSED__,
1305 Evas_Object *obj __UNUSED__,
1306 Evas_Event_Mouse_Down *ev __UNUSED__)
1308 ELM_MULTIBUTTONENTRY_DATA_GET(WIDGET(it), sd);
1310 if (sd->longpress_timer)
1312 ecore_timer_del(sd->longpress_timer);
1313 sd->longpress_timer = NULL;
1318 _item_text_set_hook(Elm_Object_Item *it,
1322 if (part && strcmp(part, "elm.btn.text")) return;
1325 elm_object_part_text_set(VIEW(it), "elm.btn.text", text);
1329 _item_text_get_hook(const Elm_Object_Item *it,
1332 if (part && strcmp(part, "elm.btn.text")) return NULL;
1334 return elm_object_part_text_get(VIEW(it), "elm.btn.text");
1338 _item_del_pre_hook(Elm_Object_Item *it)
1340 ELM_MULTIBUTTONENTRY_DATA_GET(WIDGET(it), sd);
1342 sd->items = eina_list_remove(sd->items, it);
1344 if (!elm_object_focus_get(WIDGET(it)) && !sd->expanded)
1345 _layout_shrink(WIDGET(it), EINA_TRUE);
1351 trans = (Elm_Transit *)evas_object_data_get(VIEW(it), "transit");
1354 elm_transit_del_cb_set(trans, NULL, NULL);
1355 elm_transit_del(trans);
1358 rect = (Evas_Object *)evas_object_data_get(VIEW(it), "effect_rect");
1361 Ecore_Animator *anim;
1362 anim = (Ecore_Animator*)evas_object_data_get(rect, "animator");
1363 if (anim) ecore_animator_del(anim);
1365 evas_object_del(rect);
1366 evas_object_data_set(VIEW(it), "effect_rect", NULL);
1370 elm_box_pack_end(sd->box, sd->entry);
1371 evas_object_show(sd->entry);
1372 if (elm_object_focus_get(WIDGET(it)))
1373 elm_object_focus_set(sd->entry, EINA_TRUE);
1378 if (!sd->items && !elm_object_focus_get(WIDGET(it)) &&
1379 sd->guide && !_guide_packed(WIDGET(it)))
1383 elm_box_unpack(sd->box, sd->entry);
1384 evas_object_hide(sd->entry);
1387 elm_box_pack_end(sd->box, sd->guide);
1388 evas_object_show(sd->guide);
1391 evas_object_smart_callback_call(WIDGET(it), SIG_ITEM_DELETED, it);
1397 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
1399 Elm_Multibuttonentry_Item *it = (Elm_Multibuttonentry_Item *)data;
1400 const char *txt = NULL;
1401 Eina_Strbuf *buf = NULL;
1404 if (!it) return NULL;
1406 if (!txt)txt = elm_object_item_text_get((Elm_Object_Item *)it);
1409 buf = eina_strbuf_new();
1410 eina_strbuf_append(buf, E_(" double tap to edit"));
1411 eina_strbuf_prepend(buf, txt);
1412 str = eina_strbuf_string_steal(buf);
1413 eina_strbuf_free(buf);
1421 _access_state_cb(void *data, Evas_Object *obj __UNUSED__)
1423 Elm_Multibuttonentry_Item *it = (Elm_Multibuttonentry_Item *)data;
1424 if (!it) return NULL;
1426 if (it->base.disabled)
1427 return strdup(E_("State: Disabled"));
1433 _access_activate_cb(void *data __UNUSED__,
1434 Evas_Object *part_obj __UNUSED__,
1435 Elm_Object_Item *item)
1437 _on_item_selected(item, NULL, NULL, NULL);
1441 _access_widget_item_register(Elm_Multibuttonentry_Item *it, Eina_Bool is_access)
1443 Elm_Access_Info *ai;
1445 if (!is_access) _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
1448 _elm_access_widget_item_register((Elm_Widget_Item *)it);
1450 ai = _elm_access_object_get(it->base.access_obj);
1452 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1453 _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
1454 _elm_access_activate_callback_set(ai, _access_activate_cb, it);
1458 static Elm_Multibuttonentry_Item *
1459 _item_new(Evas_Object *obj,
1464 Elm_Multibuttonentry_Item *it;
1465 Elm_Multibuttonentry_Item_Filter *ft;
1468 Evas_Coord minw, minh, maxw = 0;
1470 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
1472 EINA_LIST_FOREACH(sd->filters, l, ft)
1474 if (!ft->func(obj, text, data, ft->data))
1478 it = elm_widget_item_new(obj, Elm_Multibuttonentry_Item);
1479 if (!it) return NULL;
1481 VIEW(it) = elm_layout_add(obj);
1482 elm_layout_theme_set
1483 (VIEW(it), "multibuttonentry", "btn", elm_widget_style_get(obj));
1484 elm_layout_signal_callback_add
1485 (VIEW(it), "elm,action,clicked", "", _on_item_clicked, it);
1486 elm_layout_signal_callback_add
1487 (VIEW(it), "elm,action,selected", "", _on_item_selected, it);
1488 evas_object_event_callback_add
1489 (elm_layout_edje_get(VIEW(it)),
1490 EVAS_CALLBACK_FOCUS_IN, _on_item_focus, it);
1491 evas_object_event_callback_add
1492 (elm_layout_edje_get(VIEW(it)),
1493 EVAS_CALLBACK_FOCUS_OUT, _on_item_focus, it);
1494 evas_object_event_callback_add
1495 (elm_layout_edje_get(VIEW(it)),
1496 EVAS_CALLBACK_MOUSE_DOWN, (Evas_Object_Event_Cb)_mouse_down_cb, it);
1497 evas_object_event_callback_add
1498 (elm_layout_edje_get(VIEW(it)),
1499 EVAS_CALLBACK_MOUSE_UP, (Evas_Object_Event_Cb)_mouse_up_cb, it);
1500 elm_object_part_text_set(VIEW(it), "elm.btn.text", text);
1503 it->base.data = data;
1505 // adjust item size if item is longer than maximum size
1506 evas_object_smart_calculate(VIEW(it));
1507 evas_object_size_hint_min_get(VIEW(it), &minw, &minh);
1508 str = elm_layout_data_get(VIEW(it), "button_max_size");
1509 if (str) maxw = atoi(str);
1510 maxw = maxw * elm_widget_scale_get(obj) * elm_config_scale_get();
1513 elm_layout_signal_emit(VIEW(it), "elm,state,text,ellipsis", "");
1514 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1515 evas_object_size_hint_min_set(VIEW(it), maxw, minh);
1516 elm_layout_sizing_eval(VIEW(it));
1519 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1520 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1521 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1523 sd->item_be_selected = EINA_TRUE;
1526 if (_elm_config->access_mode) _access_widget_item_register(it, EINA_TRUE);
1532 _on_entry_unfocused(void *data,
1534 void *event_info __UNUSED__)
1538 ELM_MULTIBUTTONENTRY_DATA_GET(data, sd);
1540 str = elm_entry_markup_to_utf8(elm_object_text_get(obj));
1543 Elm_Multibuttonentry_Item *it;
1545 it = _item_new(data, str, NULL, NULL);
1548 sd->items = eina_list_append(sd->items, it);
1550 _item_adding_effect_add(data, it);
1552 elm_box_pack_before(sd->box, VIEW(it), obj);
1553 evas_object_show(VIEW(it));
1554 evas_object_smart_callback_call(data, SIG_ITEM_ADDED, it);
1557 elm_object_text_set(obj, "");
1562 // handles semicolon, comma (before inserting them to the entry)
1564 _entry_filter(void *data,
1570 ELM_MULTIBUTTONENTRY_DATA_GET(data, sd);
1572 if (!*text || !strlen(*text)) return;
1574 // cancels item_be_selected when text inserting is started
1575 if (strcmp(*text, ";") && strcmp(*text, ","))
1577 sd->item_be_selected = EINA_FALSE;
1581 str = elm_entry_markup_to_utf8(elm_object_text_get(entry));
1584 Elm_Multibuttonentry_Item *it;
1586 it = _item_new(data, str, NULL, NULL);
1589 sd->items = eina_list_append(sd->items, it);
1591 _item_adding_effect_add(data, it);
1593 elm_box_pack_before(sd->box, VIEW(it), entry);
1594 evas_object_show(VIEW(it));
1595 evas_object_smart_callback_call(data, SIG_ITEM_ADDED, it);
1598 elm_object_text_set(entry, "");
1606 // handles enter key
1608 _on_entry_key_down(void *data,
1614 Evas_Event_Key_Up *ev = (Evas_Event_Key_Up *)event_info;
1616 ELM_MULTIBUTTONENTRY_DATA_GET(data, sd);
1618 // cancels item_be_selected when text inserting is started
1619 if (strcmp(ev->keyname, "KP_Enter") && strcmp(ev->keyname, "Return") &&
1620 strcmp(ev->keyname, "BackSpace") && strcmp(ev->keyname, "Delete") &&
1621 strcmp(ev->keyname, "semicolon") && strcmp(ev->keyname, "comma"))
1623 sd->item_be_selected = EINA_FALSE;
1627 if (!strcmp(ev->keyname, "KP_Enter") || !strcmp(ev->keyname, "Return"))
1629 str = elm_entry_markup_to_utf8(elm_object_text_get(obj));
1632 Elm_Multibuttonentry_Item *it;
1634 it = _item_new(data, str, NULL, NULL);
1637 sd->items = eina_list_append(sd->items, it);
1639 _item_adding_effect_add(data, it);
1641 elm_box_pack_before(sd->box, VIEW(it), obj);
1642 evas_object_show(VIEW(it));
1643 evas_object_smart_callback_call(data, SIG_ITEM_ADDED, it);
1646 elm_object_text_set(obj, "");
1652 // handles delete key
1653 // it can be pressed when button is selected, so it is handled on layout_key_down
1655 _on_layout_key_down(void *data __UNUSED__,
1661 Evas_Event_Key_Up *ev = (Evas_Event_Key_Up *)event_info;
1663 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
1665 if (strcmp(ev->keyname, "BackSpace") && strcmp(ev->keyname, "Delete"))
1668 str = elm_entry_markup_to_utf8(elm_object_text_get(sd->entry));
1676 if (!sd->items) return;
1678 if (!sd->selected_item)
1680 if (sd->item_be_selected) // 2nd delete
1682 Elm_Multibuttonentry_Item *it;
1684 it = eina_list_data_get(eina_list_last(sd->items));
1685 evas_object_focus_set(elm_layout_edje_get(VIEW(it)), EINA_TRUE);
1688 sd->item_be_selected = EINA_TRUE;
1696 trans = (Elm_Transit *)evas_object_data_get(VIEW(sd->selected_item), "transit");
1697 rect = (Evas_Object *)evas_object_data_get(VIEW(sd->selected_item), "effect_rect");
1699 if (!trans && !rect)
1700 _item_deleting_effect_add
1701 (obj, (Elm_Multibuttonentry_Item *)sd->selected_item);
1703 elm_object_item_del(sd->selected_item);
1706 elm_object_focus_set(sd->entry, EINA_TRUE);
1712 _on_layout_clicked(void *data __UNUSED__,
1714 const char *emission __UNUSED__,
1715 const char *source __UNUSED__)
1717 evas_object_smart_callback_call(obj, SIG_CLICKED, NULL);
1721 _elm_multibuttonentry_smart_on_focus(Evas_Object *obj)
1723 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
1725 if (!ELM_WIDGET_CLASS(_elm_multibuttonentry_parent_sc)->on_focus(obj))
1728 if (elm_object_focus_get(obj))
1731 //if ((_elm_config->access_mode == ELM_ACCESS_MODE_ON)) return EINA_TRUE;
1733 if (sd->guide && _guide_packed(obj))
1735 elm_box_unpack(sd->box, sd->guide);
1736 evas_object_hide(sd->guide);
1740 elm_box_pack_end(sd->box, sd->entry);
1741 evas_object_show(sd->entry);
1744 // when object gets focused, it should be expanded layout
1745 else if (!sd->expanded)
1746 _layout_expand(obj);
1750 elm_layout_signal_emit(obj, "elm,state,event,allow", "");
1751 elm_object_focus_set(sd->entry, EINA_TRUE);
1754 evas_object_smart_callback_call(obj, SIG_FOCUSED, NULL);
1758 if (!sd->items && sd->guide)
1762 elm_box_unpack(sd->box, sd->entry);
1763 evas_object_hide(sd->entry);
1766 elm_box_pack_end(sd->box, sd->guide);
1767 evas_object_show(sd->guide);
1769 // if shrinked mode was set, it goes back to shrinked layout
1770 else if (!sd->expanded)
1771 _layout_shrink(obj, EINA_FALSE);
1774 elm_layout_signal_emit(obj, "elm,state,event,block", "");
1776 if (sd->selected_item)
1777 evas_object_focus_set
1778 (elm_layout_edje_get(VIEW(sd->selected_item)), EINA_FALSE);
1780 evas_object_smart_callback_call(obj, SIG_UNFOCUSED, NULL);
1787 _elm_multibuttonentry_smart_text_set(Evas_Object *obj,
1791 if (!part || (part && !strcmp(part, "label")))
1793 if (text) _label_set(obj, text);
1796 else if (part && !strcmp(part, "guide"))
1798 if (text) _guide_set(obj, text);
1801 else return _elm_multibuttonentry_parent_sc->text_set(obj, part, text);
1805 _elm_multibuttonentry_smart_text_get(const Evas_Object *obj,
1808 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
1810 if (!part || !strcmp(part, "label"))
1811 return elm_object_part_text_get(sd->label, "mbe.label");
1812 else if (!strcmp(part, "guide"))
1813 return elm_object_text_get(sd->guide);
1814 else return _elm_multibuttonentry_parent_sc->text_get(obj, part);
1818 _elm_multibuttonentry_smart_sizing_eval(Evas_Object *obj)
1820 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
1822 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
1824 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1825 edje_object_size_min_restricted_calc
1826 (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh);
1827 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1828 evas_object_size_hint_min_set(obj, minw, minh);
1829 evas_object_size_hint_max_set(obj, maxw, maxh);
1833 _elm_multibuttonentry_smart_theme(Evas_Object *obj)
1836 int hpad = 0, vpad = 0;
1838 Elm_Multibuttonentry_Item *it;
1840 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
1842 if (!ELM_WIDGET_CLASS(_elm_multibuttonentry_parent_sc)->theme(obj))
1845 str = elm_layout_data_get(obj, "horizontal_pad");
1846 if (str) hpad = atoi(str);
1847 str = elm_layout_data_get(obj, "vertical_pad");
1848 if (str) vpad = atoi(str);
1851 hpad * elm_widget_scale_get(obj) * elm_config_scale_get(),
1852 vpad * elm_widget_scale_get(obj) * elm_config_scale_get());
1854 elm_layout_theme_set
1855 (sd->label, "multibuttonentry", "label", elm_widget_style_get(obj));
1856 elm_layout_theme_set
1857 (sd->guide, "multibuttonentry", "guidetext", elm_widget_style_get(obj));
1858 elm_layout_theme_set
1859 (sd->end, "multibuttonentry", "number", elm_widget_style_get(obj));
1860 EINA_LIST_FOREACH(sd->items, l, it)
1861 elm_layout_theme_set
1862 (VIEW(it), "multibuttonentry", "btn", elm_widget_style_get(obj));
1864 elm_layout_sizing_eval(obj);
1870 _elm_multibuttonentry_smart_add(Evas_Object *obj)
1873 int hpad = 0, vpad = 0;
1875 EVAS_SMART_DATA_ALLOC(obj, Elm_Multibuttonentry_Smart_Data);
1877 ELM_WIDGET_CLASS(_elm_multibuttonentry_parent_sc)->base.add(obj);
1878 elm_layout_theme_set
1879 (obj, "multibuttonentry", "base", elm_widget_style_get(obj));
1880 elm_layout_signal_callback_add
1881 (obj, "elm,action,clicked", "", _on_layout_clicked, NULL);
1882 evas_object_event_callback_add
1883 (obj, EVAS_CALLBACK_KEY_DOWN, _on_layout_key_down, NULL);
1885 priv->box = elm_box_add(obj);
1886 str = elm_layout_data_get(obj, "horizontal_pad");
1887 if (str) hpad = atoi(str);
1888 str = elm_layout_data_get(obj, "vertical_pad");
1889 if (str) vpad = atoi(str);
1892 hpad * elm_widget_scale_get(obj) * elm_config_scale_get(),
1893 vpad * elm_widget_scale_get(obj) * elm_config_scale_get());
1894 elm_box_layout_set(priv->box, _box_layout, obj, NULL);
1895 elm_layout_content_set(obj, "box.swallow", priv->box);
1896 evas_object_event_callback_add
1897 (priv->box, EVAS_CALLBACK_RESIZE, _on_box_resize, obj);
1899 priv->entry = elm_entry_add(obj);
1900 elm_entry_single_line_set(priv->entry, EINA_TRUE);
1901 elm_entry_scrollable_set(priv->entry, EINA_TRUE);
1902 elm_entry_cnp_mode_set(priv->entry, ELM_CNP_MODE_PLAINTEXT);
1903 evas_object_size_hint_weight_set
1904 (priv->entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1905 evas_object_size_hint_align_set
1906 (priv->entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
1907 evas_object_event_callback_add
1908 (priv->entry, EVAS_CALLBACK_KEY_DOWN, _on_entry_key_down, obj);
1909 evas_object_smart_callback_add
1910 (priv->entry, "unfocused", _on_entry_unfocused, obj);
1911 elm_entry_markup_filter_append(priv->entry, _entry_filter, obj);
1912 elm_box_pack_end(priv->box, priv->entry);
1913 evas_object_show(priv->entry);
1915 elm_widget_can_focus_set(obj, EINA_TRUE);
1917 priv->editable = EINA_TRUE;
1918 priv->expanded = EINA_TRUE;
1919 priv->expanded_state = EINA_TRUE;
1923 _elm_access_object_register(obj, ELM_WIDGET_DATA(priv)->resize_obj);
1924 _elm_access_text_set
1925 (_elm_access_object_get(obj), ELM_ACCESS_TYPE, E_("multi button entry"));
1926 _elm_access_callback_set
1927 (_elm_access_object_get(obj), ELM_ACCESS_INFO, _access_info_cb, NULL);
1932 _elm_multibuttonentry_smart_del(Evas_Object *obj)
1934 Elm_Multibuttonentry_Item *it;
1935 Elm_Multibuttonentry_Item_Filter *ft;
1937 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
1940 EINA_LIST_FREE(sd->items, it)
1945 trans = (Elm_Transit *)evas_object_data_get(VIEW(it), "transit");
1948 elm_transit_del_cb_set(trans, NULL, NULL);
1949 elm_transit_del(trans);
1952 rect = (Evas_Object *)evas_object_data_get(VIEW(it), "effect_rect");
1955 Ecore_Animator *anim;
1956 anim = (Ecore_Animator*)evas_object_data_get(rect, "animator");
1957 if (anim) ecore_animator_del(anim);
1959 evas_object_del(rect);
1960 evas_object_data_set(VIEW(it), "effect_rect", NULL);
1962 elm_widget_item_free(it);
1965 EINA_LIST_FREE(sd->items, it)
1966 elm_widget_item_free(it);
1969 EINA_LIST_FREE(sd->filters, ft)
1972 if (sd->end) evas_object_del(sd->end);
1973 if (sd->guide) evas_object_del(sd->guide);
1974 if (sd->label) evas_object_del(sd->label);
1975 if (sd->entry) evas_object_del(sd->entry);
1976 if (sd->box) evas_object_del(sd->box);
1977 if (sd->longpress_timer) ecore_timer_del(sd->longpress_timer);
1979 ELM_WIDGET_CLASS(_elm_multibuttonentry_parent_sc)->base.del(obj);
1983 _elm_multibuttonentry_smart_access(Evas_Object *obj, Eina_Bool is_access)
1985 Eina_List *elist = NULL;
1986 Elm_Multibuttonentry_Item *it;
1988 ELM_MULTIBUTTONENTRY_CHECK(obj);
1989 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
1991 EINA_LIST_FOREACH(sd->items, elist, it)
1992 _access_widget_item_register(it, is_access);
1996 _elm_multibuttonentry_smart_set_user(Elm_Multibuttonentry_Smart_Class *sc)
1998 ELM_WIDGET_CLASS(sc)->base.add = _elm_multibuttonentry_smart_add;
1999 ELM_WIDGET_CLASS(sc)->base.del = _elm_multibuttonentry_smart_del;
2001 ELM_WIDGET_CLASS(sc)->theme = _elm_multibuttonentry_smart_theme;
2002 ELM_WIDGET_CLASS(sc)->on_focus = _elm_multibuttonentry_smart_on_focus;
2004 /* not a 'focus chain manager' */
2005 ELM_WIDGET_CLASS(sc)->focus_next = NULL;
2006 ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
2008 ELM_LAYOUT_CLASS(sc)->text_set = _elm_multibuttonentry_smart_text_set;
2009 ELM_LAYOUT_CLASS(sc)->text_get = _elm_multibuttonentry_smart_text_get;
2011 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_multibuttonentry_smart_sizing_eval;
2014 if (_elm_config->access_mode)
2015 ELM_WIDGET_CLASS(sc)->focus_next = _elm_multibuttonentry_smart_focus_next;
2017 ELM_WIDGET_CLASS(sc)->access = _elm_multibuttonentry_smart_access;
2020 EAPI const Elm_Multibuttonentry_Smart_Class *
2021 elm_multibuttonentry_smart_class_get(void)
2023 static Elm_Multibuttonentry_Smart_Class _sc =
2024 ELM_MULTIBUTTONENTRY_SMART_CLASS_INIT_NAME_VERSION
2025 (ELM_MULTIBUTTONENTRY_SMART_NAME);
2026 static const Elm_Multibuttonentry_Smart_Class *class = NULL;
2027 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
2029 if (class) return class;
2031 _elm_multibuttonentry_smart_set(&_sc);
2032 esc->callbacks = _smart_callbacks;
2039 elm_multibuttonentry_add(Evas_Object *parent)
2043 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
2045 obj = elm_widget_add(_elm_multibuttonentry_smart_class_new(), parent);
2046 if (!obj) return NULL;
2048 if (!elm_widget_sub_object_add(parent, obj))
2049 ERR("could not add %p as sub object of %p", obj, parent);
2055 elm_multibuttonentry_entry_get(const Evas_Object *obj)
2057 ELM_MULTIBUTTONENTRY_CHECK(obj) NULL;
2058 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2064 elm_multibuttonentry_expanded_set(Evas_Object *obj,
2067 ELM_MULTIBUTTONENTRY_CHECK(obj);
2068 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2070 expanded = !!expanded;
2071 if (sd->expanded == expanded) return;
2072 sd->expanded = expanded;
2074 if (elm_object_focus_get(obj)) return;
2077 _layout_expand(obj);
2079 _layout_shrink(obj, EINA_FALSE);
2083 elm_multibuttonentry_expanded_get(const Evas_Object *obj)
2085 ELM_MULTIBUTTONENTRY_CHECK(obj) EINA_FALSE;
2086 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2088 return (elm_object_focus_get(obj) || sd->expanded);
2092 elm_multibuttonentry_editable_set(Evas_Object *obj,
2095 ELM_MULTIBUTTONENTRY_CHECK(obj);
2096 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2098 editable = !!editable;
2099 if (sd->editable == editable) return;
2100 sd->editable = editable;
2104 if (!(sd->guide && _guide_packed(obj)))
2106 elm_box_pack_end(sd->box, sd->entry);
2107 evas_object_show(sd->entry);
2110 if (!elm_object_focus_get(obj))
2111 elm_layout_signal_emit(obj, "elm,state,event,block", "");
2115 if (!(sd->guide && _guide_packed(obj)))
2117 elm_box_unpack(sd->box, sd->entry);
2118 evas_object_hide(sd->entry);
2121 if (!elm_object_focus_get(obj))
2122 elm_layout_signal_emit(obj, "elm,state,event,allow", "");
2127 elm_multibuttonentry_editable_get(const Evas_Object *obj)
2129 ELM_MULTIBUTTONENTRY_CHECK(obj) EINA_FALSE;
2130 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2132 return sd->editable;
2135 EAPI Elm_Object_Item *
2136 elm_multibuttonentry_item_prepend(Evas_Object *obj,
2141 Elm_Multibuttonentry_Item *it;
2143 ELM_MULTIBUTTONENTRY_CHECK(obj) NULL;
2144 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2146 if (!label) return NULL;
2148 // if guide text was shown, hide it
2149 if (sd->guide && _guide_packed(obj))
2151 elm_box_unpack(sd->box, sd->guide);
2152 evas_object_hide(sd->guide);
2156 elm_box_pack_end(sd->box, sd->entry);
2157 evas_object_show(sd->entry);
2161 it = _item_new(obj, label, func, data);
2162 if (!it) return NULL;
2164 sd->items = eina_list_prepend(sd->items, it);
2166 if (!elm_object_focus_get(obj) && !sd->expanded && sd->boxw)
2169 _item_adding_effect_add(obj, it);
2171 _layout_shrink(obj, EINA_TRUE);
2176 if (sd->boxh && sd->boxw)
2177 _item_adding_effect_add(obj, it);
2180 if (sd->label && _label_packed(obj))
2181 elm_box_pack_after(sd->box, VIEW(it), sd->label);
2183 elm_box_pack_start(sd->box, VIEW(it));
2184 evas_object_show(VIEW(it));
2187 if (sd->label && _label_packed(obj))
2188 elm_box_pack_after(sd->box, VIEW(it), sd->label);
2190 elm_box_pack_start(sd->box, VIEW(it));
2191 evas_object_show(VIEW(it));
2196 if (!sd->boxh || !sd->boxw)
2197 evas_object_smart_callback_call(obj, SIG_ITEM_ADDED, it);
2199 evas_object_smart_callback_call(obj, SIG_ITEM_ADDED, it);
2202 return (Elm_Object_Item *)it;
2205 EAPI Elm_Object_Item *
2206 elm_multibuttonentry_item_append(Evas_Object *obj,
2211 Elm_Multibuttonentry_Item *it;
2213 ELM_MULTIBUTTONENTRY_CHECK(obj) NULL;
2214 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2216 if (!label) return NULL;
2218 // if guide text was shown, hide it
2219 if (sd->guide && _guide_packed(obj))
2221 elm_box_unpack(sd->box, sd->guide);
2222 evas_object_hide(sd->guide);
2226 elm_box_pack_end(sd->box, sd->entry);
2227 evas_object_show(sd->entry);
2231 it = _item_new(obj, label, func, data);
2232 if (!it) return NULL;
2234 sd->items = eina_list_append(sd->items, it);
2236 if (!elm_object_focus_get(obj) && !sd->expanded && sd->boxw)
2239 _item_adding_effect_add(obj, it);
2241 _layout_shrink(obj, EINA_TRUE);
2246 if (sd->boxh && sd->boxw)
2247 _item_adding_effect_add(obj, it);
2251 elm_box_pack_before(sd->box, VIEW(it), sd->entry);
2253 elm_box_pack_end(sd->box, VIEW(it));
2254 evas_object_show(VIEW(it));
2258 elm_box_pack_before(sd->box, VIEW(it), sd->entry);
2260 elm_box_pack_end(sd->box, VIEW(it));
2261 evas_object_show(VIEW(it));
2266 if (!sd->boxh || !sd->boxw)
2267 evas_object_smart_callback_call(obj, SIG_ITEM_ADDED, it);
2269 evas_object_smart_callback_call(obj, SIG_ITEM_ADDED, it);
2272 return (Elm_Object_Item *)it;
2275 EAPI Elm_Object_Item *
2276 elm_multibuttonentry_item_insert_before(Evas_Object *obj,
2277 Elm_Object_Item *before,
2282 Elm_Multibuttonentry_Item *it;
2284 ELM_MULTIBUTTONENTRY_CHECK(obj) NULL;
2285 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2287 if (!label) return NULL;
2288 if (!before) return NULL;
2290 it = _item_new(obj, label, func, data);
2291 if (!it) return NULL;
2293 sd->items = eina_list_prepend_relative(sd->items, it, before);
2295 if (!elm_object_focus_get(obj) && !sd->expanded && sd->boxw)
2298 _item_adding_effect_add(obj, it);
2300 _layout_shrink(obj, EINA_TRUE);
2305 if (sd->boxh && sd->boxw)
2306 _item_adding_effect_add(obj, it);
2309 elm_box_pack_before(sd->box, VIEW(it), VIEW(before));
2310 evas_object_show(VIEW(it));
2313 elm_box_pack_before(sd->box, VIEW(it), VIEW(before));
2314 evas_object_show(VIEW(it));
2319 if (!sd->boxh || !sd->boxw)
2320 evas_object_smart_callback_call(obj, SIG_ITEM_ADDED, it);
2322 evas_object_smart_callback_call(obj, SIG_ITEM_ADDED, it);
2325 return (Elm_Object_Item *)it;
2328 EAPI Elm_Object_Item *
2329 elm_multibuttonentry_item_insert_after(Evas_Object *obj,
2330 Elm_Object_Item *after,
2335 Elm_Multibuttonentry_Item *it;
2337 ELM_MULTIBUTTONENTRY_CHECK(obj) NULL;
2338 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2340 if (!label) return NULL;
2341 if (!after) return NULL;
2343 it = _item_new(obj, label, func, data);
2344 if (!it) return NULL;
2346 sd->items = eina_list_append_relative(sd->items, it, after);
2348 if (!elm_object_focus_get(obj) && !sd->expanded && sd->boxw)
2351 _item_adding_effect_add(obj, it);
2353 _layout_shrink(obj, EINA_TRUE);
2358 if (sd->boxw && sd->boxh)
2359 _item_adding_effect_add(obj, it);
2362 elm_box_pack_after(sd->box, VIEW(it), VIEW(after));
2363 evas_object_show(VIEW(it));
2366 elm_box_pack_after(sd->box, VIEW(it), VIEW(after));
2367 evas_object_show(VIEW(it));
2372 if (!sd->boxh || !sd->boxw)
2373 evas_object_smart_callback_call(obj, SIG_ITEM_ADDED, it);
2375 evas_object_smart_callback_call(obj, SIG_ITEM_ADDED, it);
2378 return (Elm_Object_Item *)it;
2381 EAPI const Eina_List *
2382 elm_multibuttonentry_items_get(const Evas_Object *obj)
2384 ELM_MULTIBUTTONENTRY_CHECK(obj) NULL;
2385 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2391 elm_multibuttonentry_item_object_get(const Elm_Object_Item *it)
2393 ELM_MULTIBUTTONENTRY_ITEM_CHECK_OR_RETURN(it, NULL);
2398 EAPI Elm_Object_Item *
2399 elm_multibuttonentry_first_item_get(const Evas_Object *obj)
2401 ELM_MULTIBUTTONENTRY_CHECK(obj) NULL;
2402 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2404 return eina_list_data_get(sd->items);
2407 EAPI Elm_Object_Item *
2408 elm_multibuttonentry_last_item_get(const Evas_Object *obj)
2410 ELM_MULTIBUTTONENTRY_CHECK(obj) NULL;
2411 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2413 return eina_list_data_get(eina_list_last(sd->items));
2416 EAPI Elm_Object_Item *
2417 elm_multibuttonentry_selected_item_get(const Evas_Object *obj)
2419 ELM_MULTIBUTTONENTRY_CHECK(obj) NULL;
2420 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2422 return sd->selected_item;
2426 elm_multibuttonentry_item_selected_set(Elm_Object_Item *it,
2429 ELM_MULTIBUTTONENTRY_ITEM_CHECK_OR_RETURN(it);
2430 ELM_MULTIBUTTONENTRY_DATA_GET(WIDGET(it), sd);
2432 if (!elm_object_focus_get(WIDGET(it))) return;
2434 if (selected && it != sd->selected_item)
2436 evas_object_focus_set(elm_layout_edje_get(VIEW(it)), EINA_TRUE);
2438 else if (!selected && it == sd->selected_item)
2440 evas_object_focus_set(elm_layout_edje_get(VIEW(it)), EINA_FALSE);
2443 elm_object_focus_set(sd->entry, EINA_TRUE);
2448 elm_multibuttonentry_item_selected_get(const Elm_Object_Item *it)
2450 ELM_MULTIBUTTONENTRY_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
2451 ELM_MULTIBUTTONENTRY_DATA_GET(WIDGET(it), sd);
2453 if (!elm_object_focus_get(WIDGET(it))) return EINA_FALSE;
2455 if (it == sd->selected_item)
2462 elm_multibuttonentry_clear(Evas_Object *obj)
2464 Elm_Multibuttonentry_Item *it;
2466 ELM_MULTIBUTTONENTRY_CHECK(obj);
2467 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2470 EINA_LIST_FREE(sd->items, it)
2475 trans = (Elm_Transit *)evas_object_data_get(VIEW(it), "transit");
2478 elm_transit_del_cb_set(trans, NULL, NULL);
2479 elm_transit_del(trans);
2482 rect = (Evas_Object *)evas_object_data_get(VIEW(it), "effect_rect");
2485 Ecore_Animator *anim;
2487 anim = (Ecore_Animator*)evas_object_data_get(rect, "animator");
2488 if (anim) ecore_animator_del(anim);
2490 evas_object_del(rect);
2491 evas_object_data_set(VIEW(it), "effect_rect", NULL);
2495 elm_box_pack_end(sd->box, sd->entry);
2496 evas_object_show(sd->entry);
2497 if (elm_object_focus_get(WIDGET(it)))
2498 elm_object_focus_set(sd->entry, EINA_TRUE);
2501 elm_widget_item_free(it);
2504 EINA_LIST_FREE(sd->items, it)
2505 elm_widget_item_free(it);
2509 sd->item_be_selected = EINA_FALSE;
2510 sd->expanded_state = EINA_TRUE;
2514 evas_object_del(sd->end);
2518 if (!sd->items && !elm_object_focus_get(obj) &&
2519 sd->guide && !_guide_packed(obj))
2523 elm_box_unpack(sd->box, sd->entry);
2524 evas_object_hide(sd->entry);
2527 elm_box_pack_end(sd->box, sd->guide);
2528 evas_object_show(sd->guide);
2532 EAPI Elm_Object_Item *
2533 elm_multibuttonentry_item_prev_get(const Elm_Object_Item *it)
2536 Elm_Multibuttonentry_Item *item;
2538 ELM_MULTIBUTTONENTRY_ITEM_CHECK_OR_RETURN(it, NULL);
2539 ELM_MULTIBUTTONENTRY_DATA_GET(WIDGET(it), sd);
2541 EINA_LIST_FOREACH(sd->items, l, item)
2543 if (item == (Elm_Multibuttonentry_Item *)it)
2545 l = eina_list_prev(l);
2546 if (!l) return NULL;
2547 return eina_list_data_get(l);
2553 EAPI Elm_Object_Item *
2554 elm_multibuttonentry_item_next_get(const Elm_Object_Item *it)
2557 Elm_Multibuttonentry_Item *item;
2559 ELM_MULTIBUTTONENTRY_ITEM_CHECK_OR_RETURN(it, NULL);
2560 ELM_MULTIBUTTONENTRY_DATA_GET(WIDGET(it), sd);
2562 EINA_LIST_FOREACH(sd->items, l, item)
2564 if (item == (Elm_Multibuttonentry_Item *)it)
2566 l = eina_list_next(l);
2567 if (!l) return NULL;
2568 return eina_list_data_get(l);
2575 elm_multibuttonentry_item_filter_append(Evas_Object *obj,
2576 Elm_Multibuttonentry_Item_Filter_Cb func,
2579 Elm_Multibuttonentry_Item_Filter *ft = NULL;
2581 ELM_MULTIBUTTONENTRY_CHECK(obj);
2582 EINA_SAFETY_ON_NULL_RETURN(func);
2583 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2585 ft = _filter_new(func, data);
2588 sd->filters = eina_list_append(sd->filters, ft);
2592 elm_multibuttonentry_item_filter_prepend(Evas_Object *obj,
2593 Elm_Multibuttonentry_Item_Filter_Cb func,
2596 Elm_Multibuttonentry_Item_Filter *ft = NULL;
2598 ELM_MULTIBUTTONENTRY_CHECK(obj);
2599 EINA_SAFETY_ON_NULL_RETURN(func);
2600 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2602 ft = _filter_new(func, data);
2605 sd->filters = eina_list_prepend(sd->filters, ft);
2609 elm_multibuttonentry_item_filter_remove(Evas_Object *obj,
2610 Elm_Multibuttonentry_Item_Filter_Cb func,
2613 Elm_Multibuttonentry_Item_Filter *ft;
2616 ELM_MULTIBUTTONENTRY_CHECK(obj);
2617 EINA_SAFETY_ON_NULL_RETURN(func);
2618 ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd);
2620 EINA_LIST_FOREACH(sd->filters, l, ft)
2622 if ((ft->func == func) && (!data || ft->data == data))
2624 sd->filters = eina_list_remove_list(sd->filters, l);