MyIconButton.xaml.vb 9.6 KB

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