MyLocalModItem.xaml.vb 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. Imports System.Windows.Forms
  2. Public Class MyLocalModItem
  3. #Region "基础属性"
  4. Public Uuid As Integer = GetUuid()
  5. '标题
  6. Private _Title As String
  7. Public Property Title As String
  8. Get
  9. Return _Title
  10. End Get
  11. Set(value As String)
  12. Dim RawValue = value
  13. Select Case Entry.State
  14. Case McMod.McModState.Fine
  15. LabTitle.TextDecorations = Nothing
  16. Case McMod.McModState.Disabled
  17. LabTitle.TextDecorations = TextDecorations.Strikethrough
  18. End Select
  19. If LabTitle.Text = value Then Return
  20. LabTitle.Text = value
  21. _Title = RawValue
  22. End Set
  23. End Property
  24. '副标题
  25. Public Property SubTitle As String
  26. Get
  27. Return If(LabSubtitle?.Text, "")
  28. End Get
  29. Set(value As String)
  30. If LabSubtitle.Text = value Then Return
  31. LabSubtitle.Text = value
  32. LabSubtitle.Visibility = If(value = "", Visibility.Collapsed, Visibility.Visible)
  33. End Set
  34. End Property
  35. '描述
  36. Public Property Description As String
  37. Get
  38. Return LabInfo.Text
  39. End Get
  40. Set(value As String)
  41. If LabInfo.Text = value Then Return
  42. LabInfo.Text = value
  43. End Set
  44. End Property
  45. 'Tag
  46. Public WriteOnly Property Tags As List(Of String)
  47. Set(Tags As List(Of String))
  48. PanTags.Children.Clear()
  49. PanTags.Visibility = If(Tags.Any(), Visibility.Visible, Visibility.Collapsed)
  50. For Each TagText In Tags
  51. Dim BorderTag As New Border With {
  52. .Background = New MyColor("#0A000000"), .Padding = New Thickness(3, 1, 3, 1), .CornerRadius = New CornerRadius(3),
  53. .Margin = New Thickness(0, 0, 3, 0), .SnapsToDevicePixels = True, .UseLayoutRounding = False}
  54. Dim LabTag As New TextBlock With {
  55. .Text = TagText, .Foreground = New MyColor("#B0B0B0"), .FontSize = 11}
  56. BorderTag.Child = LabTag
  57. PanTags.Children.Add(BorderTag)
  58. Next
  59. End Set
  60. End Property
  61. '相关联的 Mod
  62. Public Property Entry As McMod
  63. Get
  64. Return Tag
  65. End Get
  66. Set(value As McMod)
  67. Tag = value
  68. End Set
  69. End Property
  70. #End Region
  71. #Region "点击与勾选"
  72. '触发点击事件
  73. Public Event Click(sender As Object, e As MouseButtonEventArgs)
  74. Private Sub Button_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonUp
  75. If IsMouseDown Then
  76. RaiseEvent Click(sender, e)
  77. If e.Handled Then Return
  78. Log("[Control] 按下本地 Mod 列表项:" & LabTitle.Text)
  79. End If
  80. End Sub
  81. '鼠标点击判定
  82. Private IsMouseDown As Boolean = False
  83. Private Sub Button_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonDown
  84. If Not IsMouseDirectlyOver Then Return
  85. IsMouseDown = True
  86. If ButtonStack IsNot Nothing Then ButtonStack.IsHitTestVisible = False
  87. End Sub
  88. Private Sub Button_MouseLeave(sender As Object, e As Object) Handles Me.MouseLeave, Me.PreviewMouseLeftButtonUp
  89. IsMouseDown = False
  90. If ButtonStack IsNot Nothing Then ButtonStack.IsHitTestVisible = True
  91. End Sub
  92. '滑动选中
  93. Private Shared SwipeStart As Integer, SwipeEnd As Integer
  94. Private Shared _Swiping As Boolean = False
  95. Private Shared Property Swiping As Boolean
  96. Get
  97. Return _Swiping
  98. End Get
  99. Set(value As Boolean)
  100. _Swiping = value
  101. FrmInstanceMod.CardSelect.IsHitTestVisible = Not value
  102. End Set
  103. End Property
  104. Private Shared SwipToState As Boolean '被滑动到的目标应将 Checked 改为此值
  105. Private Sub Button_MouseSwipeStart(sender As Object, e As Object) Handles Me.MouseLeftButtonDown
  106. If Parent Is Nothing Then Return 'Mod 可能已被删除(#3824)
  107. '开始滑动
  108. Dim Index = CType(Parent, StackPanel).Children.IndexOf(Me)
  109. SwipeStart = Index
  110. SwipeEnd = Index
  111. Swiping = True
  112. SwipToState = Not Checked
  113. End Sub
  114. Private Sub Button_MouseSwipe(sender As Object, e As Object) Handles Me.MouseEnter, Me.MouseLeave, Me.MouseLeftButtonUp
  115. If Parent Is Nothing Then Return 'Mod 可能已被删除(#3824)
  116. '结束滑动
  117. If Mouse.LeftButton <> MouseButtonState.Pressed OrElse
  118. TypeOf Mouse.DirectlyOver IsNot MyLocalModItem Then '#5771
  119. Swiping = False
  120. Return
  121. End If
  122. '计算滑动范围
  123. Dim Elements = CType(Parent, StackPanel).Children
  124. Dim Index As Integer = Elements.IndexOf(Me)
  125. SwipeStart = MathClamp(Math.Min(SwipeStart, Index), 0, Elements.Count - 1)
  126. SwipeEnd = MathClamp(Math.Max(SwipeEnd, Index), 0, Elements.Count - 1)
  127. '勾选所有范围中的项
  128. If SwipeStart = SwipeEnd Then Return
  129. For i = SwipeStart To SwipeEnd
  130. Dim Item As MyLocalModItem = Elements(i)
  131. Item.InitLate(Item, e)
  132. Item.Checked = SwipToState
  133. Next
  134. End Sub
  135. '勾选状态
  136. Public Event Check(sender As Object, e As RouteEventArgs)
  137. Public Event Changed(sender As Object, e As RouteEventArgs)
  138. Private _Checked As Boolean = False
  139. Public Property Checked As Boolean
  140. Get
  141. Return _Checked
  142. End Get
  143. Set(value As Boolean)
  144. Try
  145. '触发属性值修改
  146. Dim RawValue = _Checked
  147. If value = _Checked Then Return
  148. _Checked = value
  149. Dim ChangedEventArgs As New RouteEventArgs(False)
  150. If IsInitialized Then
  151. RaiseEvent Changed(Me, ChangedEventArgs)
  152. If ChangedEventArgs.Handled Then
  153. _Checked = RawValue
  154. Return
  155. End If
  156. End If
  157. If value Then
  158. Dim CheckEventArgs As New RouteEventArgs(False)
  159. RaiseEvent Check(Me, CheckEventArgs)
  160. If CheckEventArgs.Handled Then Return
  161. End If
  162. '更改动画
  163. If IsVisibleInForm() Then
  164. Dim Anim As New List(Of AniData)
  165. If Checked Then
  166. '由无变有
  167. Dim Delta = 32 - RectCheck.ActualHeight
  168. Anim.Add(AaHeight(RectCheck, Delta * 0.4, 200,, New AniEaseOutFluent(AniEasePower.Weak)))
  169. Anim.Add(AaHeight(RectCheck, Delta * 0.6, 300,, New AniEaseOutBack(AniEasePower.Weak)))
  170. Anim.Add(AaOpacity(RectCheck, 1 - RectCheck.Opacity, 30))
  171. RectCheck.VerticalAlignment = VerticalAlignment.Center
  172. RectCheck.Margin = New Thickness(-3, 0, 0, 0)
  173. Anim.Add(AaColor(LabTitle, TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush2", "ColorBrush5"), 200))
  174. Else
  175. '由有变无
  176. Anim.Add(AaHeight(RectCheck, -RectCheck.ActualHeight, 120,, New AniEaseInFluent(AniEasePower.Weak)))
  177. Anim.Add(AaOpacity(RectCheck, -RectCheck.Opacity, 70, 40))
  178. RectCheck.VerticalAlignment = VerticalAlignment.Center
  179. Anim.Add(AaColor(LabTitle, TextBlock.ForegroundProperty, If(LabTitle.TextDecorations Is Nothing, "ColorBrush1", "ColorBrushGray4"), 120))
  180. End If
  181. AniStart(Anim, "MyLocalModItem Checked " & Uuid)
  182. Else
  183. '不在窗口上时直接设置
  184. RectCheck.VerticalAlignment = VerticalAlignment.Center
  185. RectCheck.Margin = New Thickness(-3, 0, 0, 0)
  186. If Checked Then
  187. RectCheck.Height = 32
  188. RectCheck.Opacity = 1
  189. LabTitle.SetResourceReference(TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush2", "ColorBrush5"))
  190. Else
  191. RectCheck.Height = 0
  192. RectCheck.Opacity = 0
  193. LabTitle.SetResourceReference(TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush1", "ColorBrushGray4"))
  194. End If
  195. AniStop("MyLocalModItem Checked " & Uuid)
  196. End If
  197. Catch ex As Exception
  198. Log(ex, "设置 Checked 失败")
  199. End Try
  200. End Set
  201. End Property
  202. #End Region
  203. #Region "后加载内容"
  204. '右下角状态指示图标
  205. Private ImgState As Image
  206. '指向背景
  207. Private _RectBack As Border = Nothing
  208. Public ReadOnly Property RectBack As Border
  209. Get
  210. If _RectBack Is Nothing Then
  211. Dim Rect As New Border With {
  212. .Name = "RectBack",
  213. .CornerRadius = New CornerRadius(3),
  214. .RenderTransform = New ScaleTransform(0.8, 0.8),
  215. .RenderTransformOrigin = New Point(0.5, 0.5),
  216. .BorderThickness = New Thickness(GetWPFSize(1)),
  217. .SnapsToDevicePixels = True,
  218. .IsHitTestVisible = False,
  219. .Opacity = 0
  220. }
  221. Rect.SetResourceReference(Border.BackgroundProperty, "ColorBrush7")
  222. Rect.SetResourceReference(Border.BorderBrushProperty, "ColorBrush6")
  223. SetColumnSpan(Rect, 999)
  224. SetRowSpan(Rect, 999)
  225. Children.Insert(0, Rect)
  226. _RectBack = Rect
  227. '<!--<Border x:Name = "RectBack" CornerRadius="3" RenderTransformOrigin="0.5,0.5" SnapsToDevicePixels="True"
  228. 'IsHitTestVisible = "False" Opacity="0" BorderThickness="1"
  229. 'Grid.ColumnSpan = "4" Background="{DynamicResource ColorBrush7}" BorderBrush="{DynamicResource ColorBrush6}"/>-->
  230. End If
  231. Return _RectBack
  232. End Get
  233. End Property
  234. '按钮
  235. Public ButtonHandler As Action(Of MyLocalModItem, EventArgs)
  236. Public ButtonStack As FrameworkElement
  237. Private _Buttons As IEnumerable(Of MyIconButton)
  238. Public Property Buttons As IEnumerable(Of MyIconButton)
  239. Get
  240. Return _Buttons
  241. End Get
  242. Set(value As IEnumerable(Of MyIconButton))
  243. _Buttons = value
  244. '移除原 Stack
  245. If ButtonStack IsNot Nothing Then
  246. Children.Remove(ButtonStack)
  247. ButtonStack = Nothing
  248. End If
  249. If Not value.Any() Then Return
  250. '添加新 Stack
  251. ButtonStack = New StackPanel With {.Opacity = 0, .Margin = New Thickness(0, 0, 5, 0), .SnapsToDevicePixels = False, .Orientation = Orientation.Horizontal,
  252. .HorizontalAlignment = HorizontalAlignment.Right, .VerticalAlignment = VerticalAlignment.Center, .UseLayoutRounding = False}
  253. SetColumnSpan(ButtonStack, 10) : SetRowSpan(ButtonStack, 10)
  254. '构造按钮
  255. For Each Btn As MyIconButton In value
  256. If Btn.Height.Equals(Double.NaN) Then Btn.Height = 25
  257. If Btn.Width.Equals(Double.NaN) Then Btn.Width = 25
  258. CType(ButtonStack, StackPanel).Children.Add(Btn)
  259. Next
  260. Children.Add(ButtonStack)
  261. End Set
  262. End Property
  263. '勾选条
  264. Private _RectCheck As Border
  265. Public ReadOnly Property RectCheck As Border
  266. Get
  267. If _RectCheck Is Nothing Then
  268. _RectCheck = New Border With {.Width = 5, .Height = If(Checked, Double.NaN, 0), .CornerRadius = New CornerRadius(2, 2, 2, 2),
  269. .VerticalAlignment = If(Checked, VerticalAlignment.Stretch, VerticalAlignment.Center),
  270. .HorizontalAlignment = HorizontalAlignment.Left, .UseLayoutRounding = False, .SnapsToDevicePixels = False,
  271. .Margin = If(Checked, New Thickness(-3, 6, 0, 6), New Thickness(-3, 0, 0, 0))}
  272. _RectCheck.SetResourceReference(Border.BackgroundProperty, "ColorBrush3")
  273. SetRowSpan(_RectCheck, 10)
  274. Children.Add(_RectCheck)
  275. End If
  276. Return _RectCheck
  277. End Get
  278. End Property
  279. #End Region
  280. Private Function GetUpdateCompareDescription() As String
  281. Dim CurrentName = If(Entry.CompFile.Version, Entry.CompFile.DisplayName).Replace(".jar", "")
  282. Dim NewestName = If(Entry.UpdateFile.Version, Entry.UpdateFile.DisplayName).Replace(".jar", "")
  283. '简化名称对比
  284. Dim CurrentSegs = CurrentName.Split("-_+ ".ToCharArray).ToList()
  285. Dim NewestSegs = NewestName.Split("-_+ ".ToCharArray).ToList()
  286. Dim Shortened As Boolean = False
  287. For Each Seg In CurrentSegs.ToList()
  288. If Not NewestSegs.Contains(Seg) Then Continue For
  289. CurrentSegs.Remove(Seg)
  290. NewestSegs.Remove(Seg)
  291. Shortened = True
  292. Next
  293. If Shortened AndAlso CurrentSegs.Any() AndAlso NewestSegs.Any() Then
  294. CurrentName = Join(CurrentSegs, "-")
  295. NewestName = Join(NewestSegs, "-")
  296. Entry._Version = CurrentName '使用网络信息作为显示的版本号
  297. End If
  298. Return $"当前版本:{CurrentName}({GetTimeSpanString(Entry.CompFile.ReleaseDate - Date.Now, False)}){vbCrLf}最新版本:{NewestName}({GetTimeSpanString(Entry.UpdateFile.ReleaseDate - Date.Now, False)})"
  299. End Function
  300. '懒加载
  301. Public Sub New()
  302. InitializeComponent()
  303. OnFirstEnterScrollViewerViewport(AddressOf FirstEnterScrollViewerViewport)
  304. End Sub
  305. Private HasEnteredViewport As Boolean = False
  306. Private Sub FirstEnterScrollViewerViewport()
  307. HasEnteredViewport = True
  308. Refresh()
  309. End Sub
  310. Public Sub Refresh()
  311. If Not HasEnteredViewport Then Return '避免在未显示时因为 Comp 更新而加载内容
  312. '更新
  313. If Entry.CanUpdate Then
  314. BtnUpdate.Visibility = Visibility.Visible
  315. BtnUpdate.ToolTip = $"{GetUpdateCompareDescription()}{vbCrLf}点击以更新,右键查看更新日志。"
  316. Else
  317. BtnUpdate.Visibility = Visibility.Collapsed
  318. End If
  319. '标题与描述
  320. Dim DescFileName As String
  321. If Entry.State = McMod.McModState.Fine OrElse Entry.State = McMod.McModState.Disabled Then
  322. DescFileName = IO.Path.GetFileNameWithoutExtension(Entry.Path)
  323. Else
  324. DescFileName = GetFileNameFromPath(Entry.Path)
  325. End If
  326. Dim NewDescription As String
  327. If Setup.Get("ToolModLocalNameStyle") = 1 Then
  328. '标题显示文件名,详情显示译名
  329. '标题
  330. Title = DescFileName
  331. SubTitle = ""
  332. '描述
  333. If Entry.Comp Is Nothing Then
  334. NewDescription = Entry.DisplayName
  335. Else
  336. Dim Titles = Entry.Comp.GetControlTitle(False)
  337. NewDescription = Titles.Key & Titles.Value
  338. End If
  339. NewDescription = NewDescription.Replace(" | ", " / ")
  340. If Entry.Version IsNot Nothing Then NewDescription &= $" ({Entry.Version})"
  341. Else
  342. '标题显示译名,详情显示文件名
  343. '标题
  344. If Entry.Comp Is Nothing Then
  345. Title = Entry.DisplayName
  346. SubTitle = If(Entry.Version Is Nothing, "", " | " & Entry.Version)
  347. Else
  348. Dim Titles = Entry.Comp.GetControlTitle(False)
  349. Title = Titles.Key
  350. SubTitle = Titles.Value & If(Entry.Version Is Nothing, "", " | " & Entry.Version)
  351. End If
  352. '描述
  353. NewDescription = DescFileName
  354. End If
  355. If Entry.Comp IsNot Nothing Then
  356. NewDescription += ": " & Entry.Comp.Description.Replace(vbCr, "").Replace(vbLf, "")
  357. ElseIf Entry.Description IsNot Nothing Then
  358. NewDescription += ": " & Entry.Description.Replace(vbCr, "").Replace(vbLf, "")
  359. End If
  360. Description = NewDescription
  361. If Checked Then
  362. LabTitle.SetResourceReference(TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush2", "ColorBrush5"))
  363. Else
  364. LabTitle.SetResourceReference(TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush1", "ColorBrushGray4"))
  365. End If
  366. '主 Logo
  367. If Entry.Comp IsNot Nothing Then
  368. Entry.Comp.ApplyLogoToMyImage(PathLogo)
  369. Else
  370. PathLogo.Source = PathImage & "Icons/NoIcon.png"
  371. End If
  372. '图标右下角的 Logo
  373. If Entry.State = McMod.McModState.Fine Then
  374. If ImgState IsNot Nothing Then
  375. Children.Remove(ImgState)
  376. ImgState = Nothing
  377. End If
  378. Else
  379. If ImgState Is Nothing Then
  380. ImgState = New Image With {
  381. .Width = 20, .Height = 20, .Margin = New Thickness(0, 0, -5, -3), .IsHitTestVisible = False,
  382. .HorizontalAlignment = HorizontalAlignment.Right, .VerticalAlignment = VerticalAlignment.Bottom
  383. }
  384. RenderOptions.SetBitmapScalingMode(ImgState, BitmapScalingMode.HighQuality)
  385. SetColumn(ImgState, 1) : SetRow(ImgState, 1) : SetRowSpan(ImgState, 2)
  386. Children.Add(ImgState)
  387. '<Image x:Name="ImgState" RenderOptions.BitmapScalingMode="HighQuality" Width="16" Height="16" Margin="0,0,-3,-1"
  388. ' Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" IsHitTestVisible="False"
  389. ' HorizontalAlignment="Right" VerticalAlignment="Bottom"
  390. ' Source="/Images/Icons/Unavailable.png" />
  391. End If
  392. ImgState.Source = New MyBitmap(PathImage & $"Icons/{Entry.State}.png")
  393. End If
  394. '标签
  395. If Entry.Comp IsNot Nothing Then Tags = Entry.Comp.Tags
  396. End Sub
  397. Public Sub RefreshColor(sender As Object, e As EventArgs) Handles Me.MouseEnter, Me.MouseLeave, Me.MouseLeftButtonDown, Me.MouseLeftButtonUp, Me.Changed
  398. InitLate(sender, e)
  399. '触发颜色动画
  400. Dim Time As Integer = If(IsMouseOver, 120, 180)
  401. Dim Ani As New List(Of AniData)
  402. 'ButtonStack
  403. If ButtonStack IsNot Nothing Then
  404. If IsMouseOver Then
  405. Ani.Add(AaOpacity(ButtonStack, 1 - ButtonStack.Opacity, Time * 0.7, Time * 0.3))
  406. Ani.Add(AaDouble(Sub(i) ColumnPaddingRight.Width = New GridLength(Math.Max(0, ColumnPaddingRight.Width.Value + i)),
  407. 5 + Buttons.Count * 25 - ColumnPaddingRight.Width.Value, Time * 0.3, Time * 0.7))
  408. Else
  409. Ani.Add(AaOpacity(ButtonStack, -ButtonStack.Opacity, Time * 0.4))
  410. Ani.Add(AaDouble(Sub(i) ColumnPaddingRight.Width = New GridLength(Math.Max(0, ColumnPaddingRight.Width.Value + i)),
  411. 4 - ColumnPaddingRight.Width.Value, Time * 0.4))
  412. End If
  413. End If
  414. 'RectBack
  415. If IsMouseOver OrElse Checked Then
  416. Ani.AddRange({
  417. AaColor(RectBack, Border.BackgroundProperty, If(IsMouseDown, "ColorBrush6", "ColorBrushBg1"), Time),
  418. AaOpacity(RectBack, 1 - RectBack.Opacity, Time,, New AniEaseOutFluent)
  419. })
  420. If IsMouseDown Then
  421. Ani.Add(AaScaleTransform(RectBack, 0.996 - CType(RectBack.RenderTransform, ScaleTransform).ScaleX, Time * 1.2,, New AniEaseOutFluent))
  422. Else
  423. Ani.Add(AaScaleTransform(RectBack, 1 - CType(RectBack.RenderTransform, ScaleTransform).ScaleX, Time * 1.2,, New AniEaseOutFluent))
  424. End If
  425. Else
  426. Ani.AddRange({
  427. AaOpacity(RectBack, -RectBack.Opacity, Time),
  428. AaScaleTransform(RectBack, 0.996 - CType(RectBack.RenderTransform, ScaleTransform).ScaleX, Time,, New AniEaseOutFluent),
  429. AaScaleTransform(RectBack, -0.196, 1,,, True)
  430. })
  431. End If
  432. AniStart(Ani, "LocalModItem Color " & Uuid)
  433. End Sub
  434. '触发虚拟化内容
  435. Private Sub InitLate(sender As Object, e As EventArgs)
  436. If ButtonHandler IsNot Nothing Then
  437. ButtonHandler(sender, e)
  438. ButtonHandler = Nothing
  439. End If
  440. End Sub
  441. '显示更新日志
  442. Private Sub BtnUpdate_PreviewMouseRightButtonUp(sender As Object, e As MouseButtonEventArgs) Handles BtnUpdate.PreviewMouseRightButtonUp
  443. e.Handled = True
  444. ShowUpdateLog()
  445. End Sub
  446. Private Sub ShowUpdateLog()
  447. Dim CurseForgeUrl As String = Entry.ChangelogUrls.FirstOrDefault(Function(x) x.Contains("curseforge.com"))
  448. Dim ModrinthUrl As String = Entry.ChangelogUrls.FirstOrDefault(Function(x) x.Contains("modrinth.com"))
  449. If CurseForgeUrl Is Nothing OrElse ModrinthUrl Is Nothing Then
  450. OpenWebsite(Entry.ChangelogUrls.First)
  451. Else
  452. Select Case MyMsgBox("要在哪个网站上查看更新日志?", "查看更新日志", "Modrinth", "CurseForge", "取消")
  453. Case 1
  454. OpenWebsite(ModrinthUrl)
  455. Case 2
  456. OpenWebsite(CurseForgeUrl)
  457. End Select
  458. End If
  459. End Sub
  460. '触发更新
  461. Private Sub BtnUpdate_Click(sender As Object, e As EventArgs) Handles BtnUpdate.Click
  462. Select Case MyMsgBox($"是否要更新 {Entry.DisplayName}?{vbCrLf}{vbCrLf}{GetUpdateCompareDescription()}", "Mod 更新确认", "更新", "查看更新日志", "取消")
  463. Case 1 '更新
  464. FrmInstanceMod.UpdateMods({Entry})
  465. Case 2 '查看更新日志
  466. ShowUpdateLog()
  467. Case 3 '取消
  468. End Select
  469. End Sub
  470. '自适应(#4465)
  471. Private Sub PanTitle_SizeChanged() Handles PanTitle.SizeChanged
  472. '0:全部舒展:Auto - Auto - (Auto) - 1*
  473. '1:压缩 Subtitle:Auto - 1* - (Auto) - 0
  474. '2:继续压缩 Title:1* - 0 - (Auto) - 0
  475. Dim CurrentCompressLevel As Integer =
  476. If(ColumnExtend.Width.IsStar, 0, If(ColumnTitle.Width.IsStar, 2, 1)) 'Subtitle 可能是 Collapsed
  477. Dim NewCompressLevel As Integer
  478. Select Case CurrentCompressLevel
  479. Case 0
  480. If ColumnExtend.ActualWidth < 0.5 Then
  481. NewCompressLevel = If(LabSubtitle.Visibility = Visibility.Collapsed, 2, 1)
  482. Else
  483. Return
  484. End If
  485. Case 1
  486. If ColumnSubtitle.ActualWidth < 0.5 Then
  487. NewCompressLevel = 2
  488. ElseIf Not LabSubtitle.IsTextTrimmed Then
  489. NewCompressLevel = 0
  490. Else
  491. Return
  492. End If
  493. Case 2
  494. If Not LabTitle.IsTextTrimmed Then
  495. NewCompressLevel = If(LabSubtitle.Visibility = Visibility.Collapsed, 0, 1)
  496. Else
  497. Return
  498. End If
  499. End Select
  500. Select Case NewCompressLevel
  501. Case 0
  502. '全部舒展:Auto - Auto - (Auto) - 1*
  503. ColumnTitle.Width = GridLength.Auto
  504. ColumnSubtitle.Width = GridLength.Auto
  505. ColumnExtend.Width = New GridLength(1, GridUnitType.Star)
  506. Case 1
  507. '压缩 Subtitle:Auto - 1* - (Auto) - 0
  508. ColumnTitle.Width = GridLength.Auto
  509. ColumnSubtitle.Width = New GridLength(1, GridUnitType.Star)
  510. ColumnExtend.Width = New GridLength(0, GridUnitType.Pixel)
  511. Case 2
  512. '继续压缩 Title:1* - 0 - (Auto) - 0
  513. ColumnTitle.Width = New GridLength(1, GridUnitType.Star)
  514. ColumnSubtitle.Width = New GridLength(0, GridUnitType.Pixel)
  515. ColumnExtend.Width = New GridLength(0, GridUnitType.Pixel)
  516. End Select
  517. End Sub
  518. End Class