public override void Trigger(EditableView.ClickPosition.Sources source, EditableView pnlView, Transaction transaction) { IShapeContainer container = CurrentPage.SelectionContainer(); if (container == null) { MessageBox.Show(Strings.Item("Container_Mismatch")); return; } transaction.Edit((Datum)container); Lined mask = FindSourceShape(); ImportedImage image = FindSourceImage(); transaction.Edit(mask); transaction.Edit(image); (mask as Pencil).ForceClosure(transaction); if (mask is Curve curve && !curve.Closed()) { throw new UserException("[Mask_Not_Closed]"); } MaskedImage result = new MaskedImage(image, mask); transaction.Create(result); int index = Math.Max(mask.Z, image.Z); // this will be the Z-order of the new group result.Parent = container; container.Contents.Insert(index + 1, result); // This index will be valid as the individual shapes are still in the list container.Contents.Remove(mask); container.Contents.Remove(image); container.FinishedModifyingContents(transaction, null); CurrentPage.SelectOnly(result); }
public override bool Tidy(SnapModes mode, Page page) { // By default this isn't enabled - is only usable if the overriding class adds Tidy to the Allows return value switch (mode) { case SnapModes.Grid: switch (page.Paper.PaperType) { case Paper.Papers.Plain: return(false); // cannot tidy up to an isometric grid } break; case SnapModes.Shape: // will be attempted below break; default: return(false); // mainly intended for angle; where the shape is by definition aligned on the grid } List <PointF> points = new List <PointF>(); points.AddRange(m_Bounds.GetPoints()); Lined.TidyVertices(points, this, mode, page, 3); // but that might not have created an orthogonal rectangle. So calculate the complete rectangle bounding these. For tidying to grid // that should just return the same points again m_Bounds = RectangleF.Empty; Geometry.Extend(ref m_Bounds, points); return(true); }
public override bool Tidy(SnapModes mode, Page page) { PointF newPoint = m_Centre; switch (mode) { case SnapModes.Grid: newPoint = page.Paper.SnapPoint2(newPoint); break; case SnapModes.Shape: newPoint = Lined.TidyPointToShapes(newPoint, page, this); break; case SnapModes.Angle: SizeF newVector = Geometry.AngleSnapVector(m_Exit); if (newVector.Equals(m_Exit)) { return(false); } m_Exit = newVector; return(true); default: Debug.Fail("Bad Tidy mode"); break; } if (newPoint == m_Centre) { return(false); } m_Centre = newPoint; return(true); }
public override void Load(DataReader reader) { base.Load(reader); Image = (ImportedImage)reader.ReadData(); MaskShape = (Lined)reader.ReadData(); MaskShape.Parent = this; Image.Parent = this; }
public MaskedImage(ImportedImage image, Lined mask) { Image = image; MaskShape = mask; MaskShape.Parent = this; Image.Parent = this; MaskShape.NotifyEnvironmentChanged(EnvironmentChanges.ParentReassigned); Image.NotifyEnvironmentChanged(EnvironmentChanges.ParentReassigned); }
internal override void DrawLineTarget(Target target, Graphics gr, Pen pn, int activePhase) { if (!AutoTargets) { return; } PointF start = Vertices[target.ShapeIndex % 4]; PointF end = Vertices[(target.ShapeIndex + 1) % 4]; // mod makes sure last line loops back to (0), rather than trying to access (4) Lined.DrawLineTargetGivenPoints(gr, pn, activePhase, target.Position, start, end); }
// base does Centre and Middle internal override List <Target> GenerateTargets(UserSocket floating) { if (!AutoTargets) { return(null); } List <Target> targets = new List <Target>(); Lined.AddLineTargets(this, targets, floating, m_Bounds.GetPoints(), true); targets.Add(new Target(this, Centre, Target.Types.Centre, floating)); return(targets); }
public override bool Tidy(SnapModes mode, Page page) { List <PointF> vertices = new List <PointF>(Vertices); // function below needs a list not an array bool changed = Lined.TidyVertices(vertices, this, mode, page, 1); if (changed) { Vertices = vertices.ToArray(); m_Bounds = RectangleF.Empty; ClearTextCache(); } return(changed); }
public override void CopyFrom(Datum other, CopyDepth depth, Mapping mapID) { base.CopyFrom(other, depth, mapID); MaskedImage mask = (MaskedImage)other; // largely copied fom scriptable Debug.Assert((Image == null) == (MaskShape == null)); if (depth == CopyDepth.Transform && MaskShape != null) // m_Mask and m_Image will either both be null or neither { // first time must copy reference, below if (MaskShape != mask.MaskShape) { MaskShape?.CopyFrom(mask.MaskShape, depth, mapID); } if (Image != mask.Image) { Image?.CopyFrom(mask.Image, depth, mapID); } } else // if (depth == CopyDepth.Duplicate) { if (mapID?.ContainsKey(mask.MaskShape.ID) ?? false) { MaskShape = (Lined)mapID[mask.MaskShape.ID]; } else { MaskShape = (Lined)mask.MaskShape.Clone(mapID ?? new Mapping()); // use actual mapID if there is one, otherwise need a real one as Container aspects of Item don't like Ignore } MaskShape.Parent = this; if (mapID?.ContainsKey(mask.Image.ID) ?? false) { Image = (ImportedImage)mapID[mask.Image.ID]; } else { Image = (ImportedImage)mask.Image.Clone(mapID ?? new Mapping()); // use actual mapID if there is one, otherwise need a real one as Container aspects of Item don't like Ignore } Image.Parent = this; } m_Bounds = RectangleF.Empty; }
public override bool Tidy(SnapModes mode, Page page) { List <PointF> col = new List <PointF>(Vertices); float transverse = Geometry.DistanceBetween(Vertices[1], Vertices[2]); // the transverse distance if (!Lined.TidyVertices(col, this, mode, page, 3)) { return(false); } // make sure it is rectangular again!... // the base class tidies the points independently and could end up with a parallelogram, this ensures that it remains a rectangle. Copied from rectangle, but removing part of it which snapped the transverse size (not so applicable here we probably want to maintain the ratio for images?) Vertices = col.ToArray(); int direction = Geometry.TurnDirection(Vertices[0], Vertices[1], Vertices[2]); Vertices[2] = Vertices[1] + Vertices[0].VectorTo(Vertices[1]).Perpendicular(direction).ChangeLength(transverse); Vertices[3] = Vertices[0] + Vertices[1].VectorTo(Vertices[2]); m_Bounds = CalculateBounds(); return(true); // This doesn't perform very well when aligning with other shapes; the initial function will tidy the individual points, but usually one will become misaligned again // when correcting the rectangle. It would be better to do a proper moving snap, but I'm not sure if it's really worth the effort }