@@ -9,9 +9,8 @@ namespace BluePointLilac.Controls
99{
1010 public sealed class MyToolBar : Panel
1111 {
12- // 提高不透明度值,使白色背景更加明显
13- public const float SelctedOpacity = 0.8F ;
14- public const float HoveredOpacity = 0.4F ;
12+ public const float SelctedOpacity = 1.0F ;
13+ public const float HoveredOpacity = 0.6F ;
1514 public const float UnSelctedOpacity = 0 ;
1615
1716 private readonly FlowLayoutPanel buttonContainer ;
@@ -25,7 +24,6 @@ public MyToolBar()
2524 BackColor = DarkModeHelper . TitleArea ;
2625 ForeColor = DarkModeHelper . FormFore ;
2726
28- // 创建按钮容器(左侧)
2927 buttonContainer = new FlowLayoutPanel
3028 {
3129 Dock = DockStyle . Left ,
@@ -36,7 +34,6 @@ public MyToolBar()
3634 BackColor = Color . Transparent
3735 } ;
3836
39- // 创建搜索框容器(右侧)
4037 searchBoxContainer = new Panel
4138 {
4239 Dock = DockStyle . Right ,
@@ -48,7 +45,6 @@ public MyToolBar()
4845 Controls . Add ( buttonContainer ) ;
4946 Controls . Add ( searchBoxContainer ) ;
5047
51- // 监听主题变化
5248 DarkModeHelper . ThemeChanged += OnThemeChanged ;
5349 }
5450
@@ -61,16 +57,18 @@ public MyToolBarButton SelectedButton
6157 if ( selectedButton == value ) return ;
6258 if ( selectedButton != null )
6359 {
64- selectedButton . Opacity = UnSelctedOpacity ; // 动画过渡到未选中状态
60+ selectedButton . Opacity = UnSelctedOpacity ;
6561 selectedButton . Cursor = Cursors . Hand ;
66- selectedButton . UpdateTextColor ( ) ; // 更新文字颜色
62+ selectedButton . UpdateTextColor ( ) ;
63+ selectedButton . IsSelected = false ;
6764 }
6865 selectedButton = value ;
6966 if ( selectedButton != null )
7067 {
71- selectedButton . Opacity = SelctedOpacity ; // 动画过渡到选中状态
68+ selectedButton . Opacity = SelctedOpacity ;
7269 selectedButton . Cursor = Cursors . Default ;
73- selectedButton . UpdateTextColor ( ) ; // 更新文字颜色
70+ selectedButton . UpdateTextColor ( ) ;
71+ selectedButton . IsSelected = true ;
7472 }
7573 SelectedButtonChanged ? . Invoke ( this , null ) ;
7674 }
@@ -85,7 +83,6 @@ public int SelectedIndex
8583 null : ( MyToolBarButton ) buttonContainer . Controls [ value ] ;
8684 }
8785
88- // 添加一个方法来获取所有按钮(用于兼容旧代码)
8986 public Control . ControlCollection ButtonControls => buttonContainer . Controls ;
9087
9188 public void AddButton ( MyToolBarButton button )
@@ -104,17 +101,19 @@ public void AddButton(MyToolBarButton button)
104101 {
105102 if ( button != SelectedButton )
106103 {
107- button . Opacity = HoveredOpacity ; // 动画过渡到悬停状态
108- button . UpdateTextColor ( ) ; // 更新文字颜色
104+ button . Opacity = HoveredOpacity ;
105+ button . UpdateTextColor ( ) ;
106+ button . IsHovered = true ;
109107 }
110108 } ;
111109
112110 button . MouseLeave += ( sender , e ) =>
113111 {
114112 if ( button != SelectedButton )
115113 {
116- button . Opacity = UnSelctedOpacity ; // 动画过渡到未选中状态
117- button . UpdateTextColor ( ) ; // 更新文字颜色
114+ button . Opacity = UnSelctedOpacity ;
115+ button . UpdateTextColor ( ) ;
116+ button . IsHovered = false ;
118117 }
119118 } ;
120119
@@ -128,13 +127,10 @@ public void AddButtons(MyToolBarButton[] buttons)
128127 Array . ForEach ( buttons , button => { button . Width = maxWidth ; AddButton ( button ) ; } ) ;
129128 }
130129
131- // 添加搜索框到工具栏右侧
132130 public void AddSearchBox ( SearchBox searchBox )
133131 {
134- // 清除现有搜索框
135132 searchBoxContainer . Controls . Clear ( ) ;
136133
137- // 设置搜索框
138134 searchBox . Parent = searchBoxContainer ;
139135 searchBox . Width = searchBoxContainer . Width - 40 . DpiZoom ( ) ;
140136 searchBox . Height = 36 . DpiZoom ( ) ;
@@ -146,13 +142,11 @@ protected override void OnResize(EventArgs e)
146142 {
147143 base . OnResize ( e ) ;
148144
149- // 调整搜索框容器的宽度
150145 if ( searchBoxContainer != null )
151146 {
152147 searchBoxContainer . Width = 240 . DpiZoom ( ) ;
153148 searchBoxContainer . Height = Height ;
154149
155- // 确保搜索框在容器中垂直居中
156150 var searchBox = searchBoxContainer . Controls . OfType < SearchBox > ( ) . FirstOrDefault ( ) ;
157151 if ( searchBox != null )
158152 {
@@ -167,30 +161,28 @@ protected override void OnPaintBackground(PaintEventArgs e)
167161 base . OnPaintBackground ( e ) ;
168162
169163 var rect = ClientRectangle ;
164+ var g = e . Graphics ;
165+ g . SmoothingMode = SmoothingMode . AntiAlias ;
170166
171- // 使用DarkModeHelper中的颜色
172167 var color1 = DarkModeHelper . ToolBarGradientTop ;
173168 var color2 = DarkModeHelper . ToolBarGradientMiddle ;
174169 var color3 = DarkModeHelper . ToolBarGradientBottom ;
175170
176- // 创建三色渐变
177- using var brush = new LinearGradientBrush (
178- rect , Color . Empty , Color . Empty , LinearGradientMode . Vertical ) ;
179- // 使用ColorBlend创建三色渐变
171+ using var brush = new LinearGradientBrush ( rect , Color . Empty , Color . Empty , LinearGradientMode . Vertical ) ;
180172 var colorBlend = new ColorBlend ( 3 ) ;
181173 colorBlend . Colors = new Color [ ] { color1 , color2 , color3 } ;
182174 colorBlend . Positions = new float [ ] { 0f , 0.5f , 1f } ;
183175 brush . InterpolationColors = colorBlend ;
184176
185- e . Graphics . FillRectangle ( brush , rect ) ;
177+ g . FillRectangle ( brush , rect ) ;
178+
179+ using var borderPen = new Pen ( DarkModeHelper . IsDarkTheme ?
180+ Color . FromArgb ( 60 , 60 , 60 ) : Color . FromArgb ( 220 , 220 , 220 ) , 1 ) ;
181+ g . DrawLine ( borderPen , 0 , rect . Bottom - 1 , rect . Right , rect . Bottom - 1 ) ;
186182 }
187183
188- // 重写Controls属性以保持向后兼容(注意:这可能会影响一些代码)
189- public new Control . ControlCollection Controls =>
190- // 返回包含所有子控件的集合
191- base . Controls ;
184+ public new Control . ControlCollection Controls => base . Controls ;
192185
193- // 主题变化事件处理
194186 private void OnThemeChanged ( object sender , EventArgs e )
195187 {
196188 BackColor = DarkModeHelper . TitleArea ;
@@ -212,9 +204,43 @@ public sealed class MyToolBarButton : Panel
212204 {
213205 private float targetOpacity ;
214206 private float currentOpacity ;
207+ private float currentScale = 1.0f ;
208+ private float targetScale = 1.0f ;
215209 private readonly Timer animationTimer = new ( ) { Interval = 16 } ;
216- private const float AnimationSpeed = 0.15f ;
217- private readonly int borderRadius = 10 ; // 圆角半径
210+ private const float AnimationSpeed = 0.12f ;
211+ private const float ScaleAnimationSpeed = 0.15f ;
212+ private readonly int borderRadius = 12 ;
213+
214+ private bool isSelected = false ;
215+ private bool isHovered = false ;
216+
217+ public bool IsSelected
218+ {
219+ get => isSelected ;
220+ set
221+ {
222+ if ( isSelected != value )
223+ {
224+ isSelected = value ;
225+ targetScale = value ? 1.02f : 1.0f ;
226+ if ( ! animationTimer . Enabled ) animationTimer . Start ( ) ;
227+ }
228+ }
229+ }
230+
231+ public bool IsHovered
232+ {
233+ get => isHovered ;
234+ set
235+ {
236+ if ( isHovered != value && ! isSelected )
237+ {
238+ isHovered = value ;
239+ targetScale = value ? 1.01f : 1.0f ;
240+ if ( ! animationTimer . Enabled ) animationTimer . Start ( ) ;
241+ }
242+ }
243+ }
218244
219245 public MyToolBarButton ( Image image , string text )
220246 {
@@ -225,16 +251,16 @@ public MyToolBarButton(Image image, string text)
225251 Cursor = Cursors . Hand ;
226252 Size = new Size ( 72 , 72 ) . DpiZoom ( ) ;
227253
228- // 启用透明背景
229254 SetStyle ( ControlStyles . SupportsTransparentBackColor , true ) ;
230255 SetStyle ( ControlStyles . Opaque , false ) ;
256+ SetStyle ( ControlStyles . ResizeRedraw , true ) ;
231257
232258 animationTimer . Tick += ( s , e ) => UpdateAnimation ( ) ;
233259
234260 Controls . AddRange ( new Control [ ] { picImage , lblText } ) ;
235261 lblText . Resize += ( sender , e ) => OnResize ( null ) ;
236- picImage . Top = 6 . DpiZoom ( ) ;
237- lblText . Top = 52 . DpiZoom ( ) ;
262+ picImage . Top = 8 . DpiZoom ( ) ;
263+ lblText . Top = 50 . DpiZoom ( ) ;
238264 lblText . SetEnabled ( false ) ;
239265 Image = image ;
240266 Text = text ;
@@ -244,7 +270,7 @@ public MyToolBarButton(Image image, string text)
244270 private readonly PictureBox picImage = new ( )
245271 {
246272 SizeMode = PictureBoxSizeMode . StretchImage ,
247- Size = new Size ( 40 , 40 ) . DpiZoom ( ) ,
273+ Size = new Size ( 36 , 36 ) . DpiZoom ( ) ,
248274 BackColor = Color . Transparent ,
249275 Enabled = false
250276 } ;
@@ -253,7 +279,7 @@ public MyToolBarButton(Image image, string text)
253279 {
254280 ForeColor = DarkModeHelper . FormFore ,
255281 BackColor = Color . Transparent ,
256- Font = SystemFonts . MenuFont ,
282+ Font = new Font ( SystemFonts . MenuFont . FontFamily , SystemFonts . MenuFont . SizeInPoints , FontStyle . Regular , GraphicsUnit . Point ) ,
257283 AutoSize = true ,
258284 Anchor = AnchorStyles . Left | AnchorStyles . Right
259285 } ;
@@ -271,7 +297,7 @@ public Image Image
271297 }
272298
273299 public bool CanBeSelected = true ;
274- private readonly float opacity ;
300+
275301 public float Opacity
276302 {
277303 get => currentOpacity ;
@@ -284,40 +310,61 @@ public float Opacity
284310 }
285311 }
286312
287- // 重写OnPaint方法以实现圆角效果
288313 protected override void OnPaint ( PaintEventArgs e )
289314 {
290- // 调用基类绘制以确保子控件正确显示
291315 base . OnPaint ( e ) ;
292316
293- // 创建圆角矩形路径
294- using var path = DarkModeHelper . CreateRoundedRectanglePath ( ClientRectangle , borderRadius ) ;
295- // 根据当前模式选择颜色
317+ var g = e . Graphics ;
318+ g . SmoothingMode = SmoothingMode . AntiAlias ;
319+ g . InterpolationMode = InterpolationMode . HighQualityBicubic ;
320+
296321 var isDarkMode = DarkModeHelper . IsDarkTheme ;
322+ var mainColor = DarkModeHelper . MainColor ;
323+
324+ var padding = 4 ;
325+ var drawRect = new Rectangle (
326+ padding ,
327+ padding ,
328+ Width - padding * 2 ,
329+ Height - padding * 2 ) ;
297330
298- // 深色模式使用白色,浅色模式使用黑色
299- var baseColor = isDarkMode ? Color . White : Color . Black ;
331+ using var path = DarkModeHelper . CreateRoundedRectanglePath ( drawRect , borderRadius ) ;
300332
301- // 减少两种模式的不透明度
302- var opacityFactor = isDarkMode ? 0.4f : 0.6f ; // 深色模式减少更多(0.4),浅色模式减少较少(0.6)
303- var alpha = ( int ) ( currentOpacity * 255 * opacityFactor ) ;
304- alpha = Math . Max ( 0 , Math . Min ( 255 , alpha ) ) ; // 确保alpha值在有效范围内
333+ if ( currentOpacity > 0.01f )
334+ {
335+ var baseColor = isDarkMode ? Color . White : mainColor ;
336+ var opacityFactor = isDarkMode ? 0.35f : 0.5f ;
337+ var alpha = ( int ) ( currentOpacity * 255 * opacityFactor ) ;
338+ alpha = Math . Max ( 0 , Math . Min ( 255 , alpha ) ) ;
339+ var fillColor = Color . FromArgb ( alpha , baseColor ) ;
340+
341+ using var brush = new SolidBrush ( fillColor ) ;
342+ g . FillPath ( brush , path ) ;
305343
306- var fillColor = Color . FromArgb ( alpha , baseColor ) ;
344+ if ( isSelected && currentOpacity > 0.5f )
345+ {
346+ var glowAlpha = ( int ) ( currentOpacity * 60 ) ;
347+ var glowColor = Color . FromArgb ( glowAlpha , mainColor ) ;
348+ using var glowPath = DarkModeHelper . CreateRoundedRectanglePath (
349+ new Rectangle ( drawRect . X - 2 , drawRect . Y - 2 , drawRect . Width + 4 , drawRect . Height + 4 ) ,
350+ borderRadius + 2 ) ;
351+ using var glowPen = new Pen ( glowColor , 2 ) ;
352+ g . DrawPath ( glowPen , glowPath ) ;
353+ }
307354
308- // 使用计算出的颜色填充圆角矩形
309- using var brush = new SolidBrush ( fillColor ) ;
310- e . Graphics . SmoothingMode = SmoothingMode . AntiAlias ;
311- e . Graphics . FillPath ( brush , path ) ;
355+ var borderColor = isSelected ?
356+ Color . FromArgb ( 180 , mainColor ) :
357+ Color . FromArgb ( 100 , isDarkMode ? Color . White : mainColor ) ;
358+ using var borderPen = new Pen ( borderColor , 1 ) ;
359+ g . DrawPath ( borderPen , path ) ;
360+ }
312361 }
313362
314- // 更新文字颜色的方法
315363 public void UpdateTextColor ( )
316364 {
317365 var isDarkMode = DarkModeHelper . IsDarkTheme ;
318366
319- // 浅色模式下,当按钮被选中或悬停时,文字颜色改为白色
320- if ( ! isDarkMode && currentOpacity > 0.1f )
367+ if ( ! isDarkMode && currentOpacity > 0.3f )
321368 {
322369 lblText . ForeColor = Color . White ;
323370 }
@@ -329,38 +376,55 @@ public void UpdateTextColor()
329376
330377 private void UpdateAnimation ( )
331378 {
332- currentOpacity += ( targetOpacity - currentOpacity ) * AnimationSpeed ;
333- var difference = Math . Abs ( currentOpacity - targetOpacity ) ;
379+ var needsUpdate = false ;
334380
335- if ( difference < 0.01f )
381+ var opacityDiff = targetOpacity - currentOpacity ;
382+ if ( Math . Abs ( opacityDiff ) > 0.001f )
383+ {
384+ currentOpacity += opacityDiff * AnimationSpeed ;
385+ needsUpdate = true ;
386+ }
387+ else
336388 {
337389 currentOpacity = targetOpacity ;
338- animationTimer . Stop ( ) ;
339390 }
340391
341- // 更新文字颜色
392+ var scaleDiff = targetScale - currentScale ;
393+ if ( Math . Abs ( scaleDiff ) > 0.001f )
394+ {
395+ currentScale += scaleDiff * ScaleAnimationSpeed ;
396+ needsUpdate = true ;
397+ }
398+ else
399+ {
400+ currentScale = targetScale ;
401+ }
402+
342403 UpdateTextColor ( ) ;
343404
344- // 强制重绘
345- this . Invalidate ( ) ;
346- this . Update ( ) ;
405+ Invalidate ( ) ;
406+ Update ( ) ;
407+
408+ if ( ! needsUpdate )
409+ {
410+ animationTimer . Stop ( ) ;
411+ }
347412 }
348413
349414 protected override void OnResize ( EventArgs e )
350415 {
351416 base . OnResize ( e ) ;
352417 lblText . Left = ( Width - lblText . Width ) / 2 ;
353418 picImage . Left = ( Width - picImage . Width ) / 2 ;
354- this . Invalidate ( ) ; // 重绘以确保圆角正确显示
419+ Invalidate ( ) ;
355420 }
356421
357- // 确保透明背景正确渲染
358422 protected override CreateParams CreateParams
359423 {
360424 get
361425 {
362426 var cp = base . CreateParams ;
363- cp . ExStyle |= 0x20 ; // 添加 WS_EX_TRANSPARENT 样式
427+ cp . ExStyle |= 0x20 ;
364428 return cp ;
365429 }
366430 }
0 commit comments