using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using ScottPlot; using ScottPlot.Plottable; using Uestc.Auto6.Dso.Core; using System.Threading; using Uestc.Auto6.Dso.ComModel; using System.Diagnostics; using ScottPlot.Renderable; using Uni_Trend.MSO7000X.Common.Structs; using EventBus; namespace Uestc.Auto6.Dso.U2 { public partial class MathFigure : BaseDisplayForm, ITimebaseView, ITriggerView, IChnlView { public MathFigure(DisplayPrsnt displayPrsnt) { InitializeComponent(); ConfigureWavePlot(); _TimerRefresh.Interval = 20; _TimerRefresh.Tick += TimerRefresh_Tick; _TimerRefresh.Enabled = true; _DrawMode = displayPrsnt.DrawMode; _WfmIntensity = displayPrsnt.WfmIntensity; _GridStyle = displayPrsnt.GridStyle; _GridIntensity = displayPrsnt.GridIntensity; _AxisTickVisible = displayPrsnt.AxisTickVisible; _XAxisTickBottom = displayPrsnt.XAxisTickBottom; _YAxisTickRight = displayPrsnt.YAxisTickRight; } private System.Windows.Forms.Timer _TimerRefresh = new System.Windows.Forms.Timer(); private Boolean _IsRefreshing = false; private static readonly Object _ObjectLock = new(); private Boolean _IsDraging = false; private WavePlot _WavePlot; public ChannelId Id; private VLIndicationArea vLIndicationArea; //private VRIndicationArea vRIndicationArea; //private HTIndicationArea hTIndicationArea; /// /// 视图设置窗口 /// private TimeDomainViewSettingForm _TimeDomainViewSettingForm = null; #region WavePlot /// /// 更新波形 /// private void DrawWave() { _IsRefreshing = true; AddWavePlot(); if (Program.Oscilloscope.TryGetChannel(Id, out IChnlPrsnt channel)) { //更新数据 //if (channel.Pack != null) // _WavePlot.YTs = channel.Pack.Buffer; //if ((channel as MathPrsnt).CalcType == MathType.FFT) //{ // ScottPlotFormControl.Plot.XAxis.MinorLogScale(true); // ScottPlotFormControl.Plot.YAxis.MinorLogScale(true); //} //else { ScottPlotFormControl.Plot.XAxis.MinorLogScale(false); ScottPlotFormControl.Plot.YAxis.MinorLogScale(false); } if (channel.VuDatabase.Current != null) { _WavePlot.YTs = (double[,])channel.VuDatabase.Current.Buffer; _WavePlot.SampleRate = channel.VuDatabase.Current.ZoomRatio; _WavePlot.OffsetX = channel.VuDatabase.Current.Start; } _WavePlot.Color = Color.FromArgb((Int32)(_WfmIntensity / 100d * 255), channel.DrawColor); ScottPlotFormControl.Plot.ResetChannelParameter(channel.PosIndexBymDiv, (channel as MathPrsnt).Scale, channel.Prefix.ToString(), channel.Unit, Color.FromArgb((Int32)(_GridIntensity / 100d * 255), Color.White/*channel.DrawColor*/)); //更新通道刻度信息 if (Id == DsoPrsnt.FocusId) { if (vLIndicationArea != null) { vLIndicationArea.IsFocused = true; } } else { if (vLIndicationArea != null) { vLIndicationArea.IsFocused = false; } } if (vLIndicationArea != null && _IsDraging == false) { vLIndicationArea.IsVisible = true; vLIndicationArea.Color = channel.DrawColor; vLIndicationArea.SetPosition(ScottPlotFormControl.Plot.YAxis.Dims.GetPixel(-(int)(channel as MathPrsnt).PosIndexBymDiv)); } if (vLIndicationArea != null) { vLIndicationArea.Label = channel.Label; vLIndicationArea.Name = Id.ToString(); } } ScottPlotFormControl.Plot.ResetTimebaseParameter(Presenter.Sampling.PosIndexBymDiv - 5000, Presenter.Sampling.Scale, Presenter.Sampling.Prefix.ToString(), Presenter.Sampling.Unit, Color.FromArgb((Int32)(_GridIntensity / 100d * 255), Color.White)); ScottPlotFormControl.Render(skipIfCurrentlyRendering: true); _IsRefreshing = false; } /// /// 添加波形 /// private void AddWavePlot() { if (_WavePlot == null) if (Program.Oscilloscope.TryGetChannel(Id, out IChnlPrsnt channel)) if (channel.Pack != null) _WavePlot = ScottPlotFormControl.Plot.AddWave(channel.Pack.Buffer, sampleRate: 1, isAfterglowOn: false, channel.DrawColor/*, label: channel.Id.ToString()*/); } /// /// 添加可拖拽指示区域 /// private void AddDragArea() { PlotDimensions plotDimensions = ScottPlotFormControl.Plot.GetSettings().GetPlotDimensions(0, 0, 1); vLIndicationArea = ScottPlotFormControl.Plot.AddVLIndicationArea(plotDimensions, color: Color.Red); //vLIndicationArea.LabelFont = new Font("微软雅黑", 8); vLIndicationArea.Dragged += (sender, e) => { if (Program.Oscilloscope.TryGetChannel(Id, out IChnlPrsnt channel)) { (channel as MathPrsnt).PosIndexBymDiv = ScottPlotFormControl.Plot.YAxis.Dims.GetUnit((float)vLIndicationArea.GetIndicationValue()); } }; vLIndicationArea.MouseDown += (sender, e) => { DsoPrsnt.FocusId = Id; }; ////更新拖动图片 //vLIndicationArea.IndicationImage = new Bitmap(19,19); //vRIndicationArea.IndicationImage = new Bitmap(19,19); //hTIndicationArea.IndicationImage = new Bitmap(19,19); } /// /// 配置显示信息 /// private void ConfigureWavePlot() { //控件属性配置 ScottPlotFormControl.Configuration.MiddleClickAutoAxisMarginX = 0; ScottPlotFormControl.Configuration.Quality = 0; //波形线路名称 ScottPlot.Renderable.Legend legend = ScottPlotFormControl.Plot.Legend(); legend.FontColor = Color.Gray; legend.OutlineColor = Color.White; legend.FillColor = Color.Black; ScottPlotFormControl.Plot.AxisAutoX(margin: 0); ScottPlotFormControl.Plot.SetAxisLimits(xMin: 0, xMax: 10000, yMin: -5000, yMax: 5000);//初始视阈 ScottPlotFormControl.Plot.SetViewLimits(xMin: -32768, xMax: 32768, yMin: -10000, yMax: 10000);//视阈限制 ScottPlotFormControl.Dock = DockStyle.Fill; //图形颜色设置 ScottPlotFormControl.Plot.Style(figureBackground: Color.Transparent, dataBackground: Color.Transparent, grid: Color.Gray, tick: Color.Gray, axisLabel: Color.White, titleLabel: Color.Gray); //网格属性配置 ScottPlotFormControl.Plot.Grid(enable: true, color: Color.Gray, lineStyle: LineStyle.Dot); ScottPlotFormControl.BackColor = Color.Black; AddWavePlot(); AddDragArea(); ScottPlotFormControl.Plot.RenderEventHandler += ScottPlotFormControlPlot_RenderEventHandler; } private void ScottPlotFormControlPlot_RenderEventHandler(object sender, (Bitmap bmp, PlotDimensions plotDimensions, bool lowQuality) e) { CursorApp.Default?.DrawCursor(sender, e); } #endregion #region 窗口显示属性及配置 private WfmDrawMode _DrawMode; /// /// 波形显示风格 /// public WfmDrawMode DrawMode { get => _DrawMode; set => _DrawMode = value; } private Int32 _WfmIntensity; /// /// 波形亮度 /// public Int32 WfmIntensity { get => _WfmIntensity; set => _WfmIntensity = value; } private GridType _GridStyle; /// /// 网格风格 /// public GridType GridStyle { get => _GridStyle; set => _GridStyle = value; } private Int32 _GridIntensity; /// /// 网格亮度 /// public Int32 GridIntensity { get => _GridIntensity; set => _GridIntensity = value; } private Boolean _AxisTickVisible; /// /// 标记是否可见 /// public Boolean AxisTickVisible { get => _AxisTickVisible; set => _AxisTickVisible = value; } private Boolean _XAxisTickBottom; /// /// 水平标记是否显示在下方 /// public Boolean XAxisTickBottom { get => _XAxisTickBottom; set => _XAxisTickBottom = value; } private Boolean _YAxisTickRight; /// /// 垂直标记是否显示在右方 /// public Boolean YAxisTickRight { get => _YAxisTickRight; set => _YAxisTickRight = value; } /// /// 配置波形显示风格 /// /// private void ConfigDrawMode(WfmDrawMode wfmDrawMode) { switch (wfmDrawMode) { case WfmDrawMode.Vector: ScottPlotFormControl.Plot.WavePlotStyle(WavePlotLineStyle.Vector); break; case WfmDrawMode.Dot: ScottPlotFormControl.Plot.WavePlotStyle(WavePlotLineStyle.Dot); break; default: break; } } /// /// 配置波形亮度 /// /// private void ConfigWfmIntensity(Int32 wfmIntensity) { ScottPlotFormControl.Plot.WavePlotStyle(wfmIntensity); } /// /// 配置水平标记的显示位置 /// /// private void ConfigHorizontalTickLabelDirection(Boolean horizontalBottom = true) { ScottPlotFormControl.Plot.XAxis.Edge = horizontalBottom == true ? ScottPlot.Renderable.Edge.Bottom : ScottPlot.Renderable.Edge.Top; } /// /// 配置垂直标记的显示位置 /// /// private void ConfigVirticalTickLabelDirection(Boolean virticalRight = true) { ScottPlotFormControl.Plot.YAxis.Edge = virticalRight == true ? ScottPlot.Renderable.Edge.Right : ScottPlot.Renderable.Edge.Left; } /// /// 配置标记label的显示 /// /// private void ConfigTickLabelVisible(Boolean visible = true) { ScottPlotFormControl.Plot.XAxis.IsVisible = visible; ScottPlotFormControl.Plot.YAxis.IsVisible = visible; } /// /// 配置网格样式 /// /// private void ConfigGridStyle(GridType gridType) { switch (gridType) { case GridType.Full: ScottPlotFormControl.Plot.Grid(enable: true, lineStyle: LineStyle.Dot); ScottPlotFormControl.Plot.MinorTickVisible(true); break; case GridType.Brief: ScottPlotFormControl.Plot.Grid(enable: true, lineStyle: LineStyle.Dot); ScottPlotFormControl.Plot.MinorTickVisible(false); break; case GridType.None: ScottPlotFormControl.Plot.Grid(enable: false); ScottPlotFormControl.Plot.MinorTickVisible(false); break; default: break; } } /// /// 配置网格亮度 /// /// private void ConfigGridIntensity(Int32 GridIntensity) { ScottPlotFormControl.Plot.Grid(color: Color.FromArgb((Int32)(GridIntensity / 100d * 255), Color.Gray)); } private void OnLostFocusClick_FloatForm(object obj, EventArgs e) { var form = obj as Uni_Trend.MSO7000X.UserControls.FloatForm; if (form != null) { form.Close(); } } private void ToolStripMenuItemTimeWave_Click(object sender, EventArgs e) { //if ((Program.Oscilloscope.View as DsoForm)?.OperateForm != null) //{ // (Program.Oscilloscope.View as DsoForm)?.OperateForm.Close(); //} if (_TimeDomainViewSettingForm != null) { _TimeDomainViewSettingForm.Close(); } _TimeDomainViewSettingForm = new TimeDomainViewSettingForm(); _TimeDomainViewSettingForm.SetGridComboBoxSelectType(Enum.GetValues()); XAxisTickType xaxisticktype = ScottPlotFormControl.Plot.XAxis.Edge == Edge.Bottom ? XAxisTickType.Bottom : XAxisTickType.Top; YAxisTickType yaxisticktype = ScottPlotFormControl.Plot.YAxis.Edge == Edge.Left ? YAxisTickType.Left : YAxisTickType.Right; _TimeDomainViewSettingForm.SetMutexButtonModeType(xaxisticktype, yaxisticktype, DrawMode); _TimeDomainViewSettingForm.SetParameterValue(TimeEventParameterType.TickIntensity, GridIntensity); _TimeDomainViewSettingForm.SetParameterValue(TimeEventParameterType.WFMIntensity, WfmIntensity); _TimeDomainViewSettingForm.SetParameterValue(TimeEventParameterType.AxisTick, ScottPlotFormControl.Plot.XAxis.IsVisible); _TimeDomainViewSettingForm.ParameterChangedEventHandler += TimeDomainViewSettingForm_ParameterChangedEventHandler; if (Program.Oscilloscope.View != null && Program.Oscilloscope.View is DsoForm dsoForm) { Int32 locationx = (dsoForm.Width - _TimeDomainViewSettingForm.Width) / 2; locationx = locationx > 0 ? locationx : 0; Int32 locationy = (dsoForm.Height - _TimeDomainViewSettingForm.Height) / 2; locationy = locationy > 0 ? locationy : 0; _TimeDomainViewSettingForm.Location = new Point(locationx, locationy); } _TimeDomainViewSettingForm.FormClosed += (sender, e) => { _TimeDomainViewSettingForm.ParameterChangedEventHandler -= TimeDomainViewSettingForm_ParameterChangedEventHandler; _TimeDomainViewSettingForm = null; }; FormEventArgs formeventargs = new FormEventArgs() { Current = _TimeDomainViewSettingForm, Type = FormType.SettingForm }; EventBroker.Instance.GetEvent().Publish(this, formeventargs); } private void TimeDomainViewSettingForm_ParameterChangedEventHandler(TimeEventParameterType type, object obj) { switch (type) { case TimeEventParameterType.AxisTick: { if (obj is Boolean visible) { AxisTickVisible = visible; ConfigTickLabelVisible(visible); } } break; case TimeEventParameterType.XAxisTick: { if (obj is XAxisTickType timeBaseMarkerType) { XAxisTickBottom = timeBaseMarkerType == XAxisTickType.Bottom; ConfigHorizontalTickLabelDirection(timeBaseMarkerType == XAxisTickType.Bottom); } } break; case TimeEventParameterType.YAxisTick: { if (obj is YAxisTickType verticalGearMarkerType) { YAxisTickRight = verticalGearMarkerType == YAxisTickType.Right; ConfigVirticalTickLabelDirection(verticalGearMarkerType == YAxisTickType.Right); } } break; case TimeEventParameterType.WFMType: if (obj is WfmDrawMode mode) { DrawMode = mode; ConfigDrawMode(DrawMode); } break; case TimeEventParameterType.WFMIntensity: if (obj is Int32 int32) { WfmIntensity = int32; ConfigWfmIntensity(WfmIntensity); } break; case TimeEventParameterType.TickType: if (obj is GridType value) { GridStyle = value; ConfigGridStyle(GridStyle); } break; case TimeEventParameterType.TickIntensity: if (obj is Int32 intensity) { GridIntensity = intensity; ConfigGridIntensity(GridIntensity); } break; default: break; } } #endregion #region 事件 private void MathViewForm_Load(object sender, EventArgs e) { ConfigGridIntensity(GridIntensity); ConfigGridStyle(GridStyle); ConfigWfmIntensity(WfmIntensity); ConfigDrawMode(DrawMode); ConfigTickLabelVisible(AxisTickVisible); ConfigVirticalTickLabelDirection(XAxisTickBottom); ConfigHorizontalTickLabelDirection(YAxisTickRight); } private void TimerRefresh_Tick(object sender, EventArgs e) { if (_IsRefreshing == false) DrawWave(); } protected override void OnFormClosed(FormClosedEventArgs e) { TmbPresenter.TryRemoveView(this); TrgPresenter.TryRemoveView(this); Presenter.TryRemoveView(this); Presenter.Active = false; (Program.Oscilloscope.View as DsoForm).RemoveBadge(Presenter); //(Program.Oscilloscope.View as DsoForm).DestroyDisplayForm(this); } ~MathFigure() { if (_TimerRefresh != null) _TimerRefresh.Dispose(); } #endregion #region IDsoView private MathPrsnt _Presenter; public MathPrsnt Presenter { get => _Presenter; set { _Presenter = value; } } //IChnlPrsnt IView.Presenter //{ // get => Presenter; // set => Presenter = (MathPrsnt)value; //} IBadge IView.Presenter { get => Presenter; set => Presenter = (MathPrsnt)value; } public TimebasePrsnt TmbPresenter { get; set; } ITimebasePrsnt IView.Presenter { get => TmbPresenter; set => TmbPresenter = (TimebasePrsnt)value; } public TriggerPrsnt TrgPresenter { get; set; } ITriggerPrsnt IView.Presenter { get => TrgPresenter; set => TrgPresenter = (TriggerPrsnt)value; } public void UpdateView(String propertyName) { if (String.IsNullOrEmpty(propertyName)) { UpdateView(); return; } switch (propertyName) { //case nameof(TrgPresenter.): // break; //case nameof(TmbPresenter.Length): // break; case nameof(TmbPresenter.ScaleByus): ScottPlotFormControl.Plot.ResetTimebaseParameter((Int32)TmbPresenter.PositionByus, TmbPresenter.ScaleByus, TmbPresenter.Prefix.ToString(), TmbPresenter.Unit, Color.White); break; case nameof(TmbPresenter.PositionByus): ScottPlotFormControl.Plot.ResetTimebaseParameter((Int32)TmbPresenter.PositionByus, TmbPresenter.ScaleByus, TmbPresenter.Prefix.ToString(), TmbPresenter.Unit, Color.White); break; } } protected void UpdateView() { } #endregion } }