using System; using global::System.Drawing; using System.Runtime.CompilerServices; using global::System.Windows.Forms; using global::Pilz.Drawing; namespace Pilz.UI { [Serializable] internal class PaintingObjectResizing { public PaintingObjectResizing() { mObjParent = null; mObjControl = null; } public PaintingObjectResizing(PaintingObject obj) { mObjParent = null; mObjControl = null; mObj = obj; mObjControl = mObj.Parent; } private PaintingObject _mObj; private PaintingObject mObj { [MethodImpl(MethodImplOptions.Synchronized)] get { return _mObj; } [MethodImpl(MethodImplOptions.Synchronized)] set { if (_mObj != null) { _mObj.MouseDown -= mControl_MouseDown; _mObj.MouseUp -= mControl_MouseUp; _mObj.Paint -= mControl_Paint; _mObj.SelectedChanged -= mControl_MouseLeave; _mObj.ParentChanged -= mObj_ParentChanged; } _mObj = value; if (_mObj != null) { _mObj.MouseDown += mControl_MouseDown; _mObj.MouseUp += mControl_MouseUp; _mObj.Paint += mControl_Paint; _mObj.SelectedChanged += mControl_MouseLeave; _mObj.ParentChanged += mObj_ParentChanged; } } } private Control mObjParent; private Control _mObjControl; private Control mObjControl { [MethodImpl(MethodImplOptions.Synchronized)] get { return _mObjControl; } [MethodImpl(MethodImplOptions.Synchronized)] set { if (_mObjControl != null) { _mObjControl.MouseMove -= mControl_MouseMove; _mObjControl.ParentChanged -= mObjParent_ParentChanged; } _mObjControl = value; if (_mObjControl != null) { _mObjControl.MouseMove += mControl_MouseMove; _mObjControl.ParentChanged += mObjParent_ParentChanged; } } } private bool mMouseDown = false; private EdgeEnum mEdge = EdgeEnum.None; private int mWidth = 4; private int qWidth = 4 * 4; private Rectangle rect = new Rectangle(); public bool Enabled { get; set; } = true; public SizeF MinimumSize { get; set; } = new SizeF(15f, 15f); [Serializable] private enum EdgeEnum { None, Right, Left, Top, Bottom, TopLeft, TopRight, BottomLeft, BottomRight } public bool IsResizing { get { return mMouseDown && mEdge != EdgeEnum.None; } } public static PaintingObjectResizing ApplyToControl(PaintingObject obj) { return new PaintingObjectResizing(obj); } private void mControl_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { mMouseDown = true; } } private void mControl_MouseUp(object sender, MouseEventArgs e) { mMouseDown = false; if (mObj.Selected) { mObj.AutoArrangeToGrid(); } } private void KeepInRange(ref SizeF size) { if (size.Height < MinimumSize.Height || size.Width < MinimumSize.Width) { size = new SizeF(Math.Max(size.Width, MinimumSize.Width), Math.Max(size.Height, MinimumSize.Height)); } } private void mControl_MouseMove(object sender, MouseEventArgs e) { if (mMouseDown && mEdge != EdgeEnum.None) { int eX = (int)(e.X + mObj.Parent.Offset.X); int eY = (int)(e.Y + mObj.Parent.Offset.Y); switch (mEdge) { case EdgeEnum.TopLeft: { mObj.SetBounds(eX, eY, (int)(mObj.Width + (mObj.Left - eX)), (int)(mObj.Height + (mObj.Top - eY))); break; } case EdgeEnum.TopRight: { mObj.SetBounds(mObj.Left, eY, eX - mObj.Left, (int)(mObj.Height + (mObj.Top - eY))); break; } case EdgeEnum.BottomRight: { mObj.SetBounds(mObj.Left, mObj.Top, eX - mObj.Left, eY - mObj.Top); break; } case EdgeEnum.BottomLeft: { mObj.SetBounds(eX, mObj.Top, (int)(mObj.Width + (mObj.Left - eX)), eY - mObj.Top); break; } case EdgeEnum.Left: { mObj.SetBounds(eX, mObj.Top, (int)(mObj.Width + (mObj.Left - eX)), (int)mObj.Height); break; } case EdgeEnum.Right: { mObj.SetBounds(mObj.Left, mObj.Top, eX - mObj.Left, (int)mObj.Height); break; } case EdgeEnum.Top: { mObj.SetBounds(mObj.Left, eY, (int)mObj.Width, (int)(mObj.Height + (mObj.Top - eY))); break; } case EdgeEnum.Bottom: { mObj.SetBounds(mObj.Left, mObj.Top, (int)mObj.Width, eY - mObj.Top); break; } } var argsize = mObj.Size; KeepInRange(ref argsize); mObj.Size = argsize; } else if (!mMouseDown) { int eXo = e.X; int eYo = e.Y; int realX = (int)(eXo + mObj.Parent.Offset.X); int realY = (int)(eYo + mObj.Parent.Offset.Y); int eXwo = (int)(eXo - mObj.X); int eYwo = (int)(eYo - mObj.Y); int eX = (int)(eXwo + mObj.Parent.Offset.X); int eY = (int)(eYwo + mObj.Parent.Offset.Y); var eLocation = new Point(eX, eY); RectangleF extRect = mObj.RectangleExtended; var oldRect = mObj.Rectangle; var newRect = new RectangleF(); newRect.X = extRect.X - oldRect.X; newRect.Y = extRect.Y - oldRect.Y; newRect.Width = (extRect.Width - oldRect.Width) / 2f; newRect.Height = (extRect.Height - oldRect.Height) / 2f; bool setToNone = false; bool isOnTop = ReferenceEquals(mObj.Parent.GetObject(new PointF(realX, realY), true), mObj); if (Enabled && isOnTop) { switch (true) { case object _ when HelpfulDrawingFunctions.IsPointInRectangle(eLocation, new Rectangle((int)newRect.X, (int)newRect.Y, (int)newRect.Width, (int)newRect.Height)): { mObj.Cursor = Cursors.SizeNWSE; mEdge = EdgeEnum.TopLeft; break; } case object _ when HelpfulDrawingFunctions.IsPointInRectangle(eLocation, new Rectangle((int)mObj.Width, (int)newRect.Y, (int)newRect.Width, (int)newRect.Height)): { mObj.Cursor = Cursors.SizeNESW; mEdge = EdgeEnum.TopRight; break; } case object _ when HelpfulDrawingFunctions.IsPointInRectangle(eLocation, new Rectangle((int)mObj.Width, (int)mObj.Height, (int)newRect.Width, (int)newRect.Height)): { mObj.Cursor = Cursors.SizeNWSE; mEdge = EdgeEnum.BottomRight; break; } case object _ when HelpfulDrawingFunctions.IsPointInRectangle(eLocation, new Rectangle((int)newRect.X, (int)mObj.Height, (int)newRect.Width, (int)newRect.Height)): { mObj.Cursor = Cursors.SizeNESW; mEdge = EdgeEnum.BottomLeft; break; } case object _ when HelpfulDrawingFunctions.IsPointInRectangle(eLocation, new Rectangle((int)-newRect.Width, 0, (int)newRect.Width, (int)mObj.Height)): { mObj.Cursor = Cursors.SizeWE; mEdge = EdgeEnum.Left; break; } case object _ when HelpfulDrawingFunctions.IsPointInRectangle(eLocation, new Rectangle((int)mObj.Width, 0, (int)newRect.Width, (int)mObj.Height)): { mObj.Cursor = Cursors.SizeWE; mEdge = EdgeEnum.Right; break; } case object _ when HelpfulDrawingFunctions.IsPointInRectangle(eLocation, new Rectangle(0, (int)-newRect.Height, (int)mObj.Width, (int)newRect.Height)): { mObj.Cursor = Cursors.SizeNS; mEdge = EdgeEnum.Top; break; } case object _ when HelpfulDrawingFunctions.IsPointInRectangle(eLocation, new Rectangle(0, (int)mObj.Height, (int)mObj.Width, (int)newRect.Height)): { mObj.Cursor = Cursors.SizeNS; mEdge = EdgeEnum.Bottom; break; } default: { setToNone = true; break; } } } else { setToNone = true; } if (setToNone) { mObj.Cursor = Cursors.Default; mEdge = EdgeEnum.None; } } } private void mControl_Paint(PaintingObject sender, PaintEventArgs e) { // e.Graphics.FillRectangle(brush, rect) } private void mControl_MouseLeave(PaintingObject sender, EventArgs e) { if (!sender.Selected) { mEdge = EdgeEnum.None; } } private void mObjParent_ParentChanged(object sender, EventArgs e) { mObjParent = mObjControl.Parent; } private void mObj_ParentChanged(PaintingObject sender, EventArgs e) { mObjControl = mObj.Parent; mObjParent = mObjControl?.Parent; } } }