123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755 |
- using MECF.Framework.UI.Core.DxfScript;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- using System.Windows.Media;
- using System.Windows;
- using System.Globalization;
- using System.Windows.Controls;
- using Newtonsoft.Json.Linq;
- using System.Xml.Linq;
- using Microsoft.Win32.SafeHandles;
- using System.Windows.Input;
- using MECF.Framework.UI.Core.DxfScript.Converter;
- using SciChart.Core.Extensions;
- namespace MECF.Framework.UI.Core.DxfScript
- {
- /// <summary>
- /// 名称:Draw类
- /// 用途:根据自定义对象画页面元素
- /// </summary>
- public partial class GasDxfDocument
- {
- //画全部元素
- public void Draw()
- {
- if (Lines.Count == 0)
- {
- return;
- }
- draw.ClearDrawing();
- CreateGraphics();
- InitScale();
- foreach (var line in Lines)
- {
- DrawLine(line, false);
- }
- foreach (GasCircle circle in Circles)
- {
- DrawCircle(circle, false);
- }
- foreach (GasFunnel funnel in Funnels)
- {
- DrawFunnel(funnel, false);
- }
- foreach (GasText text in Texts)
- {
- DrawText(text, false);
- }
- foreach (GasPolyLine polyLine in PolyLines)
- {
- DrawPolyLine(polyLine, false);
- }
- foreach (GasAITValve valve in Valves)
- {
- DrawValve(valve, false);
- }
- foreach (GasButton button in Buttons)
- {
- DrawButton(button, false);
- }
- foreach (GasAnalogControl4Jet analog in Analogs)
- {
- DrawAnalog(analog, false);
- }
- CloseGraphics();
- draw.SaveDrawing();
- }
- //清除所有元素
- private void ClearDxf()
- {
- if (Lines != null)
- {
- Lines.Clear();
- }
- else
- {
- Lines = new List<GasLine>();
- }
- if (PolyLines != null)
- {
- PolyLines.Clear();
- }
- else
- {
- PolyLines = new List<GasPolyLine>();
- }
- if (Circles != null)
- {
- Circles.Clear();
- }
- else
- {
- Circles = new List<GasCircle>();
- }
- if (Funnels != null)
- {
- Funnels.Clear();
- }
- else
- {
- Funnels = new List<GasFunnel>();
- }
- if (Texts != null)
- {
- Texts.Clear();
- }
- else
- {
- Texts = new List<GasText>();
- }
- if (Valves != null)
- {
- Valves.Clear();
- }
- else
- {
- Valves = new List<GasAITValve>();
- }
- if (Buttons != null)
- {
- Buttons.Clear();
- }
- else
- {
- Buttons = new List<GasButton>();
- }
- if (Analogs != null)
- {
- Analogs.Clear();
- }
- else
- {
- Analogs = new List<GasAnalogControl4Jet>();
- }
- DxfWidth = 0;
- DxfHeight = 0;
- MinX = 100000;
- MinY = 100000;
- MaxX = 0;
- MaxY = 0;
- Scale = 1;
- dragX = 0;
- dragY = 0;
- }
- //开始画元素
- public void DrawShape(GasBaseShape shape, bool isSelected)
- {
- CreateGraphics();
- draw.LoadDrawing(dragX, dragY);
- if (shape is GasFunnel)
- {
- DrawFunnel(shape as GasFunnel, isSelected);
- }
- if (shape is GasLine)
- {
- DrawLine(shape as GasLine, isSelected);
- }
- else if (shape is GasCircle)
- {
- DrawCircle(shape as GasCircle, isSelected);
- }
- else if (shape is GasText)
- {
- DrawText(shape as GasText, isSelected);
- }
- else if (shape is GasPolyLine)
- {
- DrawPolyLine(shape as GasPolyLine, isSelected);
- }
- else if (shape is GasAITValve)
- {
- DrawValve(shape as GasAITValve, isSelected);
- }
- else if (shape is GasButton)
- {
- DrawButton(shape as GasButton, isSelected);
- }
- else if (shape is GasAnalogControl4Jet)
- {
- DrawAnalog(shape as GasAnalogControl4Jet, isSelected);
- }
- CloseGraphics();
- }
- //设置画笔颜色
- private Brush GetGasShapeBrush(GasBaseShape shape, bool isSelected)
- {
- if (shape == null) return NormalBrush;
- if (!IsExecuted)
- {
- return GetDevelopmentBrush(shape, isSelected);
- }
- else
- {
- return GetExecutionBrush(shape);
- }
- }
- private Pen GetPenByBrush(Brush brush)
- {
- if (brush == NormalBrush)
- {
- return NormalPen;
- }
- else if (brush == SelectedBrush)
- {
- return SelectedPen;
- }
- else if (brush == WithConditionBrush)
- {
- return WithConditionPen;
- }
- else if (brush == ReturnTrueBrush)
- {
- return ReturnTruePen;
- }
- else if (brush == WithErrorBrush)
- {
- return WithErrorPen;
- }
- else if (brush == TransparentBrush)
- {
- return TransparentPen;
- }
- else
- {
- return null;
- }
- }
- //画单线
- private void DrawLine(GasLine line, bool isSelected, Brush brush = null)
- {
- if (brush == null)
- brush = GetGasShapeBrush(line, isSelected);
- Pen pen = GetPenByBrush(brush);
- double x1 = line.X1 * rate * Scale + XSPACE + dragX;
- double x2 = line.X2 * rate * Scale + XSPACE + dragX;
- double y1 = (DxfHeight - line.Y1) * rate * Scale + YSPACE + dragY;
- double y2 = (DxfHeight - line.Y2) * rate * Scale + YSPACE + dragY;
- dc.DrawLine(pen, new Point(x1, y1), new Point(x2, y2));
- }
- //画漏斗
- private void DrawFunnel(GasFunnel funnel, bool isSelected, Brush brush = null)
- {
- if (funnel == null) return;
- foreach (var line in funnel.GasLines)
- {
- DrawLine(line, isSelected, brush);
- }
- }
- //画圆
- private void DrawCircle(GasCircle circle, bool isSelected, Brush brush = null)
- {
- if (brush == null) brush = GetGasShapeBrush(circle, isSelected); ;
- Pen pen = GetPenByBrush(brush);
- if (brush == NormalBrush)
- {
- pen = NormalPen;
- brush = TransparentBrush;
- }
- else
- {
- pen = NormalPen;
- //brush不变
- }
- double x = (circle.X) * rate * Scale + XSPACE + dragX;//圆心x
- double y = (DxfHeight - circle.Y) * rate * Scale + YSPACE + dragY;//圆心y
- double r = circle.R * rate * Scale;
- if (circle.StartAngle > 0)
- {
- DrawGeometry(circle, isSelected, brush);
- }
- else
- {
- dc.DrawEllipse(brush, pen, new Point(x, y), r, r);
- }
- }
- //画弧线
- public void DrawGeometry(GasCircle circle, bool isSelected, Brush brush = null)
- {
- if (brush == null) brush = GetGasShapeBrush(circle, isSelected); ;
- Pen pen = GetPenByBrush(brush);
- if (brush == NormalBrush)
- {
- pen = NormalPen;
- brush = TransparentBrush;
- }
- else
- {
- pen = NormalPen;
- //brush不变
- }
- double x = (circle.X) * rate * Scale + XSPACE + dragX;//圆心x
- double y = (DxfHeight - circle.Y) * rate * Scale + YSPACE + dragY;//圆心y
- double r = circle.R * rate * Scale;
- Rect arcRect = new Rect(x - r, y - r, 2 * r, 2 * r);
- // 定义圆弧的起始角度和扫过角度
- double startAngle = circle.StartAngle; // 起始角度
- double sweepAngle = circle.EndAngle - circle.StartAngle; // 扫过角度
- // 将角度转换为弧度
- double startAngleRad = startAngle * Math.PI / 180;
- double sweepAngleRad = sweepAngle * Math.PI / 180;
- // 计算起始点和结束点
- Point startPoint = new Point(
- arcRect.X + arcRect.Width / 2 + arcRect.Width / 2 * Math.Cos(startAngleRad),
- arcRect.Y + arcRect.Height / 2 - arcRect.Height / 2 * Math.Sin(startAngleRad));
- Point endPoint = new Point(
- arcRect.X + arcRect.Width / 2 + arcRect.Width / 2 * Math.Cos(startAngleRad + sweepAngleRad),
- arcRect.Y + arcRect.Height / 2 - arcRect.Height / 2 * Math.Sin(startAngleRad + sweepAngleRad));
- // 定义弧形段
- ArcSegment arcSegment = new ArcSegment
- {
- Point = endPoint,
- Size = new Size(arcRect.Width / 2, arcRect.Height / 2),
- RotationAngle = 0,
- IsLargeArc = (sweepAngle - startAngle) > 180,
- SweepDirection = SweepDirection.Counterclockwise
- };
- // 定义路径段
- PathFigure pathFigure = new PathFigure
- {
- StartPoint = startPoint,
- Segments = new PathSegmentCollection { arcSegment }
- };
- // 定义路径几何
- PathGeometry pathGeometry = new PathGeometry();
- pathGeometry.Figures.Add(pathFigure);
- // 使用 DrawingContext 绘制路径
- dc.DrawGeometry(brush, pen, pathGeometry);
- }
- //画文本
- private void DrawText(GasText text, bool isSelected, Brush brush = null)
- {
- if (brush == null) brush = GetGasShapeBrush(text, isSelected); ;
- Pen pen = GetPenByBrush(brush);
- if (string.IsNullOrEmpty(text.Text)) return;
-
- string[] textLines = Regex.Split(text.Text, "\\\\P");
- for (int i = 0; i < textLines.Length; i++)
- {
- double x = text.X;
- double y = text.Y;
- double rectWidth = text.RectWidth;
- double rectHeight = text.RectHeight;
- double textWidth = GetFontWidth(textLines[i], text.FontSize);
- double textHeight = text.FontSize;
- double fontSize = text.FontSize;
- int alignment = text.Alignment;
- double lineSpace = text.LineSpace;
- switch (alignment)
- {
- case 1:
- x += (rectWidth - textWidth) / 2;
- y = y - (rectHeight - textHeight) / 2;
- y -= (textHeight + lineSpace) * i;
- break;
- case 4:
- x += (rectWidth - textWidth) / 2;
- y += textHeight / 2;
- y -= (textHeight + lineSpace) * i;
- break;
- case 7:
- x += (rectWidth - textWidth) / 2;
- y += (rectHeight + textHeight) / 2;
- y -= (textHeight + lineSpace) * i;
- break;
- case 2:
- x -= textWidth / 2;
- y = y - (rectHeight - textHeight) / 2;
- y -= (textHeight + lineSpace) * i;
- break;
- case 5:
- x -= textWidth / 2;
- y += textHeight / 2;
- y -= (textHeight + lineSpace) * i;
- break;
- case 8:
- x -= textWidth / 2;
- y += (rectHeight + textHeight) / 2;
- y -= (textHeight + lineSpace) * i;
- break;
- case 3:
- x -= (rectWidth + textWidth) / 2;
- y = y - (rectHeight - textHeight) / 2;
- y -= (textHeight + lineSpace) * i;
- break;
- case 6:
- x -= (rectWidth + textWidth) / 2;
- y += textHeight / 2;
- y -= (textHeight + lineSpace) * i;
- break;
- case 9:
- x -= (rectWidth + textWidth) / 2;
- y += (rectHeight + textHeight) / 2;
- y -= (textHeight + lineSpace) * i;
- break;
- }
- x = x * rate * Scale + XSPACE + dragX;
- y = (DxfHeight - y) * rate * Scale + YSPACE + dragY;
- dc.DrawText(GetFormattedText(textLines[i], text.FontSize * rate * Scale, brush), new Point(x, y));
- }
- }
- //画多线
- private void DrawPolyLine(GasPolyLine polyLine, bool isSelected, Brush brush = null)
- {
- if (brush == null) brush = GetGasShapeBrush(polyLine, isSelected); ;
- Pen pen = GetPenByBrush(brush);
- foreach (GasLine line in polyLine.InnerLines)
- {
- DrawLine(line, isSelected, brush);
- }
- }
- //画按钮
- private void DrawButton(GasButton button, bool isSelected, Brush brush = null)
- {
- if (brush == null) brush = GetGasShapeBrush(button, isSelected); ;
- Pen pen = GetPenByBrush(brush);
- if (brush == NormalBrush)
- {
- pen = NormalPen;
- brush = TransparentBrush;
- }
- else
- {
- pen = NormalPen;
- }
- double x, y, width, height;
- x = Math.Min(button.InnerPolyLine.InnerLines[0].X1, button.InnerPolyLine.InnerLines[0].X2);
- y = Math.Max(button.InnerPolyLine.InnerLines[0].Y1, button.InnerPolyLine.InnerLines[0].Y2);
- width = Math.Abs(button.InnerPolyLine.InnerLines[0].X1 - button.InnerPolyLine.InnerLines[0].X2);
- height = Math.Abs(button.InnerPolyLine.InnerLines[1].Y1 - button.InnerPolyLine.InnerLines[1].Y2);
- x = x * rate * Scale + XSPACE + dragX;
- y = (DxfHeight - y) * rate * Scale + YSPACE + dragY;
- width = width * rate * Scale;
- height = height * rate * Scale;
- dc.DrawRectangle(brush, pen, new Rect(x, y, width, height));
- DrawText(button.InnerText, isSelected, NormalBrush);
- }
- //画阀
- private void DrawValve(GasAITValve valve, bool isSelected, Brush brush = null)
- {
- if (brush == null) brush = GetGasShapeBrush(valve, isSelected); ;
- Pen pen = GetPenByBrush(brush);
- DrawCircle(valve.InnerCircle, isSelected, brush);
- DrawText(valve.InnerText, isSelected, NormalBrush);
- if (valve.InnerPolyLine != null && valve.InnerPolyLine.InnerLines != null)
- {
- DrawPolyLine(valve.InnerPolyLine, isSelected, NormalBrush);
- }
- }
- //画按钮
- private void DrawAnalog(GasAnalogControl4Jet analog, bool isSelected, Brush brush = null)
- {
- if (brush == null) brush = GetGasShapeBrush(analog, isSelected); ;
- Pen pen = GetPenByBrush(brush);
- DrawButton(analog.TopButton, isSelected, brush);
- DrawButton(analog.LeftButton, isSelected, brush);
- DrawButton(analog.RightButton, isSelected, brush);
- }
- //创建自定义画布对象
- private void CreateGraphics()
- {
- if (dc == null) dc = draw.CreateGraphics();
- }
- //清除画布对象
- private void CloseGraphics()
- {
- if (dc != null)
- {
- draw.Dispose();
- }
- dc = null;
- }
- private double GetFontWidth(string text, double fontSize)
- {
- if (computeSizeTextBlock == null)
- {
- computeSizeTextBlock = new TextBlock();
- PixelsPerDip = DpiHelper.GetPixelsPerDip(Application.Current.MainWindow);
- }
- computeSizeTextBlock.Text = text;
- computeSizeTextBlock.FontSize = fontSize == 0 ? 15 : fontSize;
- computeSizeTextBlock.FontFamily = new FontFamily("宋体");
- FormattedText formattedText = new FormattedText(
- computeSizeTextBlock.Text,
- CultureInfo.GetCultureInfo("zh-CN"),
- FlowDirection.LeftToRight,
- new Typeface(computeSizeTextBlock.FontFamily, computeSizeTextBlock.FontStyle, computeSizeTextBlock.FontWeight, computeSizeTextBlock.FontStretch),
- computeSizeTextBlock.FontSize,
- Brushes.Black);
- return formattedText.Width;
- }
- private FormattedText GetFormattedText(string text, double fontSize, Brush brush)
- {
- if (computeSizeTextBlock == null)
- {
- computeSizeTextBlock = new TextBlock();
- }
- computeSizeTextBlock.Text = text;
- computeSizeTextBlock.FontSize = fontSize == 0 ? 15 : fontSize;
- computeSizeTextBlock.FontFamily = new FontFamily("宋体");
- FormattedText formattedText = new FormattedText(
- computeSizeTextBlock.Text,
- CultureInfo.GetCultureInfo("zh-CN"),
- FlowDirection.LeftToRight,
- new Typeface(computeSizeTextBlock.FontFamily, computeSizeTextBlock.FontStyle, computeSizeTextBlock.FontWeight, computeSizeTextBlock.FontStretch),
- computeSizeTextBlock.FontSize,
- brush);
- return formattedText;
- }
- #region 根据不同环境对画刷处理
- //主方法 GetGasShapeBrush:根据 IsExecuted 的状态分为开发态和执行态处理。
- //开发态处理 GetDevelopmentBrush:处理开发态下的逻辑,包括条件检查和选择画刷。
- //如果形状未启用,直接返回 DisabledBrush。
- //依次检查 BoolCondition 和 StringCondition,如果有错误,直接返回 WithErrorBrush。
- //处理特定类型的形状逻辑。
- //条件检查 CheckAndHandleCondition:统一处理 BoolCondition 和 StringCondition 的检查逻辑,减少代码重复。
- //执行态处理 GetExecutionBrush:处理执行态下的逻辑,包括条件执行和选择画刷。
- //如果形状未启用,直接返回 DisabledBrush。
- //依次执行 BoolCondition 和 StringCondition,如果有错误,直接返回 WithErrorBrush。
- //条件执行 ExecuteAndHandleCondition:统一处理 BoolCondition 和 StringCondition 的执行逻辑,减少代码重复。
- //处理开发环境下的特定形状 HandleSpecialShapesDevelopment:处理开发环境下特定形状的逻辑。
- //处理执行环境下的特定形状 HandleSpecialShapesExecution:处理执行环境下特定形状的逻辑。
- private Brush GetDevelopmentBrush(GasBaseShape shape, bool isSelected)
- {
- if (isSelected) return SelectedBrush;
- if (!shape.Enable) return DisabledBrush;
- Brush brush = NormalBrush;
- brush = CheckAndHandleCondition(shape.BoolCondition, brush, shape.Id, BoolConditions);
- if (brush == WithErrorBrush) return brush;
- brush = CheckAndHandleCondition(shape.StringCondition, brush, shape.Id, StringConditions);
- if (brush == WithErrorBrush) return brush;
- brush = CheckAndHandleCondition(shape.ClickCondition, brush, shape.Id, ClickConditions);
- if (brush == WithErrorBrush) return brush;
- brush = HandleSpecialShapesDevelopment(shape, brush);
- return brush;
- }
- private Brush HandleSpecialShapesDevelopment(GasBaseShape shape, Brush currentBrush)
- {
- if (shape is GasAITValve)
- {
- // 处理 GasAITValve 的开发环境逻辑
- return currentBrush;
- }
- else if (shape is GasAnalogControl4Jet)
- {
- // 处理 GasAnalogControl4Jet 的开发环境逻辑
- return currentBrush;
- }
- return currentBrush;
- }
- private Brush CheckAndHandleCondition(Script condition, Brush currentBrush, int shapeId, Dictionary<int, string> conditionsDict)
- {
- if (condition == null || condition.Result == ScriptResult.EMPTY)
- {
- return currentBrush;
- }
- else if (condition.Result == ScriptResult.SUCCESS)
- {
- return WithConditionBrush;
- }
- else if (condition.Result == ScriptResult.ERROR)
- {
- if (conditionsDict.ContainsKey(shapeId))
- {
- if (!conditionsDict[shapeId].EndsWith("TODO"))
- {
- conditionsDict[shapeId] += "\n//" + condition.Error + ":TODO";
- }
- }
- return WithErrorBrush;
- }
- return currentBrush;
- }
- private Brush GetExecutionBrush(GasBaseShape shape)
- {
- bool isExec = shape.ClickCondition == null && shape.BoolCondition == null && shape.StringCondition == null;
- if (!shape.Enable&& isExec)
- {
- return DisabledBrush;
- }
-
- Brush brush = NormalBrush;
- brush = ExecuteAndHandleCondition(shape.ClickCondition, brush, shape);
- brush = ExecuteAndHandleCondition(shape.BoolCondition, brush, shape);
- if (brush == WithErrorBrush) return brush;
- brush = ExecuteAndHandleCondition(shape.StringCondition, brush, shape);
- if (brush == WithErrorBrush) return brush;
-
- return brush;
- }
- private Brush ExecuteAndHandleCondition(Script condition, Brush currentBrush, GasBaseShape shape)
- {
- if (condition == null) return currentBrush;
- if (condition.Result == ScriptResult.EMPTY)
- {
- return currentBrush;
- }
- //由于一直在Draw(),会不断的执行脚本 导致十分卡顿
- //而且由于采用切换key的方法读取值,所以这部分不需要一直执行脚本
- //if (isExecute)
- //{
- // condition.Execute();
- //}
- if (condition.Result == ScriptResult.SUCCESS)
- {
- return HandleSpecialShapes(condition, currentBrush, shape);
- }
- else if (condition.Result == ScriptResult.ERROR)
- {
- // return WithErrorBrush;
- return NormalBrush;
- }
- return currentBrush;
- }
- private Brush HandleSpecialShapes(Script condition, Brush currentBrush, GasBaseShape shape)
- {
- // 提取重复的逻辑到一个方法
- Brush defaultBrush = GetDefaultBrush(shape, currentBrush);
- switch (shape)
- {
- case GasAITValve aiTValve:
- var result = condition.ReadValue<bool>(aiTValve.Key);
- return result ? ReturnTrueBrush : defaultBrush;
- case GasAnalogControl4Jet mfc:
- var value = condition.ReadValue<double>(mfc.ValueKey);
- mfc.LeftButton.InnerText.Text = value.ToString("f2");
- mfc.RightButton.InnerText.Text = condition.ReadValue<string>(mfc.UnitKey);
- return value>0?GasMapProvider.ChangeMFCColor:defaultBrush;
- case GasButton btn:
-
- return condition.ReadValue<bool>(btn.DataKey) ? ReturnTrueBrush : defaultBrush;
- case GasCircle cycle:
- return !string.IsNullOrEmpty(cycle.Key) && condition.ReadValue<bool>(cycle.Key) ? ReturnTrueBrush : defaultBrush;
- default:
- return defaultBrush;
- }
- }
- private Brush GetDefaultBrush(GasBaseShape shape, Brush currentBrush)
- {
- // 如果 shape 自身有 Brush,则使用它;否则,使用传入的 currentBrush
- return shape.Brush ?? currentBrush;
- }
- #endregion
- }
- }
|