revised image prop, icon patch
- From: Havoc Pennington <hp redhat com>
- To: gtk-devel-list gnome org
- Subject: revised image prop, icon patch
- Date: 28 Aug 2001 01:52:03 -0400
Hi,
Revised patches for GtkImage properties and setting window icons.
Havoc
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.2216
diff -u -p -u -r1.2216 ChangeLog
--- ChangeLog 2001/08/27 01:05:05 1.2216
+++ ChangeLog 2001/08/28 05:52:21
@@ -1,3 +1,35 @@
+2001-08-28 Havoc Pennington <hp pobox com>
+
+ * demos/gtk-demo/main.c (setup_default_icon): add default icon
+
+ * gtk/gtkradiobutton.c (gtk_radio_button_new_with_mnemonic):
+ warning fix
+ (gtk_radio_button_new_with_label): warning fix
+
+ * gtk/gtkdnd.c: used some random GtkImage private structs,
+ update to reflect GtkImage changes
+
+ * gdk/x11/gdkwindow-x11.c (gdk_window_set_icon_list): don't check
+ whether the hint is supported, just always set the icon. A task
+ list might want to use it even if the WM doesn't, and the WM may
+ change over time. Also, XDeleteProperty() if list == NULL.
+
+ * gtk/gtkwindow.c (gtk_window_set_icon_list)
+ (gtk_window_get_icon_list)
+ (gtk_window_set_icon)
+ (gtk_window_get_icon)
+ (gtk_window_set_default_icon_list)
+ (gtk_window_get_default_icon_list):
+ new functions
+
+ * gtk/gtk-boxed.defs (GtkIconSet): add GtkIconSet
+
+ * gtk/gtkimage.c: Implement property support, bug #59408
+
+ * gtk/gtkcontainer.c (gtk_container_add): make the warning message
+ on reparent-without-removing-first a bit more helpful.
+ Let's just destroy this FAQ.
+
2001-08-26 Alexander Larsson <alla lysator liu se>
* gtk/gtkbutton.[ch]:
Index: demos/gtk-demo/main.c
===================================================================
RCS file: /cvs/gnome/gtk+/demos/gtk-demo/main.c,v
retrieving revision 1.28
diff -u -p -u -r1.28 main.c
--- demos/gtk-demo/main.c 2001/08/10 03:45:44 1.28
+++ demos/gtk-demo/main.c 2001/08/28 05:52:21
@@ -722,6 +722,58 @@ create_tree (void)
return tree_view;
}
+static void
+setup_default_icon (void)
+{
+ GdkPixbuf *pixbuf;
+
+ /* Try in current directory, in case we haven't yet been installed
+ * (would be wrong in a real app)
+ */
+ pixbuf = gdk_pixbuf_new_from_file ("./gtk-logo-rgb.gif", NULL);
+
+ if (pixbuf == NULL)
+ {
+ GError *err;
+
+ err = NULL;
+ pixbuf = gdk_pixbuf_new_from_file (DEMOCODEDIR"/gtk-logo-rgb.gif",
+ &err);
+
+ /* Ignoring this error (passing NULL instead of &err above)
+ * would probably be reasonable for most apps. We're just
+ * showing off.
+ */
+ if (err)
+ {
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (NULL, 0,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "Failed to read icon file "DEMOCODEDIR"/gtk-logo-rgb.gif: %s",
+ err->message);
+ g_error_free (err);
+
+ gtk_signal_connect (GTK_OBJECT (dialog),
+ "response",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy),
+ NULL);
+ }
+ }
+
+ if (pixbuf)
+ {
+ GList *list;
+
+ list = NULL;
+ list = g_list_append (list, pixbuf);
+ gtk_window_set_default_icon_list (list);
+ g_list_free (list);
+ g_object_unref (G_OBJECT (pixbuf));
+ }
+}
+
int
main (int argc, char **argv)
{
@@ -744,6 +796,8 @@ main (int argc, char **argv)
/* -- End of hack -- */
gtk_init (&argc, &argv);
+
+ setup_default_icon ();
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "GTK+ Code Demos");
Index: docs/reference/gdk/tmpl/windows.sgml
===================================================================
RCS file: /cvs/gnome/gtk+/docs/reference/gdk/tmpl/windows.sgml,v
retrieving revision 1.14
diff -u -p -u -r1.14 windows.sgml
--- docs/reference/gdk/tmpl/windows.sgml 2001/08/10 03:45:45 1.14
+++ docs/reference/gdk/tmpl/windows.sgml 2001/08/28 05:52:21
@@ -793,6 +793,7 @@ Windows
@window:
@pixbufs:
+<!-- # Unused Parameters # -->
@Returns:
Index: docs/reference/gtk/tmpl/gtkbutton.sgml
===================================================================
RCS file: /cvs/gnome/gtk+/docs/reference/gtk/tmpl/gtkbutton.sgml,v
retrieving revision 1.7
diff -u -p -u -r1.7 gtkbutton.sgml
--- docs/reference/gtk/tmpl/gtkbutton.sgml 2001/03/23 22:21:05 1.7
+++ docs/reference/gtk/tmpl/gtkbutton.sgml 2001/08/28 05:52:21
@@ -181,3 +181,13 @@ there is actually a #GtkLabel inside of
The #GtkReliefStyle as outlined in gtk_button_set_relief().
</para>
+<!-- ##### ARG GtkButton:use-underline ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkButton:use-stock ##### -->
+<para>
+
+</para>
+
Index: docs/reference/gtk/tmpl/gtkimage.sgml
===================================================================
RCS file: /cvs/gnome/gtk+/docs/reference/gtk/tmpl/gtkimage.sgml,v
retrieving revision 1.8
diff -u -p -u -r1.8 gtkimage.sgml
--- docs/reference/gtk/tmpl/gtkimage.sgml 2001/08/26 02:03:09 1.8
+++ docs/reference/gtk/tmpl/gtkimage.sgml 2001/08/28 05:52:21
@@ -278,3 +278,53 @@ Gets the GtkImage
@mask: a GDKBitmap that indicates which parts of the image should be transparent.
+<!-- ##### ARG GtkImage:pixbuf ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkImage:pixmap ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkImage:image ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkImage:mask ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkImage:file ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkImage:stock ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkImage:icon-set ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkImage:icon-size ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkImage:pixbuf-animation ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkImage:storage-type ##### -->
+<para>
+
+</para>
+
Index: docs/reference/gtk/tmpl/gtkwindow.sgml
===================================================================
RCS file: /cvs/gnome/gtk+/docs/reference/gtk/tmpl/gtkwindow.sgml,v
retrieving revision 1.20
diff -u -p -u -r1.20 gtkwindow.sgml
--- docs/reference/gtk/tmpl/gtkwindow.sgml 2001/08/10 03:46:05 1.20
+++ docs/reference/gtk/tmpl/gtkwindow.sgml 2001/08/28 05:52:21
@@ -549,3 +549,13 @@ The position of the window.
</para>
+<!-- ##### ARG GtkWindow:icon-list ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkWindow:icon ##### -->
+<para>
+
+</para>
+
Index: gdk/gdkwindow.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkwindow.h,v
retrieving revision 1.29
diff -u -p -u -r1.29 gdkwindow.h
--- gdk/gdkwindow.h 2001/08/23 15:26:46 1.29
+++ gdk/gdkwindow.h 2001/08/28 05:52:21
@@ -444,7 +444,7 @@ GdkEventMask gdk_window_get_events (Gd
void gdk_window_set_events (GdkWindow *window,
GdkEventMask event_mask);
-gboolean gdk_window_set_icon_list (GdkWindow *window,
+void gdk_window_set_icon_list (GdkWindow *window,
GList *pixbufs);
void gdk_window_set_icon (GdkWindow *window,
GdkWindow *icon_window,
Index: gdk/x11/gdkwindow-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkwindow-x11.c,v
retrieving revision 1.123
diff -u -p -u -r1.123 gdkwindow-x11.c
--- gdk/x11/gdkwindow-x11.c 2001/08/10 03:46:07 1.123
+++ gdk/x11/gdkwindow-x11.c 2001/08/28 05:52:22
@@ -2325,7 +2325,6 @@ gdk_window_set_override_redirect (GdkWin
* gdk_window_set_icon_list:
* @window: The #GdkWindow toplevel window to set the icon of.
* @pixbufs: A list of pixbufs, of different sizes.
- * @Returns: %TRUE if the icons were set, false otherwise
*
* Sets a list of icons for the window. One of these will be used
* to represent the window when it has been iconified. The icon is
@@ -2335,12 +2334,8 @@ gdk_window_set_override_redirect (GdkWin
* image quality since the window manager may only need to scale the
* icon by a small amount or not at all.
*
- * On the X11 backend this call might fail if the window manager
- * doesn't support the Extended Window Manager Hints. Then this
- * function returns FALSE, and the application should fall back
- * to #gdk_window_set_icon().
**/
-gboolean
+void
gdk_window_set_icon_list (GdkWindow *window,
GList *pixbufs)
{
@@ -2354,14 +2349,10 @@ gdk_window_set_icon_list (GdkWindow *win
gint x, y;
gint n_channels;
- g_return_val_if_fail (window != NULL, FALSE);
- g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
+ g_return_if_fail (GDK_IS_WINDOW (window));
if (GDK_WINDOW_DESTROYED (window))
- return FALSE;
-
- if (!gdk_net_wm_supports (gdk_atom_intern ("_NET_WM_ICON", FALSE)))
- return FALSE;
+ return;
l = pixbufs;
size = 0;
@@ -2417,15 +2408,22 @@ gdk_window_set_icon_list (GdkWindow *win
l = g_list_next (l);
}
-
- XChangeProperty (GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XID (window),
- gdk_atom_intern ("_NET_WM_ICON", FALSE),
- XA_CARDINAL, 32,
- PropModeReplace,
- (guchar*) data, size);
- return TRUE;
+ if (size > 0)
+ {
+ XChangeProperty (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ gdk_atom_intern ("_NET_WM_ICON", FALSE),
+ XA_CARDINAL, 32,
+ PropModeReplace,
+ (guchar*) data, size);
+ }
+ else
+ {
+ XDeleteProperty (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ gdk_atom_intern ("_NET_WM_ICON", FALSE));
+ }
}
void
Index: gtk/gtk-boxed.defs
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtk-boxed.defs,v
retrieving revision 1.16
diff -u -p -u -r1.16 gtk-boxed.defs
--- gtk/gtk-boxed.defs 2001/07/25 13:36:02 1.16
+++ gtk/gtk-boxed.defs 2001/08/28 05:52:22
@@ -23,6 +23,11 @@
gtk_requisition_free
"sizeof(GtkRequisition)")
+(define-boxed GtkIconSet
+ gtk_icon_set_ref
+ gtk_icon_set_unref
+ "sizeof(GtkIconSet)")
+
;; TextView
(define-boxed GtkTextIter
Index: gtk/gtkcontainer.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkcontainer.c,v
retrieving revision 1.86
diff -u -p -u -r1.86 gtkcontainer.c
--- gtk/gtkcontainer.c 2001/08/23 23:38:32 1.86
+++ gtk/gtkcontainer.c 2001/08/28 05:52:22
@@ -858,7 +858,8 @@ gtk_container_add (GtkContainer *contain
if (widget->parent != NULL)
{
g_warning ("Attempting to add a widget with type %s to a container of "
- "type %s, but the widget is already inside a container of type %s",
+ "type %s, but the widget is already inside a container of type %s, "
+ "the GTK+ FAQ at http://www.gtk.org/faq/ explains how to reparent a widget.",
g_type_name (G_OBJECT_TYPE (widget)),
g_type_name (G_OBJECT_TYPE (container)),
g_type_name (G_OBJECT_TYPE (widget->parent)));
Index: gtk/gtkdnd.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkdnd.c,v
retrieving revision 1.66
diff -u -p -u -r1.66 gtkdnd.c
--- gtk/gtkdnd.c 2001/07/05 03:21:52 1.66
+++ gtk/gtkdnd.c 2001/08/28 05:52:23
@@ -78,6 +78,7 @@ struct _GtkDragSourceSite
GtkImagePixbufData pixbuf;
GtkImageStockData stock;
} icon_data;
+ GdkBitmap *icon_mask;
GdkColormap *colormap; /* Colormap for drag icon */
@@ -1941,8 +1942,8 @@ gtk_drag_source_unset_icon (GtkDragSourc
case GTK_IMAGE_PIXMAP:
if (site->icon_data.pixmap.pixmap)
gdk_pixmap_unref (site->icon_data.pixmap.pixmap);
- if (site->icon_data.pixmap.mask)
- gdk_pixmap_unref (site->icon_data.pixmap.mask);
+ if (site->icon_mask)
+ gdk_pixmap_unref (site->icon_mask);
break;
case GTK_IMAGE_PIXBUF:
g_object_unref (G_OBJECT (site->icon_data.pixbuf.pixbuf));
@@ -1999,7 +2000,7 @@ gtk_drag_source_set_icon (GtkWidget
site->icon_type = GTK_IMAGE_PIXMAP;
site->icon_data.pixmap.pixmap = pixmap;
- site->icon_data.pixmap.mask = mask;
+ site->icon_mask = mask;
site->colormap = colormap;
}
@@ -2683,7 +2684,7 @@ gtk_drag_source_event_cb (GtkWidget
gtk_drag_set_icon_pixmap (context,
site->colormap,
site->icon_data.pixmap.pixmap,
- site->icon_data.pixmap.mask,
+ site->icon_mask,
-2, -2);
break;
case GTK_IMAGE_PIXBUF:
Index: gtk/gtkimage.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkimage.c,v
retrieving revision 1.28
diff -u -p -u -r1.28 gtkimage.c
--- gtk/gtkimage.c 2001/08/25 03:15:26 1.28
+++ gtk/gtkimage.c 2001/08/28 05:52:23
@@ -28,8 +28,11 @@
#include "gtkimage.h"
#include "gtkiconfactory.h"
#include "gtkstock.h"
+#include "gtkintl.h"
#include <string.h>
+#define DEFAULT_ICON_SIZE GTK_ICON_SIZE_BUTTON
+
static void gtk_image_class_init (GtkImageClass *klass);
static void gtk_image_init (GtkImage *image);
static gint gtk_image_expose (GtkWidget *widget,
@@ -44,8 +47,32 @@ static void gtk_image_update_size (GtkI
gint image_width,
gint image_height);
+static void gtk_image_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gtk_image_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
static gpointer parent_class;
+enum
+{
+ PROP_0,
+ PROP_PIXBUF,
+ PROP_PIXMAP,
+ PROP_IMAGE,
+ PROP_MASK,
+ PROP_FILE,
+ PROP_STOCK,
+ PROP_ICON_SET,
+ PROP_ICON_SIZE,
+ PROP_PIXBUF_ANIMATION,
+ PROP_STORAGE_TYPE
+};
+
GtkType
gtk_image_get_type (void)
{
@@ -74,20 +101,109 @@ gtk_image_get_type (void)
static void
gtk_image_class_init (GtkImageClass *class)
{
+ GObjectClass *gobject_class;
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
parent_class = g_type_class_peek_parent (class);
- object_class = (GtkObjectClass *) class;
+ gobject_class = G_OBJECT_CLASS (class);
+ gobject_class->set_property = gtk_image_set_property;
+ gobject_class->get_property = gtk_image_get_property;
+
+ object_class = GTK_OBJECT_CLASS (class);
+
object_class->destroy = gtk_image_destroy;
-
- widget_class = (GtkWidgetClass*) class;
+ widget_class = GTK_WIDGET_CLASS (class);
+
widget_class->expose_event = gtk_image_expose;
widget_class->size_request = gtk_image_size_request;
widget_class->unmap = gtk_image_unmap;
+
+ g_object_class_install_property (gobject_class,
+ PROP_PIXBUF,
+ g_param_spec_object ("pixbuf",
+ _("Pixbuf"),
+ _("A GdkPixbuf to display."),
+ GDK_TYPE_PIXBUF,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_PIXMAP,
+ g_param_spec_object ("pixmap",
+ _("Pixmap"),
+ _("A GdkPixmap to display."),
+ GDK_TYPE_PIXMAP,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_IMAGE,
+ g_param_spec_object ("image",
+ _("Image"),
+ _("A GdkImage to display."),
+ GDK_TYPE_IMAGE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_MASK,
+ g_param_spec_object ("mask",
+ _("Mask"),
+ _("Mask bitmap to use with GdkImage or GdkPixmap"),
+ GDK_TYPE_PIXMAP,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_FILE,
+ g_param_spec_string ("file",
+ _("Filename"),
+ _("Filename to load and siplay."),
+ NULL,
+ G_PARAM_WRITABLE));
+
+
+ g_object_class_install_property (gobject_class,
+ PROP_STOCK,
+ g_param_spec_string ("stock",
+ _("Stock ID"),
+ _("Stock ID for a stock image to display."),
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_ICON_SET,
+ g_param_spec_boxed ("icon_set",
+ _("Icon set"),
+ _("Icon set to display."),
+ GTK_TYPE_ICON_SET,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_ICON_SIZE,
+ g_param_spec_int ("icon_size",
+ _("Icon size"),
+ _("Size to use for stock icon or icon set."),
+ 0, G_MAXINT,
+ DEFAULT_ICON_SIZE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_PIXBUF_ANIMATION,
+ g_param_spec_object ("pixbuf_animation",
+ _("Animation"),
+ _("GdkPixbufAnimation to display."),
+ GDK_TYPE_PIXBUF_ANIMATION,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_STORAGE_TYPE,
+ g_param_spec_enum ("storage_type",
+ _("Storage type"),
+ _("The representation being used for image data."),
+ GTK_TYPE_IMAGE_TYPE,
+ GTK_IMAGE_EMPTY,
+ G_PARAM_READABLE));
}
static void
@@ -96,6 +212,8 @@ gtk_image_init (GtkImage *image)
GTK_WIDGET_SET_FLAGS (image, GTK_NO_WINDOW);
image->storage_type = GTK_IMAGE_EMPTY;
+ image->icon_size = DEFAULT_ICON_SIZE;
+ image->mask = NULL;
}
static void
@@ -108,6 +226,167 @@ gtk_image_destroy (GtkObject *object)
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
+static void
+gtk_image_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkImage *image;
+
+ image = GTK_IMAGE (object);
+
+ switch (prop_id)
+ {
+ case PROP_PIXBUF:
+ gtk_image_set_from_pixbuf (image,
+ g_value_get_object (value));
+ break;
+ case PROP_PIXMAP:
+ gtk_image_set_from_pixmap (image,
+ g_value_get_object (value),
+ image->mask);
+ break;
+ case PROP_IMAGE:
+ gtk_image_set_from_image (image,
+ g_value_get_object (value),
+ image->mask);
+ break;
+ case PROP_MASK:
+ /* If current storage type doesn't support a mask,
+ * we switch to one that does. This allows setting
+ * mask first then the pixmap or image.
+ */
+ if (image->storage_type == GTK_IMAGE_PIXMAP)
+ gtk_image_set_from_pixmap (image,
+ image->data.pixmap.pixmap,
+ g_value_get_object (value));
+ else if (image->storage_type == GTK_IMAGE_IMAGE)
+ gtk_image_set_from_image (image,
+ image->data.image.image,
+ g_value_get_object (value));
+ else
+ gtk_image_set_from_pixmap (image,
+ NULL,
+ g_value_get_object (value));
+ break;
+ case PROP_FILE:
+ gtk_image_set_from_file (image,
+ g_value_get_string (value));
+ break;
+ case PROP_STOCK:
+ gtk_image_set_from_stock (image, g_value_get_string (value),
+ image->icon_size);
+ break;
+ case PROP_ICON_SET:
+ gtk_image_set_from_icon_set (image, g_value_get_boxed (value),
+ image->icon_size);
+ break;
+ case PROP_ICON_SIZE:
+ /* If current storage type doesn't support icon size,
+ * we switch to one that does. This allows setting
+ * size first then the stock ID or icon set
+ */
+ if (image->storage_type == GTK_IMAGE_STOCK)
+ gtk_image_set_from_stock (image,
+ image->data.stock.stock_id,
+ g_value_get_int (value));
+ else if (image->storage_type == GTK_IMAGE_ICON_SET)
+ gtk_image_set_from_icon_set (image,
+ image->data.icon_set.icon_set,
+ g_value_get_int (value));
+ else
+ gtk_image_set_from_stock (image,
+ GTK_STOCK_MISSING_IMAGE,
+ g_value_get_int (value));
+ break;
+ case PROP_PIXBUF_ANIMATION:
+ gtk_image_set_from_animation (image,
+ g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_image_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkImage *image;
+
+ image = GTK_IMAGE (object);
+
+ /* The "getter" functions whine if you try to get the wrong
+ * storage type. This function is instead robust against that,
+ * so that GUI builders don't have to jump through hoops
+ * to avoid g_warning
+ */
+
+ switch (prop_id)
+ {
+ case PROP_PIXBUF:
+ if (image->storage_type != GTK_IMAGE_PIXBUF)
+ g_value_set_object (value, NULL);
+ else
+ g_value_set_object (value,
+ gtk_image_get_pixbuf (image));
+ break;
+ case PROP_PIXMAP:
+ if (image->storage_type != GTK_IMAGE_PIXMAP)
+ g_value_set_object (value, NULL);
+ else
+ g_value_set_object (value,
+ image->data.pixmap.pixmap);
+ break;
+ case PROP_MASK:
+ g_value_set_object (value, image->mask);
+ break;
+ case PROP_IMAGE:
+ if (image->storage_type != GTK_IMAGE_IMAGE)
+ g_value_set_object (value, NULL);
+ else
+ g_value_set_object (value,
+ image->data.image.image);
+ break;
+ case PROP_STOCK:
+ if (image->storage_type != GTK_IMAGE_STOCK)
+ g_value_set_string (value, NULL);
+ else
+ g_value_set_string (value,
+ image->data.stock.stock_id);
+ break;
+ case PROP_ICON_SET:
+ if (image->storage_type != GTK_IMAGE_ICON_SET)
+ g_value_set_boxed (value, NULL);
+ else
+ g_value_set_boxed (value,
+ image->data.icon_set.icon_set);
+ break;
+ case PROP_ICON_SIZE:
+ g_value_set_int (value, image->icon_size);
+ break;
+ case PROP_PIXBUF_ANIMATION:
+ if (image->storage_type != GTK_IMAGE_ANIMATION)
+ g_value_set_object (value, NULL);
+ else
+ g_value_set_object (value,
+ image->data.anim.anim);
+ break;
+ case PROP_STORAGE_TYPE:
+ g_value_set_enum (value, image->storage_type);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
/**
* gtk_image_new_from_pixmap:
@@ -328,6 +607,8 @@ gtk_image_set_from_pixmap (GtkImage *im
GDK_IS_PIXMAP (pixmap));
g_return_if_fail (mask == NULL ||
GDK_IS_PIXMAP (mask));
+
+ g_object_freeze_notify (G_OBJECT (image));
if (pixmap)
g_object_ref (G_OBJECT (pixmap));
@@ -345,7 +626,7 @@ gtk_image_set_from_pixmap (GtkImage *im
image->storage_type = GTK_IMAGE_PIXMAP;
image->data.pixmap.pixmap = pixmap;
- image->data.pixmap.mask = mask;
+ image->mask = mask;
gdk_drawable_get_size (GDK_DRAWABLE (pixmap), &width, &height);
@@ -357,6 +638,11 @@ gtk_image_set_from_pixmap (GtkImage *im
if (mask)
g_object_unref (G_OBJECT (mask));
}
+
+ g_object_notify (G_OBJECT (image), "pixmap");
+ g_object_notify (G_OBJECT (image), "mask");
+
+ g_object_thaw_notify (G_OBJECT (image));
}
/**
@@ -379,6 +665,7 @@ gtk_image_set_from_image (GtkImage *im
g_return_if_fail (mask == NULL ||
GDK_IS_PIXMAP (mask));
+ g_object_freeze_notify (G_OBJECT (image));
if (gdk_image)
g_object_ref (G_OBJECT (gdk_image));
@@ -393,7 +680,7 @@ gtk_image_set_from_image (GtkImage *im
image->storage_type = GTK_IMAGE_IMAGE;
image->data.image.image = gdk_image;
- image->data.image.mask = mask;
+ image->mask = mask;
gtk_image_update_size (image, gdk_image->width, gdk_image->height);
}
@@ -403,6 +690,11 @@ gtk_image_set_from_image (GtkImage *im
if (mask)
g_object_unref (G_OBJECT (mask));
}
+
+ g_object_notify (G_OBJECT (image), "image");
+ g_object_notify (G_OBJECT (image), "mask");
+
+ g_object_thaw_notify (G_OBJECT (image));
}
/**
@@ -421,11 +713,16 @@ gtk_image_set_from_file (GtkImage *
g_return_if_fail (GTK_IS_IMAGE (image));
g_return_if_fail (filename != NULL);
+
+ g_object_freeze_notify (G_OBJECT (image));
gtk_image_reset (image);
if (filename == NULL)
- return;
+ {
+ g_object_thaw_notify (G_OBJECT (image));
+ return;
+ }
anim = gdk_pixbuf_animation_new_from_file (filename, NULL);
@@ -434,6 +731,7 @@ gtk_image_set_from_file (GtkImage *
gtk_image_set_from_stock (image,
GTK_STOCK_MISSING_IMAGE,
GTK_ICON_SIZE_BUTTON);
+ g_object_thaw_notify (G_OBJECT (image));
return;
}
@@ -453,6 +751,8 @@ gtk_image_set_from_file (GtkImage *
}
g_object_unref (G_OBJECT (anim));
+
+ g_object_thaw_notify (G_OBJECT (image));
}
/**
@@ -470,6 +770,8 @@ gtk_image_set_from_pixbuf (GtkImage *im
g_return_if_fail (GTK_IS_IMAGE (image));
g_return_if_fail (pixbuf == NULL ||
GDK_IS_PIXBUF (pixbuf));
+
+ g_object_freeze_notify (G_OBJECT (image));
if (pixbuf)
g_object_ref (G_OBJECT (pixbuf));
@@ -486,6 +788,10 @@ gtk_image_set_from_pixbuf (GtkImage *im
gdk_pixbuf_get_width (pixbuf),
gdk_pixbuf_get_height (pixbuf));
}
+
+ g_object_notify (G_OBJECT (image), "pixbuf");
+
+ g_object_thaw_notify (G_OBJECT (image));
}
/**
@@ -502,22 +808,34 @@ gtk_image_set_from_stock (GtkImage
const gchar *stock_id,
GtkIconSize size)
{
+ gchar *new_id;
+
g_return_if_fail (GTK_IS_IMAGE (image));
+
+ g_object_freeze_notify (G_OBJECT (image));
+
+ /* in case stock_id == image->data.stock.stock_id */
+ new_id = g_strdup (stock_id);
gtk_image_reset (image);
- if (stock_id)
- {
+ if (new_id)
+ {
image->storage_type = GTK_IMAGE_STOCK;
- image->data.stock.stock_id = g_strdup (stock_id);
- image->data.stock.size = size;
+ image->data.stock.stock_id = new_id;
+ image->icon_size = size;
/* Size is demand-computed in size request method
* if we're a stock image, since changing the
* style impacts the size request
*/
}
+
+ g_object_notify (G_OBJECT (image), "stock");
+ g_object_notify (G_OBJECT (image), "icon_size");
+
+ g_object_thaw_notify (G_OBJECT (image));
}
/**
@@ -536,6 +854,8 @@ gtk_image_set_from_icon_set (GtkImage
{
g_return_if_fail (GTK_IS_IMAGE (image));
+ g_object_freeze_notify (G_OBJECT (image));
+
if (icon_set)
gtk_icon_set_ref (icon_set);
@@ -546,12 +866,17 @@ gtk_image_set_from_icon_set (GtkImage
image->storage_type = GTK_IMAGE_ICON_SET;
image->data.icon_set.icon_set = icon_set;
- image->data.icon_set.size = size;
+ image->icon_size = size;
/* Size is demand-computed in size request method
* if we're an icon set
*/
}
+
+ g_object_notify (G_OBJECT (image), "icon_set");
+ g_object_notify (G_OBJECT (image), "icon_size");
+
+ g_object_thaw_notify (G_OBJECT (image));
}
/**
@@ -569,6 +894,8 @@ gtk_image_set_from_animation (GtkImage
g_return_if_fail (GTK_IS_IMAGE (image));
g_return_if_fail (animation == NULL ||
GDK_IS_PIXBUF_ANIMATION (animation));
+
+ g_object_freeze_notify (G_OBJECT (image));
if (animation)
g_object_ref (G_OBJECT (animation));
@@ -587,6 +914,10 @@ gtk_image_set_from_animation (GtkImage
gdk_pixbuf_animation_get_width (animation),
gdk_pixbuf_animation_get_height (animation));
}
+
+ g_object_notify (G_OBJECT (image), "pixbuf_animation");
+
+ g_object_thaw_notify (G_OBJECT (image));
}
/**
@@ -633,7 +964,7 @@ gtk_image_get_pixmap (GtkImage *image,
*pixmap = image->data.pixmap.pixmap;
if (mask)
- *mask = image->data.pixmap.mask;
+ *mask = image->mask;
}
/**
@@ -661,7 +992,7 @@ gtk_image_get_image (GtkImage *image,
*gdk_image = image->data.image.image;
if (mask)
- *mask = image->data.image.mask;
+ *mask = image->mask;
}
/**
@@ -719,7 +1050,7 @@ gtk_image_get_stock (GtkImage *i
*stock_id = image->data.stock.stock_id;
if (size)
- *size = image->data.stock.size;
+ *size = image->icon_size;
}
/**
@@ -746,7 +1077,7 @@ gtk_image_get_icon_set (GtkImage
*icon_set = image->data.icon_set.icon_set;
if (size)
- *size = image->data.icon_set.size;
+ *size = image->icon_size;
}
/**
@@ -899,14 +1230,14 @@ gtk_image_expose (GtkWidget *widget
switch (image->storage_type)
{
case GTK_IMAGE_PIXMAP:
- mask = image->data.pixmap.mask;
+ mask = image->mask;
gdk_drawable_get_size (image->data.pixmap.pixmap,
&image_bound.width,
&image_bound.height);
break;
case GTK_IMAGE_IMAGE:
- mask = image->data.image.mask;
+ mask = image->mask;
image_bound.width = image->data.image.image->width;
image_bound.height = image->data.image.image->height;
break;
@@ -919,7 +1250,7 @@ gtk_image_expose (GtkWidget *widget
case GTK_IMAGE_STOCK:
stock_pixbuf = gtk_widget_render_icon (widget,
image->data.stock.stock_id,
- image->data.stock.size,
+ image->icon_size,
NULL);
if (stock_pixbuf)
{
@@ -934,7 +1265,7 @@ gtk_image_expose (GtkWidget *widget
widget->style,
gtk_widget_get_direction (widget),
GTK_WIDGET_STATE (widget),
- image->data.icon_set.size,
+ image->icon_size,
widget,
NULL);
@@ -1070,26 +1401,41 @@ gtk_image_expose (GtkWidget *widget
static void
gtk_image_clear (GtkImage *image)
{
+ g_object_freeze_notify (G_OBJECT (image));
+
+ if (image->storage_type != GTK_IMAGE_EMPTY)
+ g_object_notify (G_OBJECT (image), "storage_type");
+
switch (image->storage_type)
{
case GTK_IMAGE_PIXMAP:
if (image->data.pixmap.pixmap)
g_object_unref (G_OBJECT (image->data.pixmap.pixmap));
-
- if (image->data.pixmap.mask)
- g_object_unref (G_OBJECT (image->data.pixmap.mask));
-
+ image->data.pixmap.pixmap = NULL;
+
+ if (image->mask)
+ g_object_unref (G_OBJECT (image->mask));
+ image->mask = NULL;
+
+ g_object_notify (G_OBJECT (image), "pixmap");
+ g_object_notify (G_OBJECT (image), "mask");
+
break;
case GTK_IMAGE_IMAGE:
if (image->data.image.image)
g_object_unref (G_OBJECT (image->data.image.image));
-
- if (image->data.image.mask)
- g_object_unref (G_OBJECT (image->data.image.mask));
-
+ image->data.image.image = NULL;
+
+ if (image->mask)
+ g_object_unref (G_OBJECT (image->mask));
+ image->mask = NULL;
+
+ g_object_notify (G_OBJECT (image), "image");
+ g_object_notify (G_OBJECT (image), "mask");
+
break;
case GTK_IMAGE_PIXBUF:
@@ -1097,26 +1443,46 @@ gtk_image_clear (GtkImage *image)
if (image->data.pixbuf.pixbuf)
g_object_unref (G_OBJECT (image->data.pixbuf.pixbuf));
+ g_object_notify (G_OBJECT (image), "pixbuf");
+
break;
case GTK_IMAGE_STOCK:
g_free (image->data.stock.stock_id);
+
+ image->icon_size = DEFAULT_ICON_SIZE;
+ image->data.stock.stock_id = NULL;
+
+ g_object_notify (G_OBJECT (image), "stock");
+ g_object_notify (G_OBJECT (image), "icon_size");
break;
case GTK_IMAGE_ICON_SET:
if (image->data.icon_set.icon_set)
gtk_icon_set_unref (image->data.icon_set.icon_set);
+ image->data.icon_set.icon_set = NULL;
+ image->icon_size = DEFAULT_ICON_SIZE;
+
+ g_object_notify (G_OBJECT (image), "icon_set");
+ g_object_notify (G_OBJECT (image), "icon_size");
+
break;
case GTK_IMAGE_ANIMATION:
if (image->data.anim.frame_timeout)
g_source_remove (image->data.anim.frame_timeout);
-
+
if (image->data.anim.anim)
- g_object_unref (G_OBJECT (image->data.anim.anim));
+ g_object_unref (G_OBJECT (image->data.anim.anim));
+
+ image->data.anim.frame_timeout = 0;
+ image->data.anim.anim = NULL;
+
+ g_object_notify (G_OBJECT (image), "pixbuf_animation");
+
break;
case GTK_IMAGE_EMPTY:
@@ -1128,6 +1494,8 @@ gtk_image_clear (GtkImage *image)
image->storage_type = GTK_IMAGE_EMPTY;
memset (&image->data, '\0', sizeof (image->data));
+
+ g_object_thaw_notify (G_OBJECT (image));
}
static void
@@ -1158,7 +1526,7 @@ gtk_image_size_request (GtkWidget *
case GTK_IMAGE_STOCK:
pixbuf = gtk_widget_render_icon (GTK_WIDGET (image),
image->data.stock.stock_id,
- image->data.stock.size,
+ image->icon_size,
NULL);
break;
@@ -1167,7 +1535,7 @@ gtk_image_size_request (GtkWidget *
widget->style,
gtk_widget_get_direction (widget),
GTK_WIDGET_STATE (widget),
- image->data.icon_set.size,
+ image->icon_size,
widget,
NULL);
break;
Index: gtk/gtkimage.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkimage.h,v
retrieving revision 1.12
diff -u -p -u -r1.12 gtkimage.h
--- gtk/gtkimage.h 2001/08/25 03:15:26 1.12
+++ gtk/gtkimage.h 2001/08/28 05:52:23
@@ -57,13 +57,11 @@ typedef struct _GtkImageAnimationData Gt
struct _GtkImagePixmapData
{
GdkPixmap *pixmap;
- GdkBitmap *mask;
};
struct _GtkImageImageData
{
GdkImage *image;
- GdkBitmap *mask;
};
struct _GtkImagePixbufData
@@ -74,13 +72,11 @@ struct _GtkImagePixbufData
struct _GtkImageStockData
{
gchar *stock_id;
- GtkIconSize size;
};
struct _GtkImageIconSetData
{
GtkIconSet *icon_set;
- GtkIconSize size;
};
struct _GtkImageAnimationData
@@ -116,6 +112,12 @@ struct _GtkImage
GtkImageIconSetData icon_set;
GtkImageAnimationData anim;
} data;
+
+ /* Only used with GTK_IMAGE_PIXMAP, GTK_IMAGE_IMAGE */
+ GdkBitmap *mask;
+
+ /* Only used with GTK_IMAGE_STOCK, GTK_IMAGE_ICON_SET */
+ GtkIconSize icon_size;
};
struct _GtkImageClass
Index: gtk/gtkradiobutton.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkradiobutton.c,v
retrieving revision 1.29
diff -u -p -u -r1.29 gtkradiobutton.c
--- gtk/gtkradiobutton.c 2001/08/27 01:05:07 1.29
+++ gtk/gtkradiobutton.c 2001/08/28 05:52:23
@@ -220,7 +220,7 @@ gtk_radio_button_new_with_label (GSList
radio_button = g_object_new (GTK_TYPE_CHECK_BUTTON, "label", label, NULL) ;
if (group)
- gtk_radio_button_set_group (radio_button, group);
+ gtk_radio_button_set_group (GTK_RADIO_BUTTON (radio_button), group);
return radio_button;
}
@@ -246,7 +246,7 @@ gtk_radio_button_new_with_mnemonic (GSLi
radio_button = g_object_new (GTK_TYPE_CHECK_BUTTON, "label", label, "use_underline", TRUE, NULL);
if (group)
- gtk_radio_button_set_group (radio_button, group);
+ gtk_radio_button_set_group (GTK_RADIO_BUTTON (radio_button), group);
return radio_button;
}
Index: gtk/gtkwindow.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwindow.c,v
retrieving revision 1.143
diff -u -p -u -r1.143 gtkwindow.c
--- gtk/gtkwindow.c 2001/08/26 02:03:10 1.143
+++ gtk/gtkwindow.c 2001/08/28 05:52:24
@@ -64,7 +64,7 @@ enum {
/* Construct */
PROP_TYPE,
- /* Style Props */
+ /* Normal Props */
PROP_TITLE,
PROP_ALLOW_SHRINK,
PROP_ALLOW_GROW,
@@ -74,10 +74,22 @@ enum {
PROP_DEFAULT_WIDTH,
PROP_DEFAULT_HEIGHT,
PROP_DESTROY_WITH_PARENT,
-
+ PROP_ICON_LIST,
+ PROP_ICON,
+
LAST_ARG
};
+typedef struct
+{
+ GList *icon_list;
+ GdkPixmap *icon_pixmap;
+ GdkPixmap *icon_mask;
+ guint realized : 1;
+ guint using_default_icon : 1;
+ guint using_parent_icon : 1;
+} GtkWindowIconInfo;
+
typedef struct {
GdkGeometry geometry; /* Last set of geometry hints we set */
GdkWindowHints flags;
@@ -217,11 +229,17 @@ static void gtk_window_set_default_s
gboolean change_height,
gint height);
+static void gtk_window_realize_icon (GtkWindow *window);
+static void gtk_window_unrealize_icon (GtkWindow *window);
static GSList *toplevel_list = NULL;
static GHashTable *mnemonic_hash_table = NULL;
static GtkBinClass *parent_class = NULL;
static guint window_signals[LAST_SIGNAL] = { 0 };
+static GList *default_icon_list = NULL;
+/* FIXME need to be per-screen */
+static GdkPixmap *default_icon_pixmap = NULL;
+static GdkPixmap *default_icon_mask = NULL;
static void gtk_window_set_property (GObject *object,
guint prop_id,
@@ -349,7 +367,7 @@ gtk_window_class_init (GtkWindowClass *k
GTK_WINDOW_TOPLEVEL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
- /* Style Props */
+ /* Regular Props */
g_object_class_install_property (gobject_class,
PROP_TITLE,
g_param_spec_string ("title",
@@ -427,8 +445,21 @@ gtk_window_class_init (GtkWindowClass *k
FALSE,
G_PARAM_READWRITE));
- /* Style props are set or not */
+ g_object_class_install_property (gobject_class,
+ PROP_ICON_LIST,
+ g_param_spec_pointer ("icon_list",
+ _("Icon list"),
+ _("List of icons to represent the window"),
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_ICON,
+ g_param_spec_object ("icon",
+ _("Icon"),
+ _("Icon for this window"),
+ GDK_TYPE_PIXBUF,
+ G_PARAM_READWRITE));
+
window_signals[SET_FOCUS] =
g_signal_new ("set_focus",
G_TYPE_FROM_CLASS (object_class),
@@ -651,6 +682,20 @@ gtk_window_set_property (GObject *o
case PROP_DESTROY_WITH_PARENT:
gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
break;
+ case PROP_ICON_LIST:
+ gtk_window_set_icon_list (window, g_value_get_pointer (value));
+ break;
+ case PROP_ICON:
+ {
+ GdkPixbuf *pixbuf;
+ pixbuf = g_value_get_object (value);
+ if (pixbuf)
+ gtk_window_set_icon (window, GDK_PIXBUF (pixbuf));
+ else
+ gtk_window_set_icon (window, NULL);
+ }
+ break;
+
default:
break;
}
@@ -707,6 +752,17 @@ gtk_window_get_property (GObject *o
case PROP_DESTROY_WITH_PARENT:
g_value_set_boolean (value, window->destroy_with_parent);
break;
+ case PROP_ICON_LIST:
+ /* Returns a copy of the list, owned by the caller
+ * not the gvalue.
+ */
+ g_value_set_pointer (value,
+ gtk_window_get_icon_list (window));
+ break;
+ case PROP_ICON:
+ g_value_set_object (value,
+ G_OBJECT (gtk_window_get_icon (window)));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1706,6 +1762,503 @@ gtk_window_get_decorated (GtkWindow *win
}
static void
+gdk_pixbuf_render_pixmap_and_mask_with_colormap (GdkPixbuf *pixbuf,
+ GdkPixmap **pixmap_return,
+ GdkBitmap **mask_return,
+ int alpha_threshold,
+ GdkColormap *cmap)
+{
+ g_return_if_fail (pixbuf != NULL);
+
+ if (pixmap_return)
+ {
+ GdkGC *gc;
+
+ *pixmap_return = gdk_pixmap_new (NULL, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf),
+ gdk_colormap_get_visual (cmap)->depth);
+ gdk_drawable_set_colormap (GDK_DRAWABLE (*pixmap_return),
+ cmap);
+ gc = gdk_gc_new (*pixmap_return);
+ gdk_pixbuf_render_to_drawable (pixbuf, *pixmap_return, gc,
+ 0, 0, 0, 0,
+ gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf),
+ GDK_RGB_DITHER_NORMAL,
+ 0, 0);
+ gdk_gc_unref (gc);
+ }
+
+ if (mask_return)
+ {
+ if (gdk_pixbuf_get_has_alpha (pixbuf))
+ {
+ *mask_return = gdk_pixmap_new (NULL, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), 1);
+
+ gdk_pixbuf_render_threshold_alpha (pixbuf, *mask_return,
+ 0, 0, 0, 0,
+ gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf),
+ alpha_threshold);
+ }
+ else
+ *mask_return = NULL;
+ }
+}
+
+static GtkWindowIconInfo*
+get_icon_info (GtkWindow *window)
+{
+ return g_object_get_data (G_OBJECT (window),
+ "gtk-window-icon-info");
+}
+
+static GtkWindowIconInfo*
+ensure_icon_info (GtkWindow *window)
+{
+ GtkWindowIconInfo *info;
+
+ info = get_icon_info (window);
+
+ if (info == NULL)
+ {
+ info = g_new0 (GtkWindowIconInfo, 1);
+ g_object_set_data_full (G_OBJECT (window),
+ "gtk-window-icon-info",
+ info,
+ g_free);
+ }
+
+ return info;
+}
+
+static void
+get_pixmap_and_mask (GtkWindowIconInfo *parent_info,
+ gboolean is_default_list,
+ GList *icon_list,
+ GdkPixmap **pmap_return,
+ GdkBitmap **mask_return)
+{
+ GdkPixbuf *best_icon;
+ GList *tmp_list;
+ int best_size;
+
+ *pmap_return = NULL;
+ *mask_return = NULL;
+
+ if (is_default_list &&
+ default_icon_pixmap != NULL)
+ {
+ /* Use shared icon pixmap (eventually will be stored on the
+ * GdkScreen)
+ */
+ if (default_icon_pixmap)
+ g_object_ref (G_OBJECT (default_icon_pixmap));
+ if (default_icon_mask)
+ g_object_ref (G_OBJECT (default_icon_mask));
+
+ *pmap_return = default_icon_pixmap;
+ *mask_return = default_icon_mask;
+ }
+ else if (parent_info && parent_info->icon_pixmap)
+ {
+ if (parent_info->icon_pixmap)
+ g_object_ref (G_OBJECT (parent_info->icon_pixmap));
+ if (parent_info->icon_mask)
+ g_object_ref (G_OBJECT (parent_info->icon_mask));
+
+ *pmap_return = parent_info->icon_pixmap;
+ *mask_return = parent_info->icon_mask;
+ }
+ else
+ {
+#define IDEAL_SIZE 48
+
+ best_size = G_MAXINT;
+ best_icon = NULL;
+ tmp_list = icon_list;
+ while (tmp_list != NULL)
+ {
+ GdkPixbuf *pixbuf = tmp_list->data;
+ int this;
+
+ /* average width and height - if someone passes in a rectangular
+ * icon they deserve what they get.
+ */
+ this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
+ this /= 2;
+
+ if (best_icon == NULL)
+ {
+ best_icon = pixbuf;
+ best_size = this;
+ }
+ else
+ {
+ /* icon is better if it's 32 pixels or larger, and closer to
+ * the ideal size than the current best.
+ */
+ if (this >= 32 &&
+ (ABS (best_size - IDEAL_SIZE) <
+ ABS (this - IDEAL_SIZE)))
+ {
+ best_icon = pixbuf;
+ best_size = this;
+ }
+ }
+
+ tmp_list = tmp_list->next;
+ }
+
+ if (best_icon)
+ gdk_pixbuf_render_pixmap_and_mask_with_colormap (best_icon,
+ pmap_return,
+ mask_return,
+ 128,
+ gdk_colormap_get_system ());
+
+ /* Save pmap/mask for others to use if appropriate */
+ if (parent_info)
+ {
+ parent_info->icon_pixmap = *pmap_return;
+ parent_info->icon_mask = *mask_return;
+
+ if (parent_info->icon_pixmap)
+ g_object_ref (G_OBJECT (parent_info->icon_pixmap));
+ if (parent_info->icon_mask)
+ g_object_ref (G_OBJECT (parent_info->icon_mask));
+ }
+ else if (is_default_list)
+ {
+ default_icon_pixmap = *pmap_return;
+ default_icon_mask = *mask_return;
+
+ if (default_icon_pixmap)
+ g_object_add_weak_pointer (G_OBJECT (default_icon_pixmap),
+ (gpointer*)&default_icon_pixmap);
+ if (default_icon_mask)
+ g_object_add_weak_pointer (G_OBJECT (default_icon_mask),
+ (gpointer*)&default_icon_mask);
+ }
+ }
+}
+
+static void
+gtk_window_realize_icon (GtkWindow *window)
+{
+ GtkWidget *widget;
+ GtkWindowIconInfo *info;
+ GList *icon_list;
+
+ widget = GTK_WIDGET (window);
+
+ g_return_if_fail (widget->window != NULL);
+
+ /* no point setting an icon on override-redirect */
+ if (window->type == GTK_WINDOW_POPUP)
+ return;
+
+ icon_list = NULL;
+
+ info = ensure_icon_info (window);
+
+ if (info->realized)
+ return;
+
+ g_return_if_fail (info->icon_pixmap == NULL);
+ g_return_if_fail (info->icon_mask == NULL);
+
+ info->using_default_icon = FALSE;
+ info->using_parent_icon = FALSE;
+
+ icon_list = info->icon_list;
+
+ /* Inherit from transient parent */
+ if (icon_list == NULL && window->transient_parent)
+ {
+ icon_list = ensure_icon_info (window->transient_parent)->icon_list;
+ if (icon_list)
+ info->using_parent_icon = TRUE;
+ }
+
+ /* Inherit from default */
+ if (icon_list == NULL)
+ {
+ icon_list = default_icon_list;
+ if (icon_list)
+ info->using_default_icon = TRUE;
+ }
+
+ gdk_window_set_icon_list (widget->window, icon_list);
+
+ get_pixmap_and_mask (info->using_parent_icon ?
+ ensure_icon_info (window->transient_parent) : NULL,
+ info->using_default_icon,
+ icon_list,
+ &info->icon_pixmap,
+ &info->icon_mask);
+
+ /* This is a slight ICCCM violation since it's a color pixmap not
+ * a bitmap, but everyone does it.
+ */
+ gdk_window_set_icon (widget->window,
+ NULL,
+ info->icon_pixmap,
+ info->icon_mask);
+
+ info->realized = TRUE;
+}
+
+static void
+gtk_window_unrealize_icon (GtkWindow *window)
+{
+ GtkWindowIconInfo *info;
+ GtkWidget *widget;
+
+ widget = GTK_WIDGET (window);
+
+ info = get_icon_info (window);
+
+ if (info == NULL)
+ return;
+
+ if (info->icon_pixmap)
+ g_object_unref (G_OBJECT (info->icon_pixmap));
+
+ if (info->icon_mask)
+ g_object_unref (G_OBJECT (info->icon_mask));
+
+ info->icon_pixmap = NULL;
+ info->icon_mask = NULL;
+
+ /* We don't clear the properties on the window, just figure the
+ * window is going away.
+ */
+}
+
+/**
+ * gtk_window_set_icon_list:
+ * @window: a #GtkWindow
+ * @list: list of #GdkPixbuf
+ *
+ * Sets up the icon representing a #GtkWindow. The icon is used when
+ * the window is minimized (also known as iconified). Some window
+ * managers or desktop environments may also place it in the window
+ * frame, or display it in other contexts.
+ *
+ * gtk_window_set_icon_list() allows you to pass in the same icon in
+ * several hand-drawn sizes. The list should contain the natural sizes
+ * your icon is available in; that is, don't scale the image before
+ * passing it to GTK+. Scaling is postponed until the last minute,
+ * when the desired final size is known, to allow best quality.
+ *
+ * By passing several sizes, you may improve the final image quality
+ * of the icon, by reducing or eliminating automatic image scaling.
+ *
+ * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
+ * larger images (64x64, 128x128) if you have them.
+ *
+ * See also gtk_window_set_default_icon_list() to set the icon
+ * for all windows in your application in one go.
+ *
+ * Note that transient windows (those who have been set transient for another
+ * window using gtk_window_set_transient_for()) will inherit their
+ * icon from their transient parent. So there's no need to explicitly
+ * set the icon on transient windows.
+ **/
+void
+gtk_window_set_icon_list (GtkWindow *window,
+ GList *list)
+{
+ GtkWindowIconInfo *info;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
+ info = ensure_icon_info (window);
+
+ if (info->icon_list == list) /* check for NULL mostly */
+ return;
+
+ g_list_foreach (info->icon_list,
+ (GFunc) g_object_unref, NULL);
+
+ g_list_free (info->icon_list);
+
+ info->icon_list = g_list_copy (list);
+ g_list_foreach (info->icon_list,
+ (GFunc) g_object_ref, NULL);
+
+ g_object_notify (G_OBJECT (window), "icon_list");
+
+ gtk_window_unrealize_icon (window);
+
+ if (GTK_WIDGET_REALIZED (window))
+ gtk_window_realize_icon (window);
+
+ /* We could try to update our transient children, but I don't think
+ * it's really worth it. If we did it, the best way would probably
+ * be to have children connect to notify::icon_list
+ */
+}
+
+/**
+ * gtk_window_get_icon_list:
+ * @window: a #GtkWindow
+ *
+ * Retrieves the list of icons set by gtk_window_set_icon_list().
+ * The list is copied, but the reference count on each
+ * member won't be incremented.
+ *
+ * Return value: a list of icons
+ **/
+GList*
+gtk_window_get_icon_list (GtkWindow *window)
+{
+ GtkWindowIconInfo *info;
+
+ g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
+
+ info = get_icon_info (window);
+
+ if (info)
+ return g_list_copy (info->icon_list);
+ else
+ return NULL;
+}
+
+/**
+ * gtk_window_set_icon:
+ * @window: a #GtkWindow
+ * @icon: icon image, or %NULL
+ *
+ * Sets up the icon representing a #GtkWindow. This icon is used when
+ * the window is minimized (also known as iconified). Some window
+ * managers or desktop environments may also place it in the window
+ * frame, or display it in other contexts.
+ *
+ * The icon should be provided in whatever size it was naturally
+ * drawn; that is, don't scale the image before passing it to
+ * GTK+. Scaling is postponed until the last minute, when the desired
+ * final size is known, to allow best quality.
+ *
+ * If you have your icon hand-drawn in multiple sizes, use
+ * gtk_window_set_icon_list(). Then the best size will be used.
+ *
+ * This function is equivalent to calling gtk_window_set_icon_list()
+ * with a 1-element list.
+ *
+ * See also gtk_window_set_default_icon_list() to set the icon
+ * for all windows in your application in one go.
+ **/
+void
+gtk_window_set_icon (GtkWindow *window,
+ GdkPixbuf *icon)
+{
+ GList *list;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+ g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
+
+ list = NULL;
+ list = g_list_append (list, icon);
+ gtk_window_set_icon_list (window, list);
+ g_list_free (list);
+}
+
+/**
+ * gtk_window_get_icon:
+ * @window: a #GtkWindow
+ *
+ * Gets the value set by gtk_window_set_icon() (or if you've
+ * called gtk_window_set_icon_list(), gets the first icon in
+ * the icon list).
+ *
+ * Return value: icon for window
+ **/
+GdkPixbuf*
+gtk_window_get_icon (GtkWindow *window)
+{
+ GtkWindowIconInfo *info;
+
+ info = get_icon_info (window);
+ if (info && info->icon_list)
+ return GDK_PIXBUF (info->icon_list->data);
+ else
+ return NULL;
+}
+
+/**
+ * gtk_window_set_default_icon_list:
+ * @list: a list of #GdkPixbuf
+ *
+ * Sets an icon list to be used as fallback for windows that haven't
+ * had gtk_window_set_icon_list() called on them to set up a
+ * window-specific icon list. This function allows you to set up the
+ * icon for all windows in your app at once.
+ *
+ * See gtk_window_set_icon_list() for more details.
+ *
+ **/
+void
+gtk_window_set_default_icon_list (GList *list)
+{
+ GList *toplevels;
+ GList *tmp_list;
+ if (list == default_icon_list)
+ return;
+
+ if (default_icon_pixmap)
+ g_object_unref (G_OBJECT (default_icon_pixmap));
+ if (default_icon_mask)
+ g_object_unref (G_OBJECT (default_icon_mask));
+
+ default_icon_pixmap = NULL;
+ default_icon_mask = NULL;
+
+ g_list_foreach (default_icon_list,
+ (GFunc) g_object_unref, NULL);
+
+ g_list_free (default_icon_list);
+
+ default_icon_list = g_list_copy (list);
+ g_list_foreach (default_icon_list,
+ (GFunc) g_object_ref, NULL);
+
+ /* Update all toplevels */
+ toplevels = gtk_window_list_toplevels ();
+ tmp_list = toplevels;
+ while (tmp_list != NULL)
+ {
+ GtkWindowIconInfo *info;
+ GtkWindow *w = tmp_list->data;
+
+ info = get_icon_info (w);
+ if (info && info->using_default_icon)
+ {
+ gtk_window_unrealize_icon (w);
+ if (GTK_WIDGET_REALIZED (w))
+ gtk_window_realize_icon (w);
+ }
+
+ tmp_list = tmp_list->next;
+ }
+ g_list_free (toplevels);
+}
+
+/**
+ * gtk_window_get_default_icon_list:
+ *
+ * Gets the value set by gtk_window_set_default_icon_list().
+ * The list is a copy and should be freed with g_list_free(),
+ * but the pixbufs in the list have not had their reference count
+ * incremented.
+ *
+ * Return value: default icon list
+ **/
+GList*
+gtk_window_get_default_icon_list (void)
+{
+ return g_list_copy (default_icon_list);
+}
+
+static void
gtk_window_set_default_size_internal (GtkWindow *window,
gboolean change_width,
gint width,
@@ -2256,10 +2809,13 @@ gtk_window_destroy (GtkObject *object)
g_return_if_fail (GTK_IS_WINDOW (object));
window = GTK_WINDOW (object);
-
+
if (window->transient_parent)
gtk_window_set_transient_for (window, NULL);
+ /* frees the icons */
+ gtk_window_set_icon_list (window, NULL);
+
if (window->has_user_ref_count)
{
window->has_user_ref_count = FALSE;
@@ -2632,6 +3188,9 @@ gtk_window_realize (GtkWidget *widget)
gdk_window_set_modal_hint (widget->window, TRUE);
else
gdk_window_set_modal_hint (widget->window, FALSE);
+
+ /* Icons */
+ gtk_window_realize_icon (window);
}
static void
@@ -2668,6 +3227,9 @@ gtk_window_unrealize (GtkWidget *widget)
gdk_window_destroy (window->frame);
window->frame = NULL;
}
+
+ /* Icons */
+ gtk_window_unrealize_icon (window);
(* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
}
Index: gtk/gtkwindow.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwindow.h,v
retrieving revision 1.47
diff -u -p -u -r1.47 gtkwindow.h
--- gtk/gtkwindow.h 2001/08/23 15:26:48 1.47
+++ gtk/gtkwindow.h 2001/08/28 05:52:24
@@ -206,6 +206,15 @@ void gtk_window_set_decorated
gboolean setting);
gboolean gtk_window_get_decorated (GtkWindow *window);
+void gtk_window_set_icon_list (GtkWindow *window,
+ GList *list);
+GList* gtk_window_get_icon_list (GtkWindow *window);
+void gtk_window_set_icon (GtkWindow *window,
+ GdkPixbuf *icon);
+GdkPixbuf* gtk_window_get_icon (GtkWindow *window);
+void gtk_window_set_default_icon_list (GList *list);
+GList* gtk_window_get_default_icon_list (void);
+
/* If window is set modal, input will be grabbed when show and released when hide */
void gtk_window_set_modal (GtkWindow *window,
gboolean modal);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]