Code

Filters. Custom predefined filters update and new ABC filters.
[inkscape.git] / src / context-fns.cpp
index 8a131b081952a7b7d595eabf2af09e5222c48ece..81eb6fdb5b1467f0de1609bde5731c4a70e3575d 100644 (file)
@@ -9,9 +9,12 @@
 #include "message-stack.h"
 #include "context-fns.h"
 #include "snap.h"
-#include "desktop-affine.h"
 #include "event-context.h"
 #include "sp-namedview.h"
+#include "display/snap-indicator.h"
+
+static const double midpt_1_goldenratio = (1 + goldenratio) / 2;
+static const double midpt_goldenratio_2 = (goldenratio + 2) / 2;
 
 /* FIXME: could probably use a template here */
 
@@ -73,28 +76,44 @@ bool Inkscape::have_viable_layer(SPDesktop *desktop, MessageStack *message)
 }
 
 
-NR::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item,
-                                        NR::Point const &pt, NR::Point const &center, int state)
+Geom::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item,
+                                        Geom::Point const &pt, Geom::Point const &center, int state)
 {
-    NR::Point p[2];
+    Geom::Point p[2];
 
     bool const shift = state & GDK_SHIFT_MASK;
     bool const control = state & GDK_CONTROL_MASK;
 
-    SnapManager const &m = desktop->namedview->snap_manager;
+    SnapManager &m = desktop->namedview->snap_manager;
+    m.setup(desktop, false, item);
+    Inkscape::SnappedPoint snappoint;
 
     if (control) {
 
         /* Control is down: we are constrained to producing integer-ratio rectangles */
 
         /* Vector from the centre of the box to the point we are dragging to */
-        NR::Point delta = pt - center;
-
-        /* Round it so that we have an integer-ratio box */
-        if (fabs(delta[NR::X]) > fabs(delta[NR::Y]) && (delta[NR::Y] != 0.0)) {
-            delta[NR::X] = floor(delta[NR::X] / delta[NR::Y] + 0.5) * delta[NR::Y];
-        } else if (delta[NR::X] != 0.0) {
-            delta[NR::Y] = floor(delta[NR::Y] / delta[NR::X] + 0.5) * delta[NR::X];
+        Geom::Point delta = pt - center;
+
+        /* Round it so that we have an integer-ratio (or golden ratio) box */
+        if (fabs(delta[Geom::X]) > fabs(delta[Geom::Y]) && (delta[Geom::Y] != 0.0)) {
+            double ratio = delta[Geom::X] / delta[Geom::Y];
+            double ratioabs = fabs (ratio);
+            double sign = (ratio < 0 ? -1 : 1);
+            if (midpt_1_goldenratio < ratioabs && ratioabs < midpt_goldenratio_2) {
+                delta[Geom::X] = sign * goldenratio * delta[Geom::Y];
+            } else {
+                delta[Geom::X] = floor(ratio + 0.5) * delta[Geom::Y];
+            }
+        } else if (delta[Geom::X] != 0.0) {
+            double ratio = delta[Geom::Y] / delta[Geom::X];
+            double ratioabs = fabs (ratio);
+            double sign = (ratio < 0 ? -1 : 1);
+            if (midpt_1_goldenratio < ratioabs && ratioabs < midpt_goldenratio_2) {
+                delta[Geom::Y] = sign * goldenratio * delta[Geom::X];
+            } else {
+                delta[Geom::Y] = floor(delta[Geom::Y] / delta[Geom::X] + 0.5) * delta[Geom::X];
+            }
         }
 
         /* p[1] is the dragged point with the integer-ratio constraint */
@@ -112,28 +131,36 @@ NR::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item,
             Inkscape::SnappedPoint s[2];
 
             /* Try to snap p[0] (the opposite corner) along the constraint vector */
-            s[0] = m.constrainedSnap(Inkscape::Snapper::SNAPPOINT_NODE, p[0],
-                                     Inkscape::Snapper::ConstraintLine(p[0] - p[1]), item);
+            s[0] = m.constrainedSnap(Inkscape::SnapCandidatePoint(p[0], Inkscape::SNAPSOURCE_NODE_HANDLE),
+                                     Inkscape::Snapper::SnapConstraint(p[0] - p[1]));
 
             /* Try to snap p[1] (the dragged corner) along the constraint vector */
-            s[1] = m.constrainedSnap(Inkscape::Snapper::SNAPPOINT_NODE, p[1],
-                                     Inkscape::Snapper::ConstraintLine(p[1] - p[0]), item);
+            s[1] = m.constrainedSnap(Inkscape::SnapCandidatePoint(p[1], Inkscape::SNAPSOURCE_NODE_HANDLE),
+                                     Inkscape::Snapper::SnapConstraint(p[1] - p[0]));
 
             /* Choose the best snap and update points accordingly */
-            if (s[0].getDistance() < s[1].getDistance()) {
-                p[0] = s[0].getPoint();
-                p[1] = 2 * center - s[0].getPoint();
+            if (s[0].getSnapDistance() < s[1].getSnapDistance()) {
+                if (s[0].getSnapped()) {
+                    p[0] = s[0].getPoint();
+                    p[1] = 2 * center - s[0].getPoint();
+                    snappoint = s[0];
+                }
             } else {
-                p[0] = 2 * center - s[1].getPoint();
-                p[1] = s[1].getPoint();
+                if (s[1].getSnapped()) {
+                    p[0] = 2 * center - s[1].getPoint();
+                    p[1] = s[1].getPoint();
+                    snappoint = s[1];
+                }
             }
-
         } else {
 
             /* Our origin is the opposite corner.  Snap the drag point along the constraint vector */
             p[0] = center;
-            p[1] = m.constrainedSnap(Inkscape::Snapper::SNAPPOINT_NODE, p[1],
-                                     Inkscape::Snapper::ConstraintLine(p[1] - p[0]), item).getPoint();
+            snappoint = m.constrainedSnap(Inkscape::SnapCandidatePoint(p[1], Inkscape::SNAPSOURCE_NODE_HANDLE),
+                                          Inkscape::Snapper::SnapConstraint(p[1] - p[0]));
+            if (snappoint.getSnapped()) {
+                p[1] = snappoint.getPoint();
+            }
         }
 
     } else if (shift) {
@@ -147,40 +174,56 @@ NR::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item,
 
         Inkscape::SnappedPoint s[2];
 
-        s[0] = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p[0], item);
-        s[1] = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p[1], item);
+        s[0] = m.freeSnap(Inkscape::SnapCandidatePoint(p[0], Inkscape::SNAPSOURCE_NODE_HANDLE));
+        s[1] = m.freeSnap(Inkscape::SnapCandidatePoint(p[1], Inkscape::SNAPSOURCE_NODE_HANDLE));
 
-        if (s[0].getDistance() < s[1].getDistance()) {
-            p[0] = s[0].getPoint();
-            p[1] = 2 * center - s[0].getPoint();
+        if (s[0].getSnapDistance() < s[1].getSnapDistance()) {
+            if (s[0].getSnapped()) {
+                p[0] = s[0].getPoint();
+                p[1] = 2 * center - s[0].getPoint();
+                snappoint = s[0];
+            }
         } else {
-            p[0] = 2 * center - s[1].getPoint();
-            p[1] = s[1].getPoint();
+            if (s[1].getSnapped()) {
+                p[0] = 2 * center - s[1].getPoint();
+                p[1] = s[1].getPoint();
+                snappoint = s[1];
+            }
         }
 
     } else {
 
         /* There's no constraint on the corner point, so just snap it to anything */
         p[0] = center;
-        p[1] = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, pt, item).getPoint();
+        p[1] = pt;
+        snappoint = m.freeSnap(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_HANDLE));
+        if (snappoint.getSnapped()) {
+            p[1] = snappoint.getPoint();
+        }
     }
 
-    p[0] = sp_desktop_dt2root_xy_point(desktop, p[0]);
-    p[1] = sp_desktop_dt2root_xy_point(desktop, p[1]);
+    if (snappoint.getSnapped()) {
+        desktop->snapindicator->set_new_snaptarget(snappoint);
+    }
+
+    p[0] *= desktop->dt2doc();
+    p[1] *= desktop->dt2doc();
+
+    m.unSetup();
 
-    return NR::Rect(NR::Point(MIN(p[0][NR::X], p[1][NR::X]), MIN(p[0][NR::Y], p[1][NR::Y])),
-                    NR::Point(MAX(p[0][NR::X], p[1][NR::X]), MAX(p[0][NR::Y], p[1][NR::Y])));
+    return Geom::Rect(Geom::Point(MIN(p[0][Geom::X], p[1][Geom::X]), MIN(p[0][Geom::Y], p[1][Geom::Y])),
+                    Geom::Point(MAX(p[0][Geom::X], p[1][Geom::X]), MAX(p[0][Geom::Y], p[1][Geom::Y])));
 }
 
 
 
-NR::Point Inkscape::setup_for_drag_start(SPDesktop *desktop, SPEventContext* ec, GdkEvent *ev)
+Geom::Point Inkscape::setup_for_drag_start(SPDesktop *desktop, SPEventContext* ec, GdkEvent *ev)
 {
     ec->xp = static_cast<gint>(ev->button.x);
     ec->yp = static_cast<gint>(ev->button.y);
     ec->within_tolerance = true;
 
-    NR::Point const p(ev->button.x, ev->button.y);
+    Geom::Point const p(ev->button.x, ev->button.y);
     ec->item_to_select = sp_event_context_find_item(desktop, p, ev->button.state & GDK_MOD1_MASK, TRUE);
     return ec->desktop->w2d(p);
 }
@@ -195,4 +238,4 @@ NR::Point Inkscape::setup_for_drag_start(SPDesktop *desktop, SPEventContext* ec,
   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 :