Code

Use subdirectories with icon sizes.
[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     //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;
116 static void
117 sp_widget_init (SPWidget *spw)
119         spw->inkscape = NULL;
122 static void
123 sp_widget_destroy (GtkObject *object)
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);
142 static void
143 sp_widget_show (GtkWidget *widget)
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);
160 static void
161 sp_widget_hide (GtkWidget *widget)
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);
176 static gint
177 sp_widget_expose (GtkWidget *widget, GdkEventExpose *event)
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;
197 static void
198 sp_widget_size_request (GtkWidget *widget, GtkRequisition *requisition)
200         if (((GtkBin *) widget)->child)
201                 gtk_widget_size_request (((GtkBin *) widget)->child, requisition);
204 static void
205 sp_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
207         widget->allocation = *allocation;
209         if (((GtkBin *) widget)->child)
210                 gtk_widget_size_allocate (((GtkBin *) widget)->child, allocation);
213 /* Methods */
215 GtkWidget *
216 sp_widget_new_global (Inkscape::Application *inkscape)
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;
230 GtkWidget *
231 sp_widget_construct_global (SPWidget *spw, Inkscape::Application *inkscape)
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;
247 static void
248 sp_widget_modify_selection (Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, guint flags, SPWidget *spw)
250         g_signal_emit (G_OBJECT (spw), signals[MODIFY_SELECTION], 0, selection, flags);
253 static void
254 sp_widget_change_selection (Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, SPWidget *spw)
256         g_signal_emit (G_OBJECT (spw), signals[CHANGE_SELECTION], 0, selection);
259 static void
260 sp_widget_set_selection (Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, SPWidget *spw)
262         /* Emit "set_selection" signal */
263         g_signal_emit (G_OBJECT (spw), signals[SET_SELECTION], 0, selection);
264         /* Inkscape will force "change_selection" anyways */
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 :