using System; using System.ComponentModel; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using ERVSimulator.Model; namespace ERVSimulator { // 공기질 센서 히스테리시스 팝업 : 활성 프리셋(ECO/NORMAL/TURBO)의 오염단계 임계 + 히스(하강) 표시·수정 public partial class HystWindow : Window { readonly ErvState _state; public event Action? Applied; Brush Br(string key) => (Brush)FindResource(key); public HystWindow(ErvState state) { InitializeComponent(); _state = state; // MainWindow 프리셋 버튼 / 대시보드 CTRL 로 HystPreset 변경 시 팝업도 즉시 동기화 _state.PropertyChanged += OnStateChanged; RefreshPreset(); } void OnStateChanged(object? s, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(ErvState.HystPreset)) Dispatcher.BeginInvoke(new Action(RefreshPreset)); } protected override void OnClosed(EventArgs e) { _state.PropertyChanged -= OnStateChanged; base.OnClosed(e); } void RefreshPreset() { foreach (var child in PresetPanel.Children) { if (child is Button btn && btn.Tag is string tag && byte.TryParse(tag, out var p)) { bool active = p == _state.HystPreset; btn.Background = active ? Br("AccentCyanBrush") : Br("CardBgBrush"); btn.Foreground = active ? Brushes.Black : Br("TextPrimaryBrush"); } } FillGrid(_state.HystPreset); } // 활성 프리셋 값으로 표 채우기 void FillGrid(int p) { TCo2_1.Text = _state.Co2Thr[p][0].ToString(); TCo2_2.Text = _state.Co2Thr[p][1].ToString(); TCo2_3.Text = _state.Co2Thr[p][2].ToString(); TCo2_4.Text = _state.Co2Thr[p][3].ToString(); TPm25_1.Text = _state.Pm25Thr[p][0].ToString(); TPm25_2.Text = _state.Pm25Thr[p][1].ToString(); TPm25_3.Text = _state.Pm25Thr[p][2].ToString(); TPm25_4.Text = _state.Pm25Thr[p][3].ToString(); TPm10_1.Text = _state.Pm10Thr[p][0].ToString(); TPm10_2.Text = _state.Pm10Thr[p][1].ToString(); TPm10_3.Text = _state.Pm10Thr[p][2].ToString(); TPm10_4.Text = _state.Pm10Thr[p][3].ToString(); TVoc_1.Text = _state.VocThr[p][0].ToString(); TVoc_2.Text = _state.VocThr[p][1].ToString(); TVoc_3.Text = _state.VocThr[p][2].ToString(); TVoc_4.Text = _state.VocThr[p][3].ToString(); DCo2.Text = _state.Co2Db[p].ToString(); DPm25.Text = _state.Pm25Db[p].ToString(); DPm10.Text = _state.Pm10Db[p].ToString(); DVoc.Text = _state.VocDb[p].ToString(); // 4단계(최악) : 3단계 상한 초과 = (상한+1)~ (사양서 10p) MCo2.Text = $"{_state.Co2Thr[p][3] + 1}~"; MPm25.Text = $"{_state.Pm25Thr[p][3] + 1}~"; MPm10.Text = $"{_state.Pm10Thr[p][3] + 1}~"; MVoc.Text = $"{_state.VocThr[p][3] + 1}~"; } static ushort P(TextBox tb) { ushort.TryParse(tb.Text, out var v); return v; } void Preset_Click(object sender, RoutedEventArgs e) { if (sender is Button b && b.Tag is string tag && byte.TryParse(tag, out var p) && p < 3) { _state.HystPreset = p; RefreshPreset(); Applied?.Invoke($"[Manual] 히스테리시스 프리셋 → {(p == 0 ? "ECO" : p == 1 ? "NORMAL" : "TURBO")}"); } } void Apply_Click(object sender, RoutedEventArgs e) { int p = _state.HystPreset; _state.Co2Thr[p][0] = P(TCo2_1); _state.Co2Thr[p][1] = P(TCo2_2); _state.Co2Thr[p][2] = P(TCo2_3); _state.Co2Thr[p][3] = P(TCo2_4); _state.Pm25Thr[p][0] = P(TPm25_1); _state.Pm25Thr[p][1] = P(TPm25_2); _state.Pm25Thr[p][2] = P(TPm25_3); _state.Pm25Thr[p][3] = P(TPm25_4); _state.Pm10Thr[p][0] = P(TPm10_1); _state.Pm10Thr[p][1] = P(TPm10_2); _state.Pm10Thr[p][2] = P(TPm10_3); _state.Pm10Thr[p][3] = P(TPm10_4); _state.VocThr[p][0] = P(TVoc_1); _state.VocThr[p][1] = P(TVoc_2); _state.VocThr[p][2] = P(TVoc_3); _state.VocThr[p][3] = P(TVoc_4); _state.Co2Db[p] = P(DCo2); _state.Pm25Db[p] = P(DPm25); _state.Pm10Db[p] = P(DPm10); _state.VocDb[p] = P(DVoc); Applied?.Invoke($"[Manual] 공기질 센서 히스테리시스 적용 (프리셋 {(p == 0 ? "ECO" : p == 1 ? "NORMAL" : "TURBO")})"); } void Close_Click(object sender, RoutedEventArgs e) => Close(); } }