#include "e.h" typedef struct _E_Menu_Category E_Menu_Category; struct _E_Menu_Category { void *data; Eina_List *callbacks; }; /* local function prototypes */ static Eina_Bool _e_menu_categories_cb_free(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__); static void _e_menu_cb_free(E_Menu *m); static void _e_menu_cb_ee_resize(Ecore_Evas *ee); static void _e_menu_cb_container_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y); static void _e_menu_cb_container_resize(void *data, Evas_Object *obj, Evas_Coord w, Evas_Coord h); static Eina_Bool _e_menu_cb_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event); static Eina_Bool _e_menu_cb_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event); static void _e_menu_item_cb_free(E_Menu_Item *mi); static void _e_menu_item_cb_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y); static void _e_menu_item_cb_resize(void *data, Evas_Object *obj, Evas_Coord w, Evas_Coord h); static void _e_menu_item_cb_in(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__); static void _e_menu_item_cb_out(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__); static void _e_menu_item_cb_submenu_post(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi); static int _e_menu_auto_place(E_Menu *m, int x, int y, int w, int h); static void _e_menu_activate_internal(E_Menu *m, E_Zone *zone); static void _e_menu_realize(E_Menu *m); static void _e_menu_reposition(E_Menu *m); static void _e_menu_layout_update(E_Menu *m); static void _e_menu_unrealize(E_Menu *m); static void _e_menu_deactivate_above(E_Menu *m); static int _e_menu_active_call(void); static void _e_menu_deactivate_all(void); static void _e_menu_item_realize(E_Menu_Item *mi); static void _e_menu_item_unrealize(E_Menu_Item *mi); static Eina_Bool _e_menu_item_realize_call(E_Menu_Item *mi); static void _e_menu_item_submenu_activate(E_Menu_Item *mi); static void _e_menu_item_submenu_deactivate(E_Menu_Item *mi); /* local variables */ static Eina_Hash *_categories = NULL; static Eina_List *_active_menus = NULL; static Eina_List *_handlers = NULL; static E_Menu_Item *_active_item = NULL; static int _menu_x = 0; static int _menu_y = 0; static unsigned int _menu_time = 0; EINTERN int e_menu_init(void) { /* TODO: Handlers */ _handlers = eina_list_append(_handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_menu_cb_mouse_move, NULL)); _handlers = eina_list_append(_handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _e_menu_cb_mouse_up, NULL)); _categories = eina_hash_string_superfast_new(NULL); return 1; } EINTERN int e_menu_shutdown(void) { Ecore_Event_Handler *hdl; EINA_LIST_FREE(_handlers, hdl) ecore_event_handler_del(hdl); if (!wl_fatal) { E_Menu *m; EINA_LIST_FREE(_active_menus, m) { m->active = EINA_FALSE; _e_menu_unrealize(m); e_object_unref(E_OBJECT(m)); } } if (_categories) { eina_hash_foreach(_categories, _e_menu_categories_cb_free, NULL); eina_hash_free(_categories); } _categories = NULL; return 1; } EAPI E_Menu * e_menu_new(void) { E_Menu *m; m = E_OBJECT_ALLOC(E_Menu, E_MENU_TYPE, _e_menu_cb_free); if (!m) return NULL; m->cur.w = 1; m->cur.h = 1; m->category = NULL; return m; } EAPI void e_menu_activate_key(E_Menu *m, E_Zone *zone, int x, int y, int w, int h, int dir) { E_OBJECT_CHECK(m); E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE); } EAPI void e_menu_activate_mouse(E_Menu *m, E_Zone *zone, int x, int y, int w, int h, int dir, unsigned int activate_time) { E_OBJECT_CHECK(m); E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE); E_OBJECT_CHECK(zone); E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE); _e_menu_activate_internal(m, zone); if (!m->zone) { e_menu_deactivate(m); return; } switch (dir) { case E_MENU_POP_DIRECTION_LEFT: break; case E_MENU_POP_DIRECTION_RIGHT: break; case E_MENU_POP_DIRECTION_UP: break; case E_MENU_POP_DIRECTION_DOWN: break; case E_MENU_POP_DIRECTION_AUTO: _e_menu_auto_place(m, x, y, w, h); _e_menu_realize(m); break; default: m->cur.x = x + w; m->cur.y = y + h; break; } if (!_active_item) return; e_menu_item_active_set(_active_item, 0); } EAPI void e_menu_activate(E_Menu *m, E_Zone *zone, int x, int y, int w, int h, int dir) { E_OBJECT_CHECK(m); E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE); } EAPI void e_menu_deactivate(E_Menu *m) { E_OBJECT_CHECK(m); E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE); m->cur.visible = EINA_FALSE; m->active = EINA_FALSE; if (m->post_deactivate_cb.func) m->post_deactivate_cb.func(m->post_deactivate_cb.data, m); } EAPI int e_menu_freeze(E_Menu *m) { E_OBJECT_CHECK(m); E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE); m->frozen++; return m->frozen; } EAPI int e_menu_thaw(E_Menu *m) { E_OBJECT_CHECK(m); E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE); m->frozen--; if (m->frozen < 0) m->frozen = 0; return m->frozen; } EAPI void e_menu_title_set(E_Menu *m, char *title) { E_OBJECT_CHECK(m); E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE); if ((m->header.title) && (title) && (!strcmp(m->header.title, title))) return; eina_stringshare_replace(&m->header.title, title); m->changed = EINA_TRUE; } EAPI void e_menu_icon_file_set(E_Menu *m __UNUSED__, char *icon __UNUSED__) { E_OBJECT_CHECK(m); E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE); } EAPI void e_menu_category_set(E_Menu *m, char *category) { E_OBJECT_CHECK(m); E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE); if ((m->category) && (category) && (!strcmp(m->category, category))) return; eina_stringshare_replace(&m->category, category); m->changed = EINA_TRUE; } EAPI void e_menu_category_data_set(char *category, void *data) { E_Menu_Category *cat; if ((cat = eina_hash_find(_categories, category))) cat->data = data; else { cat = calloc(1, sizeof(E_Menu_Category)); cat->data = data; eina_hash_add(_categories, category, cat); } } EAPI E_Menu_Category_Callback * e_menu_category_callback_add(char *category, void (*create) (E_Menu *m, void *category_data, void *data), void (free) (void *data), void *data) { E_Menu_Category *cat; E_Menu_Category_Callback *cb = NULL; cat = eina_hash_find(_categories, category); if (!cat) { cat = calloc(1, sizeof(E_Menu_Category)); eina_hash_add(_categories, category, cat); } if (cat) { if ((cb = calloc(1, sizeof(E_Menu_Category_Callback)))) { cb->data = data; cb->create = create; cb->free = free; cb->category = eina_stringshare_add(category); cat->callbacks = eina_list_append(cat->callbacks, cb); } } return cb; } EAPI void e_menu_category_callback_del(E_Menu_Category_Callback *cb) { if (cb) { E_Menu_Category *cat; if ((cat = eina_hash_find(_categories, cb->category))) cat->callbacks = eina_list_remove(cat->callbacks, cb); eina_stringshare_del(cb->category); free(cb); } } EAPI void e_menu_pre_activate_callback_set(E_Menu *m, void (*func) (void *data, E_Menu *m), void *data) { E_OBJECT_CHECK(m); E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE); m->pre_activate_cb.func = func; m->pre_activate_cb.data = data; } EAPI void e_menu_post_deactivate_callback_set(E_Menu *m, void (*func) (void *data, E_Menu *m), void *data) { E_OBJECT_CHECK(m); E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE); m->post_deactivate_cb.func = func; m->post_deactivate_cb.data = data; } EAPI E_Menu * e_menu_root_get(E_Menu *m) { E_Menu *ret; E_OBJECT_CHECK_RETURN(m, NULL); E_OBJECT_TYPE_CHECK_RETURN(m, E_MENU_TYPE, NULL); ret = m; while ((ret->parent_item) && (ret->parent_item->menu)) ret = ret->parent_item->menu; return ret; } EAPI void e_menu_idler_before(void) { Eina_List *l; E_Menu *m; /* EINA_LIST_FOREACH(_active_menus, l, m) */ /* { */ /* if ((!m->cur.visible) && (m->prev.visible)) */ /* { */ /* m->prev.visible = m->cur.visible; */ /* ecore_evas_hide(m->ee); */ /* } */ /* } */ EINA_LIST_FOREACH(_active_menus, l, m) { if ((m->cur.visible) && (!m->prev.visible)) { if (!m->realized) _e_menu_realize(m); m->prev.visible = m->cur.visible; /* ecore_evas_raise(m->ee); */ ecore_evas_show(m->ee); } } EINA_LIST_FOREACH(_active_menus, l, m) { if (m->realized) { if ((m->cur.x != m->prev.x) || (m->cur.y != m->prev.y)) { m->prev.x = m->cur.x; m->prev.y = m->cur.y; ecore_evas_move(m->ee, m->cur.x, m->cur.y); } if ((m->cur.w != m->prev.w) || (m->cur.h != m->prev.h)) { m->prev.w = m->cur.w; m->prev.h = m->cur.h; ecore_evas_resize(m->ee, m->cur.w, m->cur.h); } } } EINA_LIST_FOREACH(_active_menus, l, m) { if (!m->active) { _active_menus = eina_list_remove(_active_menus, m); _e_menu_unrealize(m); e_object_unref(E_OBJECT(m)); } } } EAPI E_Menu_Item * e_menu_item_new(E_Menu *m) { E_Menu_Item *mi; E_OBJECT_CHECK_RETURN(m, NULL); E_OBJECT_TYPE_CHECK_RETURN(m, E_MENU_TYPE, NULL); mi = E_OBJECT_ALLOC(E_Menu_Item, E_MENU_ITEM_TYPE, _e_menu_item_cb_free); if (!mi) return NULL; mi->menu = m; mi->menu->items = eina_list_append(mi->menu->items, mi); return mi; } EAPI E_Menu_Item * e_menu_item_new_relative(E_Menu *m, E_Menu_Item *rel) { E_Menu_Item *mi; E_OBJECT_CHECK_RETURN(m, NULL); E_OBJECT_TYPE_CHECK_RETURN(m, E_MENU_TYPE, NULL); if (rel) { E_OBJECT_CHECK_RETURN(rel, NULL); E_OBJECT_TYPE_CHECK_RETURN(rel, E_MENU_ITEM_TYPE, NULL); if (rel->menu != m) return NULL; } mi = E_OBJECT_ALLOC(E_Menu_Item, E_MENU_ITEM_TYPE, _e_menu_item_cb_free); if (!mi) return NULL; mi->menu = m; if (rel) { Eina_List *l; l = eina_list_data_find_list(m->items, rel); m->items = eina_list_append_relative_list(m->items, mi, l); } else m->items = eina_list_prepend(m->items, mi); return mi; } EAPI E_Menu_Item * e_menu_item_nth(E_Menu *m, int n) { E_OBJECT_CHECK_RETURN(m, NULL); E_OBJECT_TYPE_CHECK_RETURN(m, E_MENU_TYPE, NULL); return (E_Menu_Item *)eina_list_nth(m->items, n); } EAPI int e_menu_item_num_get(const E_Menu_Item *mi) { const Eina_List *l; const E_Menu_Item *mi2; int i = 0; E_OBJECT_CHECK_RETURN(mi, -1); E_OBJECT_CHECK_RETURN(mi->menu, -1); E_OBJECT_TYPE_CHECK_RETURN(mi, E_MENU_ITEM_TYPE, -1); EINA_LIST_FOREACH(mi->menu->items, l, mi2) { if (mi2 == mi) return i; i++; } return -1; } EAPI void e_menu_item_icon_file_set(E_Menu_Item *mi, const char *icon) { E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); if ((mi->icon) && (icon) && (!strcmp(mi->icon, icon))) return; eina_stringshare_replace(&mi->icon, icon); if (mi->icon_key) eina_stringshare_del(mi->icon_key); if (icon) { int len = 0; len = strlen(icon); if ((len > 4) && (!strcasecmp(icon + len - 4, ".edj"))) mi->icon_key = eina_stringshare_add("icon"); } mi->changed = EINA_TRUE; mi->menu->changed = EINA_TRUE; } EAPI void e_menu_item_icon_edje_set(E_Menu_Item *mi, const char *icon, const char *key) { E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); if (((mi->icon) && (icon) && (!strcmp(mi->icon, icon))) || ((mi->icon_key) && (key) && (!strcmp(mi->icon_key, key)))) return; eina_stringshare_replace(&mi->icon, icon); eina_stringshare_replace(&mi->icon_key, key); mi->changed = EINA_TRUE; mi->menu->changed = EINA_TRUE; } EAPI void e_menu_item_label_set(E_Menu_Item *mi, const char *label) { E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); if ((mi->label) && (label) && (!strcmp(mi->label, label))) return; eina_stringshare_replace(&mi->label, label); mi->changed = EINA_TRUE; mi->menu->changed = EINA_TRUE; } EAPI void e_menu_item_submenu_set(E_Menu_Item *mi, E_Menu *sub) { E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); if (mi->submenu) e_object_unref(E_OBJECT(mi->submenu)); if (sub) e_object_ref(E_OBJECT(sub)); mi->submenu = sub; mi->changed = EINA_TRUE; mi->menu->changed = EINA_TRUE; } EAPI void e_menu_item_separator_set(E_Menu_Item *mi, int sep) { E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); if (mi->separator == sep) return; mi->separator = sep; mi->changed = EINA_TRUE; mi->menu->changed = EINA_TRUE; } EAPI void e_menu_item_check_set(E_Menu_Item *mi, int chk) { E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); if (mi->check == chk) return; mi->check = chk; mi->changed = EINA_TRUE; mi->menu->changed = EINA_TRUE; } EAPI void e_menu_item_radio_set(E_Menu_Item *mi, int rad) { E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); if (mi->radio == rad) return; mi->radio = rad; mi->changed = EINA_TRUE; mi->menu->changed = EINA_TRUE; } EAPI void e_menu_item_radio_group_set(E_Menu_Item *mi, int radg) { E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); if (mi->radio_group == radg) return; mi->radio_group = radg; mi->changed = EINA_TRUE; mi->menu->changed = EINA_TRUE; } EAPI void e_menu_item_toggle_set(E_Menu_Item *mi, int tog) { E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); if (mi->separator) return; if (mi->toggle == tog) return; mi->toggle = tog; if (tog) { if (mi->o_bg) edje_object_signal_emit(mi->o_bg, "e,state,on", "e"); if (mi->o_icon_bg) edje_object_signal_emit(mi->o_icon_bg, "e,state,on", "e"); if (mi->o_lbl) edje_object_signal_emit(mi->o_lbl, "e,state,on", "e"); if (mi->o_submenu) edje_object_signal_emit(mi->o_submenu, "e,state,on", "e"); if (mi->o_toggle) edje_object_signal_emit(mi->o_toggle, "e,state,on", "e"); if (mi->menu->o_bg) edje_object_signal_emit(mi->menu->o_bg, "e,state,on", "e"); if (mi->radio) { const Eina_List *l; E_Menu_Item *mi2; EINA_LIST_FOREACH(mi->menu->items, l, mi2) { if ((mi2 != mi) && (mi2->radio) && (mi2->radio_group == mi->radio_group)) e_menu_item_toggle_set(mi2, 0); } } } else { if (mi->o_bg) edje_object_signal_emit(mi->o_bg, "e,state,off", "e"); if (mi->o_icon_bg) edje_object_signal_emit(mi->o_icon_bg, "e,state,off", "e"); if (mi->o_lbl) edje_object_signal_emit(mi->o_lbl, "e,state,off", "e"); if (mi->o_submenu) edje_object_signal_emit(mi->o_submenu, "e,state,off", "e"); if (mi->o_toggle) edje_object_signal_emit(mi->o_toggle, "e,state,off", "e"); if (mi->menu->o_bg) edje_object_signal_emit(mi->menu->o_bg, "e,state,off", "e"); } } EAPI int e_menu_item_toggle_get(E_Menu_Item *mi) { E_OBJECT_CHECK_RETURN(mi, 0); E_OBJECT_TYPE_CHECK_RETURN(mi, E_MENU_ITEM_TYPE, 0); return mi->toggle; } EAPI void e_menu_item_callback_set(E_Menu_Item *mi, E_Menu_Cb func, void *data) { E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); mi->cb.func = func; mi->cb.data = data; } EAPI void e_menu_item_realize_callback_set(E_Menu_Item *mi, E_Menu_Cb func, void *data) { E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); mi->realize_cb.func = func; mi->realize_cb.data = data; } EAPI void e_menu_item_submenu_pre_callback_set(E_Menu_Item *mi, E_Menu_Cb func, void *data) { E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); mi->submenu_pre_cb.func = func; mi->submenu_pre_cb.data = data; if (!mi->submenu_post_cb.func) mi->submenu_post_cb.func = _e_menu_item_cb_submenu_post; } EAPI void e_menu_item_submenu_post_callback_set(E_Menu_Item *mi, E_Menu_Cb func, void *data) { E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); mi->submenu_post_cb.func = func; mi->submenu_post_cb.data = data; } EAPI void e_menu_item_drag_callback_set(E_Menu_Item *mi __UNUSED__, E_Menu_Cb func __UNUSED__, void *data __UNUSED__) { E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); } EAPI void e_menu_item_active_set(E_Menu_Item *mi, int active) { E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); if (mi->separator) return; if ((active) && (!mi->active)) { E_Menu_Item *pmi; if (mi->disabled) return; pmi = _active_item; if (mi == pmi) return; if (pmi) e_menu_item_active_set(pmi, 0); mi->active = EINA_TRUE; _active_item = mi; if (mi->o_bg) edje_object_signal_emit(mi->o_bg, "e,state,selected", "e"); if (mi->o_icon_bg) edje_object_signal_emit(mi->o_icon_bg, "e,state,selected", "e"); if (mi->o_lbl) edje_object_signal_emit(mi->o_lbl, "e,state,selected", "e"); if (mi->o_submenu) edje_object_signal_emit(mi->o_submenu, "e,state,selected", "e"); if (mi->o_toggle) edje_object_signal_emit(mi->o_toggle, "e,state,selected", "e"); if (mi->icon_key) { if (mi->o_icon) { if (strcmp(evas_object_type_get(mi->o_icon), "e_icon")) edje_object_signal_emit(mi->o_icon, "e,state,selected", "e"); else e_icon_selected_set(mi->o_icon, EINA_TRUE); } } edje_object_signal_emit(mi->menu->o_bg, "e,state,selected", "e"); _e_menu_item_submenu_activate(mi); } else if ((!active) && (mi->active)) { mi->active = EINA_FALSE; _active_item = NULL; if (mi->o_bg) edje_object_signal_emit(mi->o_bg, "e,state,unselected", "e"); if (mi->o_icon_bg) edje_object_signal_emit(mi->o_icon_bg, "e,state,unselected", "e"); if (mi->o_lbl) edje_object_signal_emit(mi->o_lbl, "e,state,unselected", "e"); if (mi->o_submenu) edje_object_signal_emit(mi->o_submenu, "e,state,unselected", "e"); if (mi->o_toggle) edje_object_signal_emit(mi->o_toggle, "e,state,unselected", "e"); if (mi->icon_key) { if (mi->o_icon) { if (strcmp(evas_object_type_get(mi->o_icon), "e_icon")) edje_object_signal_emit(mi->o_icon, "e,state,unselected", "e"); else e_icon_selected_set(mi->o_icon, EINA_FALSE); } } edje_object_signal_emit(mi->menu->o_bg, "e,state,unselected", "e"); _e_menu_item_submenu_deactivate(mi); } } EAPI void e_menu_item_disabled_set(E_Menu_Item *mi, int disable) { E_OBJECT_CHECK(mi); E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE); if (mi->separator) return; if (disable) { if (mi->active) e_menu_item_active_set(mi, 0); mi->disabled = EINA_TRUE; if (mi->o_icon_bg) edje_object_signal_emit(mi->o_icon_bg, "e,state,disable", "e"); if (mi->o_lbl) edje_object_signal_emit(mi->o_lbl, "e,state,disable", "e"); if (mi->o_toggle) edje_object_signal_emit(mi->o_toggle, "e,state,disable", "e"); } else { mi->disabled = EINA_FALSE; if (mi->o_icon_bg) edje_object_signal_emit(mi->o_icon_bg, "e,state,enable", "e"); if (mi->o_lbl) edje_object_signal_emit(mi->o_lbl, "e,state,enable", "e"); if (mi->o_toggle) edje_object_signal_emit(mi->o_toggle, "e,state,enable", "e"); } } /* local functions */ static Eina_Bool _e_menu_categories_cb_free(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__) { E_Menu_Category_Callback *cb; E_Menu_Category *cat; cat = (E_Menu_Category *)data; EINA_LIST_FREE(cat->callbacks, cb) free(cb); free(cat); return EINA_TRUE; } static void _e_menu_cb_free(E_Menu *m) { Eina_List *l, *ll; E_Menu_Item *mi; if (m->category) { E_Menu_Category *cat = NULL; if ((cat = eina_hash_find(_categories, m->category))) { E_Menu_Category_Callback *cb; EINA_LIST_FOREACH(cat->callbacks, l, cb) if (cb->free) cb->free(cb->data); } } _e_menu_unrealize(m); EINA_LIST_FOREACH_SAFE(m->items, l, ll, mi) e_object_del(E_OBJECT(mi)); _active_menus = eina_list_remove(_active_menus, m); e_object_unref(E_OBJECT(m)); if (m->header.title) eina_stringshare_del(m->header.title); if (m->header.icon_file) eina_stringshare_del(m->header.icon_file); E_FREE(m); } static void _e_menu_cb_ee_resize(Ecore_Evas *ee) { Evas *evas; Evas_Object *o; Evas_Coord w, h; evas = ecore_evas_get(ee); evas_output_viewport_get(evas, NULL, NULL, &w, &h); o = evas_object_name_find(evas, "menu/background"); evas_object_resize(o, w, h); } static void _e_menu_cb_container_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y) { E_Menu *m; if (!(m = data)) return; m->cx = x; m->cy = y; if (m->parent_item) _e_menu_reposition(m); evas_object_move(obj, x, y); } static void _e_menu_cb_container_resize(void *data, Evas_Object *obj, Evas_Coord w, Evas_Coord h) { E_Menu *m; if (!(m = data)) return; m->cw = w; m->ch = h; if (m->parent_item) _e_menu_reposition(m); evas_object_resize(obj, w, h); } static Eina_Bool _e_menu_cb_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event) { Ecore_Event_Mouse_Move *ev; Eina_List *l; E_Menu *m; int dx, dy, d; double dt, fast_move_threshold; Eina_Bool is_fast = EINA_FALSE; Eina_Bool event_sent = EINA_FALSE; ev = event; fast_move_threshold = e_config->menus_fast_mouse_move_threshhold; dx = ev->x - _menu_x; dy = ev->y - _menu_y; d = (dx * dy) + (dy * dy); dt = (double)(ev->timestamp - _menu_time) / 1000.0; dt = dt * dt; if ((dt > 0.0) && ((d / dt) >= (fast_move_threshold * fast_move_threshold))) is_fast = EINA_TRUE; EINA_LIST_FOREACH(_active_menus, l, m) { if ((m->realized) && (m->cur.visible)) { if (ev->event_window == m->id) { int x = 0, y = 0; if (is_fast) m->fast_mouse = EINA_TRUE; else if (dt > 0.0) { m->fast_mouse = EINA_FALSE; if (m->pending_new_submenu) { if (_active_item) _e_menu_item_submenu_deactivate(_active_item); } } x = ev->x - m->cur.x + m->zone->x; y = ev->y - m->cur.y + m->zone->y; if (ev->x < m->cur.x) x = m->cur.x - ev->x + m->zone->x; printf("Menu Position: %d %d\n", m->cur.x, m->cur.y); printf("Feeding Mouse Move On Menu: %d: %d %d\n", m->id, x, y); evas_event_feed_mouse_move(m->evas, x, y, ev->timestamp, NULL); event_sent = EINA_TRUE; } } } _menu_x = ev->x; _menu_y = ev->y; _menu_time = ev->timestamp; if (event_sent) return ECORE_CALLBACK_DONE; return ECORE_CALLBACK_PASS_ON; } static Eina_Bool _e_menu_cb_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event) { Ecore_Event_Mouse_Button *ev; int ret = 0; unsigned int t; ev = event; t = ev->timestamp - _menu_time; if ((_menu_time != 0) && (t < (e_config->menus_click_drag_timeout * 1000))) { return ECORE_CALLBACK_PASS_ON; } ret = _e_menu_active_call(); if ((ret == 1) || (ret == -1)) _e_menu_deactivate_all(); return ECORE_CALLBACK_PASS_ON; } static void _e_menu_item_cb_free(E_Menu_Item *mi) { if (mi == _active_item) _active_item = NULL; if (mi->submenu) { mi->submenu->parent_item = NULL; e_object_unref(E_OBJECT(mi->submenu)); } if (mi->menu->realized) _e_menu_item_unrealize(mi); mi->menu->items = eina_list_remove(mi->menu->items, mi); if (mi->icon) eina_stringshare_del(mi->icon); if (mi->icon_key) eina_stringshare_del(mi->icon_key); if (mi->label) eina_stringshare_del(mi->label); E_FREE(mi); } static void _e_menu_item_cb_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y) { E_Menu_Item *mi; if (!(mi = data)) return; mi->x = x; mi->y = y; evas_object_move(mi->o_event, x, y); evas_object_move(obj, x, y); if ((mi->submenu) && (mi->submenu->parent_item)) _e_menu_reposition(mi->submenu); } static void _e_menu_item_cb_resize(void *data, Evas_Object *obj, Evas_Coord w, Evas_Coord h) { E_Menu_Item *mi; if (!(mi = data)) return; mi->w = w; mi->h = h; evas_object_resize(mi->o_event, w, h); evas_object_resize(obj, w, h); if ((mi->submenu) && (mi->submenu->parent_item)) _e_menu_reposition(mi->submenu); } static void _e_menu_item_cb_in(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__) { E_Menu_Item *mi; if (!(mi = data)) return; printf("Menu Item Mouse In\n"); e_menu_item_active_set(mi, 1); } static void _e_menu_item_cb_out(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__) { E_Menu_Item *mi; if (!(mi = data)) return; printf("Menu Item Mouse Out\n"); e_menu_item_active_set(mi, 0); } static void _e_menu_item_cb_submenu_post(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi) { E_Menu *sm; if (!mi->submenu) return; sm = mi->submenu; e_menu_item_submenu_set(mi, NULL); e_object_del(E_OBJECT(sm)); } static int _e_menu_auto_place(E_Menu *m, int x, int y, int w, int h) { m->cur.x = x; m->cur.y = y; m->cur.w = w; m->cur.h = h; return 0; } static void _e_menu_activate_internal(E_Menu *m, E_Zone *zone) { m->zone = zone; m->fast_mouse = EINA_FALSE; m->pending_new_submenu = EINA_FALSE; if (m->pre_activate_cb.func) m->pre_activate_cb.func(m->pre_activate_cb.data, m); if (!m->active) { _active_menus = eina_list_append(_active_menus, m); m->active = EINA_TRUE; e_object_ref(E_OBJECT(m)); } if (m->category) { E_Menu_Category *cat = NULL; if ((cat = eina_hash_find(_categories, m->category))) { Eina_List *l; E_Menu_Category_Callback *cb; EINA_LIST_FOREACH(cat->callbacks, l, cb) if (cb->create) cb->create(m, cat->data, cb->data); } } m->cur.visible = EINA_TRUE; } static void _e_menu_realize(E_Menu *m) { Ecore_Wl_Window *win = NULL; unsigned int parent = 0; Eina_List *l; E_Menu_Item *mi; int x, y; if (m->realized) return; if (!m->zone) return; if (!m->zone->container) return; if (!m->zone->container->bg_ee) return; m->realized = EINA_TRUE; x = m->cur.x; y = m->cur.y; if (m->parent_item) { E_Menu *pm; pm = m->parent_item->menu; x = pm->cur.x + pm->cur.w; y = pm->cur.y + m->parent_item->y; /* if ((win = ecore_evas_wayland_window_get(pm->ee))) */ /* parent = win->id; */ } /* else */ /* { */ if ((win = ecore_evas_wayland_window_get(m->zone->container->bg_ee))) parent = win->id; /* } */ m->ee = e_canvas_new(parent, x, y, m->cur.w, m->cur.h, EINA_TRUE, EINA_FALSE, &win); e_canvas_add(m->ee); m->id = win->id; /* m->id = ecore_evas_wayland_window_get(m->ee)->id; */ printf("Menu Id: %d\n", m->id); ecore_evas_name_class_set(m->ee, "E", "_e_menu_window"); ecore_evas_title_set(m->ee, "E Menu"); ecore_evas_wayland_type_set(m->ee, ECORE_WL_WINDOW_TYPE_MENU); ecore_evas_callback_resize_set(m->ee, _e_menu_cb_ee_resize); m->evas = ecore_evas_get(m->ee); evas_event_freeze(m->evas); m->o_bg = edje_object_add(m->evas); evas_object_name_set(m->o_bg, "menu/background"); evas_object_data_set(m->o_bg, "e_menu", m); evas_object_move(m->o_bg, 0, 0); evas_object_resize(m->o_bg, m->cur.w, m->cur.h); if ((e_theme_edje_object_set(m->o_bg, "base/theme/menus", "e/widgets/menu/default/background"))) { const char *shaped; if ((shaped = edje_object_data_get(m->o_bg, "shaped"))) if (!strcmp(shaped, "1")) m->shaped = EINA_TRUE; ecore_evas_alpha_set(m->ee, m->shaped); } if (m->header.title) { edje_object_part_text_set(m->o_bg, "e.text.title", m->header.title); edje_object_signal_emit(m->o_bg, "e,action,show,title", "e"); edje_object_message_signal_process(m->o_bg); } evas_object_show(m->o_bg); m->o_con = e_box_add(m->evas); evas_object_intercept_move_callback_add(m->o_con, _e_menu_cb_container_move, m); evas_object_intercept_resize_callback_add(m->o_con, _e_menu_cb_container_resize, m); e_box_freeze(m->o_con); evas_object_show(m->o_con); e_box_homogenous_set(m->o_con, 0); edje_object_part_swallow(m->o_bg, "e.swallow.content", m->o_con); EINA_LIST_FOREACH(m->items, l, mi) _e_menu_item_realize(mi); _e_menu_layout_update(m); e_box_thaw(m->o_con); evas_object_resize(m->o_bg, m->cur.w, m->cur.h); evas_event_thaw(m->evas); } static void _e_menu_reposition(E_Menu *m) { Eina_List *l; E_Menu_Item *mi; int bottom = 0; if (!m->parent_item) return; // if ((!m->parent_item) || (!m->parent_item->menu)) return; m->cur.x = m->parent_item->menu->cur.x + m->parent_item->menu->cur.w; bottom = m->parent_item->menu->cur.y + m->parent_item->y; if (m->cur.h > m->zone->h) { if (bottom > (m->zone->h / 2)) m->cur.y = (bottom - (m->ch + 1)); else m->cur.y = bottom - m->cy; } else { if (((bottom + m->cur.h - m->cy) > m->zone->h) && (bottom > (m->zone->h / 2))) m->cur.y = (bottom - (m->ch + 1)) + m->parent_item->h; else m->cur.y = bottom - m->cy; } printf("Menu Reposition: %d: %d %d\n", m->id, m->cur.x, m->cur.y); EINA_LIST_FOREACH(m->items, l, mi) if ((mi->active) && (mi->submenu)) _e_menu_reposition(mi->submenu); } static void _e_menu_layout_update(E_Menu *m) { Eina_List *l; E_Menu_Item *mi; Eina_Bool icons = EINA_FALSE; Eina_Bool labels = EINA_FALSE; Eina_Bool submenus = EINA_FALSE; Eina_Bool toggles = EINA_FALSE; Evas_Coord mw = 0, mh = 0, bw = 0, bh = 0; int miw = 0, mih = 0; int mlw = 0, mlh = 0; int msw = 0, msh = 0; int mtw = 0, mth = 0; e_box_freeze(m->o_con); EINA_LIST_FOREACH(m->items, l, mi) { if ((mi->icon) || (mi->o_icon)) icons = EINA_TRUE; if (mi->label) labels = EINA_TRUE; if (mi->submenu) submenus = EINA_TRUE; if ((mi->check) || (mi->radio)) toggles = EINA_TRUE; if (mi->iw > miw) miw = mi->iw; if (mi->ih > mih) mih = mi->ih; if (mi->lw > mlw) mlw = mi->lw; if (mi->lh > mlh) mlh = mi->lh; if (mi->subw > msw) msw = mi->subw; if (mi->subh > msh) msh = mi->subh; if (mi->tw > mtw) mtw = mi->tw; if (mi->th > mth) mth = mi->th; } if (labels) { if (submenus) { if (mlh < msh) mlh = msh; } if (toggles) { if (mlh < mth) mlh = mth; } if ((icons) && (mih > 0)) { miw = (miw * mlh) / mih; miw = mlh; } mw = (mlw + miw + msw + mtw); mh = mlh; } else if (icons) { if (submenus) { if (mih < msh) mih = msh; } if (toggles) { if (mih < mth) mih = mth; } mw = (miw + mtw + msw); mh = mih; } else if (toggles) { if (submenus) { if (mth < msh) mth = msh; } mw = (mtw + msw); mh = mth; } EINA_LIST_FOREACH(m->items, l, mi) { if (mi->separator) e_box_pack_options_set(mi->o_separator, 1, 1, 1, 0, 0.5, 0.5, mi->sepw, mi->seph, -1, mi->seph); else { e_box_freeze(mi->o_con); if (toggles) e_box_pack_options_set(mi->o_toggle, 1, 1, 0, 1, 0.5, 0.5, mtw, mth, -1, -1); else e_box_pack_options_set(mi->o_toggle, 1, 1, 0, 0, 0.5, 0.5, 0, 0, 0, 0); if (icons) { if (mi->o_icon_bg) e_box_pack_options_set(mi->o_icon_bg, 1, 1, 0, 1, 0.5, 0.5, miw, mih, -1, -1); else e_box_pack_options_set(mi->o_icon, 1, 1, 0, 1, 0.5, 0.5, miw, mih, -1, -1); } else e_box_pack_options_set(mi->o_icon, 1, 1, 0, 1, 0.5, 0.5, 0, 0, 0, 0); if (labels) e_box_pack_options_set(mi->o_lbl, 1, 1, 0, 1, 0.5, 0.5, mlw, mlh, -1, -1); else e_box_pack_options_set(mi->o_lbl, 1, 1, 0, 0, 0.5, 0.5, 0, 0, 0, 0); if (submenus) e_box_pack_options_set(mi->o_submenu, 1, 1, 0, 1, 0.5, 0.5, msw, msh, -1, -1); else e_box_pack_options_set(mi->o_submenu, 1, 1, 0, 0, 0.5, 0.5, 0, 0, 0, 0); edje_extern_object_min_size_set(mi->o_con, mw, mh); edje_object_part_swallow(mi->o_bg, "e.swallow.content", mi->o_con); edje_object_size_min_calc(mi->o_bg, &mw, &mh); e_box_pack_options_set(mi->o_bg, 1, 1, 1, 0, 0.5, 0.5, mw, mh, -1, -1); e_box_thaw(mi->o_con); } } e_box_size_min_get(m->o_con, &bw, &bh); edje_extern_object_min_size_set(m->o_con, bw, bh); edje_extern_object_max_size_set(m->o_con, bw, bh); edje_object_part_swallow(m->o_bg, "e.swallow.content", m->o_con); edje_object_size_min_calc(m->o_bg, &mw, &mh); e_box_thaw(m->o_con); m->cur.w = mw; m->cur.h = mh; } static void _e_menu_unrealize(E_Menu *m) { Eina_List *l; E_Menu_Item *mi; if (!m->realized) return; evas_event_freeze(m->evas); e_box_freeze(m->o_con); EINA_LIST_FOREACH(m->items, l, mi) _e_menu_item_unrealize(mi); e_box_thaw(m->o_con); if (m->header.icon) evas_object_del(m->header.icon); m->header.icon = NULL; if (m->o_bg) evas_object_del(m->o_bg); m->o_bg = NULL; if (m->o_con) evas_object_del(m->o_con); m->o_con = NULL; evas_event_thaw(m->evas); e_canvas_del(m->ee); ecore_evas_free(m->ee); m->ee = NULL; m->evas = NULL; m->cur.visible = EINA_FALSE; m->prev.visible = EINA_FALSE; m->realized = EINA_FALSE; m->zone = NULL; } static void _e_menu_deactivate_above(E_Menu *m) { Eina_List *l; E_Menu *pm; Eina_Bool above = EINA_FALSE; EINA_LIST_FOREACH(_active_menus, l, pm) { if (above) { e_menu_deactivate(pm); pm->parent_item = NULL; } if (m == pm) above = EINA_TRUE; // e_object_unref(E_OBJECT(pm)); } } static int _e_menu_active_call(void) { E_Menu_Item *mi; mi = _active_item; if (mi) { if (mi->submenu) return 0; if (mi->check) e_menu_item_toggle_set(mi, !mi->toggle); if ((mi->radio) && (!e_menu_item_toggle_get(mi))) e_menu_item_toggle_set(mi, 1); if (mi->cb.func) mi->cb.func(mi->cb.data, mi->menu, mi); return 1; } return -1; } static void _e_menu_deactivate_all(void) { Eina_List *l; E_Menu *m; EINA_LIST_FOREACH(_active_menus, l, m) { e_menu_deactivate(m); m->parent_item = NULL; } } static void _e_menu_item_realize(E_Menu_Item *mi) { Evas *evas; evas = mi->menu->evas; if (mi->separator) { mi->o_separator = edje_object_add(evas); e_theme_edje_object_set(mi->o_separator, "base/theme/menus", "e/widgets/menu/default/separator"); evas_object_show(mi->o_separator); edje_object_size_min_calc(mi->o_separator, &mi->sepw, &mi->seph); e_box_pack_end(mi->menu->o_con, mi->o_separator); } else { mi->o_bg = edje_object_add(evas); evas_object_intercept_move_callback_add(mi->o_bg, _e_menu_item_cb_move, mi); evas_object_intercept_resize_callback_add(mi->o_bg, _e_menu_item_cb_resize, mi); if ((mi->submenu) || (mi->submenu_pre_cb.func)) { if (!e_theme_edje_object_set(mi->o_bg, "base/theme/menus", "e/widgets/menu/default/submenu_bg")) e_theme_edje_object_set(mi->o_bg, "base/theme/menus", "e/widgets/menu/default/item_bg"); } else e_theme_edje_object_set(mi->o_bg, "base/theme/menus", "e/widgets/menu/default/item_bg"); evas_object_show(mi->o_bg); mi->o_con = e_box_add(evas); e_box_homogenous_set(mi->o_con, 0); e_box_orientation_set(mi->o_con, 1); evas_object_show(mi->o_con); e_box_freeze(mi->o_con); if (mi->check) { mi->o_toggle = edje_object_add(evas); e_theme_edje_object_set(mi->o_toggle, "base/theme/menus", "e/widgets/menu/default/check"); evas_object_pass_events_set(mi->o_toggle, 1); evas_object_show(mi->o_toggle); e_box_pack_end(mi->o_con, mi->o_toggle); edje_object_size_min_calc(mi->o_toggle, &mi->tw, &mi->th); } else if (mi->radio) { mi->o_toggle = edje_object_add(evas); e_theme_edje_object_set(mi->o_toggle, "base/theme/menus", "e/widgets/menu/default/radio"); evas_object_pass_events_set(mi->o_toggle, 1); evas_object_show(mi->o_toggle); e_box_pack_end(mi->o_con, mi->o_toggle); edje_object_size_min_calc(mi->o_toggle, &mi->tw, &mi->th); } else { mi->o_toggle = evas_object_rectangle_add(evas); evas_object_color_set(mi->o_toggle, 0, 0, 0, 0); evas_object_pass_events_set(mi->o_toggle, 1); e_box_pack_end(mi->o_con, mi->o_toggle); } if ((mi->icon) || (mi->realize_cb.func)) { int icon_w = 0, icon_h = 0; mi->o_icon_bg = edje_object_add(evas); if (e_theme_edje_object_set(mi->o_icon_bg, "base/theme/menus", "e/widgets/menu/default/icon")) evas_object_show(mi->o_icon_bg); else { evas_object_del(mi->o_icon_bg); mi->o_icon_bg = NULL; } if (mi->icon) { if (mi->icon_key) { Evas_Coord iww, ihh; mi->o_icon = edje_object_add(evas); if (edje_object_file_set(mi->o_icon, mi->icon, mi->icon_key)) { edje_object_size_max_get(mi->o_icon, &iww, &ihh); icon_w = iww; icon_h = ihh; } else { evas_object_del(mi->o_icon); mi->o_icon = NULL; } } if (!mi->o_icon) { mi->o_icon = e_icon_add(evas); e_icon_scale_size_set(mi->o_icon, e_util_icon_size_normalize(24 * e_scale)); e_icon_preload_set(mi->o_icon, 1); e_icon_file_set(mi->o_icon, mi->icon); e_icon_fill_inside_set(mi->o_icon, 1); e_icon_size_get(mi->o_icon, &icon_w, &icon_h); } } if (_e_menu_item_realize_call(mi)) { e_icon_fill_inside_set(mi->o_icon, 1); e_icon_size_get(mi->o_icon, &icon_w, &icon_h); } evas_object_pass_events_set(mi->o_icon, 1); evas_object_show(mi->o_icon); if (mi->o_icon_bg) { edje_extern_object_min_size_set(mi->o_icon, icon_w, icon_h); edje_object_part_swallow(mi->o_icon_bg, "e.swallow.content", mi->o_icon); edje_object_size_min_calc(mi->o_icon_bg, &mi->iw, &mi->ih); edje_extern_object_min_size_set(mi->o_icon, 0, 0); edje_object_part_swallow(mi->o_icon_bg, "e.swallow.content", mi->o_icon); e_box_pack_end(mi->o_con, mi->o_icon_bg); } else { Evas_Object *o; o = edje_object_add(evas); e_icon_size_get(mi->o_icon, &mi->iw, &mi->ih); e_box_pack_end(mi->o_con, o); } } else { mi->o_icon = evas_object_rectangle_add(evas); evas_object_color_set(mi->o_icon, 0, 0, 0, 0); evas_object_pass_events_set(mi->o_icon, 1); e_box_pack_end(mi->o_con, mi->o_icon); } if (mi->label) { mi->o_lbl = edje_object_add(evas); e_theme_edje_object_set(mi->o_lbl, "base/theme/menus", "e/widgets/menu/default/label"); edje_object_part_text_set(mi->o_lbl, "e.text.label", mi->label); evas_object_pass_events_set(mi->o_lbl, 1); evas_object_show(mi->o_lbl); e_box_pack_end(mi->o_con, mi->o_lbl); edje_object_size_min_calc(mi->o_lbl, &mi->lw, &mi->lh); } else { mi->o_lbl = evas_object_rectangle_add(evas); evas_object_color_set(mi->o_lbl, 0, 0, 0, 0); evas_object_pass_events_set(mi->o_lbl, 1); e_box_pack_end(mi->o_con, mi->o_lbl); } if ((mi->submenu) || (mi->submenu_pre_cb.func)) { mi->o_submenu = edje_object_add(evas); e_theme_edje_object_set(mi->o_submenu, "base/theme/menus", "e/widgets/menu/default/submenu"); evas_object_pass_events_set(mi->o_submenu, 1); evas_object_show(mi->o_submenu); e_box_pack_end(mi->o_con, mi->o_submenu); edje_object_size_min_calc(mi->o_submenu, &mi->subw, &mi->subh); } else { mi->o_submenu = evas_object_rectangle_add(evas); evas_object_color_set(mi->o_submenu, 0, 0, 0, 0); evas_object_pass_events_set(mi->o_submenu, 1); e_box_pack_end(mi->o_con, mi->o_submenu); } edje_object_part_swallow(mi->o_bg, "e.swallow.content", mi->o_con); mi->o_event = evas_object_rectangle_add(evas); evas_object_color_set(mi->o_event, 0, 0, 0, 0); evas_object_layer_set(mi->o_event, 1); evas_object_repeat_events_set(mi->o_event, 1); evas_object_event_callback_add(mi->o_event, EVAS_CALLBACK_MOUSE_IN, _e_menu_item_cb_in, mi); evas_object_event_callback_add(mi->o_event, EVAS_CALLBACK_MOUSE_OUT, _e_menu_item_cb_out, mi); evas_object_show(mi->o_event); e_box_thaw(mi->o_con); e_box_pack_end(mi->menu->o_con, mi->o_bg); } if (mi->active) e_menu_item_active_set(mi, 1); if (mi->toggle) e_menu_item_toggle_set(mi, 1); if (mi->disabled) e_menu_item_disabled_set(mi, 1); } static void _e_menu_item_unrealize(E_Menu_Item *mi) { if (mi->o_con) e_box_freeze(mi->o_con); if (mi->o_separator) evas_object_del(mi->o_separator); mi->o_separator = NULL; if (mi->o_bg) evas_object_del(mi->o_bg); mi->o_bg = NULL; if (mi->o_toggle) evas_object_del(mi->o_toggle); mi->o_toggle = NULL; if (mi->o_icon_bg) evas_object_del(mi->o_icon_bg); mi->o_icon_bg = NULL; if (mi->o_icon) evas_object_del(mi->o_icon); mi->o_icon = NULL; if (mi->o_lbl) evas_object_del(mi->o_lbl); mi->o_lbl = NULL; if (mi->o_submenu) evas_object_del(mi->o_submenu); mi->o_submenu = NULL; if (mi->o_event) evas_object_del(mi->o_event); mi->o_event = NULL; if (mi->o_con) { e_box_thaw(mi->o_con); evas_object_del(mi->o_con); } mi->o_con = NULL; } static Eina_Bool _e_menu_item_realize_call(E_Menu_Item *mi) { if ((mi) && (mi->realize_cb.func)) { mi->realize_cb.func(mi->realize_cb.data, mi->menu, mi); return EINA_TRUE; } return EINA_FALSE; } static void _e_menu_item_submenu_activate(E_Menu_Item *mi) { if (!mi->menu->active) return; if (mi->menu->fast_mouse) { mi->menu->pending_new_submenu = EINA_TRUE; return; } mi->menu->pending_new_submenu = EINA_FALSE; _e_menu_deactivate_above(mi->menu); if (mi->submenu_pre_cb.func) mi->submenu_pre_cb.func(mi->submenu_pre_cb.data, mi->menu, mi); if (mi->submenu) { E_Menu *m; m = mi->submenu; e_object_ref(E_OBJECT(m)); m->parent_item = mi; _e_menu_activate_internal(m, mi->menu->zone); _e_menu_realize(m); _e_menu_reposition(m); e_object_unref(E_OBJECT(m)); } } static void _e_menu_item_submenu_deactivate(E_Menu_Item *mi) { if (!mi->menu->active) return; if (mi->submenu_post_cb.func) { printf("Menu Calling Submenu Post\n"); mi->submenu_post_cb.func(mi->submenu_post_cb.data, mi->menu, mi); } /* else */ /* { */ /* if (mi->submenu) */ /* mi->submenu->active = EINA_FALSE; */ /* if (mi->menu) */ /* mi->menu->active = EINA_TRUE; */ /* } */ }