From 8f677b1741b78e4de4c95373fc02587a05d7b5ca Mon Sep 17 00:00:00 2001
From: lixiaojun <1287241240@qq.com>
Date: 星期五, 16 八月 2024 17:52:08 +0800
Subject: [PATCH] 2d尝试,功能基本实现,还差绘制特定区域

---
 WinFrmUI/Yw.WinFrmUI.Hydro.L2d.Core/02-panel/NetworkPanel.cs |  526 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 466 insertions(+), 60 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..7f33106 100644
--- a/WinFrmUI/Yw.WinFrmUI.Hydro.L2d.Core/02-panel/NetworkPanel.cs
+++ b/WinFrmUI/Yw.WinFrmUI.Hydro.L2d.Core/02-panel/NetworkPanel.cs
@@ -1,4 +1,5 @@
-锘縩amespace Yw.WinFrmUI.HydroL2d
+锘�
+namespace Yw.WinFrmUI.HydroL2d
 {
     /// <summary>
     /// 绠$綉闈㈡澘
@@ -19,25 +20,29 @@
 
             //璁剧疆鍏佽鐨勬渶灏忓昂瀵�
             this.MinimumSize = new Size(10, 10);
-
         }
 
 
-        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;//绠$綉杈圭晫
+        private Bitmap _cache = null;//缂撳瓨<渚濇嵁宸ヤ綔鍖哄煙鍒涘缓鐨勭┖鍥剧墖>
+        private object _cacheLocker = new();//缂撳瓨閿�
+        private Bitmap _disp = null;//鏄剧ず<鍦╟ache鍩虹涓婅繘琛岀粯鍒讹紝鏈�缁堢殑鏄剧ず鍥剧墖>
+        private object _dispLocker = new();//鏄剧ず閿�
+        private float _zoomMin = 0.01f;//鏈�灏忕缉鏀惧眰绾�
+        private float _zoomMax = 10000f;//鏈�澶х缉鏀惧眰绾�
+        private float _zoom = 1f;//褰撳墠缂╂斁灞傜骇
+        private float _dxo = 0f;//x鍋忕Щ閲�
+        private float _dyo = 0f;//y鍋忕Щ閲�
+        private RectangleF _clientRectf;//宸ヤ綔鍖哄煙鐭╁舰
+
+
+        #region 鍒濆鍖�
 
         /// <summary>
         /// 鏄惁鍒濆鍖�
         /// </summary>
         public bool Initialized => _network != null;
-
-
-
 
         /// <summary>
         /// 鍒濆鍖�
@@ -45,42 +50,385 @@
         public virtual void Initial(Network network)
         {
             _network = network;
+            _networkBounds = _network.GetBounds();
+            _clientRectf = GetClientRectangleF();
+            CreateCache();
             ZoomAll();
         }
 
-        protected override void OnPaint(PaintEventArgs e)
+        #endregion
+
+        #region 缂撳瓨涓庢樉绀�
+
+        /// <summary>
+        /// 鍒涘缓缂撳瓨
+        /// </summary>
+        protected virtual void CreateCache()
         {
-            base.OnPaint(e);
             if (!Initialized)
             {
                 return;
             }
-            try
+            var img = new Bitmap((int)_clientRectf.Width, (int)_clientRectf.Height);
+            img.MakeTransparent(Color.White);
+            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 disp = _cache.CloneC();
+            if (disp == null)
+            {
+                return;
+            }
+            var dispRect = GetDispRectangleF();
+            using (var g = Graphics.FromImage(disp))
+            {
+                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);
+                _network.Draw(g);
+            }
+            lock (_dispLocker)
+            {
+                if (_disp != null)
+                {
+                    _disp.Dispose();
+                }
+                _disp = disp;
+            }
         }
+
+        /// <summary>
+        /// 搴旂敤缂撳瓨
+        /// </summary>
+        protected virtual void ApplyCache(Graphics g)
+        {
+            if (!Initialized)
+            {
+                return;
+            }
+            lock (_dispLocker)
+            {
+                if (_disp != null)
+                {
+                    g.DrawImage(_disp, _clientRectf);
+                }
+            }
+
+        }
+
+        #endregion
+
+        #region 缂╂斁
+
+        /// <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(_clientRectf.Location);
+            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)
+            {
+                if (Initialized)
+                {
+                    if (this.AllowMoveWhenMouseLeftDown)
+                    {
+                        _hasMouseLeftDown = true;
+                        _mouseLeftDownMovePoint = e.Location;
+                        return true;
+                    }
+                }
+            }
+            return true;
+        }
+
+        /// <summary>
+        /// 榧犳爣宸﹂敭鎸変笅绉诲姩
+        /// </summary>
+        /// <param name="e"></param>
+        protected virtual bool MouseLeftDownMove(MouseEventArgs e)
+        {
+            if (e.Button == MouseButtons.Left)
+            {
+                if (this.AllowMoveWhenMouseLeftDown)
+                {
+                    if (_hasMouseLeftDown)
+                    {
+                        if (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)
+        {
+            _hasMouseLeftDown = false;
+            return true;
+        }
+
+        #endregion
+
+        #region 榧犳爣鍙屽嚮鎭㈠鑷�傚簲
+
+        /// <summary>
+        /// 褰撻紶鏍囧弻鍑绘椂鍏佽鑷�傚簲
+        /// </summary>
+        [Browsable(true)]
+        [Description("褰撻紶鏍囧弻鍑绘椂鍏佽鑷�傚簲")]
+        [DefaultValue(true)]
+        public bool AllowZoomAllWhenMouseDoubleClick
+        {
+            get => _allowZoomAllWhenMouseDoubleClick;
+            set => _allowZoomAllWhenMouseDoubleClick = value;
+        }
+        private bool _allowZoomAllWhenMouseDoubleClick = true;
+
+        /// <summary>
+        /// 榧犳爣鍙屽嚮鏃惰嚜閫傚簲
+        /// </summary>
+        protected virtual bool ZoomAllWhenMouseDoubleClick(MouseEventArgs e)
+        {
+            if (e.Clicks > 1)
+            {
+                if (AllowZoomAllWhenMouseDoubleClick)
+                {
+                    ZoomAll();
+                    return true;
+                }
+            }
+            return true;
+        }
+
+        #endregion
+
+        #region 閲婃斁璧勬簮
 
         /// <summary>
         /// 閲婃斁璧勬簮
@@ -94,51 +442,109 @@
 
         }
 
+        #endregion
+
+        #region 閫夋嫨
 
         /// <summary>
-        /// 鑷�傚簲
+        /// 閫夋嫨锛堥�氳繃鐐归�夋嫨锛�
         /// </summary>
-        public void ZoomAll()
+        protected virtual List<Parter> Select(MouseEventArgs e)
         {
-            if (!Initialized)
-            {
-                return;
-            }
-
-            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();
+            var pt = ClientToDispPoint(e.Location);
+            var list = _network.Select(pt);
+            return list;
         }
 
+        /// <summary>
+        /// 鎮仠
+        /// </summary>
+        protected virtual List<Parter> Hover(MouseEventArgs e)
+        {
+            var pt = ClientToDispPoint(e.Location);
+            var list = _network.Hover(pt);
+            return list;
+        }
 
+        #endregion
 
+        /// <summary>
+        /// 閲嶇粯
+        /// </summary>
+        protected override void OnPaint(PaintEventArgs e)
+        {
+            base.OnPaint(e);
+            DrawCustomBorder(e.Graphics);
+            DrawCache();
+            ApplyCache(e.Graphics);
 
+        }
 
+        /// <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);
 
+        }
 
+        /// <summary>
+        /// 榧犳爣绉诲姩
+        /// </summary>
+        protected override void OnMouseMove(MouseEventArgs e)
+        {
+            base.OnMouseMove(e);
+            Hover(e);
+            MouseLeftDownMove(e);
+            this.Invalidate();
+        }
 
+        /// <summary>
+        /// 榧犳爣寮硅捣
+        /// </summary>
+        protected override void OnMouseUp(MouseEventArgs e)
+        {
+            base.OnMouseUp(e);
+            HasMouseLeftUp(e);
+            Select(e);
+            this.Invalidate();
+        }
 
+        //榧犳爣婊氳疆婊氬姩
+        protected override void OnMouseWheel(MouseEventArgs e)
+        {
+            base.OnMouseWheel(e);
+            ZoomToPoint(e);
+            this.Refresh();
+        }
 
+        /// <summary>
+        /// 榧犳爣鍙屽嚮
+        /// </summary>
+        protected override void OnMouseDoubleClick(MouseEventArgs e)
+        {
+            base.OnMouseDoubleClick(e);
+            if (ZoomAllWhenMouseDoubleClick(e))
+            {
+                this.Invalidate();
+            }
 
+        }
 
     }
 }

--
Gitblit v1.9.3