diff options
author | Tim Janik <timj@gtk.org> | 1998-06-07 06:48:56 +0000 |
---|---|---|
committer | Tim Janik <timj@src.gnome.org> | 1998-06-07 06:48:56 +0000 |
commit | a391196ba51da34253593712e8bf4552c04f19e5 (patch) | |
tree | 50c2edfc5d066467f3c33c1f82c89dd9923c44c4 /gtk/gtkmenu.c | |
parent | f522f36dd1c484b133ba6b04027667aa9144ad04 (diff) | |
download | gtk+-a391196ba51da34253593712e8bf4552c04f19e5.tar.gz |
fixed an assertment.
Sat Jun 6 06:01:24 1998 Tim Janik <timj@gtk.org>
* gtk/gtksignal.c (gtk_signal_emitv): fixed an assertment.
* gtk/makeenums.awk: a script to generate the GtkEnumValue arrays from,
this should eventually be done by gentypeinfo.el somewhen.
* gtk/gtkenumvalues.c: new generated file to hold GtkEnumValue arrays.
* gtk/gtktypeutils.h: new function gtk_enum_values() to retrive all the
enum values of an enum type.
* gtk/gtk.defs:
* gtk/gtkcurve.h:
* gtk/gtkobject.h:
* gtk/gtkprivate.h:
* gtk/gtkwidget.h:
* gtk/gtkenums.h:
brought enum/flags definitions in sync, added a few more enum
definitions for bindings and pattern matching.
* some more macro and GtkType fixups in various places.
* gdk/gdktypes.h (enum): added a new value GDK_AFTER_MASK, which is used
as a key-release modifier for the binding system.
Fri Jun 5 06:06:06 1998 Tim Janik <timj@gtk.org>
* gtk/gtkmenu.h (struct _GtkMenu): removed GList*children, since it
was a stale list pointer that is already present in GtkMenuShell.
* gtk/gtkmenushell.h (struct _GtkMenuShellClass): added a signal
GtkMenuShell::selection_done which is emitted after the menu shell
poped down again and all possible menu items have been activated.
Thu Jun 4 02:20:42 1998 Tim Janik <timj@gtk.org>
* gtk/gtkmenushell.c (gtk_menu_shell_button_release): flush the x-queue
before activation of the menuitem, so the menu is actually taken off the
screen prior to any menu item activation.
* gtk/gtkctree.c (gtk_ctree_get_row_data): allow function invokation
for NULL nodes.
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: new function gtk_widget_stop_accelerator to stop
the emission of the "add-accelerator" signal on a widget. this is
usefull to prevent accelerator installation on certain widgets.
* gtk/gtknotebook.c (gtk_notebook_menu_item_create): keep the menu
labels left justified, by setting their alignment. stop accelerator
installation for the menu items, since we use dynamic menus.
Wed Jun 3 06:41:22 1998 Tim Janik <timj@gtk.org>
* gtk/gtkmenufactory.c: adaptions to use the new accel groups. people
should *really* use GtkItemFactory. this is only for preserving source
compatibility where possible, use of GtkMenuFactory is deprecated as of
now.
* gtk/gtkobject.h (gtk_object_class_add_user_signal): new function
to create user signals of type GTK_RUN_NO_RECURSE. don't know why i
missed this possibility when i added gtk_object_class_add_user_signal
in late january.
* gtk/gtkmain.c (gtk_init): ignore subsequent function calls.
Sun May 31 07:31:09 1998 Tim Janik <timj@gtk.org>
* gtk/gtkaccelgroup.h:
* gtk/gtkaccelgroup.c: new implementation of the accelerator concept.
* gtk/gtkaccellabel.h:
* gtk/gtkaccellabel.c: new widget derived from GtkLabel whitch features
display of the accelerators associated with a certain widget.
* gtk/gtkitemfactory.h:
* gtk/gtkitemfactory.c: new widget, item factory with automatic rc
parsing and accelerator handling.
* gtk/gtkmenu.c (gtk_menu_reposition): new function to care for
positioning a menu.
(gtk_menu_map): removed the allocation code.
(gtk_menu_size_allocate): care for redrawing of children and resize
our widget->window correctly.
(gtk_menu_key_press): feature the new accelerator groups.
* gtk/gtkmenuitem.c (gtk_menu_item_size_allocate): reposition the
submenu if neccessary.
* gtk/gtkmenuitem.c:
* gtk/gtkcheckmenuitem.c:
* gtk/gtkradiomenuitem.c: use GtkAccelLabel in the *_new_with_label()
function variants.
* gdk/gdk.c:
(gdk_keyval_from_name):
(gdk_keyval_name): new functions for keyval<->key-name associations.
(gdk_keyval_to_upper):
(gdk_keyval_to_lower):
(gdk_keyval_is_upper):
(gdk_keyval_is_lower): new functions to check/translate keyvalues with
regards to their cases.
Wed May 27 00:48:10 1998 Tim Janik <timj@gtk.org>
* gtk/gtkwidget.c (gtk_widget_class_path): new function to calculate a
widget's class path.
(gtk_widget_path): new function to calculate a widget's name path.
* gtk/gtkrc.c: newly introduced GtkPatternSpec structures to speed up
pattern matching, features reversed pattern matches.
Diffstat (limited to 'gtk/gtkmenu.c')
-rw-r--r-- | gtk/gtkmenu.c | 561 |
1 files changed, 267 insertions, 294 deletions
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c index 82a60310c6..475e3576b8 100644 --- a/gtk/gtkmenu.c +++ b/gtk/gtkmenu.c @@ -8,7 +8,7 @@ * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -24,8 +24,8 @@ #include "gtksignal.h" -#define MENU_ITEM_CLASS(w) GTK_MENU_ITEM_CLASS (GTK_OBJECT (w)->klass) - +#define MENU_ITEM_CLASS(w) GTK_MENU_ITEM_CLASS (GTK_OBJECT (w)->klass) +#define MENU_NEEDS_RESIZE(m) GTK_MENU_SHELL (m)->menu_flag typedef struct _GtkMenuAttachData GtkMenuAttachData; @@ -36,40 +36,40 @@ struct _GtkMenuAttachData }; -static void gtk_menu_class_init (GtkMenuClass *klass); -static void gtk_menu_init (GtkMenu *menu); -static void gtk_menu_destroy (GtkObject *object); -static void gtk_menu_show (GtkWidget *widget); -static void gtk_menu_map (GtkWidget *widget); -static void gtk_menu_unmap (GtkWidget *widget); -static void gtk_menu_realize (GtkWidget *widget); -static void gtk_menu_size_request (GtkWidget *widget, +static void gtk_menu_class_init (GtkMenuClass *klass); +static void gtk_menu_init (GtkMenu *menu); +static void gtk_menu_destroy (GtkObject *object); +static void gtk_menu_show (GtkWidget *widget); +static void gtk_menu_map (GtkWidget *widget); +static void gtk_menu_unmap (GtkWidget *widget); +static void gtk_menu_realize (GtkWidget *widget); +static void gtk_menu_size_request (GtkWidget *widget, GtkRequisition *requisition); -static void gtk_menu_size_allocate (GtkWidget *widget, +static void gtk_menu_size_allocate (GtkWidget *widget, GtkAllocation *allocation); -static void gtk_menu_paint (GtkWidget *widget); -static void gtk_menu_draw (GtkWidget *widget, +static void gtk_menu_paint (GtkWidget *widget); +static void gtk_menu_draw (GtkWidget *widget, GdkRectangle *area); -static gint gtk_menu_expose (GtkWidget *widget, +static gint gtk_menu_expose (GtkWidget *widget, GdkEventExpose *event); -static gint gtk_menu_configure (GtkWidget *widget, +static gint gtk_menu_configure (GtkWidget *widget, GdkEventConfigure *event); -static gint gtk_menu_key_press (GtkWidget *widget, +static gint gtk_menu_key_press (GtkWidget *widget, GdkEventKey *event); static gint gtk_menu_need_resize (GtkContainer *container); -static void gtk_menu_deactivate (GtkMenuShell *menu_shell); -static void gtk_menu_show_all (GtkWidget *widget); -static void gtk_menu_hide_all (GtkWidget *widget); +static void gtk_menu_deactivate (GtkMenuShell *menu_shell); +static void gtk_menu_show_all (GtkWidget *widget); +static void gtk_menu_hide_all (GtkWidget *widget); static GtkMenuShellClass *parent_class = NULL; static const gchar *attach_data_key = "gtk-menu-attach-data"; -guint +GtkType gtk_menu_get_type (void) { - static guint menu_type = 0; - + static GtkType menu_type = 0; + if (!menu_type) { GtkTypeInfo menu_info = @@ -80,12 +80,12 @@ gtk_menu_get_type (void) (GtkClassInitFunc) gtk_menu_class_init, (GtkObjectInitFunc) gtk_menu_init, (GtkArgSetFunc) NULL, - (GtkArgGetFunc) NULL, + (GtkArgGetFunc) NULL, }; - + menu_type = gtk_type_unique (gtk_menu_shell_get_type (), &menu_info); } - + return menu_type; } @@ -96,15 +96,15 @@ gtk_menu_class_init (GtkMenuClass *class) GtkWidgetClass *widget_class; GtkContainerClass *container_class; GtkMenuShellClass *menu_shell_class; - + object_class = (GtkObjectClass*) class; widget_class = (GtkWidgetClass*) class; container_class = (GtkContainerClass*) class; menu_shell_class = (GtkMenuShellClass*) class; parent_class = gtk_type_class (gtk_menu_shell_get_type ()); - + object_class->destroy = gtk_menu_destroy; - + widget_class->show = gtk_menu_show; widget_class->map = gtk_menu_map; widget_class->unmap = gtk_menu_unmap; @@ -119,7 +119,7 @@ gtk_menu_class_init (GtkMenuClass *class) widget_class->hide_all = gtk_menu_hide_all; container_class->need_resize = gtk_menu_need_resize; - + menu_shell_class->submenu_placement = GTK_LEFT_RIGHT; menu_shell_class->deactivate = gtk_menu_deactivate; } @@ -128,55 +128,55 @@ static void gtk_menu_init (GtkMenu *menu) { GTK_WIDGET_SET_FLAGS (menu, GTK_TOPLEVEL); - + menu->parent_menu_item = NULL; menu->old_active_menu_item = NULL; - menu->accelerator_table = NULL; + menu->accel_group = NULL; menu->position_func = NULL; menu->position_func_data = NULL; - - GTK_MENU_SHELL (menu)->menu_flag = TRUE; + + MENU_NEEDS_RESIZE (menu) = TRUE; } static void -gtk_menu_destroy (GtkObject *object) +gtk_menu_destroy (GtkObject *object) { GtkMenuAttachData *data; - + g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_MENU (object)); - + gtk_widget_ref (GTK_WIDGET (object)); - + data = gtk_object_get_data (object, attach_data_key); if (data) gtk_menu_detach (GTK_MENU (object)); - - gtk_menu_set_accelerator_table (GTK_MENU (object), NULL); - + + gtk_menu_set_accel_group (GTK_MENU (object), NULL); + if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); - + gtk_widget_unref (GTK_WIDGET (object)); } void -gtk_menu_attach_to_widget (GtkMenu *menu, - GtkWidget *attach_widget, - GtkMenuDetachFunc detacher) +gtk_menu_attach_to_widget (GtkMenu *menu, + GtkWidget *attach_widget, + GtkMenuDetachFunc detacher) { GtkMenuAttachData *data; - + g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); g_return_if_fail (attach_widget != NULL); g_return_if_fail (GTK_IS_WIDGET (attach_widget)); g_return_if_fail (detacher != NULL); - + /* keep this function in sync with gtk_widget_set_parent() */ - + data = gtk_object_get_data (GTK_OBJECT (menu), attach_data_key); if (data) { @@ -184,31 +184,31 @@ gtk_menu_attach_to_widget (GtkMenu *menu, gtk_type_name (GTK_OBJECT_TYPE (data->attach_widget))); return; } - + gtk_widget_ref (GTK_WIDGET (menu)); gtk_object_sink (GTK_OBJECT (menu)); - + data = g_new (GtkMenuAttachData, 1); data->attach_widget = attach_widget; data->detacher = detacher; gtk_object_set_data (GTK_OBJECT (menu), attach_data_key, data); - + if (GTK_WIDGET_STATE (menu) != GTK_STATE_NORMAL) gtk_widget_set_state (GTK_WIDGET (menu), GTK_STATE_NORMAL); - + /* we don't need to set the style here, since * we are a toplevel widget. */ } GtkWidget* -gtk_menu_get_attach_widget (GtkMenu *menu) +gtk_menu_get_attach_widget (GtkMenu *menu) { GtkMenuAttachData *data; - + g_return_val_if_fail (menu != NULL, NULL); g_return_val_if_fail (GTK_IS_MENU (menu), NULL); - + data = gtk_object_get_data (GTK_OBJECT (menu), attach_data_key); if (data) return data->attach_widget; @@ -216,13 +216,13 @@ gtk_menu_get_attach_widget (GtkMenu *menu) } void -gtk_menu_detach (GtkMenu *menu) +gtk_menu_detach (GtkMenu *menu) { GtkMenuAttachData *data; - + g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); - + /* keep this function in sync with gtk_widget_unparent() */ data = gtk_object_get_data (GTK_OBJECT (menu), attach_data_key); @@ -232,14 +232,14 @@ gtk_menu_detach (GtkMenu *menu) return; } gtk_object_remove_data (GTK_OBJECT (menu), attach_data_key); - + data->detacher (data->attach_widget, menu); - + if (GTK_WIDGET_REALIZED (menu)) gtk_widget_unrealize (GTK_WIDGET (menu)); - + g_free (data); - + gtk_widget_unref (GTK_WIDGET (menu)); } @@ -266,37 +266,37 @@ gtk_menu_prepend (GtkMenu *menu, void gtk_menu_insert (GtkMenu *menu, GtkWidget *child, - gint position) + gint position) { gtk_menu_shell_insert (GTK_MENU_SHELL (menu), child, position); } void -gtk_menu_popup (GtkMenu *menu, - GtkWidget *parent_menu_shell, - GtkWidget *parent_menu_item, +gtk_menu_popup (GtkMenu *menu, + GtkWidget *parent_menu_shell, + GtkWidget *parent_menu_item, GtkMenuPositionFunc func, - gpointer data, - guint button, - guint32 activate_time) + gpointer data, + guint button, + guint32 activate_time) { GtkWidget *xgrab_shell; GtkWidget *parent; - + g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); - + GTK_MENU_SHELL (menu)->parent_menu_shell = parent_menu_shell; GTK_MENU_SHELL (menu)->active = TRUE; GTK_MENU_SHELL (menu)->button = button; - + menu->parent_menu_item = parent_menu_item; menu->position_func = func; menu->position_func_data = data; GTK_MENU_SHELL (menu)->activate_time = activate_time; - + gtk_widget_show (GTK_WIDGET (menu)); - + /* Find the last viewable ancestor, and make an X grab on it */ parent = GTK_WIDGET (menu); @@ -315,13 +315,13 @@ gtk_menu_popup (GtkMenu *menu, } tmp = tmp->parent; } - + if (viewable) xgrab_shell = parent; - + parent = GTK_MENU_SHELL (parent)->parent_menu_shell; } - + if (xgrab_shell && (!GTK_MENU_SHELL (xgrab_shell)->have_xgrab)) { GdkCursor *cursor = gdk_cursor_new (GDK_ARROW); @@ -333,7 +333,7 @@ gtk_menu_popup (GtkMenu *menu, NULL, cursor, activate_time) == 0); gdk_cursor_destroy (cursor); } - + gtk_grab_add (GTK_WIDGET (menu)); } @@ -341,27 +341,27 @@ void gtk_menu_popdown (GtkMenu *menu) { GtkMenuShell *menu_shell; - + g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); - + menu_shell = GTK_MENU_SHELL (menu); - + menu_shell->parent_menu_shell = NULL; menu_shell->active = FALSE; - + if (menu_shell->active_menu_item) { menu->old_active_menu_item = menu_shell->active_menu_item; gtk_menu_item_deselect (GTK_MENU_ITEM (menu_shell->active_menu_item)); menu_shell->active_menu_item = NULL; } - + /* The X Grab, if present, will automatically be removed when we hide * the window */ gtk_widget_hide (GTK_WIDGET (menu)); menu_shell->have_xgrab = FALSE; - + gtk_grab_remove (GTK_WIDGET (menu)); } @@ -370,28 +370,28 @@ gtk_menu_get_active (GtkMenu *menu) { GtkWidget *child; GList *children; - + g_return_val_if_fail (menu != NULL, NULL); g_return_val_if_fail (GTK_IS_MENU (menu), NULL); - + if (!menu->old_active_menu_item) { child = NULL; children = GTK_MENU_SHELL (menu)->children; - + while (children) { child = children->data; children = children->next; - + if (GTK_BIN (child)->child) break; child = NULL; } - + menu->old_active_menu_item = child; } - + return menu->old_active_menu_item; } @@ -401,10 +401,10 @@ gtk_menu_set_active (GtkMenu *menu, { GtkWidget *child; GList *tmp_list; - + g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); - + tmp_list = g_list_nth (GTK_MENU_SHELL (menu)->children, index); if (tmp_list) { @@ -415,19 +415,19 @@ gtk_menu_set_active (GtkMenu *menu, } void -gtk_menu_set_accelerator_table (GtkMenu *menu, - GtkAcceleratorTable *table) +gtk_menu_set_accel_group (GtkMenu *menu, + GtkAccelGroup *accel_group) { g_return_if_fail (menu != NULL); g_return_if_fail (GTK_IS_MENU (menu)); - - if (menu->accelerator_table != table) + + if (menu->accel_group != accel_group) { - if (menu->accelerator_table) - gtk_accelerator_table_unref (menu->accelerator_table); - menu->accelerator_table = table; - if (menu->accelerator_table) - gtk_accelerator_table_ref (menu->accelerator_table); + if (menu->accel_group) + gtk_accel_group_unref (menu->accel_group); + menu->accel_group = accel_group; + if (menu->accel_group) + gtk_accel_group_ref (menu->accel_group); } } @@ -437,11 +437,56 @@ gtk_menu_show (GtkWidget *widget) { g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); - + GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE); + if (MENU_NEEDS_RESIZE (widget)) + gtk_container_need_resize (GTK_CONTAINER (widget)); gtk_widget_map (widget); } +void +gtk_menu_reposition (GtkMenu *menu) +{ + GtkWidget *widget; + + g_return_if_fail (menu != NULL); + g_return_if_fail (GTK_IS_MENU (menu)); + + widget = GTK_WIDGET (menu); + + if (GTK_WIDGET_DRAWABLE (menu)) + { + gint x, y; + + gdk_window_get_pointer (NULL, &x, &y, NULL); + + if (menu->position_func) + (* menu->position_func) (menu, &x, &y, menu->position_func_data); + else + { + gint screen_width; + gint screen_height; + + screen_width = gdk_screen_width (); + screen_height = gdk_screen_height (); + + x -= 2; + y -= 2; + + if ((x + widget->requisition.width) > screen_width) + x -= ((x + widget->requisition.width) - screen_width); + if (x < 0) + x = 0; + if ((y + widget->requisition.height) > screen_height) + y -= ((y + widget->requisition.height) - screen_height); + if (y < 0) + y = 0; + } + + gdk_window_move (widget->window, x, y); + } +} + static void gtk_menu_map (GtkWidget *widget) { @@ -449,69 +494,26 @@ gtk_menu_map (GtkWidget *widget) GtkMenuShell *menu_shell; GtkWidget *child; GList *children; - GtkAllocation allocation; - gint x, y; - + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); - + menu = GTK_MENU (widget); menu_shell = GTK_MENU_SHELL (widget); GTK_WIDGET_SET_FLAGS (menu_shell, GTK_MAPPED); - gtk_widget_size_request (widget, &widget->requisition); - - if (menu_shell->menu_flag) - { - menu_shell->menu_flag = FALSE; - - allocation.x = widget->allocation.x; - allocation.y = widget->allocation.y; - allocation.width = widget->requisition.width; - allocation.height = widget->requisition.height; - - gtk_widget_size_allocate (widget, &allocation); - } - - gdk_window_get_pointer (NULL, &x, &y, NULL); - - if (menu->position_func) - (* menu->position_func) (menu, &x, &y, menu->position_func_data); - else - { - gint screen_width; - gint screen_height; - - screen_width = gdk_screen_width (); - screen_height = gdk_screen_height (); - - x -= 2; - y -= 2; - - if ((x + widget->requisition.width) > screen_width) - x -= ((x + widget->requisition.width) - screen_width); - if (x < 0) - x = 0; - if ((y + widget->requisition.height) > screen_height) - y -= ((y + widget->requisition.height) - screen_height); - if (y < 0) - y = 0; - } - - gdk_window_move_resize (widget->window, x, y, - widget->requisition.width, - widget->requisition.height); - + gtk_menu_reposition (menu); + children = menu_shell->children; while (children) { child = children->data; children = children->next; - + if (GTK_WIDGET_VISIBLE (child) && !GTK_WIDGET_MAPPED (child)) - gtk_widget_map (child); + gtk_widget_map (child); } - + gdk_window_show (widget->window); } @@ -520,7 +522,7 @@ gtk_menu_unmap (GtkWidget *widget) { g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); - + GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); gdk_window_hide (widget->window); } @@ -530,12 +532,12 @@ gtk_menu_realize (GtkWidget *widget) { GdkWindowAttr attributes; gint attributes_mask; - + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); - + GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); - + attributes.x = widget->allocation.x; attributes.y = widget->allocation.y; attributes.width = widget->allocation.width; @@ -548,11 +550,11 @@ gtk_menu_realize (GtkWidget *widget) attributes.event_mask |= (GDK_EXPOSURE_MASK | GDK_KEY_PRESS_MASK | GDK_STRUCTURE_MASK); - + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; widget->window = gdk_window_new (NULL, &attributes, attributes_mask); gdk_window_set_user_data (widget->window, widget); - + widget->style = gtk_style_attach (widget->style, widget->window); gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); } @@ -565,54 +567,50 @@ gtk_menu_size_request (GtkWidget *widget, GtkMenuShell *menu_shell; GtkWidget *child; GList *children; - gint max_accelerator_size; gint max_toggle_size; - + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); g_return_if_fail (requisition != NULL); - + menu = GTK_MENU (widget); menu_shell = GTK_MENU_SHELL (widget); - + requisition->width = 0; requisition->height = 0; - - max_accelerator_size = 0; + max_toggle_size = 0; - + children = menu_shell->children; while (children) { child = children->data; children = children->next; - + if (GTK_WIDGET_VISIBLE (child)) { GTK_MENU_ITEM (child)->show_submenu_indicator = TRUE; gtk_widget_size_request (child, &child->requisition); - + requisition->width = MAX (requisition->width, child->requisition.width); requisition->height += child->requisition.height; - - max_accelerator_size = MAX (max_accelerator_size, GTK_MENU_ITEM (child)->accelerator_size); + max_toggle_size = MAX (max_toggle_size, MENU_ITEM_CLASS (child)->toggle_size); } } - - requisition->width += max_toggle_size + max_accelerator_size; + + requisition->width += max_toggle_size; requisition->width += (GTK_CONTAINER (menu)->border_width + widget->style->klass->xthickness) * 2; requisition->height += (GTK_CONTAINER (menu)->border_width + widget->style->klass->ythickness) * 2; - + children = menu_shell->children; while (children) { child = children->data; children = children->next; - - GTK_MENU_ITEM (child)->accelerator_size = max_accelerator_size; + GTK_MENU_ITEM (child)->toggle_size = max_toggle_size; } } @@ -626,14 +624,14 @@ gtk_menu_size_allocate (GtkWidget *widget, GtkWidget *child; GtkAllocation child_allocation; GList *children; - + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); g_return_if_fail (allocation != NULL); - + menu = GTK_MENU (widget); menu_shell = GTK_MENU_SHELL (widget); - + widget->allocation = *allocation; if (menu_shell->children) @@ -643,23 +641,31 @@ gtk_menu_size_allocate (GtkWidget *widget, child_allocation.y = (GTK_CONTAINER (menu)->border_width + widget->style->klass->ythickness); child_allocation.width = MAX (1, allocation->width - child_allocation.x * 2); - + children = menu_shell->children; while (children) { child = children->data; children = children->next; - + if (GTK_WIDGET_VISIBLE (child)) { child_allocation.height = child->requisition.height; - + gtk_widget_size_allocate (child, &child_allocation); - + gtk_widget_queue_draw (child); + child_allocation.y += child_allocation.height; } } } + + if (GTK_WIDGET_REALIZED (widget)) + { + gdk_window_resize (widget->window, + widget->requisition.width, + widget->requisition.height); + } } static void @@ -667,7 +673,7 @@ gtk_menu_paint (GtkWidget *widget) { g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); - + if (GTK_WIDGET_DRAWABLE (widget)) { gtk_draw_shadow (widget->style, @@ -688,23 +694,23 @@ gtk_menu_draw (GtkWidget *widget, GtkWidget *child; GdkRectangle child_area; GList *children; - + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); g_return_if_fail (area != NULL); - + if (GTK_WIDGET_DRAWABLE (widget)) { gtk_menu_paint (widget); - + menu_shell = GTK_MENU_SHELL (widget); - + children = menu_shell->children; while (children) { child = children->data; children = children->next; - + if (gtk_widget_intersect (child, area, &child_area)) gtk_widget_draw (child, &child_area); } @@ -712,154 +718,122 @@ gtk_menu_draw (GtkWidget *widget, } static gint -gtk_menu_expose (GtkWidget *widget, +gtk_menu_expose (GtkWidget *widget, GdkEventExpose *event) { GtkMenuShell *menu_shell; GtkWidget *child; GdkEventExpose child_event; GList *children; - + g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_MENU (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); - + if (GTK_WIDGET_DRAWABLE (widget)) { gtk_menu_paint (widget); - + menu_shell = GTK_MENU_SHELL (widget); child_event = *event; - + children = menu_shell->children; while (children) { child = children->data; children = children->next; - + if (GTK_WIDGET_NO_WINDOW (child) && gtk_widget_intersect (child, &event->area, &child_event.area)) gtk_widget_event (child, (GdkEvent*) &child_event); } } - + return FALSE; } static gint -gtk_menu_configure (GtkWidget *widget, +gtk_menu_configure (GtkWidget *widget, GdkEventConfigure *event) { GtkAllocation allocation; - + g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_MENU (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); - + /* If the window was merely moved, do nothing */ if ((widget->allocation.width == event->width) && (widget->allocation.height == event->height)) return FALSE; - - if (GTK_MENU_SHELL (widget)->menu_flag) + + if (MENU_NEEDS_RESIZE (widget)) { - GTK_MENU_SHELL (widget)->menu_flag = FALSE; - + MENU_NEEDS_RESIZE (widget) = FALSE; + allocation.x = 0; allocation.y = 0; allocation.width = event->width; allocation.height = event->height; - + gtk_widget_size_allocate (widget, &allocation); } - + return FALSE; } static gint -gtk_menu_key_press (GtkWidget *widget, +gtk_menu_key_press (GtkWidget *widget, GdkEventKey *event) { - GtkAllocation allocation; - GtkAcceleratorTable *table; - gchar *signame; - int delete; - + gboolean delete; + g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_MENU (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); - - delete = ((event->keyval == GDK_Delete) || - (event->keyval == GDK_BackSpace)); - - if (delete || ((event->keyval >= 0x20) && (event->keyval <= 0xFF))) + + delete = (event->keyval == GDK_Delete || + event->keyval == GDK_KP_Delete || + event->keyval == GDK_BackSpace); + + if (delete || gtk_accelerator_valid (event->keyval, event->keyval)) { GtkMenuShell *menu_shell; - + menu_shell = GTK_MENU_SHELL (widget); - - if (menu_shell->active_menu_item && GTK_BIN (menu_shell->active_menu_item)->child) + + if (menu_shell->active_menu_item && + GTK_BIN (menu_shell->active_menu_item)->child && + GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu == NULL) { GtkMenuItem *menu_item; - + GtkAccelGroup *accel_group; + menu_item = GTK_MENU_ITEM (menu_shell->active_menu_item); - /* block resizes */ - gtk_container_block_resize (GTK_CONTAINER (widget)); - - table = NULL; - /* if the menu item currently has an accelerator then we'll - * remove it before we do anything else. - */ - if (menu_item->accelerator_signal) - { - signame = gtk_signal_name (menu_item->accelerator_signal); - table = gtk_accelerator_table_find (GTK_OBJECT (widget), - signame, - menu_item->accelerator_key, - menu_item->accelerator_mods); - if (!table) - table = GTK_MENU (widget)->accelerator_table; - gtk_widget_remove_accelerator (GTK_WIDGET (menu_item), - table, signame); - } - - if (!table) - table = GTK_MENU (widget)->accelerator_table; - - /* if we aren't simply deleting the accelerator, then we'll install - * the new one now. - */ - if (!delete) - gtk_widget_install_accelerator (GTK_WIDGET (menu_item), - table, "activate", - toupper (event->keyval), - event->state); - - /* check and see if the menu has changed size. */ - gtk_widget_size_request (widget, &widget->requisition); - - allocation.x = widget->allocation.x; - allocation.y = widget->allocation.y; - allocation.width = widget->requisition.width; - allocation.height = widget->requisition.height; - - if ((allocation.width == widget->allocation.width) && - (allocation.height == widget->allocation.height)) - { - gtk_widget_queue_draw (widget); - } + if (!GTK_MENU (widget)->accel_group) + accel_group = gtk_accel_group_get_default (); else - { - gtk_widget_size_allocate (GTK_WIDGET (widget), &allocation); - gtk_menu_map (widget); - } + accel_group = GTK_MENU (widget)->accel_group; - /* unblock resizes */ - gtk_container_unblock_resize (GTK_CONTAINER (widget)); + gtk_widget_remove_accelerators (GTK_WIDGET (menu_item), + gtk_signal_name (menu_item->accelerator_signal), + TRUE); + + if (!delete && + gtk_widget_accelerator_signal (GTK_WIDGET (menu_item), + accel_group, + event->keyval, + event->state) == 0) + gtk_widget_add_accelerator (GTK_WIDGET (menu_item), + gtk_signal_name (menu_item->accelerator_signal), + accel_group, + event->keyval, + event->state, + GTK_ACCEL_VISIBLE); } } - + return FALSE; } @@ -867,29 +841,29 @@ static gint gtk_menu_need_resize (GtkContainer *container) { GtkAllocation allocation; - + GtkWidget *widget; + g_return_val_if_fail (container != NULL, FALSE); g_return_val_if_fail (GTK_IS_MENU (container), FALSE); + widget = GTK_WIDGET (container); + if (GTK_WIDGET_VISIBLE (container)) { - GTK_MENU_SHELL (container)->menu_flag = FALSE; - - gtk_widget_size_request (GTK_WIDGET (container), - >K_WIDGET (container)->requisition); - - allocation.x = GTK_WIDGET (container)->allocation.x; - allocation.y = GTK_WIDGET (container)->allocation.y; - allocation.width = GTK_WIDGET (container)->requisition.width; - allocation.height = GTK_WIDGET (container)->requisition.height; - - gtk_widget_size_allocate (GTK_WIDGET (container), &allocation); + MENU_NEEDS_RESIZE (container) = FALSE; + + gtk_widget_size_request (widget, &widget->requisition); + + allocation.x = widget->allocation.x; + allocation.y = widget->allocation.y; + allocation.width = widget->requisition.width; + allocation.height = widget->requisition.height; + + gtk_widget_size_allocate (widget, &allocation); } else - { - GTK_MENU_SHELL (container)->menu_flag = TRUE; - } - + MENU_NEEDS_RESIZE (container) = TRUE; + return FALSE; } @@ -897,15 +871,15 @@ static void gtk_menu_deactivate (GtkMenuShell *menu_shell) { GtkWidget *parent; - + g_return_if_fail (menu_shell != NULL); g_return_if_fail (GTK_IS_MENU (menu_shell)); - + parent = menu_shell->parent_menu_shell; menu_shell->activate_time = 0; gtk_menu_popdown (GTK_MENU (menu_shell)); - + if (parent) gtk_menu_shell_deactivate (GTK_MENU_SHELL (parent)); } @@ -915,11 +889,11 @@ static void gtk_menu_show_all (GtkWidget *widget) { GtkContainer *container; - + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); container = GTK_CONTAINER (widget); - + /* Show children, but not self. */ gtk_container_foreach (container, (GtkCallback) gtk_widget_show_all, NULL); } @@ -929,12 +903,11 @@ static void gtk_menu_hide_all (GtkWidget *widget) { GtkContainer *container; - + g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_MENU (widget)); container = GTK_CONTAINER (widget); - + /* Hide children, but not self. */ gtk_container_foreach (container, (GtkCallback) gtk_widget_hide_all, NULL); } - |