Files
Pilz/Pilz.UI.WinForms/PaintingControl/PaintingObjectResizing.cs

345 lines
12 KiB
C#

using Pilz.Drawing;
using System.Runtime.CompilerServices;
namespace Pilz.UI.WinForms.PaintingControl;
[Serializable]
internal class PaintingObjectResizing
{
public static event CheckEnabledEventHandler CheckEnabled;
public delegate void CheckEnabledEventHandler(PaintingObjectResizing sender, ref bool enabled);
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 mObjParent
{
[MethodImpl(MethodImplOptions.Synchronized)]
get
{
return _mObjParent;
}
[MethodImpl(MethodImplOptions.Synchronized)]
set
{
_mObjParent = value;
}
}
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();
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 PaintingObject PaintingObject
{
get
{
return mObj;
}
}
public PaintingObjectResizing(PaintingObject obj)
{
mObjParent = null;
mObjControl = null;
mObj = obj;
mObjControl = mObj.Parent;
}
private bool IsEnabled()
{
var enabled = Enabled;
CheckEnabled?.Invoke(this, ref enabled);
return enabled;
}
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)
{
var eX = (int)Math.Round(e.X + mObj.Parent.Offset.X);
var eY = (int)Math.Round(e.Y + mObj.Parent.Offset.Y);
switch (mEdge)
{
case EdgeEnum.TopLeft:
{
mObj.SetBounds(eX, eY, (int)Math.Round(mObj.Width + (mObj.Left - eX)), (int)Math.Round(mObj.Height + (mObj.Top - eY)));
break;
}
case EdgeEnum.TopRight:
{
mObj.SetBounds(mObj.Left, eY, eX - mObj.Left, (int)Math.Round(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)Math.Round(mObj.Width + (mObj.Left - eX)), eY - mObj.Top);
break;
}
case EdgeEnum.Left:
{
mObj.SetBounds(eX, mObj.Top, (int)Math.Round(mObj.Width + (mObj.Left - eX)), (int)Math.Round(mObj.Height));
break;
}
case EdgeEnum.Right:
{
mObj.SetBounds(mObj.Left, mObj.Top, eX - mObj.Left, (int)Math.Round(mObj.Height));
break;
}
case EdgeEnum.Top:
{
mObj.SetBounds(mObj.Left, eY, (int)Math.Round(mObj.Width), (int)Math.Round(mObj.Height + (mObj.Top - eY)));
break;
}
case EdgeEnum.Bottom:
{
mObj.SetBounds(mObj.Left, mObj.Top, (int)Math.Round(mObj.Width), eY - mObj.Top);
break;
}
}
var argsize = mObj.Size;
KeepInRange(ref argsize);
mObj.Size = argsize;
}
else if (!mMouseDown)
{
var eXo = e.X;
var eYo = e.Y;
var realX = (int)Math.Round(eXo + mObj.Parent.Offset.X);
var realY = (int)Math.Round(eYo + mObj.Parent.Offset.Y);
var eXwo = (int)Math.Round(eXo - mObj.X);
var eYwo = (int)Math.Round(eYo - mObj.Y);
var eX = (int)Math.Round(eXwo + mObj.Parent.Offset.X);
var eY = (int)Math.Round(eYwo + mObj.Parent.Offset.Y);
var eLocation = new Point(eX, eY);
RectangleF extRect = mObj.RectangleExtended;
var oldRect = mObj.Rectangle;
var newRect = new RectangleF
{
X = extRect.X - oldRect.X,
Y = extRect.Y - oldRect.Y,
Width = (extRect.Width - oldRect.Width) / 2f,
Height = (extRect.Height - oldRect.Height) / 2f
};
var setToNone = false;
var isOnTop = ReferenceEquals(mObj.Parent.GetObject(new PointF(realX, realY), true), mObj);
if (IsEnabled() && isOnTop)
{
switch (true)
{
case object _ when HelpfulDrawingFunctions.IsPointInRectangle(eLocation, new Rectangle((int)Math.Round(newRect.X), (int)Math.Round(newRect.Y), (int)Math.Round(newRect.Width), (int)Math.Round(newRect.Height))):
{
mObj.Cursor = Cursors.SizeNWSE;
mEdge = EdgeEnum.TopLeft;
break;
}
case object _ when HelpfulDrawingFunctions.IsPointInRectangle(eLocation, new Rectangle((int)Math.Round(mObj.Width), (int)Math.Round(newRect.Y), (int)Math.Round(newRect.Width), (int)Math.Round(newRect.Height))):
{
mObj.Cursor = Cursors.SizeNESW;
mEdge = EdgeEnum.TopRight;
break;
}
case object _ when HelpfulDrawingFunctions.IsPointInRectangle(eLocation, new Rectangle((int)Math.Round(mObj.Width), (int)Math.Round(mObj.Height), (int)Math.Round(newRect.Width), (int)Math.Round(newRect.Height))):
{
mObj.Cursor = Cursors.SizeNWSE;
mEdge = EdgeEnum.BottomRight;
break;
}
case object _ when HelpfulDrawingFunctions.IsPointInRectangle(eLocation, new Rectangle((int)Math.Round(newRect.X), (int)Math.Round(mObj.Height), (int)Math.Round(newRect.Width), (int)Math.Round(newRect.Height))):
{
mObj.Cursor = Cursors.SizeNESW;
mEdge = EdgeEnum.BottomLeft;
break;
}
case object _ when HelpfulDrawingFunctions.IsPointInRectangle(eLocation, new Rectangle((int)Math.Round(-newRect.Width), 0, (int)Math.Round(newRect.Width), (int)Math.Round(mObj.Height))):
{
mObj.Cursor = Cursors.SizeWE;
mEdge = EdgeEnum.Left;
break;
}
case object _ when HelpfulDrawingFunctions.IsPointInRectangle(eLocation, new Rectangle((int)Math.Round(mObj.Width), 0, (int)Math.Round(newRect.Width), (int)Math.Round(mObj.Height))):
{
mObj.Cursor = Cursors.SizeWE;
mEdge = EdgeEnum.Right;
break;
}
case object _ when HelpfulDrawingFunctions.IsPointInRectangle(eLocation, new Rectangle(0, (int)Math.Round(-newRect.Height), (int)Math.Round(mObj.Width), (int)Math.Round(newRect.Height))):
{
mObj.Cursor = Cursors.SizeNS;
mEdge = EdgeEnum.Top;
break;
}
case object _ when HelpfulDrawingFunctions.IsPointInRectangle(eLocation, new Rectangle(0, (int)Math.Round(mObj.Height), (int)Math.Round(mObj.Width), (int)Math.Round(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;
}
}