summaryrefslogtreecommitdiff
path: root/gtk/gtkmenu.c
diff options
context:
space:
mode:
authorTim Janik <timj@gtk.org>1998-06-07 06:48:56 +0000
committerTim Janik <timj@src.gnome.org>1998-06-07 06:48:56 +0000
commita391196ba51da34253593712e8bf4552c04f19e5 (patch)
tree50c2edfc5d066467f3c33c1f82c89dd9923c44c4 /gtk/gtkmenu.c
parentf522f36dd1c484b133ba6b04027667aa9144ad04 (diff)
downloadgdk-pixbuf-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.c561
1 files changed, 267 insertions, 294 deletions
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c
index 82a60310c..475e3576b 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),
- &GTK_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);
}
-