예제 #1
0
void
StarKnotHolderEntity1::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state)
{
    SPStar *star = SP_STAR(item);

    Geom::Point const s = snap_knot_position(p, state);

    Geom::Point d = s - star->center;

    double arg1 = atan2(d);
    double darg1 = arg1 - star->arg[0];

    if (state & GDK_MOD1_MASK) {
        star->randomized = darg1/(star->arg[0] - star->arg[1]);
    } else if (state & GDK_SHIFT_MASK) {
        star->rounded = darg1/(star->arg[0] - star->arg[1]);
    } else if (state & GDK_CONTROL_MASK) {
        star->r[0]    = L2(d);
    } else {
        star->r[0]    = L2(d);
        star->arg[0]  = arg1;
        star->arg[1] += darg1;
    }
    (static_cast<SPObject *>(star))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
예제 #2
0
void
PatternKnotHolderEntityScale::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state)
{
    SPPattern *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style));

    // FIXME: this snapping should be done together with knowing whether control was pressed. If GDK_CONTROL_MASK, then constrained snapping should be used.
    Geom::Point p_snapped = snap_knot_position(p, state);

    // get angle from current transform
    gdouble theta = sp_pattern_extract_theta(pat);

    // Get the new scale from the position of the knotholder
    Geom::Point d = p_snapped - sp_pattern_extract_trans(pat);
    gdouble pat_x = pattern_width(pat);
    gdouble pat_y = pattern_height(pat);
    Geom::Scale scl(1);
    if ( state & GDK_CONTROL_MASK ) {
        // if ctrl is pressed: use 1:1 scaling
        gdouble pat_h = hypot(pat_x, pat_y);
        scl = Geom::Scale(d.length() / pat_h);
    } else {
        d *= Geom::Rotate(-theta);
        scl = Geom::Scale(d[Geom::X] / pat_x, d[Geom::Y] / pat_y);
    }

    Geom::Affine rot = (Geom::Affine)scl * Geom::Rotate(theta);

    Geom::Point const t = sp_pattern_extract_trans(pat);
    rot[4] = t[Geom::X];
    rot[5] = t[Geom::Y];
    item->adjust_pattern(rot, true);
    item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
예제 #3
0
void
Box3DKnotHolderEntityCenter::knot_set(Geom::Point const &new_pos, Geom::Point const &origin, guint state)
{
    Geom::Point const s = snap_knot_position(new_pos, state);

    SPBox3D *box = SP_BOX3D(item);
    Geom::Affine const i2dt (item->i2dt_affine ());

    box3d_set_center (SP_BOX3D(item), s * i2dt, origin * i2dt, !(state & GDK_SHIFT_MASK) ? Box3D::XY : Box3D::Z,
                      state & GDK_CONTROL_MASK);

    box3d_set_z_orders(box);
    box3d_position_set(box);
}
예제 #4
0
void
ArcKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state)
{
    SPGenericEllipse *ge = SP_GENERICELLIPSE(item);

    Geom::Point const s = snap_knot_position(p, state);

    ge->ry.computed = fabs( ge->cy.computed - s[Geom::Y] );

    if ( state & GDK_CONTROL_MASK ) {
        ge->rx.computed = ge->ry.computed;
    }

    (static_cast<SPObject *>(item))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
void
KnotHolderEntityEnd::bisector_end_set(Geom::Point const &p, guint state, bool left) {
    LPEPerpBisector *lpe = dynamic_cast<LPEPerpBisector *>(_effect);
    if (!lpe) return;

    Geom::Point const s = snap_knot_position(p, state);

    double lambda = Geom::nearest_point(s, lpe->M, lpe->perp_dir);
    if (left) {
        lpe->C = lpe->M + lpe->perp_dir * lambda;
        lpe->length_left.param_set_value(lambda);
    } else {
        lpe->D = lpe->M + lpe->perp_dir * lambda;
        lpe->length_right.param_set_value(-lambda);
    }

    // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating.
    sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), true, true);
}
예제 #6
0
void
Box3DKnotHolderEntity::knot_set_generic(SPItem *item, unsigned int knot_id, Geom::Point const &new_pos, guint state)
{
    Geom::Point const s = snap_knot_position(new_pos, state);

    g_assert(item != NULL);
    SPBox3D *box = SP_BOX3D(item);
    Geom::Affine const i2dt (item->i2dt_affine ());

    Box3D::Axis movement;
    if ((knot_id < 4) != (state & GDK_SHIFT_MASK)) {
        movement = Box3D::XY;
    } else {
        movement = Box3D::Z;
    }

    box3d_set_corner (box, knot_id, s * i2dt, movement, (state & GDK_CONTROL_MASK));
    box3d_set_z_orders(box);
    box3d_position_set(box);
}
예제 #7
0
파일: point.cpp 프로젝트: hermixy/inkscape
void
PointParamKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &origin, guint state)
{
    Geom::Point s = snap_knot_position(p, state);
    if (state & GDK_CONTROL_MASK) {
        Geom::Point A(origin[Geom::X],p[Geom::Y]);
        Geom::Point B(p[Geom::X],origin[Geom::Y]);
        double distanceA = Geom::distance(A,p);
        double distanceB = Geom::distance(B,p);
        if(distanceA > distanceB){
            s = B;
        } else {
            s = A;
        }
    }
    pparam->param_setValue(s, true);
    SPLPEItem * splpeitem = dynamic_cast<SPLPEItem *>(item);
    if(splpeitem){
        sp_lpe_item_update_patheffect(splpeitem, false, false);
    }
}
예제 #8
0
void
PatternKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &origin, guint state)
{
    SPPattern *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style));

    // FIXME: this snapping should be done together with knowing whether control was pressed. If GDK_CONTROL_MASK, then constrained snapping should be used.
    Geom::Point p_snapped = snap_knot_position(p, state);

    if ( state & GDK_CONTROL_MASK ) {
        if (fabs((p - origin)[Geom::X]) > fabs((p - origin)[Geom::Y])) {
            p_snapped[Geom::Y] = origin[Geom::Y];
        } else {
            p_snapped[Geom::X] = origin[Geom::X];
        }
    }

    if (state)  {
        Geom::Point const q = p_snapped - sp_pattern_extract_trans(pat);
        item->adjust_pattern(Geom::Affine(Geom::Translate(q)));
    }

    item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
예제 #9
0
 virtual void knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint /*state*/) {
     Geom::Point const s = snap_knot_position(p);
     param->setOrigin(s);
     sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false);
 };
예제 #10
0
void
RectKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &origin, guint state)
{
    SPRect *rect = SP_RECT(item);

    // opposite corner (unmoved)
    gdouble opposite_x = (rect->x.computed + rect->width.computed);
    gdouble opposite_y = (rect->y.computed + rect->height.computed);

    // original width/height when drag started
    gdouble w_orig = opposite_x - origin[Geom::X];
    gdouble h_orig = opposite_y - origin[Geom::Y];

    Geom::Point s = p;
    Geom::Point p_handle(rect->x.computed, rect->y.computed);

    // mouse displacement since drag started
    gdouble minx = p[Geom::X] - origin[Geom::X];
    gdouble miny = p[Geom::Y] - origin[Geom::Y];

    if (state & GDK_CONTROL_MASK) {
        //original ratio
        gdouble ratio = (w_orig / h_orig);

        if (fabs(minx) > fabs(miny)) {
            // snap to horizontal or diagonal
            if (minx != 0 && fabs(miny/minx) > 0.5 * 1/ratio && (SGN(minx) == SGN(miny))) {
                // closer to the diagonal and in same-sign quarters, change both using ratio
                s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state);
                minx = s[Geom::X] - origin[Geom::X];
                miny = s[Geom::Y] - origin[Geom::Y];
                rect->y.computed = MIN(origin[Geom::Y] + minx / ratio, opposite_y);
                rect->height.computed = MAX(h_orig - minx / ratio, 0);
            } else {
                // closer to the horizontal, change only width, height is h_orig
                s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-1, 0)), state);
                minx = s[Geom::X] - origin[Geom::X];
                miny = s[Geom::Y] - origin[Geom::Y];
                rect->y.computed = MIN(origin[Geom::Y], opposite_y);
                rect->height.computed = MAX(h_orig, 0);
            }
            rect->x.computed = MIN(s[Geom::X], opposite_x);
            rect->width.computed = MAX(w_orig - minx, 0);
        } else {
            // snap to vertical or diagonal
            if (miny != 0 && fabs(minx/miny) > 0.5 *ratio && (SGN(minx) == SGN(miny))) {
                // closer to the diagonal and in same-sign quarters, change both using ratio
                s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state);
                minx = s[Geom::X] - origin[Geom::X];
                miny = s[Geom::Y] - origin[Geom::Y];
                rect->x.computed = MIN(origin[Geom::X] + miny * ratio, opposite_x);
                rect->width.computed = MAX(w_orig - miny * ratio, 0);
            } else {
                // closer to the vertical, change only height, width is w_orig
                s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(0, -1)), state);
                minx = s[Geom::X] - origin[Geom::X];
                miny = s[Geom::Y] - origin[Geom::Y];
                rect->x.computed = MIN(origin[Geom::X], opposite_x);
                rect->width.computed = MAX(w_orig, 0);
            }
            rect->y.computed = MIN(s[Geom::Y], opposite_y);
            rect->height.computed = MAX(h_orig - miny, 0);
        }

        rect->width._set = rect->height._set = rect->x._set = rect->y._set = true;

    } else {
        // move freely
        s = snap_knot_position(p, state);
        minx = s[Geom::X] - origin[Geom::X];
        miny = s[Geom::Y] - origin[Geom::Y];

        rect->x.computed = MIN(s[Geom::X], opposite_x);
        rect->width.computed = MAX(w_orig - minx, 0);
        rect->y.computed = MIN(s[Geom::Y], opposite_y);
        rect->height.computed = MAX(h_orig - miny, 0);
        rect->width._set = rect->height._set = rect->x._set = rect->y._set = true;
    }

    sp_rect_clamp_radii(rect);

    update_knot();

    (static_cast<SPObject *>(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}