summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorHavoc Pennington <hp@pobox.com>2001-02-13 05:44:47 +0000
committerHavoc Pennington <hp@src.gnome.org>2001-02-13 05:44:47 +0000
commit2097d764a7a60f87a0ca4c43720f3e2644652a14 (patch)
tree5ce16eb25b20f4f6993b003c8e35e4eaf2f9b3c8 /gtk
parent41b2d039af6f972a5c442d860277164f90fb9ccb (diff)
downloadgtk+-2097d764a7a60f87a0ca4c43720f3e2644652a14.tar.gz
fix bug where it always set the foreground, even if we were only using a
2001-02-12 Havoc Pennington <hp@pobox.com> * gdk/gdkpango.c (gdk_pango_get_gc): fix bug where it always set the foreground, even if we were only using a stipple. (gdk_draw_layout_line_with_colors): new function, allow override colors (gdk_draw_layout_with_colors): new function, allow override colors (gdk_pango_layout_line_get_clip_region): function to get the clip region for a logical text range (gdk_pango_layout_get_clip_region): get the clip region for a logical text range * gdk/x11/gdkcolor-x11.c: forward declare gdk_colormap_sync(), (gdk_colormap_new): fix call to gdk_colormap_sync() so it has the right number of arguments. * gtk/gtktextbtree.c (gtk_text_btree_node_check_consistency): enhance the function to check that node data corresponds to a view still belonging to the tree. * gtk/gtktreeview.c (gtk_tree_view_changed): we were leaking the GtkTreePath (gtk_tree_view_inserted): ditto (gtk_tree_view_child_toggled): ditto * gtk/gtktreemodel.c (gtk_tree_path_append_index): use realloc to simplify this code. * gtk/gtkcellrenderertext.c (get_layout): fix leak of a PangoAttrList * demos/gtk-demo/main.c (load_file): Fix leak of a GString * gtk/gtkentry.c (gtk_entry_realize): Fix leak of a GdkCursor * gtk/gtkmenubar.c (gtk_menu_bar_size_request): consider toggle size in the size request (gtk_menu_bar_size_allocate): consider toggle size here * gtk/gtkimagemenuitem.h, gtkimagemenuitem.c: Menu item that displays a widget in the toggle slot * gtk/testgtk.c: test GtkImageMenuItem * gtk/Makefile.am, gtk/gtk.h: Add GtkImageMenuItem * gtk/gtkmenuitem.h: Use "gint" not "guint16" for toggle size request and allocation * gtk/gtkmenu.c (gtk_menu_size_request): use gint not guint16 * gtk/gtkcheckmenuitem.c (gtk_check_menu_item_toggle_size_request): ditto
Diffstat (limited to 'gtk')
-rw-r--r--gtk/Makefile.am2
-rw-r--r--gtk/gtk.h1
-rw-r--r--gtk/gtkcellrenderertext.c2
-rw-r--r--gtk/gtkcheckmenuitem.c4
-rw-r--r--gtk/gtkentry.c2
-rw-r--r--gtk/gtkimagemenuitem.c383
-rw-r--r--gtk/gtkimagemenuitem.h77
-rw-r--r--gtk/gtkmenu.c10
-rw-r--r--gtk/gtkmenubar.c18
-rw-r--r--gtk/gtkmenuitem.c16
-rw-r--r--gtk/gtkmenuitem.h8
-rw-r--r--gtk/gtktextbtree.c46
-rw-r--r--gtk/gtktreemodel.c13
-rw-r--r--gtk/gtktreeview.c50
-rw-r--r--gtk/testgtk.c14
15 files changed, 589 insertions, 57 deletions
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 84bc8dbc80..b709878fa7 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -104,6 +104,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
gtkhsv.h \
gtkiconfactory.h \
gtkimage.h \
+ gtkimagemenuitem.h \
gtkimcontext.h \
gtkimmodule.h \
gtkimmulticontext.h \
@@ -260,6 +261,7 @@ gtk_c_sources = @STRIP_BEGIN@ \
gtkhsv.c \
gtkiconfactory.c \
gtkimage.c \
+ gtkimagemenuitem.c \
gtkimcontext.c \
gtkimcontextsimple.c \
gtkimcontextsimple.h \
diff --git a/gtk/gtk.h b/gtk/gtk.h
index a84b83e2db..7eedaa1c8e 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -82,6 +82,7 @@
#include <gtk/gtkhseparator.h>
#include <gtk/gtkiconfactory.h>
#include <gtk/gtkimage.h>
+#include <gtk/gtkimagemenuitem.h>
#include <gtk/gtkimcontext.h>
#include <gtk/gtkimmulticontext.h>
#include <gtk/gtkinputdialog.h>
diff --git a/gtk/gtkcellrenderertext.c b/gtk/gtkcellrenderertext.c
index 7ad67797cb..cf803dd1b8 100644
--- a/gtk/gtkcellrenderertext.c
+++ b/gtk/gtkcellrenderertext.c
@@ -970,6 +970,8 @@ get_layout (GtkCellRendererText *celltext,
pango_layout_set_attributes (layout, attr_list);
pango_layout_set_width (layout, -1);
+ pango_attr_list_unref (attr_list);
+
return layout;
}
diff --git a/gtk/gtkcheckmenuitem.c b/gtk/gtkcheckmenuitem.c
index f0ad209b10..09b37baf79 100644
--- a/gtk/gtkcheckmenuitem.c
+++ b/gtk/gtkcheckmenuitem.c
@@ -42,7 +42,7 @@ static gint gtk_check_menu_item_expose (GtkWidget *wid
GdkEventExpose *event);
static void gtk_check_menu_item_activate (GtkMenuItem *menu_item);
static void gtk_check_menu_item_toggle_size_request (GtkMenuItem *menu_item,
- guint16 *requisition);
+ gint *requisition);
static void gtk_check_menu_item_draw_indicator (GtkCheckMenuItem *check_menu_item,
GdkRectangle *area);
static void gtk_real_check_menu_item_draw_indicator (GtkCheckMenuItem *check_menu_item,
@@ -147,7 +147,7 @@ gtk_check_menu_item_set_active (GtkCheckMenuItem *check_menu_item,
static void
gtk_check_menu_item_toggle_size_request (GtkMenuItem *menu_item,
- guint16 *requisition)
+ gint *requisition)
{
g_return_if_fail (menu_item != NULL);
g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (menu_item));
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index daada4fb7a..76929a7455 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -781,6 +781,8 @@ gtk_entry_realize (GtkWidget *widget)
entry->text_area = gdk_window_new (widget->window, &attributes, attributes_mask);
gdk_window_set_user_data (entry->text_area, entry);
+ gdk_cursor_destroy (attributes.cursor);
+
widget->style = gtk_style_attach (widget->style, widget->window);
gdk_window_set_background (widget->window, &widget->style->base[GTK_WIDGET_STATE (widget)]);
diff --git a/gtk/gtkimagemenuitem.c b/gtk/gtkimagemenuitem.c
new file mode 100644
index 0000000000..1266d03f2c
--- /dev/null
+++ b/gtk/gtkimagemenuitem.c
@@ -0,0 +1,383 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2001 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "gtkimagemenuitem.h"
+#include "gtkaccellabel.h"
+#include "gtksignal.h"
+
+static void gtk_image_menu_item_class_init (GtkImageMenuItemClass *klass);
+static void gtk_image_menu_item_init (GtkImageMenuItem *image_menu_item);
+
+static void gtk_image_menu_item_destroy (GtkObject *object);
+static void gtk_image_menu_item_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void gtk_image_menu_item_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static gint gtk_image_menu_item_expose (GtkWidget *widget,
+ GdkEventExpose *event);
+static void gtk_image_menu_item_remove (GtkContainer *container,
+ GtkWidget *child);
+static void gtk_image_menu_item_toggle_size_request (GtkMenuItem *menu_item,
+ gint *requisition);
+
+static void gtk_image_menu_item_map (GtkWidget *widget);
+static void gtk_image_menu_item_unmap (GtkWidget *widget);
+static void gtk_image_menu_item_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data);
+
+static GtkMenuItemClass *parent_class = NULL;
+
+GtkType
+gtk_image_menu_item_get_type (void)
+{
+ static GtkType image_menu_item_type = 0;
+
+ if (!image_menu_item_type)
+ {
+ static const GtkTypeInfo image_menu_item_info =
+ {
+ "GtkImageMenuItem",
+ sizeof (GtkImageMenuItem),
+ sizeof (GtkImageMenuItemClass),
+ (GtkClassInitFunc) gtk_image_menu_item_class_init,
+ (GtkObjectInitFunc) gtk_image_menu_item_init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ image_menu_item_type = gtk_type_unique (GTK_TYPE_MENU_ITEM, &image_menu_item_info);
+ }
+
+ return image_menu_item_type;
+}
+
+static void
+gtk_image_menu_item_class_init (GtkImageMenuItemClass *klass)
+{
+ GtkObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+ GtkMenuItemClass *menu_item_class;
+ GtkContainerClass *container_class;
+
+ object_class = (GtkObjectClass*) klass;
+ widget_class = (GtkWidgetClass*) klass;
+ menu_item_class = (GtkMenuItemClass*) klass;
+ container_class = (GtkContainerClass*) klass;
+
+ parent_class = gtk_type_class (GTK_TYPE_MENU_ITEM);
+
+ object_class->destroy = gtk_image_menu_item_destroy;
+
+ widget_class->expose_event = gtk_image_menu_item_expose;
+ widget_class->size_request = gtk_image_menu_item_size_request;
+ widget_class->size_allocate = gtk_image_menu_item_size_allocate;
+ widget_class->map = gtk_image_menu_item_map;
+ widget_class->unmap = gtk_image_menu_item_unmap;
+
+ container_class->forall = gtk_image_menu_item_forall;
+ container_class->remove = gtk_image_menu_item_remove;
+
+ menu_item_class->toggle_size_request = gtk_image_menu_item_toggle_size_request;
+}
+
+static void
+gtk_image_menu_item_init (GtkImageMenuItem *image_menu_item)
+{
+ image_menu_item->image = NULL;
+}
+
+static void
+gtk_image_menu_item_destroy (GtkObject *object)
+{
+ GtkImageMenuItem *image_menu_item;
+
+ image_menu_item = GTK_IMAGE_MENU_ITEM (object);
+
+ /* If you change forall to treat the image widget as
+ * an internal, then you have to destroy the image widget
+ * here.
+ */
+
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_image_menu_item_toggle_size_request (GtkMenuItem *menu_item,
+ gint *requisition)
+{
+ GtkImageMenuItem *image_menu_item;
+
+ g_return_if_fail (menu_item != NULL);
+ g_return_if_fail (GTK_IS_IMAGE_MENU_ITEM (menu_item));
+
+ image_menu_item = GTK_IMAGE_MENU_ITEM (menu_item);
+
+ if (image_menu_item->image)
+ *requisition = image_menu_item->image->requisition.width;
+ else
+ *requisition = 0;
+}
+
+
+static void
+gtk_image_menu_item_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ GtkImageMenuItem *image_menu_item;
+ gint child_height = 0;
+
+ image_menu_item = GTK_IMAGE_MENU_ITEM (widget);
+
+ if (image_menu_item->image && GTK_WIDGET_VISIBLE (image_menu_item->image))
+ {
+ GtkRequisition child_requisition;
+
+ gtk_widget_size_request (image_menu_item->image,
+ &child_requisition);
+
+ child_height = child_requisition.height;
+ }
+
+ (* GTK_WIDGET_CLASS (parent_class)->size_request) (widget, requisition);
+
+ /* not done with height since that happens via the
+ * toggle_size_request
+ */
+ requisition->height = MAX (requisition->height, child_height);
+
+ /* Note that GtkMenuShell always size requests before
+ * toggle_size_request, so toggle_size_request will be able to use
+ * image_menu_item->image->requisition
+ */
+}
+
+static void
+gtk_image_menu_item_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkImageMenuItem *image_menu_item;
+
+ image_menu_item = GTK_IMAGE_MENU_ITEM (widget);
+
+ (* GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation);
+
+ if (image_menu_item->image)
+ {
+ gint width, height, x, y;
+ GtkAllocation child_allocation;
+
+ /* Man this is lame hardcoding action, but I can't
+ * come up with a solution that's really better.
+ */
+
+ width = image_menu_item->image->requisition.width;
+ height = image_menu_item->image->requisition.height;
+
+ x = (GTK_CONTAINER (image_menu_item)->border_width +
+ widget->style->xthickness) +
+ (GTK_MENU_ITEM (image_menu_item)->toggle_size - width) / 2;
+ y = (widget->allocation.height - height) / 2;
+
+ child_allocation.width = width;
+ child_allocation.height = height;
+ child_allocation.x = MAX (x, 0);
+ child_allocation.y = MAX (y, 0);
+
+ gtk_widget_size_allocate (image_menu_item->image, &child_allocation);
+ }
+}
+
+static gint
+gtk_image_menu_item_expose (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ GdkEventExpose child_event;
+ GtkImageMenuItem *image_menu_item;
+
+ g_return_val_if_fail (widget != NULL, FALSE);
+ g_return_val_if_fail (GTK_IS_IMAGE_MENU_ITEM (widget), FALSE);
+ g_return_val_if_fail (event != NULL, FALSE);
+
+ image_menu_item = GTK_IMAGE_MENU_ITEM (widget);
+
+ if (GTK_WIDGET_CLASS (parent_class)->expose_event)
+ (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
+
+ child_event = *event;
+ if (image_menu_item->image && GTK_WIDGET_DRAWABLE (image_menu_item->image) &&
+ GTK_WIDGET_NO_WINDOW (image_menu_item->image) &&
+ gtk_widget_intersect (image_menu_item->image, &event->area, &child_event.area))
+ gtk_widget_event (image_menu_item->image, (GdkEvent*) &child_event);
+
+ return FALSE;
+}
+
+static void
+gtk_image_menu_item_map (GtkWidget *widget)
+{
+ GtkImageMenuItem *image_menu_item;
+
+ g_return_if_fail (GTK_IS_IMAGE_MENU_ITEM (widget));
+
+ image_menu_item = GTK_IMAGE_MENU_ITEM (widget);
+
+ (* GTK_WIDGET_CLASS (parent_class)->map) (widget);
+
+ if (image_menu_item->image &&
+ GTK_WIDGET_VISIBLE (image_menu_item->image) &&
+ !GTK_WIDGET_MAPPED (image_menu_item->image))
+ gtk_widget_map (image_menu_item->image);
+
+ if (!GTK_WIDGET_NO_WINDOW (widget))
+ gdk_window_show (widget->window);
+}
+
+static void
+gtk_image_menu_item_unmap (GtkWidget *widget)
+{
+ GtkImageMenuItem *image_menu_item;
+
+ g_return_if_fail (GTK_IS_IMAGE_MENU_ITEM (widget));
+
+ image_menu_item = GTK_IMAGE_MENU_ITEM (widget);
+
+ (* GTK_WIDGET_CLASS (parent_class)->unmap) (widget);
+
+ if (!GTK_WIDGET_NO_WINDOW (widget))
+ gdk_window_hide (widget->window);
+
+ if (image_menu_item->image && GTK_WIDGET_MAPPED (image_menu_item->image))
+ gtk_widget_unmap (image_menu_item->image);
+}
+
+static void
+gtk_image_menu_item_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ GtkImageMenuItem *image_menu_item;
+
+ g_return_if_fail (GTK_IS_IMAGE_MENU_ITEM (container));
+
+ image_menu_item = GTK_IMAGE_MENU_ITEM (container);
+
+ (* GTK_CONTAINER_CLASS (parent_class)->forall) (container,
+ include_internals,
+ callback,
+ callback_data);
+
+ if (image_menu_item->image)
+ (* callback) (image_menu_item->image, callback_data);
+}
+
+GtkWidget*
+gtk_image_menu_item_new (GtkWidget *widget,
+ const gchar *label)
+{
+ GtkImageMenuItem *image_menu_item;
+ GtkWidget *accel_label;
+
+ image_menu_item = GTK_IMAGE_MENU_ITEM (g_object_new (GTK_TYPE_IMAGE_MENU_ITEM,
+ NULL));
+
+ accel_label = gtk_accel_label_new (label);
+ gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
+
+ gtk_container_add (GTK_CONTAINER (image_menu_item), accel_label);
+ gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (accel_label),
+ GTK_WIDGET (image_menu_item));
+ gtk_widget_show (accel_label);
+
+ if (widget)
+ gtk_image_menu_item_add_image (image_menu_item, widget);
+
+ return GTK_WIDGET(image_menu_item);
+}
+
+void
+gtk_image_menu_item_add_image (GtkImageMenuItem *image_menu_item,
+ GtkWidget *child)
+{
+ g_return_if_fail (GTK_IS_IMAGE_MENU_ITEM (image_menu_item));
+ g_return_if_fail (image_menu_item->image == NULL);
+
+ gtk_widget_set_parent (child, GTK_WIDGET (image_menu_item));
+ image_menu_item->image = child;
+
+ if (GTK_WIDGET_REALIZED (child->parent))
+ gtk_widget_realize (child);
+
+ if (GTK_WIDGET_VISIBLE (child->parent) && GTK_WIDGET_VISIBLE (child))
+ {
+ if (GTK_WIDGET_MAPPED (child->parent))
+ gtk_widget_map (child);
+
+ gtk_widget_queue_resize (child);
+ }
+}
+
+GtkWidget*
+gtk_image_menu_item_get_image (GtkImageMenuItem *image_menu_item)
+{
+ g_return_val_if_fail (GTK_IS_IMAGE_MENU_ITEM (image_menu_item), NULL);
+
+ return image_menu_item->image;
+}
+
+void
+gtk_image_menu_item_remove (GtkContainer *container,
+ GtkWidget *child)
+{
+ GtkImageMenuItem *image_menu_item;
+
+ image_menu_item = GTK_IMAGE_MENU_ITEM (container);
+
+ if (child == image_menu_item->image)
+ {
+ gboolean widget_was_visible;
+
+ widget_was_visible = GTK_WIDGET_VISIBLE (child);
+
+ gtk_widget_unparent (child);
+ image_menu_item->image = NULL;
+
+ /* queue resize regardless of GTK_WIDGET_VISIBLE (container),
+ * since that's what is needed by toplevels, which derive from GtkBin.
+ */
+ if (widget_was_visible)
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ }
+ else
+ {
+ (* GTK_CONTAINER_CLASS (parent_class)->remove) (container, child);
+ }
+}
+
+
diff --git a/gtk/gtkimagemenuitem.h b/gtk/gtkimagemenuitem.h
new file mode 100644
index 0000000000..50be055b17
--- /dev/null
+++ b/gtk/gtkimagemenuitem.h
@@ -0,0 +1,77 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __GTK_MENU_IMAGE_ITEM_H__
+#define __GTK_MENU_IMAGE_ITEM_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkmenuitem.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_TYPE_IMAGE_MENU_ITEM (gtk_image_menu_item_get_type ())
+#define GTK_IMAGE_MENU_ITEM(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_IMAGE_MENU_ITEM, GtkImageMenuItem))
+#define GTK_IMAGE_MENU_ITEM_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_IMAGE_MENU_ITEM, GtkImageMenuItemClass))
+#define GTK_IS_IMAGE_MENU_ITEM(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_IMAGE_MENU_ITEM))
+#define GTK_IS_IMAGE_MENU_ITEM_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_IMAGE_MENU_ITEM))
+#define GTK_IMAGE_MENU_ITEM_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_IMAGE_MENU_ITEM, GtkImageMenuItemClass))
+
+
+typedef struct _GtkImageMenuItem GtkImageMenuItem;
+typedef struct _GtkImageMenuItemClass GtkImageMenuItemClass;
+
+struct _GtkImageMenuItem
+{
+ GtkMenuItem menu_item;
+
+ /*< private >*/
+ GtkWidget *image;
+};
+
+struct _GtkImageMenuItemClass
+{
+ GtkMenuItemClass parent_class;
+};
+
+
+GtkType gtk_image_menu_item_get_type (void) G_GNUC_CONST;
+GtkWidget* gtk_image_menu_item_new (GtkWidget *widget,
+ const gchar *label);
+void gtk_image_menu_item_add_image (GtkImageMenuItem *image_menu_item,
+ GtkWidget *child);
+GtkWidget* gtk_image_menu_item_get_image (GtkImageMenuItem *image_menu_item);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_IMAGE_MENU_ITEM_H__ */
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c
index a2015c4ff7..4a6f53ccc2 100644
--- a/gtk/gtkmenu.c
+++ b/gtk/gtkmenu.c
@@ -1089,8 +1089,14 @@ gtk_menu_size_request (GtkWidget *widget,
if (GTK_WIDGET_VISIBLE (child))
{
- guint16 toggle_size;
-
+ gint toggle_size;
+
+ /* It's important to size_request the child
+ * before doing the toggle size request, in
+ * case the toggle size request depends on the size
+ * request of a child of the child (e.g. for ImageMenuItem)
+ */
+
GTK_MENU_ITEM (child)->show_submenu_indicator = TRUE;
gtk_widget_size_request (child, &child_requisition);
diff --git a/gtk/gtkmenubar.c b/gtk/gtkmenubar.c
index 3be496c728..e6e7baf2dd 100644
--- a/gtk/gtkmenubar.c
+++ b/gtk/gtkmenubar.c
@@ -237,10 +237,16 @@ gtk_menu_bar_size_request (GtkWidget *widget,
if (GTK_WIDGET_VISIBLE (child))
{
+ gint toggle_size;
+
GTK_MENU_ITEM (child)->show_submenu_indicator = FALSE;
gtk_widget_size_request (child, &child_requisition);
-
+ gtk_menu_item_toggle_size_request (GTK_MENU_ITEM (child),
+ &toggle_size);
+
requisition->width += child_requisition.width;
+ requisition->width += toggle_size;
+
requisition->height = MAX (requisition->height, child_requisition.height);
/* Support for the right justified help menu */
if ((children == NULL) && GTK_IS_MENU_ITEM(child) &&
@@ -305,11 +311,17 @@ gtk_menu_bar_size_allocate (GtkWidget *widget,
children = menu_shell->children;
while (children)
{
+ gint toggle_size;
+
child = children->data;
children = children->next;
+ gtk_menu_item_toggle_size_request (GTK_MENU_ITEM (child),
+ &toggle_size);
gtk_widget_get_child_requisition (child, &child_requisition);
-
+
+ child_requisition.width += toggle_size;
+
/* Support for the right justified help menu */
if ( (children == NULL) && (GTK_IS_MENU_ITEM(child))
&& (GTK_MENU_ITEM(child)->right_justify))
@@ -321,6 +333,8 @@ gtk_menu_bar_size_allocate (GtkWidget *widget,
{
child_allocation.width = child_requisition.width;
+ gtk_menu_item_toggle_size_allocate (GTK_MENU_ITEM (child),
+ toggle_size);
gtk_widget_size_allocate (child, &child_allocation);
child_allocation.x += child_allocation.width + CHILD_SPACING * 2;
diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c
index 5f24585280..f44fc816f4 100644
--- a/gtk/gtkmenuitem.c
+++ b/gtk/gtkmenuitem.c
@@ -64,9 +64,9 @@ static void gtk_real_menu_item_select (GtkItem *item);
static void gtk_real_menu_item_deselect (GtkItem *item);
static void gtk_real_menu_item_activate_item (GtkMenuItem *item);
static void gtk_real_menu_item_toggle_size_request (GtkMenuItem *menu_item,
- guint16 *requisition);
+ gint *requisition);
static void gtk_real_menu_item_toggle_size_allocate (GtkMenuItem *menu_item,
- guint16 allocation);
+ gint allocation);
static gint gtk_menu_item_select_timeout (gpointer data);
static void gtk_menu_item_popup_submenu (gpointer data);
@@ -181,9 +181,9 @@ gtk_menu_item_class_init (GtkMenuItemClass *klass)
GTK_RUN_FIRST,
GTK_CLASS_TYPE (object_class),
GTK_SIGNAL_OFFSET (GtkMenuItemClass, toggle_size_allocate),
- gtk_marshal_NONE__UINT,
+ gtk_marshal_NONE__INT,
GTK_TYPE_NONE, 1,
- GTK_TYPE_UINT);
+ GTK_TYPE_INT);
}
static void
@@ -339,7 +339,7 @@ gtk_menu_item_activate (GtkMenuItem *menu_item)
void
gtk_menu_item_toggle_size_request (GtkMenuItem *menu_item,
- guint16 *requisition)
+ gint *requisition)
{
g_return_if_fail (menu_item != NULL);
g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
@@ -349,7 +349,7 @@ gtk_menu_item_toggle_size_request (GtkMenuItem *menu_item,
void
gtk_menu_item_toggle_size_allocate (GtkMenuItem *menu_item,
- guint16 allocation)
+ gint allocation)
{
g_return_if_fail (menu_item != NULL);
g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
@@ -652,7 +652,7 @@ gtk_real_menu_item_activate_item (GtkMenuItem *menu_item)
}
static void
gtk_real_menu_item_toggle_size_request (GtkMenuItem *menu_item,
- guint16 *requisition)
+ gint *requisition)
{
g_return_if_fail (menu_item != NULL);
g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
@@ -662,7 +662,7 @@ gtk_real_menu_item_toggle_size_request (GtkMenuItem *menu_item,
static void
gtk_real_menu_item_toggle_size_allocate (GtkMenuItem *menu_item,
- guint16 allocation)
+ gint allocation)
{
g_return_if_fail (menu_item != NULL);
g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
diff --git a/gtk/gtkmenuitem.h b/gtk/gtkmenuitem.h
index df52e516b2..28b081c668 100644
--- a/gtk/gtkmenuitem.h
+++ b/gtk/gtkmenuitem.h
@@ -81,9 +81,9 @@ struct _GtkMenuItemClass
void (* activate) (GtkMenuItem *menu_item);
void (* activate_item) (GtkMenuItem *menu_item);
void (* toggle_size_request) (GtkMenuItem *menu_item,
- guint16 *requisition);
+ gint *requisition);
void (* toggle_size_allocate) (GtkMenuItem *menu_item,
- guint16 allocation);
+ gint allocation);
};
@@ -102,9 +102,9 @@ void gtk_menu_item_select (GtkMenuItem *menu_item);
void gtk_menu_item_deselect (GtkMenuItem *menu_item);
void gtk_menu_item_activate (GtkMenuItem *menu_item);
void gtk_menu_item_toggle_size_request (GtkMenuItem *menu_item,
- guint16 *requisition);
+ gint *requisition);
void gtk_menu_item_toggle_size_allocate (GtkMenuItem *menu_item,
- guint16 allocation);
+ gint allocation);
void gtk_menu_item_right_justify (GtkMenuItem *menu_item);
diff --git a/gtk/gtktextbtree.c b/gtk/gtktextbtree.c
index d6bd9bca99..5cf5f889a1 100644
--- a/gtk/gtktextbtree.c
+++ b/gtk/gtktextbtree.c
@@ -5129,14 +5129,15 @@ gtk_text_btree_node_ensure_data (GtkTextBTreeNode *node, gpointer view_id)
nd = nd->next;
}
- if (nd == NULL) {
- nd = node_data_new (view_id);
-
- if (node->node_data)
- nd->next = node->node_data;
-
- node->node_data = nd;
- }
+ if (nd == NULL)
+ {
+ nd = node_data_new (view_id);
+
+ if (node->node_data)
+ nd->next = node->node_data;
+
+ node->node_data = nd;
+ }
return nd;
}
@@ -5798,7 +5799,7 @@ recompute_node_counts (GtkTextBTree *tree, GtkTextBTreeNode *node)
gtk_text_btree_node_check_valid (node, view->view_id);
view = view->next;
}
-
+
/*
* Scan through the GtkTextBTreeNode's tag records again and delete any Summary
* records that still have a zero count, or that have all the toggles.
@@ -6221,13 +6222,29 @@ _gtk_toggle_segment_check_func (GtkTextLineSegment *segPtr,
*/
static void
-gtk_text_btree_node_view_check_consistency (GtkTextBTreeNode *node,
+gtk_text_btree_node_view_check_consistency (GtkTextBTree *tree,
+ GtkTextBTreeNode *node,
NodeData *nd)
{
gint width;
gint height;
gboolean valid;
+ BTreeView *view;
+
+ view = tree->views;
+
+ while (view != NULL)
+ {
+ if (view->view_id == nd->view_id)
+ break;
+ view = view->next;
+ }
+
+ if (view == NULL)
+ g_error ("Node has data for a view %p no longer attached to the tree",
+ nd->view_id);
+
gtk_text_btree_node_compute_view_aggregates (node, nd->view_id,
&width, &height, &valid);
if (nd->width != width ||
@@ -6243,7 +6260,8 @@ gtk_text_btree_node_view_check_consistency (GtkTextBTreeNode *node,
}
static void
-gtk_text_btree_node_check_consistency (GtkTextBTreeNode *node)
+gtk_text_btree_node_check_consistency (GtkTextBTree *tree,
+ GtkTextBTreeNode *node)
{
GtkTextBTreeNode *childnode;
Summary *summary, *summary2;
@@ -6274,7 +6292,7 @@ gtk_text_btree_node_check_consistency (GtkTextBTreeNode *node)
nd = node->node_data;
while (nd != NULL)
{
- gtk_text_btree_node_view_check_consistency (node, nd);
+ gtk_text_btree_node_view_check_consistency (tree, node, nd);
nd = nd->next;
}
@@ -6343,7 +6361,7 @@ gtk_text_btree_node_check_consistency (GtkTextBTreeNode *node)
g_error ("gtk_text_btree_node_check_consistency: level mismatch (%d %d)",
node->level, childnode->level);
}
- gtk_text_btree_node_check_consistency (childnode);
+ gtk_text_btree_node_check_consistency (tree, childnode);
for (summary = childnode->summary; summary != NULL;
summary = summary->next)
{
@@ -6579,7 +6597,7 @@ _gtk_text_btree_check (GtkTextBTree *tree)
*/
node = tree->root_node;
- gtk_text_btree_node_check_consistency (tree->root_node);
+ gtk_text_btree_node_check_consistency (tree, tree->root_node);
/*
* Make sure that there are at least two lines in the text and
diff --git a/gtk/gtktreemodel.c b/gtk/gtktreemodel.c
index da6e5feea8..81befc0537 100644
--- a/gtk/gtktreemodel.c
+++ b/gtk/gtktreemodel.c
@@ -179,17 +179,8 @@ gtk_tree_path_append_index (GtkTreePath *path,
g_return_if_fail (path != NULL);
g_return_if_fail (index >= 0);
- new_indices = g_new (gint, ++path->depth);
- if (path->indices == NULL)
- {
- path->indices = new_indices;
- path->indices[0] = index;
- return;
- }
-
- memcpy (new_indices, path->indices, (path->depth - 1)*sizeof (gint));
- g_free (path->indices);
- path->indices = new_indices;
+ path->depth += 1;
+ path->indices = g_realloc (path->indices, path->depth * sizeof(gint));
path->indices[path->depth - 1] = index;
}
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 08f002f3a6..dd61fe29e6 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -2472,11 +2472,15 @@ gtk_tree_view_changed (GtkTreeModel *model,
GtkRBNode *node;
gint height;
gboolean dirty_marked;
+ gboolean free_path = FALSE;
g_return_if_fail (path != NULL || iter != NULL);
if (path == NULL)
- path = gtk_tree_model_get_path (model, iter);
+ {
+ path = gtk_tree_model_get_path (model, iter);
+ free_path = TRUE;
+ }
else if (iter == NULL)
gtk_tree_model_get_iter (model, iter, path);
@@ -2485,10 +2489,10 @@ gtk_tree_view_changed (GtkTreeModel *model,
&tree,
&node))
/* We aren't actually showing the node */
- return;
+ goto done;
if (tree == NULL)
- return;
+ goto done;
dirty_marked = gtk_tree_view_discover_dirty_iter (tree_view,
iter,
@@ -2499,7 +2503,7 @@ gtk_tree_view_changed (GtkTreeModel *model,
{
_gtk_rbtree_node_set_height (tree, node, height + TREE_VIEW_VERTICAL_SEPARATOR);
gtk_widget_queue_resize (GTK_WIDGET (data));
- return;
+ goto done;
}
if (dirty_marked)
gtk_widget_queue_resize (GTK_WIDGET (data));
@@ -2507,6 +2511,10 @@ gtk_tree_view_changed (GtkTreeModel *model,
{
gtk_tree_view_queue_draw_node (tree_view, tree, node, NULL);
}
+
+ done:
+ if (free_path)
+ gtk_tree_path_free (path);
}
static void
@@ -2522,12 +2530,16 @@ gtk_tree_view_inserted (GtkTreeModel *model,
gint max_height;
gint depth;
gint i = 0;
+ gboolean free_path = FALSE;
tmptree = tree = tree_view->priv->tree;
g_return_if_fail (path != NULL || iter != NULL);
if (path == NULL)
- path = gtk_tree_model_get_path (model, iter);
+ {
+ path = gtk_tree_model_get_path (model, iter);
+ free_path = TRUE;
+ }
else if (iter == NULL)
gtk_tree_model_get_iter (model, iter, path);
@@ -2540,7 +2552,7 @@ gtk_tree_view_inserted (GtkTreeModel *model,
if (tmptree == NULL)
{
/* We aren't showing the node */
- return;
+ goto done;
}
tmpnode = _gtk_rbtree_find_count (tmptree, indices[i] + 1);
@@ -2549,7 +2561,7 @@ gtk_tree_view_inserted (GtkTreeModel *model,
g_warning ("A node was inserted with a parent that's not in the tree.\n" \
"This possibly means that a GtkTreeModel inserted a child node\n" \
"before the parent was inserted.");
- return;
+ goto done;
}
else if (!GTK_RBNODE_FLAG_SET (tmpnode, GTK_RBNODE_IS_PARENT))
{
@@ -2562,7 +2574,7 @@ gtk_tree_view_inserted (GtkTreeModel *model,
tmpnode);
gtk_tree_view_child_toggled (model, tmppath, NULL, data);
gtk_tree_path_free (tmppath);
- return;
+ goto done;
}
tmptree = tmpnode->children;
@@ -2571,7 +2583,7 @@ gtk_tree_view_inserted (GtkTreeModel *model,
}
if (tree == NULL)
- return;
+ goto done;
/* ref the node */
gtk_tree_model_ref_iter (tree_view->priv->model, iter);
@@ -2591,6 +2603,10 @@ gtk_tree_view_inserted (GtkTreeModel *model,
}
_gtk_tree_view_set_size (tree_view, -1, tree_view->priv->height + max_height);
+
+ done:
+ if (free_path)
+ gtk_tree_path_free (path);
}
static void
@@ -2604,6 +2620,7 @@ gtk_tree_view_child_toggled (GtkTreeModel *model,
gboolean has_child;
GtkRBTree *tree;
GtkRBNode *node;
+ gboolean free_path = FALSE;
g_return_if_fail (path != NULL || iter != NULL);
@@ -2611,7 +2628,10 @@ gtk_tree_view_child_toggled (GtkTreeModel *model,
real_iter = *iter;
if (path == NULL)
- path = gtk_tree_model_get_path (model, iter);
+ {
+ path = gtk_tree_model_get_path (model, iter);
+ free_path = TRUE;
+ }
else if (iter == NULL)
gtk_tree_model_get_iter (model, &real_iter, path);
@@ -2620,16 +2640,16 @@ gtk_tree_view_child_toggled (GtkTreeModel *model,
&tree,
&node))
/* We aren't actually showing the node */
- return;
+ goto done;
if (tree == NULL)
- return;
+ goto done;
has_child = gtk_tree_model_iter_has_child (model, &real_iter);
/* Sanity check.
*/
if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_PARENT) == has_child)
- return;
+ goto done;
if (has_child)
GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_PARENT);
@@ -2656,6 +2676,10 @@ gtk_tree_view_child_toggled (GtkTreeModel *model,
/* FIXME: Just redraw the node */
gtk_widget_queue_draw (GTK_WIDGET (tree_view));
}
+
+ done:
+ if (free_path)
+ gtk_tree_path_free (path);
}
static void
diff --git a/gtk/testgtk.c b/gtk/testgtk.c
index d14d45d7a3..f257346ac9 100644
--- a/gtk/testgtk.c
+++ b/gtk/testgtk.c
@@ -2703,6 +2703,7 @@ create_menu (gint depth, gint length, gboolean tearoff)
{
GtkWidget *menu;
GtkWidget *menuitem;
+ GtkWidget *image;
GSList *group;
char buf[32];
int i, j;
@@ -2720,6 +2721,13 @@ create_menu (gint depth, gint length, gboolean tearoff)
gtk_widget_show (menuitem);
}
+ image = gtk_image_new_from_stock (GTK_STOCK_OPEN,
+ GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image);
+ menuitem = gtk_image_menu_item_new (image, "Image item");
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ gtk_widget_show (menuitem);
+
for (i = 0, j = 1; i < length; i++, j++)
{
sprintf (buf, "item %2d - %d", depth, j);
@@ -2755,6 +2763,7 @@ create_menus (void)
GtkWidget *menu;
GtkWidget *menuitem;
GtkAccelGroup *accel_group;
+ GtkWidget *image;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
@@ -2792,7 +2801,10 @@ create_menus (void)
gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
gtk_widget_show (menuitem);
- menuitem = gtk_menu_item_new_with_label ("bar");
+ image = gtk_image_new_from_stock (GTK_STOCK_HELP,
+ GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image);
+ menuitem = gtk_image_menu_item_new (image, "Help");
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (4, 5, TRUE));
gtk_menu_item_right_justify (GTK_MENU_ITEM (menuitem));
gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);