using MuchInfo.Chart.Data; using MuchInfo.Chart.Data.EnumTypes; using MuchInfo.Chart.Infrastructure.Controls; using MuchInfo.Chart.Infrastructure.Helpers; using MuchInfo.Chart.Infrastructure.Utilities; using MuchInfo.Chart.WPF.Controls.Editors; using MuchInfo.Chart.WPF.Helpers; using MuchInfo.Chart.WPF.Primitives.Interfaces; using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Xml.Linq; namespace MuchInfo.Chart.WPF.Primitives.Drawing { public abstract class Drawing2PointBase : IDrawingTool { #region Fields protected Point mActualP1; protected Point mActualP2; protected Point mDrawP1; protected Point mDrawP2; protected Color mColor; protected Color mExtensionColor; protected DateTime P1Date; protected DateTime P2Date; protected bool mExtendLeft; protected bool mExtendRight; protected float P1Val; protected float P2Val; protected Rect mLastRect; public ScaleLayer mLastScale = new ScaleLayer(); public Chart Chart { get; set; } private IDrawingToolSpec _drawingToolSpec; private bool _plotOnAllSymbols; private double _p1X; private double _p1Y; private double _p2X; private double _p2Y; #endregion Fields #region Constructors protected Drawing2PointBase() { this.mColor = Colors.Red; this.mExtensionColor = Colors.Yellow; this.mExtendRight = false; this.mExtendLeft = false; this._plotOnAllSymbols = false; } #endregion Constructors #region Properties #region Public Properties public Color Color { get { return this.mColor; } set { bool flag = !this.mColor.Equals(value); if (flag) { this.mColor = value; this.ColorChanged(); this.PropertyChanged(); } } } public DateTime DrawingDate1 { get { return this.P1Date; } set { this.P1Date = value; this.PropertyChanged(); } } public DateTime DrawingDate2 { get { return this.P2Date; } set { this.P2Date = value; this.PropertyChanged(); } } public float DrawingValue1 { get { return this.P1Val; } set { this.P1Val = value; this.PropertyChanged(); } } public float DrawingValue2 { get { return this.P2Val; } set { this.P2Val = value; this.PropertyChanged(); } } public bool ExtendLeft { get { return this.mExtendLeft; } set { bool flag = this.mExtendLeft != value; if (flag) { this.mExtendLeft = value; this.PropertyChanged(); this.MoveDrawingToNewLocations(this.mLastRect); } } } public bool ExtendRight { get { return this.mExtendRight; } set { bool flag = this.mExtendRight != value; if (flag) { this.mExtendRight = value; this.PropertyChanged(); this.MoveDrawingToNewLocations(this.mLastRect); } } } public Color ExtensionColor { get { return this.mExtensionColor; } set { bool flag = !this.mExtensionColor.Equals(value); if (flag) { this.mExtensionColor = value; this.ColorChanged(); this.PropertyChanged(); } } } public IDrawingToolSpec OwnerSpec { get { return this._drawingToolSpec; } set { this._drawingToolSpec = value; } } public bool PlotOnAllSymbols { get { return this._plotOnAllSymbols; } set { bool flag = value != this._plotOnAllSymbols; if (flag) { this._plotOnAllSymbols = value; this.PropertyChanged(); } } } public abstract string RootName { get; } #endregion Public Properties #endregion Properties #region Indexers public Point this[int aIndex] { get { bool flag = aIndex == 0; Point result = new Point(); if (flag) { Point point = new Point(this.mDrawP1.X, this.mDrawP1.Y); result = point; } else { flag = (aIndex == 1); if (flag) { Point point = new Point(this.mDrawP2.X, this.mDrawP2.Y); result = point; } } return result; } set { // Console.WriteLine("----------------------------------------------------------------------------------------"); // Console.WriteLine("----------------------------------------------------------------------------------------"); // Console.WriteLine("鼠标坐标:( " + (int)value.X + "," + (int)value.Y + " )"); //加上左边纵坐标位移 var offset = this.Chart.GetChartPanelOffset(); //Console.WriteLine("偏移量: " + (int)offset); //获取偏后一个的时间 DateTime dateTime = this.Chart.DateScaler.OriginalDateFromX((float)value.X + (float)offset); //Console.WriteLine("偏后时间: " + dateTime.ToString()); //获取偏后时间 index var lastindex = this.Chart.DateScaler.IndexFromDate(dateTime); //Console.WriteLine("获取偏后时间 index: " + lastindex.ToString()); //获取偏前时间 var fristTime = this.Chart.DateScaler.DateValue(lastindex - 1); //Console.WriteLine("获取偏前时间 index: " + fristTime.ToString()); var fristint = this.Chart.DateScaler.XforDate(fristTime); //Console.WriteLine("获取偏前长度: " + fristint); var lastint = this.Chart.DateScaler.XforDate(dateTime); //Console.WriteLine("获取偏后长度: " + lastint); //Console.WriteLine("鼠标坐标: " + (int)value.X); //Console.WriteLine("+++++++++++++++++++++++++++++++++++++++"); //Console.WriteLine("dateTime: " + dateTime.ToString()); //P1 if ((value.X - fristint) >= ((lastint - fristint) / 2)) { dateTime = this.Chart.DateScaler.OriginalDateFromX((float)value.X + (float)offset); } else if ((value.X - fristint) < ((lastint - fristint) / 2)) { dateTime = this.Chart.DateScaler.OriginalDateFromX((float)fristint + (float)offset); } //Console.WriteLine("+++++++++++++++++++++++++++++++++++++++"); //Console.WriteLine("dateTime: " + dateTime.ToString()); float num = this.mLastScale.GetRightValueScaler().ValueFromPercent((float)(1.0 - value.Y / this.mLastRect.Height)); if (aIndex == 0) { this.P1Date = dateTime; this.P1Val = num; this.mDrawP1.X = (value.X); this.mDrawP1.Y = (value.Y); this.CalculateValues(); this.MoveDrawingToNewLocations(this.mLastRect); } else if (aIndex == 1) { this.P2Date = dateTime; this.P2Val = num; this.mDrawP2.X = (value.X); this.mDrawP2.Y = (value.Y); this.CalculateValues(); this.MoveDrawingToNewLocations(this.mLastRect); } //Console.WriteLine("------------------------------------------------------------------------"); //Console.WriteLine("P1Date:" + P1Date); //Console.WriteLine("P1Val:" + (int)P1Val); //Console.WriteLine("mDrawP1: (" + (int)mDrawP1.X + "," + (int)mDrawP1.Y + ")"); //Console.WriteLine("mDrawP2: (" + (int)mDrawP2.X + "," + (int)mDrawP2.Y + ")"); } } #endregion Indexers #region Methods #region Public Methods public double GetChartFontSize() { return (Chart == null) ? 12f : this.Chart.ChartFontSize; } public abstract string Abbreviation(); public virtual List AdditionalEditors() { List result = null; return result; } public DateTime aP1Date() { return this.P1Date; } public float aP1Val() { return this.P1Val; } public DateTime aP2Date() { return this.P2Date; } public float aP2Val() { return this.P2Val; } public virtual void CalculateValues() { } public virtual bool CanPlotOnAllSymbols() { return false; } public abstract IDrawingTool Clone(); public void Delete() { bool flag = this._drawingToolSpec != null; if (flag) { this._drawingToolSpec.DeleteTool(); } } public abstract string Description(); public void FromInfo(DrawingToolInfo info) { bool hasValue = info.P1Date.HasValue; if (hasValue) { this.P1Date = info.P1Date.Value; } hasValue = info.P1Val.HasValue; if (hasValue) { this.P1Val = info.P1Val.Value; } hasValue = info.P2Date.HasValue; if (hasValue) { this.P2Date = info.P2Date.Value; } hasValue = info.P2Val.HasValue; if (hasValue) { this.P2Val = info.P2Val.Value; } hasValue = info.Color1.HasValue; if (hasValue) { this.mColor = ColorHelper.ColorFromInt(info.Color1.Value); } hasValue = info.Color2.HasValue; if (hasValue) { this.mExtensionColor = ColorHelper.ColorFromInt(info.Color2.Value); } hasValue = info.Bool1.HasValue; if (hasValue) { this.mExtendRight = info.Bool1.Value; } hasValue = info.Bool2.HasValue; if (hasValue) { this.mExtendLeft = info.Bool2.Value; } this._plotOnAllSymbols = info.DrawOnAllSymbols; this.AddFromInfo(info); } public void FromXml(XElement node) { bool flag = node.Attribute("D1") != null; if (flag) { this.P1Date = new DateTime(long.Parse(node.Attribute("D1").Value)); } flag = (node.Attribute("D2") != null); if (flag) { this.P2Date = new DateTime(long.Parse(node.Attribute("D2").Value)); } flag = (node.Attribute("V1") != null); if (flag) { this.P1Val = XMLHelp.ParseSingle(node.Attribute("V1").Value); } flag = (node.Attribute("V2") != null); if (flag) { this.P2Val = XMLHelp.ParseSingle(node.Attribute("V2").Value); } flag = (node.Attribute("Clr") != null); if (flag) { this.mColor = ColorHelper.ColorFromString(node.Attribute("Clr").Value); } flag = (node.Attribute("ALS") != null); if (flag) { this._plotOnAllSymbols = bool.Parse(node.Attribute("ALS").Value); } flag = (node.Attribute("EClr") != null); if (flag) { this.mExtensionColor = ColorHelper.ColorFromString(node.Attribute("EClr").Value); } flag = (node.Attribute("ER") != null); if (flag) { this.mExtendRight = true; } flag = (node.Attribute("EL") != null); if (flag) { this.mExtendLeft = true; } this.AddFromXml(node); } public void GetDrawingInfo(DrawingToolInfo info) { info.P1Date = this.P1Date; info.P1Val = this.P1Val; info.P2Date = this.P2Date; info.P2Val = this.P2Val; info.Color1 = ColorHelper.ColorToInt(this.mColor); info.Color2 = ColorHelper.ColorToInt(this.mExtensionColor); info.Bool1 = this.mExtendRight; info.Bool2 = this.mExtendLeft; info.DrawOnAllSymbols = this._plotOnAllSymbols; this.AddToInfo(info); } public List GetPlots(Chart owner, ScaleLayer aScale, Rect aRect, bool DrawHandles) { this.Chart = owner; this.mLastScale = aScale; this.mLastRect = aRect; bool flag = !ColorHelper.ColorIsContrasting(this.mColor, ColorHelper.GetBrushColor(owner.ChartBackground)); if (flag) { this.mColor = ColorHelper.InverseColor(this.mColor); } var list = new List(); IDateScaler dateScaler = owner.DateScaler; flag = this.IsTooSmallToShow(owner, aScale); List result; if (flag) { result = list; } else { this.mDrawP1.X = ((double)dateScaler.XforDate(this.P1Date)); this.mDrawP1.Y = ((double)aScale.GetRightValueScaler().ScaledY(this.P1Val, aRect)); this.mDrawP2.X = ((double)dateScaler.XforDate(this.P2Date)); this.mDrawP2.Y = ((double)aScale.GetRightValueScaler().ScaledY(this.P2Val, aRect)); this.mActualP1 = new Point(this.mDrawP1.X, this.mDrawP1.Y); this.mActualP2 = new Point(this.mDrawP2.X, this.mDrawP2.Y); GeometryHelper.CheckLineExtents(ref this.mDrawP1, ref this.mDrawP2); this.CalculateValues(); list.AddRange(this.GetDrawingPlots(owner, aScale, aRect)); result = list; } return result; } public virtual List GetPropertyEditors() { var list = new List { new ControlPair { ControlLeft = new TextBlock {Text = LanguageManager.FindResource(LanguageConst.DrawingTool_Edit_Color)}, ControlRight = new ColorOpacityEditor(this, "Color", "", "") } }; List list2 = this.AdditionalEditors(); if (list2 != null) { list.AddRange(list2); } var flag = (this.CanExtendLeft() || this.CanExtendRight()); bool flag2; if (flag) { flag2 = this.AllowExtensionColorEdit(); if (flag2) { list.Add(new ControlPair() { ControlLeft = new TextBlock() { Text = LanguageManager.FindResource(LanguageConst.DrawingTool_Edit_ExtensionColor) }, ControlRight = new ColorOpacityEditor(this, "ExtensionColor", "", "") }); } var controlPair = new ControlPair(); flag2 = this.CanExtendLeft(); if (flag2) { controlPair.ControlLeft = new BooleanEditor(this, "ExtendLeft", LanguageManager.FindResource(LanguageConst.DrawingTool_Edit_ExtendLeft)) { HorizontalAlignment = HorizontalAlignment.Left }; } flag2 = this.CanExtendRight(); if (flag2) { controlPair.ControlRight = new BooleanEditor(this, "ExtendRight", LanguageManager.FindResource(LanguageConst.DrawingTool_Edit_ExtendRight)) { HorizontalAlignment = HorizontalAlignment.Left }; } list.Add(controlPair); } //flag2 = this.CanPlotOnAllSymbols(); //if (flag2) //{ // list.Add(new ControlPair() // { // ControlRight = new BooleanEditor(this, "PlotOnAllSymbols", "Draw on all Symbols") // }); //} return list; } public abstract ImageSource Icon(); public void InitDone(MouseEventArgs e) { } public void InitPoint(DateTime aDate, float aVal, ScaleLayer aScale, Rect aRect, Point p) { this.mLastRect = aRect; this.mLastScale = aScale; this.P1Date = aDate; this.P1Val = aVal; this.CalculateValues(); } public bool IsTooSmallToShow(Chart owner, ScaleLayer aScale, DrawingToolInfo Info) { bool flag = Info == null; bool result; if (flag) { result = false; } else { long ticks = owner.CurrentTimeFrame.Ticks; long? timeFrame = Info.TimeFrame; bool? arg_71_0; if (!timeFrame.HasValue) { arg_71_0 = default(bool?); } else { bool? flag2 = new bool?(timeFrame.GetValueOrDefault() >= ticks); arg_71_0 = flag2; } bool? flag3 = arg_71_0; flag = flag3.GetValueOrDefault(); if (flag) { result = false; } else { flag = (owner.LimitDrawingsBySpan && aScale.GetChartPane() != null); if (flag) { IDateScaler dateScaler = owner.DateScaler; Rect aRect = aScale.GetChartPane().LastDrawnRect(); float num = dateScaler.XforDate(this.P1Date); float num2 = dateScaler.XforDate(this.P2Date); flag = ((double)Math.Abs(num - num2) > aRect.Width * (double)(owner.DrawingMinChartSpanPercent / 100f)); if (flag) { result = false; } else { float num3 = aScale.GetRightValueScaler().ScaledY(this.P1Val, aRect); float num4 = aScale.GetRightValueScaler().ScaledY(this.P2Val, aRect); flag = ((double)Math.Abs(num3 - num4) > aRect.Height * (double)(owner.DrawingMinChartSpanPercent / 100f)); result = !flag; } } else { result = false; } } } return result; } public bool IsTooSmallToShow(Chart owner, ScaleLayer aScale) { bool flag = !(this._drawingToolSpec is SharedDrawingToolSpec); bool result; if (flag) { result = false; } else { SharedDrawingToolSpec sharedDrawingToolSpec = (SharedDrawingToolSpec)this._drawingToolSpec; result = this.IsTooSmallToShow(owner, aScale, sharedDrawingToolSpec.GetDrawingInfo()); } return result; } public abstract string MenuDescription(); public void MovePlot(Point initialPosition, Point currentPosition) { double num = currentPosition.X - initialPosition.X; double num2 = currentPosition.Y - initialPosition.Y; var value = new Point(this._p1X + num, this._p1Y + num2); var value2 = new Point(this._p2X + num, this._p2Y + num2); value.X = Math.Max(0, value.X); value.Y = Math.Max(0, value.Y); value2.X = Math.Max(0, value2.X); value2.Y = Math.Max(0, value2.Y); this[0] = value; this[1] = value2; } public void MovePlot(Point initialPosition, Point currentPosition, Point maxPoint) { double num = currentPosition.X - initialPosition.X; double num2 = currentPosition.Y - initialPosition.Y; var value = new Point(this._p1X + num, this._p1Y + num2); var value2 = new Point(this._p2X + num, this._p2Y + num2); value.X = Math.Max(0, value.X); value.X = Math.Min(maxPoint.X, value.X); value.Y = Math.Max(0, value.Y); value.Y = Math.Min(maxPoint.Y, value.Y); value2.X = Math.Max(0, value2.X); value2.X = Math.Min(maxPoint.X, value2.X); value2.Y = Math.Max(0, value2.Y); value2.Y = Math.Min(maxPoint.Y, value2.Y); this[0] = value; this[1] = value2; } public void MoveSecondPoint(DateTime aDate, float aVal, Point p) { this.P2Date = aDate; this.P2Val = aVal; this.CalculateValues(); } public void PrepareToMove() { this._p1X = this.mActualP1.X; this._p1Y = this.mActualP1.Y; this._p2X = this.mActualP2.X; this._p2Y = this.mActualP2.Y; } public void PropertyChanged() { bool flag = this._drawingToolSpec != null; if (flag) { this._drawingToolSpec.ToolChanged(this); } } public void ShowEditor(MouseEventArgs Mouseargs) { bool flag = this.Chart == null; if (!flag) { var drawingToolEditor = new DrawingToolEditor(this); drawingToolEditor.Show(Mouseargs); } } public abstract DrawingToolType ToolType(); /// /// 直线矩形范围内截取 /// /// 输出起始点 /// 输出结束点 /// 原先起始点 /// 原先结束点 /// 限定范围 public void PointOfLineAtRectangleCalculator(ref Point pointA, ref Point pointB, Point oldPointA, Point oldPointB, Rect aRect) { pointA = oldPointA; pointB = oldPointB; //TODO:更改结束点 //计算斜率 double slope = GeometryHelper.LineSlope(ref oldPointA, ref oldPointB); if (pointB.Y < aRect.Top) { pointB = new Point(GeometryHelper.XFromLine(oldPointA, slope, aRect.Top), aRect.Top); } if (pointB.Y > aRect.Bottom) { pointB = new Point(GeometryHelper.XFromLine(oldPointA, slope, aRect.Bottom), aRect.Bottom); } if (pointB.X < aRect.Left) { pointB = new Point(aRect.Left, GeometryHelper.YFromLine(oldPointA, slope, aRect.Left)); } if (pointB.X > aRect.Width) { pointB = new Point(aRect.Width, GeometryHelper.YFromLine(oldPointA, slope, aRect.Width)); } //TODO:更改开始点 if (pointA.Y < aRect.Top) { pointA = new Point(GeometryHelper.XFromLine(oldPointB, slope, aRect.Top), aRect.Top); } if (pointA.Y > aRect.Bottom) { pointA = new Point(GeometryHelper.XFromLine(oldPointB, slope, aRect.Bottom), aRect.Bottom); } if (pointA.X < aRect.Left) { pointA = new Point(aRect.Left, GeometryHelper.YFromLine(oldPointB, slope, aRect.Left)); } if (pointA.X > aRect.Width) { pointA = new Point(aRect.Width, GeometryHelper.YFromLine(oldPointB, slope, aRect.Width)); } } /// /// 直线矩形范围内拓展直线 /// /// 输出起始点 /// 输出结束点 /// 原先起始点 /// 原先结束点 /// 限定范围 /// 以第二象限为准,延长线方向,0为向下,1为向右 public void PointOfLineAtRectangleExtAllCalculator(ref Point pointA, ref Point pointB, Point oldPointA, Point DirectionPoint, Rect aRect, int Direction = 0) { var flag = default(int); pointA = oldPointA; pointB = DirectionPoint; //Reg:此处的象限是以P1为坐标原点 //flag 延长方向:0为上边 1为下边 2为左边 3为右边 if (oldPointA.X < DirectionPoint.X && oldPointA.Y < DirectionPoint.Y) //第一象限 { if (Direction == 0) { pointB.X = aRect.Width + 1; } else if (Direction == 1) { pointB.Y = -1; } } else if (oldPointA.X < DirectionPoint.X && oldPointA.Y > DirectionPoint.Y) //第二象限 { if (Direction == 0) { pointB.Y = aRect.Bottom + 1; } else if (Direction == 1) { pointB.X = aRect.Width + 1; } } else if (oldPointA.X < DirectionPoint.X && oldPointA.Y < DirectionPoint.Y) //第三象限 { if (Direction == 0) { pointB.X = -1; } else if (Direction == 1) { pointB.Y = aRect.Bottom + 1; } } else if (oldPointA.X < DirectionPoint.X && oldPointA.Y > DirectionPoint.Y) //第四象限 { if (Direction == 0) { pointB.X = -1; } else if (Direction == 1) { pointB.Y = -1; } } //TODO:更改结束点 //计算斜率 double slope = GeometryHelper.LineSlope(ref oldPointA, ref DirectionPoint); if (pointB.Y < aRect.Top) { pointB = new Point(GeometryHelper.XFromLine(oldPointA, slope, aRect.Top), aRect.Top); } if (pointB.Y > aRect.Bottom) { pointB = new Point(GeometryHelper.XFromLine(oldPointA, slope, aRect.Bottom), aRect.Bottom); } if (pointB.X < aRect.Left) { pointB = new Point(aRect.Left, GeometryHelper.YFromLine(oldPointA, slope, aRect.Left)); } if (pointB.X > aRect.Width) { pointB = new Point(aRect.Width, GeometryHelper.YFromLine(oldPointA, slope, aRect.Width)); } } public XElement ToXml(List args) { var xElement = new XElement(this.RootName); bool flag = args == null || !args.Contains("SAVEDEF"); if (flag) { xElement.Add(new XAttribute("D1", this.P1Date.Ticks.ToString())); xElement.Add(new XAttribute("D2", this.P2Date.Ticks.ToString())); xElement.Add(new XAttribute("V1", XMLHelp.NumToString(this.P1Val))); xElement.Add(new XAttribute("V2", XMLHelp.NumToString(this.P2Val))); xElement.Add(new XAttribute("ALS", this._plotOnAllSymbols.ToString())); } xElement.Add(new XAttribute("Clr", this.mColor.ToString())); xElement.Add(new XAttribute("EClr", this.mExtensionColor.ToString())); flag = this.mExtendRight; if (flag) { xElement.Add(new XAttribute("ER", "1")); } flag = this.mExtendLeft; if (flag) { xElement.Add(new XAttribute("EL", "1")); } this.AddToXml(xElement, args); return xElement; } #endregion Public Methods #region Protected Methods protected virtual void AddFromInfo(DrawingToolInfo info) { } protected virtual void AddFromXml(XElement xml) { } protected virtual void AddToInfo(DrawingToolInfo info) { } protected virtual void AddToXml(XElement xml, List args) { } protected virtual bool AllowExtensionColorEdit() { return true; } protected abstract bool CanExtendLeft(); protected abstract bool CanExtendRight(); protected abstract void ColorChanged(); protected abstract List GetDrawingPlots(Chart owner, ScaleLayer aScale, Rect aRect); protected abstract void MoveDrawingToNewLocations(Rect aRect); #endregion Protected Methods public string GetXmlForDefault() { var list = new List(); list.Add("SAVEDEF"); return this.ToXml(list).ToString(); } #endregion Methods } }