f694c461ce5ca877eafdf5ccf998c500b906d39a
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 //TODO: switch to GObject
50 // GtkType and such calls were deprecated a while back with the
51 // introduction of GObject as a separate layer, with GType instead. --JonCruz
53 static GtkType type = 0;
54 if (!type) {
55 static const GtkTypeInfo info = {
56 (gchar*) "SPWidget",
57 sizeof (SPWidget),
58 sizeof (SPWidgetClass),
59 (GtkClassInitFunc) sp_widget_class_init,
60 (GtkObjectInitFunc) sp_widget_init,
61 NULL, NULL, NULL
62 };
63 type = gtk_type_unique (GTK_TYPE_BIN, &info);
64 }
65 return type;
66 }
68 static void
69 sp_widget_class_init (SPWidgetClass *klass)
70 {
71 GtkObjectClass *object_class;
72 GtkWidgetClass *widget_class;
74 object_class = (GtkObjectClass *) klass;
75 widget_class = (GtkWidgetClass *) klass;
77 parent_class = (GtkBinClass*)gtk_type_class (GTK_TYPE_BIN);
79 object_class->destroy = sp_widget_destroy;
81 signals[CONSTRUCT] = gtk_signal_new ("construct",
82 GTK_RUN_FIRST,
83 GTK_CLASS_TYPE(object_class),
84 GTK_SIGNAL_OFFSET (SPWidgetClass, construct),
85 gtk_marshal_NONE__NONE,
86 GTK_TYPE_NONE, 0);
87 signals[CHANGE_SELECTION] = gtk_signal_new ("change_selection",
88 GTK_RUN_FIRST,
89 GTK_CLASS_TYPE(object_class),
90 GTK_SIGNAL_OFFSET (SPWidgetClass, change_selection),
91 gtk_marshal_NONE__POINTER,
92 GTK_TYPE_NONE, 1,
93 GTK_TYPE_POINTER);
94 signals[MODIFY_SELECTION] = gtk_signal_new ("modify_selection",
95 GTK_RUN_FIRST,
96 GTK_CLASS_TYPE(object_class),
97 GTK_SIGNAL_OFFSET (SPWidgetClass, modify_selection),
98 gtk_marshal_NONE__POINTER_UINT,
99 GTK_TYPE_NONE, 2,
100 GTK_TYPE_POINTER, GTK_TYPE_UINT);
101 signals[SET_SELECTION] = gtk_signal_new ("set_selection",
102 GTK_RUN_FIRST,
103 GTK_CLASS_TYPE(object_class),
104 GTK_SIGNAL_OFFSET (SPWidgetClass, set_selection),
105 gtk_marshal_NONE__POINTER,
106 GTK_TYPE_NONE, 1,
107 GTK_TYPE_POINTER);
109 widget_class->show = sp_widget_show;
110 widget_class->hide = sp_widget_hide;
111 widget_class->expose_event = sp_widget_expose;
112 widget_class->size_request = sp_widget_size_request;
113 widget_class->size_allocate = sp_widget_size_allocate;
114 }
116 static void
117 sp_widget_init (SPWidget *spw)
118 {
119 spw->inkscape = NULL;
120 }
122 static void
123 sp_widget_destroy (GtkObject *object)
124 {
125 SPWidget *spw;
127 spw = (SPWidget *) object;
129 if (spw->inkscape) {
130 /* Disconnect signals */
131 // the checks are necessary because when destroy is caused by the the program shutting down,
132 // the inkscape object may already be (partly?) invalid --bb
133 if (G_IS_OBJECT(spw->inkscape) && G_OBJECT_GET_CLASS(G_OBJECT(spw->inkscape)))
134 sp_signal_disconnect_by_data (spw->inkscape, spw);
135 spw->inkscape = NULL;
136 }
138 if (((GtkObjectClass *) parent_class)->destroy)
139 (* ((GtkObjectClass *) parent_class)->destroy) (object);
140 }
142 static void
143 sp_widget_show (GtkWidget *widget)
144 {
145 SPWidget *spw;
147 spw = SP_WIDGET (widget);
149 if (spw->inkscape) {
150 /* Connect signals */
151 g_signal_connect (G_OBJECT (spw->inkscape), "modify_selection", G_CALLBACK (sp_widget_modify_selection), spw);
152 g_signal_connect (G_OBJECT (spw->inkscape), "change_selection", G_CALLBACK (sp_widget_change_selection), spw);
153 g_signal_connect (G_OBJECT (spw->inkscape), "set_selection", G_CALLBACK (sp_widget_set_selection), spw);
154 }
156 if (((GtkWidgetClass *) parent_class)->show)
157 (* ((GtkWidgetClass *) parent_class)->show) (widget);
158 }
160 static void
161 sp_widget_hide (GtkWidget *widget)
162 {
163 SPWidget *spw;
165 spw = SP_WIDGET (widget);
167 if (spw->inkscape) {
168 /* Disconnect signals */
169 sp_signal_disconnect_by_data (spw->inkscape, spw);
170 }
172 if (((GtkWidgetClass *) parent_class)->hide)
173 (* ((GtkWidgetClass *) parent_class)->hide) (widget);
174 }
176 static gint
177 sp_widget_expose (GtkWidget *widget, GdkEventExpose *event)
178 {
179 GtkBin *bin;
181 bin = GTK_BIN (widget);
183 if ( bin->child ) {
184 gtk_container_propagate_expose (GTK_CONTAINER(widget), bin->child, event);
185 }
186 /*
187 if ((bin->child) && (GTK_WIDGET_NO_WINDOW (bin->child))) {
188 GdkEventExpose ce;
189 ce = *event;
190 gtk_widget_event (bin->child, (GdkEvent *) &ce);
191 }
192 */
194 return FALSE;
195 }
197 static void
198 sp_widget_size_request (GtkWidget *widget, GtkRequisition *requisition)
199 {
200 if (((GtkBin *) widget)->child)
201 gtk_widget_size_request (((GtkBin *) widget)->child, requisition);
202 }
204 static void
205 sp_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
206 {
207 widget->allocation = *allocation;
209 if (((GtkBin *) widget)->child)
210 gtk_widget_size_allocate (((GtkBin *) widget)->child, allocation);
211 }
213 /* Methods */
215 GtkWidget *
216 sp_widget_new_global (Inkscape::Application *inkscape)
217 {
218 SPWidget *spw;
220 spw = (SPWidget*)gtk_type_new (SP_TYPE_WIDGET);
222 if (!sp_widget_construct_global (spw, inkscape)) {
223 gtk_object_unref (GTK_OBJECT (spw));
224 return NULL;
225 }
227 return (GtkWidget *) spw;
228 }
230 GtkWidget *
231 sp_widget_construct_global (SPWidget *spw, Inkscape::Application *inkscape)
232 {
233 g_return_val_if_fail (!spw->inkscape, NULL);
235 spw->inkscape = inkscape;
236 if (GTK_WIDGET_VISIBLE (spw)) {
237 g_signal_connect (G_OBJECT (inkscape), "modify_selection", G_CALLBACK (sp_widget_modify_selection), spw);
238 g_signal_connect (G_OBJECT (inkscape), "change_selection", G_CALLBACK (sp_widget_change_selection), spw);
239 g_signal_connect (G_OBJECT (inkscape), "set_selection", G_CALLBACK (sp_widget_set_selection), spw);
240 }
242 g_signal_emit (G_OBJECT (spw), signals[CONSTRUCT], 0);
244 return (GtkWidget *) spw;
245 }
247 static void
248 sp_widget_modify_selection (Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, guint flags, SPWidget *spw)
249 {
250 g_signal_emit (G_OBJECT (spw), signals[MODIFY_SELECTION], 0, selection, flags);
251 }
253 static void
254 sp_widget_change_selection (Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, SPWidget *spw)
255 {
256 g_signal_emit (G_OBJECT (spw), signals[CHANGE_SELECTION], 0, selection);
257 }
259 static void
260 sp_widget_set_selection (Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, SPWidget *spw)
261 {
262 /* Emit "set_selection" signal */
263 g_signal_emit (G_OBJECT (spw), signals[SET_SELECTION], 0, selection);
264 /* Inkscape will force "change_selection" anyways */
265 }
267 /*
268 Local Variables:
269 mode:c++
270 c-file-style:"stroustrup"
271 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
272 indent-tabs-mode:nil
273 fill-column:99
274 End:
275 */
276 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :