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 *
9 * Copyright (C) 2001-2002 Lauris Kaplinski
10 * Copyright (C) 2001 Ximian, Inc.
11 *
12 * Released under GNU GPL, read the file 'COPYING' for more information
13 */
15 #include <gtk/gtkscrolledwindow.h>
16 #include "display/canvas-arena.h"
17 #include "document.h"
18 #include "svg-view.h"
19 #include "svg-view-widget.h"
21 static void sp_svg_view_widget_class_init (SPSVGSPViewWidgetClass *klass);
22 static void sp_svg_view_widget_init (SPSVGSPViewWidget *widget);
23 static void sp_svg_view_widget_destroy (GtkObject *object);
25 static void sp_svg_view_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
26 static void sp_svg_view_widget_size_request (GtkWidget *widget, GtkRequisition *req);
28 static void sp_svg_view_widget_view_resized (SPViewWidget *vw, Inkscape::UI::View::View *view, gdouble width, gdouble height);
30 static SPViewWidgetClass *widget_parent_class;
32 /**
33 * Registers SPSVGSPViewWidget class with Gtk and returns its type number.
34 */
35 GType sp_svg_view_widget_get_type(void)
36 {
37 static GType type = 0;
38 if (!type) {
39 GTypeInfo info = {
40 sizeof(SPSVGSPViewWidgetClass),
41 0, // base_init
42 0, // base_finalize
43 (GClassInitFunc)sp_svg_view_widget_class_init,
44 0, // class_finalize
45 0, // class_data
46 sizeof(SPSVGSPViewWidget),
47 0, // n_preallocs
48 (GInstanceInitFunc)sp_svg_view_widget_init,
49 0 // value_table
50 };
51 type = g_type_register_static(SP_TYPE_VIEW_WIDGET, "SPSVGSPViewWidget", &info, static_cast<GTypeFlags>(0));
52 }
53 return type;
54 }
56 /**
57 * Callback to initialize SPSVGSPViewWidget vtable.
58 */
59 static void
60 sp_svg_view_widget_class_init (SPSVGSPViewWidgetClass *klass)
61 {
62 GtkObjectClass *object_class;
63 GtkWidgetClass *widget_class;
64 SPViewWidgetClass *vw_class;
66 object_class = GTK_OBJECT_CLASS (klass);
67 widget_class = GTK_WIDGET_CLASS (klass);
68 vw_class = SP_VIEW_WIDGET_CLASS (klass);
70 widget_parent_class = (SPViewWidgetClass*)gtk_type_class (SP_TYPE_VIEW_WIDGET);
72 object_class->destroy = sp_svg_view_widget_destroy;
74 widget_class->size_allocate = sp_svg_view_widget_size_allocate;
75 widget_class->size_request = sp_svg_view_widget_size_request;
77 vw_class->view_resized = sp_svg_view_widget_view_resized;
78 }
80 /**
81 * Callback to initialize SPSVGSPViewWidget object.
82 */
83 static void
84 sp_svg_view_widget_init (SPSVGSPViewWidget *vw)
85 {
86 GtkStyle *style;
87 SPCanvasItem *parent;
89 /* Settings */
90 vw->resize = FALSE;
91 vw->maxwidth = 400.0;
92 vw->maxheight = 400.0;
94 /* ScrolledWindow */
95 vw->sw = gtk_scrolled_window_new (NULL, NULL);
96 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(vw->sw), GTK_SHADOW_NONE);
97 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (vw->sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
98 gtk_container_add (GTK_CONTAINER (vw), vw->sw);
99 gtk_widget_show (vw->sw);
101 /* Canvas */
102 gtk_widget_push_visual (gdk_rgb_get_visual ());
103 gtk_widget_push_colormap (gdk_rgb_get_cmap ());
104 vw->canvas = sp_canvas_new_aa ();
105 gtk_widget_pop_colormap ();
106 gtk_widget_pop_visual ();
107 style = gtk_style_copy (vw->canvas->style);
108 style->bg[GTK_STATE_NORMAL] = style->white;
109 gtk_widget_set_style (vw->canvas, style);
110 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (vw->sw), vw->canvas);
111 gtk_widget_show (vw->canvas);
113 /* View */
114 parent = sp_canvas_item_new (sp_canvas_root (SP_CANVAS (vw->canvas)), SP_TYPE_CANVAS_GROUP, NULL);
115 Inkscape::UI::View::View *view = Inkscape::GC::release(new SPSVGView (SP_CANVAS_GROUP (parent)));
116 sp_view_widget_set_view (SP_VIEW_WIDGET (vw), view);
117 }
119 /*
120 * Destructor callback for SPSVGSPViewWidget objects.
121 */
122 static void
123 sp_svg_view_widget_destroy (GtkObject *object)
124 {
125 SPSVGSPViewWidget *vw = SP_SVG_VIEW_WIDGET (object);
127 vw->canvas = NULL;
129 if (((GtkObjectClass *) (widget_parent_class))->destroy)
130 (* ((GtkObjectClass *) (widget_parent_class))->destroy) (object);
131 }
133 /**
134 * Callback connected with size_request signal.
135 */
136 static void
137 sp_svg_view_widget_size_request (GtkWidget *widget, GtkRequisition *req)
138 {
139 SPSVGSPViewWidget *vw = SP_SVG_VIEW_WIDGET (widget);
140 Inkscape::UI::View::View *v = SP_VIEW_WIDGET_VIEW (widget);
142 if (((GtkWidgetClass *) (widget_parent_class))->size_request)
143 (* ((GtkWidgetClass *) (widget_parent_class))->size_request) (widget, req);
145 if (v->doc()) {
146 SPSVGView *svgv;
147 GtkPolicyType hpol, vpol;
148 gdouble width, height;
150 svgv = static_cast<SPSVGView*> (v);
151 width = (v->doc())->getWidth () * svgv->_hscale;
152 height = (v->doc())->getHeight () * svgv->_vscale;
154 if (width <= vw->maxwidth) {
155 hpol = GTK_POLICY_NEVER;
156 req->width = (gint) (width + 0.5);
157 } else {
158 hpol = GTK_POLICY_AUTOMATIC;
159 req->width = (gint) (vw->maxwidth + 0.5);
160 }
161 if (height <= vw->maxheight) {
162 vpol = GTK_POLICY_NEVER;
163 req->height = (gint) (height + 8.0);
164 } else {
165 vpol = GTK_POLICY_AUTOMATIC;
166 req->height = (gint) (vw->maxheight + 2.0);
167 }
168 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (vw->sw), hpol, vpol);
169 }
170 }
172 /**
173 * Callback connected with size_allocate signal.
174 */
175 static void
176 sp_svg_view_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
177 {
178 SPSVGSPViewWidget *svgvw = SP_SVG_VIEW_WIDGET (widget);
180 if (((GtkWidgetClass *) (widget_parent_class))->size_allocate)
181 (* ((GtkWidgetClass *) (widget_parent_class))->size_allocate) (widget, allocation);
183 if (!svgvw->resize) {
184 static_cast<SPSVGView*>(SP_VIEW_WIDGET_VIEW (svgvw))->setRescale (TRUE, TRUE,
185 (gdouble) allocation->width - 1.0, (gdouble) allocation->height - 1.0);
186 }
187 }
189 /**
190 * Callback connected with view_resized signal.
191 */
192 static void
193 sp_svg_view_widget_view_resized (SPViewWidget *vw, Inkscape::UI::View::View */*view*/, gdouble width, gdouble height)
194 {
195 SPSVGSPViewWidget *svgvw = SP_SVG_VIEW_WIDGET (vw);
197 if (svgvw->resize) {
198 gtk_widget_set_size_request (svgvw->canvas, (int)width, (int)height);
199 gtk_widget_queue_resize (GTK_WIDGET (vw));
200 }
201 }
203 /**
204 * Constructs new SPSVGSPViewWidget object and returns pointer to it.
205 */
206 GtkWidget *
207 sp_svg_view_widget_new (SPDocument *doc)
208 {
209 GtkWidget *widget;
211 g_return_val_if_fail (doc != NULL, NULL);
213 widget = (GtkWidget*)gtk_type_new (SP_TYPE_SVG_VIEW_WIDGET);
215 reinterpret_cast<SPSVGView*>(SP_VIEW_WIDGET_VIEW (widget))->setDocument (doc);
217 return widget;
218 }
220 /**
221 * Flags the SPSVGSPViewWidget to have its size renegotiated with Gtk.
222 */
223 void
224 sp_svg_view_widget_set_resize (SPSVGSPViewWidget *vw, bool resize, gdouble width, gdouble height)
225 {
226 g_return_if_fail (vw != NULL);
228 g_return_if_fail (SP_IS_SVG_VIEW_WIDGET (vw));
229 g_return_if_fail (!resize || (width > 0.0));
230 g_return_if_fail (!resize || (height > 0.0));
232 vw->resize = resize;
233 vw->maxwidth = width;
234 vw->maxheight = height;
236 if (resize) {
237 gtk_widget_queue_resize (GTK_WIDGET (vw));
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 :