Skip to content

Commit

Permalink
Refactor:重构下载管理页面
Browse files Browse the repository at this point in the history
重写右侧页面刷新相关操作并把它们挪到右侧页面的vb文件里
使用 Loader 作为唯一标识符 Fix #4556
对 UI 设计的修改:把下载任务失败后的错误提示从 TextBlock 改成了 MyHint
  • Loading branch information
Open-KFC committed Mar 5, 2025
1 parent 503244a commit afa0aa5
Show file tree
Hide file tree
Showing 8 changed files with 280 additions and 185 deletions.
1 change: 1 addition & 0 deletions Plain Craft Launcher 2/Application.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<local:MultiplicationConverter x:Key="MultiplicationConverter"/>
<local:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter"/>
<local:InverseBooleanConverter x:Key="InverseBooleanConverter"/>
<local:DlStateConveter x:Key="DlStateConverter" />

<!-- 颜色表 -->
<SolidColorBrush x:Key="ColorBrush1">#343d4a</SolidColorBrush>
Expand Down
25 changes: 25 additions & 0 deletions Plain Craft Launcher 2/Controls/MyDlEntry.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<local:MyCard x:Class="MyDlEntry"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PCL">
<local:MyIconButton x: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="0 10 10 0" LogoScale="1.1" HorizontalAlignment="Right" VerticalAlignment="Top" />
<ListBox x:Name="TaskListBox" ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:MyDlEntry}, Path=TaskEntries}"
Background="Transparent" BorderThickness="0" IsHitTestVisible="False" Margin="14 40 15 10">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid MinHeight="26">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0" Content="{Binding LoaderState, Converter={StaticResource DlStateConverter}}" />
<TextBlock Grid.Column="1" Text="{Binding Descreption, Mode=OneWay}" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Top" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<local:MyHint x:Name="ExceptionHint" Visibility="Collapsed" ToolTip="单击复制错误详情" Margin="14 40 15 10" />
</local:MyCard>
146 changes: 146 additions & 0 deletions Plain Craft Launcher 2/Controls/MyDlEntry.xaml.vb
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
Imports System.Collections.ObjectModel
Imports System.ComponentModel

Public Class MyDlEntry
Inherits MyCard

''' <summary>
''' 卡片中每一条子下载任务的数据模型,将Loader作为唯一标识符
''' </summary>
Public Class MyDlTaskEntry
Implements INotifyPropertyChanged

Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

Public Sub New(Loader As LoaderBase)
Me.Loader = Loader
_LoaderState = Loader.State
_Progress = Loader.Progress
_Descreption = Loader.Name
End Sub

''' <summary>
''' 检查值有无改变以及通知前端
''' </summary>
Public Sub SyncValuesToUI()
If (Not Loader.State = _LoaderState) Then
_LoaderState = Loader.State
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("LoaderState"))
End If
If (Not Loader.Progress = _Progress) Then
_Progress = Loader.Progress
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("PercentStr"))
End If
End Sub

Public Loader As LoaderBase

Private _LoaderState As LoadState
Public ReadOnly Property LoaderState As LoadState
Get
Return _LoaderState
End Get
End Property

Private _Progress As Double
Public ReadOnly Property PercentStr As String
Get
Return Math.Floor(_Progress * 100) & "%"
End Get
End Property

Private _Descreption As String
Public ReadOnly Property Descreption As String
Get
Return _Descreption
End Get
End Property
End Class

''' <summary>
''' TaskListBox的数据源
''' </summary>
Public ReadOnly Property TaskEntries As New ObservableCollection(Of MyDlTaskEntry)

Public Loader As LoaderBase

''' <summary>
''' 获取所有子下载任务
''' </summary>
Private ReadOnly Property SubDlTasks As List(Of LoaderBase)
Get
Return CType(Loader, Object).GetLoaderList()
End Get
End Property

Private _Failed As Boolean
''' <summary>
''' 是否已经失败,值发生改变时切换显示内容
''' </summary>
Private Property Failed
Get
Return _Failed
End Get
Set(value)
If value = _Failed Then Exit Property
_Failed = value
If value Then
ExceptionHint.Text = GetExceptionDetail(Loader.Error)
ExceptionHint.Visibility = Visibility.Visible
TaskListBox.Visibility = Visibility.Collapsed
Else '应该不会进到这个case里
ExceptionHint.Visibility = Visibility.Collapsed
TaskListBox.Visibility = Visibility.Visible
End If
End Set
End Property

Public Sub New(Loader As LoaderBase)
InitializeComponent()
Me.Loader = Loader
Title = Loader.Name
RefreshSubTasks()
End Sub

''' <summary>
''' 同步前端状态(是否已失败、初次调用时添加子任务显示条目、刷新子任务显示条目的信息)
''' </summary>
Public Sub RefreshSubTasks()
If Failed Then Exit Sub
Try
If Loader.State = LoadState.Failed Then
Failed = True
Else
For Each DlTask As LoaderBase In SubDlTasks
Dim TaskEntry = TaskEntries.FirstOrDefault(Function(t) t.Loader Is DlTask)
If TaskEntry Is Nothing Then '除了第一次调用之外不会进入这个case,因为LoaderCombo的子加载任务不会增加
TaskEntries.Add(New MyDlTaskEntry(DlTask))
Else
TaskEntry.SyncValuesToUI()
End If
Next
End If
Catch ex As Exception
Log(ex, "刷新下载管理显示失败", LogLevel.Feedback)
End Try
End Sub

''' <summary>
''' 点击失败提示卡片之后复制错误信息到剪贴板
''' </summary>
Private Sub CopyExceptionDetail(sender As MyHint, e As EventArgs) Handles ExceptionHint.MouseLeftButtonDown
ClipboardSet(sender.Text, False)
Hint("已复制错误详情!", HintType.Finish)
End Sub

''' <summary>
''' 点击取消按钮之后播放关闭动画、中止Loader
''' </summary>
Private Sub Cancel(sender As MyIconButton, e As EventArgs) Handles BtnCancel.Click
AniDispose(sender, False)
AniDispose(Me, True, Sub() FrmSpeedRight?.TryReturnToHome())
RunInThread(Sub() Loader.Abort())
LoaderTaskbar.Remove(Loader)
End Sub

End Class
23 changes: 23 additions & 0 deletions Plain Craft Launcher 2/Modules/Base/ModBase.vb
Original file line number Diff line number Diff line change
Expand Up @@ -3031,4 +3031,27 @@ Public Class InverseBooleanConverter
End Function
End Class

''' <summary>
''' 在MyDlEntry中使用,将LoaderState转换为一个UI元素;未实现反向转换。
''' </summary>
Public Class DlStateConveter
Implements IValueConverter
Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
If value Is Nothing OrElse TypeOf value IsNot LoadState Then Return Nothing
Select Case value
Case LoadState.Waiting
Return GetObjectFromXML("<Path xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" 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"" Fill=""{DynamicResource ColorBrush3}"" Margin=""0,7,0,0"" VerticalAlignment=""Top"" Height=""6""/>")
Case LoadState.Loading
Return GetObjectFromXML("<TextBlock xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" Text=""{Binding PercentStr, Mode=OneWay}"" Tag=""Loading"" HorizontalAlignment=""Center"" Foreground=""{DynamicResource ColorBrush3}"" />")
Case LoadState.Finished
Return GetObjectFromXML("<Path xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" 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"" Fill=""{DynamicResource ColorBrush3}"" Margin=""0,3,0,0"" VerticalAlignment=""Top""/>")
Case Else 'Failed, Aborted
Return 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"" Fill=""{DynamicResource ColorBrush3}"" Margin=""0,1,0,0"" VerticalAlignment=""Top""/>")
End Select
End Function
Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
Return LoadState.Waiting
End Function
End Class

#End Region
4 changes: 2 additions & 2 deletions Plain Craft Launcher 2/Modules/Base/ModLoader.vb
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ Restart:
Private LoaderTaskbarProgressLast As Shell.TaskbarItemProgressState = Shell.TaskbarItemProgressState.None

Public Sub LoaderTaskbarAdd(Of T)(Loader As LoaderCombo(Of T))
If FrmSpeedLeft IsNot Nothing Then FrmSpeedLeft.TaskRemove(Loader)
If FrmSpeedRight IsNot Nothing Then FrmSpeedRight.TaskRemove(Loader)
LoaderTaskbar.Add(Loader)
Log($"[Taskbar] {Loader.Name} 已加入任务列表")
End Sub
Expand All @@ -593,7 +593,7 @@ Restart:
'若单个任务已中止或全部任务已完成,则刷新并移除
For Each Task In LoaderTaskbar.ToList()
If IsAllDownloadTaskCompleted OrElse Task.State = LoadState.Aborted OrElse Task.State = LoadState.Waiting Then
If FrmSpeedLeft IsNot Nothing Then FrmSpeedLeft.TaskRefresh(Task)
If FrmSpeedRight IsNot Nothing Then FrmSpeedRight.TaskRefresh(Task)
LoaderTaskbar.Remove(Task)
Log($"[Taskbar] {Task.Name} 已移出任务列表")
End If
Expand Down
Loading

0 comments on commit afa0aa5

Please sign in to comment.