From: dvlierop2 Date: Sun, 15 Feb 2009 20:30:42 +0000 (+0000) Subject: After snapping, show a tooltip together with the snap indicator X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=995ec331afc69a2e82dac045e5f8749a4bc6d65e;p=inkscape.git After snapping, show a tooltip together with the snap indicator --- diff --git a/src/display/snap-indicator.cpp b/src/display/snap-indicator.cpp index 98358dbab..1785da7b9 100644 --- a/src/display/snap-indicator.cpp +++ b/src/display/snap-indicator.cpp @@ -5,8 +5,8 @@ * Johan Engelen * Diederik van Lierop * - * Copyright (C) Johan Engelen 2008 - * Copyright (C) Diederik van Lierop 2008 + * Copyright (C) Johan Engelen 2009 + * Copyright (C) Diederik van Lierop 2009 * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -18,6 +18,8 @@ #include "display/sodipodi-ctrl.h" #include "knot.h" #include "preferences.h" +#include +#include namespace Inkscape { namespace Display { @@ -53,48 +55,94 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const p) bool value = prefs->getBool("/options/snapindicator/value", true); if (value) { - SPCanvasItem * canvasitem = NULL; + gchar *target_name = _("UNDEFINED"); switch (p.getTarget()) { - /// @todo add the different kinds of snapindicator visuals - case SNAPTARGET_NODE: - canvasitem = sp_canvas_item_new(sp_desktop_tempgroup (_desktop), - SP_TYPE_CTRL, - "anchor", GTK_ANCHOR_CENTER, - "size", 10.0, - "stroked", TRUE, - "stroke_color", 0xf000f0ff, - "mode", SP_KNOT_MODE_XOR, - "shape", SP_KNOT_SHAPE_DIAMOND, - NULL ); - break; - case SNAPTARGET_GRID: + case SNAPTARGET_UNDEFINED: + target_name = _("UNDEFINED"); + break; + case SNAPTARGET_GRID: + target_name = _("grid line"); + break; case SNAPTARGET_GRID_INTERSECTION: + target_name = _("grid intersection"); + break; case SNAPTARGET_GUIDE: + target_name = _("guide"); + break; case SNAPTARGET_GUIDE_INTERSECTION: + target_name = _("guide intersection"); + break; case SNAPTARGET_GRID_GUIDE_INTERSECTION: - case SNAPTARGET_PATH: + target_name = _("grid-guide intersection"); + break; + case SNAPTARGET_NODE: + target_name = _("node"); + break; + case SNAPTARGET_PATH: + target_name = _("path"); + break; case SNAPTARGET_PATH_INTERSECTION: + target_name = _("path intersection"); + break; case SNAPTARGET_BBOX_CORNER: + target_name = _("bounding box corner"); + break; case SNAPTARGET_BBOX_EDGE: + target_name = _("bounding box side"); + break; case SNAPTARGET_GRADIENT: - case SNAPTARGET_UNDEFINED: + target_name = _("gradient"); + break; + case SNAPTARGET_PAGE_BORDER: + target_name = _("page border"); + break; default: - canvasitem = sp_canvas_item_new(sp_desktop_tempgroup (_desktop), - SP_TYPE_CTRL, - "anchor", GTK_ANCHOR_CENTER, - "size", 10.0, - "stroked", TRUE, - "stroke_color", 0xf000f0ff, - "mode", SP_KNOT_MODE_XOR, - "shape", SP_KNOT_SHAPE_CROSS, - NULL ); + g_warning("Snap target has not yet been defined!"); break; } + // std::cout << "Snapped to: " << target_name << std::endl; - SP_CTRL(canvasitem)->moveto(p.getPoint()); - remove_snapsource(); // Don't set both the source and target indicators, as these will overlap - _snaptarget = _desktop->add_temporary_canvasitem(canvasitem, 1000); // TODO add preference for snap indicator timeout - } + // Display the snap indicator (i.e. the cross) + SPCanvasItem * canvasitem = NULL; + if (p.getTarget() == SNAPTARGET_NODE) { + canvasitem = sp_canvas_item_new(sp_desktop_tempgroup (_desktop), + SP_TYPE_CTRL, + "anchor", GTK_ANCHOR_CENTER, + "size", 10.0, + "stroked", TRUE, + "stroke_color", 0xf000f0ff, + "mode", SP_KNOT_MODE_XOR, + "shape", SP_KNOT_SHAPE_DIAMOND, + NULL ); + } else { + canvasitem = sp_canvas_item_new(sp_desktop_tempgroup (_desktop), + SP_TYPE_CTRL, + "anchor", GTK_ANCHOR_CENTER, + "size", 10.0, + "stroked", TRUE, + "stroke_color", 0xf000f0ff, + "mode", SP_KNOT_MODE_XOR, + "shape", SP_KNOT_SHAPE_CROSS, + NULL ); + } + + const int timeout_val = 1000; // TODO add preference for snap indicator timeout? + + SP_CTRL(canvasitem)->moveto(p.getPoint()); + remove_snapsource(); // Don't set both the source and target indicators, as these will overlap + _snaptarget = _desktop->add_temporary_canvasitem(canvasitem, timeout_val); + + // Display the tooltip + GtkSettings *settings = gtk_widget_get_settings (&(_desktop->canvas->widget)); + // If we set the timeout too short, then the tooltip might not show at all (most noticeable when a long snap delay is active) + g_object_set(settings, "gtk-tooltip-timeout", 200, NULL); // tooltip will be shown after x msec. + gtk_widget_set_tooltip_text(&(_desktop->canvas->widget), target_name); + // has_tooltip will be true by now because gtk_widget_set_has_tooltip() has been called implicitly + update_tooltip(); + // The snap indicator will be removed automatically because it's a temporary canvas item; the tooltip + // however must be removed manually, so we'll create a timer to that end + Glib::signal_timeout().connect(sigc::mem_fun(*this, &SnapIndicator::remove_tooltip), timeout_val); + } } void @@ -104,6 +152,8 @@ SnapIndicator::remove_snaptarget() _desktop->remove_temporary_canvasitem(_snaptarget); _snaptarget = NULL; } + + remove_tooltip(); } void @@ -141,11 +191,46 @@ SnapIndicator::remove_snapsource() } } +// Shows or hides the tooltip +void SnapIndicator::update_tooltip() const +{ + // When using gtk_widget_trigger_tooltip_query, the tooltip will for some reason always popup + // in the upper-left corner of the screen (probably at (0,0)). As a workaround we'll create + // a motion event instead, which will also trigger the tooltip + gint x, y; + GdkWindow *window; + + GdkDisplay *display = gdk_display_get_default(); + window = gdk_display_get_window_at_pointer(display, &x, &y); + if (window) { + GdkEvent *event = gdk_event_new(GDK_MOTION_NOTIFY); + event->motion.window = window; + event->motion.x = x; + event->motion.y = y; + event->motion.is_hint = FALSE; + + gdk_window_get_origin(window, &x, &y); + event->motion.x_root = event->motion.x + x; + event->motion.y_root = event->motion.y + y; + + gtk_main_do_event(event); + } +} + +// Can be called either directly or through a timer +bool +SnapIndicator::remove_tooltip() const +{ + gtk_widget_set_has_tooltip (&(_desktop->canvas->widget), false); + gtk_widget_trigger_tooltip_query(&(_desktop->canvas->widget)); + return false; +} } //namespace Display } /* namespace Inkscape */ + /* Local Variables: mode:c++ diff --git a/src/display/snap-indicator.h b/src/display/snap-indicator.h index d2c6dba8e..672d2e78c 100644 --- a/src/display/snap-indicator.h +++ b/src/display/snap-indicator.h @@ -28,10 +28,10 @@ public: void set_new_snaptarget(Inkscape::SnappedPoint const p); void remove_snaptarget(); - + void set_new_snapsource(Geom::Point const p); void remove_snapsource(); - + protected: TemporaryItem *_snaptarget; TemporaryItem *_snapsource; @@ -40,6 +40,8 @@ protected: private: SnapIndicator(const SnapIndicator&); SnapIndicator& operator=(const SnapIndicator&); + void update_tooltip() const; + bool remove_tooltip() const; }; } //namespace Display diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index edd64f021..141e10611 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -938,6 +938,7 @@ static gint sp_canvas_key (GtkWidget *widget, GdkEventKey *event); static gint sp_canvas_crossing (GtkWidget *widget, GdkEventCrossing *event); static gint sp_canvas_focus_in (GtkWidget *widget, GdkEventFocus *event); static gint sp_canvas_focus_out (GtkWidget *widget, GdkEventFocus *event); +static gboolean sp_canvas_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip); static GtkWidgetClass *canvas_parent_class; @@ -1050,6 +1051,8 @@ sp_canvas_init (SPCanvas *canvas) canvas->watchdog_id = 0; canvas->watchdog_event = NULL; canvas->context_snap_delay_active = false; + + g_signal_connect(&(canvas->widget), "query-tooltip", G_CALLBACK (sp_canvas_query_tooltip), NULL); } /** @@ -1609,20 +1612,19 @@ sp_canvas_motion (GtkWidget *widget, GdkEventMotion *event) SPDesktop *dt = SP_ACTIVE_DESKTOP; - // Snap when speed drops below e.g. 0.02 px/msec, or when no motion events have occured for some period. - // i.e. snap when we're at stand still. A speed threshold enforces snapping for tablets, which might never - // be fully at stand still and might keep spitting out motion events. - if (canvas->context_snap_delay_active && dt && dt->namedview->snap_manager.snapprefs.getSnapEnabledGlobally()) { - Geom::Point event_pos(event->x, event->y); - guint32 event_t = gdk_event_get_time ( (GdkEvent *) event ); - + if (canvas->context_snap_delay_active && dt && dt->namedview->snap_manager.snapprefs.getSnapEnabledGlobally()) { + // Snap when speed drops below e.g. 0.02 px/msec, or when no motion events have occurred for some period. + // i.e. snap when we're at stand still. A speed threshold enforces snapping for tablets, which might never + // be fully at stand still and might keep spitting out motion events. dt->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(true); // put snapping on hold + Geom::Point event_pos(event->x, event->y); + guint32 event_t = gdk_event_get_time ( (GdkEvent *) event ); + if (prev_pos) { Geom::Coord dist = Geom::L2(event_pos - *prev_pos); guint32 delta_t = event_t - prev_time; gdouble speed = delta_t > 0 ? dist/delta_t : 1000; - // std::cout << "speed = " << speed << " px/msec " << "| time passed = " << delta_t << " msec" << std::endl; if (speed > 0.02) { // Jitter threshold, might be needed for tablets // We're moving fast, so postpone any snapping until the next GDK_MOTION_NOTIFY event. We // will keep on postponing the snapping as long as the speed is high. @@ -1654,13 +1656,11 @@ sp_canvas_motion (GtkWidget *widget, GdkEventMotion *event) } canvas->state = event->state; - pick_current_item (canvas, (GdkEvent *) event); - - status = emit_event (canvas, (GdkEvent *) event); - - if (event->is_hint) { - request_motions(widget->window, event); - } + pick_current_item (canvas, (GdkEvent *) event); + status = emit_event (canvas, (GdkEvent *) event); + if (event->is_hint) { + request_motions(widget->window, event); + } return status; } @@ -1670,6 +1670,7 @@ gboolean sp_canvas_snap_watchdog_callback(gpointer data) // Snap NOW! For this the "postponed" flag will be reset and an the last motion event will be repeated SPCanvas *canvas = reinterpret_cast(data); if (!canvas->watchdog_event) { + // This might occur when this method is called directly, i.e. not through the timer return FALSE; } @@ -2164,6 +2165,26 @@ sp_canvas_focus_out (GtkWidget *widget, GdkEventFocus *event) return FALSE; } + +static gboolean sp_canvas_query_tooltip (GtkWidget *widget, + gint x, + gint y, + gboolean keyboard_mode, + GtkTooltip *tooltip) +{ + // We're not really doing anything special here, so we might just as well remove sp_canvas_query_tooltip + // all together (and stop listening to the query_tooltip signal. We might make a custom tooltip however + // someday, for example to display icons instead of just plain text. In that case we will need this call + // so that's why I'm leaving it here for the time being. + + if (canvas_parent_class->query_tooltip) { + return canvas_parent_class->query_tooltip (widget, x, y, keyboard_mode, tooltip); + } + + return false; +} + + /** * Helper that repaints the areas in the canvas that need it. * diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp index 7b4a989a8..515008964 100644 --- a/src/object-snapper.cpp +++ b/src/object-snapper.cpp @@ -48,7 +48,7 @@ Inkscape::ObjectSnapper::ObjectSnapper(SnapManager *sm, Geom::Coord const d) { _candidates = new std::vector; _points_to_snap_to = new std::vector; - _paths_to_snap_to = new std::vector; + _paths_to_snap_to = new std::vector >; } Inkscape::ObjectSnapper::~ObjectSnapper() @@ -344,7 +344,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType if (_snapmanager->snapprefs.getSnapToPageBorder()) { Geom::PathVector *border_path = _getBorderPathv(); if (border_path != NULL) { - _paths_to_snap_to->push_back(border_path); + _paths_to_snap_to->push_back(std::make_pair(border_path, SNAPTARGET_PAGE_BORDER)); } } @@ -392,7 +392,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType if (curve) { // We will get our own copy of the path, which must be freed at some point Geom::PathVector *borderpathv = pathvector_for_curve(root_item, curve, true, true, Geom::identity(), (*i).additional_affine); - _paths_to_snap_to->push_back(borderpathv); // Perhaps for speed, get a reference to the Geom::pathvector, and store the transformation besides it. + _paths_to_snap_to->push_back(std::make_pair(borderpathv, SNAPTARGET_PATH)); // Perhaps for speed, get a reference to the Geom::pathvector, and store the transformation besides it. curve->unref(); } } @@ -409,7 +409,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType sp_item_invoke_bbox(root_item, rect, i2doc, TRUE, bbox_type); if (rect) { Geom::PathVector *path = _getPathvFromRect(*rect); - _paths_to_snap_to->push_back(path); + _paths_to_snap_to->push_back(std::make_pair(path, SNAPTARGET_BBOX_EDGE)); } } } @@ -446,20 +446,20 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc, SPCurve *curve = curve_for_item(SP_ITEM(selected_path)); if (curve) { Geom::PathVector *pathv = pathvector_for_curve(SP_ITEM(selected_path), curve, true, true, Geom::identity(), Geom::identity()); // We will get our own copy of the path, which must be freed at some point - _paths_to_snap_to->push_back(pathv); + _paths_to_snap_to->push_back(std::make_pair(pathv, SNAPTARGET_PATH)); curve->unref(); } } } - for (std::vector::const_iterator it_p = _paths_to_snap_to->begin(); it_p != _paths_to_snap_to->end(); it_p++) { + for (std::vector >::const_iterator it_p = _paths_to_snap_to->begin(); it_p != _paths_to_snap_to->end(); it_p++) { bool const being_edited = (node_tool_active && (*it_p) == _paths_to_snap_to->back()); //if true then this pathvector it_pv is currently being edited in the node tool - // char * svgd = sp_svg_write_path(**it_p); + // char * svgd = sp_svg_write_path(**it_p->first); // std::cout << "Dumping the pathvector: " << svgd << std::endl; - for(Geom::PathVector::iterator it_pv = (*it_p)->begin(); it_pv != (*it_p)->end(); ++it_pv) { + for(Geom::PathVector::iterator it_pv = (it_p->first)->begin(); it_pv != (it_p->first)->end(); ++it_pv) { // Find a nearest point for each curve within this path // n curves will return n time values with 0 <= t <= 1 std::vector anp = (*it_pv).nearestPointPerCurve(p_doc); @@ -496,7 +496,7 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc, if (!being_edited || (c1 && c2)) { Geom::Coord const dist = Geom::distance(sp_doc, p_doc); if (dist < getSnapperTolerance()) { - sc.curves.push_back(Inkscape::SnappedCurve(sp_dt, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), false, curve)); + sc.curves.push_back(Inkscape::SnappedCurve(sp_dt, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), false, curve, it_p->second)); } } } @@ -559,12 +559,12 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(SnappedConstraints &sc, cl.appendNew(p_max_on_cl); clv.push_back(cl); - for (std::vector::const_iterator k = _paths_to_snap_to->begin(); k != _paths_to_snap_to->end(); k++) { - if (*k) { - Geom::CrossingSet cs = Geom::crossings(clv, *(*k)); + for (std::vector >::const_iterator k = _paths_to_snap_to->begin(); k != _paths_to_snap_to->end(); k++) { + if (k->first) { + Geom::CrossingSet cs = Geom::crossings(clv, *(k->first)); if (cs.size() > 0) { // We need only the first element of cs, because cl is only a single straight linesegment - // This first element contains a vector filled with crossings of cl with *k + // This first element contains a vector filled with crossings of cl with k->first for (std::vector::const_iterator m = cs[0].begin(); m != cs[0].end(); m++) { if ((*m).ta >= 0 && (*m).ta <= 1 ) { // Reconstruct the point of intersection @@ -572,7 +572,7 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(SnappedConstraints &sc, // When it's within snapping range, then return it // (within snapping range == between p_min_on_cl and p_max_on_cl == 0 < ta < 1) Geom::Coord dist = Geom::L2(_snapmanager->getDesktop()->dt2doc(p_proj_on_cl) - p_inters); - SnappedPoint s(_snapmanager->getDesktop()->doc2dt(p_inters), SNAPTARGET_PATH, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true); + SnappedPoint s(_snapmanager->getDesktop()->doc2dt(p_inters), k->second, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true); sc.points.push_back(s); } } @@ -720,8 +720,8 @@ bool Inkscape::ObjectSnapper::GuidesMightSnap() const void Inkscape::ObjectSnapper::_clear_paths() const { - for (std::vector::const_iterator k = _paths_to_snap_to->begin(); k != _paths_to_snap_to->end(); k++) { - g_free(*k); + for (std::vector >::const_iterator k = _paths_to_snap_to->begin(); k != _paths_to_snap_to->end(); k++) { + g_free(k->first); } _paths_to_snap_to->clear(); } diff --git a/src/object-snapper.h b/src/object-snapper.h index 74bdec0ce..9a6978d47 100644 --- a/src/object-snapper.h +++ b/src/object-snapper.h @@ -86,7 +86,7 @@ private: //store some lists of candidates, points and paths, so we don't have to rebuild them for each point we want to snap std::vector *_candidates; std::vector *_points_to_snap_to; - std::vector *_paths_to_snap_to; + std::vector > *_paths_to_snap_to; void _findCandidates(SPObject* parent, std::vector const *it, diff --git a/src/seltrans.cpp b/src/seltrans.cpp index e55c25d79..4614adb87 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -1392,7 +1392,6 @@ void sp_sel_trans_center(Inkscape::SelTrans *seltrans, SPSelTransHandle const &, void Inkscape::SelTrans::moveTo(Geom::Point const &xy, guint state) { SnapManager &m = _desktop->namedview->snap_manager; - m.setup(_desktop, true, _items_const); /* The amount that we've moved by during this drag */ Geom::Point dxy = xy - _point; @@ -1407,7 +1406,8 @@ void Inkscape::SelTrans::moveTo(Geom::Point const &xy, guint state) ** FIXME: this will snap to more than just the grid, nowadays. */ - m.freeSnapReturnByRef(SnapPreferences::SNAPPOINT_NODE, dxy); + m.setup(_desktop, true, _items_const); + m.freeSnapReturnByRef(SnapPreferences::SNAPPOINT_NODE, dxy); } else if (!shift) { @@ -1416,7 +1416,9 @@ void Inkscape::SelTrans::moveTo(Geom::Point const &xy, guint state) ** pick the smallest. */ - /* This will be our list of possible translations */ + m.setup(_desktop, false, _items_const); + + /* This will be our list of possible translations */ std::list s; if (control) { diff --git a/src/snap.h b/src/snap.h index 177e9b529..b86ceb8b0 100644 --- a/src/snap.h +++ b/src/snap.h @@ -139,6 +139,8 @@ public: SPNamedView const *getNamedView() const {return _named_view;} SPDocument *getDocument() const; + bool getSnapIndicator() const {return _snapindicator;} + protected: SPNamedView const *_named_view; diff --git a/src/snapped-curve.cpp b/src/snapped-curve.cpp index 20d7aea33..34cc4dad2 100644 --- a/src/snapped-curve.cpp +++ b/src/snapped-curve.cpp @@ -14,7 +14,7 @@ #include <2geom/path-intersection.h> #include -Inkscape::SnappedCurve::SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve) +Inkscape::SnappedCurve::SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapTargetType target) { _distance = snapped_distance; _tolerance = std::max(snapped_tolerance, 1.0); @@ -26,6 +26,7 @@ Inkscape::SnappedCurve::SnappedCurve(Geom::Point const &snapped_point, Geom::Coo _point = snapped_point; _at_intersection = false; _fully_constrained = fully_constrained; + _target = target; } Inkscape::SnappedCurve::SnappedCurve() @@ -40,6 +41,7 @@ Inkscape::SnappedCurve::SnappedCurve() _point = Geom::Point(0,0); _at_intersection = false; _fully_constrained = false; + _target = SNAPTARGET_UNDEFINED; } Inkscape::SnappedCurve::~SnappedCurve() diff --git a/src/snapped-curve.h b/src/snapped-curve.h index 8414c10eb..d3dcd0238 100644 --- a/src/snapped-curve.h +++ b/src/snapped-curve.h @@ -1,55 +1,55 @@ -#ifndef SEEN_SNAPPEDCURVE_H -#define SEEN_SNAPPEDCURVE_H - -/** - * \file src/snapped-curve.h - * \brief SnappedCurve class. - * - * Authors: - * Diederik van Lierop - * - * Released under GNU GPL, read the file 'COPYING' for more information. - */ - -#include -#include -#include "libnr/nr-coord.h" -#include "libnr/nr-point.h" -#include -#include "snapped-point.h" -#include <2geom/forward.h> - -namespace Inkscape -{ - -/// Class describing the result of an attempt to snap to a curve. -class SnappedCurve : public SnappedPoint -{ -public: - SnappedCurve(); - SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve); - ~SnappedCurve(); - Inkscape::SnappedPoint intersect(SnappedCurve const &curve, Geom::Point const &p, Geom::Matrix dt2doc) const; //intersect with another SnappedCurve - -private: - Geom::Curve const *_curve; -}; - -} - -bool getClosestCurve(std::list const &list, Inkscape::SnappedCurve &result); -bool getClosestIntersectionCS(std::list const &list, Geom::Point const &p, Inkscape::SnappedPoint &result, Geom::Matrix dt2doc); - - -#endif /* !SEEN_SNAPPEDCURVE_H */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +#ifndef SEEN_SNAPPEDCURVE_H +#define SEEN_SNAPPEDCURVE_H + +/** + * \file src/snapped-curve.h + * \brief SnappedCurve class. + * + * Authors: + * Diederik van Lierop + * + * Released under GNU GPL, read the file 'COPYING' for more information. + */ + +#include +#include +#include "libnr/nr-coord.h" +#include "libnr/nr-point.h" +#include +#include "snapped-point.h" +#include <2geom/forward.h> + +namespace Inkscape +{ + +/// Class describing the result of an attempt to snap to a curve. +class SnappedCurve : public SnappedPoint +{ +public: + SnappedCurve(); + SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapTargetType target); + ~SnappedCurve(); + Inkscape::SnappedPoint intersect(SnappedCurve const &curve, Geom::Point const &p, Geom::Matrix dt2doc) const; //intersect with another SnappedCurve + +private: + Geom::Curve const *_curve; +}; + +} + +bool getClosestCurve(std::list const &list, Inkscape::SnappedCurve &result); +bool getClosestIntersectionCS(std::list const &list, Geom::Point const &p, Inkscape::SnappedPoint &result, Geom::Matrix dt2doc); + + +#endif /* !SEEN_SNAPPEDCURVE_H */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/snapped-point.h b/src/snapped-point.h index cddddd53b..7085ccae8 100644 --- a/src/snapped-point.h +++ b/src/snapped-point.h @@ -33,7 +33,8 @@ enum SnapTargetType { SNAPTARGET_PATH_INTERSECTION, SNAPTARGET_BBOX_CORNER, SNAPTARGET_BBOX_EDGE, - SNAPTARGET_GRADIENT + SNAPTARGET_GRADIENT, + SNAPTARGET_PAGE_BORDER }; /// Class describing the result of an attempt to snap.