]> Pileus Git - ~andy/gtk/blob - gtk/gtkseparator.c
separator: Convert to draw signal
[~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_draw         (GtkWidget      *widget,
68                                               cairo_t        *cr);
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->draw         = gtk_separator_draw;
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_draw (GtkWidget    *widget,
190                     cairo_t      *cr)
191 {
192   GtkSeparator *separator = GTK_SEPARATOR (widget);
193   GtkSeparatorPrivate *private = separator->priv;
194   GtkStateType state;
195   GtkStyle *style;
196   GdkWindow *window;
197   gboolean wide_separators;
198   gint separator_width;
199   gint separator_height;
200   int width, height;
201
202   style = gtk_widget_get_style (widget);
203   gtk_widget_style_get (widget,
204                         "wide-separators",  &wide_separators,
205                         "separator-width",  &separator_width,
206                         "separator-height", &separator_height,
207                         NULL);
208
209   window = gtk_widget_get_window (widget);
210   state = gtk_widget_get_state (widget);
211   width = gtk_widget_get_allocated_width (widget);
212   height = gtk_widget_get_allocated_height (widget);
213
214   if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
215     {
216       if (wide_separators)
217         gtk_cairo_paint_box (style, cr,
218                        gtk_widget_get_state (widget), GTK_SHADOW_ETCHED_OUT,
219                        widget, "hseparator",
220                        0, (height - separator_height) / 2,
221                        width, separator_height);
222       else
223         gtk_cairo_paint_hline (style, cr,
224                          gtk_widget_get_state (widget),
225                          widget, "hseparator",
226                          0, width - 1,
227                          (height - style->ythickness) / 2);
228     }
229   else
230     {
231       if (wide_separators)
232         gtk_cairo_paint_box (style, cr,
233                        gtk_widget_get_state (widget), GTK_SHADOW_ETCHED_OUT,
234                        widget, "vseparator",
235                        (width - separator_width) / 2, 0,
236                        separator_width, height);
237       else
238         gtk_cairo_paint_vline (style, cr,
239                          gtk_widget_get_state (widget),
240                          widget, "vseparator",
241                          0, height - 1,
242                          (width - style->xthickness) / 2);
243     }
244
245   return FALSE;
246 }
247
248 /**
249  * gtk_separator_new:
250  * @orientation: the separator's orientation.
251  *
252  * Creates a new #GtkSeparator with the given orientation.
253  *
254  * Return value: a new #GtkSeparator.
255  *
256  * Since: 3.0
257  **/
258 GtkWidget *
259 gtk_separator_new (GtkOrientation orientation)
260 {
261   return g_object_new (GTK_TYPE_SEPARATOR,
262                        "orientation", orientation,
263                        NULL);
264 }