MyIconButton.xaml.vb 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. Imports System.Windows.Shapes
  2. Public Class MyIconButton
  3. '自定义事件
  4. Public Event Click(sender As Object, e As EventArgs)
  5. '自定义属性
  6. Public Uuid As Integer = GetUuid()
  7. Public Property Logo As String
  8. Get
  9. Return Path.Data.ToString
  10. End Get
  11. Set(value As String)
  12. Path.Data = (New GeometryConverter).ConvertFromString(value)
  13. End Set
  14. End Property
  15. Private _LogoScale As Double = 1
  16. Public Property LogoScale() As Double
  17. Get
  18. Return _LogoScale
  19. End Get
  20. Set(value As Double)
  21. _LogoScale = value
  22. If Not IsNothing(Path) Then Path.RenderTransform = New ScaleTransform With {.ScaleX = LogoScale, .ScaleY = LogoScale}
  23. End Set
  24. End Property
  25. Public Enum Themes
  26. Color
  27. White
  28. Black
  29. Red
  30. Custom
  31. End Enum
  32. Public Property Theme As Themes = Themes.Color
  33. Private _Foreground As New SolidColorBrush(Color.FromRgb(128, 128, 128))
  34. Public Property Foreground As SolidColorBrush
  35. Get
  36. Return _Foreground
  37. End Get
  38. Set(value As SolidColorBrush)
  39. _Foreground = value
  40. AniControlEnabled += 1
  41. RefreshAnim()
  42. AniControlEnabled -= 1
  43. End Set
  44. End Property
  45. '鼠标点击判定(务必放在点击事件之后,以使得 Button_MouseUp 先于 Button_MouseLeave 执行)
  46. Private IsMouseDown As Boolean = False
  47. Public Property CanClick As Boolean = True
  48. Private Sub Button_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonUp
  49. If Not CanClick Then Return
  50. If Not IsMouseDown Then Return
  51. Logger.Info($"按下图标按钮{If(String.IsNullOrEmpty(Name), "", ":" & Name)}")
  52. RaiseEvent Click(sender, e)
  53. e.Handled = True
  54. Button_MouseUp()
  55. RaiseCustomEvent() '自定义事件
  56. End Sub
  57. Private Sub Button_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonDown
  58. If Not CanClick Then Return
  59. IsMouseDown = True
  60. Focus()
  61. '指向
  62. AniStart(AaScaleTransform(PanBack, 0.8 - CType(PanBack.RenderTransform, ScaleTransform).ScaleX, 400,, New AniEaseOutFluent(AniEasePower.Strong)), "MyIconButton Scale " & Uuid)
  63. End Sub
  64. Private Sub Button_MouseUp() Handles Me.MouseLeftButtonUp
  65. If Not CanClick Then Return
  66. If IsMouseDown Then
  67. IsMouseDown = False
  68. AniStart({
  69. AaScaleTransform(PanBack, 1.05 - CType(PanBack.RenderTransform, ScaleTransform).ScaleX, 250,, New AniEaseOutBack(AniEasePower.Weak)),
  70. AaScaleTransform(PanBack, -0.05, 250,, New AniEaseOutFluent(AniEasePower.Strong))
  71. }, "MyIconButton Scale " & Uuid)
  72. End If
  73. RefreshAnim() '直接刷新颜色以判断是否已触发 MouseLeave
  74. End Sub
  75. Private Sub Button_MouseLeave() Handles Me.MouseLeave
  76. If Not CanClick Then Return
  77. IsMouseDown = False
  78. AniStart({
  79. AaScaleTransform(PanBack, 1 - CType(PanBack.RenderTransform, ScaleTransform).ScaleX, 250,, New AniEaseOutFluent)
  80. }, "MyIconButton Scale " & Uuid)
  81. RefreshAnim() '直接刷新颜色以判断是否已触发 MouseLeave
  82. End Sub
  83. '务必放在 IsMouseDown 更新之后
  84. Private Const AnimationColorIn As Integer = 120
  85. Private Const AnimationColorOut As Integer = 150
  86. Public Sub RefreshAnim() Handles Me.MouseEnter, Me.MouseLeave, Me.Loaded, Me.IsEnabledChanged
  87. Try
  88. If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画
  89. If PanBack.Background Is Nothing Then PanBack.Background = New MyColor(0, 255, 255, 255)
  90. If Path.Fill Is Nothing Then
  91. Select Case Theme
  92. Case Themes.Red
  93. Path.Fill = New MyColor(160, 255, 76, 76)
  94. Case Themes.Black
  95. Path.Fill = New MyColor(160, 0, 0, 0)
  96. Case Themes.Custom
  97. Path.Fill = New MyColor(160, Foreground)
  98. End Select
  99. End If
  100. Dim AnimList As New List(Of AniData)
  101. If Not IsEnabled Then
  102. AnimList.Add(AaColor(Path, Shape.FillProperty, "ColorBrushGray5", AnimationColorIn))
  103. ElseIf IsMouseOver Then '指向
  104. Select Case Theme
  105. Case Themes.Color
  106. AnimList.Add(AaColor(Path, Shape.FillProperty, "ColorBrush2", AnimationColorIn))
  107. Case Themes.White
  108. AnimList.Add(AaColor(PanBack, BackgroundProperty, New MyColor(50, 255, 255, 255) - PanBack.Background, AnimationColorIn))
  109. Case Themes.Red
  110. AnimList.Add(AaColor(Path, Shape.FillProperty, New MyColor(255, 76, 76) - Path.Fill, AnimationColorIn))
  111. Case Themes.Black
  112. AnimList.Add(AaColor(Path, Shape.FillProperty, New MyColor(230, 0, 0, 0) - Path.Fill, AnimationColorIn))
  113. Case Themes.Custom
  114. AnimList.Add(AaColor(Path, Shape.FillProperty, New MyColor(255, Foreground) - Path.Fill, AnimationColorIn))
  115. End Select
  116. Else '普通
  117. Select Case Theme
  118. Case Themes.Color
  119. AnimList.Add(AaColor(Path, Shape.FillProperty, "ColorBrush4", AnimationColorOut))
  120. PanBack.Background = New MyColor(0, 255, 255, 255)
  121. Case Themes.White
  122. AnimList.Add(AaColor(Path, Shape.FillProperty, "ColorBrush8", AnimationColorOut))
  123. AnimList.Add(AaColor(PanBack, BackgroundProperty, New MyColor(0, 255, 255, 255) - PanBack.Background, AnimationColorOut))
  124. Case Themes.Red
  125. AnimList.Add(AaColor(Path, Shape.FillProperty, New MyColor(160, 255, 76, 76) - Path.Fill, AnimationColorOut))
  126. PanBack.Background = New MyColor(0, 255, 255, 255)
  127. Case Themes.Black
  128. AnimList.Add(AaColor(Path, Shape.FillProperty, New MyColor(160, 0, 0, 0) - Path.Fill, AnimationColorOut))
  129. PanBack.Background = New MyColor(0, 255, 255, 255)
  130. Case Themes.Custom
  131. AnimList.Add(AaColor(Path, Shape.FillProperty, New MyColor(160, Foreground) - Path.Fill, AnimationColorOut))
  132. PanBack.Background = New MyColor(0, 255, 255, 255)
  133. End Select
  134. End If
  135. AniStart(AnimList, "MyIconButton Color " & Uuid)
  136. Else
  137. AniStop("MyIconButton Color " & Uuid)
  138. If IsEnabled Then
  139. Select Case Theme
  140. Case Themes.Color
  141. Path.SetResourceReference(Shape.FillProperty, "ColorBrush5")
  142. Case Themes.White
  143. Path.SetResourceReference(Shape.FillProperty, "ColorBrush8")
  144. Case Themes.Red
  145. Path.Fill = New MyColor(160, 255, 76, 76)
  146. Case Themes.Black
  147. Path.Fill = New MyColor(160, 0, 0, 0)
  148. Case Themes.Custom
  149. Path.Fill = New MyColor(160, Foreground)
  150. End Select
  151. Else
  152. Path.SetResourceReference(Shape.FillProperty, "ColorBrushGray5")
  153. End If
  154. PanBack.Background = New MyColor(0, 255, 255, 255)
  155. End If
  156. Catch ex As Exception
  157. Logger.Warn(ex, "刷新图标按钮动画状态出错")
  158. End Try
  159. End Sub
  160. End Class
  161. Partial Public Module ModAnimation
  162. Public Sub AniDispose(Control As MyIconButton, RemoveFromChildren As Boolean, Optional CallBack As ParameterizedThreadStart = Nothing)
  163. If Not Control.IsHitTestVisible Then Return
  164. Control.IsHitTestVisible = False
  165. AniStart({
  166. AaScaleTransform(Control, -1.5, 200,, New AniEaseInFluent),
  167. AaCode(Sub()
  168. If RemoveFromChildren Then
  169. CType(Control.Parent, Object).Children.Remove(Control)
  170. Else
  171. Control.Visibility = Visibility.Collapsed
  172. End If
  173. If CallBack IsNot Nothing Then CallBack(Control)
  174. End Sub,, True)
  175. }, "MyIconButton Dispose " & Control.Uuid)
  176. End Sub
  177. End Module