Code

- Snap to the midpoint of shapes and bboxes
authordvlierop2 <dvlierop2@users.sourceforge.net>
Sun, 18 Jan 2009 20:00:19 +0000 (20:00 +0000)
committerdvlierop2 <dvlierop2@users.sourceforge.net>
Sun, 18 Jan 2009 20:00:19 +0000 (20:00 +0000)
- Snap to the midpoint of paths and bbox edges
- Refactor the snapping toggle, i.e. what snaps to what when toggling a specific option in the snapping toolbar
PS: icons.svg has been modified, so use "make install" if needed

22 files changed:
share/icons/icons.svg
src/attributes-test.h
src/attributes.cpp
src/attributes.h
src/guide-snapper.cpp
src/line-snapper.cpp
src/object-snapper.cpp
src/object-snapper.h
src/seltrans.cpp
src/snap-preferences.cpp
src/snap-preferences.h
src/snap.cpp
src/snap.h
src/sp-ellipse.cpp
src/sp-item.cpp
src/sp-namedview.cpp
src/sp-rect.cpp
src/sp-shape.cpp
src/sp-spiral.cpp
src/sp-star.cpp
src/ui/dialog/document-properties.cpp
src/widgets/toolbox.cpp

index 297e9aa1d01c14359006a759ccff26c944489bb7..10b3a6d05399e0ec946761ee3f49a0816484309d 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" inkscape:version="0.46+devel" sodipodi:docname="my-icons.svg" height="1000.0000pt" width="1000.0000pt" sodipodi:version="0.32" id="svg1" inkscape:output_extension="org.inkscape.output.svg.inkscape">
+<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" inkscape:version="0.46+devel r20521 custom" sodipodi:docname="icons.svg" height="1000.0000pt" width="1000.0000pt" sodipodi:version="0.32" id="svg1" inkscape:output_extension="org.inkscape.output.svg.inkscape">
 <defs id="defs3">
 <inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 625 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="1250 : 625 : 1" inkscape:persp3d-origin="625 : 416.6667 : 1" id="perspective8072" />
 <linearGradient inkscape:collect="always" id="linearGradient7836">
 <inkscape:perspective id="perspective6611" inkscape:persp3d-origin="0.5 : 0.3333333 : 1" inkscape:vp_z="1 : 0.5 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_x="0 : 0.5 : 1" sodipodi:type="inkscape:persp3d" />
 <inkscape:perspective id="perspective6654" inkscape:persp3d-origin="0.5 : 0.3333333 : 1" inkscape:vp_z="1 : 0.5 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_x="0 : 0.5 : 1" sodipodi:type="inkscape:persp3d" />
 <inkscape:perspective id="perspective6676" inkscape:persp3d-origin="0.5 : 0.3333333 : 1" inkscape:vp_z="1 : 0.5 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_x="0 : 0.5 : 1" sodipodi:type="inkscape:persp3d" />
+<inkscape:perspective id="perspective8509" inkscape:persp3d-origin="0.5 : 0.3333333 : 1" inkscape:vp_z="1 : 0.5 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_x="0 : 0.5 : 1" sodipodi:type="inkscape:persp3d" />
+<inkscape:perspective id="perspective8552" inkscape:persp3d-origin="0.5 : 0.3333333 : 1" inkscape:vp_z="1 : 0.5 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_x="0 : 0.5 : 1" sodipodi:type="inkscape:persp3d" />
+<inkscape:perspective id="perspective8583" inkscape:persp3d-origin="0.5 : 0.3333333 : 1" inkscape:vp_z="1 : 0.5 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_x="0 : 0.5 : 1" sodipodi:type="inkscape:persp3d" />
+<inkscape:perspective id="perspective8605" inkscape:persp3d-origin="0.5 : 0.3333333 : 1" inkscape:vp_z="1 : 0.5 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_x="0 : 0.5 : 1" sodipodi:type="inkscape:persp3d" />
+<inkscape:perspective id="perspective8636" inkscape:persp3d-origin="0.5 : 0.3333333 : 1" inkscape:vp_z="1 : 0.5 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_x="0 : 0.5 : 1" sodipodi:type="inkscape:persp3d" />
+<inkscape:perspective id="perspective9457" inkscape:persp3d-origin="0.5 : 0.3333333 : 1" inkscape:vp_z="1 : 0.5 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_x="0 : 0.5 : 1" sodipodi:type="inkscape:persp3d" />
+<inkscape:perspective id="perspective9457-2" inkscape:persp3d-origin="0.5 : 0.3333333 : 1" inkscape:vp_z="1 : 0.5 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_x="0 : 0.5 : 1" sodipodi:type="inkscape:persp3d" />
 </defs>
-<sodipodi:namedview inkscape:guide-bbox="true" inkscape:current-layer="svg1" inkscape:grid-bbox="true" inkscape:pageopacity="1.0000000" pagecolor="#e8e8e4" snaptoguides="true" showguides="true" inkscape:window-y="24" inkscape:window-x="0" inkscape:window-height="1129" inkscape:window-width="1920" inkscape:cy="1176.017" inkscape:cx="722.4667" inkscape:zoom="3.884101" gridtolerance="6" snaptogrid="false" showgrid="false" id="base" inkscape:document-units="px" inkscape:grid-points="true" guidetolerance="8" fill="#8ab3de" stroke="#646464" inkscape:object-nodes="false" objecttolerance="11" inkscape:snap-bbox="false" inkscape:snap-nodes="true" inkscape:bbox-nodes="true" inkscape:bbox-paths="true" inkscape:snap-global="true" inkscape:snap-center="true" inkscape:snap-midpoints="true" inkscape:snap-intersection-paths="true" inkscape:object-paths="true">
+<sodipodi:namedview inkscape:guide-bbox="true" inkscape:current-layer="toggle_snap_to_bbox_midpoints-3" inkscape:grid-bbox="true" inkscape:pageopacity="1.0000000" pagecolor="#e8e8e4" snaptoguides="true" showguides="true" inkscape:window-y="24" inkscape:window-x="0" inkscape:window-height="1129" inkscape:window-width="1920" inkscape:cy="1204.346" inkscape:cx="805.2226" inkscape:zoom="5.492948" gridtolerance="6" snaptogrid="false" showgrid="false" id="base" inkscape:document-units="px" inkscape:grid-points="true" guidetolerance="8" fill="#8ab3de" stroke="#646464" inkscape:object-nodes="false" objecttolerance="11" inkscape:snap-bbox="true" inkscape:snap-nodes="false" inkscape:bbox-nodes="false" inkscape:bbox-paths="false" inkscape:snap-global="true" inkscape:snap-center="true" inkscape:snap-midpoints="false" inkscape:snap-intersection-paths="true" inkscape:object-paths="true" inkscape:snap-object-midpoints="false">
 <inkscape:grid type="xygrid" id="grid9252" originx="0px" originy="0px" spacingx="0.5px" spacingy="0.5px" empspacing="2" visible="true" enabled="true" />
 <sodipodi:guide orientation="0,1" position="630.08101,968.02815" id="guide4946" />
 <sodipodi:guide orientation="0,1" position="618.47896,943.93157" id="guide4948" />
@@ -727,7 +734,7 @@ http://www.inkscape.org/</dc:description>
 <dc:title>Inkscape Developers</dc:title>
 </cc:Agent>
 </dc:rights>
-<dc:title />
+<dc:title></dc:title>
 </cc:Work>
 <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
 <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" />
@@ -3228,32 +3235,32 @@ http://www.inkscape.org/</dc:description>
 <path id="path9141-9-2" d="m 687,30 0,13 -13,0" style="color:#000000;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 2;stroke-dashoffset:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
 <rect transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,0,0)" style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#008000;stroke-width:0.9051017;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline" id="rect3224-2-8-6" width="3.584063" height="3.621212" x="453.5847" y="514.3773" />
 </g>
-<g id="toggle_snap_nodes">
-<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;display:inline" id="rect5385-6-7" width="16" height="16" x="692" y="30.00057" />
-<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;display:inline" id="rect5385-6-0-8" width="16" height="16" x="692" y="30.00114" />
+<g id="toggle_snap_nodes" transform="translate(36,-0.001709)">
+<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.1;marker:none;display:inline" id="rect5385-6-7" width="16" height="16" x="692" y="30.00057" />
+<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.1;marker:none;display:inline" id="rect5385-6-0-8" width="16" height="16" x="692" y="30.00114" />
 <path sodipodi:nodetypes="ccsc" id="path6308" d="m 693,38 c 0,0 0,-5 7,-5 -4,5 -2.25,8 0.5,9.75 2.75,1.75 6.5,2.25 6.5,2.25" style="color:#000000;fill:none;stroke:#646464;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
 <rect transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,0,0)" style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.9051017;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline" id="rect3224-2-9" width="3.584063" height="3.621212" x="469.8239" y="516.5415" />
 </g>
-<g id="toggle_snap_to_paths">
-<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;display:inline" id="rect5385-6-4-8" width="16" height="16" x="710" y="30.00057" />
+<g id="toggle_snap_to_paths" transform="translate(36,-0.001709)">
+<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.1;marker:none;display:inline" id="rect5385-6-4-8" width="16" height="16" x="710" y="30.00057" />
 <path sodipodi:nodetypes="ccsc" id="path6308-6" d="m 725,39 c 0,0 0,5 -7,5 4,-5 2.25,-8 -0.5,-9.75 C 714.75,32.5 711,32 711,32" style="color:#000000;fill:none;stroke:#646464;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
 </g>
-<g id="toggle_snap_to_nodes">
-<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;display:inline" id="rect5385-6-74" width="16" height="16" x="728" y="30.00057" />
-<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;display:inline" id="rect5385-6-0-19" width="16" height="16" x="728" y="30.00114" />
+<g id="toggle_snap_to_nodes" transform="translate(36,-0.001709)">
+<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.1;marker:none;display:inline" id="rect5385-6-74" width="16" height="16" x="728" y="30.00057" />
+<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.1;marker:none;display:inline" id="rect5385-6-0-19" width="16" height="16" x="728" y="30.00114" />
 <path sodipodi:nodetypes="ccsc" id="path6308-6-3" d="m 743,38 c 0,0 0,5 -7,5 4,-5 2.25,-8 -0.5,-9.75 C 732.75,31.5 729,31 729,31" style="color:#000000;fill:none;stroke:#646464;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
 <rect transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,0,0)" style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#008000;stroke-width:0.9051017;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline" id="rect3224-2-8-6-5" width="3.584063" height="3.621212" x="488.233" y="549.0256" />
 </g>
-<g id="toggle_snap_to_smooth_nodes">
-<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;display:inline" id="rect5385-6-4-09" width="16" height="16" x="746" y="30.00057" />
+<g id="toggle_snap_to_smooth_nodes" transform="translate(36,-0.001709)">
+<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.1;marker:none;display:inline" id="rect5385-6-4-09" width="16" height="16" x="746" y="30.00057" />
 <path sodipodi:nodetypes="ccsc" id="path6308-6-3-2" d="m 761,38 c 0,0 0,5 -7,5 4,-5 2.25,-8 -0.5,-9.75 C 750.75,31.5 747,31 747,31" style="color:#000000;fill:none;stroke:#646464;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
 <rect transform="matrix(0,-1,1,0,0,0)" style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#008000;stroke-width:0.9051017;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline" id="rect3224-2-8-6-5-6" width="3.584063" height="3.621212" x="-35.08406" y="751.8788" />
 </g>
-<g id="toggle_snap_to_midpoints">
+<g id="toggle_snap_to_midpoints" transform="translate(36,-0.001709)">
 <rect style="color:#000000;fill:none;stroke:none;stroke-width:0.1;marker:none;display:inline" id="rect5385-6-5-8" width="16" height="16" x="764" y="30.00114" />
 <rect style="color:#000000;fill:none;stroke:none;stroke-width:0.1;marker:none;display:inline" id="rect5385-6-0-1-8" width="16" height="16" x="764" y="30.00171" />
 <path id="path6507" d="M 765,45 779,31" style="color:#000000;fill:none;stroke:#646464;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-<path transform="matrix(0.8749999,0,0,0.875,112.6876,9.126711)" d="m 755.5,33 a 2,2 0 1 1 -4,0 2,2 0 1 1 4,0 z" sodipodi:ry="2" sodipodi:rx="2" sodipodi:cy="33" sodipodi:cx="753.5" id="path6530" style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#008000;stroke-width:1.1428572;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" sodipodi:type="arc" />
+<path transform="matrix(0.8749999,0,0,0.875,112.6876,9.126711)" d="m 755.5,33 c 0,1.104 -0.896,2 -2,2 -1.104,0 -2,-0.896 -2,-2 0,-1.104 0.896,-2 2,-2 1.104,0 2,0.896 2,2 z" sodipodi:ry="2" sodipodi:rx="2" sodipodi:cy="33" sodipodi:cx="753.5" id="path6530" style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#008000;stroke-width:1.1428572;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" sodipodi:type="arc" />
 <g transform="matrix(1.5,0,0,1.5,-383.9324,-21.06763)" id="g6242">
 <path style="color:#000000;fill:#c00000;fill-opacity:1;fill-rule:nonzero;stroke:#c00000;stroke-width:0.6666667px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" d="m 766.7737,40.68077 1,4" id="path6218" />
 <path style="color:#000000;fill:#c00000;fill-opacity:1;fill-rule:nonzero;stroke:#c00000;stroke-width:0.6666667px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" d="m 767.9558,39.58974 1,4" id="path6218-9" />
@@ -3263,31 +3270,48 @@ http://www.inkscape.org/</dc:description>
 <path style="color:#000000;fill:#c00000;fill-opacity:1;fill-rule:nonzero;stroke:#c00000;stroke-width:0.6666667px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" d="m 767.9558,39.58974 1,4" id="path6218-9-6" />
 </g>
 </g>
-<g id="toggle_snap_to_path_intersections">
+<g id="toggle_snap_to_path_intersections" transform="translate(36,-0.001709)">
 <g id="g6774">
-<rect y="30.00114" x="782" height="16" width="16" id="rect5385-6-4-0-5" style="color:#000000;fill:none;stroke:none;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;display:inline" />
-<path style="color:#000000;fill:none;stroke:#646464;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" d="M 783,45 797,31" id="path6507-9" />
+<rect y="30.00114" x="782" height="16" width="16" id="rect5385-6-4-0-5" style="color:#000000;fill:none;stroke:none;stroke-width:0.1;marker:none;display:inline" />
+<path style="color:#000000;fill:none;stroke:#646464;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" d="M 783,45 797,31" id="path6507-9" />
 <path style="color:#000000;fill:none;stroke:#646464;stroke-width:1.0000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" d="m 783,40 14,-4" id="path6507-9-3" />
-<path sodipodi:type="arc" style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#008000;stroke-width:1.1428572;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="path6530-3" sodipodi:cx="753.5" sodipodi:cy="33" sodipodi:rx="2" sodipodi:ry="2" d="m 755.5,33 a 2,2 0 1 1 -4,0 2,2 0 1 1 4,0 z" transform="matrix(0.8749999,0,0,0.875,130.6876,9.127)" />
+<path sodipodi:type="arc" style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#008000;stroke-width:1.1428572;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="path6530-3" sodipodi:cx="753.5" sodipodi:cy="33" sodipodi:rx="2" sodipodi:ry="2" d="m 755.5,33 c 0,1.104 -0.896,2 -2,2 -1.104,0 -2,-0.896 -2,-2 0,-1.104 0.896,-2 2,-2 1.104,0 2,0.896 2,2 z" transform="matrix(0.8749999,0,0,0.875,130.6876,9.127)" />
 </g>
 </g>
-<g id="toggle_snap_center">
-<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;display:inline" id="rect5385-6-7-8" width="16" height="16" x="800" y="30.00114" />
-<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;display:inline" id="rect5385-6-0-8-4" width="16" height="16" x="800" y="30.00171" />
+<g id="toggle_snap_center" transform="translate(54.5,0.5)">
+<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.1;marker:none;display:inline" id="rect5385-6-7-8" width="16" height="16" x="800" y="30.00114" />
+<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.1;marker:none;display:inline" id="rect5385-6-0-8-4" width="16" height="16" x="800" y="30.00171" />
 <path id="path9141-9-0" d="m 813,30 0,13 -13,0" style="color:#000000;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 2;stroke-dashoffset:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
 <path id="path6380" d="m 805,31.5 0,3" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
 <path id="path6380-4" d="m 805,35.5 0,3" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
 <path id="path6380-8" d="m 801.5,35 3,0" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
 <path id="path6380-4-0" d="m 805.5,35 3,0" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
 </g>
-<g id="toggle_snap_page_border">
-<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;display:inline" id="rect5385-6-4-8-3" width="16" height="16" x="818" y="30.00114" />
+<g id="toggle_snap_page_border" transform="translate(54.5,0.5)">
+<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.1;marker:none;display:inline" id="rect5385-6-4-8-3" width="16" height="16" x="818" y="30.00114" />
 <path sodipodi:nodetypes="ccccc" id="path3805-7" d="m 820.7689,31.00114 10.4622,0 0,14 -10.4622,0 0,-14 z" style="color:#000000;fill:url(#linearGradient6465);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient6467);stroke-width:1.0000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;display:inline" />
 </g>
-<g id="toggle_snap_grid_guide_intersections">
-<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.10000000000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;display:inline" id="rect5385-6-4-8-3-1" width="16" height="16" x="836" y="30.00057" />
+<g id="toggle_snap_grid_guide_intersections" transform="translate(54.5,0.5)">
+<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.1;marker:none;display:inline" id="rect5385-6-4-8-3-1" width="16" height="16" x="836" y="30.00057" />
 <path id="path6498-9-0" d="m 851,37 -14,0" style="color:#000000;fill:#c00000;fill-opacity:1;fill-rule:nonzero;stroke:#0065ff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
 <path id="path6498-1" d="m 841.5822,45.57303 4.8364,-15.14606" style="color:#000000;fill:#c00000;fill-opacity:1;fill-rule:nonzero;stroke:#0065ff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
 <path transform="matrix(0.8749999,0,0,0.875,185.0073,8.125)" d="m 755.5,33 a 2,2 0 1 1 -4,0 2,2 0 1 1 4,0 z" sodipodi:ry="2" sodipodi:rx="2" sodipodi:cy="33" sodipodi:cx="753.5" id="path6530-3-7" style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#008000;stroke-width:1.1428572;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" sodipodi:type="arc" />
 </g>
+<g id="toggle_snap_to_bbox_midpoints">
+<path transform="matrix(0.8749999,0,0,0.875,56.39207,5.147436)" d="m 755.5,33 a 2,2 0 1 1 -4,0 2,2 0 1 1 4,0 z" sodipodi:ry="2" sodipodi:rx="2" sodipodi:cy="33" sodipodi:cx="753.5" id="path6530-5" style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#008000;stroke-width:1.1428572;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" sodipodi:type="arc" />
+<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.1;marker:none;display:inline" id="rect5385-6-4-0-8" width="16" height="16" x="712" y="29.99886" />
+<path id="path9141-9-2-5" d="m 725,29.99829 0,13 -13,0" style="color:#000000;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 2;stroke-dashoffset:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+</g>
+<g transform="translate(162.5,0.5)" id="toggle_snap_to_bbox_midpoints-3">
+<g id="toggle_snap_to_object_midpoints">
+<rect y="30.00057" x="674" height="16" width="16" id="rect5385-6-4-0-8-1" style="color:#000000;fill:none;stroke:none;stroke-width:0.1;marker:none;display:inline" />
+<path style="color:#000000;fill:none;stroke:#646464;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" d="m 687,30 0,13 -13,0" id="path9141-9-2-5-1" />
+<path transform="matrix(0.8749999,0,0,0.875,19.93758,6.375)" d="m 755.5,33 a 2,2 0 1 1 -4,0 2,2 0 1 1 4,0 z" sodipodi:ry="2" sodipodi:rx="2" sodipodi:cy="33" sodipodi:cx="753.5" id="path6530-3-6" style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#008000;stroke-width:1.1428572;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" sodipodi:type="arc" />
+</g>
+</g>
+<g id="toggle_snap_to_bbox_edge_midpoints">
+<rect style="color:#000000;fill:none;stroke:none;stroke-width:0.1;marker:none;display:inline" id="rect5385-6-4-0-8-5" width="16" height="16" x="692.5" y="30" />
+<path id="path9141-9-2-5-3" d="m 705.5,29.99943 0,13 -13,0" style="color:#000000;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 2;stroke-dashoffset:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+<path sodipodi:type="arc" style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#008000;stroke-width:1.1428572;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="path6530-4" sodipodi:cx="753.5" sodipodi:cy="33" sodipodi:rx="2" sodipodi:ry="2" d="m 755.5,33 a 2,2 0 1 1 -4,0 2,2 0 1 1 4,0 z" transform="matrix(0.8749999,0,0,0.875,46.21002,5.147436)" />
+</g>
 </svg>
index 5e3f741d73104deddd8cdc65c14f0a451bf0d091..1148953ec1c386bd8933056652eccefaf234c09d 100644 (file)
@@ -352,7 +352,10 @@ struct {char const *attr; bool supported;} const all_attrs[] = {
     {"inkscape:snap-center", true},
     {"inkscape:snap-smooth-nodes", true},
     {"inkscape:snap-midpoints", true},
-    {"inkscape:snap-intersection-grid-guide", true},
+    {"inkscape:snap-object-midpoints", true},
+    {"inkscape:snap-bbox-edge-midpoints", true},
+    {"inkscape:snap-bbox-midpoints", true},
+       {"inkscape:snap-intersection-grid-guide", true},
     {"inkscape:snap-intersection-paths", true},
     {"inkscape:pageopacity", true},
     {"inkscape:pageshadow", true},
index 1ee33ef832468e8680eb06adb4c988a4c8fcf8c5..049632e50f1b6524292971978f4122b76d6c1dec 100644 (file)
@@ -92,8 +92,11 @@ static SPStyleProp const props[] = {
     {SP_ATTR_INKSCAPE_SNAP_GUIDE, "inkscape:snap-guide"},
     {SP_ATTR_INKSCAPE_SNAP_CENTER, "inkscape:snap-center"},
     {SP_ATTR_INKSCAPE_SNAP_SMOOTH_NODES, "inkscape:snap-smooth-nodes"},
-    {SP_ATTR_INKSCAPE_SNAP_MIDPOINTS, "inkscape:snap-midpoints"},
-    {SP_ATTR_INKSCAPE_SNAP_INTERS_GRIDGUIDE, "inkscape:snap-intersection-grid-guide"},
+    {SP_ATTR_INKSCAPE_SNAP_LINE_MIDPOINTS, "inkscape:snap-midpoints"},
+    {SP_ATTR_INKSCAPE_SNAP_OBJECT_MIDPOINTS, "inkscape:snap-object-midpoints"},
+    {SP_ATTR_INKSCAPE_SNAP_BBOX_EDGE_MIDPOINTS, "inkscape:snap-bbox-edge-midpoints"},
+       {SP_ATTR_INKSCAPE_SNAP_BBOX_MIDPOINTS, "inkscape:snap-bbox-midpoints"},
+       {SP_ATTR_INKSCAPE_SNAP_INTERS_GRIDGUIDE, "inkscape:snap-intersection-grid-guide"},
     {SP_ATTR_INKSCAPE_SNAP_INTERS_PATHS, "inkscape:snap-intersection-paths"},
     {SP_ATTR_INKSCAPE_OBJECT_PATHS, "inkscape:object-paths"},
     {SP_ATTR_INKSCAPE_OBJECT_NODES, "inkscape:object-nodes"},
index 68e6135dbd2084aae24b71fb56f1babed465fca3..6fe3ebb806bc54891dee44481b2a6dd33f3b9046 100644 (file)
@@ -92,7 +92,10 @@ enum SPAttributeEnum {
     SP_ATTR_INKSCAPE_SNAP_GUIDE,
     SP_ATTR_INKSCAPE_SNAP_CENTER,
     SP_ATTR_INKSCAPE_SNAP_SMOOTH_NODES,
-    SP_ATTR_INKSCAPE_SNAP_MIDPOINTS,
+    SP_ATTR_INKSCAPE_SNAP_LINE_MIDPOINTS,
+    SP_ATTR_INKSCAPE_SNAP_OBJECT_MIDPOINTS,
+    SP_ATTR_INKSCAPE_SNAP_BBOX_EDGE_MIDPOINTS,
+       SP_ATTR_INKSCAPE_SNAP_BBOX_MIDPOINTS,
     SP_ATTR_INKSCAPE_SNAP_INTERS_GRIDGUIDE,
     SP_ATTR_INKSCAPE_SNAP_INTERS_PATHS,
     SP_ATTR_INKSCAPE_OBJECT_PATHS,
index be2e84170aff18ce4fbc4241f760c4bd6979d575..b05466ede6ef7ad761e66a49bea7e4e11357e0fb 100644 (file)
@@ -43,7 +43,11 @@ Inkscape::GuideSnapper::LineList Inkscape::GuideSnapper::_getSnapLines(Geom::Poi
  */
 bool Inkscape::GuideSnapper::ThisSnapperMightSnap() const
 {
-    return _snapmanager->getNamedView() == NULL ? false : (_snap_enabled && _snapmanager->snapprefs.getSnapModeBBoxOrNodes() && _snapmanager->getNamedView()->showguides);
+       if (_snapmanager->getNamedView() == NULL) {
+               return false;
+       }
+
+       return (_snap_enabled && _snapmanager->snapprefs.getSnapModeBBoxOrNodes() && _snapmanager->getNamedView()->showguides);
 }
 
 void Inkscape::GuideSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, Geom::Point const normal_to_line, Geom::Point const point_on_line) const
index bfcda3f79dfba34402853eccf5afeed1e580fd10..bc43d640b0d9c6a327c26fe2e8a2609b2b1f69eb 100644 (file)
@@ -31,7 +31,7 @@ void Inkscape::LineSnapper::freeSnap(SnappedConstraints &sc,
                                                     std::vector<SPItem const *> const */*it*/,
                                                     std::vector<Geom::Point> */*unselected_nodes*/) const
 {
-       if (_snap_enabled == false || _snapmanager->snapprefs.getSnapFrom(t) == false) {
+       if (!(_snap_enabled && _snapmanager->snapprefs.getSnapFrom(t)) ) {
         return;
     }
 
index 35841891f69969d3e16d896edcae6a1f83dd5d96..f5021e2088afdc1f6945dc6745909eca9e586f48 100644 (file)
@@ -44,9 +44,7 @@ Inkscape::SnapCandidate::~SnapCandidate()
 }
 
 Inkscape::ObjectSnapper::ObjectSnapper(SnapManager *sm, Geom::Coord const d)
-    : Snapper(sm, d), _snap_to_itemnode(true), _snap_to_itempath(true),
-      _snap_to_bboxnode(true), _snap_to_bboxpath(true), _snap_to_page_border(false),
-      _strict_snapping(true)
+    : Snapper(sm, d)
 {
     _candidates = new std::vector<SnapCandidate>;
     _points_to_snap_to = new std::vector<Geom::Point>;
@@ -176,7 +174,7 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType
         // A point considered for snapping should be either a node, a bbox corner or a guide. Pick only ONE!
         g_assert(!((p_is_a_node && p_is_a_bbox) || (p_is_a_bbox && p_is_a_guide) || (p_is_a_node && p_is_a_guide)));
 
-        if (_snap_to_bboxnode) {
+        if (_snapmanager->snapprefs.getSnapToBBoxNode() || _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints() || _snapmanager->snapprefs.getSnapBBoxMidpoints()) {
             Inkscape::Preferences *prefs = Inkscape::Preferences::get();
             bool prefs_bbox = prefs->getBool("/tools/bounding_box");
             bbox_type = !prefs_bbox ?
@@ -184,7 +182,7 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType
         }
 
         // Consider the page border for snapping
-        if (_snap_to_page_border) {
+        if (_snapmanager->snapprefs.getSnapToPageBorder()) {
             _getBorderNodes(_points_to_snap_to);
         }
 
@@ -197,51 +195,47 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType
             g_return_if_fail(root_item);
 
             //Collect all nodes so we can snap to them
-            if (_snap_to_itemnode) {
-                if (!(_strict_snapping && !p_is_a_node) || p_is_a_guide) {
-                    // Note: there are two ways in which intersections are considered:
-                    // Method 1: Intersections are calculated for each shape individually, for both the
-                    //           snap source and snap target (see sp_shape_snappoints)
-                    // Method 2: Intersections are calculated for each curve or line that we've snapped to, i.e. only for
-                    //           the target (see the intersect() method in the SnappedCurve and SnappedLine classes)
-                    // Some differences:
-                    // - Method 1 doesn't find intersections within a set of multiple objects
-                    // - Method 2 only works for targets
-                    // When considering intersections as snap targets:
-                    // - Method 1 only works when snapping to nodes, whereas
-                    // - Method 2 only works when snapping to paths
-                    // - There will be performance differences too!
-                    // If both methods are being used simultaneously, then this might lead to duplicate targets!
-
-                    // Well, here we will be looking for snap TARGETS. Both methods can therefore be used.
-                    // When snapping to paths, we will get a collection of snapped lines and snapped curves. findBestSnap() will
-                    // go hunting for intersections (but only when asked to in the prefs of course). In that case we can just
-                    // temporarily block the intersections in sp_item_snappoints, we don't need duplicates. If we're not snapping to
-                    // paths though but only to item nodes then we should still look for the intersections in sp_item_snappoints()
-                    bool old_pref = _snapmanager->snapprefs.getSnapIntersectionCS();
-                    if (_snap_to_itempath) {
-                        _snapmanager->snapprefs.setSnapIntersectionCS(false);
-                    }
-
-                    sp_item_snappoints(root_item, SnapPointsIter(*_points_to_snap_to), &_snapmanager->snapprefs);
-
-                    if (_snap_to_itempath) {
-                        _snapmanager->snapprefs.setSnapIntersectionCS(old_pref);
-                    }
-                }
-            }
+                       if (p_is_a_node || !(_snapmanager->snapprefs.getStrictSnapping() && !p_is_a_node) || p_is_a_guide) {
+                               // Note: there are two ways in which intersections are considered:
+                               // Method 1: Intersections are calculated for each shape individually, for both the
+                               //           snap source and snap target (see sp_shape_snappoints)
+                               // Method 2: Intersections are calculated for each curve or line that we've snapped to, i.e. only for
+                               //           the target (see the intersect() method in the SnappedCurve and SnappedLine classes)
+                               // Some differences:
+                               // - Method 1 doesn't find intersections within a set of multiple objects
+                               // - Method 2 only works for targets
+                               // When considering intersections as snap targets:
+                               // - Method 1 only works when snapping to nodes, whereas
+                               // - Method 2 only works when snapping to paths
+                               // - There will be performance differences too!
+                               // If both methods are being used simultaneously, then this might lead to duplicate targets!
+
+                               // Well, here we will be looking for snap TARGETS. Both methods can therefore be used.
+                               // When snapping to paths, we will get a collection of snapped lines and snapped curves. findBestSnap() will
+                               // go hunting for intersections (but only when asked to in the prefs of course). In that case we can just
+                               // temporarily block the intersections in sp_item_snappoints, we don't need duplicates. If we're not snapping to
+                               // paths though but only to item nodes then we should still look for the intersections in sp_item_snappoints()
+                               bool old_pref = _snapmanager->snapprefs.getSnapIntersectionCS();
+                               if (_snapmanager->snapprefs.getSnapToItemPath()) {
+                                       _snapmanager->snapprefs.setSnapIntersectionCS(false);
+                               }
+
+                               sp_item_snappoints(root_item, SnapPointsIter(*_points_to_snap_to), &_snapmanager->snapprefs);
+
+                               if (_snapmanager->snapprefs.getSnapToItemPath()) {
+                                       _snapmanager->snapprefs.setSnapIntersectionCS(old_pref);
+                               }
+                       }
 
             //Collect the bounding box's corners so we can snap to them
-            if (_snap_to_bboxnode) {
-                if (!(_strict_snapping && !p_is_a_bbox) || p_is_a_guide) {
-                    // Discard the bbox of a clipped path / mask, because we don't want to snap to both the bbox
-                    // of the item AND the bbox of the clipping path at the same time
-                    if (!(*i).clip_or_mask) {
-                        Geom::OptRect b = sp_item_bbox_desktop(root_item, bbox_type);
-                        getBBoxPoints(b, _points_to_snap_to, _snapmanager->snapprefs.getSnapMidpoints());
-                    }
-                }
-            }
+                       if (p_is_a_bbox || !(_snapmanager->snapprefs.getStrictSnapping() && !p_is_a_bbox) || p_is_a_guide) {
+                               // Discard the bbox of a clipped path / mask, because we don't want to snap to both the bbox
+                               // of the item AND the bbox of the clipping path at the same time
+                               if (!(*i).clip_or_mask) {
+                                       Geom::OptRect b = sp_item_bbox_desktop(root_item, bbox_type);
+                                       getBBoxPoints(b, _points_to_snap_to, _snapmanager->snapprefs.getSnapToBBoxNode(), _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints(), _snapmanager->snapprefs.getSnapBBoxMidpoints());
+                               }
+                       }
         }
     }
 }
@@ -324,7 +318,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
 
         bool p_is_a_node = t & Inkscape::SnapPreferences::SNAPPOINT_NODE;
 
-        if (_snap_to_bboxpath) {
+        if (_snapmanager->snapprefs.getSnapToBBoxPath()) {
             Inkscape::Preferences *prefs = Inkscape::Preferences::get();
             int prefs_bbox = prefs->getBool("/tools/bounding_box", 0);
             bbox_type = !prefs_bbox ?
@@ -332,7 +326,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
         }
 
         // Consider the page border for snapping
-        if (_snap_to_page_border) {
+        if (_snapmanager->snapprefs.getSnapToPageBorder()) {
             Geom::PathVector *border_path = _getBorderPathv();
             if (border_path != NULL) {
                 _paths_to_snap_to->push_back(border_path);
@@ -357,8 +351,8 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
             //Build a list of all paths considered for snapping to
 
             //Add the item's path to snap to
-            if (_snap_to_itempath) {
-                if (!(_strict_snapping && !p_is_a_node)) {
+            if (_snapmanager->snapprefs.getSnapToItemPath()) {
+                if (!(_snapmanager->snapprefs.getStrictSnapping() && !p_is_a_node)) {
                     // Snapping to the path of characters is very cool, but for a large
                     // chunk of text this will take ages! So limit snapping to text paths
                     // containing max. 240 characters. Snapping the bbox will not be affected
@@ -391,8 +385,8 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
             }
 
             //Add the item's bounding box to snap to
-            if (_snap_to_bboxpath) {
-                if (!(_strict_snapping && p_is_a_node)) {
+            if (_snapmanager->snapprefs.getSnapToBBoxPath()) {
+                if (!(_snapmanager->snapprefs.getStrictSnapping() && p_is_a_node)) {
                     // Discard the bbox of a clipped path / mask, because we don't want to snap to both the bbox
                     // of the item AND the bbox of the clipping path at the same time
                     if (!(*i).clip_or_mask) {
@@ -422,7 +416,7 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc,
     g_assert(_snapmanager->getDesktop() != NULL);
     Geom::Point const p_doc = _snapmanager->getDesktop()->dt2doc(p);
 
-    bool const node_tool_active = _snap_to_itempath && selected_path != NULL;
+    bool const node_tool_active = _snapmanager->snapprefs.getSnapToItemPath() && selected_path != NULL;
 
     if (first_point) {
         /* findCandidates() is used for snapping to both paths and nodes. It ignores the path that is
@@ -591,11 +585,15 @@ void Inkscape::ObjectSnapper::freeSnap(SnappedConstraints &sc,
         _findCandidates(sp_document_root(_snapmanager->getDocument()), it, first_point, local_bbox_to_snap, TRANSL_SNAP_XY, false, Geom::identity());
     }
 
-    if (_snap_to_itemnode || _snap_to_bboxnode || _snap_to_page_border) {
+    if (_snapmanager->snapprefs.getSnapToItemNode() || _snapmanager->snapprefs.getSnapSmoothNodes()
+       || _snapmanager->snapprefs.getSnapToBBoxNode() || _snapmanager->snapprefs.getSnapToPageBorder()
+               || _snapmanager->snapprefs.getSnapLineMidpoints() || _snapmanager->snapprefs.getSnapObjectMidpoints()
+               || _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints() || _snapmanager->snapprefs.getSnapBBoxMidpoints()
+               || _snapmanager->snapprefs.getIncludeItemCenter()) {
         _snapNodes(sc, t, p, first_point, unselected_nodes);
     }
 
-    if (_snap_to_itempath || _snap_to_bboxpath || _snap_to_page_border) {
+    if (_snapmanager->snapprefs.getSnapToItemPath() || _snapmanager->snapprefs.getSnapToBBoxPath() || _snapmanager->snapprefs.getSnapToPageBorder()) {
         unsigned n = (unselected_nodes == NULL) ? 0 : unselected_nodes->size();
         if (n > 0) {
             /* While editing a path in the node tool, findCandidates must ignore that path because
@@ -643,7 +641,7 @@ void Inkscape::ObjectSnapper::constrainedSnap( SnappedConstraints &sc,
     // to objects we will only consider the object's paths. Beside, the nodes will be at these paths,
     // so we will more or less snap to them anyhow.
 
-    if (_snap_to_itempath || _snap_to_bboxpath || _snap_to_page_border) {
+    if (_snapmanager->snapprefs.getSnapToItemPath() || _snapmanager->snapprefs.getSnapToBBoxPath() || _snapmanager->snapprefs.getSnapToPageBorder()) {
         _snapPathsConstrained(sc, t, p, first_point, c);
     }
 }
@@ -687,13 +685,21 @@ void Inkscape::ObjectSnapper::guideSnap(SnappedConstraints &sc,
  */
 bool Inkscape::ObjectSnapper::ThisSnapperMightSnap() const
 {
-    bool snap_to_something = _snap_to_itempath || _snap_to_itemnode || _snap_to_bboxpath || _snap_to_bboxnode || _snap_to_page_border;
+    bool snap_to_something = _snapmanager->snapprefs.getSnapToItemPath()
+                                               || _snapmanager->snapprefs.getSnapToItemNode()
+                                               || _snapmanager->snapprefs.getSnapToBBoxPath()
+                                               || _snapmanager->snapprefs.getSnapToBBoxNode()
+                                               || _snapmanager->snapprefs.getSnapToPageBorder()
+                                               || _snapmanager->snapprefs.getSnapLineMidpoints() || _snapmanager->snapprefs.getSnapObjectMidpoints()
+                                               || _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints() || _snapmanager->snapprefs.getSnapBBoxMidpoints()
+                                               || _snapmanager->snapprefs.getIncludeItemCenter();
+
     return (_snap_enabled && _snapmanager->snapprefs.getSnapModeBBoxOrNodes() && snap_to_something);
 }
 
 bool Inkscape::ObjectSnapper::GuidesMightSnap() const
 {
-    bool snap_to_something = _snap_to_itemnode || _snap_to_bboxnode;
+    bool snap_to_something = _snapmanager->snapprefs.getSnapToItemNode() || _snapmanager->snapprefs.getSnapToBBoxNode();
     return (_snap_enabled && _snapmanager->snapprefs.getSnapModeGuide() && snap_to_something);
 }
 
@@ -732,17 +738,22 @@ void Inkscape::ObjectSnapper::_getBorderNodes(std::vector<Geom::Point> *points)
     points->push_back(Geom::Point(w,0));
 }
 
-void Inkscape::getBBoxPoints(Geom::OptRect const bbox, std::vector<Geom::Point> *points, bool const includeMidpoints)
+void Inkscape::getBBoxPoints(Geom::OptRect const bbox, std::vector<Geom::Point> *points, bool const includeCorners, bool const includeLineMidpoints, bool const includeObjectMidpoints)
 {
        if (bbox) {
                // collect the corners of the bounding box
                for ( unsigned k = 0 ; k < 4 ; k++ ) {
-                       points->push_back(bbox->corner(k));
+                       if (includeCorners) {
+                               points->push_back(bbox->corner(k));
+                       }
                        // optionally, collect the midpoints of the bounding box's edges too
-                       if (includeMidpoints) {
+                       if (includeLineMidpoints) {
                                points->push_back((bbox->corner(k) + bbox->corner((k+1) % 4))/2);
                        }
                }
+               if (includeObjectMidpoints) {
+                       points->push_back(bbox->midpoint());
+               }
        }
 }
 
index 9151dbd8acd34e0eba4c7eeddc3ba1649331897d..9c391a90f7623c0c436fd65462f3c5d6ba8f6ec5 100644 (file)
@@ -56,16 +56,6 @@ public:
           ANGLED_GUIDE_ROT_SNAP, // For snapping an angled guide, while rotating it around some pivot point
           TRANSL_SNAP_XY}; // All other cases; for snapping to objects, other than guides
 
-    void setSnapToItemNode(bool s) {_snap_to_itemnode = s;}
-      bool getSnapToItemNode() const {return _snap_to_itemnode;}
-      void setSnapToItemPath(bool s) {_snap_to_itempath = s;}
-      bool getSnapToItemPath() const {return _snap_to_itempath;}
-      void setSnapToBBoxNode(bool s) {_snap_to_bboxnode = s;}
-      bool getSnapToBBoxNode() const {return _snap_to_bboxnode;}
-      void setSnapToBBoxPath(bool s) {_snap_to_bboxpath = s;}
-      bool getSnapToBBoxPath() const {return _snap_to_bboxpath;}
-      void setSnapToPageBorder(bool s) {_snap_to_page_border = s;}
-      bool getSnapToPageBorder() const {return _snap_to_page_border;}
       void guideSnap(SnappedConstraints &sc,
                    Geom::Point const &p,
                  Geom::Point const &guide_normal) const;
@@ -140,20 +130,9 @@ private:
     Geom::PathVector* _getPathvFromRect(Geom::Rect const rect) const;
     void _getBorderNodes(std::vector<Geom::Point> *points) const;
 
-    bool _snap_to_itemnode;
-    bool _snap_to_itempath;
-    bool _snap_to_bboxnode;
-    bool _snap_to_bboxpath;
-    bool _snap_to_page_border;
-
-    //If enabled, then bbox corners will only snap to bboxes,
-    //and nodes will only snap to nodes and paths. We will not
-    //snap bbox corners to nodes, or nodes to bboxes.
-    //(snapping to grids and guides is not affected by this)
-    bool _strict_snapping;
 }; // end of ObjectSnapper class
 
-void getBBoxPoints(Geom::OptRect const bbox, std::vector<Geom::Point> *points, bool const includeMidpoints);
+void getBBoxPoints(Geom::OptRect const bbox, std::vector<Geom::Point> *points, bool const includeCorners, bool const includeLineMidpoints, bool const includeObjectMidpoints);
 
 } // end of namespace Inkscape
 
index 1055e55ef6f76146fa2ed5f2b3c84c2807996c60..0fd15593c78ae910c35670e33bc357a6e8354ea5 100644 (file)
@@ -285,16 +285,20 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
 
     // Next, get all points to consider for snapping
     SnapManager const &m = _desktop->namedview->snap_manager;
+       Inkscape::SnapPreferences local_snapprefs = m.snapprefs;
+       local_snapprefs.setSnapToItemNode(true); // We should get at least the cusp nodes here. This might
+       // have been turned off because (for example) the user only want paths as a snap target, not nodes
+       // but as a snap source we still need some nodes though!
     _snap_points.clear();
-    _snap_points = selection->getSnapPoints(&m.snapprefs);
-    std::vector<Geom::Point> snap_points_hull = selection->getSnapPointsConvexHull(&m.snapprefs);
-    if (_snap_points.size() > 100) {
-        /* Snapping a huge number of nodes will take way too long, so limit the number of snappable nodes
-        An average user would rarely ever try to snap such a large number of nodes anyway, because
-        (s)he could hardly discern which node would be snapping */
-        _snap_points = snap_points_hull;
-        // Unfortunately, by now we will have lost the font-baseline snappoints :-(
-    }
+       _snap_points = selection->getSnapPoints(&local_snapprefs);
+       std::vector<Geom::Point> snap_points_hull = selection->getSnapPointsConvexHull(&local_snapprefs);
+       if (_snap_points.size() > 100) {
+               /* Snapping a huge number of nodes will take way too long, so limit the number of snappable nodes
+               An average user would rarely ever try to snap such a large number of nodes anyway, because
+               (s)he could hardly discern which node would be snapping */
+               _snap_points = snap_points_hull;
+               // Unfortunately, by now we will have lost the font-baseline snappoints :-(
+       }
 
     // Find bbox hulling all special points, which excludes stroke width. Here we need to include the
     // path nodes, for example because a rectangle which has been converted to a path doesn't have
@@ -312,7 +316,9 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
 
     _bbox_points.clear();
     if (_bbox) {
-       getBBoxPoints(_bbox, &_bbox_points, m.snapprefs.getSnapMidpoints());
+       if (m.snapprefs.getSnapModeBBox()) {
+               getBBoxPoints(_bbox, &_bbox_points, true, m.snapprefs.getSnapBBoxEdgeMidpoints(), m.snapprefs.getSnapBBoxMidpoints());
+       }
        // There are two separate "opposites" (i.e. opposite w.r.t. the handle being dragged):
         //  - one for snapping the boundingbox, which can be either visual or geometric
         //  - one for snapping the special points
index 0bfd94c71f2e93384f744b824828cf2a14148bd6..d212599839334450c12656aa5d1b5d537c031ace 100644 (file)
@@ -23,18 +23,22 @@ Inkscape::SnapPreferences::PointType const Inkscape::SnapPreferences::SNAPPOINT_
 Inkscape::SnapPreferences::SnapPreferences() :
        _include_item_center(false),
     _snap_enabled_globally(true),
-    _snap_postponed_globally(false)
+    _snap_postponed_globally(false),
+    _snap_to_itemnode(true), _snap_to_itempath(true),
+       _snap_to_bboxnode(true), _snap_to_bboxpath(true),
+       _snap_to_page_border(false),
+       _strict_snapping(true)
 {
        setSnapFrom(SNAPPOINT_BBOX | SNAPPOINT_NODE, true); //Snap any point. In v0.45 and earlier, this was controlled in the preferences tab
 }
 
 /*
  *  The snappers have too many parameters to adjust individually. Therefore only
- *  two snapping modes are presented to the user: snapping bounding box corners (to 
+ *  two snapping modes are presented to the user: snapping bounding box corners (to
  *  other bounding boxes, grids or guides), and/or snapping nodes (to other nodes,
- *  paths, grids or guides). To select either of these modes (or both), use the 
+ *  paths, grids or guides). To select either of these modes (or both), use the
  *  methods defined below: setSnapModeBBox() and setSnapModeNode().
- * 
+ *
  * */
 
 
index a52e0cfd9a32d079ffee2f9f4a0846af3387d586..97ef3cec210081653894a629c926bf953e0bed4c 100644 (file)
@@ -39,11 +39,17 @@ public:
     void setSnapIntersectionGG(bool enabled) {_intersectionGG = enabled;}
     void setSnapIntersectionCS(bool enabled) {_intersectionCS = enabled;}
     void setSnapSmoothNodes(bool enabled) {_smoothNodes = enabled;}
-    void setSnapMidpoints(bool enabled) {_midpoints = enabled;}
+    void setSnapLineMidpoints(bool enabled) {_line_midpoints = enabled;}
+    void setSnapObjectMidpoints(bool enabled) {_object_midpoints = enabled;}
+    void setSnapBBoxEdgeMidpoints(bool enabled) {_bbox_edge_midpoints = enabled;}
+       void setSnapBBoxMidpoints(bool enabled) {_bbox_midpoints = enabled;}
     bool getSnapIntersectionGG() const {return _intersectionGG;}
     bool getSnapIntersectionCS() const {return _intersectionCS;}
     bool getSnapSmoothNodes() const {return _smoothNodes;}
-    bool getSnapMidpoints() const {return _midpoints;}
+    bool getSnapLineMidpoints() const {return _line_midpoints;}
+    bool getSnapObjectMidpoints() const {return _object_midpoints;}
+    bool getSnapBBoxEdgeMidpoints() const {return _bbox_edge_midpoints;}
+       bool getSnapBBoxMidpoints() const {return _bbox_midpoints;}
 
     void setIncludeItemCenter(bool enabled) {_include_item_center = enabled;}
     bool getIncludeItemCenter() const {return _include_item_center;}
@@ -57,16 +63,43 @@ public:
     void setSnapFrom(PointType t, bool s);
     bool getSnapFrom(PointType t) const;
 
+    // These will only be used for the object snapper
+    void setSnapToItemNode(bool s) {_snap_to_itemnode = s;}
+       bool getSnapToItemNode() const {return _snap_to_itemnode;}
+       void setSnapToItemPath(bool s) {_snap_to_itempath = s;}
+       bool getSnapToItemPath() const {return _snap_to_itempath;}
+       void setSnapToBBoxNode(bool s) {_snap_to_bboxnode = s;}
+       bool getSnapToBBoxNode() const {return _snap_to_bboxnode;}
+       void setSnapToBBoxPath(bool s) {_snap_to_bboxpath = s;}
+       bool getSnapToBBoxPath() const {return _snap_to_bboxpath;}
+       void setSnapToPageBorder(bool s) {_snap_to_page_border = s;}
+       bool getSnapToPageBorder() const {return _snap_to_page_border;}
+       bool getStrictSnapping() const {return _strict_snapping;}
+
 private:
     bool _include_item_center; //If true, snapping nodes will also snap the item's center
     bool _intersectionGG; //Consider snapping to intersections of grid and guides
     bool _intersectionCS; //Consider snapping to intersections of curves
     bool _smoothNodes;
-    bool _midpoints;
+    bool _line_midpoints;
+    bool _object_midpoints; // the midpoint of shapes (e.g. a circle, rect, polygon) or of any other shape (at [h/2, w/2])
+    bool _bbox_edge_midpoints;
+       bool _bbox_midpoints;
     bool _snap_enabled_globally; // Toggles ALL snapping
     bool _snap_postponed_globally; // Hold all snapping temporarily when the mouse is moving fast
     PointType _snap_from; ///< bitmap of point types that we will snap from
 
+    // These will only be used for the object snapper
+    bool _snap_to_itemnode;
+       bool _snap_to_itempath;
+       bool _snap_to_bboxnode;
+       bool _snap_to_bboxpath;
+       bool _snap_to_page_border;
+       //If enabled, then bbox corners will only snap to bboxes,
+       //and nodes will only snap to nodes and paths. We will not
+       //snap bbox corners to nodes, or nodes to bboxes.
+       //(snapping to grids and guides is not affected by this)
+       bool _strict_snapping;
 };
 
 }
index a6c4b87296fb07fd13045abe00edc8ac8dcabf9b..24cfefe0ba53024633648f31a275a5e41d597560 100644 (file)
@@ -107,6 +107,25 @@ bool SnapManager::someSnapperMightSnap() const
     return (i != s.end());
 }
 
+/**
+ * \return true if one of the snappers will try to snap something.
+ */
+
+bool SnapManager::gridSnapperMightSnap() const
+{
+    if ( !snapprefs.getSnapEnabledGlobally() || snapprefs.getSnapPostponedGlobally() ) {
+        return false;
+    }
+
+    SnapperList const s = getGridSnappers();
+    SnapperList::const_iterator i = s.begin();
+    while (i != s.end() && (*i)->ThisSnapperMightSnap() == false) {
+        i++;
+    }
+
+    return (i != s.end());
+}
+
 /**
  *  Try to snap a point to any of the specified snappers.
  *
index 14adf399facbb4e564653ee6a7f068beb55e776b..177e9b529fc0cc3f485526fe45cd2e5687b3f10e 100644 (file)
@@ -54,6 +54,7 @@ public:
     typedef std::list<const Inkscape::Snapper*> SnapperList;
 
     bool someSnapperMightSnap() const;
+    bool gridSnapperMightSnap() const;
 
     void setup(SPDesktop const *desktop, bool snapindicator = true, SPItem const *item_to_ignore = NULL, std::vector<Geom::Point> *unselected_nodes = NULL);
     void setup(SPDesktop const *desktop, bool snapindicator, std::vector<SPItem const *> &items_to_ignore, std::vector<Geom::Point> *unselected_nodes = NULL);
index c7ed88513a4ae8e51e520e78a9a16358c05962d6..0d28e9f6b370b2c94c2aca77ddd1df4b39b3348a 100644 (file)
@@ -257,16 +257,21 @@ static void sp_genericellipse_set_shape(SPShape *shape)
     curve->unref();
 }
 
-static void sp_genericellipse_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const */*snapprefs*/)
+static void sp_genericellipse_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
 {
     g_assert(item != NULL);
     g_assert(SP_IS_GENERICELLIPSE(item));
 
+    // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
+       if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
+               return;
+       }
+
     SPGenericEllipse *ellipse = SP_GENERICELLIPSE(item);
     sp_genericellipse_normalize(ellipse);
     Geom::Matrix const i2d = sp_item_i2d_affine(item);
 
-    // figure out if we have a slice, whilst guarding against rounding errors
+    // figure out if we have a slice, while guarding against rounding errors
     bool slice = false;
     double len = fmod(ellipse->end - ellipse->start, SP_2PI);
     if (len < 0.0) len += SP_2PI;
@@ -284,19 +289,22 @@ static void sp_genericellipse_snappoints(SPItem const *item, SnapPointsIter p, I
 
     // Snap to the 4 quadrant points of the ellipse, but only if the arc
     // spans far enough to include them
-    double angle = 0;
-    for (angle = 0; angle < SP_2PI; angle += M_PI_2) {
-        if (angle >= ellipse->start && angle <= ellipse->end) {
-            *p = Geom::Point(cx + cos(angle)*rx, cy + sin(angle)*ry) * i2d;
-        }
+    if (snapprefs->getSnapToItemNode()) { //TODO: Make a separate snap option toggle for this?
+               double angle = 0;
+               for (angle = 0; angle < SP_2PI; angle += M_PI_2) {
+                       if (angle >= ellipse->start && angle <= ellipse->end) {
+                               *p = Geom::Point(cx + cos(angle)*rx, cy + sin(angle)*ry) * i2d;
+                       }
+               }
     }
 
-    // And if we have a slice, also snap to the endpoints and the centre point
-    if (slice) {
-        // Add the centre, if we have a closed slice
-        if (ellipse->closed) {
-            *p = Geom::Point(cx, cy) * i2d;
-        }
+    // Add the centre, if we have a closed slice or when explicitly asked for
+    if ((snapprefs->getSnapToItemNode() && slice && ellipse->closed) || snapprefs->getSnapObjectMidpoints()) {
+       *p = Geom::Point(cx, cy) * i2d;
+    }
+
+    // And if we have a slice, also snap to the endpoints
+    if (snapprefs->getSnapToItemNode() && slice) {
         // Add the start point, if it's not coincident with a quadrant point
         if (fmod(ellipse->start, M_PI_2) != 0.0 ) {
             *p = Geom::Point(cx + cos(ellipse->start)*rx, cy + sin(ellipse->start)*ry) * i2d;
index 8971c3abbd240951e11d07d2012ac7ec74589e6a..2ac480341a4ef469a9194ed439bff6f249a517ea 100644 (file)
@@ -973,7 +973,7 @@ void sp_item_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPref
 
     // Get the snappoints at the item's center
     if (snapprefs != NULL && snapprefs->getIncludeItemCenter()) {
-        *p = item->getCenter();
+       *p = item->getCenter();
     }
 
     // Get the snappoints of clipping paths and mask, if any
index c46f30e0696ddca39e83e758b3b64b2b1d3349a2..4ff66f6c38cf7316aefc1d7331ea98e343357a85 100644 (file)
@@ -249,7 +249,10 @@ static void sp_namedview_build(SPObject *object, SPDocument *document, Inkscape:
     sp_object_read_attr(object, "inkscape:snap-center");
     sp_object_read_attr(object, "inkscape:snap-smooth-nodes");
     sp_object_read_attr(object, "inkscape:snap-midpoints");
-    sp_object_read_attr(object, "inkscape:snap-intersection-grid-guide");
+    sp_object_read_attr(object, "inkscape:snap-object-midpoints");
+    sp_object_read_attr(object, "inkscape:snap-bbox-edge-midpoints");
+    sp_object_read_attr(object, "inkscape:snap-bbox-midpoints");
+       sp_object_read_attr(object, "inkscape:snap-intersection-grid-guide");
     sp_object_read_attr(object, "inkscape:snap-intersection-paths");
     sp_object_read_attr(object, "inkscape:object-paths");
     sp_object_read_attr(object, "inkscape:object-nodes");
@@ -471,11 +474,23 @@ static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *va
             nv->snap_manager.snapprefs.setSnapSmoothNodes(value ? sp_str_to_bool(value) : FALSE);
             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
-    case SP_ATTR_INKSCAPE_SNAP_MIDPOINTS:
-            nv->snap_manager.snapprefs.setSnapMidpoints(value ? sp_str_to_bool(value) : FALSE);
+    case SP_ATTR_INKSCAPE_SNAP_LINE_MIDPOINTS:
+            nv->snap_manager.snapprefs.setSnapLineMidpoints(value ? sp_str_to_bool(value) : FALSE);
             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
-    case SP_ATTR_INKSCAPE_SNAP_GUIDE:
+    case SP_ATTR_INKSCAPE_SNAP_OBJECT_MIDPOINTS:
+                       nv->snap_manager.snapprefs.setSnapObjectMidpoints(value ? sp_str_to_bool(value) : FALSE);
+                       object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+                       break;
+    case SP_ATTR_INKSCAPE_SNAP_BBOX_EDGE_MIDPOINTS:
+                       nv->snap_manager.snapprefs.setSnapBBoxEdgeMidpoints(value ? sp_str_to_bool(value) : FALSE);
+                       object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+                       break;
+       case SP_ATTR_INKSCAPE_SNAP_BBOX_MIDPOINTS:
+                       nv->snap_manager.snapprefs.setSnapBBoxMidpoints(value ? sp_str_to_bool(value) : FALSE);
+                       object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+                       break;
+       case SP_ATTR_INKSCAPE_SNAP_GUIDE:
             nv->snap_manager.snapprefs.setSnapModeGuide(value ? sp_str_to_bool(value) : FALSE);
             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
@@ -488,23 +503,23 @@ static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *va
             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
     case SP_ATTR_INKSCAPE_OBJECT_PATHS:
-            nv->snap_manager.object.setSnapToItemPath(value ? sp_str_to_bool(value) : FALSE);
+            nv->snap_manager.snapprefs.setSnapToItemPath(value ? sp_str_to_bool(value) : FALSE);
             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
     case SP_ATTR_INKSCAPE_OBJECT_NODES:
-            nv->snap_manager.object.setSnapToItemNode(value ? sp_str_to_bool(value) : FALSE);
+            nv->snap_manager.snapprefs.setSnapToItemNode(value ? sp_str_to_bool(value) : FALSE);
             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
     case SP_ATTR_INKSCAPE_BBOX_PATHS:
-            nv->snap_manager.object.setSnapToBBoxPath(value ? sp_str_to_bool(value) : FALSE);
+            nv->snap_manager.snapprefs.setSnapToBBoxPath(value ? sp_str_to_bool(value) : FALSE);
             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
     case SP_ATTR_INKSCAPE_BBOX_NODES:
-            nv->snap_manager.object.setSnapToBBoxNode(value ? sp_str_to_bool(value) : FALSE);
+            nv->snap_manager.snapprefs.setSnapToBBoxNode(value ? sp_str_to_bool(value) : FALSE);
             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
     case SP_ATTR_INKSCAPE_SNAP_PAGE:
-            nv->snap_manager.object.setSnapToPageBorder(value ? sp_str_to_bool(value) : FALSE);
+            nv->snap_manager.snapprefs.setSnapToPageBorder(value ? sp_str_to_bool(value) : FALSE);
             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
     case SP_ATTR_INKSCAPE_CURRENT_LAYER:
index 2f3fc1864acab40039b0c3e3f4d4144df0c1b160..c2fe527b664ab40aa7e95458d3ba077dee02c771 100644 (file)
@@ -556,6 +556,11 @@ static void sp_rect_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::S
     g_assert(item != NULL);
     g_assert(SP_IS_RECT(item));
 
+    // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
+       if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
+               return;
+       }
+
     SPRect *rect = SP_RECT(item);
 
     Geom::Matrix const i2d (sp_item_i2d_affine (item));
@@ -565,17 +570,24 @@ static void sp_rect_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::S
     Geom::Point p2 = Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed) * i2d;
     Geom::Point p3 = Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed) * i2d;
 
-    *p = p0;
-    *p = p1;
-    *p = p2;
-    *p = p3;
-
-    if (snapprefs->getSnapMidpoints()) {
-       *p = (p0 + p1)/2;
-       *p = (p1 + p2)/2;
-       *p = (p2 + p3)/2;
-       *p = (p3 + p0)/2;
+    if (snapprefs->getSnapToItemNode()) {
+               *p = p0;
+               *p = p1;
+               *p = p2;
+               *p = p3;
     }
+
+       if (snapprefs->getSnapLineMidpoints()) { // only do this when we're snapping nodes (enforce strict snapping)
+               *p = (p0 + p1)/2;
+               *p = (p1 + p2)/2;
+               *p = (p2 + p3)/2;
+               *p = (p3 + p0)/2;
+       }
+
+       if (snapprefs->getSnapObjectMidpoints()) { // only do this when we're snapping nodes (enforce strict snapping)
+               *p = (p0 + p2)/2;
+       }
+
 }
 
 void
index ce73888ed168b8cd00ee3b8558cf53ca7c98bd20..4adf883a46ddd230d9c20946c10e51c76bbc282f 100644 (file)
@@ -1067,14 +1067,28 @@ static void sp_shape_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::
         return;
     }
 
+    // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
+    if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
+       return;
+    }
+
     Geom::PathVector const &pathv = shape->curve->get_pathvector();
     if (pathv.empty())
         return;
 
     Geom::Matrix const i2d (sp_item_i2d_affine (item));
 
+       if (snapprefs->getSnapObjectMidpoints()) {
+               Geom::OptRect bbox = item->getBounds(sp_item_i2d_affine(item));
+               if (bbox) {
+                       *p = bbox->midpoint();
+               }
+       }
+
     for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) {
-        *p = path_it->initialPoint() * i2d;
+        if (snapprefs->getSnapToItemNode()) {
+               *p = path_it->initialPoint() * i2d;
+        }
 
         Geom::Path::const_iterator curve_it1 = path_it->begin();      // incoming curve
         Geom::Path::const_iterator curve_it2 = ++(path_it->begin());  // outgoing curve
@@ -1088,23 +1102,26 @@ static void sp_shape_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::
 
             Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, *curve_it2);
 
-            // Depending on the snapping preferences, either add only cusp nodes, or add add both cusp and smooth nodes
-            if (snapprefs->getSnapSmoothNodes() || nodetype == Geom::NODE_NONE || nodetype == Geom::NODE_CUSP) {
-                *p = curve_it1->finalPoint() * i2d;
-            }
+            bool c1 = snapprefs->getSnapToItemNode() && (nodetype == Geom::NODE_CUSP || nodetype == Geom::NODE_NONE);
+            bool c2 = snapprefs->getSnapSmoothNodes() && (nodetype == Geom::NODE_SMOOTH || nodetype == Geom::NODE_SYMM);
 
-            // Consider midpoints of line segments for snapping
-            if (snapprefs->getSnapMidpoints()) {
-               if (Geom::LineSegment const* line_segment = dynamic_cast<Geom::LineSegment const*>(&(*curve_it1))) {
-                    *p = Geom::middle_point(*line_segment) * i2d;
-                }
+            if (c1 || c2) {
+                               *p = curve_it1->finalPoint() * i2d;
             }
 
+                       // Consider midpoints of line segments for snapping
+                       if (snapprefs->getSnapLineMidpoints()) { // only do this when we're snapping nodes (enforce strict snapping)
+                               if (Geom::LineSegment const* line_segment = dynamic_cast<Geom::LineSegment const*>(&(*curve_it1))) {
+                                       *p = Geom::middle_point(*line_segment) * i2d;
+                               }
+                       }
+
             ++curve_it1;
             ++curve_it2;
         }
 
-        // Find the internal intersections of each path and consider these for snapping (using "Method 1" as desciribed in Inkscape::ObjectSnapper::_collectNodes())
+        // Find the internal intersections of each path and consider these for snapping
+        // (using "Method 1" as described in Inkscape::ObjectSnapper::_collectNodes())
         if (snapprefs->getSnapIntersectionCS()) {
             Geom::Crossings cs;
             cs = self_crossings(*path_it);
@@ -1117,8 +1134,6 @@ static void sp_shape_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::
         }
     }
 
-
-
 }
 
 /*
index 377cc13f4264ee67cf070d8032134978a066a47a..624c5ae181ad7513a2200cac5e1c79373270043a 100644 (file)
@@ -426,7 +426,7 @@ sp_spiral_set_shape (SPShape *shape)
        SP_OBJECT (spiral)->requestModified(SP_OBJECT_MODIFIED_FLAG);
 
        SPCurve *c = new SPCurve ();
-       
+
 #ifdef SPIRAL_VERBOSE
        g_print ("cx=%g, cy=%g, exp=%g, revo=%g, rad=%g, arg=%g, t0=%g\n",
                 spiral->cx,
@@ -496,7 +496,7 @@ sp_spiral_position_set       (SPSpiral          *spiral,
        spiral->rad        = MAX (rad, 0.001);
        spiral->arg        = arg;
        spiral->t0         = CLAMP(t0, 0.0, 0.999);
-       
+
        ((SPObject *)spiral)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 }
 
@@ -505,8 +505,26 @@ sp_spiral_position_set       (SPSpiral          *spiral,
  */
 static void sp_spiral_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
 {
+       // We will determine the spiral's midpoint ourselves, instead of trusting on the base class
+       // Therefore setSnapObjectMidpoints() is set to false temporarily
+       Inkscape::SnapPreferences local_snapprefs = *snapprefs;
+       local_snapprefs.setSnapObjectMidpoints(false);
+
        if (((SPItemClass *) parent_class)->snappoints) {
-               ((SPItemClass *) parent_class)->snappoints (item, p, snapprefs);
+               ((SPItemClass *) parent_class)->snappoints (item, p, &local_snapprefs);
+       }
+
+       // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
+       if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
+               return;
+       }
+
+       if (snapprefs->getSnapObjectMidpoints()) {
+               Geom::Matrix const i2d (sp_item_i2d_affine (item));
+               SPSpiral *spiral = SP_SPIRAL(item);
+               *p = Geom::Point(spiral->cx, spiral->cy) * i2d;
+               // This point is the start-point of the spiral, which is also returned when _snap_to_itemnode has been set
+               // in the object snapper. In that case we will get a duplicate!
        }
 }
 
index bbf8082096b50b0d6d283a4f9ea701c89a9077ef..c1581a6d6d7bc3baa131f52680b1bde2f0d31b00 100644 (file)
@@ -429,7 +429,7 @@ sp_star_set_shape (SPShape *shape)
        SPStar *star = SP_STAR (shape);
 
        SPCurve *c = new SPCurve ();
-       
+
        gint sides = star->sides;
        bool not_rounded = (fabs (star->rounded) < 1e-4);
 
@@ -474,7 +474,7 @@ sp_star_set_shape (SPShape *shape)
                        }
                }
        }
-       
+
        // draw last segment
                if (not_rounded) {
                        c->lineto(sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true));
@@ -511,7 +511,7 @@ sp_star_position_set (SPStar *star, gint sides, Geom::Point center, gdouble r1,
 {
        g_return_if_fail (star != NULL);
        g_return_if_fail (SP_IS_STAR (star));
-       
+
        star->sides = CLAMP (sides, 3, 1024);
        star->center = center;
        star->r[0] = MAX (r1, 0.001);
@@ -528,12 +528,25 @@ sp_star_position_set (SPStar *star, gint sides, Geom::Point center, gdouble r1,
        SP_OBJECT(star)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 }
 
-/* fixme: We should use all corners of star (Lauris) */
-
 static void sp_star_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
 {
+       // We will determine the star's midpoint ourselves, instead of trusting on the base class
+       // Therefore setSnapObjectMidpoints() is set to false temporarily
+       Inkscape::SnapPreferences local_snapprefs = *snapprefs;
+       local_snapprefs.setSnapObjectMidpoints(false);
+
        if (((SPItemClass *) parent_class)->snappoints) {
-               ((SPItemClass *) parent_class)->snappoints (item, p, snapprefs);
+               ((SPItemClass *) parent_class)->snappoints (item, p, &local_snapprefs);
+       }
+
+       // Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
+       if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
+               return;
+       }
+
+       if (snapprefs->getSnapObjectMidpoints()) {
+               Geom::Matrix const i2d (sp_item_i2d_affine (item));
+               *p = SP_STAR(item)->center * i2d;
        }
 }
 
index b2b3d1e8155ede6efc8062a2126fe2ca8e2c205c..36861ad2c7f0db5b6c373c2d59775f657b0d14a2 100644 (file)
@@ -875,14 +875,14 @@ DocumentProperties::update()
     _rcbsng.setActive (nv->snap_manager.snapprefs.getSnapModeGuide());
     _rcbic.setActive (nv->snap_manager.snapprefs.getIncludeItemCenter());
     _rcbsm.setActive (nv->snap_manager.snapprefs.getSnapSmoothNodes());
-    _rcbmp.setActive (nv->snap_manager.snapprefs.getSnapMidpoints());
+    _rcbmp.setActive (nv->snap_manager.snapprefs.getSnapLineMidpoints());
     _rcbsigg.setActive (nv->snap_manager.snapprefs.getSnapIntersectionGG());
     _rcbsils.setActive (nv->snap_manager.snapprefs.getSnapIntersectionCS());
-    _rcbsnop.setActive(nv->snap_manager.object.getSnapToItemPath());
-    _rcbsnon.setActive(nv->snap_manager.object.getSnapToItemNode());
-    _rcbsnbbp.setActive(nv->snap_manager.object.getSnapToBBoxPath());
-    _rcbsnbbn.setActive(nv->snap_manager.object.getSnapToBBoxNode());
-    _rcbsnpb.setActive(nv->snap_manager.object.getSnapToPageBorder());
+    _rcbsnop.setActive(nv->snap_manager.snapprefs.getSnapToItemPath());
+    _rcbsnon.setActive(nv->snap_manager.snapprefs.getSnapToItemNode());
+    _rcbsnbbp.setActive(nv->snap_manager.snapprefs.getSnapToBBoxPath());
+    _rcbsnbbn.setActive(nv->snap_manager.snapprefs.getSnapToBBoxNode());
+    _rcbsnpb.setActive(nv->snap_manager.snapprefs.getSnapToPageBorder());
     _rsu_sno.setValue (nv->objecttolerance);
 
     _rsu_sn.setValue (nv->gridtolerance);
index 571e440f202930fff0b496113a8e27a29e2115b5..0acc7731ab7f31bdd037d2016623231dc8f20bab 100644 (file)
@@ -1909,11 +1909,11 @@ void toggle_snap_callback (GtkToggleAction *act, gpointer data) { //data points
                sp_repr_set_boolean(repr, "inkscape:snap-bbox", !v);
                break;
        case SP_ATTR_INKSCAPE_BBOX_PATHS:
-               v = nv->snap_manager.object.getSnapToBBoxPath();
+               v = nv->snap_manager.snapprefs.getSnapToBBoxPath();
                sp_repr_set_boolean(repr, "inkscape:bbox-paths", !v);
                break;
        case SP_ATTR_INKSCAPE_BBOX_NODES:
-               v = nv->snap_manager.object.getSnapToBBoxNode();
+               v = nv->snap_manager.snapprefs.getSnapToBBoxNode();
                sp_repr_set_boolean(repr, "inkscape:bbox-nodes", !v);
                break;
        case SP_ATTR_INKSCAPE_SNAP_NODES:
@@ -1921,21 +1921,17 @@ void toggle_snap_callback (GtkToggleAction *act, gpointer data) { //data points
                sp_repr_set_boolean(repr, "inkscape:snap-nodes", !v);
                break;
        case SP_ATTR_INKSCAPE_OBJECT_PATHS:
-               v = nv->snap_manager.object.getSnapToItemPath();
+               v = nv->snap_manager.snapprefs.getSnapToItemPath();
                sp_repr_set_boolean(repr, "inkscape:object-paths", !v);
                break;
        case SP_ATTR_INKSCAPE_OBJECT_NODES:
-               v = nv->snap_manager.object.getSnapToItemNode();
+               v = nv->snap_manager.snapprefs.getSnapToItemNode();
                sp_repr_set_boolean(repr, "inkscape:object-nodes", !v);
                break;
        case SP_ATTR_INKSCAPE_SNAP_SMOOTH_NODES:
                v = nv->snap_manager.snapprefs.getSnapSmoothNodes();
                sp_repr_set_boolean(repr, "inkscape:snap-smooth-nodes", !v);
                break;
-       case SP_ATTR_INKSCAPE_SNAP_MIDPOINTS:
-               v = nv->snap_manager.snapprefs.getSnapMidpoints();
-               sp_repr_set_boolean(repr, "inkscape:snap-midpoints", !v);
-               break;
        case SP_ATTR_INKSCAPE_SNAP_INTERS_PATHS:
                v = nv->snap_manager.snapprefs.getSnapIntersectionCS();
                sp_repr_set_boolean(repr, "inkscape:snap-intersection-paths", !v);
@@ -1945,13 +1941,29 @@ void toggle_snap_callback (GtkToggleAction *act, gpointer data) { //data points
                sp_repr_set_boolean(repr, "inkscape:snap-center", !v);
                break;
        case SP_ATTR_INKSCAPE_SNAP_PAGE:
-               v = nv->snap_manager.object.getSnapToPageBorder();
+               v = nv->snap_manager.snapprefs.getSnapToPageBorder();
                sp_repr_set_boolean(repr, "inkscape:snap-page", !v);
                break;
        case SP_ATTR_INKSCAPE_SNAP_INTERS_GRIDGUIDE:
                v = nv->snap_manager.snapprefs.getSnapIntersectionGG();
                sp_repr_set_boolean(repr, "inkscape:snap-intersection-grid-guide", !v);
                break;
+       case SP_ATTR_INKSCAPE_SNAP_LINE_MIDPOINTS:
+               v = nv->snap_manager.snapprefs.getSnapLineMidpoints();
+               sp_repr_set_boolean(repr, "inkscape:snap-midpoints", !v);
+               break;
+       case SP_ATTR_INKSCAPE_SNAP_OBJECT_MIDPOINTS:
+               v = nv->snap_manager.snapprefs.getSnapObjectMidpoints();
+               sp_repr_set_boolean(repr, "inkscape:snap-object-midpoints", !v);
+               break;
+       case SP_ATTR_INKSCAPE_SNAP_BBOX_EDGE_MIDPOINTS:
+               v = nv->snap_manager.snapprefs.getSnapBBoxEdgeMidpoints();
+               sp_repr_set_boolean(repr, "inkscape:snap-bbox-edge-midpoints", !v);
+               break;
+       case SP_ATTR_INKSCAPE_SNAP_BBOX_MIDPOINTS:
+               v = nv->snap_manager.snapprefs.getSnapBBoxMidpoints();
+               sp_repr_set_boolean(repr, "inkscape:snap-bbox-midpoints", !v);
+               break;
        default:
                g_warning("toggle_snap_callback has been called with an ID for which no action has been defined");
                break;
@@ -1975,17 +1987,20 @@ void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
                        "    <toolitem action='ToggleSnapFromBBoxCorner' />"
                        "    <toolitem action='ToggleSnapToBBoxPath' />"
                        "    <toolitem action='ToggleSnapToBBoxNode' />"
+                       "    <toolitem action='ToggleSnapToFromBBoxEdgeMidpoints' />"
+                       "    <toolitem action='ToggleSnapToFromBBoxMidpoints' />"
                        "    <separator />"
                        "    <toolitem action='ToggleSnapFromNode' />"
                        "    <toolitem action='ToggleSnapToItemPath' />"
+                       "    <toolitem action='ToggleSnapToPathIntersections' />"
                        "    <toolitem action='ToggleSnapToItemNode' />"
                        "    <toolitem action='ToggleSnapToSmoothNodes' />"
-                       "    <toolitem action='ToggleSnapToPathIntersections' />"
+                       "    <toolitem action='ToggleSnapToFromLineMidpoints' />"
+                       "    <toolitem action='ToggleSnapToFromObjectMidpoints' />"
                        "    <toolitem action='ToggleSnapToFromCenter' />"
                        "    <separator />"
                        "    <toolitem action='ToggleSnapToPageBorder' />"
                        "    <toolitem action='ToggleSnapToGridGuideIntersections' />"
-                       "    <toolitem action='ToggleSnapToFromMidpoints' />"
                        "  </toolbar>"
                "</ui>";
 
@@ -1994,7 +2009,7 @@ void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
        {
                InkToggleAction* act = ink_toggle_action_new("ToggleSnapGlobal",                // "name"
                                                                                                 _("Snap"),                                             // "label"
-                                                                                                _("Toggle all snapping"),              // "tooltip"
+                                                                                                _("Enable snapping"),          // "tooltip"
                                                                                                 "toggle_snap_global",                  // "iconId"
                                                                                                 secondarySize,
                                                                                                 SP_ATTR_INKSCAPE_SNAP_GLOBAL);
@@ -2006,7 +2021,7 @@ void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
        {
                InkToggleAction* act = ink_toggle_action_new("ToggleSnapFromBBoxCorner",// "name"
                                                                                                 _("Bounding box"),                             // "label"
-                                                                                                _("Toggle snapping of bounding box corners"),  // "tooltip"
+                                                                                                _("Snap bounding box corners"),        // "tooltip"
                                                                                                 "toggle_snap_bbox",                    // "iconId"
                                                                                                 secondarySize,
                                                                                                 SP_ATTR_INKSCAPE_SNAP_BBOX);
@@ -2018,7 +2033,7 @@ void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
        {
                InkToggleAction* act = ink_toggle_action_new("ToggleSnapToBBoxPath",    // "name"
                                                                                                 _("Bounding box edges"),               // "label"
-                                                                                                _("Toggle snapping to edges of a bounding box"),       // "tooltip"
+                                                                                                _("Snap to edges of a bounding box"),  // "tooltip"
                                                                                                 "toggle_snap_to_bbox_path",    // "iconId"
                                                                                                 secondarySize,
                                                                                                 SP_ATTR_INKSCAPE_BBOX_PATHS);
@@ -2030,7 +2045,7 @@ void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
        {
                InkToggleAction* act = ink_toggle_action_new("ToggleSnapToBBoxNode",    // "name"
                                                                                                 _("Bounding box corners"),             // "label"
-                                                                                                _("Toggle snapping to bounding box corners"),  // "tooltip"
+                                                                                                _("Snap to bounding box corners"),     // "tooltip"
                                                                                                 "toggle_snap_to_bbox_node",    // "iconId"
                                                                                                 secondarySize,
                                                                                                 SP_ATTR_INKSCAPE_BBOX_NODES);
@@ -2039,10 +2054,34 @@ void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
                g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox );
        }
 
+       {
+               InkToggleAction* act = ink_toggle_action_new("ToggleSnapToFromBBoxEdgeMidpoints",       // "name"
+                                                                                                _("BBox Edge Midpoints"),                              // "label"
+                                                                                                _("Snap from and to midpoints of bounding box edges"), // "tooltip"
+                                                                                                "toggle_snap_to_bbox_edge_midpoints",  // "iconId"
+                                                                                                secondarySize,
+                                                                                                SP_ATTR_INKSCAPE_SNAP_BBOX_EDGE_MIDPOINTS);
+
+               gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) );
+               g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox );
+       }
+
+       {
+               InkToggleAction* act = ink_toggle_action_new("ToggleSnapToFromBBoxMidpoints",   // "name"
+                                                                                                _("BBox Midpoints"),                           // "label"
+                                                                                                _("Snapping from and to midpoints of bounding boxes"), // "tooltip"
+                                                                                                "toggle_snap_to_bbox_midpoints",       // "iconId"
+                                                                                                secondarySize,
+                                                                                                SP_ATTR_INKSCAPE_SNAP_BBOX_MIDPOINTS);
+
+               gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) );
+               g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox );
+       }
+
        {
                InkToggleAction* act = ink_toggle_action_new("ToggleSnapFromNode",              // "name"
                                                                                                 _("Nodes"),                                    // "label"
-                                                                                                _("Toggle snapping of nodes"), // "tooltip"
+                                                                                                _("Snap nodes"),       // "tooltip"
                                                                                                 "toggle_snap_nodes",                   // "iconId"
                                                                                                 secondarySize,
                                                                                                 SP_ATTR_INKSCAPE_SNAP_NODES);
@@ -2054,7 +2093,7 @@ void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
        {
                InkToggleAction* act = ink_toggle_action_new("ToggleSnapToItemPath",    // "name"
                                                                                                 _("Paths"),                                    // "label"
-                                                                                                _("Toggle snapping to paths"), // "tooltip"
+                                                                                                _("Snap to paths"),    // "tooltip"
                                                                                                 "toggle_snap_to_paths",                // "iconId"
                                                                                                 secondarySize,
                                                                                                 SP_ATTR_INKSCAPE_OBJECT_PATHS);
@@ -2063,10 +2102,22 @@ void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
                g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox );
        }
 
+       {
+               InkToggleAction* act = ink_toggle_action_new("ToggleSnapToPathIntersections",                   // "name"
+                                                                                                _("Path intersections"),                                               // "label"
+                                                                                                _("Snap to path intersections"),       // "tooltip"
+                                                                                                "toggle_snap_to_path_intersections",                   // "iconId"
+                                                                                                secondarySize,
+                                                                                                SP_ATTR_INKSCAPE_SNAP_INTERS_PATHS);
+
+               gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) );
+               g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox );
+       }
+
        {
                InkToggleAction* act = ink_toggle_action_new("ToggleSnapToItemNode",    // "name"
                                                                                                 _("To nodes"),                                 // "label"
-                                                                                                _("Toggle snapping to cusp nodes"), // "tooltip"
+                                                                                                _("Snap to cusp nodes"), // "tooltip"
                                                                                                 "toggle_snap_to_nodes",                // "iconId"
                                                                                                 secondarySize,
                                                                                                 SP_ATTR_INKSCAPE_OBJECT_NODES);
@@ -2078,7 +2129,7 @@ void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
        {
                InkToggleAction* act = ink_toggle_action_new("ToggleSnapToSmoothNodes", // "name"
                                                                                                 _("Smooth nodes"),                             // "label"
-                                                                                                _("Consider smooth nodes too, not just cusp nodes"),// "tooltip"
+                                                                                                _("Snap to smooth nodes"),// "tooltip"
                                                                                                 "toggle_snap_to_smooth_nodes", // "iconId"
                                                                                                 secondarySize,
                                                                                                 SP_ATTR_INKSCAPE_SNAP_SMOOTH_NODES);
@@ -2088,24 +2139,24 @@ void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
        }
 
        {
-               InkToggleAction* act = ink_toggle_action_new("ToggleSnapToFromMidpoints",       // "name"
-                                                                                                _("Midpoints"),                                // "label"
-                                                                                                _("Toggle snapping from and to midpoints of line segments and bounding boxes"),        // "tooltip"
+               InkToggleAction* act = ink_toggle_action_new("ToggleSnapToFromLineMidpoints",   // "name"
+                                                                                                _("Line Midpoints"),                           // "label"
+                                                                                                _("Snap from and to midpoints of line segments"),      // "tooltip"
                                                                                                 "toggle_snap_to_midpoints",    // "iconId"
                                                                                                 secondarySize,
-                                                                                                SP_ATTR_INKSCAPE_SNAP_MIDPOINTS);
+                                                                                                SP_ATTR_INKSCAPE_SNAP_LINE_MIDPOINTS);
 
                gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) );
                g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox );
        }
 
        {
-               InkToggleAction* act = ink_toggle_action_new("ToggleSnapToPathIntersections",                   // "name"
-                                                                                                _("Path intersections"),                                               // "label"
-                                                                                                _("Toggle snapping to path intersections"),    // "tooltip"
-                                                                                                "toggle_snap_to_path_intersections",                   // "iconId"
+               InkToggleAction* act = ink_toggle_action_new("ToggleSnapToFromObjectMidpoints", // "name"
+                                                                                                _("Object Midpoints"),                         // "label"
+                                                                                                _("Snap from and to midpoints of objects"),    // "tooltip"
+                                                                                                "toggle_snap_to_object_midpoints",     // "iconId"
                                                                                                 secondarySize,
-                                                                                                SP_ATTR_INKSCAPE_SNAP_INTERS_PATHS);
+                                                                                                SP_ATTR_INKSCAPE_SNAP_OBJECT_MIDPOINTS);
 
                gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) );
                g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox );
@@ -2114,7 +2165,7 @@ void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
        {
                InkToggleAction* act = ink_toggle_action_new("ToggleSnapToFromCenter",// "name"
                                                                                                 _("Center"),                                   // "label"
-                                                                                                _("Toggle snapping from and to an item's rotation center"),    // "tooltip"
+                                                                                                _("Snap from and to an item's rotation center"),       // "tooltip"
                                                                                                 "toggle_snap_center",                  // "iconId"
                                                                                                 secondarySize,
                                                                                                 SP_ATTR_INKSCAPE_SNAP_CENTER);
@@ -2126,7 +2177,7 @@ void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
        {
                InkToggleAction* act = ink_toggle_action_new("ToggleSnapToPageBorder",  // "name"
                                                                                                 _("Page border"),                              // "label"
-                                                                                                _("Toggle snapping to the page border"),       // "tooltip"
+                                                                                                _("Snap to the page border"),  // "tooltip"
                                                                                                 "toggle_snap_page_border",             // "iconId"
                                                                                                 secondarySize,
                                                                                                 SP_ATTR_INKSCAPE_SNAP_PAGE);
@@ -2138,7 +2189,7 @@ void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
        {
                InkToggleAction* act = ink_toggle_action_new("ToggleSnapToGridGuideIntersections",      // "name"
                                                                                                 _("Grid/guide intersections"),                         // "label"
-                                                                                                _("Toggle snapping to intersections of a grid with a guide"),  // "tooltip"
+                                                                                                _("Snap to intersections of a grid with a guide"),     // "tooltip"
                                                                                                 "toggle_snap_grid_guide_intersections",        // "iconId"
                                                                                                 secondarySize,
                                                                                                 SP_ATTR_INKSCAPE_SNAP_INTERS_GRIDGUIDE);
@@ -2192,15 +2243,18 @@ void update_snap_toolbox(SPDesktop *desktop, SPEventContext */*eventcontext*/, G
        Glib::RefPtr<Gtk::Action> act2 = mainActions->get_action("ToggleSnapFromBBoxCorner");
        Glib::RefPtr<Gtk::Action> act3 = mainActions->get_action("ToggleSnapToBBoxPath");
        Glib::RefPtr<Gtk::Action> act4 = mainActions->get_action("ToggleSnapToBBoxNode");
+       Glib::RefPtr<Gtk::Action> act4b = mainActions->get_action("ToggleSnapToFromBBoxEdgeMidpoints");
+       Glib::RefPtr<Gtk::Action> act4c = mainActions->get_action("ToggleSnapToFromBBoxMidpoints");
        Glib::RefPtr<Gtk::Action> act5 = mainActions->get_action("ToggleSnapFromNode");
        Glib::RefPtr<Gtk::Action> act6 = mainActions->get_action("ToggleSnapToItemPath");
+       Glib::RefPtr<Gtk::Action> act6b = mainActions->get_action("ToggleSnapToPathIntersections");
        Glib::RefPtr<Gtk::Action> act7 = mainActions->get_action("ToggleSnapToItemNode");
        Glib::RefPtr<Gtk::Action> act8 = mainActions->get_action("ToggleSnapToSmoothNodes");
-       Glib::RefPtr<Gtk::Action> act10 = mainActions->get_action("ToggleSnapToPathIntersections");
+       Glib::RefPtr<Gtk::Action> act9 = mainActions->get_action("ToggleSnapToFromLineMidpoints");
+       Glib::RefPtr<Gtk::Action> act10 = mainActions->get_action("ToggleSnapToFromObjectMidpoints");
        Glib::RefPtr<Gtk::Action> act11 = mainActions->get_action("ToggleSnapToFromCenter");
        Glib::RefPtr<Gtk::Action> act12 = mainActions->get_action("ToggleSnapToPageBorder");
        Glib::RefPtr<Gtk::Action> act13 = mainActions->get_action("ToggleSnapToGridGuideIntersections");
-       Glib::RefPtr<Gtk::Action> act14 = mainActions->get_action("ToggleSnapToFromMidpoints");
 
 
        if (!act1) {
@@ -2219,34 +2273,39 @@ void update_snap_toolbox(SPDesktop *desktop, SPEventContext */*eventcontext*/, G
        gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act2->gobj()), c2);
        gtk_action_set_sensitive(GTK_ACTION(act2->gobj()), c1);
 
-       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act3->gobj()), nv->snap_manager.object.getSnapToBBoxPath());
+       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act3->gobj()), nv->snap_manager.snapprefs.getSnapToBBoxPath());
        gtk_action_set_sensitive(GTK_ACTION(act3->gobj()), c1 && c2);
-       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act4->gobj()), nv->snap_manager.object.getSnapToBBoxNode());
+       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act4->gobj()), nv->snap_manager.snapprefs.getSnapToBBoxNode());
        gtk_action_set_sensitive(GTK_ACTION(act4->gobj()), c1 && c2);
+       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act4b->gobj()), nv->snap_manager.snapprefs.getSnapBBoxEdgeMidpoints());
+       gtk_action_set_sensitive(GTK_ACTION(act4b->gobj()), c1 && c2);
+       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act4c->gobj()), nv->snap_manager.snapprefs.getSnapBBoxMidpoints());
+       gtk_action_set_sensitive(GTK_ACTION(act4c->gobj()), c1 && c2);
 
        bool const c3 = nv->snap_manager.snapprefs.getSnapModeNode();
        gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act5->gobj()), c3);
        gtk_action_set_sensitive(GTK_ACTION(act5->gobj()), c1);
 
-       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act6->gobj()), nv->snap_manager.object.getSnapToItemPath());
+       bool const c4 = nv->snap_manager.snapprefs.getSnapToItemPath();
+       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act6->gobj()), c4);
        gtk_action_set_sensitive(GTK_ACTION(act6->gobj()), c1 && c3);
-       bool const c4 = nv->snap_manager.object.getSnapToItemNode();
-       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act7->gobj()), c4);
+       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act6b->gobj()), nv->snap_manager.snapprefs.getSnapIntersectionCS());
+       gtk_action_set_sensitive(GTK_ACTION(act6b->gobj()), c1 && c3 && c4);
+       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act7->gobj()), nv->snap_manager.snapprefs.getSnapToItemNode());
        gtk_action_set_sensitive(GTK_ACTION(act7->gobj()), c1 && c3);
        gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act8->gobj()), nv->snap_manager.snapprefs.getSnapSmoothNodes());
-       gtk_action_set_sensitive(GTK_ACTION(act8->gobj()), c1 && c3 && c4);
-       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act10->gobj()), nv->snap_manager.snapprefs.getSnapIntersectionCS());
+       gtk_action_set_sensitive(GTK_ACTION(act8->gobj()), c1 && c3);
+       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act9->gobj()), nv->snap_manager.snapprefs.getSnapLineMidpoints());
+       gtk_action_set_sensitive(GTK_ACTION(act9->gobj()), c1 && c3);
+       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act10->gobj()), nv->snap_manager.snapprefs.getSnapObjectMidpoints());
        gtk_action_set_sensitive(GTK_ACTION(act10->gobj()), c1 && c3);
        gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act11->gobj()), nv->snap_manager.snapprefs.getIncludeItemCenter());
        gtk_action_set_sensitive(GTK_ACTION(act11->gobj()), c1 && c3);
 
-       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act12->gobj()), nv->snap_manager.object.getSnapToPageBorder());
+       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act12->gobj()), nv->snap_manager.snapprefs.getSnapToPageBorder());
        gtk_action_set_sensitive(GTK_ACTION(act12->gobj()), c1);
        gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act13->gobj()), nv->snap_manager.snapprefs.getSnapIntersectionGG());
        gtk_action_set_sensitive(GTK_ACTION(act13->gobj()), c1);
-       gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act14->gobj()), nv->snap_manager.snapprefs.getSnapMidpoints());
-       gtk_action_set_sensitive(GTK_ACTION(act14->gobj()), c1);
-
 
        g_object_set_data(G_OBJECT(toolbox), "freeze", GINT_TO_POINTER(FALSE)); // unfreeze (see above)
 }