X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fgradient-drag.cpp;h=2e9a21acf2ccceb0786e36ae253a8c716c073e9d;hb=030609cb99174ea85e69635c494ccaaaa20b2ac5;hp=1492e900851def296c83a7e302040a6e55dfdb49;hpb=c5dd34e5650c52686ead8880909b4c4e90caa666;p=inkscape.git diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp index 1492e9008..2e9a21acf 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -5,6 +5,7 @@ * bulia byak * Johan Engelen * Jon A. Cruz + * Abhishek Sharma * * Copyright (C) 2007 Johan Engelen * Copyright (C) 2005,2010 Authors @@ -44,6 +45,8 @@ #include "sp-namedview.h" #include "selection-chemistry.h" +using Inkscape::DocumentUndo; + #define GR_KNOT_COLOR_NORMAL 0xffffff00 #define GR_KNOT_COLOR_MOUSEOVER 0xff000000 #define GR_KNOT_COLOR_SELECTED 0x0000ff00 @@ -176,6 +179,43 @@ gr_drag_style_query (SPStyle *style, int property, gpointer data) } } +Glib::ustring GrDrag::makeStopSafeColor( gchar const *str, bool &isNull ) +{ + Glib::ustring colorStr; + if ( str ) { + isNull = false; + colorStr = str; + Glib::ustring::size_type pos = colorStr.find("url(#"); + if ( pos != Glib::ustring::npos ) { + Glib::ustring targetName = colorStr.substr(pos + 5, colorStr.length() - 6); + const GSList *gradients = desktop->doc()->getResourceList("gradient"); + for (const GSList *item = gradients; item; item = item->next) { + SPGradient* grad = SP_GRADIENT(item->data); + if ( targetName == grad->getId() ) { + SPGradient *vect = grad->getVector(); + SPStop *firstStop = (vect) ? vect->getFirstStop() : grad->getFirstStop(); + if (firstStop) { + Glib::ustring stopColorStr; + if (firstStop->currentColor) { + stopColorStr = firstStop->getStyleProperty("color", NULL); + } else { + stopColorStr = firstStop->specified_color.toString(); + } + if ( !stopColorStr.empty() ) { + colorStr = stopColorStr; + } + } + break; + } + } + } + } else { + isNull = true; + } + + return colorStr; +} + bool GrDrag::styleSet( const SPCSSAttr *css ) { if (!selected) { @@ -214,30 +254,10 @@ bool GrDrag::styleSet( const SPCSSAttr *css ) // Make sure the style is allowed for gradient stops. if ( !sp_repr_css_property_is_unset( stop, "stop-color") ) { - Glib::ustring tmp = sp_repr_css_property( stop, "stop-color", "" ); - Glib::ustring::size_type pos = tmp.find("url(#"); - if ( pos != Glib::ustring::npos ) { - Glib::ustring targetName = tmp.substr(pos + 5, tmp.length() - 6); - const GSList *gradients = sp_document_get_resource_list(desktop->doc(), "gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); - if ( targetName == grad->getId() ) { - SPGradient *vect = grad->getVector(); - SPStop *firstStop = (vect) ? vect->getFirstStop() : grad->getFirstStop(); - if (firstStop) { - Glib::ustring stopColorStr; - if (firstStop->currentColor) { - stopColorStr = sp_object_get_style_property(firstStop, "color", NULL); - } else { - stopColorStr = firstStop->specified_color.toString(); - } - if ( !stopColorStr.empty() ) { - sp_repr_css_set_property( stop, "stop-color", stopColorStr.c_str() ); - } - } - break; - } - } + bool stopIsNull = false; + Glib::ustring tmp = makeStopSafeColor( sp_repr_css_property( stop, "stop-color", "" ), stopIsNull ); + if ( !stopIsNull && !tmp.empty() ) { + sp_repr_css_set_property( stop, "stop-color", tmp.c_str() ); } } @@ -393,14 +413,18 @@ GrDrag::addStopNearPoint (SPItem *item, Geom::Point mouse_p, double tolerance) bool GrDrag::dropColor(SPItem */*item*/, gchar const *c, Geom::Point p) { + // Note: not sure if a null pointer can come in for the style, but handle that just in case + bool stopIsNull = false; + Glib::ustring toUse = makeStopSafeColor( c, stopIsNull ); + // first, see if we can drop onto one of the existing draggers for (GList *i = draggers; i != NULL; i = i->next) { // for all draggables of dragger GrDragger *d = (GrDragger *) i->data; if (Geom::L2(p - d->point)*desktop->current_zoom() < 5) { SPCSSAttr *stop = sp_repr_css_attr_new (); - sp_repr_css_set_property (stop, "stop-color", c); - sp_repr_css_set_property (stop, "stop-opacity", "1"); + sp_repr_css_set_property( stop, "stop-color", stopIsNull ? 0 : toUse.c_str() ); + sp_repr_css_set_property( stop, "stop-opacity", "1" ); for (GSList *j = d->draggables; j != NULL; j = j->next) { // for all draggables of dragger GrDraggable *draggable = (GrDraggable *) j->data; local_change = true; @@ -423,8 +447,8 @@ GrDrag::dropColor(SPItem */*item*/, gchar const *c, Geom::Point p) SPStop *stop = addStopNearPoint (line->item, p, 5/desktop->current_zoom()); if (stop) { SPCSSAttr *css = sp_repr_css_attr_new (); - sp_repr_css_set_property (css, "stop-color", c); - sp_repr_css_set_property (css, "stop-opacity", "1"); + sp_repr_css_set_property( css, "stop-color", stopIsNull ? 0 : toUse.c_str() ); + sp_repr_css_set_property( css, "stop-opacity", "1" ); sp_repr_css_change (SP_OBJECT_REPR (stop), css, "style"); return true; } @@ -547,22 +571,6 @@ SPObject *GrDraggable::getServer() return server; } -static -boost::optional -get_snap_vector (Geom::Point p, Geom::Point o, double snap, double initial) -{ - double r = L2 (p - o); - if (r < 1e-3) { - return boost::optional(); - } - - double angle = atan2 (p - o); - // snap angle to snaps increments, starting from initial: - double a_snapped = initial + floor((angle - initial)/snap + 0.5) * snap; - // calculate the new position and subtract p to get the vector: - return (o + r * Geom::Point(cos(a_snapped), sin(a_snapped)) - p); -} - static void gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gpointer data) { @@ -617,22 +625,24 @@ gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gp d_new->updateKnotShape (); d_new->updateTip (); d_new->updateDependencies(true); - sp_document_done (sp_desktop_document (d_new->parent->desktop), SP_VERB_CONTEXT_GRADIENT, - _("Merge gradient handles")); + DocumentUndo::done(sp_desktop_document (d_new->parent->desktop), SP_VERB_CONTEXT_GRADIENT, + _("Merge gradient handles")); return; } } } - m.setup(desktop); if (!((state & GDK_SHIFT_MASK) || (state & GDK_CONTROL_MASK))) { + m.setup(desktop); Inkscape::SnappedPoint s = m.freeSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_OTHER_HANDLE)); + m.unSetup(); if (s.getSnapped()) { p = s.getPoint(); sp_knot_moveto (knot, p); } } else if (state & GDK_CONTROL_MASK) { SnappedConstraints sc; + Inkscape::SnapCandidatePoint scp = Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_OTHER_HANDLE); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); unsigned snaps = abs(prefs->getInt("/options/rotationsnapsperpi/value", 12)); /* 0 means no snapping. */ @@ -678,36 +688,38 @@ gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gp dr_snap = dragger->point_original; } - boost::optional snap_vector; + // dr_snap contains the origin of the gradient, whereas p will be the new endpoint which we will try to snap now + Inkscape::SnappedPoint sp; if (dr_snap.isFinite()) { + m.setup(desktop); if (state & GDK_MOD1_MASK) { // with Alt, snap to the original angle and its perpendiculars - snap_vector = get_snap_vector (p, dr_snap, M_PI/2, Geom::atan2 (dragger->point_original - dr_snap)); + sp = m.constrainedAngularSnap(scp, dragger->point_original, dr_snap, 2); } else { // with Ctrl, snap to M_PI/snaps - snap_vector = get_snap_vector (p, dr_snap, M_PI/snaps, 0); - } - if (snap_vector) { - Inkscape::Snapper::SnapConstraint cl(dr_snap, p + *snap_vector - dr_snap); - Inkscape::SnappedPoint s = m.constrainedSnap(Inkscape::SnapCandidatePoint(p + *snap_vector, Inkscape::SNAPSOURCE_OTHER_HANDLE), cl); - if (s.getSnapped()) { - s.setTransformation(s.getPoint() - p); - sc.points.push_back(s); - } else { - Inkscape::SnappedPoint dummy(p + *snap_vector, Inkscape::SNAPSOURCE_OTHER_HANDLE, 0, Inkscape::SNAPTARGET_CONSTRAINED_ANGLE, Geom::L2(*snap_vector), 10000, true, true, false); - dummy.setTransformation(*snap_vector); - sc.points.push_back(dummy); - } + sp = m.constrainedAngularSnap(scp, boost::optional(), dr_snap, snaps); } + m.unSetup(); + sc.points.push_back(sp); } } - Inkscape::SnappedPoint bsp = m.findBestSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_OTHER_HANDLE), sc, true); // snap indicator will be displayed if needed - - if (bsp.getSnapped()) { - p += bsp.getTransformation(); - sp_knot_moveto (knot, p); + m.setup(desktop, false); // turn of the snap indicator temporarily + Inkscape::SnappedPoint bsp = m.findBestSnap(scp, sc, true); + m.unSetup(); + if (!bsp.getSnapped()) { + // If we didn't truly snap to an object or to a grid, then we will still have to look for the + // closest projection onto one of the constraints. findBestSnap() will not do this for us + for (std::list::const_iterator i = sc.points.begin(); i != sc.points.end(); i++) { + if (i == sc.points.begin() || (Geom::L2((*i).getPoint() - p) < Geom::L2(bsp.getPoint() - p))) { + bsp.setPoint((*i).getPoint()); + bsp.setTarget(Inkscape::SNAPTARGET_CONSTRAINED_ANGLE); + } + } } + //p = sc.points.front().getPoint(); + p = bsp.getPoint(); + sp_knot_moveto (knot, p); } drag->keep_selection = (bool) g_list_find(drag->selected, dragger); @@ -843,6 +855,7 @@ gr_knot_moved_midpoint_handler(SPKnot */*knot*/, Geom::Point const &ppointer, gu SnapManager &m = desktop->namedview->snap_manager; m.setup(desktop); m.constrainedSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE, cl); + m.unSetup(); } } Geom::Point displacement = p - dragger->point; @@ -917,8 +930,8 @@ gr_knot_ungrabbed_handler (SPKnot *knot, unsigned int state, gpointer data) dragger->updateDependencies(true); // we did an undoable action - sp_document_done (sp_desktop_document (dragger->parent->desktop), SP_VERB_CONTEXT_GRADIENT, - _("Move gradient handle")); + DocumentUndo::done(sp_desktop_document (dragger->parent->desktop), SP_VERB_CONTEXT_GRADIENT, + _("Move gradient handle")); } /** @@ -970,8 +983,8 @@ gr_knot_clicked_handler(SPKnot */*knot*/, guint state, gpointer data) } SP_OBJECT_REPR(gradient)->removeChild(SP_OBJECT_REPR(stop)); - sp_document_done (SP_OBJECT_DOCUMENT (gradient), SP_VERB_CONTEXT_GRADIENT, - _("Delete gradient stop")); + DocumentUndo::done(SP_OBJECT_DOCUMENT (gradient), SP_VERB_CONTEXT_GRADIENT, + _("Delete gradient stop")); } } else { // select the dragger @@ -1130,7 +1143,7 @@ GrDragger::updateTip () if (g_slist_length (this->draggables) == 1) { GrDraggable *draggable = (GrDraggable *) this->draggables->data; - char *item_desc = sp_item_description(draggable->item); + char *item_desc = draggable->item->description(); switch (draggable->point_type) { case POINT_LG_MID: case POINT_RG_MID1: @@ -1774,7 +1787,7 @@ GrDrag::updateLevels () for (GSList const* i = this->selection->itemList(); i != NULL; i = i->next) { SPItem *item = SP_ITEM(i->data); - Geom::OptRect rect = sp_item_bbox_desktop (item); + Geom::OptRect rect = item->getBboxDesktop (); if (rect) { // Remember the edges of the bbox and the center axis hor_levels.push_back(rect->min()[Geom::Y]); @@ -1853,7 +1866,7 @@ GrDrag::selected_move (double x, double y, bool write_repr, bool scale_radial) if (write_repr && did) { // we did an undoable action - sp_document_maybe_done (sp_desktop_document (desktop), "grmoveh", SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::maybeDone(sp_desktop_document (desktop), "grmoveh", SP_VERB_CONTEXT_GRADIENT, _("Move gradient handle(s)")); return; } @@ -1889,7 +1902,7 @@ GrDrag::selected_move (double x, double y, bool write_repr, bool scale_radial) if (write_repr && did) { // we did an undoable action - sp_document_maybe_done (sp_desktop_document (desktop), "grmovem", SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::maybeDone(sp_desktop_document (desktop), "grmovem", SP_VERB_CONTEXT_GRADIENT, _("Move gradient mid stop(s)")); } } @@ -2037,11 +2050,11 @@ GrDrag::deleteSelected (bool just_one) // cannot use vector->vector.stops.size() because the vector might be invalidated by deletion of a midstop // manually count the children, don't know if there already exists a function for this... int len = 0; - for ( SPObject *child = sp_object_first_child(stopinfo->vector) ; - child != NULL ; - child = SP_OBJECT_NEXT(child) ) + for ( SPObject *child = (stopinfo->vector)->firstChild() ; child ; child = child->getNext() ) { - if ( SP_IS_STOP(child) ) len ++; + if ( SP_IS_STOP(child) ) { + len ++; + } } if (len > 2) { @@ -2178,7 +2191,7 @@ GrDrag::deleteSelected (bool just_one) } if (document) { - sp_document_done ( document, SP_VERB_CONTEXT_GRADIENT, _("Delete gradient stop(s)") ); + DocumentUndo::done( document, SP_VERB_CONTEXT_GRADIENT, _("Delete gradient stop(s)") ); } }