Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / svg-view.cpp
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  *   Jon A. Cruz <jon@joncruz.org>
8  *   Abhishek Sharma
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 "display/canvas-arena.h"
17 #include "display/display-forward.h"
18 #include "document.h"
19 #include "sp-item.h"
20 #include "svg-view.h"
23 /**
24  * Constructs new SPSVGView object and returns pointer to it.
25  */
26 SPSVGView::SPSVGView (SPCanvasGroup *parent)
27 {
28     _hscale = 1.0;
29     _vscale = 1.0;
30     _rescale = FALSE;
31     _keepaspect = FALSE;
32     _width = 0.0;
33     _height = 0.0;
35     _dkey = 0;
36     _drawing = 0;
37     _parent = parent;
38 }
40 SPSVGView::~SPSVGView()
41 {
42     if (doc() && _drawing)
43     {
44         SP_ITEM( doc()->getRoot() )->invoke_hide(_dkey);
45         _drawing = NULL;
46     }
47 }
49 /**
50  * Rescales SPSVGView to given proportions.
51  */
52 void
53 SPSVGView::setScale (gdouble hscale, gdouble vscale)
54 {
55     if (!_rescale && ((hscale != _hscale) || (vscale != _vscale))) {
56         _hscale = hscale;
57         _vscale = vscale;
58         doRescale (true);
59     }
60 }
62 /**
63  * Rescales SPSVGView and keeps aspect ratio.
64  */
65 void
66 SPSVGView::setRescale
67 (bool rescale, bool keepaspect, gdouble width, gdouble height)
68 {
69     g_return_if_fail (!rescale || (width >= 0.0));
70     g_return_if_fail (!rescale || (height >= 0.0));
72     _rescale = rescale;
73     _keepaspect = keepaspect;
74     _width = width;
75     _height = height;
77     doRescale (true);
78 }
80 /**
81  * Helper function that sets rescale ratio and emits resize event.
82  */
83 void
84 SPSVGView::doRescale (bool event)
85 {
86     if (!doc()) return;
87     if (doc()->getWidth () < 1e-9) return;
88     if (doc()->getHeight () < 1e-9) return;
90     if (_rescale) {
91         _hscale = _width / doc()->getWidth ();
92         _vscale = _height / doc()->getHeight ();
93         if (_keepaspect) {
94             if (_hscale > _vscale) {
95                 _hscale = _vscale;
96                 } else {
97                     _vscale = _hscale;
98                 }
99         }
100     }
102     if (_drawing) {
103         sp_canvas_item_affine_absolute (_drawing, Geom::Scale(_hscale, _vscale));
104     }
106     if (event) {
107         emitResized (doc()->getWidth () * _hscale,
108                 doc()->getHeight () * _vscale);
109     }
112 void
113 SPSVGView::mouseover()
115     GdkCursor *cursor = gdk_cursor_new(GDK_HAND2);
116     gdk_window_set_cursor(GTK_WIDGET(SP_CANVAS_ITEM(_drawing)->canvas)->window, cursor);
117     gdk_cursor_unref(cursor);
120 void
121 SPSVGView::mouseout()
123     gdk_window_set_cursor(GTK_WIDGET(SP_CANVAS_ITEM(_drawing)->canvas)->window, NULL);
126 //----------------------------------------------------------------
127 /**
128  * Callback connected with arena_event.
129  */
130 /// \todo fixme.
131 static gint
132 arena_handler (SPCanvasArena */*arena*/, NRArenaItem *ai, GdkEvent *event, SPSVGView *svgview)
134         static gdouble x, y;
135         static gboolean active = FALSE;
136         SPEvent spev;
138         SPItem *spitem = (ai) ? (SPItem*)NR_ARENA_ITEM_GET_DATA (ai) : 0;
140         switch (event->type) {
141         case GDK_BUTTON_PRESS:
142                 if (event->button.button == 1) {
143                         active = TRUE;
144                         x = event->button.x;
145                         y = event->button.y;
146                 }
147                 break;
148         case GDK_BUTTON_RELEASE:
149                 if (event->button.button == 1) {
150                         if (active && (event->button.x == x) &&
151                                       (event->button.y == y)) {
152                                 spev.type = SP_EVENT_ACTIVATE;
153                                 if ( spitem != 0 )
154                                 {
155                                   spitem->emitEvent (spev);
156                                 }
157                         }
158                 }
159                 active = FALSE;
160                 break;
161         case GDK_MOTION_NOTIFY:
162                 active = FALSE;
163                 break;
164         case GDK_ENTER_NOTIFY:
165                 spev.type = SP_EVENT_MOUSEOVER;
166                 spev.data = svgview;
167                 if ( spitem != 0 )
168                 {
169                   spitem->emitEvent (spev);
170                 }
171                 break;
172         case GDK_LEAVE_NOTIFY:
173                 spev.type = SP_EVENT_MOUSEOUT;
174                 spev.data = svgview;
175                 if ( spitem != 0 )
176                 {
177                   spitem->emitEvent (spev);
178                 }
179                 break;
180         default:
181                 break;
182         }
184         return TRUE;
187 /**
188  * Callback connected with set_document signal.
189  */
190 void
191 SPSVGView::setDocument (SPDocument *document)
193     if (doc()) {
194         SP_ITEM( doc()->getRoot() )->invoke_hide(_dkey);
195     }
197     if (!_drawing) {
198         _drawing = sp_canvas_item_new (_parent, SP_TYPE_CANVAS_ARENA, NULL);
199         g_signal_connect (G_OBJECT (_drawing), "arena_event", G_CALLBACK (arena_handler), this);
200     }
202     if (document) {
203         NRArenaItem *ai = SP_ITEM( document->getRoot() )->invoke_show(
204                 SP_CANVAS_ARENA (_drawing)->arena,
205                 _dkey,
206                 SP_ITEM_SHOW_DISPLAY);
208         if (ai) {
209             nr_arena_item_add_child (SP_CANVAS_ARENA (_drawing)->root, ai, NULL);
210         }
212         doRescale (!_rescale);
213     }
215     View::setDocument (document);
218 /**
219  * Callback connected with document_resized signal.
220  */
221 void
222 SPSVGView::onDocumentResized (gdouble width, gdouble height)
224     setScale (width, height);
225     doRescale (!_rescale);
229 /*
230   Local Variables:
231   mode:c++
232   c-file-style:"stroustrup"
233   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
234   indent-tabs-mode:nil
235   fill-column:99
236   End:
237 */
238 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :