PageSpeedLeft.xaml.vb 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. Public Class PageSpeedLeft
  2. Private Const WatcherInterval As Integer = 300
  3. '初始化
  4. Private IsLoad As Boolean = False
  5. Private Sub Page_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
  6. '进入时就刷新一次显示
  7. Watcher()
  8. '如果在页面切换动画的 “上一页消失” 部分已经完成了下载,就直接尝试返回
  9. TryReturnToHome()
  10. If IsLoad Then Return
  11. IsLoad = True
  12. '监控定时器
  13. Dim timer As New Threading.DispatcherTimer With {.Interval = New TimeSpan(0, 0, 0, 0, WatcherInterval)}
  14. AddHandler timer.Tick, AddressOf Watcher
  15. timer.Start()
  16. '非调试模式隐藏线程数
  17. If Not ModeDebug Then
  18. RowDefinitions(12).Height = New GridLength(0)
  19. RowDefinitions(13).Height = New GridLength(0)
  20. RowDefinitions(14).Height = New GridLength(0)
  21. RowDefinitions(15).Height = New GridLength(0)
  22. End If
  23. End Sub
  24. '定时器任务
  25. Private ReadOnly RightCards As New Dictionary(Of String, MyCard)
  26. Private Sub Watcher()
  27. If Not FrmMain.PageCurrent = FormMain.PageType.TaskManager Then Return
  28. Try
  29. #Region "更新左边栏"
  30. If Not LoaderTaskbar.Any() Then
  31. '无任务
  32. LabProgress.Text = "100 %"
  33. LabSpeed.Text = "0 B/s"
  34. LabFile.Text = "0"
  35. LabThread.Text = "0 / " & NetTaskThreadLimit
  36. Else
  37. '有任务,输出基本信息
  38. Dim Tasks = LoaderTaskbar.Where(Function(l) l.Show).ToList() '筛选掉启动 MC 的任务(#6270)
  39. Dim RawPercent As Double = If(Tasks.Any, Tasks.Select(Function(l) l.Progress).Average().Clamp(0, 1), 1)
  40. Dim PredictText As String = Math.Floor(RawPercent * 100) & "." & Math.Floor((RawPercent * 100 - Math.Floor(RawPercent * 100)) * 100).ToString.EnsureLength("0", 2) & " %"
  41. LabProgress.Text = If(RawPercent > 0.999999, "100 %", PredictText)
  42. LabSpeed.Text = StringUtils.FormatByteSize(NetManager.Speed) & "/s"
  43. LabFile.Text = If(NetManager.FileRemain < 0, "0*", NetManager.FileRemain)
  44. LabThread.Text = NetTaskThreadCount & " / " & NetTaskThreadLimit
  45. End If
  46. #End Region
  47. Catch ex As Exception
  48. Logger.Error(ex, "任务管理左栏监视出错")
  49. End Try
  50. If FrmSpeedRight Is Nothing OrElse FrmSpeedRight.PanMain Is Nothing Then Return
  51. Try
  52. For Each Loader In LoaderTaskbar.ToList
  53. TaskRefresh(Loader)
  54. Next
  55. Catch ex As Exception
  56. Logger.Error(ex, "任务管理右栏监视出错")
  57. End Try
  58. End Sub
  59. Public Sub TaskRefresh(Loader As LoaderBase)
  60. If Loader Is Nothing OrElse Not Loader.Show Then Return
  61. Try
  62. '获取实际加载器列表
  63. Dim LoaderList As List(Of LoaderBase) = CType(Loader, Object).GetLoaderList()
  64. If RightCards.ContainsKey(Loader.Name) Then
  65. '已有此卡片
  66. Dim Card As Grid = RightCards(Loader.Name)
  67. Dim NewValue As Double = Loader.Progress + Loader.State
  68. If Val(Card.Tag) = NewValue Then Return
  69. Card.Tag = NewValue
  70. If Card.Children.Count <= 3 Then
  71. Logger.Warn($"元素不足的卡片:{Loader.Name}")
  72. Return
  73. End If
  74. Card = Card.Children(3)
  75. Try
  76. Select Case Loader.State
  77. Case LoadState.Failed
  78. #Region "失败,更新卡片"
  79. Card.RowDefinitions.Clear()
  80. Card.Children.Clear()
  81. Card.Children.Add(GetObjectFromXML("<Path xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" Stretch=""Uniform"" Tag=""Failed"" Data=""F1 M2.5,0 L0,2.5 7.5,10 0,17.5 2.5,20 10,12.5 17.5,20 20,17.5 12.5,10 20,2.5 17.5,0 10,7.5 2.5,0Z"" Height=""15"" Width=""15"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""0"" Fill=""{DynamicResource ColorBrush3}"" Margin=""0,1,0,0"" VerticalAlignment=""Top""/>"))
  82. Dim Tb As TextBlock = GetObjectFromXML("<TextBlock xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" TextWrapping=""Wrap"" HorizontalAlignment=""Left"" ToolTip=""单击复制错误详情"" Grid.Column=""1"" Grid.Row=""0"" Margin=""0,0,0,5"" />")
  83. Tb.Text = Loader.Error.GetDisplay(True)
  84. AddHandler Tb.MouseLeftButtonDown,
  85. Sub(sender As TextBlock, e As EventArgs)
  86. ClipboardSet(sender.Text, False)
  87. Hint("已复制错误详情!", HintType.Green)
  88. End Sub
  89. Card.Children.Add(Tb)
  90. #End Region
  91. Case LoadState.Finished, LoadState.Canceled
  92. #Region "完成或中断,销毁卡片并返回"
  93. AniDispose(CType(Card.Parent, MyCard), True, AddressOf TryReturnToHome)
  94. #End Region
  95. Case LoadState.Loading, LoadState.Waiting
  96. #Region "进度不同,更新卡片"
  97. Try
  98. If Card.Children.Count < LoaderList.Count * 2 Then
  99. Logger.Warn($"刷新任务管理卡片 {Loader.Name} 失败:卡片中仅有 {Card.Children.Count} 个子项,要求至少有 {LoaderList.Count * 2} 个子项")
  100. Exit Try
  101. End If
  102. Dim Row As Integer = 0
  103. For Each SubTask In LoaderList
  104. Select Case SubTask.State
  105. Case LoadState.Waiting
  106. If CType(Card.Children(Row * 2), FrameworkElement).Tag <> "Waiting" Then
  107. Card.Children.RemoveAt(Row * 2)
  108. Card.Children.Insert(Row * 2, GetObjectFromXML("<Path xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:local=""clr-namespace:PCL;assembly=Plain Craft Launcher 2"" Stretch=""Uniform"" Tag=""Waiting"" Data=""F1 M5,0 a5,5 360 1 0 0,0.0001 m15,0 a5,5 360 1 0 0,0.0001 m15,0 a5,5 360 1 0 0,0.0001 Z"" Width=""18"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""" & Row & """ Fill=""{DynamicResource ColorBrush3}"" Margin=""0,7,0,0"" VerticalAlignment=""Top"" Height=""6""/>"))
  109. End If
  110. Case LoadState.Loading
  111. If CType(Card.Children(Row * 2), FrameworkElement).Tag <> "Loading" Then
  112. Card.Children.RemoveAt(Row * 2)
  113. Card.Children.Insert(Row * 2, GetObjectFromXML("<TextBlock xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:local=""clr-namespace:PCL;assembly=Plain Craft Launcher 2"" Text=""" & Math.Floor(SubTask.Progress * 100) & "%"" Tag=""Loading"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""" & Row & """ Foreground=""{DynamicResource ColorBrush3}""/>"))
  114. Else
  115. CType(Card.Children(Row * 2), TextBlock).Text = Math.Floor(SubTask.Progress * 100) & "%"
  116. End If
  117. Case LoadState.Finished
  118. If CType(Card.Children(Row * 2), FrameworkElement).Tag <> "Finished" Then
  119. Card.Children.RemoveAt(Row * 2)
  120. Card.Children.Insert(Row * 2, GetObjectFromXML("<Path xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:local=""clr-namespace:PCL;assembly=Plain Craft Launcher 2"" Stretch=""Uniform"" Tag=""Finished"" Data=""F1 M 23.7501,33.25L 34.8334,44.3333L 52.2499,22.1668L 56.9999,26.9168L 34.8334,53.8333L 19.0001,38L 23.7501,33.25 Z"" Height=""16"" Width=""15"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""" & Row & """ Fill=""{DynamicResource ColorBrush3}"" Margin=""0,3,0,0"" VerticalAlignment=""Top""/>"))
  121. End If
  122. End Select
  123. Row += 1
  124. Next
  125. Catch ex As Exception
  126. Logger.Error(ex, $"刷新任务管理卡片 {Loader.Name} 失败")
  127. End Try
  128. #End Region
  129. End Select
  130. Catch ex As Exception
  131. Logger.Error(ex, $"更新任务管理显示失败({Loader.State})")
  132. End Try
  133. ElseIf Not (Loader.State = LoadState.Canceled OrElse Loader.State = LoadState.Finished) Then
  134. Try
  135. #Region "没有卡片且未中断或完成,添加新的卡片"
  136. Dim CardXAML As String = "
  137. <local:MyCard xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:local=""clr-namespace:PCL;assembly=Plain Craft Launcher 2""
  138. Tag=""" & (Loader.Progress + Loader.State) & """ Title=""" & StringUtils.XmlEscape(Loader.Name) & """ Margin=""0,0,0,15"">
  139. <Grid Margin=""14,40,15,10"">
  140. <Grid.ColumnDefinitions>
  141. <ColumnDefinition Width=""50""/>
  142. <ColumnDefinition/>
  143. </Grid.ColumnDefinitions>
  144. <Grid.RowDefinitions>"
  145. For Each SubTask In LoaderList
  146. CardXAML += "<RowDefinition Height=""26""/>"
  147. Next
  148. CardXAML += "</Grid.RowDefinitions>"
  149. Dim Row As Integer = 0
  150. For Each SubTask In LoaderList
  151. Select Case SubTask.State
  152. Case LoadState.Waiting
  153. CardXAML += "<Path Stretch=""Uniform"" Tag=""Waiting"" Data=""F1 M5,0 a5,5 360 1 0 0,0.0001 m15,0 a5,5 360 1 0 0,0.0001 m15,0 a5,5 360 1 0 0,0.0001 Z"" Width=""18"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""" & Row & """ Fill=""{DynamicResource ColorBrush3}"" Margin=""0,7,0,0"" VerticalAlignment=""Top"" Height=""6""/>"
  154. Case LoadState.Loading
  155. CardXAML += "<TextBlock Text=""" & Math.Floor(SubTask.Progress * 100) & "%"" Tag=""Loading"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""" & Row & """ Foreground=""{DynamicResource ColorBrush3}"" />"
  156. Case LoadState.Finished
  157. CardXAML += "<Path Stretch=""Uniform"" Tag=""Finished"" Data=""F1 M 23.7501,33.25L 34.8334,44.3333L 52.2499,22.1668L 56.9999,26.9168L 34.8334,53.8333L 19.0001,38L 23.7501,33.25 Z"" Height=""16"" Width=""15"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""" & Row & """ Fill=""{DynamicResource ColorBrush3}"" Margin=""0,3,0,0"" VerticalAlignment=""Top""/>"
  158. Case Else
  159. CardXAML += "<Path Stretch=""Uniform"" Tag=""Failed"" Data=""F1 M2.5,0 L0,2.5 7.5,10 0,17.5 2.5,20 10,12.5 17.5,20 20,17.5 12.5,10 20,2.5 17.5,0 10,7.5 2.5,0Z"" Height=""15"" Width=""15"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""" & Row & """ Fill=""{DynamicResource ColorBrush3}"" Margin=""0,1,0,0"" VerticalAlignment=""Top""/>"
  160. End Select
  161. CardXAML += "<TextBlock Text=""" & StringUtils.XmlEscape(SubTask.Name) & """ HorizontalAlignment=""Left"" Grid.Column=""1"" Grid.Row=""" & Row & """/>"
  162. Row += 1
  163. Next
  164. CardXAML += "</Grid></local:MyCard>"
  165. '实例化控件
  166. Dim Card As MyCard
  167. Try
  168. Card = GetObjectFromXML(CardXAML)
  169. Catch ex As Exception
  170. Logger.Warn(ex, "新建任务管理卡片失败")
  171. Logger.Info($"出错的卡片内容:{vbCrLf}{CardXAML}")
  172. Throw
  173. End Try
  174. FrmSpeedRight.PanMain.Children.Insert(0, Card)
  175. RightCards.Add(Loader.Name, Card)
  176. Logger.Info($"新建任务管理卡片:{Loader.Name}")
  177. '添加取消按钮
  178. Dim Cancel As New MyIconButton With {.Name = "BtnCancel", .Logo = "F1 M2,0 L0,2 8,10 0,18 2,20 10,12 18,20 20,18 12,10 20,2 18,0 10,8 2,0Z", .Height = 20, .Margin = New Thickness(0, 10, 10, 0), .LogoScale = 1.1, .HorizontalAlignment = HorizontalAlignment.Right, .VerticalAlignment = VerticalAlignment.Top}
  179. Card.Children.Add(Cancel)
  180. AddHandler Cancel.Click,
  181. Sub(sender As MyIconButton, e As EventArgs)
  182. AniDispose(sender, False)
  183. AniDispose(Card, True, Sub() If FrmSpeedRight.PanMain.Children.Count = 0 AndAlso FrmMain.PageCurrent = FormMain.PageType.TaskManager Then FrmMain.PageBack())
  184. RightCards.Remove(Loader.Name)
  185. LoaderTaskbar.Remove(Loader)
  186. Logger.Info($"关闭任务管理卡片:{Loader.Name},且移出任务列表")
  187. RunInThread(Sub() Loader.Cancel())
  188. End Sub
  189. '如果已经失败,再刷新一次,修改成失败的控件
  190. If Loader.State = LoadState.Failed Then
  191. Card.Tag = Nothing '避免重复导致刷新无效
  192. TaskRefresh(Loader)
  193. End If
  194. #End Region
  195. Catch ex As Exception
  196. Logger.Error(ex, "添加任务管理卡片失败")
  197. End Try
  198. End If
  199. Catch ex As Exception
  200. Logger.Error(ex, "刷新任务管理显示失败")
  201. End Try
  202. End Sub
  203. Public Sub TaskRemove(Loader As Object)
  204. If RightCards.ContainsKey(Loader.Name) Then
  205. RunInUiWait(
  206. Sub()
  207. '移除已有的卡片
  208. Dim Card As Grid = RightCards(Loader.Name)
  209. FrmSpeedRight.PanMain.Children.Remove(Card)
  210. RightCards.Remove(Loader.Name)
  211. Logger.Info($"移除任务管理卡片:{Loader.Name}")
  212. End Sub)
  213. End If
  214. End Sub
  215. ''' <summary>
  216. ''' 若没有任务,尝试返回主页。
  217. ''' </summary>
  218. Private Sub TryReturnToHome()
  219. If FrmSpeedRight.PanMain.Children.Count = 0 AndAlso FrmMain.PageCurrent = FormMain.PageType.TaskManager Then
  220. FrmMain.PageBack()
  221. End If
  222. End Sub
  223. End Class