elm menu+toolbar: Rewrite the menu, add separator and submenus. Fix the separator in the toolbar

SVN revision: 43019
This commit is contained in:
Jonathan Atton 2009-10-11 13:37:01 +00:00
parent dc3083f1c0
commit 2dc274cc02
7 changed files with 3101 additions and 2310 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,9 @@
#include <Elementary.h>
#ifndef ELM_LIB_QUICKLAUNCH
static Evas_Object *win, *bg, *notify, *menu, *rect, *ic;;
static char buf[PATH_MAX];
static void
_show(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
@ -12,15 +15,128 @@ _show(void *data, Evas *e, Evas_Object *obj, void *event_info)
evas_object_show(data);
}
static void _populate_4(Elm_Menu_Item *item)
{
Evas_Object *ic;
Elm_Menu_Item *item2, *item3;
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
elm_menu_item_add(menu, item, ic, "menu 2", NULL, NULL);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
item2 = elm_menu_item_add(menu, item, ic, "menu 3", NULL, NULL);
elm_menu_item_separator_add(menu,item);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
item3 = elm_menu_item_add(menu, item, ic, "Disabled item", NULL, NULL);
elm_menu_item_disabled_set(item3, 1);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
item3 = elm_menu_item_add(menu, item, ic, "Disabled item", NULL, NULL);
elm_menu_item_disabled_set(item3, 1);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
item3 = elm_menu_item_add(menu, item, ic, "Disabled item", NULL, NULL);
elm_menu_item_disabled_set(item3, 1);
}
static void _populate_3(Elm_Menu_Item *item)
{
Evas_Object *ic;
Elm_Menu_Item *item2, *item3;
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
elm_menu_item_add(menu, item, ic, "menu 2", NULL, NULL);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
item2 = elm_menu_item_add(menu, item, ic, "menu 3", NULL, NULL);
elm_menu_item_separator_add(menu,item);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
item3 = elm_menu_item_add(menu, item, ic, "Disabled item", NULL, NULL);
elm_menu_item_disabled_set(item3, 1);
}
static void _populate_2(Elm_Menu_Item *item)
{
Evas_Object *ic;
Elm_Menu_Item *item2, *item3;
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
elm_menu_item_add(menu, item, ic, "menu 2", NULL, NULL);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
item2 = elm_menu_item_add(menu, item, ic, "menu 3", NULL, NULL);
_populate_3(item2);
elm_menu_item_separator_add(menu,item);
elm_menu_item_separator_add(menu,item);
elm_menu_item_separator_add(menu,item);
elm_menu_item_separator_add(menu,item);
elm_menu_item_separator_add(menu,item);
elm_menu_item_separator_add(menu,item);
elm_menu_item_separator_add(menu,item);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
item2 = elm_menu_item_add(menu, item, ic, "menu 2", NULL, NULL);
elm_menu_item_separator_add(menu,item);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
item3 = elm_menu_item_add(menu, item, ic, "Disabled item", NULL, NULL);
elm_menu_item_disabled_set(item3, 1);
_populate_4(item2);
}
static void _populate_1(Elm_Menu_Item *item)
{
Elm_Menu_Item *item2;
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
item2 = elm_menu_item_add(menu, item, ic, "menu 1", NULL, NULL);
_populate_2(item2);
}
void
test_menu(void *data, Evas_Object *obj, void *event_info)
{
Evas_Object *win, *bg, *notify, *menu, *rect;
char buf[PATH_MAX];
const Eina_List *l;
const char *transition;
Elm_Menu_Item *item;
win = elm_win_add(NULL, "Menu", ELM_WIN_BASIC);
elm_win_title_set(win, "Menu");
@ -39,8 +155,20 @@ test_menu(void *data, Evas_Object *obj, void *event_info)
menu = elm_menu_add(win);
elm_menu_item_add(menu, NULL, "first item", NULL, NULL);
elm_menu_item_add(menu, NULL, "second item", NULL, NULL);
item = elm_menu_item_add(menu, NULL, NULL, "first item", NULL, NULL);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
item = elm_menu_item_add(menu, NULL, ic, "second item", NULL, NULL);
_populate_1(item);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
elm_menu_item_add(menu, item, ic, "sub menu", NULL, NULL);
evas_object_event_callback_add(rect, EVAS_CALLBACK_MOUSE_DOWN, _show, menu);

View File

@ -41,9 +41,10 @@ tb_5(void *data, Evas_Object *obj, void *event_info)
void
test_toolbar(void *data, Evas_Object *obj, void *event_info)
{
Evas_Object *win, *bg, *bx, *tb, *ic, *ph;
Evas_Object *win, *bg, *bx, *tb, *ic, *ph, *menu;
Evas_Object *ph1, *ph2, *ph3, *ph4;
Elm_Toolbar_Item *item;
Elm_Menu_Item *menu_item;
char buf[PATH_MAX];
win = elm_win_add(NULL, "toolbar", ELM_WIN_BASIC);
@ -61,6 +62,7 @@ test_toolbar(void *data, Evas_Object *obj, void *event_info)
evas_object_show(bx);
tb = elm_toolbar_add(win);
elm_toolbar_homogenous_set(tb, 0);
evas_object_size_hint_weight_set(tb, 0.0, 0.0);
evas_object_size_hint_align_set(tb, EVAS_HINT_FILL, 0.0);
@ -83,7 +85,7 @@ test_toolbar(void *data, Evas_Object *obj, void *event_info)
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
elm_toolbar_item_add(tb, ic, "Here", tb_3, ph4);
elm_toolbar_item_add(tb, ic, "H", tb_3, ph4);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
@ -101,21 +103,27 @@ test_toolbar(void *data, Evas_Object *obj, void *event_info)
item = elm_toolbar_item_add(tb, ic, "Menu", NULL, NULL);
elm_toolbar_item_menu_set(item, 1);
elm_toolbar_menu_parent_set(tb, win);
menu = elm_toolbar_item_menu_get(item);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
elm_toolbar_item_menu_item_add(item, ic, "Here", tb_3, ph4);
elm_menu_item_add(menu, NULL, ic, "Here", tb_3, ph4);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
elm_toolbar_item_menu_item_add(item, ic, "Comes", tb_4, ph4);
menu_item = elm_menu_item_add(menu, NULL, ic, "Comes", tb_4, ph4);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
elm_toolbar_item_menu_item_add(item, ic, "Elementary", tb_5, ph4);
elm_menu_item_add(menu, menu_item, ic, "hey ho", tb_4, ph4);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
menu_item = elm_menu_item_add(menu, NULL, ic, "Elementary", tb_5, ph4);
elm_box_pack_end(bx, tb);
evas_object_show(tb);

View File

@ -315,7 +315,6 @@ extern "C" {
* anchor
* hoversel_vertical
* hoversel_vertical_entry
* menu
*/
/* smart callbacks called:
* "clicked" - the user clicked the button
@ -598,7 +597,6 @@ extern "C" {
*/
typedef struct _Elm_Toolbar_Item Elm_Toolbar_Item;
typedef struct _Elm_Toolbar_Menu_Item Elm_Toolbar_Menu_Item;
EAPI Evas_Object *elm_toolbar_add(Evas_Object *parent);
EAPI void elm_toolbar_icon_size_set(Evas_Object *obj, int icon_size);
EAPI void elm_toolbar_align_set(Evas_Object *obj, double align);
@ -615,8 +613,8 @@ extern "C" {
EAPI void elm_toolbar_item_separator_set(Elm_Toolbar_Item *item, Eina_Bool separator);
EAPI Eina_Bool elm_toolbar_item_separator_get(Elm_Toolbar_Item *item);
EAPI void elm_toolbar_item_menu_set(Elm_Toolbar_Item *item, Eina_Bool menu);
EAPI Evas_Object *elm_toolbar_item_menu_get(Elm_Toolbar_Item *item);
EAPI void elm_toolbar_menu_parent_set(Evas_Object *obj, Evas_Object *parent);
EAPI Elm_Toolbar_Menu_Item *elm_toolbar_item_menu_item_add(Elm_Toolbar_Item *item, Evas_Object *icon, const char *label, void (*func) (void *data, Evas_Object *obj, void *event_info), const void *data);
EAPI void elm_toolbar_scrollable_set(Evas_Object *obj, Eina_Bool scrollable);
EAPI void elm_toolbar_homogenous_set(Evas_Object *obj, Eina_Bool homogenous);
/* smart callbacks called:
@ -627,9 +625,15 @@ extern "C" {
EAPI Evas_Object * elm_menu_add(Evas_Object *parent);
EAPI void elm_menu_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
EAPI void elm_menu_parent_set(Evas_Object *obj, Evas_Object *parent);
EAPI Elm_Menu_Item * elm_menu_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func) (void *data, Evas_Object *obj, void *event_info), const void *data);
EAPI Elm_Menu_Item * elm_menu_item_add(Evas_Object *obj, Elm_Menu_Item *parent, Evas_Object *icon, const char *label, void (*func) (void *data, Evas_Object *obj, void *event_info), const void *data);
EAPI Elm_Menu_Item * elm_menu_item_separator_add(Evas_Object *obj, Elm_Menu_Item *parent);
EAPI void elm_menu_item_label_set(Elm_Menu_Item *item, const char *label);
EAPI const char * elm_menu_item_label_get(Elm_Menu_Item *item);
EAPI void elm_menu_item_icon_set(Elm_Menu_Item *item, Evas_Object *icon);
EAPI void elm_menu_item_disabled_set(Elm_Menu_Item *item, Eina_Bool disabled);
EAPI void elm_menu_item_del(Elm_Menu_Item *item);
EAPI const Eina_List*elm_menu_item_subitems_get(Elm_Menu_Item *item);
/* smart callbacks called:
* "clicked" - the user clicked the empty space in the menu to dismiss
*/

View File

@ -7,64 +7,136 @@
/**
* @defgroup Menu menu
*
* A menu is a list of items display on top of the window. It can be used to
* A menu is a list of items display on top of the window. Each item can have a sub-menu. It can be used to
* display a menu on right click, in a toolbar ...
*
* This widget use a hover and each item is a button with the style "menu"
*/
typedef struct _Widget_Data Widget_Data;
struct _Menu_Item
{
Evas_Object *parent;
Evas_Object *menu;
Evas_Object *o;
Elm_Menu_Item *parent;
Eina_Bool separator;
Eina_Bool disabled;
//if classic item or submenu
Evas_Object *icon;
const char *label;
void (*func) (void *data, Evas_Object *obj, void *event_info);
const void *data;
//
//if submenu
Eina_Bool open;
Evas_Object *hv, *bx, *location;
Eina_List *items;
//
};
struct _Widget_Data
{
Evas_Object *hv, *bx, *location, *parent;
Eina_List *menu;
Eina_List *items;
Evas_Coord xloc, yloc;
};
static void _del_hook(Evas_Object *obj);
static void _theme_hook(Evas_Object *obj);
static void _sizing_eval(Evas_Object *obj);
static void _submenu_sizing_eval(Elm_Menu_Item *parent);
static void _item_sizing_eval(Elm_Menu_Item *item);
static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _submenu_hide(Elm_Menu_Item *item);
static void _submenu_open(void *data, Evas_Object *obj, const char *emission, const char *source);
static void
static void
_del_hook(Evas_Object *obj)
{
Eina_List *l, *ll = NULL;
Elm_Menu_Item *item;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
ll = eina_list_append(ll, wd->items);
EINA_LIST_FOREACH(ll, ll, l)
{
EINA_LIST_FREE(l, item)
{
ll = eina_list_append(ll, item->items);
if(item->label)
eina_stringshare_del(item->label);
if(item->bx)
{
evas_object_del(item->hv);
evas_object_del(item->location);
}
free(item);
}
}
free(wd);
}
static void
static void
_theme_hook(Evas_Object *obj)
{
Eina_List *l, *_l, *ll = NULL;
Elm_Menu_Item *item;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if(!wd) return;
//_elm_theme_set(wd->base, "menu", "base", "default");
//edje_object_scale_set(wd->base, elm_widget_scale_get(obj) *
// _elm_config->scale);
ll = eina_list_append(ll, wd->items);
EINA_LIST_FOREACH(ll, ll, l)
{
EINA_LIST_FOREACH(l, _l, item)
{
ll = eina_list_append(ll, item->items);
if(item->separator)
_elm_theme_set(item->o, "menu", "separator", elm_widget_style_get(obj));
else if(item->bx)
{
_elm_theme_set(item->o, "menu", "item_with_submenu", elm_widget_style_get(obj));
elm_menu_item_label_set(item, item->label);
elm_menu_item_icon_set(item, item->icon);
}
else
{
_elm_theme_set(item->o, "menu", "item", elm_widget_style_get(obj));
elm_menu_item_label_set(item, item->label);
elm_menu_item_icon_set(item, item->icon);
}
if(item->disabled)
edje_object_signal_emit(item->o, "elm,state,disabled", "elm");
else
edje_object_signal_emit(item->o, "elm,state,enabled", "elm");
edje_object_message_signal_process(item->o);
edje_object_scale_set(item->o, elm_widget_scale_get(obj) * _elm_config->scale);
}
}
_sizing_eval(obj);
}
static void
_sizing_eval(Evas_Object *obj)
{
Eina_List *l;
Elm_Menu_Item *item;
Evas_Coord x_p,y_p,w_p,h_p,x2,y2,w2,h2,bx,by,bw,bh;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd || !wd->parent) return;
EINA_LIST_FOREACH(wd->items,l,item)
{
_item_sizing_eval(item);
}
evas_object_geometry_get(wd->location, &x_p, &y_p, &w_p, &h_p);
evas_object_geometry_get(wd->parent, &x2, &y2, &w2, &h2);
evas_object_geometry_get(wd->bx, &bx, &by, &bw, &bh);
@ -72,7 +144,6 @@ _sizing_eval(Evas_Object *obj)
x_p = wd->xloc;
y_p = wd->yloc;
//printf("%d %d %d %d\n%d %d %d %d\n\n", x_p, y_p, bw, bh,x2, y2, w2, h2);
if(x_p+bw > x2+w2)
x_p -= x_p+bw - (x2+w2);
if(x_p < x2)
@ -83,15 +154,76 @@ _sizing_eval(Evas_Object *obj)
if(y_p < y2)
y_p += y2 - y_p;
//printf("%d %d %d %d\n\n\n", x_p, y_p, bw, bh);
evas_object_move(wd->location, x_p, y_p);
evas_object_resize(wd->location, bw, h_p);
evas_object_size_hint_min_set(wd->location, bw, h_p);
evas_object_size_hint_max_set(wd->location, bw, h_p);
elm_hover_target_set(wd->hv, wd->location);
EINA_LIST_FOREACH(wd->items,l,item)
{
if(item->open)
_submenu_sizing_eval(item);
}
}
static void
static void
_submenu_sizing_eval(Elm_Menu_Item *parent)
{
Eina_List *l;
Elm_Menu_Item *item;
Evas_Coord x_p,y_p,w_p,h_p,x2,y2,w2,h2,bx,by,bw,bh,px,py,pw,ph;
Widget_Data *wd = elm_widget_data_get(parent->menu);
EINA_LIST_FOREACH(parent->items,l,item)
{
_item_sizing_eval(item);
}
evas_object_geometry_get(parent->location, &x_p, &y_p, &w_p, &h_p);
evas_object_geometry_get(parent->o, &x2, &y2, &w2, &h2);
evas_object_geometry_get(parent->bx, &bx, &by, &bw, &bh);
evas_object_geometry_get(wd->parent, &px, &py, &pw, &ph);
x_p = x2+w2;
y_p = y2;
if(x_p + bw > px + pw)
x_p = x2-bw;
if(y_p+bh > py+ph)
y_p -= y_p+bh - (py+ph);
if(y_p < py)
y_p += y_p - y_p;
evas_object_move(parent->location, x_p, y_p);
evas_object_resize(parent->location, bw, h_p);
evas_object_size_hint_min_set(parent->location, bw, h_p);
evas_object_size_hint_max_set(parent->location, bw, h_p);
elm_hover_target_set(parent->hv, parent->location);
EINA_LIST_FOREACH(parent->items,l,item)
{
if(item->open)
_submenu_sizing_eval(item);
}
}
static void
_item_sizing_eval(Elm_Menu_Item *item)
{
Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
if(!item->separator)
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
edje_object_size_min_restricted_calc(item->o, &minw, &minh, minw, minh);
if(!item->separator)
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
evas_object_size_hint_min_set(item->o, minw, minh);
evas_object_size_hint_max_set(item->o, maxw, maxh);
}
static void
_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
Widget_Data *wd = elm_widget_data_get(data);
@ -99,7 +231,7 @@ _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
_sizing_eval(data);
}
static void
static void
_menu_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
Widget_Data *wd = elm_widget_data_get(data);
@ -107,7 +239,7 @@ _menu_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
_sizing_eval(data);
}
static void
static void
_parent_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
Widget_Data *wd = elm_widget_data_get(data);
@ -115,32 +247,169 @@ _parent_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
_sizing_eval(data);
}
static void
static void
_item_move_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
Elm_Menu_Item *item = data;
if(item->open)
_submenu_sizing_eval(item);
}
static void
_menu_hide(void *data, Evas_Object *obj, void *event_info)
{
Eina_List *l;
Elm_Menu_Item *item2;
Widget_Data *wd = elm_widget_data_get(data);
evas_object_hide(wd->hv);
evas_object_hide(data);
evas_object_smart_callback_call(data, "clicked", event_info);
EINA_LIST_FOREACH(wd->items, l, item2)
{
if(item2->open)
_submenu_hide(item2);
}
}
static void
_menu_item_select(void *data, Evas_Object *obj, void *event_info)
static void
_submenu_hide(Elm_Menu_Item *item)
{
Elm_Menu_Item *it = data;
if (it->func) it->func((void *)(it->data), it->o, it);
Eina_List *l;
Elm_Menu_Item *item2;
_menu_hide(it->parent, NULL, NULL);
evas_object_hide(item->hv);
item->open = EINA_FALSE;
EINA_LIST_FOREACH(item->items, l, item2)
{
if(item2->open)
_submenu_hide(item2);
}
}
static void
static void
_menu_item_select(void *data, Evas_Object *obj, const char *emission, const char *source)
{
Elm_Menu_Item *it = data;
if(it->items)
{
if(!it->open)
_submenu_open(it, NULL, NULL, NULL);
else
_submenu_hide(it);
}
else
_menu_hide(it->menu, NULL, NULL);
if (it->func) it->func((void *)(it->data), it->menu, it);
}
static void
_menu_item_activate(void *data, Evas_Object *obj, const char *emission, const char *source)
{
Eina_List *l;
Elm_Menu_Item *item2;
Elm_Menu_Item *item = data;
if(item->parent)
{
EINA_LIST_FOREACH(item->parent->items, l, item2)
{
if(item2->open && item2 != item)
_submenu_hide(item2);
}
}
else
{
Widget_Data *wd = elm_widget_data_get(item->menu);
EINA_LIST_FOREACH(wd->items, l, item2)
{
if(item2->open && item2 != item)
_submenu_hide(item2);
}
}
}
static void
_submenu_open(void *data, Evas_Object *obj, const char *emission, const char *source)
{
Elm_Menu_Item *it = data;
it->open = EINA_TRUE;
evas_object_show(it->hv);
_sizing_eval(it->menu);
}
static void
_show(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
Widget_Data *wd = elm_widget_data_get(data);
evas_object_show(wd->hv);
}
static void
_item_obj_create(Elm_Menu_Item *item)
{
Widget_Data *wd = elm_widget_data_get(item->menu);
item->o = edje_object_add(evas_object_evas_get(wd->bx));
evas_object_size_hint_weight_set(item->o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_fill_set(item->o, EVAS_HINT_FILL, EVAS_HINT_FILL);
_elm_theme_set(item->o, "menu", "item", elm_widget_style_get(item->menu));
edje_object_signal_callback_add(item->o, "elm,action,click", "",
_menu_item_select, item);
edje_object_signal_callback_add(item->o, "elm,action,activate", "",
_menu_item_activate, item);
evas_object_show(item->o);
}
static void
_item_separator_obj_create(Elm_Menu_Item *item)
{
Widget_Data *wd = elm_widget_data_get(item->menu);
item->o = edje_object_add(evas_object_evas_get(wd->bx));
evas_object_size_hint_weight_set(item->o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_fill_set(item->o, EVAS_HINT_FILL, EVAS_HINT_FILL);
_elm_theme_set(item->o, "menu", "separator", elm_widget_style_get(item->menu));
edje_object_signal_callback_add(item->o, "elm,action,activate", "",
_menu_item_activate, item);
evas_object_show(item->o);
}
static void
_item_submenu_obj_create(Elm_Menu_Item *item)
{
Widget_Data *wd = elm_widget_data_get(item->menu);
item->location = elm_icon_add(wd->bx);
item->hv = elm_hover_add(wd->bx);
elm_hover_target_set(item->hv, item->location);
elm_hover_parent_set(item->hv, wd->parent);
elm_hover_style_set(item->hv, "submenu");
item->bx = elm_box_add(wd->bx);
evas_object_event_callback_add(item->bx, EVAS_CALLBACK_RESIZE, _menu_resize, item->menu);
evas_object_size_hint_weight_set(item->bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_show(item->bx);
elm_hover_content_set(item->hv, elm_hover_best_content_location_get(item->hv, ELM_HOVER_AXIS_VERTICAL), item->bx);
_elm_theme_set(item->o, "menu", "item_with_submenu", elm_widget_style_get(item->menu));
elm_menu_item_label_set(item, item->label);
elm_menu_item_icon_set(item, item->icon);
edje_object_signal_callback_add(item->o, "elm,action,open", "",
_submenu_open, item);
evas_object_event_callback_add(item->o, EVAS_CALLBACK_MOVE, _item_move_resize, item);
evas_object_event_callback_add(item->o, EVAS_CALLBACK_RESIZE, _item_move_resize, item);
}
/**
* Add a new menu to the parent
*
@ -149,7 +418,7 @@ _show(void *data, Evas *e, Evas_Object *obj, void *event_info)
*
* @ingroup Menu
*/
EAPI Evas_Object *
EAPI Evas_Object *
elm_menu_add(Evas_Object *parent)
{
Evas_Object *obj;
@ -194,14 +463,31 @@ elm_menu_add(Evas_Object *parent)
* @param obj The menu object.
* @param parent The new parent.
*/
EAPI void
EAPI void
elm_menu_parent_set(Evas_Object *obj, Evas_Object *parent)
{
Eina_List *l, *_l, *ll = NULL;
Elm_Menu_Item *item;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
elm_hover_parent_set(wd->hv, parent);
wd->parent = parent;
ll = eina_list_append(ll, wd->items);
EINA_LIST_FOREACH(ll, ll, l)
{
EINA_LIST_FOREACH(l, _l, item)
{
if(item->hv)
{
elm_hover_parent_set(item->hv, parent);
ll = eina_list_append(ll, item->items);
}
}
}
_sizing_eval(obj);
}
@ -212,7 +498,7 @@ elm_menu_parent_set(Evas_Object *obj, Evas_Object *parent)
* @param x The new position.
* @param y The new position.
*/
EAPI void
EAPI void
elm_menu_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
{
Widget_Data *wd = elm_widget_data_get(obj);
@ -234,38 +520,169 @@ elm_menu_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
* @param data Data sent by the callback.
* #return Returns the new item.
*/
EAPI Elm_Menu_Item *
elm_menu_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func) (void *data, Evas_Object *obj, void *event_info), const void *data)
EAPI Elm_Menu_Item *
elm_menu_item_add(Evas_Object *obj, Elm_Menu_Item *parent, Evas_Object *icon, const char *label, void (*func) (void *data, Evas_Object *obj, void *event_info), const void *data)
{
Evas_Object *bt;
Elm_Menu_Item *item;
Elm_Menu_Item *subitem;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
item = calloc(1, sizeof(Elm_Menu_Item));
if(!item) return NULL;
if(label)
item->label = eina_stringshare_add(label);
item->icon = icon;
item->func = func;
item->data = data;
item->parent = obj;
subitem = calloc(1, sizeof(Elm_Menu_Item));
if(!subitem) return NULL;
subitem->func = func;
subitem->data = data;
subitem->menu = obj;
subitem->parent = parent;
bt = elm_button_add(obj);
item->o = bt;
evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_style_set(bt, "menu");
elm_button_label_set(bt, label);
elm_button_icon_set(bt, icon);
evas_object_smart_callback_add(bt, "clicked", _menu_item_select, item);
elm_box_pack_end(wd->bx, bt);
evas_object_show(bt);
_item_obj_create(subitem);
elm_menu_item_label_set(subitem, label);
elm_menu_item_icon_set(subitem, icon);
wd->menu = eina_list_append(wd->menu, item);
if(parent)
{
if(!parent->bx)
_item_submenu_obj_create(parent);
elm_box_pack_end(parent->bx, subitem->o);
parent->items = eina_list_append(parent->items, subitem);
}
else
{
elm_box_pack_end(wd->bx, subitem->o);
wd->items = eina_list_append(wd->items, subitem);
}
_sizing_eval(obj);
return item;
return subitem;
}
EAPI void
elm_menu_item_label_set(Elm_Menu_Item *item, const char *label)
{
Evas_Coord mw, mh;
if (item->label) eina_stringshare_del(item->label);
if (label)
{
item->label = eina_stringshare_add(label);
edje_object_signal_emit(item->o, "elm,state,text,visible", "elm");
}
else
{
item->label = NULL;
edje_object_signal_emit(item->o, "elm,state,text,hidden", "elm");
}
edje_object_message_signal_process(item->o);
edje_object_part_text_set(item->o, "elm.text", label);
_sizing_eval(item->menu);
}
EAPI const char *
elm_menu_item_label_get(Elm_Menu_Item *item)
{
if(!item) return ;
return item->label;
}
EAPI void
elm_menu_item_icon_set(Elm_Menu_Item *item, Evas_Object *icon)
{
if ((item->icon != icon) && (item->icon))
elm_widget_sub_object_del(item->menu, item->icon);
if ((icon) && (item->icon != icon))
{
item->icon = icon;
elm_widget_sub_object_add(item->menu, icon);
edje_object_part_swallow(item->o, "elm.swallow.content", icon);
edje_object_signal_emit(item->o, "elm,state,icon,visible", "elm");
evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_changed_size_hints, item->menu);
edje_object_message_signal_process(item->o);
_sizing_eval(item->menu);
}
else
item->icon = icon;
}
EAPI void
elm_menu_item_disabled_set(Elm_Menu_Item *item, Eina_Bool disabled)
{
if(disabled == item->disabled) return;
item->disabled = disabled;
if(disabled)
{
edje_object_signal_emit(item->o, "elm,state,disabled", "elm");
if(item->open)
_submenu_hide(item);
}
else
edje_object_signal_emit(item->o, "elm,state,enabled", "elm");
edje_object_message_signal_process(item->o);
}
EAPI Elm_Menu_Item *
elm_menu_item_separator_add(Evas_Object *obj, Elm_Menu_Item *parent)
{
Elm_Menu_Item *subitem;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
subitem = calloc(1, sizeof(Elm_Menu_Item));
if(!subitem) return NULL;
subitem->menu = obj;
subitem->separator = 1;
_item_separator_obj_create(subitem);
if(!parent)
{
elm_box_pack_end(wd->bx, subitem->o);
wd->items = eina_list_append(wd->items, subitem);
}
else
{
if(!parent->bx)
_item_submenu_obj_create(parent);
elm_box_pack_end(parent->bx, subitem->o);
parent->items = eina_list_append(parent->items, subitem);
}
_sizing_eval(obj);
return subitem;
}
EAPI void
elm_menu_item_del(Elm_Menu_Item *item)
{
Eina_List *l;
Elm_Menu_Item *_item;
if(!item) return;
EINA_LIST_FREE(item->items, _item)
elm_menu_item_del(_item);
if(item->label) eina_stringshare_del(item->label);
if(item->icon) evas_object_del(item->icon);
if(item->hv) evas_object_del(item->hv);
if(item->location) evas_object_del(item->location);
if(item->o) evas_object_del(item->o);
if(item->parent)
item->parent->items = eina_list_remove(item->parent->items, item);
else
{
Widget_Data *wd = elm_widget_data_get(item->menu);
wd->items = eina_list_remove(wd->items, item);
}
free(item);
}
EAPI const Eina_List *
elm_menu_item_subitems_get(Elm_Menu_Item *item)
{
return item->items;
}

View File

@ -17,15 +17,6 @@ struct _Widget_Data
double align;
};
struct _Elm_Toolbar_Menu_Item
{
Elm_Toolbar_Item *parent;
Elm_Menu_Item *item;
void (*func) (void *data, Evas_Object *obj, void *event_info);
const void *data;
};
struct _Elm_Toolbar_Item
{
Evas_Object *obj;
@ -39,7 +30,6 @@ struct _Elm_Toolbar_Item
Eina_Bool separator : 1;
Eina_Bool menu;
Eina_List *menu_items;
Evas_Object *o_menu;
};
@ -51,7 +41,7 @@ static void _theme_hook(Evas_Object *obj);
static void _sizing_eval(Evas_Object *obj);
static void _menu_move_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _menu_hide(void *data, Evas_Object *obj, void *event_info);
static void _menu_hide(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _menu_item_select(void *data, Evas_Object *obj, void *event_info);
static void
@ -70,7 +60,6 @@ static void
_item_select(Elm_Toolbar_Item *it)
{
Elm_Toolbar_Item *it2;
Elm_Toolbar_Menu_Item *it_menu;
Widget_Data *wd = elm_widget_data_get(it->obj);
Evas_Object *obj2, *bt, *hv, *bx, *ic;
const Eina_List *l;
@ -104,20 +93,9 @@ _item_select(Elm_Toolbar_Item *it)
}
static void
_menu_item_select(void *data, Evas_Object *obj, void *event_info)
{
Elm_Toolbar_Menu_Item *it = data;
if (it->func) it->func((void *)(it->data), it->parent->obj, it);
_menu_hide(it->parent, NULL, NULL);
}
static void
_menu_hide(void *data, Evas_Object *obj, void *event_info)
_menu_hide(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
Elm_Toolbar_Item *it = data;
evas_object_hide(it->o_menu);
elm_toolbar_item_unselect_all(it->obj);
}
@ -152,7 +130,6 @@ _del_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
Elm_Toolbar_Item *it;
Elm_Toolbar_Menu_Item *it_menu;
if (!wd) return;
EINA_LIST_FREE(wd->items, it)
@ -160,10 +137,6 @@ _del_hook(Evas_Object *obj)
eina_stringshare_del(it->label);
if (it->icon) evas_object_del(it->icon);
evas_object_del(it->base);
if(it->o_menu)
evas_object_del(it->o_menu);
EINA_LIST_FREE(it->menu_items, it_menu)
free(it_menu);
free(it);
}
free(wd);
@ -198,7 +171,8 @@ _theme_hook(Evas_Object *obj)
int ms = 0;
ms = ((double)wd->icon_size * _elm_config->scale);
edje_extern_object_min_size_set(it->icon, ms, ms);
evas_object_size_hint_min_set(it->icon, ms, ms);
evas_object_size_hint_max_set(it->icon, ms, ms);
edje_object_part_swallow(it->base, "elm.swallow.icon",
it->icon);
}
@ -209,11 +183,12 @@ _theme_hook(Evas_Object *obj)
_elm_theme_set(it->base, "toolbar", "separator", style);
}
mw = mh = -1;
elm_coords_finger_size_adjust(1, &mw, 1, &mh);
if(!it->separator)
elm_coords_finger_size_adjust(1, &mw, 1, &mh);
edje_object_size_min_restricted_calc(it->base, &mw, &mh, mw, mh);
elm_coords_finger_size_adjust(1, &mw, 1, &mh);
if(!it->separator)
elm_coords_finger_size_adjust(1, &mw, 1, &mh);
evas_object_size_hint_min_set(it->base, mw, mh);
evas_object_size_hint_max_set(it->base, 9999, mh);
}
_sizing_eval(obj);
}
@ -385,7 +360,10 @@ elm_toolbar_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, voi
int ms = 0;
ms = ((double)wd->icon_size * _elm_config->scale);
edje_extern_object_min_size_set(it->icon, ms, ms);
//TODO uncomment the next line to get a big icon
//ms = 100;
evas_object_size_hint_min_set(it->icon, ms, ms);
evas_object_size_hint_max_set(it->icon, ms, ms);
edje_object_part_swallow(it->base, "elm.swallow.icon", it->icon);
evas_object_show(it->icon);
elm_widget_sub_object_add(obj, it->icon);
@ -395,10 +373,9 @@ elm_toolbar_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, voi
elm_coords_finger_size_adjust(1, &mw, 1, &mh);
edje_object_size_min_restricted_calc(it->base, &mw, &mh, mw, mh);
elm_coords_finger_size_adjust(1, &mw, 1, &mh);
evas_object_size_hint_weight_set(it->base, -1.0, 0.0);
evas_object_size_hint_weight_set(it->base, -1.0, 1.0);
evas_object_size_hint_align_set(it->base, 0.5, -1.0);
evas_object_size_hint_min_set(it->base, mw, mh);
evas_object_size_hint_max_set(it->base, 9999, mh);
evas_object_box_append(wd->bx, it->base);
evas_object_show(it->base);
_sizing_eval(obj);
@ -513,7 +490,7 @@ elm_toolbar_menu_parent_set(Evas_Object *obj, Evas_Object *parent)
wd->menu_parent = parent;
EINA_LIST_FOREACH(wd->items, l, it)
{
if (it->menu)
if (it->o_menu)
elm_menu_parent_set(it->o_menu, wd->menu_parent);
}
}
@ -571,30 +548,19 @@ elm_toolbar_item_menu_set(Elm_Toolbar_Item *item, Eina_Bool menu)
item->o_menu = elm_menu_add(item->base);
if(wd->menu_parent)
elm_menu_parent_set(item->o_menu, wd->menu_parent);
evas_object_smart_callback_add(item->o_menu, "clicked", _menu_hide, item);
evas_object_event_callback_add(item->o_menu, EVAS_CALLBACK_HIDE, _menu_hide, item);
}
else
evas_object_hide(item->o_menu);
evas_object_del(item->o_menu);
}
EAPI Elm_Toolbar_Menu_Item *
elm_toolbar_item_menu_item_add(Elm_Toolbar_Item *item, Evas_Object *icon, const char *label, void (*func) (void *data, Evas_Object *obj, void *event_info), const void *data)
EAPI Evas_Object *
elm_toolbar_item_menu_get(Elm_Toolbar_Item *item)
{
Elm_Toolbar_Menu_Item *menu_item;
if (!item) return NULL;
elm_toolbar_item_menu_set(item, 1);
menu_item = calloc(1, sizeof(Elm_Toolbar_Menu_Item));
if(!menu_item) return NULL;
menu_item->func = func;
menu_item->data = data;
menu_item->parent = item;
item->menu_items = eina_list_append(item->menu_items, menu_item);
menu_item->item = elm_menu_item_add(item->o_menu, icon, label, _menu_item_select, menu_item);
return menu_item;
if (!item) return;
Widget_Data *wd = elm_widget_data_get(item->obj);
if (!wd) return;
elm_toolbar_item_menu_set(item, 1);
return item->o_menu;
}