PageSpeedLeft.xaml.vb 16 KB

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