1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * Insensitive pixmap building code by Eckehard Berns from GNOME Stock
5 * Copyright (C) 1997, 1998 Free Software Foundation
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
25 * file for a list of people on the GTK+ Team. See the ChangeLog
26 * files for a list of changes. These files are distributed with
27 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 #include "gtkcontainer.h"
31 #include "gtkpixmap.h"
34 static void gtk_pixmap_class_init (GtkPixmapClass *klass);
35 static void gtk_pixmap_init (GtkPixmap *pixmap);
36 static gint gtk_pixmap_expose (GtkWidget *widget,
37 GdkEventExpose *event);
38 static void gtk_pixmap_finalize (GtkObject *object);
39 static void build_insensitive_pixmap (GtkPixmap *gtkpixmap);
41 static GtkWidgetClass *parent_class;
44 gtk_pixmap_get_type (void)
46 static GtkType pixmap_type = 0;
50 static const GtkTypeInfo pixmap_info =
54 sizeof (GtkPixmapClass),
55 (GtkClassInitFunc) gtk_pixmap_class_init,
56 (GtkObjectInitFunc) gtk_pixmap_init,
57 /* reserved_1 */ NULL,
58 /* reserved_2 */ NULL,
59 (GtkClassInitFunc) NULL,
62 pixmap_type = gtk_type_unique (GTK_TYPE_MISC, &pixmap_info);
69 gtk_pixmap_class_init (GtkPixmapClass *class)
71 GtkObjectClass *object_class;
72 GtkWidgetClass *widget_class;
74 object_class = (GtkObjectClass*) class;
75 widget_class = (GtkWidgetClass*) class;
76 parent_class = gtk_type_class (gtk_widget_get_type ());
78 object_class->finalize = gtk_pixmap_finalize;
79 widget_class->expose_event = gtk_pixmap_expose;
83 gtk_pixmap_init (GtkPixmap *pixmap)
85 GTK_WIDGET_SET_FLAGS (pixmap, GTK_NO_WINDOW);
87 pixmap->pixmap = NULL;
92 gtk_pixmap_new (GdkPixmap *val,
97 g_return_val_if_fail (val != NULL, NULL);
99 pixmap = gtk_type_new (gtk_pixmap_get_type ());
101 pixmap->build_insensitive = TRUE;
102 gtk_pixmap_set (pixmap, val, mask);
104 return GTK_WIDGET (pixmap);
108 gtk_pixmap_finalize (GtkObject *object)
110 gtk_pixmap_set (GTK_PIXMAP (object), NULL, NULL);
111 (* GTK_OBJECT_CLASS (parent_class)->finalize) (object);
115 gtk_pixmap_set (GtkPixmap *pixmap,
124 g_return_if_fail (pixmap != NULL);
125 g_return_if_fail (GTK_IS_PIXMAP (pixmap));
127 if (pixmap->pixmap != val)
129 oldwidth = GTK_WIDGET (pixmap)->requisition.width;
130 oldheight = GTK_WIDGET (pixmap)->requisition.height;
132 gdk_pixmap_unref (pixmap->pixmap);
133 if (pixmap->pixmap_insensitive)
134 gdk_pixmap_unref (pixmap->pixmap_insensitive);
135 pixmap->pixmap = val;
136 pixmap->pixmap_insensitive = NULL;
139 gdk_pixmap_ref (pixmap->pixmap);
140 gdk_window_get_size (pixmap->pixmap, &width, &height);
141 GTK_WIDGET (pixmap)->requisition.width =
142 width + GTK_MISC (pixmap)->xpad * 2;
143 GTK_WIDGET (pixmap)->requisition.height =
144 height + GTK_MISC (pixmap)->ypad * 2;
148 GTK_WIDGET (pixmap)->requisition.width = 0;
149 GTK_WIDGET (pixmap)->requisition.height = 0;
151 if (GTK_WIDGET_VISIBLE (pixmap))
153 if ((GTK_WIDGET (pixmap)->requisition.width != oldwidth) ||
154 (GTK_WIDGET (pixmap)->requisition.height != oldheight))
155 gtk_widget_queue_resize (GTK_WIDGET (pixmap));
157 gtk_widget_queue_clear (GTK_WIDGET (pixmap));
161 if (pixmap->mask != mask)
164 gdk_bitmap_unref (pixmap->mask);
167 gdk_bitmap_ref (pixmap->mask);
172 gtk_pixmap_get (GtkPixmap *pixmap,
176 g_return_if_fail (pixmap != NULL);
177 g_return_if_fail (GTK_IS_PIXMAP (pixmap));
180 *val = pixmap->pixmap;
182 *mask = pixmap->mask;
186 gtk_pixmap_expose (GtkWidget *widget,
187 GdkEventExpose *event)
193 g_return_val_if_fail (widget != NULL, FALSE);
194 g_return_val_if_fail (GTK_IS_PIXMAP (widget), FALSE);
195 g_return_val_if_fail (event != NULL, FALSE);
197 if (GTK_WIDGET_DRAWABLE (widget))
199 pixmap = GTK_PIXMAP (widget);
200 misc = GTK_MISC (widget);
202 x = (widget->allocation.x * (1.0 - misc->xalign) +
203 (widget->allocation.x + widget->allocation.width
204 - (widget->requisition.width - misc->xpad * 2)) *
206 y = (widget->allocation.y * (1.0 - misc->yalign) +
207 (widget->allocation.y + widget->allocation.height
208 - (widget->requisition.height - misc->ypad * 2)) *
213 gdk_gc_set_clip_mask (widget->style->black_gc, pixmap->mask);
214 gdk_gc_set_clip_origin (widget->style->black_gc, x, y);
217 if (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE
218 && pixmap->build_insensitive)
220 if (!pixmap->pixmap_insensitive)
221 build_insensitive_pixmap (pixmap);
222 gdk_draw_pixmap (widget->window,
223 widget->style->black_gc,
224 pixmap->pixmap_insensitive,
229 gdk_draw_pixmap (widget->window,
230 widget->style->black_gc,
237 gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
238 gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
245 gtk_pixmap_set_build_insensitive (GtkPixmap *pixmap, guint build)
247 g_return_if_fail (pixmap != NULL);
248 g_return_if_fail (GTK_IS_PIXMAP (pixmap));
250 pixmap->build_insensitive = build;
252 if (GTK_WIDGET_VISIBLE (pixmap))
254 gtk_widget_queue_clear (GTK_WIDGET (pixmap));
259 build_insensitive_pixmap(GtkPixmap *gtkpixmap)
262 GdkPixmap *pixmap = gtkpixmap->pixmap;
263 GdkPixmap *insensitive;
271 gint32 red, green, blue;
277 window = GTK_WIDGET (gtkpixmap);
279 g_return_if_fail(window != NULL);
281 gdk_window_get_size(pixmap, &w, &h);
282 image = gdk_image_get(pixmap, 0, 0, w, h);
283 insensitive = gdk_pixmap_new(GTK_WIDGET (gtkpixmap)->window, w, h, -1);
284 gc = gdk_gc_new (pixmap);
286 visual = gtk_widget_get_visual(GTK_WIDGET(gtkpixmap));
287 cmap = gtk_widget_get_colormap(GTK_WIDGET(gtkpixmap));
288 cc = gdk_color_context_new(visual, cmap);
290 if ((cc->mode != GDK_CC_MODE_TRUE) && (cc->mode != GDK_CC_MODE_MY_GRAY))
292 gdk_draw_image(insensitive, gc, image, 0, 0, 0, 0, w, h);
294 style = gtk_widget_get_style(window);
295 color = style->bg[0];
296 gdk_gc_set_foreground (gc, &color);
297 for (y = 0; y < h; y++)
299 for (x = y % 2; x < w; x += 2)
301 gdk_draw_point(insensitive, gc, x, y);
307 gdk_gc_get_values(gc, &vals);
308 style = gtk_widget_get_style(window);
310 color = style->bg[0];
315 for (y = 0; y < h; y++)
317 for (x = 0; x < w; x++)
319 c.pixel = gdk_image_get_pixel(image, x, y);
320 gdk_color_context_query_color(cc, &c);
321 c.red = (((gint32)c.red - red) >> 1) + red;
322 c.green = (((gint32)c.green - green) >> 1) + green;
323 c.blue = (((gint32)c.blue - blue) >> 1) + blue;
324 c.pixel = gdk_color_context_get_pixel(cc, c.red, c.green, c.blue,
326 gdk_image_put_pixel(image, x, y, c.pixel);
330 for (y = 0; y < h; y++)
332 for (x = y % 2; x < w; x += 2)
334 c.pixel = gdk_image_get_pixel(image, x, y);
335 gdk_color_context_query_color(cc, &c);
336 c.red = (((gint32)c.red - red) >> 1) + red;
337 c.green = (((gint32)c.green - green) >> 1) + green;
338 c.blue = (((gint32)c.blue - blue) >> 1) + blue;
339 c.pixel = gdk_color_context_get_pixel(cc, c.red, c.green, c.blue,
341 gdk_image_put_pixel(image, x, y, c.pixel);
345 gdk_draw_image(insensitive, gc, image, 0, 0, 0, 0, w, h);
348 gtkpixmap->pixmap_insensitive = insensitive;
350 gdk_image_destroy(image);
351 gdk_color_context_free(cc);