Code

Split SPCanvasItem and SPCanvasGroup to individual .h files. Removed forward header.
[inkscape.git] / src / rubberband.cpp
1 /**
2  * \file src/rubberband.cpp
3  * \brief Rubberbanding selector
4  *
5  * Author:
6  *   Lauris Kaplinski <lauris@kaplinski.com>
7  *
8  * Copyright (C) 1999-2002 Lauris Kaplinski
9  *
10  * Released under GNU GPL, read the file 'COPYING' for more information
11  */
13 #include "display/sodipodi-ctrlrect.h"
14 #include "desktop.h"
15 #include "desktop-handles.h"
16 #include "rubberband.h"
17 #include "display/sp-canvas.h"
18 #include "display/sp-canvas-item.h"
19 #include "display/canvas-bpath.h"
20 #include "display/curve.h"
22 Inkscape::Rubberband *Inkscape::Rubberband::_instance = NULL;
24 Inkscape::Rubberband::Rubberband(SPDesktop *dt)
25     : _desktop(dt), _rect(NULL), _touchpath(NULL), _started(false)
26 {
27     _points.clear();
28     _mode = RUBBERBAND_MODE_RECT;
29     _touchpath_curve = new SPCurve();
30 }
32 void Inkscape::Rubberband::delete_canvas_items()
33 {
34     if (_rect) {
35         GtkObject *temp = _rect;
36         _rect = NULL;
37         gtk_object_destroy(temp);
38     }
39     if (_touchpath) {
40         GtkObject *temp = _touchpath;
41         _touchpath = NULL;
42         gtk_object_destroy(temp);
43     }
44 }
47 void Inkscape::Rubberband::start(SPDesktop *d, Geom::Point const &p)
48 {
49     _points.clear();
50     _touchpath_curve->reset();
51     delete_canvas_items();
52     _desktop = d;
53     _start = p;
54     _started = true;
55     _points.push_back(_desktop->d2w(p));
56     _touchpath_curve->moveto(p);
58     sp_canvas_force_full_redraw_after_interruptions(_desktop->canvas, 5);
59 }
61 void Inkscape::Rubberband::stop()
62 {
63     _started = false;
64     _mode = RUBBERBAND_MODE_RECT; // restore the default
66     _points.clear();
67     _touchpath_curve->reset();
69     delete_canvas_items();
71     if (_desktop)
72         sp_canvas_end_forced_full_redraws(_desktop->canvas);
73 }
75 void Inkscape::Rubberband::move(Geom::Point const &p)
76 {
77     if (!_started) 
78         return;
80     _end = p;
81     _desktop->scroll_to_point(p);
82     _touchpath_curve->lineto(p);
84     Geom::Point next = _desktop->d2w(p);
85     // we want the points to be at most 0.5 screen pixels apart,
86     // so that we don't lose anything small;
87     // if they are farther apart, we interpolate more points
88     if (_points.size() > 0 && Geom::L2(next-_points.back()) > 0.5) {
89         Geom::Point prev = _points.back();
90         int subdiv = 2 * (int) round(Geom::L2(next-prev) + 0.5);
91         for (int i = 1; i <= subdiv; i ++) {
92             _points.push_back(prev + ((double)i/subdiv) * (next - prev));
93         }
94     } else {
95         _points.push_back(next);
96     }
98     if (_mode == RUBBERBAND_MODE_RECT) {
99         if (_rect == NULL) {
100             _rect = static_cast<CtrlRect *>(sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRLRECT, NULL));
101         }
102         _rect->setRectangle(Geom::Rect(_start, _end));
104         sp_canvas_item_show(_rect);
105         if (_touchpath)
106             sp_canvas_item_hide(_touchpath);
108     } else if (_mode == RUBBERBAND_MODE_TOUCHPATH) {
109         if (_touchpath == NULL) {
110             _touchpath = sp_canvas_bpath_new(sp_desktop_sketch(_desktop), NULL);
111             sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(_touchpath), 0xff0000ff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
112             sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(_touchpath), 0, SP_WIND_RULE_NONZERO);
113         }
114         sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(_touchpath), _touchpath_curve);
116         sp_canvas_item_show(_touchpath);
117         if (_rect)
118             sp_canvas_item_hide(_rect);
119     }
122 void Inkscape::Rubberband::setMode(int mode) 
124     _mode = mode;
127 Geom::OptRect Inkscape::Rubberband::getRectangle() const
129     if (!_started) {
130         return Geom::OptRect();
131     }
133     return Geom::Rect(_start, _end);
136 Inkscape::Rubberband *Inkscape::Rubberband::get(SPDesktop *desktop)
138     if (_instance == NULL) {
139         _instance = new Inkscape::Rubberband(desktop);
140     }
142     return _instance;
145 bool Inkscape::Rubberband::is_started()
147     return _started;
150 /*
151   Local Variables:
152   mode:c++
153   c-file-style:"stroustrup"
154   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
155   indent-tabs-mode:nil
156   fill-column:99
157   End:
158 */
159 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :