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

Reply via email to