]> Pileus Git - ~andy/gtk/blob - gtk/gtkmisc.c
configure.in acheader.h gdk/gdkwindow.c Check for Shape extension both on
[~andy/gtk] / gtk / gtkmisc.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 #include "gtkcontainer.h"
20 #include "gtkmisc.h"
21
22
23 enum {
24   ARG_0,
25   ARG_XALIGN,
26   ARG_YALIGN,
27   ARG_XPAD,
28   ARG_YPAD
29 };
30
31 static void gtk_misc_class_init (GtkMiscClass *klass);
32 static void gtk_misc_init       (GtkMisc      *misc);
33 static void gtk_misc_realize    (GtkWidget    *widget);
34 static void gtk_misc_set_arg    (GtkMisc      *misc,
35                                  GtkArg       *arg,
36                                  guint         arg_id);
37 static void gtk_misc_get_arg    (GtkMisc      *misc,
38                                  GtkArg       *arg,
39                                  guint         arg_id);
40
41
42 guint
43 gtk_misc_get_type (void)
44 {
45   static guint misc_type = 0;
46
47   if (!misc_type)
48     {
49       GtkTypeInfo misc_info =
50       {
51         "GtkMisc",
52         sizeof (GtkMisc),
53         sizeof (GtkMiscClass),
54         (GtkClassInitFunc) gtk_misc_class_init,
55         (GtkObjectInitFunc) gtk_misc_init,
56         (GtkArgSetFunc) gtk_misc_set_arg,
57         (GtkArgGetFunc) gtk_misc_get_arg,
58       };
59
60       misc_type = gtk_type_unique (gtk_widget_get_type (), &misc_info);
61     }
62
63   return misc_type;
64 }
65
66 static void
67 gtk_misc_class_init (GtkMiscClass *class)
68 {
69   GtkWidgetClass *widget_class;
70
71   widget_class = (GtkWidgetClass*) class;
72
73   gtk_object_add_arg_type ("GtkMisc::xalign", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_XALIGN);
74   gtk_object_add_arg_type ("GtkMisc::yalign", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_YALIGN);
75   gtk_object_add_arg_type ("GtkMisc::xpad", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_XPAD);
76   gtk_object_add_arg_type ("GtkMisc::ypad", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_YPAD);
77   
78   widget_class->realize = gtk_misc_realize;
79 }
80
81 static void
82 gtk_misc_init (GtkMisc *misc)
83 {
84   GTK_WIDGET_SET_FLAGS (misc, GTK_BASIC);
85
86   misc->xalign = 0.5;
87   misc->yalign = 0.5;
88   misc->xpad = 0;
89   misc->ypad = 0;
90 }
91
92 static void
93 gtk_misc_set_arg (GtkMisc        *misc,
94                   GtkArg         *arg,
95                   guint           arg_id)
96 {
97   switch (arg_id)
98     {
99     case ARG_XALIGN:
100       gtk_misc_set_alignment (misc, GTK_VALUE_DOUBLE (*arg), misc->yalign);
101       break;
102     case ARG_YALIGN:
103       gtk_misc_set_alignment (misc, misc->xalign, GTK_VALUE_DOUBLE (*arg));
104       break;
105     case ARG_XPAD:
106       gtk_misc_set_alignment (misc, GTK_VALUE_INT (*arg), misc->ypad);
107       break;
108     case ARG_YPAD:
109       gtk_misc_set_alignment (misc, misc->xpad, GTK_VALUE_INT (*arg));
110       break;
111     default:
112       arg->type = GTK_TYPE_INVALID;
113       break;
114     }
115 }
116
117 static void
118 gtk_misc_get_arg (GtkMisc        *misc,
119                   GtkArg         *arg,
120                   guint           arg_id)
121 {
122   switch (arg_id)
123     {
124     case ARG_XALIGN:
125       GTK_VALUE_DOUBLE (*arg) = misc->xalign;
126       break;
127     case ARG_YALIGN:
128       GTK_VALUE_DOUBLE (*arg) = misc->yalign;
129       break;
130     case ARG_XPAD:
131       GTK_VALUE_INT (*arg) = misc->xpad;
132       break;
133     case ARG_YPAD:
134       GTK_VALUE_INT (*arg) = misc->ypad;
135       break;
136     default:
137       arg->type = GTK_TYPE_INVALID;
138       break;
139     }
140 }
141
142 void
143 gtk_misc_set_alignment (GtkMisc *misc,
144                         gfloat   xalign,
145                         gfloat   yalign)
146 {
147   g_return_if_fail (misc != NULL);
148   g_return_if_fail (GTK_IS_MISC (misc));
149
150   if (xalign < 0.0)
151     xalign = 0.0;
152   else if (xalign > 1.0)
153     xalign = 1.0;
154
155   if (yalign < 0.0)
156     yalign = 0.0;
157   else if (yalign > 1.0)
158     yalign = 1.0;
159
160   if ((xalign != misc->xalign) || (yalign != misc->yalign))
161     {
162       misc->xalign = xalign;
163       misc->yalign = yalign;
164       
165       /* clear the area that was allocated before the change
166        */
167       if (GTK_WIDGET_DRAWABLE (misc))
168         {
169           GtkWidget *widget;
170           
171           widget = GTK_WIDGET (misc);
172           gdk_window_clear_area (widget->window,
173                                  widget->allocation.x,
174                                  widget->allocation.y,
175                                  widget->allocation.width,
176                                  widget->allocation.height);
177           gtk_widget_queue_draw (GTK_WIDGET (misc));
178         }
179     }
180 }
181
182 void
183 gtk_misc_set_padding (GtkMisc *misc,
184                       gint     xpad,
185                       gint     ypad)
186 {
187   GtkRequisition *requisition;
188   
189   g_return_if_fail (misc != NULL);
190   g_return_if_fail (GTK_IS_MISC (misc));
191   
192   if (xpad < 0)
193     xpad = 0;
194   if (ypad < 0)
195     ypad = 0;
196   
197   if ((xpad != misc->xpad) || (ypad != misc->ypad))
198     {
199       requisition = &(GTK_WIDGET (misc)->requisition);
200       requisition->width -= misc->xpad * 2;
201       requisition->height -= misc->ypad * 2;
202       
203       misc->xpad = xpad;
204       misc->ypad = ypad;
205       
206       requisition->width += misc->xpad * 2;
207       requisition->height += misc->ypad * 2;
208       
209       if (GTK_WIDGET_DRAWABLE (misc))
210         gtk_widget_queue_resize (GTK_WIDGET (misc));
211     }
212 }
213
214 static void
215 gtk_misc_realize (GtkWidget *widget)
216 {
217   GtkMisc *misc;
218   GdkWindowAttr attributes;
219   gint attributes_mask;
220
221   g_return_if_fail (widget != NULL);
222   g_return_if_fail (GTK_IS_MISC (widget));
223
224   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
225   misc = GTK_MISC (widget);
226
227   if (GTK_WIDGET_NO_WINDOW (widget))
228     {
229       widget->window = gtk_widget_get_parent_window (widget);
230       gdk_window_ref (widget->window);
231       widget->style = gtk_style_attach (widget->style, widget->window);
232     }
233   else
234     {
235       attributes.window_type = GDK_WINDOW_CHILD;
236       attributes.x = widget->allocation.x;
237       attributes.y = widget->allocation.y;
238       attributes.width = widget->allocation.width;
239       attributes.height = widget->allocation.height;
240       attributes.wclass = GDK_INPUT_OUTPUT;
241       attributes.visual = gtk_widget_get_visual (widget);
242       attributes.colormap = gtk_widget_get_colormap (widget);
243       attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
244       attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
245
246       widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
247       gdk_window_set_user_data (widget->window, widget);
248
249       widget->style = gtk_style_attach (widget->style, widget->window);
250       gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
251     }
252 }