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); }
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); }
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); }
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); }
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); }
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); } }
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); }
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); };
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); }