source: trunk/third/gtk/gtk/gtkpixmap.c @ 14482

Revision 14482, 9.2 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r14481, which included commits to RCS files with non-trunk default branches.
Line 
1/* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * Insensitive pixmap building code by Eckehard Berns from GNOME Stock
5 * Copyright (C) 1997, 1998 Free Software Foundation
6 *
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.
11 *
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.
16 *
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.
21 */
22
23/*
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/.
28 */
29
30#include "gtkcontainer.h"
31#include "gtkpixmap.h"
32
33
34static void gtk_pixmap_class_init (GtkPixmapClass  *klass);
35static void gtk_pixmap_init       (GtkPixmap       *pixmap);
36static gint gtk_pixmap_expose     (GtkWidget       *widget,
37                                   GdkEventExpose  *event);
38static void gtk_pixmap_finalize   (GtkObject       *object);
39static void build_insensitive_pixmap (GtkPixmap *gtkpixmap);
40
41static GtkWidgetClass *parent_class;
42
43GtkType
44gtk_pixmap_get_type (void)
45{
46  static GtkType pixmap_type = 0;
47
48  if (!pixmap_type)
49    {
50      static const GtkTypeInfo pixmap_info =
51      {
52        "GtkPixmap",
53        sizeof (GtkPixmap),
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,
60      };
61
62      pixmap_type = gtk_type_unique (GTK_TYPE_MISC, &pixmap_info);
63    }
64
65  return pixmap_type;
66}
67
68static void
69gtk_pixmap_class_init (GtkPixmapClass *class)
70{
71  GtkObjectClass *object_class;
72  GtkWidgetClass *widget_class;
73
74  object_class = (GtkObjectClass*) class;
75  widget_class = (GtkWidgetClass*) class;
76  parent_class = gtk_type_class (gtk_widget_get_type ());
77
78  object_class->finalize = gtk_pixmap_finalize;
79  widget_class->expose_event = gtk_pixmap_expose;
80}
81
82static void
83gtk_pixmap_init (GtkPixmap *pixmap)
84{
85  GTK_WIDGET_SET_FLAGS (pixmap, GTK_NO_WINDOW);
86
87  pixmap->pixmap = NULL;
88  pixmap->mask = NULL;
89}
90
91GtkWidget*
92gtk_pixmap_new (GdkPixmap *val,
93                GdkBitmap *mask)
94{
95  GtkPixmap *pixmap;
96   
97  g_return_val_if_fail (val != NULL, NULL);
98 
99  pixmap = gtk_type_new (gtk_pixmap_get_type ());
100 
101  pixmap->build_insensitive = TRUE;
102  gtk_pixmap_set (pixmap, val, mask);
103 
104  return GTK_WIDGET (pixmap);
105}
106
107static void
108gtk_pixmap_finalize (GtkObject *object)
109{
110  gtk_pixmap_set (GTK_PIXMAP (object), NULL, NULL);
111  (* GTK_OBJECT_CLASS (parent_class)->finalize) (object);
112}
113
114void
115gtk_pixmap_set (GtkPixmap *pixmap,
116                GdkPixmap *val,
117                GdkBitmap *mask)
118{
119  gint width;
120  gint height;
121  gint oldwidth;
122  gint oldheight;
123
124  g_return_if_fail (pixmap != NULL);
125  g_return_if_fail (GTK_IS_PIXMAP (pixmap));
126
127  if (pixmap->pixmap != val)
128    {
129      oldwidth = GTK_WIDGET (pixmap)->requisition.width;
130      oldheight = GTK_WIDGET (pixmap)->requisition.height;
131      if (pixmap->pixmap)
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;
137      if (pixmap->pixmap)
138        {
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;
145        }
146      else
147        {
148          GTK_WIDGET (pixmap)->requisition.width = 0;
149          GTK_WIDGET (pixmap)->requisition.height = 0;
150        }
151      if (GTK_WIDGET_VISIBLE (pixmap))
152        {
153          if ((GTK_WIDGET (pixmap)->requisition.width != oldwidth) ||
154              (GTK_WIDGET (pixmap)->requisition.height != oldheight))
155            gtk_widget_queue_resize (GTK_WIDGET (pixmap));
156          else
157            gtk_widget_queue_clear (GTK_WIDGET (pixmap));
158        }
159    }
160
161  if (pixmap->mask != mask)
162    {
163      if (pixmap->mask)
164        gdk_bitmap_unref (pixmap->mask);
165      pixmap->mask = mask;
166      if (pixmap->mask)
167        gdk_bitmap_ref (pixmap->mask);
168    }
169}
170
171void
172gtk_pixmap_get (GtkPixmap  *pixmap,
173                GdkPixmap **val,
174                GdkBitmap **mask)
175{
176  g_return_if_fail (pixmap != NULL);
177  g_return_if_fail (GTK_IS_PIXMAP (pixmap));
178
179  if (val)
180    *val = pixmap->pixmap;
181  if (mask)
182    *mask = pixmap->mask;
183}
184
185static gint
186gtk_pixmap_expose (GtkWidget      *widget,
187                   GdkEventExpose *event)
188{
189  GtkPixmap *pixmap;
190  GtkMisc *misc;
191  gint x, y;
192
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);
196
197  if (GTK_WIDGET_DRAWABLE (widget))
198    {
199      pixmap = GTK_PIXMAP (widget);
200      misc = GTK_MISC (widget);
201
202      x = (widget->allocation.x * (1.0 - misc->xalign) +
203           (widget->allocation.x + widget->allocation.width
204            - (widget->requisition.width - misc->xpad * 2)) *
205           misc->xalign) + 0.5;
206      y = (widget->allocation.y * (1.0 - misc->yalign) +
207           (widget->allocation.y + widget->allocation.height
208            - (widget->requisition.height - misc->ypad * 2)) *
209           misc->yalign) + 0.5;
210
211      if (pixmap->mask)
212        {
213          gdk_gc_set_clip_mask (widget->style->black_gc, pixmap->mask);
214          gdk_gc_set_clip_origin (widget->style->black_gc, x, y);
215        }
216
217      if (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE
218          && pixmap->build_insensitive)
219        {
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,
225                           0, 0, x, y, -1, -1);
226        }
227      else
228        {
229          gdk_draw_pixmap (widget->window,
230                           widget->style->black_gc,
231                           pixmap->pixmap,
232                           0, 0, x, y, -1, -1);
233        }
234
235      if (pixmap->mask)
236        {
237          gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
238          gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
239        }
240    }
241  return FALSE;
242}
243
244void
245gtk_pixmap_set_build_insensitive (GtkPixmap *pixmap, guint build)
246{
247  g_return_if_fail (pixmap != NULL);
248  g_return_if_fail (GTK_IS_PIXMAP (pixmap));
249
250  pixmap->build_insensitive = build;
251
252  if (GTK_WIDGET_VISIBLE (pixmap))
253    {
254      gtk_widget_queue_clear (GTK_WIDGET (pixmap));
255    }
256}
257
258static void
259build_insensitive_pixmap(GtkPixmap *gtkpixmap)
260{
261  GdkGC *gc;
262  GdkPixmap *pixmap = gtkpixmap->pixmap;
263  GdkPixmap *insensitive;
264  gint w, h, x, y;
265  GdkGCValues vals;
266  GdkVisual *visual;
267  GdkImage *image;
268  GdkColorContext *cc;
269  GdkColor color;
270  GdkColormap *cmap;
271  gint32 red, green, blue;
272  GtkStyle *style;
273  GtkWidget *window;
274  GdkColor c;
275  int failed;
276
277  window = GTK_WIDGET (gtkpixmap);
278
279  g_return_if_fail(window != NULL);
280
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);
285
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);
289
290  if ((cc->mode != GDK_CC_MODE_TRUE) && (cc->mode != GDK_CC_MODE_MY_GRAY))
291    {
292      gdk_draw_image(insensitive, gc, image, 0, 0, 0, 0, w, h);
293
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++)
298        {
299          for (x = y % 2; x < w; x += 2)
300            {
301              gdk_draw_point(insensitive, gc, x, y);
302            }
303        }
304    }
305  else
306    {
307      gdk_gc_get_values(gc, &vals);
308      style = gtk_widget_get_style(window);
309
310      color = style->bg[0];
311      red = color.red;
312      green = color.green;
313      blue = color.blue;
314
315      for (y = 0; y < h; y++)
316        {
317          for (x = 0; x < w; x++)
318            {
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,
325                                                    &failed);
326              gdk_image_put_pixel(image, x, y, c.pixel);
327            }
328        }
329
330      for (y = 0; y < h; y++)
331        {
332          for (x = y % 2; x < w; x += 2)
333            {
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,
340                                                    &failed);
341              gdk_image_put_pixel(image, x, y, c.pixel);
342            }
343        }
344
345      gdk_draw_image(insensitive, gc, image, 0, 0, 0, 0, w, h);
346    }
347
348  gtkpixmap->pixmap_insensitive = insensitive;
349
350  gdk_image_destroy(image);
351  gdk_color_context_free(cc);
352  gdk_gc_destroy(gc);
353}
354
355
Note: See TracBrowser for help on using the repository browser.