Code

Merge from fe-moved
[inkscape.git] / src / widgets / sp-widget.cpp
1 #define __SP_WIDGET_C__
3 /*
4  * Abstract base class for dynamic control widgets
5  *
6  * Authors:
7  *   Lauris Kaplinski <lauris@kaplinski.com>
8  *   bulia byak <buliabyak@users.sf.net>
9  *
10  * Copyright (C) 1999-2002 Lauris Kaplinski
11  * Copyright (C) 2000-2001 Ximian, Inc.
12  *
13  * Released under GNU GPL, read the file 'COPYING' for more information
14  */
16 #include "macros.h"
17 #include "../document.h"
18 #include "sp-widget.h"
20 enum {
21         CONSTRUCT,
22         MODIFY_SELECTION,
23         CHANGE_SELECTION,
24         SET_SELECTION,
25         LAST_SIGNAL
26 };
28 static void sp_widget_class_init (SPWidgetClass *klass);
29 static void sp_widget_init (SPWidget *widget);
31 static void sp_widget_destroy (GtkObject *object);
33 static void sp_widget_show (GtkWidget *widget);
34 static void sp_widget_hide (GtkWidget *widget);
35 static gint sp_widget_expose (GtkWidget *widget, GdkEventExpose *event);
36 static void sp_widget_size_request (GtkWidget *widget, GtkRequisition *requisition);
37 static void sp_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
39 static void sp_widget_modify_selection (Inkscape::Application *inkscape, Inkscape::Selection *selection, guint flags, SPWidget *spw);
40 static void sp_widget_change_selection (Inkscape::Application *inkscape, Inkscape::Selection *selection, SPWidget *spw);
41 static void sp_widget_set_selection (Inkscape::Application *inkscape, Inkscape::Selection *selection, SPWidget *spw);
43 static GtkBinClass *parent_class;
44 static guint signals[LAST_SIGNAL] = {0};
46 GtkType
47 sp_widget_get_type (void)
48 {
49         static GtkType type = 0;
50         if (!type) {
51                 static const GtkTypeInfo info = {
52                         "SPWidget",
53                         sizeof (SPWidget),
54                         sizeof (SPWidgetClass),
55                         (GtkClassInitFunc) sp_widget_class_init,
56                         (GtkObjectInitFunc) sp_widget_init,
57                         NULL, NULL, NULL
58                 };
59                 type = gtk_type_unique (GTK_TYPE_BIN, &info);
60         }
61         return type;
62 }
64 static void
65 sp_widget_class_init (SPWidgetClass *klass)
66 {
67         GtkObjectClass *object_class;
68         GtkWidgetClass *widget_class;
70         object_class = (GtkObjectClass *) klass;
71         widget_class = (GtkWidgetClass *) klass;
73         parent_class = (GtkBinClass*)gtk_type_class (GTK_TYPE_BIN);
75         object_class->destroy = sp_widget_destroy;
77         signals[CONSTRUCT] =        gtk_signal_new ("construct",
78                                                     GTK_RUN_FIRST,
79                                                     GTK_CLASS_TYPE(object_class),
80                                                     GTK_SIGNAL_OFFSET (SPWidgetClass, construct),
81                                                     gtk_marshal_NONE__NONE,
82                                                     GTK_TYPE_NONE, 0);
83         signals[CHANGE_SELECTION] = gtk_signal_new ("change_selection",
84                                                     GTK_RUN_FIRST,
85                                                     GTK_CLASS_TYPE(object_class),
86                                                     GTK_SIGNAL_OFFSET (SPWidgetClass, change_selection),
87                                                     gtk_marshal_NONE__POINTER,
88                                                     GTK_TYPE_NONE, 1,
89                                                     GTK_TYPE_POINTER);
90         signals[MODIFY_SELECTION] = gtk_signal_new ("modify_selection",
91                                                     GTK_RUN_FIRST,
92                                                     GTK_CLASS_TYPE(object_class),
93                                                     GTK_SIGNAL_OFFSET (SPWidgetClass, modify_selection),
94                                                     gtk_marshal_NONE__POINTER_UINT,
95                                                     GTK_TYPE_NONE, 2,
96                                                     GTK_TYPE_POINTER, GTK_TYPE_UINT);
97         signals[SET_SELECTION] =    gtk_signal_new ("set_selection",
98                                                     GTK_RUN_FIRST,
99                                                     GTK_CLASS_TYPE(object_class),
100                                                     GTK_SIGNAL_OFFSET (SPWidgetClass, set_selection),
101                                                     gtk_marshal_NONE__POINTER,
102                                                     GTK_TYPE_NONE, 1,
103                                                     GTK_TYPE_POINTER);
105         widget_class->show = sp_widget_show;
106         widget_class->hide = sp_widget_hide;
107         widget_class->expose_event = sp_widget_expose;
108         widget_class->size_request = sp_widget_size_request;
109         widget_class->size_allocate = sp_widget_size_allocate;
112 static void
113 sp_widget_init (SPWidget *spw)
115         spw->inkscape = NULL;
118 static void
119 sp_widget_destroy (GtkObject *object)
121         SPWidget *spw;
123         spw = (SPWidget *) object;
125         if (spw->inkscape) {
126                 /* Disconnect signals */
127                 // the checks are necessary because when destroy is caused by the the program shutting down,
128                 // the inkscape object may already be (partly?) invalid --bb
129                 if (G_IS_OBJECT(spw->inkscape) && G_OBJECT_GET_CLASS(G_OBJECT(spw->inkscape)))
130                         sp_signal_disconnect_by_data (spw->inkscape, spw);
131                 spw->inkscape = NULL;
132         }
134         if (((GtkObjectClass *) parent_class)->destroy)
135                 (* ((GtkObjectClass *) parent_class)->destroy) (object);
138 static void
139 sp_widget_show (GtkWidget *widget)
141         SPWidget *spw;
143         spw = SP_WIDGET (widget);
145         if (spw->inkscape) {
146                 /* Connect signals */
147                 g_signal_connect (G_OBJECT (spw->inkscape), "modify_selection", G_CALLBACK (sp_widget_modify_selection), spw);
148                 g_signal_connect (G_OBJECT (spw->inkscape), "change_selection", G_CALLBACK (sp_widget_change_selection), spw);
149                 g_signal_connect (G_OBJECT (spw->inkscape), "set_selection", G_CALLBACK (sp_widget_set_selection), spw);
150         }
152         if (((GtkWidgetClass *) parent_class)->show)
153                 (* ((GtkWidgetClass *) parent_class)->show) (widget);
156 static void
157 sp_widget_hide (GtkWidget *widget)
159         SPWidget *spw;
161         spw = SP_WIDGET (widget);
163         if (spw->inkscape) {
164                 /* Disconnect signals */
165                 sp_signal_disconnect_by_data (spw->inkscape, spw);
166         }
168         if (((GtkWidgetClass *) parent_class)->hide)
169                 (* ((GtkWidgetClass *) parent_class)->hide) (widget);
172 static gint
173 sp_widget_expose (GtkWidget *widget, GdkEventExpose *event)
175         GtkBin *bin;
177         bin = GTK_BIN (widget);
179         if ( bin->child ) {
180             gtk_container_propagate_expose (GTK_CONTAINER(widget), bin->child, event);
181         }
182         /*
183         if ((bin->child) && (GTK_WIDGET_NO_WINDOW (bin->child))) {
184                 GdkEventExpose ce;
185                 ce = *event;
186                 gtk_widget_event (bin->child, (GdkEvent *) &ce);
187         }
188         */
190         return FALSE;
193 static void
194 sp_widget_size_request (GtkWidget *widget, GtkRequisition *requisition)
196         if (((GtkBin *) widget)->child)
197                 gtk_widget_size_request (((GtkBin *) widget)->child, requisition);
200 static void
201 sp_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
203         widget->allocation = *allocation;
205         if (((GtkBin *) widget)->child)
206                 gtk_widget_size_allocate (((GtkBin *) widget)->child, allocation);
209 /* Methods */
211 GtkWidget *
212 sp_widget_new_global (Inkscape::Application *inkscape)
214         SPWidget *spw;
216         spw = (SPWidget*)gtk_type_new (SP_TYPE_WIDGET);
218         if (!sp_widget_construct_global (spw, inkscape)) {
219                 gtk_object_unref (GTK_OBJECT (spw));
220                 return NULL;
221         }
223         return (GtkWidget *) spw;
226 GtkWidget *
227 sp_widget_construct_global (SPWidget *spw, Inkscape::Application *inkscape)
229         g_return_val_if_fail (!spw->inkscape, NULL);
231         spw->inkscape = inkscape;
232         if (GTK_WIDGET_VISIBLE (spw)) {
233                 g_signal_connect (G_OBJECT (inkscape), "modify_selection", G_CALLBACK (sp_widget_modify_selection), spw);
234                 g_signal_connect (G_OBJECT (inkscape), "change_selection", G_CALLBACK (sp_widget_change_selection), spw);
235                 g_signal_connect (G_OBJECT (inkscape), "set_selection", G_CALLBACK (sp_widget_set_selection), spw);
236         }
238         g_signal_emit (G_OBJECT (spw), signals[CONSTRUCT], 0);
240         return (GtkWidget *) spw;
243 static void
244 sp_widget_modify_selection (Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, guint flags, SPWidget *spw)
246         g_signal_emit (G_OBJECT (spw), signals[MODIFY_SELECTION], 0, selection, flags);
249 static void
250 sp_widget_change_selection (Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, SPWidget *spw)
252         g_signal_emit (G_OBJECT (spw), signals[CHANGE_SELECTION], 0, selection);
255 static void
256 sp_widget_set_selection (Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, SPWidget *spw)
258         /* Emit "set_selection" signal */
259         g_signal_emit (G_OBJECT (spw), signals[SET_SELECTION], 0, selection);
260         /* Inkscape will force "change_selection" anyways */
263 /*
264   Local Variables:
265   mode:c++
266   c-file-style:"stroustrup"
267   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
268   indent-tabs-mode:nil
269   fill-column:99
270   End:
271 */
272 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :