Merge branch 'master' of http://git.51dayu.com.cn/diamond-cut/SparkClient
commit
caac05598b
11 changed files with 483 additions and 330 deletions
@ -0,0 +1,300 @@ |
|||||||
|
using System.IO; |
||||||
|
using System.Windows.Input; |
||||||
|
using System.Windows.Media; |
||||||
|
using System.Windows.Media.Imaging; |
||||||
|
using SparkClient.Model.Common; |
||||||
|
using SparkClient.Model.Helper; |
||||||
|
using SparkClient.Model.Services; |
||||||
|
using SparkClient.Views.Dialog; |
||||||
|
|
||||||
|
namespace SparkClient.ViewModel.Grading; |
||||||
|
|
||||||
|
public class GradingLoadingVM : BaseViewModel,IDisposable |
||||||
|
{ |
||||||
|
private double _progress; |
||||||
|
private SOCClientService _socClientService; |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// 进度 |
||||||
|
/// </summary> |
||||||
|
public double Progress |
||||||
|
{ |
||||||
|
get => _progress; |
||||||
|
set |
||||||
|
{ |
||||||
|
_progress = value; |
||||||
|
OnPropertyChanged(nameof(Progress)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public ICommand StopCommand { get; } |
||||||
|
|
||||||
|
private string _diamondCode; |
||||||
|
|
||||||
|
private string _diamnondType; |
||||||
|
|
||||||
|
private bool _disposed; |
||||||
|
|
||||||
|
private CancellationTokenSource _progressCts; |
||||||
|
private CancellationTokenSource? _playbackCts; |
||||||
|
#region 图片播放控制 |
||||||
|
private PlayStatus _currentStatus = PlayStatus.Stopped; |
||||||
|
public PlayStatus CurrentStatus |
||||||
|
{ |
||||||
|
get => _currentStatus; |
||||||
|
set |
||||||
|
{ |
||||||
|
_currentStatus = value; |
||||||
|
OnPropertyChanged(nameof(CurrentStatus)); |
||||||
|
OnPropertyChanged(nameof(ButtonText)); // 状态变更时更新按钮文本 |
||||||
|
} |
||||||
|
} |
||||||
|
public string ButtonText => CurrentStatus switch |
||||||
|
{ |
||||||
|
PlayStatus.Playing => "暂停", |
||||||
|
PlayStatus.Paused => "继续", |
||||||
|
_ => "重播" // Stopped 状态 |
||||||
|
}; |
||||||
|
private CancellationTokenSource _cts; |
||||||
|
private int _playDelay = 200; // 默认播放速度 |
||||||
|
|
||||||
|
public ICommand PlayControlCommand { get; } |
||||||
|
public ICommand PreviousCommand { get; } |
||||||
|
public ICommand NextCommand { get; } |
||||||
|
|
||||||
|
private int _currentIndex; |
||||||
|
public int CurrentIndex |
||||||
|
{ |
||||||
|
get => _currentIndex; |
||||||
|
set |
||||||
|
{ |
||||||
|
_currentIndex = value; |
||||||
|
OnPropertyChanged(nameof(CurrentIndex)); |
||||||
|
UpdateCurrentImage(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public string[] ImagePaths { get; set; } |
||||||
|
public ImageSource CurrentImage { get; private set; } |
||||||
|
|
||||||
|
public bool ImageIsEnable { get; private set; } |
||||||
|
|
||||||
|
#endregion |
||||||
|
|
||||||
|
public GradingLoadingVM(string diamnondType, string diamondCode) |
||||||
|
{ |
||||||
|
_diamondCode = diamondCode; |
||||||
|
_diamnondType = diamnondType; |
||||||
|
StopCommand = new RelayCommand(Stop); |
||||||
|
PlayControlCommand = new RelayCommand(async _ => await HandlePlayControl()); |
||||||
|
PreviousCommand = new RelayCommand(_ => MovePrevious()); |
||||||
|
NextCommand = new RelayCommand(_ => MoveNext()); |
||||||
|
ImageIsEnable = false; |
||||||
|
|
||||||
|
_progressCts = new CancellationTokenSource(); |
||||||
|
_playbackCts = new CancellationTokenSource(); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// 开始检测 |
||||||
|
/// </summary> |
||||||
|
public async Task<int> Start() |
||||||
|
{ |
||||||
|
//开始显示进度条 |
||||||
|
//切工仪通讯 拉取图片 延时...5秒 |
||||||
|
//播放图片 |
||||||
|
//图片拉取完毕---| |
||||||
|
// var configValue = ConfigurationHelper.ReadConfigValue("ProgressTime"); |
||||||
|
// int iProgTime = int.TryParse(configValue, out var result) ? result : 50000; |
||||||
|
// int stepTime = iProgTime / 97; |
||||||
|
// |
||||||
|
// for (int i = 0; i <= 97; i++) |
||||||
|
// { |
||||||
|
// _progressCts.Token.ThrowIfCancellationRequested(); |
||||||
|
// Progress = i; |
||||||
|
// await Task.Delay(stepTime, _progressCts.Token); |
||||||
|
// } |
||||||
|
var progress = RunProgressAsync(_progressCts.Token); |
||||||
|
|
||||||
|
_socClientService = new SOCClientService(); |
||||||
|
var processImage = _socClientService.ProcessImageCollectionAsync(); |
||||||
|
//通知页面可以播放图片 |
||||||
|
await processImage; |
||||||
|
|
||||||
|
if (!"ok".Equals(processImage.Result.Status)) |
||||||
|
{ |
||||||
|
_progressCts.Cancel(); |
||||||
|
new MessageBox().Show(MultilingualHelper.getString(StatusCodes.GetConstantNameByValue(processImage.Result.Status))); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
LoadImages(processImage.Result.Images); |
||||||
|
ImageIsEnable = true; |
||||||
|
|
||||||
|
await progress; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
private void Stop(object param) |
||||||
|
{ |
||||||
|
//询问?停止:忽略 |
||||||
|
} |
||||||
|
|
||||||
|
private async Task RunProgressAsync(CancellationToken token) |
||||||
|
{ |
||||||
|
var configValue = ConfigurationHelper.ReadConfigValue("ProgressTime"); |
||||||
|
int totalDuration = int.TryParse(configValue, out var result) ? result : 50000; |
||||||
|
int stepTime = totalDuration / 97; |
||||||
|
|
||||||
|
// 使用 IProgress 实现线程安全的进度报告 |
||||||
|
var progress = new Progress<double>(value => |
||||||
|
{ |
||||||
|
if (!token.IsCancellationRequested) |
||||||
|
Progress = value; |
||||||
|
}); |
||||||
|
|
||||||
|
await Task.Run(async () => |
||||||
|
{ |
||||||
|
for (int i = 0; i <= 97; i++) |
||||||
|
{ |
||||||
|
token.ThrowIfCancellationRequested(); |
||||||
|
|
||||||
|
// 报告进度 |
||||||
|
((IProgress<double>)progress).Report(i); |
||||||
|
|
||||||
|
// 使用可取消的延迟 |
||||||
|
await Task.Delay(stepTime, token); |
||||||
|
} |
||||||
|
}, token); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void Dispose() |
||||||
|
{ |
||||||
|
Dispose(true); |
||||||
|
GC.SuppressFinalize(this); |
||||||
|
} |
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing) |
||||||
|
{ |
||||||
|
if (_disposed) return; |
||||||
|
|
||||||
|
if (disposing) |
||||||
|
{ |
||||||
|
// 取消所有操作 |
||||||
|
_progressCts?.Cancel(); |
||||||
|
_playbackCts?.Cancel(); |
||||||
|
|
||||||
|
// 释放托管资源 |
||||||
|
_progressCts?.Dispose(); |
||||||
|
_playbackCts?.Dispose(); |
||||||
|
} |
||||||
|
|
||||||
|
_disposed = true; |
||||||
|
} |
||||||
|
|
||||||
|
#region 图片播放处理 |
||||||
|
|
||||||
|
public void LoadImages(string folderPath) |
||||||
|
{ |
||||||
|
ImagePaths = Directory.GetFiles(folderPath, "*.bmp"); |
||||||
|
CurrentIndex = 0; |
||||||
|
CurrentStatus = PlayStatus.Stopped; |
||||||
|
} |
||||||
|
public void LoadImages(List<string> folderPath) |
||||||
|
{ |
||||||
|
ImagePaths = folderPath.ToArray(); |
||||||
|
CurrentIndex = 0; |
||||||
|
CurrentStatus = PlayStatus.Stopped; |
||||||
|
} |
||||||
|
private async Task HandlePlayControl() |
||||||
|
{ |
||||||
|
switch (CurrentStatus) |
||||||
|
{ |
||||||
|
case PlayStatus.Stopped: |
||||||
|
await StartPlayback(); // 开始或重播 |
||||||
|
break; |
||||||
|
case PlayStatus.Playing: |
||||||
|
PausePlayback(); // 暂停 |
||||||
|
break; |
||||||
|
case PlayStatus.Paused: |
||||||
|
await ResumePlayback();// 继续 |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
private async Task StartPlayback() |
||||||
|
{ |
||||||
|
CurrentStatus = PlayStatus.Playing; |
||||||
|
_cts = new CancellationTokenSource(); |
||||||
|
|
||||||
|
try |
||||||
|
{ |
||||||
|
for (CurrentIndex = 0; CurrentIndex < ImagePaths.Length; CurrentIndex++) |
||||||
|
{ |
||||||
|
if (_cts.Token.IsCancellationRequested) break; |
||||||
|
await Task.Delay(_playDelay); |
||||||
|
} |
||||||
|
|
||||||
|
// 播放完成处理 |
||||||
|
if (CurrentIndex >= ImagePaths.Length) |
||||||
|
{ |
||||||
|
CurrentStatus = PlayStatus.Stopped; |
||||||
|
CurrentIndex = 0; // 重置为初始位置 |
||||||
|
} |
||||||
|
} |
||||||
|
catch (TaskCanceledException) { /* 正常取消处理 */ } |
||||||
|
} |
||||||
|
|
||||||
|
private void PausePlayback() |
||||||
|
{ |
||||||
|
_cts?.Cancel(); |
||||||
|
CurrentStatus = PlayStatus.Paused; |
||||||
|
} |
||||||
|
|
||||||
|
private async Task ResumePlayback() |
||||||
|
{ |
||||||
|
CurrentStatus = PlayStatus.Playing; |
||||||
|
_cts = new CancellationTokenSource(); |
||||||
|
await StartPlayback(); |
||||||
|
} |
||||||
|
private void UpdateCurrentImage() |
||||||
|
{ |
||||||
|
if (ImagePaths == null || CurrentIndex < 0 || CurrentIndex >= ImagePaths.Length) |
||||||
|
return; |
||||||
|
|
||||||
|
var bitmap = new BitmapImage(); |
||||||
|
bitmap.BeginInit(); |
||||||
|
bitmap.CacheOption = BitmapCacheOption.OnLoad; |
||||||
|
bitmap.UriSource = new Uri(ImagePaths[CurrentIndex]); |
||||||
|
bitmap.EndInit(); |
||||||
|
bitmap.Freeze(); // 确保跨线程安全 |
||||||
|
|
||||||
|
CurrentImage = bitmap; |
||||||
|
OnPropertyChanged(nameof(CurrentImage)); |
||||||
|
} |
||||||
|
|
||||||
|
private void MovePrevious() |
||||||
|
{ |
||||||
|
if (CurrentStatus == PlayStatus.Playing) |
||||||
|
PausePlayback(); |
||||||
|
|
||||||
|
CurrentIndex = (CurrentIndex - 1 + ImagePaths.Length) % ImagePaths.Length; |
||||||
|
} |
||||||
|
|
||||||
|
private void MoveNext() |
||||||
|
{ |
||||||
|
if (CurrentStatus == PlayStatus.Playing) |
||||||
|
PausePlayback(); |
||||||
|
|
||||||
|
CurrentIndex = (CurrentIndex + 1) % ImagePaths.Length; |
||||||
|
} |
||||||
|
#endregion |
||||||
|
} |
||||||
|
public enum PlayStatus |
||||||
|
{ |
||||||
|
Stopped, // 初始/停止状态 |
||||||
|
Playing, // 播放中 |
||||||
|
Paused // 暂停中 |
||||||
|
} |
Loading…
Reference in new issue