summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorbulia byak <buliabyak@gmail.com>2007-04-12 07:20:37 +0000
committerbuliabyak <buliabyak@users.sourceforge.net>2007-04-12 07:20:37 +0000
commitbf913ea3e95443e8e43d9f30e9a3a1efa9cae79a (patch)
treeebbe20b03cee40bd28cb0593a110a4eab5b2f6af /src
parentUse the existing Inkscape::Event instead of creating a new one (and (diff)
downloadinkscape-bf913ea3e95443e8e43d9f30e9a3a1efa9cae79a.tar.gz
inkscape-bf913ea3e95443e8e43d9f30e9a3a1efa9cae79a.zip
add touchpath mode
(bzr r2863)
Diffstat (limited to 'src')
-rw-r--r--src/rubberband.cpp93
-rw-r--r--src/rubberband.h24
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<CtrlRect *>(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<CtrlRect *>(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<NR::Rect> 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 <vector>
/* 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<NR::Point> 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<NR::Point> _points;
+
+ CtrlRect *_rect;
+ SPCanvasItem *_touchpath;
+ SPCurve *_touchpath_curve;
+
+ void delete_canvas_items();
+
bool _started;
+ int _mode;
};
}