From e47f92df1569e16a19deed592f773591da02d890 Mon Sep 17 00:00:00 2001 From: lixiaojun <1287241240@qq.com> Date: 星期三, 11 十二月 2024 10:28:55 +0800 Subject: [PATCH] 水泵分析优化 --- WinFrmUI/Yw.WinFrmUI.Hydro.L2d.Core/02-panel/NetworkPanel.cs | 711 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 647 insertions(+), 64 deletions(-) diff --git a/WinFrmUI/Yw.WinFrmUI.Hydro.L2d.Core/02-panel/NetworkPanel.cs b/WinFrmUI/Yw.WinFrmUI.Hydro.L2d.Core/02-panel/NetworkPanel.cs index 52074f2..e0174ba 100644 --- a/WinFrmUI/Yw.WinFrmUI.Hydro.L2d.Core/02-panel/NetworkPanel.cs +++ b/WinFrmUI/Yw.WinFrmUI.Hydro.L2d.Core/02-panel/NetworkPanel.cs @@ -19,25 +19,18 @@ //璁剧疆鍏佽鐨勬渶灏忓昂瀵� this.MinimumSize = new Size(10, 10); - } + #region 鍒濆鍖� - private Network _network = null;//绠$綉 - private Bitmap _cache = null;//缁樺埗缂撳瓨 - private float _zoomMin = 1;//鏈�灏忕缉鏀惧眰绾� - private float _zoomMax = 3200;//鏈�澶х缉鏀惧眰绾� - private float _zoom = 1;//褰撳墠缂╂斁灞傜骇 - private float _dxo = 0;//x鍋忕Щ閲� - private float _dyo = 0;//y鍋忕Щ閲� + protected Network _network = null;//绠$綉 + protected RectangleF _networkBounds;//绠$綉杈圭晫 + protected RectangleF _clientRectf;//宸ヤ綔鍖哄煙鐭╁舰 /// <summary> /// 鏄惁鍒濆鍖� /// </summary> public bool Initialized => _network != null; - - - /// <summary> /// 鍒濆鍖� @@ -45,42 +38,585 @@ public virtual void Initial(Network network) { _network = network; + _networkBounds = _network.GetBounds(); + _clientRectf = GetClientRectangleF(); + CreateCache(); ZoomAll(); } - protected override void OnPaint(PaintEventArgs e) + #endregion + + #region 缂撳瓨涓庢樉绀� + + private Bitmap _cache = null;//缂撳瓨<渚濇嵁宸ヤ綔鍖哄煙鍒涘缓鐨勭┖鍥剧墖> + private object _cacheLocker = new();//缂撳瓨閿� + + /// <summary> + /// 鍒涘缓缂撳瓨 + /// </summary> + protected virtual void CreateCache() { - base.OnPaint(e); if (!Initialized) { return; } - try + var img = new Bitmap((int)_clientRectf.Width, (int)_clientRectf.Height); + lock (_cacheLocker) { - e.Graphics.PageUnit = GraphicsUnit.Pixel; - e.Graphics.InterpolationMode = InterpolationMode.High; - e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; - e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; - e.Graphics.PageScale = _zoom; - e.Graphics.TranslateTransform(_dxo, _dyo); - e.Graphics.ScaleTransform(1, -1); + if (_cache != null) + { + _cache.Dispose(); + } + _cache = img; } - catch - { - return; - } - _network.Draw(e.Graphics); } /// <summary> - /// 鐣岄潰灏哄鍙戠敓鏀瑰彉 + /// 缁樺埗缂撳瓨 /// </summary> - /// <param name="eventargs"></param> - protected override void OnResize(EventArgs eventargs) + protected virtual void DrawCache() { - base.OnResize(eventargs); - ZoomAll(); + if (!Initialized) + { + return; + } + if (_cache == null) + { + return; + } + var dispRect = GetDispRectangleF(); + using (var g = Graphics.FromImage(_cache)) + { + g.Clear(Color.White); + g.PageUnit = GraphicsUnit.Pixel; + g.InterpolationMode = InterpolationMode.High; + g.SmoothingMode = SmoothingMode.AntiAlias; + g.PixelOffsetMode = PixelOffsetMode.HighQuality; + g.PageScale = _zoom; + g.TranslateTransform(_dxo, _dyo); + g.ScaleTransform(1, -1); + + _network.Draw(g, dispRect); + } } + + /// <summary> + /// 搴旂敤缂撳瓨 + /// </summary> + protected virtual void ApplyCache(Graphics g) + { + if (!Initialized) + { + return; + } + lock (_cacheLocker) + { + if (_cache != null) + { + g.DrawImage(_cache, _clientRectf); + } + } + + } + + #endregion + + #region 缂╂斁涓庡亸绉� + + private float _zoomMin = 0.001f;//鏈�灏忕缉鏀惧眰绾� + private float _zoomMax = 30000f;//鏈�澶х缉鏀惧眰绾� + private float _zoom = 1f;//褰撳墠缂╂斁灞傜骇 + private float _dxo = 0f;//x鍋忕Щ閲� + private float _dyo = 0f;//y鍋忕Щ閲� + + /// <summary> + /// 缂╂斁绛夌骇 + /// </summary> + public float Zoom + { + get => _zoom; + private set + { + if (_networkBounds.IsEmpty) + { + _zoom = 1f; + return; + } + + float sizeMax = Math.Max(_networkBounds.Height, _networkBounds.Width); + float sizeNew = sizeMax * value; + + if (sizeNew > _zoomMax) + { + _zoom = _zoomMax / sizeMax; + } + else if (sizeNew < _zoomMin) + { + _zoom = _zoomMin / sizeMax; + } + else + { + _zoom = value; + } + } + } + + /// <summary> + /// 鑷�傚簲 + /// </summary> + public void ZoomAll() + { + if (!Initialized) + { + return; + } + var networkBounds = _network.GetBounds(); + if (networkBounds.IsEmpty) + { + return; + } + this.Zoom = networkBounds.Width / networkBounds.Height < this.Width / this.Height ? + this.Height / networkBounds.Height : + this.Width / networkBounds.Width; + + + _dxo = -networkBounds.X; + _dyo = networkBounds.Bottom; + + this.Zoom *= 0.9f; + + _dxo += this.Width * 0.5f / this.Zoom - networkBounds.Width * 0.5f; + _dyo += this.Height * 0.5f / this.Zoom - networkBounds.Height * 0.5f; + } + + + private void ZoomToPoint(MouseEventArgs e) + { + float scale = e.Delta > 0 ? this.Zoom * 1.5f : this.Zoom / 1.5f; + var pt = ClientToDispPoint(e.Location); + this.Zoom = scale; + _dxo = -pt.X + e.X / this.Zoom; + _dyo = pt.Y + e.Y / this.Zoom; + } + + #endregion + + #region 鍧愭爣杞崲 + + protected PointF ClientToDispPoint(PointF cp) + { + return new PointF(-_dxo + cp.X / _zoom, _dyo - cp.Y / _zoom); + } + + #endregion + + #region 杈规缁樺埗 + + /// <summary> + /// 杈规棰滆壊 + /// </summary> + [Browsable(true)] + [Description("鑷畾涔夎竟妗嗛鑹�")] + public Color CustomBorderColor + { + get { return _customBorderColor; } + set { _customBorderColor = value; } + } + private Color _customBorderColor = Color.Gray; + + /// <summary> + /// 杈规瀹藉害 + /// </summary> + [Browsable(true)] + [Description("鑷畾涔夎竟妗嗗搴�")] + public int CustomBorderWidth + { + get { return _customBorderWidth; } + set { _customBorderWidth = value; } + } + private int _customBorderWidth = 1; + + /// <summary> + /// 杈规鏄惁鏄剧ず + /// </summary> + [Browsable(true)] + [Description("鑷畾涔夎竟妗嗗彲瑙佹��")] + [DefaultValue(false)] + public bool CustomBorderVisible + { + get { return _customBorderVisible; } + set + { + _customBorderVisible = value; + } + } + private bool _customBorderVisible = false; + + /// <summary> + /// 缁樺埗鑷畾涔夎竟妗� + /// </summary> + protected virtual void DrawCustomBorder(Graphics g) + { + if (this.CustomBorderVisible) + { + ControlPaint.DrawBorder(g, + this.ClientRectangle, + this.CustomBorderColor, this.CustomBorderWidth, ButtonBorderStyle.Solid, + this.CustomBorderColor, this.CustomBorderWidth, ButtonBorderStyle.Solid, + this.CustomBorderColor, this.CustomBorderWidth, ButtonBorderStyle.Solid, + this.CustomBorderColor, this.CustomBorderWidth, ButtonBorderStyle.Solid); + } + } + + + #endregion + + #region 鑾峰彇鐭╁舰鍖哄煙 + + /// <summary> + /// 鑾峰彇宸ヤ綔鍖哄煙 + /// </summary> + /// <returns></returns> + protected virtual RectangleF GetClientRectangleF() + { + return new RectangleF(0, 0, this.Width, this.Height); + } + + /// <summary> + /// 鑾峰彇鏄剧ず鍖哄煙 + /// </summary> + protected virtual RectangleF GetDispRectangleF() + { + if (_clientRectf.IsEmpty) + { + return default; + } + if (!Initialized) + { + return default; + } + var pt = ClientToDispPoint(new PointF(_clientRectf.X, _clientRectf.Height)); + var width = _clientRectf.Width / _zoom; + var height = _clientRectf.Height / _zoom; + return new RectangleF(pt, new SizeF(width, height)); + } + + #endregion + + #region 榧犳爣宸﹂敭鎸変笅鎷栧姩 + + /// <summary> + /// 褰撻紶鏍囧乏閿寜涓嬫椂鍏佽鎷栧姩 + /// </summary> + [Browsable(true)] + [Description("褰撻紶鏍囧乏閿寜涓嬫椂鍏佽鎷栧姩")] + [DefaultValue(true)] + public bool AllowMoveWhenMouseLeftDown + { + get => _allowMoveWhenMouseLeftDown; + set => _allowMoveWhenMouseLeftDown = value; + } + private bool _allowMoveWhenMouseLeftDown = true; + + protected bool _hasMouseLeftDown = false;//榧犳爣宸﹂敭鏄惁鎸変笅 + protected Point _mouseLeftDownMovePoint;//榧犳爣宸﹂敭鎸変笅绉诲姩鐐� + + /// <summary> + /// 鍒ゆ柇榧犳爣宸﹂敭鏄惁鎸変笅 + /// </summary> + protected virtual bool HasMouseLeftDown(MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + _hasMouseLeftDown = true; + _mouseLeftDownMovePoint = e.Location; + return true; + } + return false; + } + + /// <summary> + /// 榧犳爣宸﹂敭鎸変笅绉诲姩 + /// </summary> + /// <param name="e"></param> + protected virtual bool MouseLeftDownMove(MouseEventArgs e) + { + if (_hasMouseLeftDown) + { + if (this.AllowMoveWhenMouseLeftDown) + { + if (this.Initialized) + { + var pt = new PointF(e.X - _mouseLeftDownMovePoint.X, e.Y - _mouseLeftDownMovePoint.Y); + _dxo += pt.X / _zoom; + _dyo += pt.Y / _zoom; + _mouseLeftDownMovePoint = e.Location; + return true; + } + } + } + return false; + } + + /// <summary> + /// 鍒ゆ柇榧犳爣宸﹂敭鏄惁寮硅捣 + /// </summary> + protected virtual bool HasMouseLeftUp(MouseEventArgs e) + { + if (_hasMouseLeftDown) + { + _hasMouseLeftDown = false; + return true; + } + return false; + } + + #endregion + + #region 榧犳爣鍙抽敭鎸変笅鎷栧姩 + + /// <summary> + /// 褰撻紶鏍囧彸閿寜涓嬫椂鍏佽鎷栧姩 + /// </summary> + [Browsable(true)] + [Description("褰撻紶鏍囧彸閿寜涓嬫椂鍏佽鎷栧姩")] + [DefaultValue(true)] + public bool AllowMoveWhenMouseRightDown + { + get => _allowMoveWhenMouseRightDown; + set => _allowMoveWhenMouseRightDown = value; + } + private bool _allowMoveWhenMouseRightDown = true; + + protected bool _hasMouseRightDown = false;//榧犳爣鍙抽敭鏄惁鎸変笅 + protected Point _mouseRightDownMovePoint;//榧犳爣鍙抽敭鎸変笅绉诲姩鐐� + + /// <summary> + /// 鍒ゆ柇榧犳爣鍙抽敭鏄惁鎸変笅 + /// </summary> + protected virtual bool HasMouseRightDown(MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + _hasMouseRightDown = true; + _mouseRightDownMovePoint = e.Location; + return true; + } + return false; + } + + /// <summary> + /// 榧犳爣鍙抽敭鎸変笅绉诲姩 + /// </summary> + protected virtual bool MouseRightDownMove(MouseEventArgs e) + { + if (_hasMouseRightDown) + { + if (this.AllowMoveWhenMouseRightDown) + { + if (this.Initialized) + { + var pt = new PointF(e.X - _mouseRightDownMovePoint.X, e.Y - _mouseRightDownMovePoint.Y); + _dxo += pt.X / _zoom; + _dyo += pt.Y / _zoom; + _mouseRightDownMovePoint = e.Location; + return true; + } + } + } + return false; + } + + /// <summary> + /// 鍒ゆ柇榧犳爣宸﹂敭鏄惁寮硅捣 + /// </summary> + protected virtual bool HasMouseRightUp(MouseEventArgs e) + { + if (_hasMouseRightDown) + { + _hasMouseRightDown = false; + return true; + } + return false; + } + + #endregion + + #region 榧犳爣宸﹂敭鍙屽嚮鎭㈠鑷�傚簲 + + /// <summary> + /// 褰撻紶鏍囧弻鍑绘椂鍏佽鑷�傚簲 + /// </summary> + [Browsable(true)] + [Description("褰撻紶鏍囧弻鍑绘椂鍏佽鑷�傚簲")] + [DefaultValue(true)] + public bool AllowZoomAllWhenMouseLeftDoubleClick + { + get => _allowZoomAllWhenMouseLeftDoubleClick; + set => _allowZoomAllWhenMouseLeftDoubleClick = value; + } + private bool _allowZoomAllWhenMouseLeftDoubleClick = true; + + /// <summary> + /// 榧犳爣鍙屽嚮鏃惰嚜閫傚簲 + /// </summary> + protected virtual bool ZoomAllWhenMouseLeftDoubleClick(MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + if (e.Clicks > 1) + { + if (this.AllowZoomAllWhenMouseLeftDoubleClick) + { + if (this.Initialized) + { + ZoomAll(); + return true; + } + } + } + } + return false; + } + + #endregion + + #region 榧犳爣鎮仠 + + /// <summary> + /// 鍏佽榧犳爣鎮仠 + /// </summary> + [Browsable(true)] + [Description("鍏佽榧犳爣鎮仠")] + [DefaultValue(true)] + public bool AllowMouseHover + { + get => _allowMouseHover; + set => _allowMouseHover = value; + } + private bool _allowMouseHover = true; + private List<Parter> _lastHoverList = null;//鏈�鍚庝竴娆℃偓鍋滃垪琛� + + /// <summary> + /// 鎮仠 + /// 濡傛灉鍙戠敓鏀瑰彉灏辫繑鍥瀟rue + /// </summary> + protected virtual bool Hover(MouseEventArgs e) + { + if (this.AllowMouseHover) + { + if (this.Initialized) + { + var pt = ClientToDispPoint(e.Location); + var hoverList = _network.Hover(pt); + if (hoverList == null || hoverList.Count < 1) + { + if (_lastHoverList == null || _lastHoverList.Count < 1) + { + return false; + } + } + _lastHoverList = hoverList; + return true; + } + } + if (_lastHoverList == null || _lastHoverList.Count < 1) + { + return false; + } + return true; + } + + #endregion + + #region 榧犳爣宸﹂敭鐐瑰嚮閫夋嫨 + + /// <summary> + /// 鍏佽榧犳爣宸﹂敭鍗曞嚮閫夋嫨 + /// </summary> + [Browsable(true)] + [Description("鍏佽榧犳爣宸﹂敭鍗曞嚮閫夋嫨")] + [DefaultValue(true)] + public bool AllowMouseLeftSingleClickSelect + { + get => _allowMouseLeftSingleClickSelect; + set => _allowMouseLeftSingleClickSelect = value; + } + private bool _allowMouseLeftSingleClickSelect = true; + private List<Parter> _lastMouseLeftClickSelectList = null;//鏈�鍚庝竴娆¢紶鏍囧乏閿崟鍑婚�夋嫨鍒楄〃 + + + /// <summary> + /// 褰撻紶鏍囧乏閿崟鍑绘椂閫夋嫨 + /// </summary> + protected virtual bool SelectWhenMouseLeftSingleClick(MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + if (e.Clicks == 1) + { + if (this.Initialized) + { + var pt = ClientToDispPoint(e.Location); + var selectList = _network.Select(pt); + if (selectList == null || selectList.Count < 1) + { + if (_lastMouseLeftClickSelectList == null || _lastMouseLeftClickSelectList.Count < 1) + { + return false; + } + } + _lastMouseLeftClickSelectList = selectList; + return true; + } + } + } + if (_lastMouseLeftClickSelectList == null || _lastMouseLeftClickSelectList.Count < 1) + { + return false; + } + return true; + } + + #endregion + + #region 榧犳爣婊氳疆婊氬姩缂╂斁 + + /// <summary> + /// 褰撻紶鏍囨粴杞粴鍔ㄦ椂鍏佽缂╂斁 + /// </summary> + [Browsable(true)] + [Description("褰撻紶鏍囨粴杞粴鍔ㄦ椂鍏佽缂╂斁")] + [DefaultValue(true)] + public bool AllowZoomWhenMouseWheelRoll + { + get => _allowZoomWhenMouseWheelRoll; + set => _allowZoomWhenMouseWheelRoll = value; + } + private bool _allowZoomWhenMouseWheelRoll = true; + + /// <summary> + /// 褰撻紶鏍囨粴杞粴鍔ㄦ椂缂╂斁 + /// </summary> + protected virtual bool ZoomWhenMouseWheelRoll(MouseEventArgs e) + { + if (e.Delta != 0) + { + if (this.AllowZoomWhenMouseWheelRoll) + { + if (this.Initialized) + { + ZoomToPoint(e); + return true; + } + } + } + return false; + } + + #endregion + + #region 閲婃斁璧勬簮 /// <summary> /// 閲婃斁璧勬簮 @@ -94,51 +630,98 @@ } + #endregion + + /// <summary> - /// 鑷�傚簲 + /// 閲嶇粯 /// </summary> - public void ZoomAll() + protected override void OnPaint(PaintEventArgs e) { - if (!Initialized) - { - return; - } + base.OnPaint(e); + DrawCustomBorder(e.Graphics); + DrawCache(); + ApplyCache(e.Graphics); - float w = Width; - float h = Height; - var networkBounds = _network.GetBounds(); - if (networkBounds.IsEmpty) - { - return; - } - _zoom = networkBounds.Width / networkBounds.Height < w / h ? - h / networkBounds.Height : - w / networkBounds.Width; - - - _dxo = -networkBounds.X; - _dyo = networkBounds.Bottom; - - _zoom *= 0.95f; - - _dxo += w * 0.5f / _zoom - networkBounds.Width * 0.5f; - _dyo += h * 0.5f / _zoom - networkBounds.Height * 0.5f; - - Invalidate(); } + /// <summary> + /// 鐣岄潰灏哄鍙戠敓鏀瑰彉 + /// </summary> + /// <param name="eventargs"></param> + protected override void OnResize(EventArgs eventargs) + { + base.OnResize(eventargs); + _clientRectf = GetClientRectangleF(); + ZoomAll(); + CreateCache(); + this.Invalidate(); + } + /// <summary> + /// 榧犳爣鎸変笅 + /// </summary> + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + HasMouseLeftDown(e); + HasMouseRightDown(e); + } + /// <summary> + /// 榧犳爣绉诲姩 + /// </summary> + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + var hoverResult = Hover(e); + var hasMouseLeftDownMove = MouseLeftDownMove(e); + var hasMouseRightDownMove = MouseRightDownMove(e); + if (hoverResult || hasMouseLeftDownMove || hasMouseRightDownMove) + { + this.Invalidate(); + } + } + /// <summary> + /// 榧犳爣寮硅捣 + /// </summary> + protected override void OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + var hasMouseLeftUp = HasMouseLeftUp(e); + var hasMouseRightUp = HasMouseRightUp(e); + var mouseLeftSingleClickSelectResult = SelectWhenMouseLeftSingleClick(e); + if (hasMouseLeftUp || hasMouseRightUp || mouseLeftSingleClickSelectResult) + { + this.Invalidate(); + } + } + //榧犳爣婊氳疆婊氬姩 + protected override void OnMouseWheel(MouseEventArgs e) + { + base.OnMouseWheel(e); + var zoomWhenMouseWheelRollResult = ZoomWhenMouseWheelRoll(e); + if (zoomWhenMouseWheelRollResult) + { + this.Refresh(); + } + } - - - - - - + /// <summary> + /// 榧犳爣鍙屽嚮 + /// </summary> + protected override void OnMouseDoubleClick(MouseEventArgs e) + { + base.OnMouseDoubleClick(e); + var zoomAllWhenMouseLeftDoubleClickResult = ZoomAllWhenMouseLeftDoubleClick(e); + if (zoomAllWhenMouseLeftDoubleClickResult) + { + this.Invalidate(); + } + } } } -- Gitblit v1.9.3