Logo Search packages:      
Sourcecode: inkscape version File versions

Geom::Point SnapManager::multipleOfGridPitch ( Geom::Point const &  t  )  const

Snap to the closest multiple of a grid pitch.

When pasting, we would like to snap to the grid. Problem is that we don't know which nodes were aligned to the grid at the time of copying, so we don't know which nodes to snap. If we'd snap an unaligned node to the grid, previously aligned nodes would become unaligned. That's undesirable. Instead we will make sure that the offset between the source and its pasted copy is a multiple of the grid pitch. If the source was aligned, then the copy will therefore also be aligned.

PS: Whether we really find a multiple also depends on the snapping range! Most users will have "always snap" enabled though, in which case a multiple will always be found. PS2: When multiple grids are present then the result will become ambiguous. There is no way to control to which grid this method will snap.

t Vector that represents the offset of the pasted copy with respect to the original
Offset vector after snapping to the closest multiple of a grid pitch

Definition at line 263 of file snap.cpp.

References findBestSnap(), Inkscape::SnappedPoint::getPoint(), Inkscape::SnappedPoint::getSnapDistance(), Inkscape::SnappedPoint::getSnapped(), and SPDesktop::gridsEnabled().

Referenced by Inkscape::UI::ClipboardManagerImpl::_pasteDocument().

    if (!snapprefs.getSnapEnabledGlobally()) // No need to check for snapprefs.getSnapPostponedGlobally() here
        return t;

    if (_desktop && _desktop->gridsEnabled()) {
        bool success = false;
        Geom::Point nearest_multiple;
        Geom::Coord nearest_distance = NR_HUGE;

        // It will snap to the grid for which we find the closest snap. This might be a different
        // grid than to which the objects were initially aligned. I don't see an easy way to fix
        // this, so when using multiple grids one can get unexpected results

        // Cannot use getGridSnappers() because we need both the grids AND their snappers
        // Therefore we iterate through all grids manually
        for (GSList const *l = _named_view->grids; l != NULL; l = l->next) {
            Inkscape::CanvasGrid *grid = (Inkscape::CanvasGrid*) l->data;
            const Inkscape::Snapper* snapper = grid->snapper;
            if (snapper && snapper->ThisSnapperMightSnap()) {
                // To find the nearest multiple of the grid pitch for a given translation t, we
                // will use the grid snapper. Simply snapping the value t to the grid will do, but
                // only if the origin of the grid is at (0,0). If it's not then compensate for this
                // in the translation t
                Geom::Point const t_offset = t + grid->origin;
                SnappedConstraints sc;
                // Only the first three parameters are being used for grid snappers
                snapper->freeSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_NODE, t_offset, Inkscape::SNAPSOURCE_UNDEFINED, TRUE, Geom::OptRect(), NULL, NULL);
                // Find the best snap for this grid, including intersections of the grid-lines
                Inkscape::SnappedPoint s = findBestSnap(t_offset, Inkscape::SNAPSOURCE_UNDEFINED, sc, false);
                if (s.getSnapped() && (s.getSnapDistance() < nearest_distance)) {
                    // use getSnapDistance() instead of getWeightedDistance() here because the pointer's position
                    // doesn't tell us anything about which node to snap
                    success = true;
                    nearest_multiple = s.getPoint() - to_2geom(grid->origin);
                    nearest_distance = s.getSnapDistance();

        if (success)
            return nearest_multiple;

    return t;

Generated by  Doxygen 1.6.0   Back to index