DCS/ruiyiweiUX/Assets/Scripts/Views/TimeSettingPanel.cs

454 lines
15 KiB
C#
Raw Permalink 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 UnityEngine;
using UnityEngine.UI;
using TMPro;
using System;
/// <summary>
/// 时间设置面板
/// 提供系统时间调节功能
/// </summary>
public class TimeSettingPanel : BasePanel
{
[Header("时间显示")]
public TextMeshProUGUI CurrentTimeText;
public TextMeshProUGUI DateDisplayText;
[Header("日期设置")]
public TMP_Dropdown YearDropdown;
public TMP_Dropdown MonthDropdown;
public TMP_Dropdown DayDropdown;
[Header("时间设置")]
public TMP_Dropdown HourDropdown;
public TMP_Dropdown MinuteDropdown;
public TMP_Dropdown SecondDropdown;
[Header("快捷按钮")]
public Button SyncNetworkTimeButton;
public Button ResetToNowButton;
[Header("控制按钮")]
public Button HomeButton;
public Button ConfirmButton;
public Button BackButton;
private SettingsViewModel _vm;
private DateTime _tempDateTime;
private DateTime _baseConfigTime; // 配置的基准时间
private DateTime _baseRealTime; // 真实的基准时间
private bool _configTimeSet = false; // 是否已设置基准时间
public override void Init()
{
_vm = new SettingsViewModel();
// 从 TimeUpdateComponent 获取当前正在显示的时间
var mainPanel = UIManager.Instance.GetPanel<MainPanel>();
if (mainPanel != null && mainPanel.TimeUpdater != null)
{
// 直接使用 TimeUpdateComponent 的当前显示时间,确保完全同步
_tempDateTime = mainPanel.TimeUpdater.GetCurrentDisplayTime();
_baseConfigTime = _tempDateTime;
_baseRealTime = DateTime.Now;
_configTimeSet = true;
Debug.Log($"TimeSettingPanel: 从TimeUpdateComponent获取当前显示时间: {_tempDateTime:yyyy-MM-dd HH:mm:ss}");
}
else
{
// 备用方案:使用配置时间或系统时间
DateTime configTime = _vm.SystemTime;
if (configTime == DateTime.MinValue)
{
_tempDateTime = DateTime.Now;
}
else
{
_tempDateTime = configTime;
}
_baseConfigTime = _tempDateTime;
_baseRealTime = DateTime.Now;
_configTimeSet = true;
Debug.Log($"TimeSettingPanel: TimeUpdateComponent不可用使用备用时间: {_tempDateTime:yyyy-MM-dd HH:mm:ss}");
}
InitializeUI();
PopulateDropdowns();
UpdateTimeDisplay();
// 每秒更新时间显示和下拉框(让时间持续流动)
InvokeRepeating(nameof(UpdateCurrentTimeDisplay), 0f, 1f);
InvokeRepeating(nameof(UpdateDisplayedTime), 1f, 1f);
}
private void InitializeUI()
{
// 下拉框事件监听
if (YearDropdown != null) YearDropdown.onValueChanged.AddListener(OnYearOrMonthChanged);
if (MonthDropdown != null) MonthDropdown.onValueChanged.AddListener(OnYearOrMonthChanged);
if (DayDropdown != null) DayDropdown.onValueChanged.AddListener(OnDayChanged);
if (HourDropdown != null) HourDropdown.onValueChanged.AddListener(OnTimeChanged);
if (MinuteDropdown != null) MinuteDropdown.onValueChanged.AddListener(OnTimeChanged);
if (SecondDropdown != null) SecondDropdown.onValueChanged.AddListener(OnTimeChanged);
// 快捷按钮
// if (SyncNetworkTimeButton != null)
// SyncNetworkTimeButton.onClick.AddListener(SyncWithNetworkTime);
if (ResetToNowButton != null)
ResetToNowButton.onClick.AddListener(ResetToCurrentTime);
// 控制按钮
if (HomeButton != null)
{
HomeButton.onClick.AddListener(() =>
{
ConfirmDialog.Show("确认", "是否返回主界面?", () =>
{
ReturnToHome();
});
});
}
if (ConfirmButton != null)
{
ConfirmButton.onClick.AddListener(ApplyAndBack);
}
if (BackButton != null)
{
BackButton.onClick.AddListener(() =>
ConfirmDialog.Show("确认", "是否返回设置界面?", () =>
{
ClosePanel();
ClosePanel();
})
);
}
}
private void PopulateDropdowns()
{
_isRefreshingDropdowns = true; // 防止触发事件
// 年份下拉框 (当前年份前后10年)
if (YearDropdown != null)
{
YearDropdown.options.Clear();
int currentYear = DateTime.Now.Year;
for (int year = currentYear - 10; year <= currentYear + 10; year++)
{
YearDropdown.options.Add(new TMP_Dropdown.OptionData(year.ToString()));
}
// 先设置value这样PopulateDayDropdown能读取到正确的年份
YearDropdown.SetValueWithoutNotify(_tempDateTime.Year - (currentYear - 10));
YearDropdown.RefreshShownValue();
}
// 月份下拉框
if (MonthDropdown != null)
{
MonthDropdown.options.Clear();
for (int month = 1; month <= 12; month++)
{
MonthDropdown.options.Add(new TMP_Dropdown.OptionData(month.ToString("00")));
}
// 先设置value这样PopulateDayDropdown能读取到正确的月份
MonthDropdown.SetValueWithoutNotify(_tempDateTime.Month - 1);
MonthDropdown.RefreshShownValue();
}
// 日期下拉框(现在能正确读取年月了)
PopulateDayDropdown();
// 小时下拉框
if (HourDropdown != null)
{
HourDropdown.options.Clear();
for (int hour = 0; hour < 24; hour++)
{
HourDropdown.options.Add(new TMP_Dropdown.OptionData(hour.ToString("00")));
}
HourDropdown.SetValueWithoutNotify(_tempDateTime.Hour);
HourDropdown.RefreshShownValue();
}
// 分钟下拉框
if (MinuteDropdown != null)
{
MinuteDropdown.options.Clear();
for (int minute = 0; minute < 60; minute++)
{
MinuteDropdown.options.Add(new TMP_Dropdown.OptionData(minute.ToString("00")));
}
MinuteDropdown.SetValueWithoutNotify(_tempDateTime.Minute);
MinuteDropdown.RefreshShownValue();
}
// 秒钟下拉框
if (SecondDropdown != null)
{
SecondDropdown.options.Clear();
for (int second = 0; second < 60; second++)
{
SecondDropdown.options.Add(new TMP_Dropdown.OptionData(second.ToString("00")));
}
SecondDropdown.SetValueWithoutNotify(_tempDateTime.Second);
SecondDropdown.RefreshShownValue();
}
_isRefreshingDropdowns = false;
}
private void PopulateDayDropdown()
{
if (DayDropdown == null) return;
// 保存当前选择的日期从1开始
int currentDay = _tempDateTime.Day;
DayDropdown.options.Clear();
// 获取当前选择的年月,计算该月的天数
int year = GetSelectedYear();
int month = GetSelectedMonth();
int daysInMonth = DateTime.DaysInMonth(year, month);
for (int day = 1; day <= daysInMonth; day++)
{
DayDropdown.options.Add(new TMP_Dropdown.OptionData(day.ToString("00")));
}
// 设置当前选择的日期,确保不超过该月的最大天数
int selectedDay = Mathf.Min(currentDay, daysInMonth);
// 重要设置value时不触发事件然后手动刷新显示
DayDropdown.SetValueWithoutNotify(selectedDay - 1);
DayDropdown.RefreshShownValue();
// 更新_tempDateTime以反映可能的日期调整例如从31号变为30号
if (currentDay != selectedDay)
{
_tempDateTime = new DateTime(year, month, selectedDay,
_tempDateTime.Hour, _tempDateTime.Minute, _tempDateTime.Second);
}
}
private int GetSelectedYear()
{
if (YearDropdown == null) return DateTime.Now.Year;
int currentYear = DateTime.Now.Year;
return currentYear - 10 + YearDropdown.value;
}
private int GetSelectedMonth()
{
if (MonthDropdown == null) return DateTime.Now.Month;
return MonthDropdown.value + 1;
}
private bool _isRefreshingDropdowns = false;
private void OnYearOrMonthChanged(int value)
{
// 防止下拉框更新时触发循环调用
if (_isRefreshingDropdowns) return;
_isRefreshingDropdowns = true;
// 当年份或月份改变时,需要重新填充日期下拉框
PopulateDayDropdown();
_isRefreshingDropdowns = false;
UpdateTempDateTime();
}
private void OnDayChanged(int value)
{
// 防止下拉框更新时触发循环调用
if (_isRefreshingDropdowns) return;
// 日期改变时只需要更新_tempDateTime不需要重新填充下拉框
UpdateTempDateTime();
}
private void OnTimeChanged(int value)
{
UpdateTempDateTime();
}
private void UpdateTempDateTime()
{
try
{
int year = GetSelectedYear();
int month = GetSelectedMonth();
int day = DayDropdown != null ? DayDropdown.value + 1 : 1;
int hour = HourDropdown != null ? HourDropdown.value : 0;
int minute = MinuteDropdown != null ? MinuteDropdown.value : 0;
int second = SecondDropdown != null ? SecondDropdown.value : 0;
_tempDateTime = new DateTime(year, month, day, hour, minute, second);
// 用户手动调整时,重置基准时间
_baseConfigTime = _tempDateTime;
_baseRealTime = DateTime.Now;
_configTimeSet = true;
UpdateTimeDisplay();
}
catch (Exception ex)
{
Debug.LogError($"更新临时时间失败: {ex.Message}");
}
}
private void UpdateTimeDisplay()
{
if (DateDisplayText != null)
{
DateDisplayText.text = _tempDateTime.ToString("yyyy年MM月dd日 HH:mm:ss");
}
}
private void UpdateCurrentTimeDisplay()
{
if (CurrentTimeText != null)
{
// 显示真实的系统时间作为参考
CurrentTimeText.text = $"当前系统时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}";
}
}
/// <summary>
/// 更新显示的时间(让时间持续流动,与 TimeUpdateComponent 保持一致)
/// </summary>
private void UpdateDisplayedTime()
{
if (!_configTimeSet) return;
// 计算从基准时间到现在的时间差
TimeSpan elapsed = DateTime.Now - _baseRealTime;
_tempDateTime = _baseConfigTime.Add(elapsed);
// 更新下拉框显示
UpdateDropdownsFromDateTime(_tempDateTime);
}
// private void SyncWithNetworkTime()
// {
// Debug.Log("尝试与网络时间同步...");
// // 在实际实现中这里应该连接NTP服务器获取网络时间
// // 现在使用本地时间作为模拟
// DateTime networkTime = DateTime.Now;
// _tempDateTime = networkTime;
// // 重置基准时间
// _baseConfigTime = _tempDateTime;
// _baseRealTime = DateTime.Now;
// _configTimeSet = true;
// UpdateDropdownsFromDateTime(_tempDateTime);
// UpdateTimeDisplay();
// Debug.Log($"已同步网络时间: {networkTime:yyyy-MM-dd HH:mm:ss}");
// }
private void ResetToCurrentTime()
{
_tempDateTime = DateTime.Now;
// 重置基准时间
_baseConfigTime = _tempDateTime;
_baseRealTime = DateTime.Now;
_configTimeSet = true;
UpdateDropdownsFromDateTime(_tempDateTime);
UpdateTimeDisplay();
Debug.Log("时间已重置为当前系统时间");
}
private void UpdateDropdownsFromDateTime(DateTime dateTime)
{
_isRefreshingDropdowns = true;
// 先更新_tempDateTime这样PopulateDayDropdown可以使用正确的日期
_tempDateTime = dateTime;
// 更新年份
if (YearDropdown != null)
{
int currentYear = DateTime.Now.Year;
int yearIndex = dateTime.Year - (currentYear - 10);
if (yearIndex >= 0 && yearIndex < YearDropdown.options.Count)
{
YearDropdown.SetValueWithoutNotify(yearIndex);
YearDropdown.RefreshShownValue();
}
}
// 更新月份
if (MonthDropdown != null)
{
MonthDropdown.SetValueWithoutNotify(dateTime.Month - 1);
MonthDropdown.RefreshShownValue();
}
// 重新填充日期下拉框(会自动设置正确的日期值)
PopulateDayDropdown();
// 更新时间
if (HourDropdown != null)
{
HourDropdown.SetValueWithoutNotify(dateTime.Hour);
HourDropdown.RefreshShownValue();
}
if (MinuteDropdown != null)
{
MinuteDropdown.SetValueWithoutNotify(dateTime.Minute);
MinuteDropdown.RefreshShownValue();
}
if (SecondDropdown != null)
{
SecondDropdown.SetValueWithoutNotify(dateTime.Second);
SecondDropdown.RefreshShownValue();
}
_isRefreshingDropdowns = false;
// 最后更新显示
UpdateTimeDisplay();
}
private void ApplyAndBack()
{
// 只更新显示时间,不修改安卓系统时间
// 注意这里只是保存到配置中用于UI显示不会调用系统API修改实际系统时间
_vm.SystemTime = _tempDateTime;
// 通知MainPanel的TimeUpdateComponent刷新显示
var mainPanel = UIManager.Instance.GetPanel<MainPanel>();
if (mainPanel != null && mainPanel.TimeUpdater != null)
{
mainPanel.TimeUpdater.RefreshConfigTime();
Debug.Log("TimeSettingPanel: 已通知TimeUpdateComponent刷新时间显示");
}
Debug.Log($"UI显示时间已更新为: {_tempDateTime:yyyy-MM-dd HH:mm:ss}(不修改系统时间)");
ClosePanel();
}
// public void ClosePanel()
// {
// CancelInvoke();
// UIManager.Instance.HidePanel<TimeSettingPanel>();
// }
void OnDestroy()
{
CancelInvoke();
}
}