Enlightenment CVS committal Author : moom16 Project : e17 Module : proto
Dir : e17/proto/etk/src/lib Modified Files: Etk.h Makefile.am etk_container.c etk_menu.c etk_menu.h etk_menu_item.c etk_menu_item.h etk_scrolled_view.c etk_types.h etk_widget.c etk_window.c Added Files: etk_menu_shell.c etk_menu_shell.h Log Message: * More work on the menus =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/Etk.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -3 -r1.9 -r1.10 --- Etk.h 11 Nov 2005 22:48:48 -0000 1.9 +++ Etk.h 13 Nov 2005 12:04:05 -0000 1.10 @@ -46,6 +46,7 @@ #include "etk_scale.h" #include "etk_scrollbar.h" #include "etk_separator.h" +#include "etk_menu_shell.h" #include "etk_menu.h" #include "etk_menu_item.h" =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/Makefile.am,v retrieving revision 1.12 retrieving revision 1.13 diff -u -3 -r1.12 -r1.13 --- Makefile.am 11 Nov 2005 22:48:48 -0000 1.12 +++ Makefile.am 13 Nov 2005 12:04:05 -0000 1.13 @@ -35,7 +35,7 @@ etk_tree.h \ etk_range.h etk_scale.h etk_scrollbar.h \ etk_separator.h \ -etk_menu.h etk_menu_item.h +etk_menu_shell.h etk_menu.h etk_menu_item.h libetk_la_SOURCES = \ etk_main.c etk_utils.c \ @@ -57,7 +57,7 @@ etk_tree.c \ etk_range.c etk_scale.c etk_scrollbar.c \ etk_separator.c \ -etk_menu.c etk_menu_item.c \ +etk_menu_shell.c etk_menu.c etk_menu_item.c \ $(ETKHEADERS) installed_headersdir = $(prefix)/include/etk =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_container.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- etk_container.c 11 Nov 2005 22:48:48 -0000 1.3 +++ etk_container.c 13 Nov 2005 12:04:05 -0000 1.4 @@ -11,8 +11,8 @@ enum _Etk_Container_Signal_Id { - ETK_CONTAINER_ADD_SIGNAL, - ETK_CONTAINER_REMOVE_SIGNAL, + ETK_CONTAINER_CHILD_ADDED_SIGNAL, + ETK_CONTAINER_CHILD_REMOVED_SIGNAL, ETK_CONTAINER_NUM_SIGNALS }; @@ -46,8 +46,8 @@ { container_type = etk_type_new("Etk_Container", ETK_WIDGET_TYPE, sizeof(Etk_Container), ETK_CONSTRUCTOR(_etk_container_constructor), ETK_DESTRUCTOR(_etk_container_destructor)); - _etk_container_signals[ETK_CONTAINER_ADD_SIGNAL] = etk_signal_new("add", container_type, ETK_MEMBER_OFFSET(Etk_Container, child_add), etk_marshaller_VOID__POINTER, NULL, NULL); - _etk_container_signals[ETK_CONTAINER_REMOVE_SIGNAL] = etk_signal_new("remove", container_type, ETK_MEMBER_OFFSET(Etk_Container, child_remove), etk_marshaller_VOID__POINTER, NULL, NULL); + _etk_container_signals[ETK_CONTAINER_CHILD_ADDED_SIGNAL] = etk_signal_new("child_added", container_type, -1, etk_marshaller_VOID__POINTER, NULL, NULL); + _etk_container_signals[ETK_CONTAINER_CHILD_REMOVED_SIGNAL] = etk_signal_new("child_removed", container_type, -1, etk_marshaller_VOID__POINTER, NULL, NULL); etk_type_property_add(container_type, "border_width", ETK_CONTAINER_BORDER_WIDTH_PROPERTY, ETK_PROPERTY_INT, ETK_PROPERTY_READABLE_WRITABLE, etk_property_value_int(0)); @@ -65,9 +65,9 @@ */ void etk_container_add(Etk_Container *container, Etk_Widget *widget) { - if (!container || !widget) + if (!container || !widget || !container->child_add) return; - etk_signal_emit(_etk_container_signals[ETK_CONTAINER_ADD_SIGNAL], ETK_OBJECT(container), NULL, widget); + container->child_add(container, widget); } /** @@ -77,9 +77,9 @@ */ void etk_container_remove(Etk_Container *container, Etk_Widget *widget) { - if (!container || !widget) + if (!container || !widget || !container->child_remove) return; - etk_signal_emit(_etk_container_signals[ETK_CONTAINER_REMOVE_SIGNAL], ETK_OBJECT(container), NULL, widget); + container->child_remove(container, widget); } /** =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_menu.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -3 -r1.1 -r1.2 --- etk_menu.c 11 Nov 2005 22:48:48 -0000 1.1 +++ etk_menu.c 13 Nov 2005 12:04:05 -0000 1.2 @@ -3,8 +3,8 @@ #include <stdlib.h> #include <Ecore.h> #include <Ecore_X.h> +#include "etk_window.h" #include "etk_menu_item.h" -#include "etk_vbox.h" #include "etk_utils.h" #include "etk_signal.h" #include "etk_signal_callback.h" @@ -32,13 +32,16 @@ static void _etk_menu_constructor(Etk_Menu *menu); static void _etk_menu_destructor(Etk_Menu *menu); +static void _etk_menu_size_request(Etk_Widget *widget, Etk_Size *size_requisition); +static void _etk_menu_size_allocate(Etk_Widget *widget, Etk_Geometry geometry); +static void _etk_menu_items_update(Etk_Menu_Shell *menu_shell); +static void _etk_menu_child_added_cb(Etk_Object *object, void *child, void *data); +static void _etk_menu_child_removed_cb(Etk_Object *object, void *child, void *data); static int _etk_menu_mouse_up_cb(void *data, int type, void *event); static int _etk_menu_mouse_move_cb(void *data, int type, void *event); -static void _etk_menu_item_enter_cb(Etk_Object *object, void *data); -static void _etk_menu_item_leave_cb(Etk_Object *object, void *data); -static void _etk_menu_item_up_cb(Etk_Object *object, void *event, void *data); static void _etk_menu_item_select_cb(Etk_Object *object, void *data); static void _etk_menu_item_deselect_cb(Etk_Object *object, void *data); +static void _etk_menu_item_activate_cb(Etk_Object *object, void *data); static Etk_Menu_Screen_Edge _etk_menu_over_screen_edge(Etk_Menu *menu); static Etk_Menu_Screen_Edge _etk_menu_mouse_on_screen_edge(); @@ -73,7 +76,7 @@ if (!menu_type) { - menu_type = etk_type_new("Etk_Menu", ETK_WINDOW_TYPE, sizeof(Etk_Menu), ETK_CONSTRUCTOR(_etk_menu_constructor), ETK_DESTRUCTOR(_etk_menu_destructor)); + menu_type = etk_type_new("Etk_Menu", ETK_MENU_SHELL_TYPE, sizeof(Etk_Menu), ETK_CONSTRUCTOR(_etk_menu_constructor), ETK_DESTRUCTOR(_etk_menu_destructor)); } return menu_type; @@ -88,25 +91,6 @@ return etk_widget_new(ETK_MENU_TYPE, "theme_group", "menu", NULL); } -/** - * @brief Adds a menu item at the end of the menu - * @param menu a menu - * @param item the menu item to add - */ -void etk_menu_append(Etk_Menu *menu, Etk_Menu_Item *item) -{ - if (!menu || !item) - return; - - etk_box_pack_start(ETK_BOX(menu->vbox), ETK_WIDGET(item), FALSE, FALSE, 0); - item->parent = menu; - etk_signal_connect("enter", ETK_OBJECT(item), ETK_CALLBACK(_etk_menu_item_enter_cb), NULL); - etk_signal_connect("leave", ETK_OBJECT(item), ETK_CALLBACK(_etk_menu_item_leave_cb), NULL); - etk_signal_connect("mouse_up", ETK_OBJECT(item), ETK_CALLBACK(_etk_menu_item_up_cb), NULL); - etk_signal_connect("select", ETK_OBJECT(item), ETK_CALLBACK(_etk_menu_item_select_cb), NULL); - etk_signal_connect("deselect", ETK_OBJECT(item), ETK_CALLBACK(_etk_menu_item_deselect_cb), NULL); -} - /** * @brief Popups the menu at the position (x, y) * @param menu a menu @@ -123,7 +107,7 @@ Ecore_X_Window root, parent; int root_x, root_y, root_w, root_h; - root = ETK_WINDOW(menu)->x_window; + root = menu->window->x_window; while ((parent = ecore_x_window_parent_get(root)) != 0) root = parent; @@ -141,10 +125,11 @@ _etk_menu_root_popup_timestamp = ecore_x_current_time_get(); _etk_menu_root = menu; } - etk_window_move(ETK_WINDOW(menu), x, y); + etk_window_move(menu->window, x, y); + etk_widget_show(ETK_WIDGET(menu->window)); etk_widget_show(ETK_WIDGET(menu)); - evas_event_feed_mouse_move(ETK_TOPLEVEL_WIDGET(menu)->evas, -100000, -100000, ecore_x_current_time_get(), NULL); - evas_event_feed_mouse_in(ETK_TOPLEVEL_WIDGET(menu)->evas, ecore_x_current_time_get(), NULL); + evas_event_feed_mouse_move(ETK_TOPLEVEL_WIDGET(menu->window)->evas, -100000, -100000, ecore_x_current_time_get(), NULL); + evas_event_feed_mouse_in(ETK_TOPLEVEL_WIDGET(menu->window)->evas, ecore_x_current_time_get(), NULL); _etk_menu_popped_menus = evas_list_append(_etk_menu_popped_menus, menu); _etk_menu_slide_timer_update(menu); @@ -168,20 +153,15 @@ */ void etk_menu_popdown(Etk_Menu *menu) { - Evas_List *items, *l; - Etk_Menu_Item *item; + Evas_List *l; if (!menu) return; - items = ETK_CONTAINER(menu->vbox)->children; - for (l = items; l; l = l->next) - { - item = ETK_MENU_ITEM(l->data); - etk_menu_item_deselect(item); - } + for (l = ETK_CONTAINER(menu)->children; l; l = l->next) + etk_menu_item_deselect(ETK_MENU_ITEM(l->data)); - etk_widget_hide(ETK_WIDGET(menu)); + etk_widget_hide(ETK_WIDGET(menu->window)); if (menu == _etk_menu_root) { ecore_x_keyboard_ungrab(); @@ -206,17 +186,19 @@ { if (!menu) return; + + menu->window = ETK_WINDOW(etk_widget_new(ETK_WINDOW_TYPE, NULL)); + etk_window_decorated_set(menu->window, FALSE); + etk_window_skip_taskbar_hint_set(menu->window, TRUE); + etk_window_skip_pager_hint_set(menu->window, TRUE); + + etk_container_add(ETK_CONTAINER(menu->window), ETK_WIDGET(menu)); + ETK_WIDGET(menu)->size_request = _etk_menu_size_request; + ETK_WIDGET(menu)->size_allocate = _etk_menu_size_allocate; + ETK_MENU_SHELL(menu)->items_update = _etk_menu_items_update; - etk_window_decorated_set(ETK_WINDOW(menu), FALSE); - etk_window_skip_taskbar_hint_set(ETK_WINDOW(menu), TRUE); - etk_window_skip_pager_hint_set(ETK_WINDOW(menu), TRUE); - - menu->vbox = etk_vbox_new(FALSE, 0); - etk_container_add(ETK_CONTAINER(menu), menu->vbox); - etk_widget_show(menu->vbox); - - /* TODO */ - ETK_CONTAINER(menu)->child_add = NULL; + etk_signal_connect("child_added", ETK_OBJECT(menu), ETK_CALLBACK(_etk_menu_child_added_cb), NULL); + etk_signal_connect("child_removed", ETK_OBJECT(menu), ETK_CALLBACK(_etk_menu_child_removed_cb), NULL); } /* Destroys the menu */ @@ -224,8 +206,85 @@ { if (!menu) return; + etk_object_destroy(ETK_OBJECT(menu->window)); +} - /* TODO */ +/* Calculates the ideal size of the menu */ +static void _etk_menu_size_request(Etk_Widget *widget, Etk_Size *size_requisition) +{ + Evas_List *l; + Etk_Container *menu_container; + + if (!(menu_container = ETK_CONTAINER(widget)) || !size_requisition) + return; + + size_requisition->w = 0; + size_requisition->h = 0; + for (l = menu_container->children; l; l = l->next) + { + Etk_Size child_requisition; + + etk_widget_size_request(ETK_WIDGET(l->data), &child_requisition); + size_requisition->w = ETK_MAX(size_requisition->w, child_requisition.w); + size_requisition->h += child_requisition.h; + } +} + +/* Resizes the menu to the size allocation */ +static void _etk_menu_size_allocate(Etk_Widget *widget, Etk_Geometry geometry) +{ + Etk_Geometry child_geometry; + Etk_Container *menu_container; + Evas_List *l; + int y_offset; + + if (!(menu_container = ETK_CONTAINER(widget))) + return; + + /* Then we allocate size for the child items */ + y_offset = geometry.y; + child_geometry.x = geometry.x; + for (l = menu_container->children; l; l = l->next) + { + Etk_Size child_requisition; + + etk_widget_size_request(ETK_WIDGET(l->data), &child_requisition); + child_geometry.y = y_offset; + child_geometry.w = geometry.w; + child_geometry.h = child_requisition.h; + + etk_widget_size_allocate(ETK_WIDGET(l->data), child_geometry); + y_offset += child_requisition.h; + } +} + +/* Updates the items */ +static void _etk_menu_items_update(Etk_Menu_Shell *menu_shell) +{ + Etk_Menu *menu; + Evas_List *l; + Etk_Bool items_has_image = FALSE; + Etk_Bool items_has_right_element = FALSE; + Etk_Menu_Item *i; + + if (!(menu = ETK_MENU(menu_shell))) + return; + + for (l = ETK_CONTAINER(menu_shell)->children; l; l = l->next) + { + i = ETK_MENU_ITEM(l->data); + + if (i->image) + items_has_image = TRUE; + if (i->submenu) + items_has_right_element = TRUE; + } + + for (l = ETK_CONTAINER(menu_shell)->children; l; l = l->next) + etk_menu_item_image_show(ETK_MENU_ITEM(l->data), items_has_image); + + for (l = ETK_CONTAINER(menu_shell)->children; l; l = l->next) + etk_menu_item_right_swallow_show(ETK_MENU_ITEM(l->data), items_has_right_element); } /************************** @@ -234,6 +293,34 @@ * **************************/ +/* Called when a child is added to the menu */ +static void _etk_menu_child_added_cb(Etk_Object *object, void *child, void *data) +{ + Etk_Object *item; + + if (!(item = ETK_OBJECT(child))) + return; + + etk_signal_connect("select", item, ETK_CALLBACK(_etk_menu_item_select_cb), NULL); + etk_signal_connect("deselect", item, ETK_CALLBACK(_etk_menu_item_deselect_cb), NULL); + etk_signal_connect("activate", item, ETK_CALLBACK(_etk_menu_item_activate_cb), NULL); + etk_menu_shell_update(ETK_MENU_SHELL(object)); +} + +/* Called when a child is removed from the menu */ +static void _etk_menu_child_removed_cb(Etk_Object *object, void *child, void *data) +{ + Etk_Object *item; + + if (!(item = ETK_OBJECT(child))) + return; + + etk_signal_disconnect("select", item, ETK_CALLBACK(_etk_menu_item_select_cb)); + etk_signal_disconnect("deselect", item, ETK_CALLBACK(_etk_menu_item_deselect_cb)); + etk_signal_disconnect("activate", item, ETK_CALLBACK(_etk_menu_item_activate_cb)); + etk_menu_shell_update(ETK_MENU_SHELL(object)); +} + /* * Called when the user clicks on the menu input window: * it pops down the menus if needed and feeds the mouse up event to the menu window @@ -254,11 +341,11 @@ int mx, my, mw, mh; m = ETK_MENU(l->data); - etk_window_geometry_get(ETK_WINDOW(menu), &mx, &my, &mw, &mh); + etk_window_geometry_get(m->window, &mx, &my, &mw, &mh); if (_etk_menu_mouse_x >= mx && _etk_menu_mouse_x <= mx + mw && _etk_menu_mouse_y >= my && _etk_menu_mouse_y <= my + mh) { pointer_over_menu = TRUE; - evas_event_feed_mouse_up(ETK_TOPLEVEL_WIDGET(m)->evas, mouse_event->button, EVAS_BUTTON_NONE, mouse_event->time, NULL); + evas_event_feed_mouse_up(ETK_TOPLEVEL_WIDGET(m->window)->evas, mouse_event->button, EVAS_BUTTON_NONE, mouse_event->time, NULL); if (!_etk_menu_popped_menus) break; } @@ -290,8 +377,8 @@ for (l = _etk_menu_popped_menus; l; l = l->next) { m = ETK_MENU(l->data); - etk_window_geometry_get(ETK_WINDOW(menu), &mx, &my, NULL, NULL); - evas_event_feed_mouse_move(ETK_TOPLEVEL_WIDGET(m)->evas, mouse_event->x - mx, mouse_event->y - my, mouse_event->time, NULL); + etk_window_geometry_get(m->window, &mx, &my, NULL, NULL); + evas_event_feed_mouse_move(ETK_TOPLEVEL_WIDGET(m->window)->evas, mouse_event->x - mx, mouse_event->y - my, mouse_event->time, NULL); /* Start to make the menu window slide if needed */ _etk_menu_slide_timer_update(m); @@ -300,67 +387,52 @@ return 1; } -/* Called when the mouse pointer enters the item */ -static void _etk_menu_item_enter_cb(Etk_Object *object, void *data) -{ - etk_menu_item_select(ETK_MENU_ITEM(object)); -} - -/* Called when the mouse pointer leaves the item */ -static void _etk_menu_item_leave_cb(Etk_Object *object, void *data) -{ - Etk_Menu_Item *item; - - if (!(item = ETK_MENU_ITEM(object)) || item->child) - return; - etk_menu_item_deselect(item); -} - -/* Called when the user has clicked on the item */ -static void _etk_menu_item_up_cb(Etk_Object *object, void *event, void *data) -{ - Etk_Menu_Item *item; - - if (!(item = ETK_MENU_ITEM(object)) || item->child) - return; - - etk_menu_item_activate(item); - etk_menu_popdown(_etk_menu_root); -} - /* Called when the item is selected */ static void _etk_menu_item_select_cb(Etk_Object *object, void *data) { Etk_Menu_Item *item; Etk_Menu *menu; - Etk_Menu_Item *i; Evas_List *l; - if (!(item = ETK_MENU_ITEM(object)) || !(menu = item->parent)) + if (!(item = ETK_MENU_ITEM(object)) || !(menu = ETK_MENU(item->parent))) return; /* First, we deactivate all the items that are on the same menu than the item */ - for (l = ETK_CONTAINER(menu->vbox)->children; l; l = l->next) - { - i = ETK_MENU_ITEM(l->data); - /* TODO */ - etk_menu_item_deselect(i); - } + for (l = ETK_CONTAINER(menu)->children; l; l = l->next) + etk_menu_item_deselect(ETK_MENU_ITEM(l->data)); /* Then we popup the child menu */ - if (item->child) + if (item->submenu) { int mx, my, mw, item_y; - item_y = ETK_WIDGET(item)->geometry.h; - etk_window_geometry_get(ETK_WINDOW(menu), &mx, &my, &mw, NULL); - etk_menu_popup_at_xy(item->child, mx + mw, my + item_y); + item_y = ETK_WIDGET(item)->geometry.y; + etk_window_geometry_get(menu->window, &mx, &my, &mw, NULL); + etk_menu_popup_at_xy(item->submenu, mx + mw, my + item_y); } } /* Called when the item is deselected */ static void _etk_menu_item_deselect_cb(Etk_Object *object, void *data) { + Etk_Menu_Item *item; + + if (!(item = ETK_MENU_ITEM(object))) + return; + + if (item->submenu) + etk_menu_popdown(item->submenu); +} + + +/* Called when the item is activated */ +static void _etk_menu_item_activate_cb(Etk_Object *object, void *data) +{ + Etk_Menu_Item *item; + + if (!(item = ETK_MENU_ITEM(object))) + return; + etk_menu_popdown(_etk_menu_root); } /************************** @@ -380,7 +452,7 @@ return ETK_MENU_NO_EDGE; ecore_x_window_geometry_get(_etk_menu_input_window, &rx, &ry, &rw, &rh); - etk_window_geometry_get(ETK_WINDOW(menu), &mx, &my, &mw, &mh); + etk_window_geometry_get(menu->window, &mx, &my, &mw, &mh); if (mx < rx) result |= ETK_MENU_LEFT_EDGE; @@ -461,7 +533,7 @@ /* Then we move all the menu windows in the right direction */ mouse_edge = _etk_menu_mouse_on_screen_edge(); ecore_x_window_geometry_get(_etk_menu_input_window, &rx, &ry, &rw, &rh); - etk_window_geometry_get(ETK_WINDOW(menu), &mx, &my, &mw, &mh); + etk_window_geometry_get(menu->window, &mx, &my, &mw, &mh); if (mouse_edge & menu_edge & ETK_MENU_LEFT_EDGE) { if (max_delta < rx - mx) @@ -500,11 +572,11 @@ for (l = _etk_menu_popped_menus; l; l = l->next) { m = ETK_MENU(l->data); - etk_window_geometry_get(ETK_WINDOW(m), &x, &y, NULL, NULL); - etk_window_move(ETK_WINDOW(m), x + dx, y + dy); + etk_window_geometry_get(m->window, &x, &y, NULL, NULL); + etk_window_move(m->window, x + dx, y + dy); /* We feed a mouse move event since the relative position between the mouse pointer and the menu window has changed */ - evas_event_feed_mouse_move(ETK_TOPLEVEL_WIDGET(m)->evas, _etk_menu_mouse_x - x, _etk_menu_mouse_y - y, ecore_x_current_time_get(), NULL); + evas_event_feed_mouse_move(ETK_TOPLEVEL_WIDGET(m->window)->evas, _etk_menu_mouse_x - x, _etk_menu_mouse_y - y, ecore_x_current_time_get(), NULL); } return 1; =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_menu.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -3 -r1.1 -r1.2 --- etk_menu.h 11 Nov 2005 22:48:48 -0000 1.1 +++ etk_menu.h 13 Nov 2005 12:04:05 -0000 1.2 @@ -2,7 +2,7 @@ #ifndef _ETK_MENU_H_ #define _ETK_MENU_H_ -#include "etk_window.h" +#include "etk_menu_shell.h" #include "etk_types.h" /** @@ -20,17 +20,15 @@ struct _Etk_Menu { /* private: */ - /* Inherit from Etk_Window */ - Etk_Window window; + /* Inherit from Etk_Menu_Shell */ + Etk_Menu_Shell menu_shell; - Etk_Widget *vbox; + Etk_Window *window; }; Etk_Type *etk_menu_type_get(); Etk_Widget *etk_menu_new(); -void etk_menu_append(Etk_Menu *menu, Etk_Menu_Item *item); - void etk_menu_popup_at_xy(Etk_Menu *menu, int x, int y); void etk_menu_popup(Etk_Menu *menu); void etk_menu_popdown(Etk_Menu *menu); =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_menu_item.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -3 -r1.1 -r1.2 --- etk_menu_item.c 11 Nov 2005 22:48:48 -0000 1.1 +++ etk_menu_item.c 13 Nov 2005 12:04:05 -0000 1.2 @@ -2,6 +2,7 @@ #include "etk_menu_item.h" #include <stdlib.h> #include <string.h> +#include "etk_menu_shell.h" #include "etk_signal.h" #include "etk_signal_callback.h" #include "etk_utils.h" @@ -30,8 +31,13 @@ static void _etk_menu_item_property_get(Etk_Object *object, int property_id, Etk_Property_Value *value); static void _etk_menu_item_realize_cb(Etk_Object *object, void *data); static void _etk_menu_item_image_realize_cb(Etk_Object *object, void *data); +static void _etk_menu_item_right_widget_realize_cb(Etk_Object *object, void *data); +static void _etk_menu_item_enter_cb(Etk_Object *object, void *data); +static void _etk_menu_item_leave_cb(Etk_Object *object, void *data); +static void _etk_menu_item_up_cb(Etk_Object *object, void *event, void *data); static void _etk_menu_item_select_handler(Etk_Menu_Item *menu_item); static void _etk_menu_item_deselect_handler(Etk_Menu_Item *menu_item); +static void _etk_menu_item_activate_handler(Etk_Menu_Item *menu_item); static Etk_Signal *_etk_menu_item_signals[ETK_MENU_ITEM_NUM_SIGNALS]; @@ -72,7 +78,7 @@ */ Etk_Widget *etk_menu_item_new() { - return etk_widget_new(ETK_MENU_ITEM_TYPE, "theme_group", "menu_item", NULL); + return etk_widget_new(ETK_MENU_ITEM_TYPE, "theme_group", "menu_item", "visible", TRUE, NULL); } /** @@ -82,7 +88,7 @@ */ Etk_Widget *etk_menu_item_new_with_label(const char *label) { - return etk_widget_new(ETK_MENU_ITEM_TYPE, "theme_group", "menu_item", "label", label, NULL); + return etk_widget_new(ETK_MENU_ITEM_TYPE, "theme_group", "menu_item", "visible", TRUE, "label", label, NULL); } /** @@ -164,10 +170,34 @@ { if (!menu_item) return; - menu_item->child = submenu; + menu_item->submenu = submenu; + + if (menu_item->submenu && !menu_item->right_widget) + { + menu_item->right_widget = etk_widget_new(ETK_WIDGET_TYPE, "theme_group", "menu_arrow", NULL); + /* TODO: disconnect */ + etk_signal_connect_after("realize", ETK_OBJECT(menu_item->right_widget), ETK_CALLBACK(_etk_menu_item_right_widget_realize_cb), menu_item); + etk_widget_parent_set(menu_item->right_widget, ETK_CONTAINER(menu_item)); + etk_widget_pass_events_set(menu_item->right_widget, TRUE); + menu_item->right_widget_is_arrow = TRUE; + } + else if (!menu_item->submenu && menu_item->right_widget && menu_item->right_widget_is_arrow) + { + etk_object_destroy(ETK_OBJECT(menu_item->right_widget)); + menu_item->right_widget = NULL; + menu_item->right_widget_is_arrow = FALSE; + } + + etk_menu_item_right_swallow_show(menu_item, menu_item->submenu != NULL); + if (menu_item->parent) + etk_menu_shell_update(menu_item->parent); } -/* TODO */ +/** + * @brief Sets the image of the menu item. It will be displayed at the left of the label + * @param menu_item a menu_item + * @param image the image to set (NULL to unset the image) + */ void etk_menu_item_image_set(Etk_Menu_Item *menu_item, Etk_Image *image) { Etk_Widget *image_widget; @@ -179,7 +209,6 @@ { etk_widget_parent_set(ETK_WIDGET(menu_item->image), NULL); menu_item->image = NULL; - etk_widget_size_recalc_queue(ETK_WIDGET(menu_item)); } if ((image_widget = ETK_WIDGET(image))) @@ -190,9 +219,47 @@ /* TODO: disconnect */ etk_signal_connect_after("realize", ETK_OBJECT(image_widget), ETK_CALLBACK(_etk_menu_item_image_realize_cb), menu_item); etk_widget_parent_set(image_widget, ETK_CONTAINER(menu_item)); - etk_widget_theme_object_signal_emit(ETK_WIDGET(menu_item), ""); + etk_widget_pass_events_set(image_widget, TRUE); menu_item->image = image; } + + etk_menu_item_right_swallow_show(menu_item, menu_item->image != NULL); + if (menu_item->parent) + etk_menu_shell_update(menu_item->parent); +} + +/** + * @brief Show the image swallow area of the menu item. It's a function used by etk_menu, do not use it manually! + * @param menu_item a menu item + * @param show TRUE whether the image swallow area should be show or not + */ +void etk_menu_item_image_show(Etk_Menu_Item *menu_item, Etk_Bool show) +{ + if (!menu_item || menu_item->show_image == show) + return; + + if (show) + etk_widget_theme_object_signal_emit(ETK_WIDGET(menu_item), "image_show"); + else + etk_widget_theme_object_signal_emit(ETK_WIDGET(menu_item), "image_hide"); + menu_item->show_image = show; +} + +/** + * @brief Show the right swallow area of the menu item. It's a function used by Etk_Menu, do not use it manually! + * @param menu_item a menu item + * @param show TRUE whether the right swallow area should be show or not + */ +void etk_menu_item_right_swallow_show(Etk_Menu_Item *menu_item, Etk_Bool show) +{ + if (!menu_item || menu_item->show_right_swallow == show) + return; + + if (show) + etk_widget_theme_object_signal_emit(ETK_WIDGET(menu_item), "right_swallow_show"); + else + etk_widget_theme_object_signal_emit(ETK_WIDGET(menu_item), "right_swallow_hide"); + menu_item->show_right_swallow = show; } /************************** @@ -209,15 +276,22 @@ menu_item->select = _etk_menu_item_select_handler; menu_item->deselect = _etk_menu_item_deselect_handler; - menu_item->activate = NULL; + menu_item->activate = _etk_menu_item_activate_handler; - menu_item->child = NULL; + menu_item->submenu = NULL; menu_item->parent = NULL; menu_item->label = NULL; menu_item->image = NULL; + menu_item->right_widget = NULL; + menu_item->selected = FALSE; + menu_item->show_image = FALSE; + menu_item->show_right_swallow = FALSE; etk_signal_connect_after("realize", ETK_OBJECT(menu_item), ETK_CALLBACK(_etk_menu_item_realize_cb), NULL); + etk_signal_connect("enter", ETK_OBJECT(menu_item), ETK_CALLBACK(_etk_menu_item_enter_cb), NULL); + etk_signal_connect("leave", ETK_OBJECT(menu_item), ETK_CALLBACK(_etk_menu_item_leave_cb), NULL); + etk_signal_connect("mouse_up", ETK_OBJECT(menu_item), ETK_CALLBACK(_etk_menu_item_up_cb), NULL); } /* Destroys the menu item */ @@ -225,7 +299,6 @@ { if (!menu_item) return; - free(menu_item->label); } @@ -283,6 +356,16 @@ etk_widget_theme_object_part_text_set(ETK_WIDGET(menu_item), "label", menu_item->label); else etk_widget_theme_object_part_text_set(ETK_WIDGET(menu_item), "label", ""); + + if (menu_item->image && ETK_WIDGET(menu_item->image)->realized) + etk_widget_swallow_widget(ETK_WIDGET(menu_item), "image_swallow", ETK_WIDGET(menu_item->image)); + if (menu_item->right_widget && ETK_WIDGET(menu_item->right_widget)->realized) + etk_widget_swallow_widget(ETK_WIDGET(menu_item), "right_swallow", ETK_WIDGET(menu_item->right_widget)); + + if (menu_item->show_image) + etk_widget_theme_object_signal_emit(ETK_WIDGET(menu_item), "image_show"); + if (menu_item->show_right_swallow) + etk_widget_theme_object_signal_emit(ETK_WIDGET(menu_item), "right_swallow_show"); } /* Called when the image of the menu is realized */ @@ -290,21 +373,60 @@ { Etk_Menu_Item *menu_item; - if (!(menu_item = ETK_MENU_ITEM(data)) || !menu_item->image || ETK_OBJECT(menu_item->image) != object) + if (!(menu_item = ETK_MENU_ITEM(data)) || !menu_item->image) return; - if (ETK_WIDGET(menu_item)->realized && ETK_WIDGET(menu_item->image)->realized) + if (ETK_WIDGET(menu_item)->realized) etk_widget_swallow_widget(ETK_WIDGET(menu_item), "image_swallow", ETK_WIDGET(menu_item->image)); } +/* Called when the right widget of the menu is realized */ +static void _etk_menu_item_right_widget_realize_cb(Etk_Object *object, void *data) +{ + Etk_Menu_Item *menu_item; + + if (!(menu_item = ETK_MENU_ITEM(data)) || !menu_item->right_widget) + return; + + if (ETK_WIDGET(menu_item)->realized) + etk_widget_swallow_widget(ETK_WIDGET(menu_item), "right_swallow", ETK_WIDGET(menu_item->right_widget)); +} + +/* Called when the mouse pointer enters the item */ +static void _etk_menu_item_enter_cb(Etk_Object *object, void *data) +{ + etk_menu_item_select(ETK_MENU_ITEM(object)); +} + +/* Called when the mouse pointer leaves the item */ +static void _etk_menu_item_leave_cb(Etk_Object *object, void *data) +{ + Etk_Menu_Item *item; + + if (!(item = ETK_MENU_ITEM(object)) || item->submenu) + return; + etk_menu_item_deselect(item); +} + +/* Called when the user has clicked on the item */ +static void _etk_menu_item_up_cb(Etk_Object *object, void *event, void *data) +{ + Etk_Menu_Item *item; + + if (!(item = ETK_MENU_ITEM(object)) || item->submenu) + return; + etk_menu_item_activate(item); +} + /* Default handler for the "select" signal */ static void _etk_menu_item_select_handler(Etk_Menu_Item *menu_item) { if (!menu_item || menu_item->selected) return; - menu_item->selected = TRUE; etk_widget_theme_object_signal_emit(ETK_WIDGET(menu_item), "select"); + etk_widget_theme_object_signal_emit(ETK_WIDGET(menu_item->image), "select"); + etk_widget_theme_object_signal_emit(ETK_WIDGET(menu_item->right_widget), "select"); } /* Default handler for the "deselect" signal */ @@ -312,9 +434,20 @@ { if (!menu_item || !menu_item->selected) return; - etk_widget_theme_object_signal_emit(ETK_WIDGET(menu_item), "deselect"); + etk_widget_theme_object_signal_emit(ETK_WIDGET(menu_item->image), "deselect"); + etk_widget_theme_object_signal_emit(ETK_WIDGET(menu_item->right_widget), "deselect"); menu_item->selected = FALSE; } +/* Default handler for the "activate" signal */ +static void _etk_menu_item_activate_handler(Etk_Menu_Item *menu_item) +{ + if (!menu_item) + return; + etk_widget_theme_object_signal_emit(ETK_WIDGET(menu_item), "activate"); + etk_widget_theme_object_signal_emit(ETK_WIDGET(menu_item->image), "activate"); + etk_widget_theme_object_signal_emit(ETK_WIDGET(menu_item->right_widget), "activate"); +} + /** @} */ =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_menu_item.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -3 -r1.1 -r1.2 --- etk_menu_item.h 11 Nov 2005 22:48:48 -0000 1.1 +++ etk_menu_item.h 13 Nov 2005 12:04:05 -0000 1.2 @@ -17,7 +17,10 @@ /** @brief Checks if the object is an Etk_Menu_Item */ #define ETK_IS_MENU_ITEM(obj) (ETK_OBJECT_CHECK_TYPE((obj), ETK_MENU_ITEM_TYPE)) -/* TODO: doc */ +/** + * @struct Etk_Menu_Item + * @brief An item of a menu or of a menu bar + */ struct _Etk_Menu_Item { /* private: */ @@ -28,10 +31,18 @@ void (*deselect)(Etk_Menu_Item *menu_item); void (*activate)(Etk_Menu_Item *menu_item); - Etk_Menu *child, *parent; + Etk_Menu_Shell *parent; + Etk_Menu *submenu; + char *label; Etk_Image *image; + /* "right_widget" can be the submenu arrow, the checkbox or the radiobox widget */ + Etk_Widget *right_widget; + Etk_Bool selected; + Etk_Bool show_image; + Etk_Bool show_right_swallow; + Etk_Bool right_widget_is_arrow; }; Etk_Type *etk_menu_item_type_get(); @@ -48,6 +59,9 @@ void etk_menu_item_submenu_set(Etk_Menu_Item *menu_item, Etk_Menu *submenu); void etk_menu_item_image_set(Etk_Menu_Item *menu_item, Etk_Image *image); +void etk_menu_item_image_show(Etk_Menu_Item *menu_item, Etk_Bool show); +void etk_menu_item_right_swallow_show(Etk_Menu_Item *menu_item, Etk_Bool show); + /** @} */ #endif =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_scrolled_view.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -3 -r1.4 -r1.5 --- etk_scrolled_view.c 11 Nov 2005 22:48:48 -0000 1.4 +++ etk_scrolled_view.c 13 Nov 2005 12:04:05 -0000 1.5 @@ -186,7 +186,7 @@ etk_signal_connect("value_changed", ETK_OBJECT(scrolled_view->hscrollbar), ETK_CALLBACK(_etk_scrolled_view_hscrollbar_value_changed_cb), scrolled_view); etk_signal_connect("value_changed", ETK_OBJECT(scrolled_view->vscrollbar), ETK_CALLBACK(_etk_scrolled_view_vscrollbar_value_changed_cb), scrolled_view); - etk_signal_connect("add", ETK_OBJECT(scrolled_view), ETK_CALLBACK(_etk_scrolled_view_add_cb), NULL); + etk_signal_connect("child_added", ETK_OBJECT(scrolled_view), ETK_CALLBACK(_etk_scrolled_view_add_cb), NULL); } /* Destroys the scrolled_view */ =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_types.h,v retrieving revision 1.12 retrieving revision 1.13 diff -u -3 -r1.12 -r1.13 --- etk_types.h 11 Nov 2005 22:48:48 -0000 1.12 +++ etk_types.h 13 Nov 2005 12:04:05 -0000 1.13 @@ -95,6 +95,7 @@ typedef struct _Etk_VScrollbar Etk_VScrollbar; typedef struct _Etk_HSeparator Etk_HSeparator; typedef struct _Etk_VSeparator Etk_VSeparator; +typedef struct _Etk_Menu_Shell Etk_Menu_Shell; typedef struct _Etk_Menu Etk_Menu; typedef struct _Etk_Menu_Item Etk_Menu_Item; =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_widget.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -3 -r1.11 -r1.12 --- etk_widget.c 11 Nov 2005 22:48:48 -0000 1.11 +++ etk_widget.c 13 Nov 2005 12:04:05 -0000 1.12 @@ -283,6 +283,7 @@ * @param widget the widget to realize * @note It shouldn't be called manually, it's mainly called by widget implementations */ +/* TODO realize all on realize */ void etk_widget_realize(Etk_Widget *widget) { Evas *evas = NULL; @@ -428,9 +429,15 @@ return; if (parent) + { parent->children = evas_list_append(parent->children, widget); + etk_signal_emit_by_name("child_added", ETK_OBJECT(parent), NULL, widget); + } else if (widget->parent) + { widget->parent->children = evas_list_remove(widget->parent->children, widget); + etk_signal_emit_by_name("child_removed", ETK_OBJECT(widget->parent), NULL, widget); + } old_parent = widget->parent; widget->parent = parent; =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_window.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -3 -r1.4 -r1.5 --- etk_window.c 11 Nov 2005 22:48:48 -0000 1.4 +++ etk_window.c 13 Nov 2005 12:04:05 -0000 1.5 @@ -415,6 +415,8 @@ etk_signal_connect("size_request", ETK_OBJECT(window), ETK_CALLBACK(_etk_window_size_request_cb), NULL); etk_signal_connect_swapped("show", ETK_OBJECT(window), ETK_CALLBACK(ecore_evas_show), window->ecore_evas); etk_signal_connect_swapped("hide", ETK_OBJECT(window), ETK_CALLBACK(ecore_evas_hide), window->ecore_evas); + + etk_widget_realize(ETK_WIDGET(window)); } /* Destroys the window */ ------------------------------------------------------- SF.Net email is sponsored by: Tame your development challenges with Apache's Geronimo App Server. Download it for free - -and be entered to win a 42" plasma tv or your very own Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs