From 641ff38fd1641391fdda1b92fb2ce2e5ec3d3e0c Mon Sep 17 00:00:00 2001 From: buliabyak Date: Thu, 12 Apr 2007 07:20:37 +0000 Subject: [PATCH] add touchpath mode --- src/rubberband.cpp | 93 +++++++++++++++++++++++++++++++++++++++------- src/rubberband.h | 24 +++++++++++- 2 files changed, 102 insertions(+), 15 deletions(-) diff --git a/src/rubberband.cpp b/src/rubberband.cpp index 0de3cd763..a16212379 100644 --- a/src/rubberband.cpp +++ b/src/rubberband.cpp @@ -17,21 +17,45 @@ #include "inkscape.h" #include "desktop-handles.h" #include "rubberband.h" +#include "display/canvas-bpath.h" +#include "display/curve.h" +#include "libnr/nr-point.h" Inkscape::Rubberband *Inkscape::Rubberband::_instance = NULL; Inkscape::Rubberband::Rubberband() - : _desktop(SP_ACTIVE_DESKTOP), _canvas(NULL), _started(false) + : _desktop(SP_ACTIVE_DESKTOP), _rect(NULL), _touchpath(NULL), _started(false) { + _points.clear(); + _mode = RUBBERBAND_MODE_RECT; + _touchpath_curve = sp_curve_new_sized(2000); +} +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) { - stop(); + _points.clear(); + sp_curve_reset(_touchpath_curve); + delete_canvas_items(); _desktop = d; _start = p; _started = true; + _points.push_back(_desktop->d2w(p)); + sp_curve_moveto(_touchpath_curve, p); sp_canvas_force_full_redraw_after_interruptions(_desktop->canvas, 5); } @@ -39,30 +63,71 @@ void Inkscape::Rubberband::start(SPDesktop *d, NR::Point const &p) void Inkscape::Rubberband::stop() { _started = false; + _mode = RUBBERBAND_MODE_RECT; // restore the default - if (_canvas) { - GtkObject *temp = _canvas; - _canvas = NULL; - gtk_object_destroy(temp); - sp_canvas_end_forced_full_redraws(_desktop->canvas); - } + _points.clear(); + sp_curve_reset(_touchpath_curve); + + delete_canvas_items(); + + sp_canvas_end_forced_full_redraws(_desktop->canvas); } void Inkscape::Rubberband::move(NR::Point const &p) { - if (_canvas == NULL) { - _canvas = static_cast(sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRLRECT, NULL)); - } + if (!_started) + return; - _desktop->scroll_to_point(&p); _end = p; + _desktop->scroll_to_point(&p); + sp_curve_lineto (_touchpath_curve, p); + + NR::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 && NR::L2(next-_points.back()) > 0.5) { + NR::Point prev = _points.back(); + int subdiv = 2 * (int) round(NR::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); + } - _canvas->setRectangle(NR::Rect(_start, _end)); + 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(NR::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); + } +} + +void Inkscape::Rubberband::setMode(int mode) +{ + _mode = mode; } NR::Maybe Inkscape::Rubberband::getRectangle() const { - if (_canvas == NULL) { + if (!_started) { return NR::Nothing(); } diff --git a/src/rubberband.h b/src/rubberband.h index 36e9c4d8e..b6ef1984e 100644 --- a/src/rubberband.h +++ b/src/rubberband.h @@ -18,10 +18,18 @@ #include "libnr/nr-forward.h" #include "libnr/nr-point.h" #include "libnr/nr-maybe.h" +#include /* fixme: do multidocument safe */ class CtrlRect; +class SPCanvasItem; +class SPCurve; + +enum { + RUBBERBAND_MODE_RECT, + RUBBERBAND_MODE_TOUCHPATH +}; namespace Inkscape { @@ -36,6 +44,11 @@ public: void stop(); bool is_started(); + inline int getMode() {return _mode;} + inline std::vector getPoints() {return _points;} + + void setMode(int mode); + static Rubberband* get(); private: @@ -46,8 +59,17 @@ private: SPDesktop *_desktop; NR::Point _start; NR::Point _end; - CtrlRect *_canvas; + + std::vector _points; + + CtrlRect *_rect; + SPCanvasItem *_touchpath; + SPCurve *_touchpath_curve; + + void delete_canvas_items(); + bool _started; + int _mode; }; } -- 2.30.2