456 lines
14 KiB
C#
456 lines
14 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections;
|
|||
|
|
using TMPro;
|
|||
|
|
using UnityEngine;
|
|||
|
|
using UnityEngine.UI;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// BFI阈值设置弹窗
|
|||
|
|
/// 用于设置BFI数值的上下限阈值,超过阈值会触发报警
|
|||
|
|
/// </summary>
|
|||
|
|
public class BFIThresholdDialog : BasePanel
|
|||
|
|
{
|
|||
|
|
[Header("阈值设置")]
|
|||
|
|
public Slider MinThresholdSlider;
|
|||
|
|
public Slider MaxThresholdSlider;
|
|||
|
|
public TMP_InputField MinThresholdInput;
|
|||
|
|
public TMP_InputField MaxThresholdInput;
|
|||
|
|
public TextMeshProUGUI MinValueText;
|
|||
|
|
public TextMeshProUGUI MaxValueText;
|
|||
|
|
|
|||
|
|
[Header("当前值显示")]
|
|||
|
|
public TextMeshProUGUI CurrentBFIText;
|
|||
|
|
public TextMeshProUGUI StatusText;
|
|||
|
|
public Image BFIStatusIndicator;
|
|||
|
|
|
|||
|
|
[Header("按钮")]
|
|||
|
|
public Button HomeButton;
|
|||
|
|
public Button ConfirmButton;
|
|||
|
|
public Button CancelButton;
|
|||
|
|
public Button ResetButton;
|
|||
|
|
|
|||
|
|
// [Header("预设按钮")]
|
|||
|
|
// public Button NormalPresetButton; // 正常范围预设
|
|||
|
|
// public Button SensitivePresetButton; // 敏感范围预设
|
|||
|
|
// public Button CustomPresetButton; // 自定义范围预设
|
|||
|
|
|
|||
|
|
// [Header("报警设置")]
|
|||
|
|
// public Toggle EnableLowAlarmToggle;
|
|||
|
|
// public Toggle EnableHighAlarmToggle;
|
|||
|
|
// public Dropdown AlarmPriorityDropdown;
|
|||
|
|
|
|||
|
|
// 阈值数据
|
|||
|
|
private BFIThresholdSettings _settings;
|
|||
|
|
private IDataService _dataService;
|
|||
|
|
|
|||
|
|
// 默认阈值
|
|||
|
|
private const float DEFAULT_MIN = 0f;
|
|||
|
|
private const float DEFAULT_MAX = 200f;
|
|||
|
|
private const float BFI_MIN_RANGE = 0f;
|
|||
|
|
private const float BFI_MAX_RANGE = 200f;
|
|||
|
|
|
|||
|
|
public static event Action<BFIThresholdSettings> OnThresholdChanged;
|
|||
|
|
|
|||
|
|
public override void Init()
|
|||
|
|
{
|
|||
|
|
// 获取数据服务
|
|||
|
|
_dataService = ServiceLocator.Get<IDataService>();
|
|||
|
|
|
|||
|
|
// 加载当前设置
|
|||
|
|
LoadCurrentSettings();
|
|||
|
|
|
|||
|
|
// 初始化UI
|
|||
|
|
InitializeUI();
|
|||
|
|
|
|||
|
|
// 订阅数据更新事件
|
|||
|
|
if (_dataService != null)
|
|||
|
|
{
|
|||
|
|
_dataService.OnBFIValueUpdated += OnBFIValueUpdated;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 开始实时更新
|
|||
|
|
// StartCoroutine(UpdateCurrentBFIDisplay());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void LoadCurrentSettings()
|
|||
|
|
{
|
|||
|
|
// 从配置服务加载当前阈值设置
|
|||
|
|
var settingsService = ServiceLocator.Get<ISystemSettingsService>();
|
|||
|
|
|
|||
|
|
_settings = new BFIThresholdSettings
|
|||
|
|
{
|
|||
|
|
MinThreshold = settingsService?.BFILowThreshold ?? DEFAULT_MIN,
|
|||
|
|
MaxThreshold = settingsService?.BFIHighThreshold ?? DEFAULT_MAX,
|
|||
|
|
// EnableLowAlarm = settingsService?.EnableBFIAlarm ?? true,
|
|||
|
|
// EnableHighAlarm = settingsService?.EnableBFIAlarm ?? true,
|
|||
|
|
AlarmPriority = AlarmPriority.High,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void InitializeUI()
|
|||
|
|
{
|
|||
|
|
// 初始化滑块
|
|||
|
|
if (MinThresholdSlider != null)
|
|||
|
|
{
|
|||
|
|
MinThresholdSlider.minValue = BFI_MIN_RANGE;
|
|||
|
|
MinThresholdSlider.maxValue = BFI_MAX_RANGE;
|
|||
|
|
MinThresholdSlider.value = _settings.MinThreshold;
|
|||
|
|
MinThresholdSlider.onValueChanged.AddListener(OnMinThresholdSliderChanged);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (MaxThresholdSlider != null)
|
|||
|
|
{
|
|||
|
|
MaxThresholdSlider.minValue = BFI_MIN_RANGE;
|
|||
|
|
MaxThresholdSlider.maxValue = BFI_MAX_RANGE;
|
|||
|
|
MaxThresholdSlider.value = _settings.MaxThreshold;
|
|||
|
|
MaxThresholdSlider.onValueChanged.AddListener(OnMaxThresholdSliderChanged);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 初始化输入框
|
|||
|
|
if (MinThresholdInput != null)
|
|||
|
|
{
|
|||
|
|
MinThresholdInput.text = _settings.MinThreshold.ToString("F1");
|
|||
|
|
MinThresholdInput.onEndEdit.AddListener(OnMinThresholdInputChanged);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (MaxThresholdInput != null)
|
|||
|
|
{
|
|||
|
|
MaxThresholdInput.text = _settings.MaxThreshold.ToString("F1");
|
|||
|
|
MaxThresholdInput.onEndEdit.AddListener(OnMaxThresholdInputChanged);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 初始化按钮
|
|||
|
|
if(HomeButton != null)
|
|||
|
|
{
|
|||
|
|
HomeButton.onClick.AddListener(OnCancelClicked);
|
|||
|
|
}
|
|||
|
|
if (ConfirmButton != null)
|
|||
|
|
{
|
|||
|
|
ConfirmButton.onClick.AddListener(OnConfirmClicked);
|
|||
|
|
// #if UNITY_ANDROID && !UNITY_EDITOR
|
|||
|
|
// ConfirmButton.gameObject.SetActive(false);
|
|||
|
|
// #endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (CancelButton != null)
|
|||
|
|
{
|
|||
|
|
CancelButton.onClick.AddListener(OnCancelClicked);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (ResetButton != null)
|
|||
|
|
{
|
|||
|
|
ResetButton.onClick.AddListener(OnResetClicked);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新显示
|
|||
|
|
UpdateDisplayValues();
|
|||
|
|
|
|||
|
|
// 禁用系统键盘(安卓优化)
|
|||
|
|
DisableSystemKeyboardForInputFields();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void OnMinThresholdSliderChanged(float value)
|
|||
|
|
{
|
|||
|
|
_settings.MinThreshold = value;
|
|||
|
|
|
|||
|
|
// 确保最小值不大于最大值
|
|||
|
|
if (_settings.MinThreshold >= _settings.MaxThreshold)
|
|||
|
|
{
|
|||
|
|
_settings.MaxThreshold = _settings.MinThreshold + 1f;
|
|||
|
|
if (MaxThresholdSlider != null)
|
|||
|
|
{
|
|||
|
|
MaxThresholdSlider.value = _settings.MaxThreshold;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
UpdateDisplayValues();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void OnMaxThresholdSliderChanged(float value)
|
|||
|
|
{
|
|||
|
|
_settings.MaxThreshold = value;
|
|||
|
|
|
|||
|
|
// 确保最大值不小于最小值
|
|||
|
|
if (_settings.MaxThreshold <= _settings.MinThreshold)
|
|||
|
|
{
|
|||
|
|
_settings.MinThreshold = _settings.MaxThreshold - 1f;
|
|||
|
|
if (MinThresholdSlider != null)
|
|||
|
|
{
|
|||
|
|
MinThresholdSlider.value = _settings.MinThreshold;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
UpdateDisplayValues();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void OnMinThresholdInputChanged(string value)
|
|||
|
|
{
|
|||
|
|
if (float.TryParse(value, out float newValue))
|
|||
|
|
{
|
|||
|
|
newValue = Mathf.Clamp(newValue, BFI_MIN_RANGE, BFI_MAX_RANGE);
|
|||
|
|
_settings.MinThreshold = newValue;
|
|||
|
|
|
|||
|
|
if (MinThresholdSlider != null)
|
|||
|
|
{
|
|||
|
|
MinThresholdSlider.value = newValue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
UpdateDisplayValues();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void OnMaxThresholdInputChanged(string value)
|
|||
|
|
{
|
|||
|
|
if (float.TryParse(value, out float newValue))
|
|||
|
|
{
|
|||
|
|
newValue = Mathf.Clamp(newValue, BFI_MIN_RANGE, BFI_MAX_RANGE);
|
|||
|
|
_settings.MaxThreshold = newValue;
|
|||
|
|
|
|||
|
|
if (MaxThresholdSlider != null)
|
|||
|
|
{
|
|||
|
|
MaxThresholdSlider.value = newValue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
UpdateDisplayValues();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void UpdateDisplayValues()
|
|||
|
|
{
|
|||
|
|
if (MinValueText != null)
|
|||
|
|
{
|
|||
|
|
MinValueText.text = $"下限: {_settings.MinThreshold:F1}";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (MaxValueText != null)
|
|||
|
|
{
|
|||
|
|
MaxValueText.text = $"上限: {_settings.MaxThreshold:F1}";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (MinThresholdInput != null)
|
|||
|
|
{
|
|||
|
|
MinThresholdInput.text = _settings.MinThreshold.ToString("F1");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (MaxThresholdInput != null)
|
|||
|
|
{
|
|||
|
|
MaxThresholdInput.text = _settings.MaxThreshold.ToString("F1");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (StatusText != null)
|
|||
|
|
{
|
|||
|
|
string priorityText = GetPriorityText(_settings.AlarmPriority);
|
|||
|
|
StatusText.text = $"正常范围: {_settings.MinThreshold:F1} - {_settings.MaxThreshold:F1}\n" +
|
|||
|
|
$"报警优先级: {priorityText}";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private string GetPriorityText(AlarmPriority priority)
|
|||
|
|
{
|
|||
|
|
return priority switch
|
|||
|
|
{
|
|||
|
|
AlarmPriority.Low => "低",
|
|||
|
|
AlarmPriority.Medium => "中",
|
|||
|
|
AlarmPriority.High => "高",
|
|||
|
|
_ => "中"
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void OnBFIValueUpdated(float currentBFI)
|
|||
|
|
{
|
|||
|
|
// 在主线程更新UI
|
|||
|
|
if (CurrentBFIText != null)
|
|||
|
|
{
|
|||
|
|
CurrentBFIText.text = $"当前BFI: {currentBFI:F1}";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新状态指示器
|
|||
|
|
UpdateBFIStatusIndicator(currentBFI);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void UpdateBFIStatusIndicator(float currentBFI)
|
|||
|
|
{
|
|||
|
|
if (BFIStatusIndicator == null) return;
|
|||
|
|
|
|||
|
|
Color indicatorColor;
|
|||
|
|
|
|||
|
|
if (currentBFI < _settings.MinThreshold)
|
|||
|
|
{
|
|||
|
|
indicatorColor = Color.red ;
|
|||
|
|
}
|
|||
|
|
else if (currentBFI > _settings.MaxThreshold)
|
|||
|
|
{
|
|||
|
|
indicatorColor = Color.red ;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
indicatorColor = Color.green;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
BFIStatusIndicator.color = indicatorColor;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
private void SyncUIWithSettings()
|
|||
|
|
{
|
|||
|
|
if (MinThresholdSlider != null) MinThresholdSlider.value = _settings.MinThreshold;
|
|||
|
|
if (MaxThresholdSlider != null) MaxThresholdSlider.value = _settings.MaxThreshold;
|
|||
|
|
// if (EnableLowAlarmToggle != null) EnableLowAlarmToggle.isOn = _settings.EnableLowAlarm;
|
|||
|
|
// if (EnableHighAlarmToggle != null) EnableHighAlarmToggle.isOn = _settings.EnableHighAlarm;
|
|||
|
|
// if (AlarmPriorityDropdown != null) AlarmPriorityDropdown.value = (int)_settings.AlarmPriority;
|
|||
|
|
|
|||
|
|
UpdateDisplayValues();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
private void OnConfirmClicked()
|
|||
|
|
{
|
|||
|
|
// 保存设置到系统配置
|
|||
|
|
var settingsService = ServiceLocator.Get<ISystemSettingsService>();
|
|||
|
|
if (settingsService != null)
|
|||
|
|
{
|
|||
|
|
settingsService.SetBFIAlarmSettings(
|
|||
|
|
_settings.MinThreshold,
|
|||
|
|
_settings.MaxThreshold,
|
|||
|
|
(int)_settings.AlarmPriority,
|
|||
|
|
settingsService.EnableBFIAlarm);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 通知其他系统阈值已更改
|
|||
|
|
OnThresholdChanged?.Invoke(_settings);
|
|||
|
|
|
|||
|
|
// 只显示确认按钮,不显示取消按钮
|
|||
|
|
ConfirmDialog.Show("提示", "设置已保存", () => { ClosePanel(); }, null, "确认", "取消", false, false);
|
|||
|
|
|
|||
|
|
// 延迟关闭
|
|||
|
|
// StartCoroutine(CloseAfterDelay(1f));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void OnCancelClicked()
|
|||
|
|
{
|
|||
|
|
ConfirmDialog.Show("确认", "是否返回主界面?", () =>
|
|||
|
|
{
|
|||
|
|
ClosePanel();
|
|||
|
|
ClosePanel();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void OnResetClicked()
|
|||
|
|
{
|
|||
|
|
_settings.MinThreshold = DEFAULT_MIN;
|
|||
|
|
_settings.MaxThreshold = DEFAULT_MAX;
|
|||
|
|
// _settings.EnableLowAlarm = true;
|
|||
|
|
// _settings.EnableHighAlarm = true;
|
|||
|
|
_settings.AlarmPriority = AlarmPriority.High;
|
|||
|
|
|
|||
|
|
SyncUIWithSettings();
|
|||
|
|
|
|||
|
|
// SetStatusMessage("已重置为默认设置", Color.yellow);
|
|||
|
|
// 只显示确认按钮,不显示取消按钮
|
|||
|
|
ConfirmDialog.Show("提示", "已重置为默认设置", () => { }, null, "确认", "取消", false, false);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private IEnumerator CloseAfterDelay(float delay)
|
|||
|
|
{
|
|||
|
|
yield return new WaitForSeconds(delay);
|
|||
|
|
ClosePanel();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void OnDestroy()
|
|||
|
|
{
|
|||
|
|
// 取消数据服务订阅
|
|||
|
|
if (_dataService != null)
|
|||
|
|
{
|
|||
|
|
_dataService.OnBFIValueUpdated -= OnBFIValueUpdated;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 关闭自定义键盘(如果正在显示)
|
|||
|
|
if (CustomKeyboardManager.Instance != null && CustomKeyboardManager.Instance.IsKeyboardShowing())
|
|||
|
|
{
|
|||
|
|
CustomKeyboardManager.Instance.HideKeyboard();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 禁用InputField的系统键盘,改用自定义输入对话框
|
|||
|
|
/// </summary>
|
|||
|
|
private void DisableSystemKeyboardForInputFields()
|
|||
|
|
{
|
|||
|
|
// #if UNITY_ANDROID && !UNITY_EDITOR
|
|||
|
|
// 在安卓平台设置InputField为只读,通过透明按钮触发自定义输入
|
|||
|
|
// SetupCustomNumericInput(MinThresholdInput, "请输入BFI下限值");
|
|||
|
|
// SetupCustomNumericInput(MaxThresholdInput, "请输入BFI上限值");
|
|||
|
|
|
|||
|
|
if (MinThresholdInput != null)
|
|||
|
|
CustomKeyboardManager.SetupInputField(MinThresholdInput, KeyboardLayout.Numeric,
|
|||
|
|
(newValue) =>
|
|||
|
|
{
|
|||
|
|
// 验证数字输入
|
|||
|
|
if (float.TryParse(newValue, out float numValue))
|
|||
|
|
{
|
|||
|
|
numValue = Mathf.Clamp(numValue, BFI_MIN_RANGE, BFI_MAX_RANGE);
|
|||
|
|
|
|||
|
|
// 更新对应的输入框和滑块
|
|||
|
|
_settings.MinThreshold = numValue;
|
|||
|
|
if (MinThresholdSlider != null)
|
|||
|
|
{
|
|||
|
|
MinThresholdSlider.value = numValue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
OnConfirmClicked();
|
|||
|
|
UpdateDisplayValues();
|
|||
|
|
}
|
|||
|
|
else if (!string.IsNullOrEmpty(newValue))
|
|||
|
|
{
|
|||
|
|
// 只显示确认按钮,不显示取消按钮
|
|||
|
|
ConfirmDialog.Show("提示", "请输入有效的数字(0.0-200.0)", () => { }, null, "确认", "取消", false, false);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
clearOnFirstInput: true); // 首次输入时清空原内容
|
|||
|
|
|
|||
|
|
if (MaxThresholdInput != null)
|
|||
|
|
CustomKeyboardManager.SetupInputField(MaxThresholdInput, KeyboardLayout.Numeric,
|
|||
|
|
(newValue) =>
|
|||
|
|
{
|
|||
|
|
// 验证数字输入
|
|||
|
|
if (float.TryParse(newValue, out float numValue))
|
|||
|
|
{
|
|||
|
|
numValue = Mathf.Clamp(numValue, BFI_MIN_RANGE, BFI_MAX_RANGE);
|
|||
|
|
|
|||
|
|
// 更新对应的输入框和滑块
|
|||
|
|
_settings.MaxThreshold = numValue;
|
|||
|
|
if (MaxThresholdSlider != null)
|
|||
|
|
{
|
|||
|
|
MaxThresholdSlider.value = numValue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
OnConfirmClicked();
|
|||
|
|
UpdateDisplayValues();
|
|||
|
|
}
|
|||
|
|
else if (!string.IsNullOrEmpty(newValue))
|
|||
|
|
{
|
|||
|
|
// 只显示确认按钮,不显示取消按钮
|
|||
|
|
ConfirmDialog.Show("提示", "请输入有效的数字(0.0-200.0)", () => { }, null, "确认", "取消", false, false);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
clearOnFirstInput: true); // 首次输入时清空原内容
|
|||
|
|
|
|||
|
|
// #endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// BFI阈值设置数据结构
|
|||
|
|
/// </summary>
|
|||
|
|
[Serializable]
|
|||
|
|
public class BFIThresholdSettings
|
|||
|
|
{
|
|||
|
|
public float MinThreshold;
|
|||
|
|
public float MaxThreshold;
|
|||
|
|
// public bool EnableLowAlarm;
|
|||
|
|
// public bool EnableHighAlarm;
|
|||
|
|
public AlarmPriority AlarmPriority;
|
|||
|
|
}
|