EduNetworkBuilder/EduNetworkBuilder/NetShape.cs

189 lines
6.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Xml;
namespace EduNetworkBuilder
{
/// <summary>
/// For drawing shapes on a network. Rectangles, circles. Filled or not
/// </summary>
public class NetShape
{
public NetShapeType MyShape = NetShapeType.none;
public Rectangle InArea;
public Color LineColor = Color.Empty;
public Color FillColor = Color.Empty;
public string Name = "";
int DragSize = 15;
public NetShape(NetShapeType What, Rectangle Where, Color fillcolor, Color linecolor)
{
MyShape = What;
InArea = Where;
FillColor = fillcolor;
LineColor = linecolor;
}
public NetShape(XmlNode what)
{
Load(what);
}
/// <summary>
/// Draw the specified shape on the image
/// </summary>
/// <param name="baseImage"></param>
public void Draw(Image baseImage, bool InShapeEditMode = false)
{
Graphics G = Graphics.FromImage(baseImage);
Pen trimPen = new Pen(LineColor);
Brush coloredBrush = new SolidBrush(FillColor);
switch(MyShape)
{
case NetShapeType.circle:
if(FillColor != Color.Empty)
G.FillEllipse(coloredBrush,InArea);
if (LineColor != Color.Empty)
G.DrawEllipse(trimPen, InArea);
break;
case NetShapeType.rectangle:
if (FillColor != Color.Empty)
G.FillRectangle(coloredBrush, InArea);
if (LineColor != Color.Empty)
G.DrawRectangle(trimPen, InArea);
break;
}
if(InShapeEditMode)
{
int sz = DragSize;
Color edgeColor = Color.Black;
if (FillColor == Color.Black) edgeColor = Color.White;
coloredBrush = new SolidBrush(edgeColor);
//We want to put drag-marks on the corners of our rectangle
foreach(Rectangle one in Corners())
G.FillRectangle(coloredBrush, one);
G.DrawImage(Properties.Resources.X, Center());
}
G.Dispose();
}
List<Rectangle> Corners()
{
int sz = DragSize;
List<Rectangle> tCorners = new List<Rectangle>();
Rectangle TL = new Rectangle(InArea.X, InArea.Y, sz, sz);
Rectangle TR = new Rectangle(InArea.X + InArea.Width - sz, InArea.Y, sz, sz);
Rectangle BL = new Rectangle(InArea.X, InArea.Y + InArea.Height - sz, sz, sz);
Rectangle BR = new Rectangle(InArea.X + InArea.Width - sz, InArea.Y + InArea.Height - sz, sz, sz);
tCorners.Add(TL);
tCorners.Add(TR);
tCorners.Add(BL);
tCorners.Add(BR);
return tCorners;
}
//A rectangle in the center of the shape that we can click on
Rectangle Center()
{
int size = 100;
if (InArea.Width < 200 || InArea.Height < 200)
size = 50;
if (InArea.Width < size || InArea.Height < size)
size = Math.Min(InArea.Width / 2, InArea.Height / 2);
int cx = InArea.X + (InArea.Width / 2);
int cy = InArea.Y + (InArea.Height / 2);
return new Rectangle(cx - (size / 2), cy - (size / 2), size, size);
}
public bool CornersAreClickedOn(Point ClickPoint)
{
foreach(Rectangle rec in Corners())
{
if (rec.Contains(ClickPoint))
return true;
}
return false;
}
public bool CenterIsClickedOn(Point ClickPoint)
{
if (Center().Contains(ClickPoint))
return true;
return false;
}
/// <summary>
/// return the opposite point from the one clicked on. This is so we can start
/// dragging from here.
/// </summary>
/// <param name="ClickPoint"></param>
/// <returns></returns>
public Point OppositePoint(Point ClickPoint)
{
int fX = ClickPoint.X;
int fY = ClickPoint.Y;
int halfWidth = InArea.Width / 2;
int halfHeight = InArea.Height / 2;
if (ClickPoint.X > InArea.X + halfWidth) fX = InArea.X;
else fX = InArea.X + InArea.Width;
if (ClickPoint.Y > InArea.Y + halfHeight) fY = InArea.Y;
else fY = InArea.Y + InArea.Height;
return new Point(fX, fY);
}
public override string ToString()
{
string answer = Name + " " + MyShape.ToString() + " " + LineColor.Name + "/" + FillColor.Name;
answer = answer + " X:" + InArea.X + " Y:" + InArea.Y;
answer = answer + "W:" + InArea.Width + " H:" + InArea.Height;
return answer;
}
public void Load(XmlNode theNode)
{
foreach (XmlNode Individual in theNode.ChildNodes)
{
XmlNodeType myNodetype = Individual.NodeType;
if (myNodetype == XmlNodeType.Element)
{
switch (Individual.Name.ToLower())
{
case "name":
Name = Individual.InnerText;
break;
case "what":
MyShape = NB.TryParseEnum<NetShapeType>(Individual.InnerText, NetShapeType.none);
break;
case "where":
RectangleConverter converter = new RectangleConverter();
InArea = (Rectangle)converter.ConvertFromString(Individual.InnerText);
break;
case "fillcolor":
FillColor = Color.FromName(Individual.InnerText);
break;
case "linecolor":
LineColor = Color.FromName(Individual.InnerText);
break;
}
}
}
}
public void Save(XmlWriter writer)
{
writer.WriteStartElement("shape");
writer.WriteElementString("name", Name);
writer.WriteElementString("what", MyShape.ToString());
RectangleConverter converter = new RectangleConverter();
writer.WriteElementString("where", converter.ConvertToString(InArea));
writer.WriteElementString("fillcolor", FillColor.Name);
writer.WriteElementString("linecolor", LineColor.Name);
writer.WriteEndElement();
}
}
}