Code

Split SPCanvasItem and SPCanvasGroup to individual .h files. Removed forward header.
[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 "document.h"
18 #include "sp-item.h"
19 #include "svg-view.h"
22 /**
23  * Constructs new SPSVGView object and returns pointer to it.
24  */
25 SPSVGView::SPSVGView (SPCanvasGroup *parent)
26 {
27     _hscale = 1.0;
28     _vscale = 1.0;
29     _rescale = FALSE;
30     _keepaspect = FALSE;
31     _width = 0.0;
32     _height = 0.0;
34     _dkey = 0;
35     _drawing = 0;
36     _parent = parent;
37 }
39 SPSVGView::~SPSVGView()
40 {
41     if (doc() && _drawing)
42     {
43         SP_ITEM( doc()->getRoot() )->invoke_hide(_dkey);
44         _drawing = NULL;
45     }
46 }
48 /**
49  * Rescales SPSVGView to given proportions.
50  */
51 void
52 SPSVGView::setScale (gdouble hscale, gdouble vscale)
53 {
54     if (!_rescale && ((hscale != _hscale) || (vscale != _vscale))) {
55         _hscale = hscale;
56         _vscale = vscale;
57         doRescale (true);
58     }
59 }
61 /**
62  * Rescales SPSVGView and keeps aspect ratio.
63  */
64 void
65 SPSVGView::setRescale
66 (bool rescale, bool keepaspect, gdouble width, gdouble height)
67 {
68     g_return_if_fail (!rescale || (width >= 0.0));
69     g_return_if_fail (!rescale || (height >= 0.0));
71     _rescale = rescale;
72     _keepaspect = keepaspect;
73     _width = width;
74     _height = height;
76     doRescale (true);
77 }
79 /**
80  * Helper function that sets rescale ratio and emits resize event.
81  */
82 void
83 SPSVGView::doRescale (bool event)
84 {
85     if (!doc()) return;
86     if (doc()->getWidth () < 1e-9) return;
87     if (doc()->getHeight () < 1e-9) return;
89     if (_rescale) {
90         _hscale = _width / doc()->getWidth ();
91         _vscale = _height / doc()->getHeight ();
92         if (_keepaspect) {
93             if (_hscale > _vscale) {
94                 _hscale = _vscale;
95                 } else {
96                     _vscale = _hscale;
97                 }
98         }
99     }
101     if (_drawing) {
102         sp_canvas_item_affine_absolute (_drawing, Geom::Scale(_hscale, _vscale));
103     }
105     if (event) {
106         emitResized (doc()->getWidth () * _hscale,
107                 doc()->getHeight () * _vscale);
108     }
111 void
112 SPSVGView::mouseover()
114     GdkCursor *cursor = gdk_cursor_new(GDK_HAND2);
115     gdk_window_set_cursor(GTK_WIDGET(SP_CANVAS_ITEM(_drawing)->canvas)->window, cursor);
116     gdk_cursor_unref(cursor);
119 void
120 SPSVGView::mouseout()
122     gdk_window_set_cursor(GTK_WIDGET(SP_CANVAS_ITEM(_drawing)->canvas)->window, NULL);
125 //----------------------------------------------------------------
126 /**
127  * Callback connected with arena_event.
128  */
129 /// \todo fixme.
130 static gint
131 arena_handler (SPCanvasArena */*arena*/, NRArenaItem *ai, GdkEvent *event, SPSVGView *svgview)
133         static gdouble x, y;
134         static gboolean active = FALSE;
135         SPEvent spev;
137         SPItem *spitem = (ai) ? (SPItem*)NR_ARENA_ITEM_GET_DATA (ai) : 0;
139         switch (event->type) {
140         case GDK_BUTTON_PRESS:
141                 if (event->button.button == 1) {
142                         active = TRUE;
143                         x = event->button.x;
144                         y = event->button.y;
145                 }
146                 break;
147         case GDK_BUTTON_RELEASE:
148                 if (event->button.button == 1) {
149                         if (active && (event->button.x == x) &&
150                                       (event->button.y == y)) {
151                                 spev.type = SP_EVENT_ACTIVATE;
152                                 if ( spitem != 0 )
153                                 {
154                                   spitem->emitEvent (spev);
155                                 }
156                         }
157                 }
158                 active = FALSE;
159                 break;
160         case GDK_MOTION_NOTIFY:
161                 active = FALSE;
162                 break;
163         case GDK_ENTER_NOTIFY:
164                 spev.type = SP_EVENT_MOUSEOVER;
165                 spev.data = svgview;
166                 if ( spitem != 0 )
167                 {
168                   spitem->emitEvent (spev);
169                 }
170                 break;
171         case GDK_LEAVE_NOTIFY:
172                 spev.type = SP_EVENT_MOUSEOUT;
173                 spev.data = svgview;
174                 if ( spitem != 0 )
175                 {
176                   spitem->emitEvent (spev);
177                 }
178                 break;
179         default:
180                 break;
181         }
183         return TRUE;
186 /**
187  * Callback connected with set_document signal.
188  */
189 void
190 SPSVGView::setDocument (SPDocument *document)
192     if (doc()) {
193         SP_ITEM( doc()->getRoot() )->invoke_hide(_dkey);
194     }
196     if (!_drawing) {
197         _drawing = sp_canvas_item_new (_parent, SP_TYPE_CANVAS_ARENA, NULL);
198         g_signal_connect (G_OBJECT (_drawing), "arena_event", G_CALLBACK (arena_handler), this);
199     }
201     if (document) {
202         NRArenaItem *ai = SP_ITEM( document->getRoot() )->invoke_show(
203                 SP_CANVAS_ARENA (_drawing)->arena,
204                 _dkey,
205                 SP_ITEM_SHOW_DISPLAY);
207         if (ai) {
208             nr_arena_item_add_child (SP_CANVAS_ARENA (_drawing)->root, ai, NULL);
209         }
211         doRescale (!_rescale);
212     }
214     View::setDocument (document);
217 /**
218  * Callback connected with document_resized signal.
219  */
220 void
221 SPSVGView::onDocumentResized (gdouble width, gdouble height)
223     setScale (width, height);
224     doRescale (!_rescale);
228 /*
229   Local Variables:
230   mode:c++
231   c-file-style:"stroustrup"
232   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
233   indent-tabs-mode:nil
234   fill-column:99
235   End:
236 */
237 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :