]> Pileus Git - ~andy/gtk/blob - gtk/gtkseparatortoolitem.c
a37f66de4e955f322997e780df786f819ea4bf1e
[~andy/gtk] / gtk / gtkseparatortoolitem.c
1 /* gtkseparatortoolitem.c
2  *
3  * Copyright (C) 2002 Anders Carlsson <andersca@gnome.org>
4  * Copyright (C) 2002 James Henstridge <james@daa.com.au>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #undef GTK_DISABLE_DEPRECATED
23
24 #include "gtkseparatormenuitem.h"
25 #include "gtkseparatortoolitem.h"
26 #include "gtkintl.h"
27 #include "gtktoolbar.h"
28
29 /* note: keep in sync with DEFAULT_SPACE_SIZE and DEFAULT_SPACE_STYLE in gtktoolbar.c */
30 #define DEFAULT_SPACE_SIZE 4
31 #define DEFAULT_SPACE_STYLE GTK_TOOLBAR_SPACE_LINE
32
33 #define SPACE_LINE_DIVISION 10
34 #define SPACE_LINE_START    3
35 #define SPACE_LINE_END      7
36
37 #define MENU_ID "gtk-separator-tool-item-menu-id"
38
39 enum {
40   PROP_0,
41   PROP_DRAW
42 };
43
44 static void     gtk_separator_tool_item_class_init        (GtkSeparatorToolItemClass *class);
45 static void     gtk_separator_tool_item_init              (GtkSeparatorToolItem      *separator_item,
46                                                            GtkSeparatorToolItemClass *class);
47 static gboolean gtk_separator_tool_item_create_menu_proxy (GtkToolItem               *item);
48 static void     gtk_separator_tool_item_set_property      (GObject                   *object,
49                                                            guint                      prop_id,
50                                                            const GValue              *value,
51                                                            GParamSpec                *pspec);
52 static void     gtk_separator_tool_item_get_property       (GObject                   *object,
53                                                            guint                      prop_id,
54                                                            GValue                    *value,
55                                                            GParamSpec                *pspec);
56 static void     gtk_separator_tool_item_size_request      (GtkWidget                 *widget,
57                                                            GtkRequisition            *requisition);
58 static gboolean gtk_separator_tool_item_expose            (GtkWidget                 *widget,
59                                                            GdkEventExpose            *event);
60 static void     gtk_separator_tool_item_add               (GtkContainer              *container,
61                                                            GtkWidget                 *child);
62 static GtkToolbarSpaceStyle get_space_style               (GtkToolItem               *tool_item);
63 static gint                 get_space_size                (GtkToolItem               *tool_item);
64
65
66
67 static GObjectClass *parent_class = NULL;
68
69 #define GTK_SEPARATOR_TOOL_ITEM_GET_PRIVATE(obj)(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_SEPARATOR_TOOL_ITEM, GtkSeparatorToolItemPrivate))
70
71 struct _GtkSeparatorToolItemPrivate
72 {
73   guint draw : 1;
74 };
75
76 GType
77 gtk_separator_tool_item_get_type (void)
78 {
79   static GType type = 0;
80   
81   if (!type)
82     {
83       static const GTypeInfo type_info =
84         {
85           sizeof (GtkSeparatorToolItemClass),
86           (GBaseInitFunc) 0,
87           (GBaseFinalizeFunc) 0,
88           (GClassInitFunc) gtk_separator_tool_item_class_init,
89           (GClassFinalizeFunc) 0,
90           NULL,
91           sizeof (GtkSeparatorToolItem),
92           0, /* n_preallocs */
93           (GInstanceInitFunc) gtk_separator_tool_item_init,
94         };
95       
96       type = g_type_register_static (GTK_TYPE_TOOL_ITEM,
97                                      "GtkSeparatorToolItem", &type_info, 0);
98     }
99   return type;
100 }
101
102 static GtkToolbarSpaceStyle
103 get_space_style (GtkToolItem *tool_item)
104 {
105   GtkToolbarSpaceStyle space_style = DEFAULT_SPACE_STYLE;
106   GtkWidget *parent = GTK_WIDGET (tool_item)->parent;
107   
108   if (GTK_IS_TOOLBAR (parent))
109     {
110       gtk_widget_style_get (parent,
111                             "space_style", &space_style,
112                             NULL);
113     }
114   
115   return space_style;  
116 }
117
118 static gint
119 get_space_size (GtkToolItem *tool_item)
120 {
121   gint space_size = DEFAULT_SPACE_SIZE;
122   GtkWidget *parent = GTK_WIDGET (tool_item)->parent;
123   
124   if (GTK_IS_TOOLBAR (parent))
125     {
126       gtk_widget_style_get (parent,
127                             "space_size", &space_size,
128                             NULL);
129     }
130   
131   return space_size;
132 }
133
134 static void
135 gtk_separator_tool_item_class_init (GtkSeparatorToolItemClass *class)
136 {
137   GObjectClass *object_class;
138   GtkContainerClass *container_class;
139   GtkToolItemClass *toolitem_class;
140   GtkWidgetClass *widget_class;
141   
142   parent_class = g_type_class_peek_parent (class);
143   object_class = (GObjectClass *)class;
144   container_class = (GtkContainerClass *)class;
145   toolitem_class = (GtkToolItemClass *)class;
146   widget_class = (GtkWidgetClass *)class;
147
148   object_class->set_property = gtk_separator_tool_item_set_property;
149   object_class->get_property = gtk_separator_tool_item_get_property;
150   widget_class->size_request = gtk_separator_tool_item_size_request;
151   widget_class->expose_event = gtk_separator_tool_item_expose;
152   toolitem_class->create_menu_proxy = gtk_separator_tool_item_create_menu_proxy;
153   
154   container_class->add = gtk_separator_tool_item_add;
155   
156   g_object_class_install_property (object_class,
157                                    PROP_DRAW,
158                                    g_param_spec_boolean ("draw",
159                                                          _("Draw"),
160                                                          _("Whether the separator is drawn, or just blank"),
161                                                          TRUE,
162                                                          G_PARAM_READWRITE));
163   
164   g_type_class_add_private (object_class, sizeof (GtkSeparatorToolItemPrivate));
165 }
166
167 static void
168 gtk_separator_tool_item_init (GtkSeparatorToolItem      *separator_item,
169                               GtkSeparatorToolItemClass *class)
170 {
171   separator_item->priv = GTK_SEPARATOR_TOOL_ITEM_GET_PRIVATE (separator_item);
172   separator_item->priv->draw = TRUE;
173 }
174
175 static void
176 gtk_separator_tool_item_add (GtkContainer *container,
177                              GtkWidget    *child)
178 {
179   g_warning("attempt to add a child to an GtkSeparatorToolItem");
180 }
181
182 static gboolean
183 gtk_separator_tool_item_create_menu_proxy (GtkToolItem *item)
184 {
185   GtkWidget *menu_item = NULL;
186   
187   menu_item = gtk_separator_menu_item_new();
188   
189   gtk_tool_item_set_proxy_menu_item (item, MENU_ID, menu_item);
190   
191   return TRUE;
192 }
193
194 static void
195 gtk_separator_tool_item_set_property (GObject      *object,
196                                       guint         prop_id,
197                                       const GValue *value,
198                                       GParamSpec   *pspec)
199 {
200   GtkSeparatorToolItem *item = GTK_SEPARATOR_TOOL_ITEM (object);
201   
202   switch (prop_id)
203     {
204     case PROP_DRAW:
205       gtk_separator_tool_item_set_draw (item, g_value_get_boolean (value));
206       break;
207     default:
208       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
209       break;
210     }
211 }
212
213 static void
214 gtk_separator_tool_item_get_property (GObject      *object,
215                                       guint         prop_id,
216                                       GValue       *value,
217                                       GParamSpec   *pspec)
218 {
219   GtkSeparatorToolItem *item = GTK_SEPARATOR_TOOL_ITEM (object);
220   
221   switch (prop_id)
222     {
223     case PROP_DRAW:
224       g_value_set_boolean (value, gtk_separator_tool_item_get_draw (item));
225       break;
226     default:
227       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
228       break;
229     }
230 }
231
232 static void
233 gtk_separator_tool_item_size_request (GtkWidget      *widget,
234                                       GtkRequisition *requisition)
235 {
236   GtkToolItem *item = GTK_TOOL_ITEM (widget);
237   GtkOrientation orientation = gtk_tool_item_get_orientation (item);
238   
239   if (orientation == GTK_ORIENTATION_HORIZONTAL)
240     {
241       requisition->width = get_space_size (item);
242       requisition->height = 1;
243     }
244   else
245     {
246       requisition->height = get_space_size (item);
247       requisition->width = 1;
248     }
249 }
250
251 static gboolean
252 gtk_separator_tool_item_expose (GtkWidget      *widget,
253                                 GdkEventExpose *event)
254 {
255   GtkToolItem *tool_item = GTK_TOOL_ITEM (widget);
256   GtkSeparatorToolItem *separator_tool_item = GTK_SEPARATOR_TOOL_ITEM (widget);
257   gint space_size;
258   GtkAllocation *allocation;
259   GtkOrientation orientation;
260   GdkRectangle *area;
261
262   if (separator_tool_item->priv->draw &&
263       get_space_style (tool_item) == GTK_TOOLBAR_SPACE_LINE)
264     {
265       space_size = get_space_size (tool_item);
266       allocation = &(widget->allocation);
267       orientation = gtk_tool_item_get_orientation (tool_item);
268       area = &(event->area);
269       
270       if (orientation == GTK_ORIENTATION_HORIZONTAL)
271         {
272           gtk_paint_vline (widget->style, widget->window,
273                            GTK_WIDGET_STATE (widget), area, widget,
274                            "separator_tool_item",
275                            allocation->y + allocation->height *
276                            SPACE_LINE_START / SPACE_LINE_DIVISION,
277                            allocation->y + allocation->height *
278                            SPACE_LINE_END / SPACE_LINE_DIVISION,
279                            allocation->x + (space_size - widget->style->xthickness) / 2);
280         }
281       else if (orientation == GTK_ORIENTATION_VERTICAL)
282         {
283           gtk_paint_hline (widget->style, widget->window,
284                            GTK_WIDGET_STATE (widget), area, widget,
285                            "separator_tool_item",
286                            allocation->x + allocation->width *
287                            SPACE_LINE_START / SPACE_LINE_DIVISION,
288                            allocation->x + allocation->width *
289                            SPACE_LINE_END / SPACE_LINE_DIVISION,
290                            allocation->y + (space_size - widget->style->ythickness) / 2);
291         }
292     }
293   
294   return FALSE;
295 }
296
297 /**
298  * gtk_separator_tool_item_new:
299  * 
300  * Create a new #GtkSeparatorToolItem
301  * 
302  * Return value: the new #GtkSeparatorToolItem
303  * 
304  * Since: 2.4
305  **/
306 GtkToolItem *
307 gtk_separator_tool_item_new (void)
308 {
309   GtkToolItem *self;
310   
311   self = g_object_new (GTK_TYPE_SEPARATOR_TOOL_ITEM,
312                        NULL);
313   
314   return self;
315 }
316
317 /**
318  * gtk_separator_tool_item_get_draw:
319  * @separator_tool_item: a #GtkSeparatorToolItem 
320  * 
321  * Returns whether @separator_tool_item is drawn as a
322  * line, or just blank. See gtk_separator_tool_item_set_draw().
323  * 
324  * Return value: #TRUE if @separator_tool_item is drawn as a line, or just blank.
325  * 
326  * Since: 2.4
327  **/
328 gboolean
329 gtk_separator_tool_item_get_draw (GtkSeparatorToolItem *separator_tool_item)
330 {
331   g_return_val_if_fail (GTK_IS_SEPARATOR_TOOL_ITEM (separator_tool_item), FALSE);
332   
333   return separator_tool_item->priv->draw;
334 }
335
336 /**
337  * gtk_separator_tool_item_set_draw:
338  * @separator_tool_item: a #GtkSeparatorToolItem
339  * @draw: whether @separator_tool_item is drawn as a vertical iln
340  * 
341  * When @separator_tool_items is drawn as a vertical line, or just blank.
342  * Setting this #FALSE along with gtk_tool_item_set_expand() is useful
343  * to create an item that forces following items to the end of the toolbar.
344  * 
345  * Since: 2.4
346  **/
347 void
348 gtk_separator_tool_item_set_draw (GtkSeparatorToolItem *separator_tool_item,
349                                   gboolean              draw)
350 {
351   g_return_if_fail (GTK_IS_SEPARATOR_TOOL_ITEM (separator_tool_item));
352
353   draw = draw != FALSE;
354
355   if (draw != separator_tool_item->priv->draw)
356     {
357       separator_tool_item->priv->draw = draw;
358
359       gtk_widget_queue_draw (GTK_WIDGET (separator_tool_item));
360
361       g_object_notify (G_OBJECT (separator_tool_item), "draw");
362     }
363 }
364