]> Pileus Git - ~andy/gtk/blob - gtk/gtkpixmap.c
Add hidden aliases for exported symbols which are used internally in order
[~andy/gtk] / gtk / gtkpixmap.c
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 Lesser 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  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser 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-2000.  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 #undef GDK_DISABLE_DEPRECATED
31 #undef GTK_DISABLE_DEPRECATED
32
33 #include <config.h>
34 #include <math.h>
35 #include "gtkalias.h"
36 #include "gtkcontainer.h"
37 #include "gtkpixmap.h"
38
39
40 static void gtk_pixmap_class_init (GtkPixmapClass  *klass);
41 static void gtk_pixmap_init       (GtkPixmap       *pixmap);
42 static gint gtk_pixmap_expose     (GtkWidget       *widget,
43                                    GdkEventExpose  *event);
44 static void gtk_pixmap_finalize   (GObject         *object);
45 static void build_insensitive_pixmap (GtkPixmap *gtkpixmap);
46
47 static GtkWidgetClass *parent_class;
48
49 GtkType
50 gtk_pixmap_get_type (void)
51 {
52   static GtkType pixmap_type = 0;
53
54   if (!pixmap_type)
55     {
56       static const GtkTypeInfo pixmap_info =
57       {
58         "GtkPixmap",
59         sizeof (GtkPixmap),
60         sizeof (GtkPixmapClass),
61         (GtkClassInitFunc) gtk_pixmap_class_init,
62         (GtkObjectInitFunc) gtk_pixmap_init,
63         /* reserved_1 */ NULL,
64         /* reserved_2 */ NULL,
65         (GtkClassInitFunc) NULL,
66       };
67
68       pixmap_type = gtk_type_unique (GTK_TYPE_MISC, &pixmap_info);
69     }
70
71   return pixmap_type;
72 }
73
74 static void
75 gtk_pixmap_class_init (GtkPixmapClass *class)
76 {
77   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
78   GtkObjectClass *object_class;
79   GtkWidgetClass *widget_class;
80
81   object_class = (GtkObjectClass*) class;
82   widget_class = (GtkWidgetClass*) class;
83   parent_class = gtk_type_class (gtk_misc_get_type ());
84
85   gobject_class->finalize = gtk_pixmap_finalize;
86
87   widget_class->expose_event = gtk_pixmap_expose;
88 }
89
90 static void
91 gtk_pixmap_init (GtkPixmap *pixmap)
92 {
93   GTK_WIDGET_SET_FLAGS (pixmap, GTK_NO_WINDOW);
94
95   pixmap->pixmap = NULL;
96   pixmap->mask = NULL;
97 }
98
99 GtkWidget*
100 gtk_pixmap_new (GdkPixmap *val,
101                 GdkBitmap *mask)
102 {
103   GtkPixmap *pixmap;
104    
105   g_return_val_if_fail (val != NULL, NULL);
106   
107   pixmap = gtk_type_new (gtk_pixmap_get_type ());
108   
109   pixmap->build_insensitive = TRUE;
110   gtk_pixmap_set (pixmap, val, mask);
111   
112   return GTK_WIDGET (pixmap);
113 }
114
115 static void
116 gtk_pixmap_finalize (GObject *object)
117 {
118   gtk_pixmap_set (GTK_PIXMAP (object), NULL, NULL);
119
120   G_OBJECT_CLASS (parent_class)->finalize (object);
121 }
122
123 void
124 gtk_pixmap_set (GtkPixmap *pixmap,
125                 GdkPixmap *val,
126                 GdkBitmap *mask)
127 {
128   gint width;
129   gint height;
130   gint oldwidth;
131   gint oldheight;
132
133   g_return_if_fail (GTK_IS_PIXMAP (pixmap));
134
135   if (pixmap->pixmap != val)
136     {
137       oldwidth = GTK_WIDGET (pixmap)->requisition.width;
138       oldheight = GTK_WIDGET (pixmap)->requisition.height;
139       if (pixmap->pixmap)
140         gdk_pixmap_unref (pixmap->pixmap);
141       if (pixmap->pixmap_insensitive)
142         gdk_pixmap_unref (pixmap->pixmap_insensitive);
143       pixmap->pixmap = val;
144       pixmap->pixmap_insensitive = NULL;
145       if (pixmap->pixmap)
146         {
147           gdk_pixmap_ref (pixmap->pixmap);
148           gdk_window_get_size (pixmap->pixmap, &width, &height);
149           GTK_WIDGET (pixmap)->requisition.width =
150             width + GTK_MISC (pixmap)->xpad * 2;
151           GTK_WIDGET (pixmap)->requisition.height =
152             height + GTK_MISC (pixmap)->ypad * 2;
153         }
154       else
155         {
156           GTK_WIDGET (pixmap)->requisition.width = 0;
157           GTK_WIDGET (pixmap)->requisition.height = 0;
158         }
159       if (GTK_WIDGET_VISIBLE (pixmap))
160         {
161           if ((GTK_WIDGET (pixmap)->requisition.width != oldwidth) ||
162               (GTK_WIDGET (pixmap)->requisition.height != oldheight))
163             gtk_widget_queue_resize (GTK_WIDGET (pixmap));
164           else
165             gtk_widget_queue_clear (GTK_WIDGET (pixmap));
166         }
167     }
168
169   if (pixmap->mask != mask)
170     {
171       if (pixmap->mask)
172         gdk_bitmap_unref (pixmap->mask);
173       pixmap->mask = mask;
174       if (pixmap->mask)
175         gdk_bitmap_ref (pixmap->mask);
176     }
177 }
178
179 void
180 gtk_pixmap_get (GtkPixmap  *pixmap,
181                 GdkPixmap **val,
182                 GdkBitmap **mask)
183 {
184   g_return_if_fail (GTK_IS_PIXMAP (pixmap));
185
186   if (val)
187     *val = pixmap->pixmap;
188   if (mask)
189     *mask = pixmap->mask;
190 }
191
192 static gint
193 gtk_pixmap_expose (GtkWidget      *widget,
194                    GdkEventExpose *event)
195 {
196   GtkPixmap *pixmap;
197   GtkMisc *misc;
198   gint x, y;
199   gfloat xalign;
200
201   g_return_val_if_fail (GTK_IS_PIXMAP (widget), FALSE);
202   g_return_val_if_fail (event != NULL, FALSE);
203
204   if (GTK_WIDGET_DRAWABLE (widget))
205     {
206       pixmap = GTK_PIXMAP (widget);
207       misc = GTK_MISC (widget);
208
209       if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
210         xalign = misc->xalign;
211       else
212         xalign = 1.0 - misc->xalign;
213   
214       x = floor (widget->allocation.x + misc->xpad
215                  + ((widget->allocation.width - widget->requisition.width) * xalign)
216                  + 0.5);
217       y = floor (widget->allocation.y + misc->ypad 
218                  + ((widget->allocation.height - widget->requisition.height) * misc->yalign)
219                  + 0.5);
220       
221       if (pixmap->mask)
222         {
223           gdk_gc_set_clip_mask (widget->style->black_gc, pixmap->mask);
224           gdk_gc_set_clip_origin (widget->style->black_gc, x, y);
225         }
226
227       if (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE
228           && pixmap->build_insensitive)
229         {
230           if (!pixmap->pixmap_insensitive)
231             build_insensitive_pixmap (pixmap);
232           gdk_draw_pixmap (widget->window,
233                            widget->style->black_gc,
234                            pixmap->pixmap_insensitive,
235                            0, 0, x, y, -1, -1);
236         }
237       else
238         {
239           gdk_draw_pixmap (widget->window,
240                            widget->style->black_gc,
241                            pixmap->pixmap,
242                            0, 0, x, y, -1, -1);
243         }
244
245       if (pixmap->mask)
246         {
247           gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
248           gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
249         }
250     }
251   return FALSE;
252 }
253
254 void
255 gtk_pixmap_set_build_insensitive (GtkPixmap *pixmap, gboolean build)
256 {
257   g_return_if_fail (GTK_IS_PIXMAP (pixmap));
258
259   pixmap->build_insensitive = build;
260
261   if (GTK_WIDGET_VISIBLE (pixmap))
262     {
263       gtk_widget_queue_clear (GTK_WIDGET (pixmap));
264     }
265 }
266
267 static void
268 build_insensitive_pixmap (GtkPixmap *gtkpixmap)
269 {
270   GdkPixmap *pixmap = gtkpixmap->pixmap;
271   GdkPixmap *insensitive;
272   gint w, h;
273   GdkPixbuf *pixbuf;
274   GdkPixbuf *stated;
275   
276   gdk_window_get_size (pixmap, &w, &h);
277
278   pixbuf = gdk_pixbuf_get_from_drawable (NULL,
279                                          pixmap,
280                                          gtk_widget_get_colormap (GTK_WIDGET(gtkpixmap)),
281                                          0, 0,
282                                          0, 0,
283                                          w, h);
284   
285   stated = gdk_pixbuf_copy (pixbuf);
286   
287   gdk_pixbuf_saturate_and_pixelate (pixbuf, stated,
288                                     0.8, TRUE);
289
290   g_object_unref (G_OBJECT (pixbuf));
291   pixbuf = NULL;
292   
293   insensitive = gdk_pixmap_new (GTK_WIDGET (gtkpixmap)->window, w, h, -1);
294
295   gdk_draw_pixbuf (insensitive,
296                    GTK_WIDGET (gtkpixmap)->style->white_gc,
297                    stated,
298                    0, 0,
299                    0, 0,
300                    w, h,
301                    GDK_RGB_DITHER_NORMAL,
302                    0, 0);
303
304   gtkpixmap->pixmap_insensitive = insensitive;
305
306   g_object_unref (G_OBJECT (stated));
307 }
308
309