Code

Color Matrix Filter:
[inkscape.git] / src / gradient-drag.cpp
index 74fc2fe67c6317cc4e5e484421d4957600edc455..59081475ee22a0f6550b243f844e1889f71445a9 100644 (file)
 #include "gradient-drag.h"
 #include "sp-stop.h"
 
+#include "snap.h"
+#include "sp-namedview.h"
+
+
 #define GR_KNOT_COLOR_NORMAL 0xffffff00
 #define GR_KNOT_COLOR_SELECTED 0x0000ff00
 
@@ -149,12 +153,12 @@ gr_drag_style_query (SPStyle *style, int property, gpointer data)
             cf[3] /= count;
 
             // set both fill and stroke with our stop-color and stop-opacity
-            sp_color_set_rgb_float((SPColor *) &style->fill.value.color, cf[0], cf[1], cf[2]);
+            style->fill.clear();
+            style->fill.setColor( cf[0], cf[1], cf[2] );
             style->fill.set = TRUE;
-            style->fill.type = SP_PAINT_TYPE_COLOR;
-            sp_color_set_rgb_float((SPColor *) &style->stroke.value.color, cf[0], cf[1], cf[2]);
+            style->stroke.clear();
+            style->stroke.setColor( cf[0], cf[1], cf[2] );
             style->stroke.set = TRUE;
-            style->stroke.type = SP_PAINT_TYPE_COLOR;
 
             style->fill_opacity.value = SP_SCALE24_FROM_FLOAT (1.0);
             style->fill_opacity.set = TRUE;
@@ -429,19 +433,26 @@ gr_knot_moved_handler(SPKnot *knot, NR::Point const *ppointer, guint state, gpoi
         }
     }
 
-
     if (!((state & GDK_SHIFT_MASK) || ((state & GDK_CONTROL_MASK) && (state & GDK_MOD1_MASK)))) {
-        // See if we need to snap to any of the levels
-        for (guint i = 0; i < dragger->parent->hor_levels.size(); i++) {
-            if (fabs(p[NR::Y] - dragger->parent->hor_levels[i]) < snap_dist) {
-                p[NR::Y] = dragger->parent->hor_levels[i];
-                sp_knot_moveto (knot, &p);
+        // Try snapping to the grid or guides
+        SnapManager const &m = dragger->parent->desktop->namedview->snap_manager;
+        Inkscape::SnappedPoint s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p, NULL);
+        if (s.getDistance() < 1e6) {
+            p = s.getPoint();
+            sp_knot_moveto (knot, &p);
+        } else {
+            // No snapping so far, let's see if we need to snap to any of the levels
+            for (guint i = 0; i < dragger->parent->hor_levels.size(); i++) {
+                if (fabs(p[NR::Y] - dragger->parent->hor_levels[i]) < snap_dist) {
+                    p[NR::Y] = dragger->parent->hor_levels[i];
+                    sp_knot_moveto (knot, &p);
+                }
             }
-        }
-        for (guint i = 0; i < dragger->parent->vert_levels.size(); i++) {
-            if (fabs(p[NR::X] - dragger->parent->vert_levels[i]) < snap_dist) {
-                p[NR::X] = dragger->parent->vert_levels[i];
-                sp_knot_moveto (knot, &p);
+            for (guint i = 0; i < dragger->parent->vert_levels.size(); i++) {
+                if (fabs(p[NR::X] - dragger->parent->vert_levels[i]) < snap_dist) {
+                    p[NR::X] = dragger->parent->vert_levels[i];
+                    sp_knot_moveto (knot, &p);
+                }
             }
         }
     }
@@ -791,7 +802,9 @@ GrDragger::fireDraggables (bool write_repr, bool scale_radial, bool merging_focu
         // to the center, unless it's the first update upon merge when we must snap it to the point
         if (merging_focus ||
             !(draggable->point_type == POINT_RG_FOCUS && this->isA(draggable->item, POINT_RG_CENTER, draggable->point_i, draggable->fill_or_stroke)))
+        {
             sp_item_gradient_set_coords (draggable->item, draggable->point_type, draggable->point_i, this->point, draggable->fill_or_stroke, write_repr, scale_radial);
+        }
     }
 }
 
@@ -1364,7 +1377,7 @@ GrDrag::updateDraggers ()
         SPItem *item = SP_ITEM(i->data);
         SPStyle *style = SP_OBJECT_STYLE (item);
 
-        if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER)) {
+        if (style && (style->fill.isPaintserver())) {
             SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
             if (SP_IS_LINEARGRADIENT (server)) {
                 addDraggersLinear (SP_LINEARGRADIENT (server), item, true);
@@ -1373,7 +1386,7 @@ GrDrag::updateDraggers ()
             }
         }
 
-        if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER)) {
+        if (style && (style->stroke.isPaintserver())) {
             SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
             if (SP_IS_LINEARGRADIENT (server)) {
                 addDraggersLinear (SP_LINEARGRADIENT (server), item, false);
@@ -1406,7 +1419,7 @@ GrDrag::updateLines ()
 
         SPStyle *style = SP_OBJECT_STYLE (item);
 
-        if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER)) {
+        if (style && (style->fill.isPaintserver())) {
             SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
             if (SP_IS_LINEARGRADIENT (server)) {
                 this->addLine (sp_item_gradient_get_coords (item, POINT_LG_BEGIN, 0, true), sp_item_gradient_get_coords (item, POINT_LG_END, 0, true), GR_LINE_COLOR_FILL);
@@ -1417,7 +1430,7 @@ GrDrag::updateLines ()
             }
         }
 
-        if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER)) {
+        if (style && (style->stroke.isPaintserver())) {
             SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
             if (SP_IS_LINEARGRADIENT (server)) {
                 this->addLine (sp_item_gradient_get_coords (item, POINT_LG_BEGIN, 0, false), sp_item_gradient_get_coords (item, POINT_LG_END, 0, false), GR_LINE_COLOR_STROKE);
@@ -1443,14 +1456,16 @@ GrDrag::updateLevels ()
 
     for (GSList const* i = this->selection->itemList(); i != NULL; i = i->next) {
         SPItem *item = SP_ITEM(i->data);
-        NR::Rect rect = sp_item_bbox_desktop (item);
-        // Remember the edges of the bbox and the center axis
-        hor_levels.push_back(rect.min()[NR::Y]);
-        hor_levels.push_back(rect.max()[NR::Y]);
-        hor_levels.push_back(0.5 * (rect.min()[NR::Y] + rect.max()[NR::Y]));
-        vert_levels.push_back(rect.min()[NR::X]);
-        vert_levels.push_back(rect.max()[NR::X]);
-        vert_levels.push_back(0.5 * (rect.min()[NR::X] + rect.max()[NR::X]));
+        NR::Maybe<NR::Rect> rect = sp_item_bbox_desktop (item);
+        if (rect) {
+            // Remember the edges of the bbox and the center axis
+            hor_levels.push_back(rect->min()[NR::Y]);
+            hor_levels.push_back(rect->max()[NR::Y]);
+            hor_levels.push_back(0.5 * (rect->min()[NR::Y] + rect->max()[NR::Y]));
+            vert_levels.push_back(rect->min()[NR::X]);
+            vert_levels.push_back(rect->max()[NR::X]);
+            vert_levels.push_back(0.5 * (rect->min()[NR::X] + rect->max()[NR::X]));
+        }
     }
 }
 
@@ -1550,7 +1565,8 @@ GrDrag::deleteSelected (bool just_one)
         for (GSList * drgble = dragger->draggables; drgble != NULL; drgble = drgble->next) {
             GrDraggable *draggable = (GrDraggable*) drgble->data;
             SPGradient *gradient = sp_item_gradient (draggable->item, draggable->fill_or_stroke);
-            SPGradient *vector   = sp_gradient_get_vector (gradient, false);
+            SPGradient *vector   = sp_gradient_get_forked_vector_if_necessary (gradient, false);
+
             switch (draggable->point_type) {
                 case POINT_LG_MID:
                 case POINT_RG_MID1:
@@ -1729,11 +1745,31 @@ GrDrag::deleteSelected (bool just_one)
         else
         { // delete the gradient from the object. set fill to unset  FIXME: set to fill of unselected node?
             SPCSSAttr *css = sp_repr_css_attr_new ();
-            if (stopinfo->draggable->fill_or_stroke) {
-                sp_repr_css_unset_property (css, "fill");
+
+            // stopinfo->spstop is the selected stop
+            Inkscape::XML::Node *unselectedrepr = SP_OBJECT_REPR(stopinfo->vector)->firstChild();
+            if (unselectedrepr == SP_OBJECT_REPR(stopinfo->spstop) ) {
+                unselectedrepr = unselectedrepr->next();
+            }
+
+            if (unselectedrepr == NULL) {
+                if (stopinfo->draggable->fill_or_stroke) {
+                    sp_repr_css_unset_property (css, "fill");
+                } else {
+                    sp_repr_css_unset_property (css, "stroke");
+                }
             } else {
-                sp_repr_css_unset_property (css, "stroke");
+                SPCSSAttr *stopcss = sp_repr_css_attr(unselectedrepr, "style");
+                if (stopinfo->draggable->fill_or_stroke) {
+                    sp_repr_css_set_property(css, "fill", sp_repr_css_property(stopcss, "stop-color", "inkscape:unset"));
+                    sp_repr_css_set_property(css, "fill-opacity", sp_repr_css_property(stopcss, "stop-opacity", "1"));
+                } else {
+                    sp_repr_css_set_property(css, "stroke", sp_repr_css_property(stopcss, "stop-color", "inkscape:unset"));
+                    sp_repr_css_set_property(css, "stroke-opacity", sp_repr_css_property(stopcss, "stop-opacity", "1"));
+                }
+                sp_repr_css_attr_unref (stopcss);
             }
+            
             sp_repr_css_change (SP_OBJECT_REPR (stopinfo->draggable->item), css, "style");
             sp_repr_css_attr_unref (css);
         }