diff options
| author | Diederik van Lierop <mail@diedenrezi.nl> | 2009-01-18 20:00:19 +0000 |
|---|---|---|
| committer | dvlierop2 <dvlierop2@users.sourceforge.net> | 2009-01-18 20:00:19 +0000 |
| commit | 644f4f4a93a81735fb8265907533308df80d6b11 (patch) | |
| tree | 47a80b1dc162b88a063b295dbae920cc2a668e93 | |
| parent | snap indicator: try a diamond shaped indicator for snapping to nodes. see how... (diff) | |
| download | inkscape-644f4f4a93a81735fb8265907533308df80d6b11.tar.gz inkscape-644f4f4a93a81735fb8265907533308df80d6b11.zip | |
- Snap to the midpoint of shapes and bboxes
- 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
(bzr r7144)
| -rw-r--r-- | share/icons/icons.svg | 76 | ||||
| -rw-r--r-- | src/attributes-test.h | 5 | ||||
| -rw-r--r-- | src/attributes.cpp | 7 | ||||
| -rw-r--r-- | src/attributes.h | 5 | ||||
| -rw-r--r-- | src/guide-snapper.cpp | 6 | ||||
| -rw-r--r-- | src/line-snapper.cpp | 2 | ||||
| -rw-r--r-- | src/object-snapper.cpp | 137 | ||||
| -rw-r--r-- | src/object-snapper.h | 23 | ||||
| -rw-r--r-- | src/seltrans.cpp | 26 | ||||
| -rw-r--r-- | src/snap-preferences.cpp | 12 | ||||
| -rw-r--r-- | src/snap-preferences.h | 39 | ||||
| -rw-r--r-- | src/snap.cpp | 19 | ||||
| -rw-r--r-- | src/snap.h | 1 | ||||
| -rw-r--r-- | src/sp-ellipse.cpp | 34 | ||||
| -rw-r--r-- | src/sp-item.cpp | 2 | ||||
| -rw-r--r-- | src/sp-namedview.cpp | 33 | ||||
| -rw-r--r-- | src/sp-rect.cpp | 32 | ||||
| -rw-r--r-- | src/sp-shape.cpp | 41 | ||||
| -rw-r--r-- | src/sp-spiral.cpp | 24 | ||||
| -rw-r--r-- | src/sp-star.cpp | 25 | ||||
| -rw-r--r-- | src/ui/dialog/document-properties.cpp | 12 | ||||
| -rw-r--r-- | src/widgets/toolbox.cpp | 147 |
22 files changed, 469 insertions, 239 deletions
diff --git a/share/icons/icons.svg b/share/icons/icons.svg index 297e9aa1d..10b3a6d05 100644 --- a/share/icons/icons.svg +++ b/share/icons/icons.svg @@ -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"> @@ -703,8 +703,15 @@ <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> diff --git a/src/attributes-test.h b/src/attributes-test.h index 5e3f741d7..1148953ec 100644 --- a/src/attributes-test.h +++ b/src/attributes-test.h @@ -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}, diff --git a/src/attributes.cpp b/src/attributes.cpp index 1ee33ef83..049632e50 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -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"}, diff --git a/src/attributes.h b/src/attributes.h index 68e6135db..6fe3ebb80 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -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, diff --git a/src/guide-snapper.cpp b/src/guide-snapper.cpp index be2e84170..b05466ede 100644 --- a/src/guide-snapper.cpp +++ b/src/guide-snapper.cpp @@ -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 diff --git a/src/line-snapper.cpp b/src/line-snapper.cpp index bfcda3f79..bc43d640b 100644 --- a/src/line-snapper.cpp +++ b/src/line-snapper.cpp @@ -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; } diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp index 35841891f..f5021e208 100644 --- a/src/object-snapper.cpp +++ b/src/object-snapper.cpp @@ -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()); + } } } diff --git a/src/object-snapper.h b/src/object-snapper.h index 9151dbd8a..9c391a90f 100644 --- a/src/object-snapper.h +++ b/src/object-snapper.h @@ -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 diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 1055e55ef..0fd15593c 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -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 diff --git a/src/snap-preferences.cpp b/src/snap-preferences.cpp index 0bfd94c71..d21259983 100644 --- a/src/snap-preferences.cpp +++ b/src/snap-preferences.cpp @@ -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(). - * + * * */ diff --git a/src/snap-preferences.h b/src/snap-preferences.h index a52e0cfd9..97ef3cec2 100644 --- a/src/snap-preferences.h +++ b/src/snap-preferences.h @@ -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; }; } diff --git a/src/snap.cpp b/src/snap.cpp index a6c4b8729..24cfefe0b 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -108,6 +108,25 @@ bool SnapManager::someSnapperMightSnap() const } /** + * \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. * * \param point_type Type of point. diff --git a/src/snap.h b/src/snap.h index 14adf399f..177e9b529 100644 --- a/src/snap.h +++ b/src/snap.h @@ -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); diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index c7ed88513..0d28e9f6b 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -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; diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 8971c3abb..2ac480341 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -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 diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index c46f30e06..4ff66f6c3 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -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: diff --git a/src/sp-rect.cpp b/src/sp-rect.cpp index 2f3fc1864..c2fe527b6 100644 --- a/src/sp-rect.cpp +++ b/src/sp-rect.cpp @@ -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 diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index ce73888ed..4adf883a4 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -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:: } } - - } /* diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp index 377cc13f4..624c5ae18 100644 --- a/src/sp-spiral.cpp +++ b/src/sp-spiral.cpp @@ -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! } } diff --git a/src/sp-star.cpp b/src/sp-star.cpp index bbf808209..c1581a6d6 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -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; } } diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index b2b3d1e81..36861ad2c 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -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); diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 571e440f2..0acc7731a 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -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); @@ -2040,9 +2055,33 @@ void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop) } { + 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); @@ -2064,9 +2103,21 @@ void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop) } { + 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) } |
