]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkpixmap.c
Bug 535862 – gtk_action_create_icon can't create icons from the icon
[~andy/gtk] / gtk / gtkpixmap.c
index 06e9aa73122cedb9c65eb601d589b6d87ec53a25..bee47809d2e3cbb458e52447a10d1b9622c6085a 100644 (file)
@@ -1,68 +1,60 @@
 /* GTK - The GIMP Toolkit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
  *
+ * Insensitive pixmap building code by Eckehard Berns from GNOME Stock
+ * Copyright (C) 1997, 1998 Free Software Foundation
+ *
  * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
+ * 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
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU Library General Public
+ * 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/. 
+ */
+
+#undef GDK_DISABLE_DEPRECATED
+#undef GTK_DISABLE_DEPRECATED
+
+#include <config.h>
+#include <math.h>
 #include "gtkcontainer.h"
 #include "gtkpixmap.h"
+#include "gtkintl.h"
+#include "gtkalias.h"
 
 
-static void gtk_pixmap_class_init (GtkPixmapClass  *klass);
-static void gtk_pixmap_init       (GtkPixmap       *pixmap);
 static gint gtk_pixmap_expose     (GtkWidget       *widget,
                                   GdkEventExpose  *event);
-static void gtk_pixmap_finalize   (GtkObject       *object);
-
-static GtkWidgetClass *parent_class;
-
-guint
-gtk_pixmap_get_type (void)
-{
-  static guint pixmap_type = 0;
-
-  if (!pixmap_type)
-    {
-      GtkTypeInfo pixmap_info =
-      {
-       "GtkPixmap",
-       sizeof (GtkPixmap),
-       sizeof (GtkPixmapClass),
-       (GtkClassInitFunc) gtk_pixmap_class_init,
-       (GtkObjectInitFunc) gtk_pixmap_init,
-       (GtkArgSetFunc) NULL,
-        (GtkArgGetFunc) NULL,
-      };
-
-      pixmap_type = gtk_type_unique (gtk_misc_get_type (), &pixmap_info);
-    }
+static void gtk_pixmap_finalize   (GObject         *object);
+static void build_insensitive_pixmap (GtkPixmap *gtkpixmap);
 
-  return pixmap_type;
-}
+G_DEFINE_TYPE (GtkPixmap, gtk_pixmap, GTK_TYPE_MISC)
 
 static void
 gtk_pixmap_class_init (GtkPixmapClass *class)
 {
-  GtkObjectClass *object_class;
+  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
   GtkWidgetClass *widget_class;
 
-  object_class = (GtkObjectClass*) class;
   widget_class = (GtkWidgetClass*) class;
-  parent_class = gtk_type_class (gtk_widget_get_type ());
 
-  object_class->finalize = gtk_pixmap_finalize;
+  gobject_class->finalize = gtk_pixmap_finalize;
+
   widget_class->expose_event = gtk_pixmap_expose;
 }
 
@@ -80,21 +72,23 @@ gtk_pixmap_new (GdkPixmap *val,
                GdkBitmap *mask)
 {
   GtkPixmap *pixmap;
-
+   
   g_return_val_if_fail (val != NULL, NULL);
-
+  
   pixmap = gtk_type_new (gtk_pixmap_get_type ());
-
+  
+  pixmap->build_insensitive = TRUE;
   gtk_pixmap_set (pixmap, val, mask);
-
+  
   return GTK_WIDGET (pixmap);
 }
 
 static void
-gtk_pixmap_finalize (GtkObject *object)
+gtk_pixmap_finalize (GObject *object)
 {
   gtk_pixmap_set (GTK_PIXMAP (object), NULL, NULL);
-  (* GTK_OBJECT_CLASS (parent_class)->finalize) (object);
+
+  G_OBJECT_CLASS (gtk_pixmap_parent_class)->finalize (object);
 }
 
 void
@@ -107,8 +101,9 @@ gtk_pixmap_set (GtkPixmap *pixmap,
   gint oldwidth;
   gint oldheight;
 
-  g_return_if_fail (pixmap != NULL);
   g_return_if_fail (GTK_IS_PIXMAP (pixmap));
+  if(GDK_IS_DRAWABLE(val))
+    g_return_if_fail (gdk_colormap_get_visual (gtk_widget_get_colormap (GTK_WIDGET (pixmap)))->depth == gdk_drawable_get_depth (GDK_DRAWABLE (val)));
 
   if (pixmap->pixmap != val)
     {
@@ -116,7 +111,10 @@ gtk_pixmap_set (GtkPixmap *pixmap,
       oldheight = GTK_WIDGET (pixmap)->requisition.height;
       if (pixmap->pixmap)
        gdk_pixmap_unref (pixmap->pixmap);
+      if (pixmap->pixmap_insensitive)
+       gdk_pixmap_unref (pixmap->pixmap_insensitive);
       pixmap->pixmap = val;
+      pixmap->pixmap_insensitive = NULL;
       if (pixmap->pixmap)
        {
          gdk_pixmap_ref (pixmap->pixmap);
@@ -137,7 +135,7 @@ gtk_pixmap_set (GtkPixmap *pixmap,
              (GTK_WIDGET (pixmap)->requisition.height != oldheight))
            gtk_widget_queue_resize (GTK_WIDGET (pixmap));
          else
-           gtk_widget_queue_draw (GTK_WIDGET (pixmap));
+           gtk_widget_queue_clear (GTK_WIDGET (pixmap));
        }
     }
 
@@ -156,7 +154,6 @@ gtk_pixmap_get (GtkPixmap  *pixmap,
                GdkPixmap **val,
                GdkBitmap **mask)
 {
-  g_return_if_fail (pixmap != NULL);
   g_return_if_fail (GTK_IS_PIXMAP (pixmap));
 
   if (val)
@@ -165,7 +162,6 @@ gtk_pixmap_get (GtkPixmap  *pixmap,
     *mask = pixmap->mask;
 }
 
-
 static gint
 gtk_pixmap_expose (GtkWidget      *widget,
                   GdkEventExpose *event)
@@ -173,8 +169,8 @@ gtk_pixmap_expose (GtkWidget      *widget,
   GtkPixmap *pixmap;
   GtkMisc *misc;
   gint x, y;
+  gfloat xalign;
 
-  g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_PIXMAP (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
 
@@ -183,25 +179,39 @@ gtk_pixmap_expose (GtkWidget      *widget,
       pixmap = GTK_PIXMAP (widget);
       misc = GTK_MISC (widget);
 
-      x = (widget->allocation.x * (1.0 - misc->xalign) +
-          (widget->allocation.x + widget->allocation.width
-           - (widget->requisition.width - misc->xpad * 2)) *
-          misc->xalign) + 0.5;
-      y = (widget->allocation.y * (1.0 - misc->yalign) +
-          (widget->allocation.y + widget->allocation.height
-           - (widget->requisition.height - misc->ypad * 2)) *
-          misc->yalign) + 0.5;
-
+      if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
+       xalign = misc->xalign;
+      else
+       xalign = 1.0 - misc->xalign;
+  
+      x = floor (widget->allocation.x + misc->xpad
+                + ((widget->allocation.width - widget->requisition.width) * xalign));
+      y = floor (widget->allocation.y + misc->ypad 
+                + ((widget->allocation.height - widget->requisition.height) * misc->yalign));
+      
       if (pixmap->mask)
        {
          gdk_gc_set_clip_mask (widget->style->black_gc, pixmap->mask);
          gdk_gc_set_clip_origin (widget->style->black_gc, x, y);
        }
 
-      gdk_draw_pixmap (widget->window,
-                      widget->style->black_gc,
-                      pixmap->pixmap,
-                      0, 0, x, y, -1, -1);
+      if (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE
+          && pixmap->build_insensitive)
+        {
+         if (!pixmap->pixmap_insensitive)
+           build_insensitive_pixmap (pixmap);
+          gdk_draw_pixmap (widget->window,
+                          widget->style->black_gc,
+                          pixmap->pixmap_insensitive,
+                          0, 0, x, y, -1, -1);
+        }
+      else
+       {
+          gdk_draw_pixmap (widget->window,
+                          widget->style->black_gc,
+                          pixmap->pixmap,
+                          0, 0, x, y, -1, -1);
+       }
 
       if (pixmap->mask)
        {
@@ -209,6 +219,63 @@ gtk_pixmap_expose (GtkWidget      *widget,
          gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
        }
     }
-
   return FALSE;
 }
+
+void
+gtk_pixmap_set_build_insensitive (GtkPixmap *pixmap, gboolean build)
+{
+  g_return_if_fail (GTK_IS_PIXMAP (pixmap));
+
+  pixmap->build_insensitive = build;
+
+  if (GTK_WIDGET_VISIBLE (pixmap))
+    {
+      gtk_widget_queue_clear (GTK_WIDGET (pixmap));
+    }
+}
+
+static void
+build_insensitive_pixmap (GtkPixmap *gtkpixmap)
+{
+  GdkPixmap *pixmap = gtkpixmap->pixmap;
+  GdkPixmap *insensitive;
+  gint w, h;
+  GdkPixbuf *pixbuf;
+  GdkPixbuf *stated;
+  
+  gdk_window_get_size (pixmap, &w, &h);
+
+  pixbuf = gdk_pixbuf_get_from_drawable (NULL,
+                                         pixmap,
+                                         gtk_widget_get_colormap (GTK_WIDGET (gtkpixmap)),
+                                         0, 0,
+                                         0, 0,
+                                         w, h);
+  
+  stated = gdk_pixbuf_copy (pixbuf);
+  
+  gdk_pixbuf_saturate_and_pixelate (pixbuf, stated,
+                                    0.8, TRUE);
+
+  g_object_unref (G_OBJECT (pixbuf));
+  pixbuf = NULL;
+  
+  insensitive = gdk_pixmap_new (GTK_WIDGET (gtkpixmap)->window, w, h, -1);
+
+  gdk_draw_pixbuf (insensitive,
+                  GTK_WIDGET (gtkpixmap)->style->white_gc,
+                  stated,
+                  0, 0,
+                  0, 0,
+                  w, h,
+                  GDK_RGB_DITHER_NORMAL,
+                  0, 0);
+
+  gtkpixmap->pixmap_insensitive = insensitive;
+
+  g_object_unref (G_OBJECT (stated));
+}
+
+#define __GTK_PIXMAP_C__
+#include "gtkaliasdef.c"