2026-02-24 13:19:21 +08:00

385 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AiSportsMicrospaceDB.DBContext;
using AiSportsMicrospaceDB.Entities;
using Common;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System.Diagnostics;
using System.IO;
using System.Net.NetworkInformation;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using Views.JumpLong;
using Views.JumpRope;
using Views.SquatFu;
using Wpf_AiSportsMicrospace.Common;
using Wpf_AiSportsMicrospace.Enum;
using Wpf_AiSportsMicrospace.MyUserControl;
using Wpf_AiSportsMicrospace.Views;
using Wpf_AiSportsMicrospace.Views.JumpRope;
using Yztob.AiSports.Inferences.Things;
namespace Wpf_AiSportsMicrospace
{
/// <summary>
/// Home.xaml 的交互逻辑
/// </summary>
public partial class Home : UserControl
{
public static Uri loadingImage = new Uri("pack://application:,,,/Resources/Img/Album/1.gif");
public static Uri countDownGif = new Uri("pack://application:,,,/Resources/Img/gif/time_3.gif");
private int _adminClickCount = 0;
private readonly DispatcherTimer _resetTimer;
private Main _mainWin => Application.Current.MainWindow as Main;
public Home()
{
InitializeComponent();
// 初始化隐藏按钮点击计数重置定时器(3 秒无操作则重置计数)
_resetTimer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(3)
};
_resetTimer.Tick += (s, e) =>
{
_adminClickCount = 0;
_resetTimer.Stop();
};
// --------------------- CoverFlow 加载 ---------------------
coverFlow.Images.Add(new CoverFlowItem
{
ImageUri = GetResourceUri("test_img/test_rope.png"),
ProgressColor1 = "#215bc7",
ProgressColor2 = "#fc640e"
});
coverFlow.Images.Add(new CoverFlowItem
{
ImageUri = GetResourceUri("play_img/play_music.png"),
ProgressColor1 = "#e73d42",
ProgressColor2 = "#fd8212"
});
coverFlow.Images.Add(new CoverFlowItem
{
ImageUri = GetResourceUri("Album/home_history.png"),
ProgressColor1 = "#e73d42",
ProgressColor2 = "#215bc7"
});
// 默认选中第3张
coverFlow.SelectedIndex = 0;
Loaded += Window_Loaded;
Unloaded += Home_Unloaded;
Load_Base();
Utils.PlayBackgroundMusic("homeprojectselected.mp3", true);
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
_mainWin.HumanFrameUpdated += OnHumanFrameUpdated;
if (_mainWin.WebcamClient == null)
{
//HandyControl.Controls.MessageBox.Show("摄像头网络异常,请重新连接!");
return;
}
_mainWin.WebcamClient.StartExtract();
Utils.PreloadGifs();
}
private void Home_Unloaded(object sender, RoutedEventArgs e)
{
_mainWin.HumanFrameUpdated -= OnHumanFrameUpdated;
}
private bool IsGestureActive = true; // 标记手势识别是否有效
private void OnHumanFrameUpdated(object sender, List<Human> humans)
{
if (!IsGestureActive) return; // 手势识别已停止,直接返回
var human = humans.FirstOrDefault();
if (human == null) return;
// 检测挥手动作
var wavingaction = _mainWin.SportOperate.VerifyRightWavingAction(humans);
switch (wavingaction)
{
case (int)WavingAction.LeftWave: // 左手挥动
Application.Current.Dispatcher.BeginInvoke(() => coverFlow.SlideRight());
break;
case (int)WavingAction.RightWave: // 右手挥动
Application.Current.Dispatcher.BeginInvoke(() => coverFlow.SlideLeft());
break;
case (int)WavingAction.FirstHand: // 举手开始
Application.Current.Dispatcher.BeginInvoke(() => coverFlow.StartSelectedProgress());
break;
case (int)WavingAction.Raising: // 举手中,实时更新进度
break;
case (int)WavingAction.RaiseHand: // 举手完成
coverFlow.ProgressCompleted += CoverFlow_ProgressCompleted;
// 设置标记,停止后续手势识别
IsGestureActive = false;
break;
default: // 没有动作 → 取消进度
Application.Current.Dispatcher.BeginInvoke(() => coverFlow.CancelSelectedProgress());
break;
}
}
private void CoverFlow_ProgressCompleted(CoverFlowItem item)
{
// 停止抽帧线程/释放资源
try
{
//_mainWin.HumanFrameUpdated -= OnHumanFrameUpdated;
//_mainWin.WebcamClient.StopExtract();
RouterGoNew();
}
catch (Exception ex)
{
Debug.WriteLine($"停止抽帧异常: {ex.Message}");
}
}
//测试点击
private void GoNew(object sender, MouseButtonEventArgs e)
{
RouterGoNew();
}
//跳转二级页面
private void RouterGoNew()
{
// 跳转逻辑(如导航到新页面并传递参数)
// 例如:RaiseEvent、调用外部委托、或使用导航框架
var mainWin = Application.Current.MainWindow as Main;
if (coverFlow.SelectedIndex == 0)
{
var newPage = new GroupJumpRope();
//mainWin?.SwitchPageWithMaskAnimation(newPage, true);
//var newPage = new BambooDragonfly();
//var newPage = new WhackAMole();
mainWin?.SwitchPageWithMaskAnimation(newPage, true);
}
else if (coverFlow.SelectedIndex == 1)
{
var newPage = new MusicJumpRope();
mainWin?.SwitchPageWithMaskAnimation(newPage, true);
}
else
{
//var newPage = new TrainingRecords();
//var newPage = new WhackAMole();
var newPage = new StandingLeap();
mainWin?.SwitchPageWithMaskAnimation(newPage, true);
}
}
private void Image_MouseDown(object sender, MouseButtonEventArgs e)
{
var mainWin = Application.Current.MainWindow as Main;
mainWin!.ShowCountDownAnimation();
}
// 隐藏按钮点击处理:连续点击五次显示内嵌密码弹窗
private void HiddenAdminButton_Click(object sender, RoutedEventArgs e)
{
_adminClickCount++;
// 每次点击重启计时器
_resetTimer.Stop();
_resetTimer.Start();
if (_adminClickCount >= 5)
{
_resetTimer.Stop();
_adminClickCount = 0;
// 显示内嵌密码弹窗
AdminPasswordBox.Password = string.Empty;
AdminDialogGrid.Visibility = Visibility.Visible;
AdminPasswordBox.Focus();
}
}
// 密码弹窗:确定按钮
private void AdminOkButton_Click(object sender, RoutedEventArgs e)
{
var entered = AdminPasswordBox.Password ?? string.Empty;
if (entered == "8888")
{
AdminDialogGrid.Visibility = Visibility.Collapsed;
// 密码正确,打开管理员页面(已有 AdminWindow 或按需改为导航)
try
{
SetDialogGrid.Visibility = Visibility.Visible;
//var adminWin = new Views.AdminWindow();
//adminWin.Owner = Window.GetWindow(this);
//adminWin.Show();
}
catch (Exception ex)
{
MessageBox.Show("密码正确");
Debug.WriteLine($"打开管理员页面异常: {ex.Message}");
}
}
else
{
MessageBox.Show("密码错误", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
AdminPasswordBox.Password = string.Empty;
AdminPasswordBox.Focus();
}
}
// 密码弹窗:取消按钮
private void AdminCancelButton_Click(object sender, RoutedEventArgs e)
{
AdminDialogGrid.Visibility = Visibility.Collapsed;
}
// 在 PasswordBox 按 Enter 等同于确定,按 Esc 等同于取消
private void AdminPasswordBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
AdminOkButton_Click(sender, e);
e.Handled = true;
}
else if (e.Key == Key.Escape)
{
AdminCancelButton_Click(sender, e);
e.Handled = true;
}
}
private void SetCancelButton_Click(object sender, RoutedEventArgs e)
{
SetDialogGrid.Visibility = Visibility.Collapsed;
}
//加载配置
private async void Load_Base()
{
var app = (App)Application.Current;
using var scope = App.AppHost.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var baseData = await db.BasicConfig.FirstOrDefaultAsync(x => x.Code == AppSettings.Code);
if (baseData == null)
{
baseData = new BasicConfig { Code = AppSettings.Code, Host = host.Text, UserName = name.Text, Password = password.Text , HomeWidth = int.Parse(homeWidth.Text)};
db.BasicConfig.Add(baseData);
db.SaveChanges();
}
else
{
host.Text = baseData.Host;
name.Text = baseData.UserName;
password.Text = baseData.Password;
homeWidth.Text = baseData.HomeWidth.ToString();
}
}
//保存基本配置
private async void SetOkButton_Click(object sender, RoutedEventArgs e)
{
var app = (App)Application.Current;
using var scope = App.AppHost.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var baseData = await db.BasicConfig.FirstOrDefaultAsync(x => x.Code == AppSettings.Code);
if (baseData == null)
{
db.BasicConfig.Add(new BasicConfig
{
Code = AppSettings.Code,
Host = host.Text,
UserName = name.Text,
Password = password.Text,
HomeWidth = int.Parse(homeWidth.Text)
});
}
else
{
baseData.Host = host.Text;
baseData.UserName = name.Text;
baseData.Password = password.Text;
baseData.HomeWidth = int.Parse(homeWidth.Text);
db.BasicConfig.Update(baseData);
}
db.SaveChanges();
HandyControl.Controls.MessageBox.Show("保存成功!", "提示");
SetDialogGrid.Visibility = Visibility.Collapsed;
}
//多人跳绳
private void GoRopeSet(object sender, RoutedEventArgs e)
{
//var app = (App)Application.Current;
//using var scope = App.AppHost.Services.CreateScope();
//var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
//var mainWindow = new MainWindow(db);
//mainWindow.Show();
var mainWin = Application.Current.MainWindow as Main;
mainWin.SwitchPageWithMaskAnimation(new MultiJumpRope(), true);
}
//跳远
private void GoLongSet(object sender, RoutedEventArgs e)
{
var mainWin = Application.Current.MainWindow as Main;
mainWin.SwitchPageWithMaskAnimation(new LongSttting(), true);
}
private void Ping_Click(object sender, RoutedEventArgs e)
{
//var config = _context.BasicConfig.FirstOrDefault();
//if (config != null)
//{
// //var ip = config.Ip;
//}
var host = this.host.Text.Trim();
if (string.IsNullOrWhiteSpace(host))
{
this.ShowError("相机主机地址/IP不能为空。");
return;
}
var pinger = new Ping();
var reply = pinger.Send(host, 10);
if (reply.Status == IPStatus.Success)
this.ShowInformation("与相机通信正常。");
else
this.ShowError($"与相机通信失败,错误:{reply.Status}。");
}
// 辅助方法:获取资源绝对 Uri,兼容 Debug 和 发布
private static Uri GetResourceUri(string relativePath)
{
string baseDir = AppContext.BaseDirectory;
// 发布目录下路径
string fullPath = Path.Combine(baseDir, "Resources", "Img", relativePath.Replace("/", Path.DirectorySeparatorChar.ToString()));
if (!File.Exists(fullPath))
{
#if DEBUG
// Debug 下 fallback 到项目根目录
string projectRoot = Path.Combine(baseDir, @"..\..\..");
fullPath = Path.Combine(projectRoot, "Resources", "Img", relativePath.Replace("/", Path.DirectorySeparatorChar.ToString()));
#endif
}
return new Uri(fullPath, UriKind.Absolute);
}
}
}