1 /** \file
2 * Functions and callbacks for generic SVG view and widget
3 *
4 * Authors:
5 * Lauris Kaplinski <lauris@kaplinski.com>
6 * Ralf Stephan <ralf@ark.in-berlin.de>
7 * Abhishek Sharma
8 * Jon A. Cruz <jon@joncruz.org>
9 *
10 * Copyright (C) 2010 authors
11 * Copyright (C) 2001-2002 Lauris Kaplinski
12 * Copyright (C) 2001 Ximian, Inc.
13 *
14 * Released under GNU GPL, read the file 'COPYING' for more information
15 */
17 #include <gtk/gtkscrolledwindow.h>
18 #include "display/sp-canvas.h"
19 #include "display/sp-canvas-group.h"
20 #include "display/canvas-arena.h"
21 #include "document.h"
22 #include "svg-view.h"
23 #include "svg-view-widget.h"
25 static void sp_svg_view_widget_class_init (SPSVGSPViewWidgetClass *klass);
26 static void sp_svg_view_widget_init (SPSVGSPViewWidget *widget);
27 static void sp_svg_view_widget_destroy (GtkObject *object);
29 static void sp_svg_view_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
30 static void sp_svg_view_widget_size_request (GtkWidget *widget, GtkRequisition *req);
32 static void sp_svg_view_widget_view_resized (SPViewWidget *vw, Inkscape::UI::View::View *view, gdouble width, gdouble height);
34 static SPViewWidgetClass *widget_parent_class;
36 /**
37 * Registers SPSVGSPViewWidget class with Gtk and returns its type number.
38 */
39 GType sp_svg_view_widget_get_type(void)
40 {
41 static GType type = 0;
42 if (!type) {
43 GTypeInfo info = {
44 sizeof(SPSVGSPViewWidgetClass),
45 0, // base_init
46 0, // base_finalize
47 (GClassInitFunc)sp_svg_view_widget_class_init,
48 0, // class_finalize
49 0, // class_data
50 sizeof(SPSVGSPViewWidget),
51 0, // n_preallocs
52 (GInstanceInitFunc)sp_svg_view_widget_init,
53 0 // value_table
54 };
55 type = g_type_register_static(SP_TYPE_VIEW_WIDGET, "SPSVGSPViewWidget", &info, static_cast<GTypeFlags>(0));
56 }
57 return type;
58 }
60 /**
61 * Callback to initialize SPSVGSPViewWidget vtable.
62 */
63 static void
64 sp_svg_view_widget_class_init (SPSVGSPViewWidgetClass *klass)
65 {
66 GtkObjectClass *object_class;
67 GtkWidgetClass *widget_class;
68 SPViewWidgetClass *vw_class;
70 object_class = GTK_OBJECT_CLASS (klass);
71 widget_class = GTK_WIDGET_CLASS (klass);
72 vw_class = SP_VIEW_WIDGET_CLASS (klass);
74 widget_parent_class = (SPViewWidgetClass*)gtk_type_class (SP_TYPE_VIEW_WIDGET);
76 object_class->destroy = sp_svg_view_widget_destroy;
78 widget_class->size_allocate = sp_svg_view_widget_size_allocate;
79 widget_class->size_request = sp_svg_view_widget_size_request;
81 vw_class->view_resized = sp_svg_view_widget_view_resized;
82 }
84 /**
85 * Callback to initialize SPSVGSPViewWidget object.
86 */
87 static void
88 sp_svg_view_widget_init (SPSVGSPViewWidget *vw)
89 {
90 GtkStyle *style;
91 SPCanvasItem *parent;
93 /* Settings */
94 vw->resize = FALSE;
95 vw->maxwidth = 400.0;
96 vw->maxheight = 400.0;
98 /* ScrolledWindow */
99 vw->sw = gtk_scrolled_window_new (NULL, NULL);
100 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(vw->sw), GTK_SHADOW_NONE);
101 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (vw->sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
102 gtk_container_add (GTK_CONTAINER (vw), vw->sw);
103 gtk_widget_show (vw->sw);
105 /* Canvas */
106 gtk_widget_push_visual (gdk_rgb_get_visual ());
107 gtk_widget_push_colormap (gdk_rgb_get_cmap ());
108 vw->canvas = sp_canvas_new_aa ();
109 gtk_widget_pop_colormap ();
110 gtk_widget_pop_visual ();
111 style = gtk_style_copy (vw->canvas->style);
112 style->bg[GTK_STATE_NORMAL] = style->white;
113 gtk_widget_set_style (vw->canvas, style);
114 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (vw->sw), vw->canvas);
115 gtk_widget_show (vw->canvas);
117 /* View */
118 parent = sp_canvas_item_new (sp_canvas_root (SP_CANVAS (vw->canvas)), SP_TYPE_CANVAS_GROUP, NULL);
119 Inkscape::UI::View::View *view = Inkscape::GC::release(new SPSVGView (SP_CANVAS_GROUP (parent)));
120 sp_view_widget_set_view (SP_VIEW_WIDGET (vw), view);
121 }
123 /*
124 * Destructor callback for SPSVGSPViewWidget objects.
125 */
126 static void
127 sp_svg_view_widget_destroy (GtkObject *object)
128 {
129 SPSVGSPViewWidget *vw = SP_SVG_VIEW_WIDGET (object);
131 vw->canvas = NULL;
133 if (((GtkObjectClass *) (widget_parent_class))->destroy)
134 (* ((GtkObjectClass *) (widget_parent_class))->destroy) (object);
135 }
137 /**
138 * Callback connected with size_request signal.
139 */
140 static void
141 sp_svg_view_widget_size_request (GtkWidget *widget, GtkRequisition *req)
142 {
143 SPSVGSPViewWidget *vw = SP_SVG_VIEW_WIDGET (widget);
144 Inkscape::UI::View::View *v = SP_VIEW_WIDGET_VIEW (widget);
146 if (((GtkWidgetClass *) (widget_parent_class))->size_request)
147 (* ((GtkWidgetClass *) (widget_parent_class))->size_request) (widget, req);
149 if (v->doc()) {
150 SPSVGView *svgv;
151 GtkPolicyType hpol, vpol;
152 gdouble width, height;
154 svgv = static_cast<SPSVGView*> (v);
155 width = (v->doc())->getWidth () * svgv->_hscale;
156 height = (v->doc())->getHeight () * svgv->_vscale;
158 if (width <= vw->maxwidth) {
159 hpol = GTK_POLICY_NEVER;
160 req->width = (gint) (width + 0.5);
161 } else {
162 hpol = GTK_POLICY_AUTOMATIC;
163 req->width = (gint) (vw->maxwidth + 0.5);
164 }
165 if (height <= vw->maxheight) {
166 vpol = GTK_POLICY_NEVER;
167 req->height = (gint) (height + 8.0);
168 } else {
169 vpol = GTK_POLICY_AUTOMATIC;
170 req->height = (gint) (vw->maxheight + 2.0);
171 }
172 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (vw->sw), hpol, vpol);
173 }
174 }
176 /**
177 * Callback connected with size_allocate signal.
178 */
179 static void
180 sp_svg_view_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
181 {
182 SPSVGSPViewWidget *svgvw = SP_SVG_VIEW_WIDGET (widget);
184 if (((GtkWidgetClass *) (widget_parent_class))->size_allocate)
185 (* ((GtkWidgetClass *) (widget_parent_class))->size_allocate) (widget, allocation);
187 if (!svgvw->resize) {
188 static_cast<SPSVGView*>(SP_VIEW_WIDGET_VIEW (svgvw))->setRescale (TRUE, TRUE,
189 (gdouble) allocation->width - 1.0, (gdouble) allocation->height - 1.0);
190 }
191 }
193 /**
194 * Callback connected with view_resized signal.
195 */
196 static void
197 sp_svg_view_widget_view_resized (SPViewWidget *vw, Inkscape::UI::View::View */*view*/, gdouble width, gdouble height)
198 {
199 SPSVGSPViewWidget *svgvw = SP_SVG_VIEW_WIDGET (vw);
201 if (svgvw->resize) {
202 gtk_widget_set_size_request (svgvw->canvas, (int)width, (int)height);
203 gtk_widget_queue_resize (GTK_WIDGET (vw));
204 }
205 }
207 /**
208 * Constructs new SPSVGSPViewWidget object and returns pointer to it.
209 */
210 GtkWidget *
211 sp_svg_view_widget_new (SPDocument *doc)
212 {
213 GtkWidget *widget;
215 g_return_val_if_fail (doc != NULL, NULL);
217 widget = (GtkWidget*)gtk_type_new (SP_TYPE_SVG_VIEW_WIDGET);
219 reinterpret_cast<SPSVGView*>(SP_VIEW_WIDGET_VIEW (widget))->setDocument (doc);
221 return widget;
222 }
224 /**
225 * Flags the SPSVGSPViewWidget to have its size renegotiated with Gtk.
226 */
227 void SPSVGSPViewWidget::setResize(bool resize, gdouble width, gdouble height)
228 {
229 g_return_if_fail( !resize || (width > 0.0) );
230 g_return_if_fail( !resize || (height > 0.0) );
232 this->resize = resize;
233 this->maxwidth = width;
234 this->maxheight = height;
236 if ( resize ) {
237 gtk_widget_queue_resize( GTK_WIDGET(this) );
238 }
239 }
242 /*
243 Local Variables:
244 mode:c++
245 c-file-style:"stroustrup"
246 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
247 indent-tabs-mode:nil
248 fill-column:99
249 End:
250 */
251 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :