using System;
using System .Collections .Generic;
using System .Drawing;
using System .Drawing .Drawing2D;
using System .Windows .Forms;
using MoveGraphLibrary;
namespace Test_MoveGraphLibrary
{
public partial class Form_NNodeContours : Form
{
Mover mover;
bool bShowContours = false;
MRCircle mrcircle;
MRRectangle mrrect;
PolyRectangle polyrect;
NRing ring;
int cyShiftComments, cxShiftComments_R;
string [] Cmnts = new string [] { "L_Press anywhere inside ", "- move",
"L_Press at any border ", "- resize",
"NO rotation in this form!", " " };
// -------------------------------------------------
public Form_NNodeContours ()
{
InitializeComponent ();
Auxi_Common .TwoColumnPanelComments (this, panelInfo, Font, Cmnts, out cxShiftComments_R, out cyShiftComments);
mover = new Mover (this);
int nW = ClientSize .Width;
int nH = ClientSize .Height;
mrcircle = new MRCircle (new Point (nW / 6, nH / 4), Convert .ToInt32 (Math .Min (nW / 6, nH / 4) * 0.8), Color .Yellow);
mover .Add (mrcircle);
mrrect = new MRRectangle (new Rectangle (nW / 9, nH / 2, nW / 4, nH * 5 / 16), Color .Cyan);
mover .Insert (0, mrrect);
polyrect = new PolyRectangle (new Rectangle (nW * 7 / 12, nH * 7 / 10, nW / 4, nH / 4));
polyrect .Color = Color .LightGreen;
mover .Insert (0, polyrect);
ring = new NRing (new Point (nW * 2 / 3, nH * 3 / 10), nH * 2 / 15, nH / 3, new double [] { 1, 5, 3, 10, 7 });
mover .Insert (0, ring);
mover .Insert (0, buttonContours);
mover .Insert (0, panelInfo);
}
// ------------------------------------------------- Click_btnContours
private void Click_btnContours (object sender, EventArgs e)
{
bShowContours = !bShowContours;
Invalidate ();
}
// ------------------------------------------------- OnPaint
private void OnPaint (object sender, PaintEventArgs e)
{
Graphics grfx = e .Graphics;
mrcircle .Draw (grfx);
mrrect .Draw (grfx);
polyrect .Draw (grfx);
ring .Draw (grfx);
if (bShowContours)
{
for (int i = mover .Count - 1; i >= 0; i--)
{
mover [i] .DrawCover (grfx);
}
}
}
// ------------------------------------------------- OnMouseDown
private void OnMouseDown (object sender, MouseEventArgs mea)
{
if (mea .Button == MouseButtons .Left)
{
mover .Catch (mea .Location);
}
}
// ------------------------------------------------- OnMouseUp
private void OnMouseUp (object sender, MouseEventArgs mea)
{
if (mover .Release ())
{
if (mover [mover .WasCaughtObject] .Source is MRRectangle)
{
(mover [mover .WasCaughtObject] .Source as MRRectangle) .RedefineCover ();
Invalidate ();
}
else if (mover [mover .WasCaughtObject] .Source is NRing)
{
(mover [mover .WasCaughtObject] .Source as NRing) .RedefineCover ();
Invalidate ();
}
}
}
// ------------------------------------------------- OnMouseMove
private void OnMouseMove (object sender, MouseEventArgs mea)
{
if (mover .Move (mea .Location))
{
Invalidate ();
}
}
// ------------------------------------------------- OnPaint_panelComments
private void OnPaint_panelComments (object sender, PaintEventArgs e)
{
Graphics grfx = e .Graphics;
SolidBrush brush = new SolidBrush (Color .Black);
int nLines = Cmnts .Length / 2;
for (int i = 0; i < nLines; i++)
{
grfx .DrawString (Cmnts [i * 2], Font, brush, 0, i * cyShiftComments);
grfx .DrawString (Cmnts [i * 2 + 1], Font, brush, cxShiftComments_R, i * cyShiftComments);
}
}
}
// ******************************************
//
public class MRCircle : GraphicalObject
{
Point ptCenter;
int radius;
Color clr = Color .Blue;
int nrSmall = 5;
int distanceNeighbours = 9;
int nMinRadius = 25; // min size is set to avoid disappearence while resizing
bool bShowRadius;
Color clrText;
Font font;
double angle = 0.0;
// -------------------------------------------------
public MRCircle (Point pt, int rad, Color color)
{
ptCenter = pt;
radius = rad;
clr = color;
bShowRadius = false;
clrText = Color .Black;
font = new Font ("Microsoft Sans Serif", (float) 7.8);
}
// ------------------------------------------------- Center
public Point Center
{
get { return (ptCenter); }
}
// ------------------------------------------------- Radius
public int Radius
{
get { return (radius); }
}
// ------------------------------------------------- Color
public Color Color
{
get { return (clr); }
set { clr = value; }
}
// ------------------------------------------------- ShowRadius
public bool ShowRadius
{
get { return (bShowRadius); }
set { bShowRadius = value; }
}
// ------------------------------------------------- TextColor
public Color TextColor
{
get { return (clrText); }
set { clrText = value; }
}
// ------------------------------------------------- Font
public Font Font
{
get { return (font); }
set
{
if (font != null)
{
font = value;
}
}
}
// ------------------------------------------------- Angle
public double Angle
{
get { return (angle); }
set { angle = value; }
}
// ------------------------------------------------- IsInside
public bool IsInside (Point pt)
{
return (Auxi_Geometry .Distance (ptCenter, pt) <= radius);
}
// ------------------------------------------------- Draw
public void Draw (Graphics grfx)
{
Auxi_Drawing .FillEllipse (grfx, clr, ptCenter, radius);
Auxi_Drawing .DrawEllipse (grfx, Color .DarkGray, ptCenter, radius);
if (bShowRadius)
{
Auxi_Drawing .RotatedText (grfx, radius .ToString (), font, angle, TextColor, ptCenter, TextBasicPoint .M);
}
}
// ------------------------------------------------- DefineCover
public override void DefineCover ()
{
int nOnPerimeter = Convert .ToInt32 ((2 * Math .PI * radius) / distanceNeighbours);
CoverNode [] shreds = new CoverNode [nOnPerimeter + 1];
shreds [0] = new CoverNode (0, ptCenter, radius - nrSmall + 1, Cursors .SizeAll);
for (int i = 1; i <= nOnPerimeter; i++)
{
shreds [i] = new CoverNode (i, Auxi_Geometry .PointToPoint (ptCenter, 2 * Math .PI * (i - 1) / nOnPerimeter, radius), nrSmall);
shreds [i] .Clearance = false;
}
cover = new Cover (shreds);
}
// -------------------------------------------------
public override void Move (int cx, int cy)
{
ptCenter += new Size (cx, cy);
}
// ------------------------------------------------- MoveNode
public override bool MoveNode (int i, int cx, int cy, Point ptM, MouseButtons catcher)
{
bool bRet = false;
if (catcher == MouseButtons .Left)
{
if (i == 0)
{
Move (cx, cy);
}
else
{
int nRadNew = Convert .ToInt32 (Auxi_Geometry .Distance (ptCenter, ptM));
if (nRadNew != radius && nRadNew >= nMinRadius)
{
radius = nRadNew;
bRet = true;
}
}
}
return (bRet);
}
}
// ******************************************
//
public class MRRectangle : GraphicalObject
{
Rectangle rect;
Color color = Color .Blue;
Brush brush;
int halfNode = 3;
int sideNode;
int nMinRectSide = 25; // min size is set to avoid disappearence while resizing
int nNodesOnSide;
int nNodesOnTop;
int iFirstOnLeft;
int iFirstOnRight;
int iFirstOnTop;
int iFirstOnBottom;
// -------------------------------------------------
public MRRectangle (Rectangle rc, Color clr)
{
if (rc .IsEmpty)
{
rect = new Rectangle (100, 100, 200, 120);
}
else
{
rc .Width = Math .Max (nMinRectSide, rc .Width);
rc .Height = Math .Max (nMinRectSide, rc .Height);
rect = rc;
}
sideNode = 2 * halfNode;
NodesOnSides ();
color = clr;
brush = new SolidBrush (Color);
}
// ------------------------------------------------- NodesOnSides
private void NodesOnSides ()
{
nNodesOnSide = (rect .Height - sideNode) / sideNode;
if (rect .Height % sideNode != 0)
{
nNodesOnSide++;
}
nNodesOnTop = (rect .Width - sideNode) / sideNode;
if (rect .Width % sideNode != 0)
{
nNodesOnTop++;
}
iFirstOnLeft = 6;
iFirstOnRight = iFirstOnLeft + nNodesOnSide;
iFirstOnTop = iFirstOnRight + nNodesOnSide;
iFirstOnBottom = iFirstOnTop + nNodesOnTop;
}
// ------------------------------------------------- Rectangle
public Rectangle Rectangle
{
get { return (rect); }
}
// ------------------------------------------------- Color
public Color Color
{
get { return (color); }
set
{
color = value;
brush = new SolidBrush (Color);
}
}
// ------------------------------------------------- Draw
public void Draw (Graphics grfx)
{
grfx .FillRectangle (brush, rect);
}
// ------------------------------------------------- DefineCover
public void RedefineCover ()
{
NodesOnSides ();
DefineCover ();
}
// ------------------------------------------------- DefineCover
// order of nodes: 2 big inside,
// 4 on corners (LT, RT, RB, LB),
// 2 * nNodesOnSide on sides (left, right)
// 2 * nNodesOnTop on sides (top, bottom)
// nodes 0, 1 - cover the ends of the inside area; the only nodes that are connected
//
public override void DefineCover ()
{
Rectangle rcInner = new Rectangle (rect .Left + halfNode, rect .Top + halfNode, rect .Width - sideNode, rect .Height - sideNode);
int nBigNodeSide;
Point [] ptM = Auxi_Geometry .TwoSquaresOnRectangle (rcInner, out nBigNodeSide);
CoverNode [] nodes = new CoverNode [2 + 4 + 2 * nNodesOnSide + 2 * nNodesOnTop];
int halfBig = nBigNodeSide / 2; ;
nodes [0] = new CoverNode (0, new PointF [] {new PointF (ptM [0] .X - halfBig, ptM [0] .Y - halfBig),
new PointF (ptM [0] .X + halfBig, ptM [0] .Y - halfBig),
new PointF (ptM [0] .X + halfBig, ptM [0] .Y + halfBig),
new PointF (ptM [0] .X - halfBig, ptM [0] .Y + halfBig) });
nodes [1] = new CoverNode (1, new PointF [] {new PointF (ptM [1] .X - halfBig, ptM [1] .Y - halfBig),
new PointF (ptM [1] .X + halfBig, ptM [1] .Y - halfBig),
new PointF (ptM [1] .X + halfBig, ptM [1] .Y + halfBig),
new PointF (ptM [1] .X - halfBig, ptM [1] .Y + halfBig) });
nodes [2] = new CoverNode (2, new PointF (rect .Left, rect .Top), 5, Cursors .SizeNWSE);
nodes [3] = new CoverNode (3, new PointF (rect .Right, rect .Top), 5, Cursors .SizeNESW);
nodes [4] = new CoverNode (4, new PointF (rect .Right, rect .Bottom), 5, Cursors .SizeNWSE);
nodes [5] = new CoverNode (5, new PointF (rect .Left, rect .Bottom), 5, Cursors .SizeNESW);
int cyMax = rect .Bottom - (halfNode + 1);
for (int i = 0; i < nNodesOnSide; i++)
{
nodes [i + iFirstOnLeft] = new CoverNode (i + iFirstOnLeft,
new PointF (rect .Left, Math .Min (rect .Top + sideNode * (i + 1), cyMax)),
MovementFreedom .WE, Cursors .SizeWE);
}
for (int i = 0; i < nNodesOnSide; i++)
{
nodes [i + iFirstOnRight] = new CoverNode (i + iFirstOnRight,
new PointF (rect .Right, Math .Min (rect .Top + sideNode * (i + 1), cyMax)),
MovementFreedom .WE, Cursors .SizeWE);
}
int cxMax = rect .Right - (halfNode + 1);
for (int i = 0; i < nNodesOnTop; i++)
{
nodes [i + iFirstOnTop] = new CoverNode (i + iFirstOnTop,
new PointF (Math .Min (rect .Left + sideNode * (i + 1), cxMax), rect .Top),
MovementFreedom .NS, Cursors .SizeNS);
}
for (int i = 0; i < nNodesOnTop; i++)
{
nodes [i + iFirstOnBottom] = new CoverNode (i + iFirstOnBottom,
new PointF (Math .Min (rect .Left + sideNode * (i + 1), cxMax), rect .Bottom),
MovementFreedom .NS, Cursors .SizeNS);
}
for (int i = 0; i < nodes .Length; i++)
{
nodes [i] .Clearance = false;
}
cover = new Cover (nodes);
}
// -------------------------------------------------
public override void Move (int cx, int cy)
{
rect .X += cx;
rect .Y += cy;
}
// ------------------------------------------------- MoveNode
public override bool MoveNode (int i, int cx, int cy, Point ptM, MouseButtons catcher)
{
bool bRet = false;
if (catcher == MouseButtons .Left)
{
if (i == 0 || i == 1)
{
Move (cx, cy);
}
else if (i == 2) //LT corner
{
if (rect .Height - cy >= nMinRectSide)
{
MoveBorder_Top (cy);
bRet = true;
}
if (rect .Width - cx >= nMinRectSide)
{
MoveBorder_Left (cx);
bRet = true;
}
}
else if (i == 3) // RT corner
{
if (rect .Height - cy >= nMinRectSide)
{
MoveBorder_Top (cy);
bRet = true;
}
if (rect .Width + cx >= nMinRectSide)
{
MoveBorder_Right (cx);
bRet = true;
}
}
else if (i == 4) // RB corner
{
if (rect .Width + cx >= nMinRectSide)
{
MoveBorder_Right (cx);
bRet = true;
}
if (rect .Height + cy >= nMinRectSide)
{
MoveBorder_Bottom (cy);
bRet = true;
}
}
else if (i == 5) // LB corner
{
if (rect .Height + cy >= nMinRectSide)
{
MoveBorder_Bottom (cy);
bRet = true;
}
if (rect .Width - cx >= nMinRectSide)
{
MoveBorder_Left (cx);
bRet = true;
}
}
else if (i >= iFirstOnBottom) // on bottom
{
if (rect .Height + cy >= nMinRectSide)
{
MoveBorder_Bottom (cy);
bRet = true;
}
}
else if (i >= iFirstOnTop) // on top
{
if (rect .Height - cy >= nMinRectSide)
{
MoveBorder_Top (cy);
bRet = true;
}
}
else if (i >= iFirstOnRight) // on right side
{
if (rect .Width + cx >= nMinRectSide)
{
MoveBorder_Right (cx);
bRet = true;
}
}
else if (i >= iFirstOnLeft) // on left side
{
if (rect .Width - cx >= nMinRectSide)
{
MoveBorder_Left (cx);
bRet = true;
}
}
}
return (bRet);
}
// ------------------------------------------------- MoveBorder_Top
private void MoveBorder_Top (int cy)
{
rect .Y += cy;
rect .Height -= cy;
}
// ------------------------------------------------- MoveBorder_Bottom
private void MoveBorder_Bottom (int cy)
{
rect .Height += cy;
}
// ------------------------------------------------- MoveBorder_Left
private void MoveBorder_Left (int cx)
{
rect .X += cx;
rect .Width -= cx;
}
// ------------------------------------------------- MoveBorder_Right
private void MoveBorder_Right (int cx)
{
rect .Width += cx;
}
}
// ******************************************
//
public class PolyRectangle : GraphicalObject
{
Rectangle rect;
Color color = Color .LightGreen;
Brush brush;
int minwidth = 35; // to avoid disappearence while resizing
int minheight = 25; // to avoid disappearence while resizing
// -------------------------------------------------
public PolyRectangle (Rectangle rc)
{
if (rc .IsEmpty)
{
rect = new Rectangle (200, 200, 160, 110);
}
else
{
rc .Width = Math .Max (minwidth, rc .Width);
rc .Height = Math .Max (minheight, rc .Height);
rect = rc;
}
brush = new SolidBrush (Color);
}
// ------------------------------------------------- Rectangle
public Rectangle Rectangle
{
get { return (rect); }
}
// ------------------------------------------------- Color
public Color Color
{
get { return (color); }
set
{
color = value;
brush = new SolidBrush (Color);
}
}
// ------------------------------------------------- Draw
public void Draw (Graphics grfx)
{
grfx .FillRectangle (brush, rect);
}
// ------------------------------------------------- DefineCover
// order of nodes: 4 on corners (LT, RT, RB, LB),
// 4 polygon nodes on sides (left, top, right, bottom)
// 1 polygon (rectangular) node inside,
//
public override void DefineCover ()
{
int smallhalf = 3;
int cornerradius = 6;
CoverNode [] nodes = new CoverNode [4 + 4 + 1];
nodes [0] = new CoverNode (0, new PointF (rect .Left, rect .Top), cornerradius, Cursors .SizeNWSE);
nodes [1] = new CoverNode (1, new PointF (rect .Right, rect .Top), cornerradius, Cursors .SizeNESW);
nodes [2] = new CoverNode (2, new PointF (rect .Right, rect .Bottom), cornerradius, Cursors .SizeNWSE);
nodes [3] = new CoverNode (3, new PointF (rect .Left, rect .Bottom), cornerradius, Cursors .SizeNESW);
nodes [4] = new CoverNode (4, new PointF [] {new PointF (rect .Left - smallhalf, rect .Top),
new PointF (rect .Left + smallhalf, rect .Top),
new PointF (rect .Left + smallhalf, rect .Bottom),
new PointF (rect .Left - smallhalf, rect .Bottom)},
MovementFreedom .WE, Cursors .SizeWE);
nodes [5] = new CoverNode (5, new PointF [] {new PointF (rect .Left, rect .Top - smallhalf),
new PointF (rect .Right, rect .Top - smallhalf),
new PointF (rect .Right, rect .Top + smallhalf),
new PointF (rect .Left, rect .Top + smallhalf)},
MovementFreedom .NS, Cursors .SizeNS);
nodes [6] = new CoverNode (6, new PointF [] { new PointF (rect .Right - smallhalf, rect .Top),
new PointF (rect .Right + smallhalf, rect .Top),
new PointF (rect .Right + smallhalf, rect .Bottom),
new PointF (rect .Right - smallhalf, rect .Bottom)},
MovementFreedom .WE, Cursors .SizeWE);
nodes [7] = new CoverNode (7, new PointF [] { new PointF (rect .Left, rect .Bottom - smallhalf),
new PointF (rect .Right, rect .Bottom - smallhalf),
new PointF (rect .Right, rect .Bottom + smallhalf),
new PointF (rect .Left, rect .Bottom + smallhalf)},
MovementFreedom .NS, Cursors .SizeNS);
nodes [8] = new CoverNode (8, new PointF [] { new PointF (rect .Left, rect .Top),
new PointF (rect .Right, rect .Top),
new PointF (rect .Right, rect .Bottom),
new PointF (rect .Left, rect .Bottom)});
cover = new Cover (nodes);
}
// -------------------------------------------------
public override void Move (int cx, int cy)
{
rect .X += cx;
rect .Y += cy;
}
// ------------------------------------------------- MoveNode
public override bool MoveNode (int i, int cx, int cy, Point ptM, MouseButtons catcher)
{
bool bRet = false;
if (catcher == MouseButtons .Left)
{
if (i == 8)
{
Move (cx, cy);
}
else if (i == 0) //LT corner
{
if (rect .Height - cy >= minheight)
{
MoveBorder_Top (cy);
bRet = true;
}
if (rect .Width - cx >= minwidth)
{
MoveBorder_Left (cx);
bRet = true;
}
}
else if (i == 1) // RT corner
{
if (rect .Height - cy >= minheight)
{
MoveBorder_Top (cy);
bRet = true;
}
if (rect .Width + cx >= minwidth)
{
MoveBorder_Right (cx);
bRet = true;
}
}
else if (i == 2) // RB corner
{
if (rect .Width + cx >= minwidth)
{
MoveBorder_Right (cx);
bRet = true;
}
if (rect .Height + cy >= minheight)
{
MoveBorder_Bottom (cy);
bRet = true;
}
}
else if (i == 3) // LB corner
{
if (rect .Height + cy >= minheight)
{
MoveBorder_Bottom (cy);
bRet = true;
}
if (rect .Width - cx >= minwidth)
{
MoveBorder_Left (cx);
bRet = true;
}
}
else if (i == 4) // on left side
{
if (rect .Width - cx >= minwidth)
{
MoveBorder_Left (cx);
bRet = true;
}
}
else if (i == 5) // on top
{
if (rect .Height - cy >= minheight)
{
MoveBorder_Top (cy);
bRet = true;
}
}
else if (i == 6) // on right side
{
if (rect .Width + cx >= minwidth)
{
MoveBorder_Right (cx);
bRet = true;
}
}
else if (i == 7) // on bottom
{
if (rect .Height + cy >= minheight)
{
MoveBorder_Bottom (cy);
bRet = true;
}
}
}
return (bRet);
}
// ------------------------------------------------- MoveBorder_Top
private void MoveBorder_Top (int cy)
{
rect .Y += cy;
rect .Height -= cy;
}
// ------------------------------------------------- MoveBorder_Bottom
private void MoveBorder_Bottom (int cy)
{
rect .Height += cy;
}
// ------------------------------------------------- MoveBorder_Left
private void MoveBorder_Left (int cx)
{
rect .X += cx;
rect .Width -= cx;
}
// ------------------------------------------------- MoveBorder_Right
private void MoveBorder_Right (int cx)
{
rect .Width += cx;
}
}
}