X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fseltrans.cpp;h=9a648e2efa752649aaba270db9741ccc4ed67a0d;hb=cb5346ef4a77117f8ba1868d40e0f5222134f4ea;hp=0c478edaa2e6a23957bf23e4d5c89a02b7907096;hpb=632d86fab41e4e40033cfcc6822937ad96d39c43;p=inkscape.git diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 0c478edaa..9a648e2ef 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -39,6 +39,7 @@ #include "seltrans.h" #include "selection-chemistry.h" #include "sp-metrics.h" +#include "verbs.h" #include #include "display/sp-ctrlline.h" #include "prefs-utils.h" @@ -222,7 +223,8 @@ void Inkscape::SelTrans::setCenter(NR::Point const &p) it->setCenter(p); SP_OBJECT(it)->updateRepr(); } - sp_document_maybe_done (sp_desktop_document(_desktop), "center::move"); + sp_document_maybe_done (sp_desktop_document(_desktop), "center::move", SP_VERB_CONTEXT_SELECT, + _("Set center")); _updateHandles(); } @@ -253,8 +255,8 @@ void Inkscape::SelTrans::grab(NR::Point const &p, gdouble x, gdouble y, bool sho _point = p; - _snap_points = selection->getSnapPoints(); - _bbox_points = selection->getBBoxPoints(); + _snap_points = selection->getSnapPointsConvexHull(); + _bbox_points = selection->getBBoxPointsOuter(); gchar const *scale_origin = prefs_get_string_attribute("tools.select", "scale_origin"); bool const origin_on_bbox = (scale_origin == NULL || !strcmp(scale_origin, "bbox")); @@ -340,7 +342,20 @@ void Inkscape::SelTrans::ungrab() } } - sp_document_done(sp_desktop_document(_desktop)); + if (_current.is_translation()) { + sp_document_done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + _("Move")); + } else if (_current.is_scale()) { + sp_document_done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + _("Scale")); + } else if (_current.is_rotation()) { + sp_document_done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + _("Rotate")); + } else { + sp_document_done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + _("Skew")); + } + updh = false; } @@ -380,6 +395,13 @@ void Inkscape::SelTrans::stamp() { Inkscape::Selection *selection = sp_desktop_selection(_desktop); + bool fixup = !_grabbed; + if ( fixup && _stamp_cache ) { + // TODO - give a proper fix. Simple temproary work-around for the grab() issue + g_slist_free(_stamp_cache); + _stamp_cache = NULL; + } + /* stamping mode */ if (!_empty) { GSList *l; @@ -429,7 +451,14 @@ void Inkscape::SelTrans::stamp() Inkscape::GC::release(copy_repr); l = l->next; } - sp_document_done(sp_desktop_document(_desktop)); + sp_document_done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + _("Stamp")); + } + + if ( fixup && _stamp_cache ) { + // TODO - give a proper fix. Simple temproary work-around for the grab() issue + g_slist_free(_stamp_cache); + _stamp_cache = NULL; } } @@ -605,8 +634,11 @@ void Inkscape::SelTrans::handleClick(SPKnot *knot, guint state, SPSelTransHandle SPItem *it = (SPItem*)sp_object_ref(SP_OBJECT(l->data), NULL); it->unsetCenter(); SP_OBJECT(it)->updateRepr(); + _center_is_set = false; // center has changed + _updateHandles(); } - sp_document_maybe_done (sp_desktop_document(_desktop), "center::unset"); + sp_document_maybe_done (sp_desktop_document(_desktop), "center::unset", SP_VERB_CONTEXT_SELECT, + _("Reset center")); } break; default: @@ -769,6 +801,8 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state) } } + SnapManager const &m = _desktop->namedview->snap_manager; + /* Get a STL list of the selected items. ** FIXME: this should probably be done by Inkscape::Selection. */ @@ -778,50 +812,72 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state) } if ((state & GDK_CONTROL_MASK) || _desktop->isToolboxButtonActive ("lock")) { - /* Scale is locked to a 1:1 aspect ratio, so that s[X] must be made to equal s[Y] */ + /* Scale is locked to a 1:1 aspect ratio, so that s[X] must be made to equal s[Y]. + ** To do this, we snap along a suitable constraint vector from the origin. + */ - NR::Dim2 locked_dim; + NR::Point const cv = NR::Point( + pt[NR::X] > _origin[NR::X] ? 1 : -1, + pt[NR::Y] > _origin[NR::Y] ? 1 : -1 + ); + + std::pair bb = m.constrainedSnapScale(Snapper::BBOX_POINT, + _bbox_points, + it, + Snapper::ConstraintLine(_origin, cv), + s, + _origin); + + std::pair sn = m.constrainedSnapScale(Snapper::SNAP_POINT, + _snap_points, + it, + Snapper::ConstraintLine(_origin, cv), + s, + _origin); + + if (bb.second == false && sn.second == false) { + + /* We didn't snap, so just lock aspect ratio */ + if (fabs(s[NR::X]) > fabs(s[NR::Y])) { + s[NR::X] = fabs(s[NR::Y]) * sign(s[NR::X]); + } else { + s[NR::Y] = fabs(s[NR::X]) * sign(s[NR::Y]); + } - /* Lock aspect ratio, using the smaller of the x and y factors */ - if (fabs(s[NR::X]) > fabs(s[NR::Y])) { - s[NR::X] = fabs(s[NR::Y]) * sign(s[NR::X]); - locked_dim = NR::X; } else { - s[NR::Y] = fabs(s[NR::X]) * sign(s[NR::Y]); - locked_dim = NR::Y; - } - /* Snap the scale factor */ - std::pair bb = namedview_vector_snap_list(_desktop->namedview, - Snapper::BBOX_POINT, _bbox_points, - _origin, s, it); - std::pair sn = namedview_vector_snap_list(_desktop->namedview, - Snapper::SNAP_POINT, _snap_points, - _origin, s, it); - - double bd = bb.second ? fabs(bb.first - s[locked_dim]) : NR_HUGE; - double sd = sn.second ? fabs(sn.first - s[locked_dim]) : NR_HUGE; - double r = (bd < sd) ? bb.first : sn.first; - - for ( unsigned int i = 0 ; i < 2 ; i++ ) { - s[i] = r * sign(s[i]); + /* Choose the smaller difference in scale. Since s[X] == s[Y] we can + ** just compare difference in s[X]. + */ + double const bd = bb.second ? fabs(bb.first[NR::X] - s[NR::X]) : NR_HUGE; + double const sd = sn.second ? fabs(sn.first[NR::X] - s[NR::X]) : NR_HUGE; + s = (bd < sd) ? bb.first : sn.first; } } else { /* Scale aspect ratio is unlocked */ - for ( unsigned int i = 0 ; i < 2 ; i++ ) { - std::pair bb = namedview_dim_snap_list_scale(_desktop->namedview, - Snapper::BBOX_POINT, _bbox_points, - _origin, s[i], NR::Dim2(i), it); - std::pair sn = namedview_dim_snap_list_scale(_desktop->namedview, - Snapper::SNAP_POINT, _snap_points, - _origin, s[i], NR::Dim2(i), it); - - /* Pick the snap that puts us closest to the original scale */ - NR::Coord bd = bb.second ? fabs(bb.first - s[i]) : NR_HUGE; - NR::Coord sd = sn.second ? fabs(sn.first - s[i]) : NR_HUGE; - s[i] = (bd < sd) ? bb.first : sn.first; - } + + std::pair bb = m.freeSnapScale(Snapper::BBOX_POINT, + _bbox_points, + it, + s, + _origin); + std::pair sn = m.freeSnapScale(Snapper::SNAP_POINT, + _snap_points, + it, + s, + _origin); + + /* Pick the snap that puts us closest to the original scale */ + NR::Coord bd = bb.second ? + fabs(NR::L2(NR::Point(bb.first[NR::X], bb.first[NR::Y])) - + NR::L2(NR::Point(s[NR::X], s[NR::Y]))) + : NR_HUGE; + NR::Coord sd = sn.second ? + fabs(NR::L2(NR::Point(sn.first[NR::X], sn.first[NR::Y])) - + NR::L2(NR::Point(s[NR::X], s[NR::Y]))) + : NR_HUGE; + s = (bd < sd) ? bb.first : sn.first; } /* Update the knot position */ @@ -877,34 +933,60 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR:: it.push_back(reinterpret_cast(i->data)); } + SnapManager const &m = _desktop->namedview->snap_manager; + if ( state & GDK_CONTROL_MASK ) { s[perp] = fabs(s[axis]); - std::pair sn = namedview_vector_snap_list(_desktop->namedview, - Snapper::BBOX_POINT, - _bbox_points, _origin, s, it); - std::pair bb = namedview_vector_snap_list(_desktop->namedview, - Snapper::SNAP_POINT, - _snap_points, _origin, s, it); - - double bd = bb.second ? fabs(bb.first - s[axis]) : NR_HUGE; - double sd = sn.second ? fabs(sn.first - s[axis]) : NR_HUGE; - double ratio = (bd < sd) ? bb.first : sn.first; + std::pair const bb = m.freeSnapStretch( + Snapper::BBOX_POINT, + _bbox_points, + it, + s[axis], + _origin, + axis, + true); + + std::pair const sn = m.freeSnapStretch( + Snapper::SNAP_POINT, + _snap_points, + it, + s[axis], + _origin, + axis, + true); + + NR::Coord const bd = bb.second ? fabs(bb.first - s[axis]) : NR_HUGE; + NR::Coord const sd = sn.second ? fabs(sn.first - s[axis]) : NR_HUGE; + NR::Coord const ratio = (bd < sd) ? bb.first : sn.first; s[axis] = fabs(ratio) * sign(s[axis]); s[perp] = fabs(s[axis]); } else { - std::pair bb = namedview_dim_snap_list_scale(_desktop->namedview, Snapper::BBOX_POINT, - _bbox_points, _origin, - s[axis], axis, it); - std::pair sn = namedview_dim_snap_list_scale(_desktop->namedview, Snapper::SNAP_POINT, - _snap_points, _origin, - s[axis], axis, it); - /* Pick the snap that puts us closest to the original scale */ - NR::Coord bd = bb.second ? fabs(bb.first - s[axis]) : NR_HUGE; - NR::Coord sd = sn.second ? fabs(sn.first - s[axis]) : NR_HUGE; + std::pair const bb = m.freeSnapStretch( + Snapper::BBOX_POINT, + _bbox_points, + it, + s[axis], + _origin, + axis, + false); + + std::pair const sn = m.freeSnapStretch( + Snapper::SNAP_POINT, + _snap_points, + it, + s[axis], + _origin, + axis, + false); + + /* Choose the smaller difference in scale */ + NR::Coord const bd = bb.second ? fabs(bb.first - s[axis]) : NR_HUGE; + NR::Coord const sd = sn.second ? fabs(sn.first - s[axis]) : NR_HUGE; s[axis] = (bd < sd) ? bb.first : sn.first; + s[perp] = 1; } pt = ( _point - _origin ) * NR::scale(s) + _origin; @@ -970,9 +1052,28 @@ gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, NR::Poi } skew[dim_a] = tan(radians) * s[dim_a]; } else { - skew[dim_a] = namedview_dim_snap_list_skew(_desktop->namedview, - Snapper::SNAP_POINT, _snap_points, - _origin, skew[dim_a], dim_b); + SnapManager const &m = _desktop->namedview->snap_manager; + + std::pair bb = m.freeSnapSkew(Inkscape::Snapper::BBOX_POINT, + _bbox_points, + std::list(), + skew[dim_a], + _origin, + dim_a); + + std::pair sn = m.freeSnapSkew(Inkscape::Snapper::SNAP_POINT, + _snap_points, + std::list(), + skew[dim_a], + _origin, + dim_a); + + if (bb.second || sn.second) { + /* We snapped something, so change the skew to reflect it */ + NR::Coord const bd = bb.second ? bb.first : NR_HUGE; + NR::Coord const sd = sn.second ? sn.first : NR_HUGE; + skew[dim_a] = std::min(bd, sd); + } } pt[dim_b] = ( _point[dim_a] - _origin[dim_a] ) * skew[dim_a] + _point[dim_b]; @@ -1045,7 +1146,7 @@ gboolean Inkscape::SelTrans::centerRequest(NR::Point &pt, guint state) using NR::X; using NR::Y; - SnapManager const m(_desktop->namedview); + SnapManager const &m = _desktop->namedview->snap_manager; pt = m.freeSnap(Snapper::SNAP_POINT, pt, NULL).getPoint(); if (state & GDK_CONTROL_MASK) { @@ -1245,7 +1346,7 @@ void sp_sel_trans_center(Inkscape::SelTrans *seltrans, SPSelTransHandle const &, void Inkscape::SelTrans::moveTo(NR::Point const &xy, guint state) { - SnapManager const m(_desktop->namedview); + SnapManager const &m = _desktop->namedview->snap_manager; /* The amount that we've moved by during this drag */ NR::Point dxy = xy - _point; @@ -1287,10 +1388,15 @@ void Inkscape::SelTrans::moveTo(NR::Point const &xy, guint state) for (unsigned int dim = 0; dim < 2; dim++) { s.push_back(m.constrainedSnapTranslation(Inkscape::Snapper::BBOX_POINT, _bbox_points, - component_vectors[dim], it, dxy)); + it, + Inkscape::Snapper::ConstraintLine(component_vectors[dim]), + dxy)); + s.push_back(m.constrainedSnapTranslation(Inkscape::Snapper::SNAP_POINT, _snap_points, - component_vectors[dim], it, dxy)); + it, + Inkscape::Snapper::ConstraintLine(component_vectors[dim]), + dxy)); } } else {