using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.IO;
using System.Runtime.Serialization;
using System.Windows.Forms;
using SmartCoalApplication.Annotation.Enum;
using SmartCoalApplication.Base.SettingModel;
namespace SmartCoalApplication.Annotation.Label
{
///
/// 标注->直线->线段
///
public class DrawLineSegment : DrawObject
{
private const string entryStart = "Start";
private const string entryEnd = "End";
///
/// Graphic objects for hit test
///
private GraphicsPath areaPath = null;
private Pen areaPen = null;
private Region areaRegion = null;
// Create the outline for our custom end cap.
GraphicsPath hPath = new GraphicsPath();
// Construct the hook-shaped end cap.
CustomLineCap HookCap;
///
/// 标注样式信息model
///
private LabelStyleModel.LineChildLineSegment labelLineSegment;
public LabelStyleModel.LineChildLineSegment LabelLineSegment
{
set
{
this.labelLineSegment = value;
}
}
public DrawLineSegment(ISurfaceBox surfaceBox, int x1, int y1, int x2, int y2) : base()
{
this.objectType = DrawClass.Label;
this.drawToolType = DrawToolType.DrawLineSegment;
labelLineSegment = surfaceBox.GetLabelStyleModel().lineChildLineSegment;
startPoint.X = x1;
startPoint.Y = y1;
endPoint.X = x2;
endPoint.Y = y2;
//自定义线形的线帽
hPath.AddLine(new PointF(-10, 0), new PointF(10, 0));
HookCap = new CustomLineCap(null, hPath);
HookCap.SetStrokeCaps(LineCap.Round, LineCap.Round);
/*//求出亮点之间的距离
int xy = (startPoint.X - endPoint.X) * (startPoint.X - endPoint.X) + (startPoint.Y - endPoint.Y) * (startPoint.Y - endPoint.Y);
int k = (int)Math.Sqrt(xy);
//没有则创建这个文件
StreamWriter sw = File.AppendText("e:\\temp\\testtxt.txt");
sw.Write(DateTime.Now + " : " + xy + "\r\n");
sw.Flush();
sw.Close();
sw.Dispose();*/
Initialize();
}
public DrawLineSegment(ISurfaceBox surfaceBox, List points, ParentStyleModel parentStyleModel, Object content) : base()
{
this.objectType = DrawClass.Label;
this.drawToolType = DrawToolType.DrawLineSegment;
this.ISurfaceBox = surfaceBox;
labelLineSegment = (LabelStyleModel.LineChildLineSegment)parentStyleModel;
startPoint.X = points[0].X;
startPoint.Y = points[0].Y;
endPoint.X = points[1].X;
endPoint.Y = points[1].Y;
hPath.AddLine(new PointF(-10, 0), new PointF(10, 0));
HookCap = new CustomLineCap(null, hPath);
HookCap.SetStrokeCaps(LineCap.Round, LineCap.Round);
}
///
/// Clone this instance
///
public override DrawObject Clone()
{
DrawLineSegment drawLineSegment = new DrawLineSegment(ISurfaceBox, 0, 0, 1, 0);
drawLineSegment.objectType = DrawClass.Label;
drawLineSegment.drawToolType = DrawToolType.DrawLineSegment;
drawLineSegment.ISurfaceBox = this.ISurfaceBox;
drawLineSegment.startPoint = this.startPoint;
drawLineSegment.endPoint = this.endPoint;
drawLineSegment.hPath.AddLine(new PointF(-10, 0), new PointF(10, 0));
drawLineSegment.HookCap = new CustomLineCap(null, hPath);
drawLineSegment.HookCap.SetStrokeCaps(LineCap.Round, LineCap.Round);
FillDrawObjectFields(drawLineSegment);
return drawLineSegment;
}
public override DrawObject Clone(ISurfaceBox surfaceBox)
{
DrawLineSegment drawLineSegment = new DrawLineSegment(surfaceBox, 0, 0, 1, 0);
drawLineSegment.objectType = DrawClass.Label;
drawLineSegment.drawToolType = DrawToolType.DrawLineSegment;
drawLineSegment.ISurfaceBox = surfaceBox;
drawLineSegment.startPoint = this.startPoint;
drawLineSegment.endPoint = this.endPoint;
drawLineSegment.hPath.AddLine(new PointF(-10, 0), new PointF(10, 0));
drawLineSegment.HookCap = new CustomLineCap(null, hPath);
drawLineSegment.HookCap.SetStrokeCaps(LineCap.Round, LineCap.Round);
drawLineSegment.labelLineSegment = this.labelLineSegment;
FillDrawObjectFields(drawLineSegment);
return drawLineSegment;
}
public override void Draw(Graphics g)
{
g.SmoothingMode = SmoothingMode.AntiAlias;
Color color = Color.FromArgb(this.labelLineSegment.lineColor);
Pen pen = new Pen(color, this.labelLineSegment.lineWidth);
pen.DashStyle = (DashStyle)this.labelLineSegment.lineStyle;
pen.CustomStartCap = HookCap;
pen.CustomEndCap = HookCap;
g.DrawLine(pen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
pen.Dispose();
}
public override int HandleCount
{
get
{
return 2;
}
}
///
/// Get handle pointscroll by 1-based number
///
///
///
public override PointF GetHandle(int handleNumber)
{
if (handleNumber == 1)
return startPoint;
else
return endPoint;
}
///
/// Hit test.
/// Return value: -1 - no hit
/// 0 - hit anywhere
/// > 1 - handle number
///
///
///
public override int HitTest(Point point)
{
if (Selected)
{
for (int i = 1; i <= HandleCount; i++)
{
if (GetHandleRectangle(i).Contains(point))
return i;
}
}
if (PointInObject(point))
return 0;
return -1;
}
protected override bool PointInObject(Point point)
{
CreateObjects();
return AreaRegion.IsVisible(point);
}
public override bool IntersectsWith(Rectangle rectangle)
{
CreateObjects();
return AreaRegion.IsVisible(rectangle);
}
public override Cursor GetHandleCursor(int handleNumber)
{
switch (handleNumber)
{
case 1:
case 2:
return Cursors.SizeAll;
default:
return Cursors.Default;
}
}
public override void MoveHandleTo(Point point, int handleNumber)
{
if (handleNumber == 1)
startPoint = point;
else
endPoint = point;
Invalidate();
}
public override void Move(int deltaX, int deltaY)
{
int x = ISurfaceBox.UnscaleScalar(deltaX);
int y = ISurfaceBox.UnscaleScalar(deltaY);
startPoint.X += x;
startPoint.Y += y;
endPoint.X += x;
endPoint.Y += y;
Invalidate();
}
public override void SaveToStream(System.Runtime.Serialization.SerializationInfo info, int orderNumber)
{
info.AddValue(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}",
entryStart, orderNumber),
startPoint);
info.AddValue(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}",
entryEnd, orderNumber),
endPoint);
base.SaveToStream(info, orderNumber);
}
public override void LoadFromStream(SerializationInfo info, int orderNumber)
{
startPoint = (Point)info.GetValue(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}",
entryStart, orderNumber),
typeof(Point));
endPoint = (Point)info.GetValue(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}",
entryEnd, orderNumber),
typeof(Point));
base.LoadFromStream(info, orderNumber);
}
///
/// Invalidate object.
/// When object is invalidated, path used for hit test
/// is released and should be created again.
///
protected void Invalidate()
{
if (AreaPath != null)
{
AreaPath.Dispose();
AreaPath = null;
}
if (AreaPen != null)
{
AreaPen.Dispose();
AreaPen = null;
}
if (AreaRegion != null)
{
AreaRegion.Dispose();
AreaRegion = null;
}
}
///
/// Create graphic objects used from hit test.
///
protected virtual void CreateObjects()
{
if (AreaPath != null)
return;
// Create path which contains wide line
// for easy mouse selection
AreaPath = new GraphicsPath();
AreaPen = new Pen(Color.Black, 7);
AreaPath.AddLine(startPoint.X-1, startPoint.Y-1, endPoint.X+1, endPoint.Y+1);
AreaPath.Widen(AreaPen);
// Create region from the path
AreaRegion = new Region(AreaPath);
}
protected GraphicsPath AreaPath
{
get
{
return areaPath;
}
set
{
areaPath = value;
}
}
protected Pen AreaPen
{
get
{
return areaPen;
}
set
{
areaPen = value;
}
}
protected Region AreaRegion
{
get
{
return areaRegion;
}
set
{
areaRegion = value;
}
}
public override RectangleF GetBoundingBox()
{
RectangleF rectangle = GetNotmalizedRectangle(startPoint, endPoint);
return rectangle;
}
public static RectangleF GetNotmalizedRectangle(PointF a, PointF b)
{
RectangleF rect = new RectangleF();
if (a.X < b.X)
{
rect.X = a.X;
rect.Width = b.X - a.X;
}
else
{
rect.X = b.X;
rect.Width = a.X - b.X;
}
if (a.Y < b.Y)
{
rect.Y = a.Y;
rect.Height = b.Y - a.Y;
}
else
{
rect.Y = b.Y;
rect.Height = a.Y - b.Y;
}
return rect;
}
///
/// Draw tracker for selected object
///
///
public override void DrawTracker(Graphics g)
{
if (!Selected)
return;
SolidBrush brush = new SolidBrush(Color.Black);
for (int i = 1; i <= HandleCount; i++)
{
g.FillRectangle(brush, GetHandleRectangle(i));
}
brush.Dispose();
}
public override List GetPoints()
{
List points = new List();
points.Add(startPoint);
points.Add(endPoint);
return points;
}
public override ParentStyleModel GetStyle()
{
return labelLineSegment;
}
}
}