MyCompItem.xaml.vb 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. Public Class MyCompItem
  2. Public Uuid As Integer = GetUuid()
  3. #Region "Logo"
  4. Private _Logo As String = ""
  5. Public Property Logo As String
  6. Get
  7. Return _Logo
  8. End Get
  9. Set(value As String)
  10. If _Logo = value OrElse value Is Nothing Then Exit Property
  11. _Logo = value
  12. Dim FileAddress = PathTemp & "CompLogo\" & GetHash(_Logo) & ".png"
  13. Try
  14. If _Logo.ToLower.StartsWith("http") Then
  15. '网络图片
  16. If File.Exists(FileAddress) Then
  17. PathLogo.Source = New MyBitmap(FileAddress)
  18. ElseIf _Logo.ToLower.EndsWith(".webp") Then 'Modrinth 林业 Mod 使用了不支持的 WebP 格式 Logo
  19. Log($"[Comp] 发现不支持的 WebP 格式图标,已更改为默认图标:{_Logo}")
  20. PathLogo.Source = New MyBitmap("pack://application:,,,/images/Icons/NoIcon.png")
  21. Else
  22. PathLogo.Source = New MyBitmap("pack://application:,,,/images/Icons/NoIcon.png")
  23. RunInNewThread(Sub() LogoLoader(FileAddress), "Comp Logo Loader " & Uuid & "#", ThreadPriority.BelowNormal)
  24. End If
  25. Else
  26. '位图
  27. PathLogo.Source = New MyBitmap(_Logo)
  28. End If
  29. Catch ex As IOException
  30. Log(ex, "加载资源工程图标时读取失败(" & FileAddress & ")")
  31. Catch ex As ArgumentException
  32. '考虑缓存的图片本身可能有误
  33. Log(ex, "可视化资源工程图标失败(" & FileAddress & ")")
  34. Try
  35. File.Delete(FileAddress)
  36. Log("[Comp] 已清理损坏的资源工程图标:" & FileAddress)
  37. Catch exx As Exception
  38. Log(exx, "清理损坏的资源工程图标缓存失败(" & FileAddress & ")", LogLevel.Hint)
  39. End Try
  40. Catch ex As Exception
  41. Log(ex, "加载资源工程图标失败(" & value & ")")
  42. End Try
  43. End Set
  44. End Property
  45. Private Sub LogoLoader(Address As String)
  46. Dim Retry As Boolean = False
  47. Dim DownloadEnd As String = GetUuid()
  48. RetryStart:
  49. Try
  50. NetDownload(_Logo, Address & DownloadEnd)
  51. Dim LoadError As Exception = Nothing
  52. RunInUiWait(Sub()
  53. Try
  54. '在地址更换时取消加载
  55. If Not Address = PathTemp & "CompLogo\" & GetHash(_Logo) & ".png" Then Exit Sub
  56. '在完成正常加载后才保存缓存图片
  57. PathLogo.Source = New MyBitmap(Address & DownloadEnd)
  58. Catch ex As Exception
  59. Log(ex, "读取资源工程图标失败(" & Address & ")")
  60. File.Delete(Address & DownloadEnd)
  61. LoadError = ex
  62. End Try
  63. End Sub)
  64. If LoadError IsNot Nothing Then Throw LoadError
  65. If File.Exists(Address) Then
  66. File.Delete(Address & DownloadEnd)
  67. Else
  68. FileIO.FileSystem.MoveFile(Address & DownloadEnd, Address)
  69. End If
  70. Catch ex As Exception
  71. If Not Retry Then
  72. Retry = True
  73. GoTo RetryStart
  74. Else
  75. Log(ex, $"下载资源工程图标失败({_Logo})")
  76. RunInUi(Sub() PathLogo.Source = New MyBitmap("pack://application:,,,/images/Icons/NoIcon.png"))
  77. End If
  78. End Try
  79. End Sub
  80. #End Region
  81. #Region "点击"
  82. '触发点击事件
  83. Public Event Click(sender As Object, e As MouseButtonEventArgs)
  84. Private Sub Button_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonUp
  85. If IsMouseDown Then
  86. RaiseEvent Click(sender, e)
  87. If e.Handled Then Exit Sub
  88. Log("[Control] 按下资源工程列表项:" & LabTitle.Text)
  89. End If
  90. End Sub
  91. '鼠标点击判定
  92. Private IsMouseDown As Boolean = False
  93. Private Sub Button_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonDown
  94. If IsMouseOver Then IsMouseDown = True
  95. End Sub
  96. Private Sub Button_MouseLeave(sender As Object, e As Object) Handles Me.MouseLeave, Me.PreviewMouseLeftButtonUp
  97. IsMouseDown = False
  98. End Sub
  99. #End Region
  100. #Region "后加载指向背景"
  101. Private _RectBack As Border = Nothing
  102. Public ReadOnly Property RectBack As Border
  103. Get
  104. If _RectBack Is Nothing Then
  105. Dim Rect As New Border With {
  106. .Name = "RectBack",
  107. .CornerRadius = New CornerRadius(3),
  108. .RenderTransform = New ScaleTransform(0.8, 0.8),
  109. .RenderTransformOrigin = New Point(0.5, 0.5),
  110. .BorderThickness = New Thickness(GetWPFSize(1)),
  111. .SnapsToDevicePixels = True,
  112. .IsHitTestVisible = False,
  113. .Opacity = 0
  114. }
  115. Rect.SetResourceReference(Border.BackgroundProperty, "ColorBrush7")
  116. Rect.SetResourceReference(Border.BorderBrushProperty, "ColorBrush6")
  117. SetColumnSpan(Rect, 999)
  118. SetRowSpan(Rect, 999)
  119. Children.Insert(0, Rect)
  120. _RectBack = Rect
  121. '<!--<Border x:Name = "RectBack" CornerRadius="3" RenderTransformOrigin="0.5,0.5" SnapsToDevicePixels="True"
  122. 'IsHitTestVisible = "False" Opacity="0" BorderThickness="1"
  123. 'Grid.ColumnSpan = "4" Background="{DynamicResource ColorBrush7}" BorderBrush="{DynamicResource ColorBrush6}"/>-->
  124. End If
  125. Return _RectBack
  126. End Get
  127. End Property
  128. #End Region
  129. Private StateLast As String
  130. Public HasAnimation As Boolean = True
  131. Public Sub RefreshColor(sender As Object, e As EventArgs) Handles Me.MouseEnter, Me.MouseLeave, Me.MouseLeftButtonDown, Me.MouseLeftButtonUp
  132. If Not HasAnimation Then Exit Sub
  133. '判断当前颜色
  134. Dim StateNew As String, Time As Integer
  135. If IsMouseOver Then
  136. If IsMouseDown Then
  137. StateNew = "MouseDown"
  138. Time = 120
  139. Else
  140. StateNew = "MouseOver"
  141. Time = 120
  142. End If
  143. Else
  144. StateNew = "Idle"
  145. Time = 180
  146. End If
  147. If StateLast = StateNew Then Exit Sub
  148. StateLast = StateNew
  149. '触发颜色动画
  150. If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画
  151. '有动画
  152. Dim Ani As New List(Of AniData)
  153. If IsMouseOver Then
  154. Ani.AddRange({
  155. AaColor(RectBack, Border.BackgroundProperty, If(IsMouseDown, "ColorBrush6", "ColorBrushBg1"), Time),
  156. AaOpacity(RectBack, 1 - RectBack.Opacity, Time,, New AniEaseOutFluent)
  157. })
  158. If IsMouseDown Then
  159. Ani.Add(AaScaleTransform(RectBack, 0.996 - CType(RectBack.RenderTransform, ScaleTransform).ScaleX, Time * 1.2,, New AniEaseOutFluent))
  160. Else
  161. Ani.Add(AaScaleTransform(RectBack, 1 - CType(RectBack.RenderTransform, ScaleTransform).ScaleX, Time * 1.2,, New AniEaseOutFluent))
  162. End If
  163. Else
  164. Ani.AddRange({
  165. AaOpacity(RectBack, -RectBack.Opacity, Time),
  166. AaColor(RectBack, Border.BackgroundProperty, If(IsMouseDown, "ColorBrush6", "ColorBrush7"), Time),
  167. AaScaleTransform(RectBack, 0.996 - CType(RectBack.RenderTransform, ScaleTransform).ScaleX, Time,, New AniEaseOutFluent),
  168. AaScaleTransform(RectBack, -0.196, 1,,, True)
  169. })
  170. End If
  171. AniStart(Ani, "CompItem Color " & Uuid)
  172. Else
  173. '无动画
  174. AniStop("CompItem Color " & Uuid)
  175. If _RectBack IsNot Nothing Then RectBack.Opacity = 0
  176. End If
  177. End Sub
  178. '指向时扩展描述
  179. Private Sub LabInfo_MouseEnter(sender As Object, e As MouseEventArgs) Handles LabInfo.MouseEnter
  180. If IsTextTrimmed(LabInfo) Then
  181. ToolTipInfo.Content = LabInfo.Text
  182. ToolTipInfo.Width = LabInfo.ActualWidth + 25
  183. LabInfo.ToolTip = ToolTipInfo
  184. Else
  185. LabInfo.ToolTip = Nothing
  186. End If
  187. End Sub
  188. Private Function IsTextTrimmed(textBlock As TextBlock) As Boolean
  189. Dim typeface As New Typeface(textBlock.FontFamily, textBlock.FontStyle, textBlock.FontWeight, textBlock.FontStretch)
  190. Dim formattedText As New FormattedText(textBlock.Text, Thread.CurrentThread.CurrentCulture, textBlock.FlowDirection, typeface, textBlock.FontSize, textBlock.Foreground, DPI)
  191. Return formattedText.Width > textBlock.ActualWidth
  192. End Function
  193. End Class