1 #define __SP_SVG_VIEW_C__
3 /** \file
4 * Functions and callbacks for generic SVG view and widget
5 *
6 * Authors:
7 * Lauris Kaplinski <lauris@kaplinski.com>
8 * Ralf Stephan <ralf@ark.in-berlin.de>
9 *
10 * Copyright (C) 2001-2002 Lauris Kaplinski
11 * Copyright (C) 2001 Ximian, Inc.
12 *
13 * Released under GNU GPL, read the file 'COPYING' for more information
14 */
16 #include <gtk/gtkscrolledwindow.h>
17 #include "display/canvas-arena.h"
18 #include "document.h"
19 #include "svg-view.h"
20 #include "svg-view-widget.h"
22 static void sp_svg_view_widget_class_init (SPSVGSPViewWidgetClass *klass);
23 static void sp_svg_view_widget_init (SPSVGSPViewWidget *widget);
24 static void sp_svg_view_widget_destroy (GtkObject *object);
26 static void sp_svg_view_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
27 static void sp_svg_view_widget_size_request (GtkWidget *widget, GtkRequisition *req);
29 static void sp_svg_view_widget_view_resized (SPViewWidget *vw, Inkscape::UI::View::View *view, gdouble width, gdouble height);
31 static SPViewWidgetClass *widget_parent_class;
33 /**
34 * Registers SPSVGSPViewWidget class with Gtk and returns its type number.
35 */
36 GtkType
37 sp_svg_view_widget_get_type (void)
38 {
39 static GtkType type = 0;
40 if (!type) {
41 GtkTypeInfo info = {
42 "SPSVGSPViewWidget",
43 sizeof (SPSVGSPViewWidget),
44 sizeof (SPSVGSPViewWidgetClass),
45 (GtkClassInitFunc) sp_svg_view_widget_class_init,
46 (GtkObjectInitFunc) sp_svg_view_widget_init,
47 NULL, NULL, NULL
48 };
49 type = gtk_type_unique (SP_TYPE_VIEW_WIDGET, &info);
50 }
51 return type;
52 }
54 /**
55 * Callback to initialize SPSVGSPViewWidget vtable.
56 */
57 static void
58 sp_svg_view_widget_class_init (SPSVGSPViewWidgetClass *klass)
59 {
60 GtkObjectClass *object_class;
61 GtkWidgetClass *widget_class;
62 SPViewWidgetClass *vw_class;
64 object_class = GTK_OBJECT_CLASS (klass);
65 widget_class = GTK_WIDGET_CLASS (klass);
66 vw_class = SP_VIEW_WIDGET_CLASS (klass);
68 widget_parent_class = (SPViewWidgetClass*)gtk_type_class (SP_TYPE_VIEW_WIDGET);
70 object_class->destroy = sp_svg_view_widget_destroy;
72 widget_class->size_allocate = sp_svg_view_widget_size_allocate;
73 widget_class->size_request = sp_svg_view_widget_size_request;
75 vw_class->view_resized = sp_svg_view_widget_view_resized;
76 }
78 /**
79 * Callback to initialize SPSVGSPViewWidget object.
80 */
81 static void
82 sp_svg_view_widget_init (SPSVGSPViewWidget *vw)
83 {
84 GtkStyle *style;
85 SPCanvasItem *parent;
87 /* Settings */
88 vw->resize = FALSE;
89 vw->maxwidth = 400.0;
90 vw->maxheight = 400.0;
92 /* ScrolledWindow */
93 vw->sw = gtk_scrolled_window_new (NULL, NULL);
94 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(vw->sw), GTK_SHADOW_NONE);
95 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (vw->sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
96 gtk_container_add (GTK_CONTAINER (vw), vw->sw);
97 gtk_widget_show (vw->sw);
99 /* Canvas */
100 gtk_widget_push_visual (gdk_rgb_get_visual ());
101 gtk_widget_push_colormap (gdk_rgb_get_cmap ());
102 vw->canvas = sp_canvas_new_aa ();
103 gtk_widget_pop_colormap ();
104 gtk_widget_pop_visual ();
105 style = gtk_style_copy (vw->canvas->style);
106 style->bg[GTK_STATE_NORMAL] = style->white;
107 gtk_widget_set_style (vw->canvas, style);
108 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (vw->sw), vw->canvas);
109 gtk_widget_show (vw->canvas);
111 /* View */
112 parent = sp_canvas_item_new (sp_canvas_root (SP_CANVAS (vw->canvas)), SP_TYPE_CANVAS_GROUP, NULL);
113 Inkscape::UI::View::View *view = Inkscape::GC::release(new SPSVGView (SP_CANVAS_GROUP (parent)));
114 sp_view_widget_set_view (SP_VIEW_WIDGET (vw), view);
115 }
117 /*
118 * Destructor callback for SPSVGSPViewWidget objects.
119 */
120 static void
121 sp_svg_view_widget_destroy (GtkObject *object)
122 {
123 SPSVGSPViewWidget *vw = SP_SVG_VIEW_WIDGET (object);
125 vw->canvas = NULL;
127 if (((GtkObjectClass *) (widget_parent_class))->destroy)
128 (* ((GtkObjectClass *) (widget_parent_class))->destroy) (object);
129 }
131 /**
132 * Callback connected with size_request signal.
133 */
134 static void
135 sp_svg_view_widget_size_request (GtkWidget *widget, GtkRequisition *req)
136 {
137 SPSVGSPViewWidget *vw = SP_SVG_VIEW_WIDGET (widget);
138 Inkscape::UI::View::View *v = SP_VIEW_WIDGET_VIEW (widget);
140 if (((GtkWidgetClass *) (widget_parent_class))->size_request)
141 (* ((GtkWidgetClass *) (widget_parent_class))->size_request) (widget, req);
143 if (v->doc()) {
144 SPSVGView *svgv;
145 GtkPolicyType hpol, vpol;
146 gdouble width, height;
148 svgv = static_cast<SPSVGView*> (v);
149 width = sp_document_width (v->doc()) * svgv->_hscale;
150 height = sp_document_height (v->doc()) * svgv->_vscale;
152 if (width <= vw->maxwidth) {
153 hpol = GTK_POLICY_NEVER;
154 req->width = (gint) (width + 0.5);
155 } else {
156 hpol = GTK_POLICY_AUTOMATIC;
157 req->width = (gint) (vw->maxwidth + 0.5);
158 }
159 if (height <= vw->maxheight) {
160 vpol = GTK_POLICY_NEVER;
161 req->height = (gint) (height + 8.0);
162 } else {
163 vpol = GTK_POLICY_AUTOMATIC;
164 req->height = (gint) (vw->maxheight + 2.0);
165 }
166 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (vw->sw), hpol, vpol);
167 }
168 }
170 /**
171 * Callback connected with size_allocate signal.
172 */
173 static void
174 sp_svg_view_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
175 {
176 SPSVGSPViewWidget *svgvw = SP_SVG_VIEW_WIDGET (widget);
178 if (((GtkWidgetClass *) (widget_parent_class))->size_allocate)
179 (* ((GtkWidgetClass *) (widget_parent_class))->size_allocate) (widget, allocation);
181 if (!svgvw->resize) {
182 static_cast<SPSVGView*>(SP_VIEW_WIDGET_VIEW (svgvw))->setRescale (TRUE, TRUE,
183 (gdouble) allocation->width - 1.0, (gdouble) allocation->height - 1.0);
184 }
185 }
187 /**
188 * Callback connected with view_resized signal.
189 */
190 static void
191 sp_svg_view_widget_view_resized (SPViewWidget *vw, Inkscape::UI::View::View *view, gdouble width, gdouble height)
192 {
193 SPSVGSPViewWidget *svgvw = SP_SVG_VIEW_WIDGET (vw);
195 if (svgvw->resize) {
196 gtk_widget_set_size_request (svgvw->canvas, (int)width, (int)height);
197 gtk_widget_queue_resize (GTK_WIDGET (vw));
198 }
199 }
201 /**
202 * Constructs new SPSVGSPViewWidget object and returns pointer to it.
203 */
204 GtkWidget *
205 sp_svg_view_widget_new (SPDocument *doc)
206 {
207 GtkWidget *widget;
209 g_return_val_if_fail (doc != NULL, NULL);
211 widget = (GtkWidget*)gtk_type_new (SP_TYPE_SVG_VIEW_WIDGET);
213 reinterpret_cast<SPSVGView*>(SP_VIEW_WIDGET_VIEW (widget))->setDocument (doc);
215 return widget;
216 }
218 /**
219 * Flags the SPSVGSPViewWidget to have its size renegotiated with Gtk.
220 */
221 void
222 sp_svg_view_widget_set_resize (SPSVGSPViewWidget *vw, bool resize, gdouble width, gdouble height)
223 {
224 g_return_if_fail (vw != NULL);
226 g_return_if_fail (SP_IS_SVG_VIEW_WIDGET (vw));
227 g_return_if_fail (!resize || (width > 0.0));
228 g_return_if_fail (!resize || (height > 0.0));
230 vw->resize = resize;
231 vw->maxwidth = width;
232 vw->maxheight = height;
234 if (resize) {
235 gtk_widget_queue_resize (GTK_WIDGET (vw));
236 }
237 }
240 /*
241 Local Variables:
242 mode:c++
243 c-file-style:"stroustrup"
244 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
245 indent-tabs-mode:nil
246 fill-column:99
247 End:
248 */
249 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :