]> Pileus Git - ~andy/gtk/blob - gtk/gtkseparator.c
579231c64f56f8b02e4f8799d3c2761fe1ff675f
[~andy/gtk] / gtk / gtkseparator.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 Lesser 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  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser 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
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
25  */
26
27 #include "config.h"
28
29 #include "gtkorientable.h"
30 #include "gtkseparator.h"
31 #include "gtkprivate.h"
32 #include "gtkintl.h"
33
34 /**
35  * SECTION:gtkseparator
36  * @Short_description: Base class for GtkHSeparator and GtkVSeparator
37  * @Title: GtkSeparator
38  *
39  * The GtkSeparator widget is the base class for #GtkHSeparator and
40  * #GtkVSeparator. It can be used in the same way as these, by setting
41  * the "orientation" property suitably.
42  */
43
44
45 struct _GtkSeparatorPrivate
46 {
47   GtkOrientation orientation;
48 };
49
50
51 enum {
52   PROP_0,
53   PROP_ORIENTATION
54 };
55
56 static void       gtk_separator_set_property (GObject        *object,
57                                               guint           prop_id,
58                                               const GValue   *value,
59                                               GParamSpec     *pspec);
60 static void       gtk_separator_get_property (GObject        *object,
61                                               guint           prop_id,
62                                               GValue         *value,
63                                               GParamSpec     *pspec);
64
65 static void       gtk_separator_size_request (GtkWidget      *widget,
66                                               GtkRequisition *requisition);
67 static gboolean   gtk_separator_expose       (GtkWidget      *widget,
68                                               GdkEventExpose *event);
69
70
71 G_DEFINE_TYPE_WITH_CODE (GtkSeparator, gtk_separator, GTK_TYPE_WIDGET,
72                          G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE,
73                                                 NULL))
74
75
76 static void
77 gtk_separator_class_init (GtkSeparatorClass *class)
78 {
79   GObjectClass *object_class = G_OBJECT_CLASS (class);
80   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
81
82   object_class->set_property = gtk_separator_set_property;
83   object_class->get_property = gtk_separator_get_property;
84
85   widget_class->size_request = gtk_separator_size_request;
86   widget_class->expose_event = gtk_separator_expose;
87
88   g_object_class_override_property (object_class,
89                                     PROP_ORIENTATION,
90                                     "orientation");
91
92   g_type_class_add_private (object_class, sizeof (GtkSeparatorPrivate));
93 }
94
95 static void
96 gtk_separator_init (GtkSeparator *separator)
97 {
98   GtkSeparatorPrivate *private;
99
100   separator->priv = G_TYPE_INSTANCE_GET_PRIVATE (separator,
101                                                  GTK_TYPE_SEPARATOR,
102                                                  GtkSeparatorPrivate);
103   private = separator->priv;
104
105   gtk_widget_set_has_window (GTK_WIDGET (separator), FALSE);
106
107   private->orientation = GTK_ORIENTATION_HORIZONTAL;
108 }
109
110 static void
111 gtk_separator_set_property (GObject      *object,
112                             guint         prop_id,
113                             const GValue *value,
114                             GParamSpec   *pspec)
115 {
116   GtkSeparator *separator = GTK_SEPARATOR (object);
117   GtkSeparatorPrivate *private = separator->priv;
118
119   switch (prop_id)
120     {
121     case PROP_ORIENTATION:
122       private->orientation = g_value_get_enum (value);
123       gtk_widget_queue_resize (GTK_WIDGET (object));
124       break;
125     default:
126       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
127       break;
128     }
129 }
130
131 static void
132 gtk_separator_get_property (GObject    *object,
133                             guint       prop_id,
134                             GValue     *value,
135                             GParamSpec *pspec)
136 {
137   GtkSeparator *separator = GTK_SEPARATOR (object);
138   GtkSeparatorPrivate *private = separator->priv;
139
140   switch (prop_id)
141     {
142     case PROP_ORIENTATION:
143       g_value_set_enum (value, private->orientation);
144       break;
145     default:
146       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
147       break;
148     }
149 }
150
151 static void
152 gtk_separator_size_request (GtkWidget      *widget,
153                             GtkRequisition *requisition)
154 {
155   GtkSeparator *separator = GTK_SEPARATOR (widget);
156   GtkSeparatorPrivate *private = separator->priv;
157   GtkStyle *style;
158   gboolean wide_separators;
159   gint     separator_width;
160   gint     separator_height;
161
162   style = gtk_widget_get_style (widget);
163   gtk_widget_style_get (widget,
164                         "wide-separators",  &wide_separators,
165                         "separator-width",  &separator_width,
166                         "separator-height", &separator_height,
167                         NULL);
168
169   requisition->width  = 1;
170   requisition->height = 1;
171
172   if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
173     {
174       if (wide_separators)
175         requisition->height = separator_height;
176       else
177         requisition->height = style->ythickness;
178     }
179   else
180     {
181       if (wide_separators)
182         requisition->width = separator_width;
183       else
184         requisition->width = style->xthickness;
185     }
186 }
187
188 static gboolean
189 gtk_separator_expose (GtkWidget      *widget,
190                       GdkEventExpose *event)
191 {
192   GtkSeparator *separator = GTK_SEPARATOR (widget);
193   GtkSeparatorPrivate *private = separator->priv;
194   GtkAllocation allocation;
195   GtkStateType state;
196   GtkStyle *style;
197   GdkWindow *window;
198   gboolean wide_separators;
199   gint     separator_width;
200   gint     separator_height;
201
202   if (!gtk_widget_is_drawable (widget))
203     return FALSE;
204
205   style = gtk_widget_get_style (widget);
206   gtk_widget_style_get (widget,
207                         "wide-separators",  &wide_separators,
208                         "separator-width",  &separator_width,
209                         "separator-height", &separator_height,
210                         NULL);
211
212   window = gtk_widget_get_window (widget);
213   state = gtk_widget_get_state (widget);
214   gtk_widget_get_allocation (widget, &allocation);
215
216   if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
217     {
218       if (wide_separators)
219         gtk_paint_box (style, window,
220                        state, GTK_SHADOW_ETCHED_OUT,
221                        &event->area, widget, "hseparator",
222                        allocation.x,
223                        allocation.y + (allocation.height - separator_height) / 2,
224                        allocation.width,
225                        separator_height);
226       else
227         gtk_paint_hline (style, window,
228                          state,
229                          &event->area, widget, "hseparator",
230                          allocation.x,
231                          allocation.x + allocation.width - 1,
232                          allocation.y + (allocation.height - style->ythickness) / 2);
233     }
234   else
235     {
236       if (wide_separators)
237         gtk_paint_box (style, window,
238                        state, GTK_SHADOW_ETCHED_OUT,
239                        &event->area, widget, "vseparator",
240                        allocation.x + (allocation.width - separator_width) / 2,
241                        allocation.y,
242                        separator_width,
243                        allocation.height);
244       else
245         gtk_paint_vline (style, window,
246                          state,
247                          &event->area, widget, "vseparator",
248                          allocation.y,
249                          allocation.y + allocation.height - 1,
250                          allocation.x + (allocation.width - style->xthickness) / 2);
251     }
252
253   return FALSE;
254 }
255
256 /**
257  * gtk_separator_new:
258  * @orientation: the separator's orientation.
259  *
260  * Creates a new #GtkSeparator with the given orientation.
261  *
262  * Return value: a new #GtkSeparator.
263  *
264  * Since: 3.0
265  **/
266 GtkWidget *
267 gtk_separator_new (GtkOrientation orientation)
268 {
269   return g_object_new (GTK_TYPE_SEPARATOR,
270                        "orientation", orientation,
271                        NULL);
272 }