public static void MoveSelection(Data.Layer layer, float dx, float dy, MoveMode mode = MoveMode.Normal) { using var group = layer.CreateUndoGroup(); foreach (var anchor in layer.Anchors) { if (anchor.IsSelected) { anchor.X = RoundToGrid(anchor.X + dx); anchor.Y = RoundToGrid(anchor.Y + dy); } } foreach (var component in layer.Components) { if (component.IsSelected) { var t = component.Transformation; t.M31 = RoundToGrid(t.M31 + dx); t.M32 = RoundToGrid(t.M32 + dy); component.Transformation = t; } } foreach (var guideline in UIBroker.GetAllGuidelines(layer)) { if (guideline.IsSelected) { guideline.X = RoundToGrid(guideline.X + dx); guideline.Y = RoundToGrid(guideline.Y + dy); } } foreach (var path in layer.Paths) { MoveSelection(path, dx, dy, mode); } }
public static void StretchCurve(Data.Layer layer, IList <Data.Point> curve, float dx, float dy, bool maintainDirection = false) { Debug.Assert(curve.Count == 4); var leftVector = curve[1].ToVector2(); var rightVector = curve[2].ToVector2(); using var group = layer.CreateUndoGroup(); curve[1].X = curve[1].X + dx; curve[1].Y = curve[1].Y + dy; if (maintainDirection || curve[0].IsSmooth) { VectorProjection(curve[1], curve[0].ToVector2(), leftVector); } else { curve[1].X = RoundToGrid(curve[1].X); curve[1].Y = RoundToGrid(curve[1].Y); } curve[2].X = curve[2].X + dx; curve[2].Y = curve[2].Y + dy; if (maintainDirection || curve[3].IsSmooth) { VectorProjection(curve[2], curve[3].ToVector2(), rightVector); } else { curve[2].X = RoundToGrid(curve[2].X); curve[2].Y = RoundToGrid(curve[2].Y); } }
void AlignPaths(Data.Layer layer, Func <Data.Path, Rect, Vector2> transformFunc) { Rect targetBounds; IEnumerable <Data.Path> targetPaths; bool alignToMetricsRect; if (layer.Selection.OfType <Data.Point>().Any()) { var selectedBounds = Rect.Empty; var selectedPaths = new List <Data.Path>(); foreach (var path in layer.Paths) { if (Enumerable.Any(path.Points, point => point.IsSelected)) { selectedBounds.Union(path.Bounds); selectedPaths.Add(path); } } targetBounds = selectedBounds; targetPaths = selectedPaths; alignToMetricsRect = selectedPaths.Count == 1; } else { targetBounds = default; // this just to appease the compiler.. targetPaths = layer.Paths; alignToMetricsRect = true; } if (alignToMetricsRect) { targetBounds = new Rect(0, 0, layer.Width, 0); if (layer.Master is Data.Master master) { targetBounds.Y = master.Descender; targetBounds.Height = Math.Max(master.Ascender, master.CapHeight) - targetBounds.Y; } } using (var group = layer.CreateUndoGroup()) { foreach (var path in targetPaths) { var delta = transformFunc(path, targetBounds); if (delta != Vector2.Zero) { path.Transform(Matrix3x2.CreateTranslation(delta)); } } } }
public static void DeleteSelection(Data.Layer layer, bool breakPaths = false) { using var group = layer.CreateUndoGroup(); for (int ix = layer.Anchors.Count - 1; ix >= 0; --ix) { var anchor = layer.Anchors[ix]; if (anchor.IsSelected) { layer.Anchors.RemoveAt(ix); } } for (int ix = layer.Components.Count - 1; ix >= 0; --ix) { var component = layer.Components[ix]; if (component.IsSelected) { layer.Components.RemoveAt(ix); } } if (layer.Master is Data.Master master) { for (int ix = master.Guidelines.Count - 1; ix >= 0; --ix) { var guideline = master.Guidelines[ix]; if (guideline.IsSelected) { master.Guidelines.RemoveAt(ix); } } } for (int ix = layer.Guidelines.Count - 1; ix >= 0; --ix) { var guideline = layer.Guidelines[ix]; if (guideline.IsSelected) { layer.Guidelines.RemoveAt(ix); } } if (breakPaths) { BreakPathsSelection(layer); } else { DeletePathsSelection(layer); } }
public static void RoundSelection(Data.Layer layer) { using var group = layer.CreateUndoGroup(); foreach (var anchor in layer.Anchors) { if (anchor.IsSelected) { anchor.X = RoundToGrid(anchor.X); anchor.Y = RoundToGrid(anchor.Y); } } foreach (var component in layer.Components) { if (component.IsSelected) { var t = component.Transformation; // TODO: could round scale to 2 decimal digits, like we do when transforming // worth having a round to digits (default = 2) method here? t.M31 = RoundToGrid(t.M31); t.M32 = RoundToGrid(t.M32); component.Transformation = t; } } foreach (var guideline in UIBroker.GetAllGuidelines(layer)) { if (guideline.IsSelected) { // TODO: introduce some angle rounding? guideline.X = RoundToGrid(guideline.X); guideline.Y = RoundToGrid(guideline.Y); } } foreach (var path in layer.Paths) { foreach (var point in path.Points) { if (point.IsSelected) { point.X = RoundToGrid(point.X); point.Y = RoundToGrid(point.Y); } } } }