1 #include <Elementary.h>
3 #include "elm_widget_hoversel.h"
5 EAPI const char ELM_HOVERSEL_SMART_NAME[] = "elm_hoversel";
7 static const char SIG_SELECTED[] = "selected";
8 static const char SIG_DISMISSED[] = "dismissed";
9 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
15 EVAS_SMART_SUBCLASS_NEW
16 (ELM_HOVERSEL_SMART_NAME, _elm_hoversel, Elm_Hoversel_Smart_Class,
17 Elm_Button_Smart_Class, elm_button_smart_class_get, _smart_callbacks);
20 _elm_hoversel_smart_theme(Evas_Object *obj)
25 ELM_HOVERSEL_DATA_GET(obj, sd);
27 style = eina_stringshare_add(elm_widget_style_get(obj));
30 snprintf(buf, sizeof(buf), "hoversel_horizontal/%s", style);
32 snprintf(buf, sizeof(buf), "hoversel_vertical/%s", style);
34 /* hoversel's style has an extra bit: orientation */
35 eina_stringshare_replace(&(ELM_WIDGET_DATA(sd)->style), buf);
37 if (!ELM_WIDGET_CLASS(_elm_hoversel_parent_sc)->theme(obj))
40 eina_stringshare_replace(&(ELM_WIDGET_DATA(sd)->style), style);
42 eina_stringshare_del(style);
45 elm_widget_mirrored_set(sd->hover, elm_widget_mirrored_get(obj));
47 elm_hoversel_hover_end(obj);
53 _on_hover_clicked(void *data,
54 Evas_Object *obj __UNUSED__,
55 void *event_info __UNUSED__)
57 elm_hoversel_hover_end(data);
61 _on_item_clicked(void *data,
62 Evas_Object *obj __UNUSED__,
63 void *event_info __UNUSED__)
65 Elm_Hoversel_Item *item = data;
66 Evas_Object *obj2 = WIDGET(item);
68 if (item->func) item->func((void *)item->base.data, obj2, item);
69 evas_object_smart_callback_call(obj2, SIG_SELECTED, item);
70 elm_hoversel_hover_end(obj2);
74 _activate(Evas_Object *obj)
76 const Elm_Hoversel_Item *item;
77 Evas_Object *bt, *bx, *ic;
81 ELM_HOVERSEL_DATA_GET(obj, sd);
85 elm_hoversel_hover_end(obj);
88 sd->expanded = EINA_TRUE;
90 if (elm_widget_disabled_get(obj)) return;
92 sd->hover = elm_hover_add(sd->hover_parent);
93 elm_widget_mirrored_automatic_set(sd->hover, EINA_FALSE);
96 snprintf(buf, sizeof(buf), "hoversel_horizontal/%s",
97 elm_widget_style_get(obj));
99 snprintf(buf, sizeof(buf), "hoversel_vertical/%s",
100 elm_widget_style_get(obj));
102 elm_object_style_set(sd->hover, buf);
104 evas_object_smart_callback_add
105 (sd->hover, "clicked", _on_hover_clicked, obj);
106 elm_hover_target_set(sd->hover, obj);
108 /* hover's content */
109 bx = elm_box_add(sd->hover);
110 elm_widget_mirrored_automatic_set(bx, EINA_FALSE);
111 elm_box_homogeneous_set(bx, EINA_TRUE);
112 elm_box_horizontal_set(bx, sd->horizontal);
115 snprintf(buf, sizeof(buf), "hoversel_horizontal_entry/%s",
116 elm_widget_style_get(obj));
118 snprintf(buf, sizeof(buf), "hoversel_vertical_entry/%s",
119 elm_widget_style_get(obj));
121 EINA_LIST_FOREACH(sd->items, l, item)
123 bt = elm_button_add(bx);
124 elm_widget_mirrored_automatic_set(bt, EINA_FALSE);
125 elm_widget_mirrored_set(bt, elm_widget_mirrored_get(obj));
126 elm_object_style_set(bt, buf);
127 elm_object_text_set(bt, item->label);
131 ic = elm_icon_add(obj);
132 elm_image_resizable_set(ic, EINA_FALSE, EINA_TRUE);
133 if (item->icon_type == ELM_ICON_FILE)
134 elm_image_file_set(ic, item->icon_file, item->icon_group);
135 else if (item->icon_type == ELM_ICON_STANDARD)
136 elm_icon_standard_set(ic, item->icon_file);
137 elm_object_part_content_set(bt, "icon", ic);
140 evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
141 evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
142 elm_box_pack_end(bx, bt);
143 evas_object_smart_callback_add(bt, "clicked", _on_item_clicked, item);
144 evas_object_show(bt);
148 elm_object_part_content_set(sd->hover, elm_hover_best_content_location_get
149 (sd->hover, ELM_HOVER_AXIS_HORIZONTAL), bx);
151 elm_object_part_content_set(sd->hover, elm_hover_best_content_location_get
152 (sd->hover, ELM_HOVER_AXIS_VERTICAL), bx);
154 evas_object_show(sd->hover);
158 _on_clicked(void *data,
159 Evas_Object *obj __UNUSED__,
160 void *event_info __UNUSED__)
166 _on_parent_del(void *data,
168 Evas_Object *obj __UNUSED__,
169 void *event_info __UNUSED__)
171 elm_hoversel_hover_parent_set(data, NULL);
175 _item_text_get_hook(const Elm_Object_Item *it,
178 if (part && strcmp(part, "default")) return NULL;
179 return ((Elm_Hoversel_Item *)it)->label;
183 _item_del_pre_hook(Elm_Object_Item *it)
185 Elm_Hoversel_Item *item = (Elm_Hoversel_Item *)it;
187 ELM_HOVERSEL_DATA_GET_OR_RETURN_VAL(WIDGET(item), sd, EINA_FALSE);
189 elm_hoversel_hover_end(WIDGET(item));
190 sd->items = eina_list_remove(sd->items, item);
191 eina_stringshare_del(item->label);
192 eina_stringshare_del(item->icon_file);
193 eina_stringshare_del(item->icon_group);
199 _elm_hoversel_smart_add(Evas_Object *obj)
201 EVAS_SMART_DATA_ALLOC(obj, Elm_Hoversel_Smart_Data);
203 ELM_WIDGET_CLASS(_elm_hoversel_parent_sc)->base.add(obj);
205 elm_widget_mirrored_automatic_set(obj, EINA_FALSE);
207 priv->expanded = EINA_FALSE;
209 evas_object_smart_callback_add(obj, "clicked", _on_clicked, obj);
211 _elm_hoversel_smart_theme(obj);
215 _elm_hoversel_smart_del(Evas_Object *obj)
217 Elm_Hoversel_Item *item;
219 ELM_HOVERSEL_DATA_GET(obj, sd);
221 EINA_LIST_FREE (sd->items, item)
223 eina_stringshare_del(item->label);
224 eina_stringshare_del(item->icon_file);
225 eina_stringshare_del(item->icon_group);
226 elm_widget_item_free(item);
228 elm_hoversel_hover_parent_set(obj, NULL);
230 ELM_WIDGET_CLASS(_elm_hoversel_parent_sc)->base.del(obj);
234 _elm_hoversel_smart_parent_set(Evas_Object *obj,
237 elm_hoversel_hover_parent_set(obj, parent);
241 _elm_hoversel_smart_set_user(Elm_Hoversel_Smart_Class *sc)
243 ELM_WIDGET_CLASS(sc)->base.add = _elm_hoversel_smart_add;
244 ELM_WIDGET_CLASS(sc)->base.del = _elm_hoversel_smart_del;
246 ELM_WIDGET_CLASS(sc)->parent_set = _elm_hoversel_smart_parent_set;
247 ELM_WIDGET_CLASS(sc)->theme = _elm_hoversel_smart_theme;
249 ELM_BUTTON_CLASS(sc)->admits_autorepeat = EINA_FALSE;
252 EAPI const Elm_Hoversel_Smart_Class *
253 elm_hoversel_smart_class_get(void)
255 static Elm_Hoversel_Smart_Class _sc =
256 ELM_HOVERSEL_SMART_CLASS_INIT_NAME_VERSION(ELM_HOVERSEL_SMART_NAME);
257 static const Elm_Hoversel_Smart_Class *class = NULL;
258 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
260 if (class) return class;
262 _elm_hoversel_smart_set(&_sc);
263 esc->callbacks = _smart_callbacks;
270 elm_hoversel_add(Evas_Object *parent)
274 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
276 obj = elm_widget_add(_elm_hoversel_smart_class_new(), parent);
277 if (!obj) return NULL;
279 if (!elm_widget_sub_object_add(parent, obj))
280 ERR("could not add %p as sub object of %p", obj, parent);
286 elm_hoversel_hover_parent_set(Evas_Object *obj,
289 ELM_HOVERSEL_CHECK(obj);
290 ELM_HOVERSEL_DATA_GET(obj, sd);
292 if (sd->hover_parent)
293 evas_object_event_callback_del_full
294 (sd->hover_parent, EVAS_CALLBACK_DEL, _on_parent_del, obj);
296 sd->hover_parent = parent;
297 if (sd->hover_parent)
298 evas_object_event_callback_add
299 (sd->hover_parent, EVAS_CALLBACK_DEL, _on_parent_del, obj);
303 elm_hoversel_hover_parent_get(const Evas_Object *obj)
305 ELM_HOVERSEL_CHECK(obj) NULL;
306 ELM_HOVERSEL_DATA_GET(obj, sd);
308 return sd->hover_parent;
312 elm_hoversel_horizontal_set(Evas_Object *obj,
313 Eina_Bool horizontal)
315 ELM_HOVERSEL_CHECK(obj);
316 ELM_HOVERSEL_DATA_GET(obj, sd);
318 sd->horizontal = !!horizontal;
320 _elm_hoversel_smart_theme(obj);
324 elm_hoversel_horizontal_get(const Evas_Object *obj)
326 ELM_HOVERSEL_CHECK(obj) EINA_FALSE;
327 ELM_HOVERSEL_DATA_GET(obj, sd);
329 return sd->horizontal;
333 elm_hoversel_hover_begin(Evas_Object *obj)
335 ELM_HOVERSEL_CHECK(obj);
336 ELM_HOVERSEL_DATA_GET(obj, sd);
338 if (sd->hover) return;
344 elm_hoversel_hover_end(Evas_Object *obj)
346 ELM_HOVERSEL_CHECK(obj);
347 ELM_HOVERSEL_DATA_GET(obj, sd);
349 if (!sd->hover) return;
351 sd->expanded = EINA_FALSE;
353 evas_object_del(sd->hover);
356 evas_object_smart_callback_call(obj, SIG_DISMISSED, NULL);
360 elm_hoversel_expanded_get(const Evas_Object *obj)
362 ELM_HOVERSEL_CHECK(obj) EINA_FALSE;
363 ELM_HOVERSEL_DATA_GET(obj, sd);
365 return (sd->hover) ? EINA_TRUE : EINA_FALSE;
369 elm_hoversel_clear(Evas_Object *obj)
374 ELM_HOVERSEL_CHECK(obj);
375 ELM_HOVERSEL_DATA_GET(obj, sd);
377 EINA_LIST_FOREACH_SAFE(sd->items, l, ll, it)
379 elm_widget_item_del(it);
383 EAPI const Eina_List *
384 elm_hoversel_items_get(const Evas_Object *obj)
386 ELM_HOVERSEL_CHECK(obj) NULL;
387 ELM_HOVERSEL_DATA_GET(obj, sd);
392 EAPI Elm_Object_Item *
393 elm_hoversel_item_add(Evas_Object *obj,
395 const char *icon_file,
396 Elm_Icon_Type icon_type,
400 ELM_HOVERSEL_CHECK(obj) NULL;
401 ELM_HOVERSEL_DATA_GET(obj, sd);
403 Elm_Hoversel_Item *item = elm_widget_item_new(obj, Elm_Hoversel_Item);
404 if (!item) return NULL;
406 elm_widget_item_del_pre_hook_set(item, _item_del_pre_hook);
407 elm_widget_item_text_get_hook_set(item, _item_text_get_hook);
409 item->label = eina_stringshare_add(label);
410 item->icon_file = eina_stringshare_add(icon_file);
411 item->icon_type = icon_type;
413 item->base.data = data;
415 sd->items = eina_list_append(sd->items, item);
417 return (Elm_Object_Item *)item;
421 elm_hoversel_item_icon_set(Elm_Object_Item *it,
422 const char *icon_file,
423 const char *icon_group,
424 Elm_Icon_Type icon_type)
426 ELM_HOVERSEL_ITEM_CHECK_OR_RETURN(it);
428 Elm_Hoversel_Item *item = (Elm_Hoversel_Item *)it;
430 eina_stringshare_replace(&item->icon_file, icon_file);
431 eina_stringshare_replace(&item->icon_group, icon_group);
433 item->icon_type = icon_type;
437 elm_hoversel_item_icon_get(const Elm_Object_Item *it,
438 const char **icon_file,
439 const char **icon_group,
440 Elm_Icon_Type *icon_type)
442 ELM_HOVERSEL_ITEM_CHECK_OR_RETURN(it);
444 Elm_Hoversel_Item *item = (Elm_Hoversel_Item *)it;
446 if (icon_file) *icon_file = item->icon_file;
447 if (icon_group) *icon_group = item->icon_group;
448 if (icon_type) *icon_type = item->icon_type;