X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Frubberband.cpp;h=398f01d3e38e971acf40339432b8796c9326268f;hb=0dc33d4ce43e0bb49c63aa53b826ec4a1ff68e28;hp=dd16a62d841fd5b18cdfbd3703b3ea2fadd3f274;hpb=f951374eef04129c6a0d213e7ab4d9ed2095ca69;p=inkscape.git diff --git a/src/rubberband.cpp b/src/rubberband.cpp index dd16a62d8..398f01d3e 100644 --- a/src/rubberband.cpp +++ b/src/rubberband.cpp @@ -1,5 +1,3 @@ -#define __RUBBERBAND_C__ - /** * \file src/rubberband.cpp * \brief Rubberbanding selector @@ -16,60 +14,139 @@ #include "desktop.h" #include "desktop-handles.h" #include "rubberband.h" +#include "display/sp-canvas.h" +#include "display/sp-canvas-item.h" +#include "display/canvas-bpath.h" +#include "display/curve.h" Inkscape::Rubberband *Inkscape::Rubberband::_instance = NULL; -Inkscape::Rubberband::Rubberband() - : _desktop(NULL), _canvas(NULL) +Inkscape::Rubberband::Rubberband(SPDesktop *dt) + : _desktop(dt), _rect(NULL), _touchpath(NULL), _started(false) { + _points.clear(); + _mode = RUBBERBAND_MODE_RECT; + _touchpath_curve = new SPCurve(); +} +void Inkscape::Rubberband::delete_canvas_items() +{ + if (_rect) { + GtkObject *temp = _rect; + _rect = NULL; + gtk_object_destroy(temp); + } + if (_touchpath) { + GtkObject *temp = _touchpath; + _touchpath = NULL; + gtk_object_destroy(temp); + } } -void Inkscape::Rubberband::start(SPDesktop *d, NR::Point const &p) + +void Inkscape::Rubberband::start(SPDesktop *d, Geom::Point const &p) { - stop(); + _points.clear(); + _touchpath_curve->reset(); + delete_canvas_items(); _desktop = d; _start = p; + _started = true; + _points.push_back(_desktop->d2w(p)); + _touchpath_curve->moveto(p); + + sp_canvas_force_full_redraw_after_interruptions(_desktop->canvas, 5); } void Inkscape::Rubberband::stop() { - if (_canvas) { - gtk_object_destroy((GtkObject *) _canvas); - _canvas = NULL; - } + _started = false; + _mode = RUBBERBAND_MODE_RECT; // restore the default + + _points.clear(); + _touchpath_curve->reset(); + + delete_canvas_items(); + + if (_desktop) + sp_canvas_end_forced_full_redraws(_desktop->canvas); } -void Inkscape::Rubberband::move(NR::Point const &p) +void Inkscape::Rubberband::move(Geom::Point const &p) { - if (_canvas == NULL) { - _canvas = static_cast(sp_canvas_item_new(SP_DT_CONTROLS(_desktop), SP_TYPE_CTRLRECT, NULL)); - } + if (!_started) + return; - _desktop->scroll_to_point(&p); _end = p; + _desktop->scroll_to_point(p); + _touchpath_curve->lineto(p); - _canvas->setRectangle(NR::Rect(_start, _end)); + Geom::Point next = _desktop->d2w(p); + // we want the points to be at most 0.5 screen pixels apart, + // so that we don't lose anything small; + // if they are farther apart, we interpolate more points + if (_points.size() > 0 && Geom::L2(next-_points.back()) > 0.5) { + Geom::Point prev = _points.back(); + int subdiv = 2 * (int) round(Geom::L2(next-prev) + 0.5); + for (int i = 1; i <= subdiv; i ++) { + _points.push_back(prev + ((double)i/subdiv) * (next - prev)); + } + } else { + _points.push_back(next); + } + + if (_mode == RUBBERBAND_MODE_RECT) { + if (_rect == NULL) { + _rect = static_cast(sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRLRECT, NULL)); + } + _rect->setRectangle(Geom::Rect(_start, _end)); + + sp_canvas_item_show(_rect); + if (_touchpath) + sp_canvas_item_hide(_touchpath); + + } else if (_mode == RUBBERBAND_MODE_TOUCHPATH) { + if (_touchpath == NULL) { + _touchpath = sp_canvas_bpath_new(sp_desktop_sketch(_desktop), NULL); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(_touchpath), 0xff0000ff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(_touchpath), 0, SP_WIND_RULE_NONZERO); + } + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(_touchpath), _touchpath_curve); + + sp_canvas_item_show(_touchpath); + if (_rect) + sp_canvas_item_hide(_rect); + } } -NR::Maybe Inkscape::Rubberband::getRectangle() const +void Inkscape::Rubberband::setMode(int mode) { - if (_canvas == NULL) { - return NR::Nothing(); + _mode = mode; +} + +Geom::OptRect Inkscape::Rubberband::getRectangle() const +{ + if (!_started) { + return Geom::OptRect(); } - return NR::Rect(_start, _end); + return Geom::Rect(_start, _end); } -Inkscape::Rubberband *Inkscape::Rubberband::get() +Inkscape::Rubberband *Inkscape::Rubberband::get(SPDesktop *desktop) { if (_instance == NULL) { - _instance = new Inkscape::Rubberband; + _instance = new Inkscape::Rubberband(desktop); } return _instance; } +bool Inkscape::Rubberband::is_started() +{ + return _started; +} + /* Local Variables: mode:c++ @@ -79,4 +156,4 @@ Inkscape::Rubberband *Inkscape::Rubberband::get() fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :