diff --git a/src/MaaWpfGui/Services/RemoteControl/RemoteControlService.cs b/src/MaaWpfGui/Services/RemoteControl/RemoteControlService.cs index 2702c84a2a..30b35ac0b1 100644 --- a/src/MaaWpfGui/Services/RemoteControl/RemoteControlService.cs +++ b/src/MaaWpfGui/Services/RemoteControl/RemoteControlService.cs @@ -607,7 +607,7 @@ namespace MaaWpfGui.Services.RemoteControl { // 虽然更改时已经保存过了,不过保险起见还是在点击开始之后再保存一次(任务及基建列表) Instances.TaskQueueViewModel.TaskItemSelectionChanged(); - Instances.SettingsViewModel.InfrastOrderSelectionChanged(); + SettingsViewModel.InfrastTask.InfrastOrderSelectionChanged(); InvokeInstanceMethod(Instances.TaskQueueViewModel, "ClearLog"); diff --git a/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs b/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs index 684363193b..49a73025fe 100644 --- a/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs +++ b/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs @@ -16,9 +16,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Collections.Specialized; using System.Globalization; -using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; @@ -35,9 +33,7 @@ using MaaWpfGui.States; using MaaWpfGui.Utilities.ValueType; using MaaWpfGui.ViewModels.UserControl.Settings; using MaaWpfGui.ViewModels.UserControl.TaskQueue; -using Microsoft.Win32; using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Serilog; using Stylet; using ComboBox = System.Windows.Controls.ComboBox; @@ -79,6 +75,11 @@ namespace MaaWpfGui.ViewModels.UI /// public static MallSettingsUserControlModel MallTask { get; } = new(); + /// + /// Gets 基建任务Model + /// + public static InfrastSettingsUserControlModel InfrastTask { get; } = new(); + /// /// Gets 肉鸽任务Model /// @@ -189,7 +190,7 @@ namespace MaaWpfGui.ViewModels.UI private void Init() { - InitInfrast(); + InfrastTask.InitInfrast(); RoguelikeTask.InitRoguelike(); InitConfiguration(); InitUiSettings(); @@ -197,61 +198,6 @@ namespace MaaWpfGui.ViewModels.UI InitVersionUpdate(); } - private void InitInfrast() - { - var facilityList = new[] - { - "Mfg", - "Trade", - "Control", - "Power", - "Reception", - "Office", - "Dorm", - "Processing", - "Training", - }; - - var tempOrderList = new List(new DragItemViewModel[facilityList.Length]); - var nonOrderList = new List(); - for (int i = 0; i != facilityList.Length; ++i) - { - var facility = facilityList[i]; - bool parsed = int.TryParse(ConfigurationHelper.GetFacilityOrder(facility, "-1"), out int order); - - DragItemViewModel vm = new DragItemViewModel( - LocalizationHelper.GetString(facility), - facility, - "Infrast."); - - if (!parsed || order < 0 || order >= tempOrderList.Count || tempOrderList[order] != null) - { - nonOrderList.Add(vm); - } - else - { - tempOrderList[order] = vm; - } - } - - foreach (var newVm in nonOrderList) - { - int i = 0; - while (i < tempOrderList.Count && tempOrderList[i] != null) - { - ++i; - } - - tempOrderList[i] = newVm; - ConfigurationHelper.SetFacilityOrder(newVm.OriginalName, i.ToString()); - } - - InfrastItemViewModels = new ObservableCollection(tempOrderList!); - InfrastItemViewModels.CollectionChanged += InfrastOrderSelectionChanged; - - _dormThresholdLabel = LocalizationHelper.GetString("DormThreshold") + ": " + _dormThreshold + "%"; - } - private void InitConfiguration() { var configurations = new ObservableCollection(); @@ -471,425 +417,6 @@ namespace MaaWpfGui.ViewModels.UI #endregion 开始唤醒 - #region 基建设置 - - /// - /// Gets or sets the infrast item view models. - /// - public ObservableCollection InfrastItemViewModels { get; set; } - - /// - /// Gets the list of uses of drones. - /// - public List UsesOfDronesList { get; } = - [ - new() { Display = LocalizationHelper.GetString("DronesNotUse"), Value = "_NotUse" }, - new() { Display = LocalizationHelper.GetString("Money"), Value = "Money" }, - new() { Display = LocalizationHelper.GetString("SyntheticJade"), Value = "SyntheticJade" }, - new() { Display = LocalizationHelper.GetString("CombatRecord"), Value = "CombatRecord" }, - new() { Display = LocalizationHelper.GetString("PureGold"), Value = "PureGold" }, - new() { Display = LocalizationHelper.GetString("OriginStone"), Value = "OriginStone" }, - new() { Display = LocalizationHelper.GetString("Chip"), Value = "Chip" }, - ]; - - /// - /// Gets the list of uses of default infrast. - /// - public List DefaultInfrastList { get; } = - [ - new() { Display = LocalizationHelper.GetString("UserDefined"), Value = UserDefined }, - new() { Display = LocalizationHelper.GetString("153Time3"), Value = "153_layout_3_times_a_day.json" }, - new() { Display = LocalizationHelper.GetString("153Time4"), Value = "153_layout_4_times_a_day.json" }, - new() { Display = LocalizationHelper.GetString("243Time3"), Value = "243_layout_3_times_a_day.json" }, - new() { Display = LocalizationHelper.GetString("243Time4"), Value = "243_layout_4_times_a_day.json" }, - new() { Display = LocalizationHelper.GetString("333Time3"), Value = "333_layout_for_Orundum_3_times_a_day.json" }, - ]; - - private int _dormThreshold = Convert.ToInt32(ConfigurationHelper.GetValue(ConfigurationKeys.DormThreshold, "30")); - - /// - /// Gets or sets the threshold to enter dormitory. - /// - public int DormThreshold - { - get => _dormThreshold; - set - { - SetAndNotify(ref _dormThreshold, value); - DormThresholdLabel = LocalizationHelper.GetString("DormThreshold") + ": " + _dormThreshold + "%"; - ConfigurationHelper.SetValue(ConfigurationKeys.DormThreshold, value.ToString()); - } - } - - private string _dormThresholdLabel; - - /// - /// Gets or sets the label of dormitory threshold. - /// - public string DormThresholdLabel - { - get => _dormThresholdLabel; - set => SetAndNotify(ref _dormThresholdLabel, value); - } - - /// - /// Gets infrast order list. - /// - /// The infrast order list. - public List GetInfrastOrderList() - { - return (from item in InfrastItemViewModels where item.IsChecked select item.OriginalName).ToList(); - } - - // UI 绑定的方法 - // ReSharper disable once UnusedMember.Global - public void InfrastItemSelectedAll() - { - foreach (var item in InfrastItemViewModels) - { - item.IsChecked = true; - } - } - - // UI 绑定的方法 - // ReSharper disable once UnusedMember.Global - public void InfrastItemUnselectedAll() - { - foreach (var item in InfrastItemViewModels) - { - item.IsChecked = false; - } - } - - /// - /// 实时更新基建换班顺序 - /// - /// ignored object - /// ignored NotifyCollectionChangedEventArgs - public void InfrastOrderSelectionChanged(object? sender = null, NotifyCollectionChangedEventArgs? e = null) - { - _ = (sender, e); - int index = 0; - foreach (var item in InfrastItemViewModels) - { - ConfigurationHelper.SetFacilityOrder(item.OriginalName, index.ToString()); - ++index; - } - } - - public static TaskQueueViewModel CustomInfrastPlanDataContext { get => Instances.TaskQueueViewModel; } - - private string _usesOfDrones = ConfigurationHelper.GetValue(ConfigurationKeys.UsesOfDrones, "Money"); - - /// - /// Gets or sets the uses of drones. - /// - public string UsesOfDrones - { - get => _usesOfDrones; - set - { - SetAndNotify(ref _usesOfDrones, value); - ConfigurationHelper.SetValue(ConfigurationKeys.UsesOfDrones, value); - } - } - - private bool _continueTraining = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.ContinueTraining, bool.FalseString)); - - /// - /// Gets or sets a value indicating whether to continue training after current training completed. - /// - public bool ContinueTraining - { - get => _continueTraining; - set - { - SetAndNotify(ref _continueTraining, value); - ConfigurationHelper.SetValue(ConfigurationKeys.ContinueTraining, value.ToString()); - } - } - - private string _defaultInfrast = ConfigurationHelper.GetValue(ConfigurationKeys.DefaultInfrast, UserDefined); - - private const string UserDefined = "user_defined"; - - /// - /// Gets or sets the uses of drones. - /// - public string DefaultInfrast - { - get => _defaultInfrast; - set - { - SetAndNotify(ref _defaultInfrast, value); - if (_defaultInfrast != UserDefined) - { - CustomInfrastFile = @"resource\custom_infrast\" + value; - IsCustomInfrastFileReadOnly = true; - } - else - { - IsCustomInfrastFileReadOnly = false; - } - - ConfigurationHelper.SetValue(ConfigurationKeys.DefaultInfrast, value); - } - } - - private bool _isCustomInfrastFileReadOnly = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.IsCustomInfrastFileReadOnly, bool.FalseString)); - - /// - /// Gets or sets a value indicating whether CustomInfrastFile is read-only - /// - public bool IsCustomInfrastFileReadOnly - { - get => _isCustomInfrastFileReadOnly; - set - { - SetAndNotify(ref _isCustomInfrastFileReadOnly, value); - ConfigurationHelper.SetValue(ConfigurationKeys.IsCustomInfrastFileReadOnly, value.ToString()); - } - } - - private bool _dormFilterNotStationedEnabled = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.DormFilterNotStationedEnabled, bool.TrueString)); - - /// - /// Gets or sets a value indicating whether the not stationed filter in dorm is enabled. - /// - public bool DormFilterNotStationedEnabled - { - get => _dormFilterNotStationedEnabled; - set - { - SetAndNotify(ref _dormFilterNotStationedEnabled, value); - ConfigurationHelper.SetValue(ConfigurationKeys.DormFilterNotStationedEnabled, value.ToString()); - } - } - - private bool _dormTrustEnabled = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.DormTrustEnabled, bool.FalseString)); - - /// - /// Gets or sets a value indicating whether trust in dorm is enabled. - /// - public bool DormTrustEnabled - { - get => _dormTrustEnabled; - set - { - SetAndNotify(ref _dormTrustEnabled, value); - ConfigurationHelper.SetValue(ConfigurationKeys.DormTrustEnabled, value.ToString()); - } - } - - private bool _originiumShardAutoReplenishment = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.OriginiumShardAutoReplenishment, bool.TrueString)); - - /// - /// Gets or sets a value indicating whether Originium shard auto replenishment is enabled. - /// - public bool OriginiumShardAutoReplenishment - { - get => _originiumShardAutoReplenishment; - set - { - SetAndNotify(ref _originiumShardAutoReplenishment, value); - ConfigurationHelper.SetValue(ConfigurationKeys.OriginiumShardAutoReplenishment, value.ToString()); - } - } - - private bool _customInfrastEnabled = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.CustomInfrastEnabled, bool.FalseString)); - - public bool CustomInfrastEnabled - { - get => _customInfrastEnabled; - set - { - SetAndNotify(ref _customInfrastEnabled, value); - ConfigurationHelper.SetValue(ConfigurationKeys.CustomInfrastEnabled, value.ToString()); - Instances.TaskQueueViewModel.CustomInfrastEnabled = value; - } - } - - /// - /// Selects infrast config file. - /// - // UI 绑定的方法 - // ReSharper disable once UnusedMember.Global - public void SelectCustomInfrastFile() - { - var dialog = new OpenFileDialog - { - Filter = LocalizationHelper.GetString("CustomInfrastFile") + "|*.json", - }; - - if (dialog.ShowDialog() == true) - { - CustomInfrastFile = dialog.FileName; - } - - DefaultInfrast = UserDefined; - } - - private string _customInfrastFile = ConfigurationHelper.GetValue(ConfigurationKeys.CustomInfrastFile, string.Empty); - - public string CustomInfrastFile - { - get => _customInfrastFile; - set - { - SetAndNotify(ref _customInfrastFile, value); - ConfigurationHelper.SetValue(ConfigurationKeys.CustomInfrastFile, value); - Instances.TaskQueueViewModel.RefreshCustomInfrastPlan(); - - // SetAndNotify 在值没有变化时不会触发 PropertyChanged 事件,所以这里手动触发一下 - Instances.TaskQueueViewModel.NeedAddCustomInfrastPlanInfo = false; - { - Instances.TaskQueueViewModel.CustomInfrastPlanIndex--; - Instances.TaskQueueViewModel.CustomInfrastPlanIndex++; - } - - Instances.TaskQueueViewModel.NeedAddCustomInfrastPlanInfo = true; - } - } - - #region 设置页面列表和滚动视图联动绑定 - - private enum NotifyType - { - None, - SelectedIndex, - ScrollOffset, - } - - private NotifyType _notifySource = NotifyType.None; - - private Timer _resetNotifyTimer; - - private void ResetNotifySource() - { - if (_resetNotifyTimer != null) - { - _resetNotifyTimer.Stop(); - _resetNotifyTimer.Close(); - } - - _resetNotifyTimer = new Timer(20); - _resetNotifyTimer.Elapsed += (_, _) => - { - _notifySource = NotifyType.None; - }; - _resetNotifyTimer.AutoReset = false; - _resetNotifyTimer.Enabled = true; - _resetNotifyTimer.Start(); - } - - /// - /// Gets or sets the height of scroll viewport. - /// - public double ScrollViewportHeight { get; set; } - - /// - /// Gets or sets the extent height of scroll. - /// - public double ScrollExtentHeight { get; set; } - - /// - /// Gets or sets the list of divider vertical offset. - /// - public List DividerVerticalOffsetList { get; set; } = []; - - private int _selectedIndex; - - /// - /// Gets or sets the index selected. - /// - public int SelectedIndex - { - get => _selectedIndex; - set - { - switch (_notifySource) - { - case NotifyType.None: - _notifySource = NotifyType.SelectedIndex; - SetAndNotify(ref _selectedIndex, value); - - if (DividerVerticalOffsetList?.Count > 0 && value < DividerVerticalOffsetList.Count) - { - ScrollOffset = DividerVerticalOffsetList[value]; - } - - ResetNotifySource(); - break; - - case NotifyType.ScrollOffset: - SetAndNotify(ref _selectedIndex, value); - break; - - case NotifyType.SelectedIndex: - break; - - default: - throw new ArgumentOutOfRangeException(); - } - } - } - - private double _scrollOffset; - - /// - /// Gets or sets the scroll offset. - /// - public double ScrollOffset - { - get => _scrollOffset; - set - { - switch (_notifySource) - { - case NotifyType.None: - _notifySource = NotifyType.ScrollOffset; - SetAndNotify(ref _scrollOffset, value); - - // 设置 ListBox SelectedIndex 为当前 ScrollOffset 索引 - if (DividerVerticalOffsetList?.Count > 0) - { - // 滚动条滚动到底部,返回最后一个 Divider 索引 - if (value + ScrollViewportHeight >= ScrollExtentHeight) - { - SelectedIndex = DividerVerticalOffsetList.Count - 1; - ResetNotifySource(); - break; - } - - // 根据出当前 ScrollOffset 选出最后一个在可视范围的 Divider 索引 - var dividerSelect = DividerVerticalOffsetList.Select((n, i) => ( - dividerAppeared: value >= n, - index: i)); - - var index = dividerSelect.LastOrDefault(n => n.dividerAppeared).index; - SelectedIndex = index; - } - - ResetNotifySource(); - break; - - case NotifyType.SelectedIndex: - SetAndNotify(ref _scrollOffset, value); - break; - - case NotifyType.ScrollOffset: - break; - - default: - throw new ArgumentOutOfRangeException(); - } - } - } - - #endregion 设置页面列表和滚动视图联动绑定 - - #endregion 基建设置 - #region 领取奖励设置 private bool _receiveAward = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.ReceiveAward, bool.TrueString)); @@ -1702,6 +1229,143 @@ namespace MaaWpfGui.ViewModels.UI #endregion SettingsGuide + #region 设置页面列表和滚动视图联动绑定 + + private enum NotifyType + { + None, + SelectedIndex, + ScrollOffset, + } + + private NotifyType _notifySource = NotifyType.None; + + private Timer _resetNotifyTimer; + + private void ResetNotifySource() + { + if (_resetNotifyTimer != null) + { + _resetNotifyTimer.Stop(); + _resetNotifyTimer.Close(); + } + + _resetNotifyTimer = new Timer(20); + _resetNotifyTimer.Elapsed += (_, _) => + { + _notifySource = NotifyType.None; + }; + _resetNotifyTimer.AutoReset = false; + _resetNotifyTimer.Enabled = true; + _resetNotifyTimer.Start(); + } + + /// + /// Gets or sets the height of scroll viewport. + /// + public double ScrollViewportHeight { get; set; } + + /// + /// Gets or sets the extent height of scroll. + /// + public double ScrollExtentHeight { get; set; } + + /// + /// Gets or sets the list of divider vertical offset. + /// + public List DividerVerticalOffsetList { get; set; } = new(); + + private int _selectedIndex; + + /// + /// Gets or sets the index selected. + /// + public int SelectedIndex + { + get => _selectedIndex; + set + { + switch (_notifySource) + { + case NotifyType.None: + _notifySource = NotifyType.SelectedIndex; + SetAndNotify(ref _selectedIndex, value); + + if (DividerVerticalOffsetList?.Count > 0 && value < DividerVerticalOffsetList.Count) + { + ScrollOffset = DividerVerticalOffsetList[value]; + } + + ResetNotifySource(); + break; + + case NotifyType.ScrollOffset: + SetAndNotify(ref _selectedIndex, value); + break; + + case NotifyType.SelectedIndex: + break; + + default: + throw new ArgumentOutOfRangeException(); + } + } + } + + private double _scrollOffset; + + /// + /// Gets or sets the scroll offset. + /// + public double ScrollOffset + { + get => _scrollOffset; + set + { + switch (_notifySource) + { + case NotifyType.None: + _notifySource = NotifyType.ScrollOffset; + SetAndNotify(ref _scrollOffset, value); + + // 设置 ListBox SelectedIndex 为当前 ScrollOffset 索引 + if (DividerVerticalOffsetList?.Count > 0) + { + // 滚动条滚动到底部,返回最后一个 Divider 索引 + if (value + ScrollViewportHeight >= ScrollExtentHeight) + { + SelectedIndex = DividerVerticalOffsetList.Count - 1; + ResetNotifySource(); + break; + } + + // 根据出当前 ScrollOffset 选出最后一个在可视范围的 Divider 索引 + var dividerSelect = DividerVerticalOffsetList.Select((n, i) => ( + dividerAppeared: value >= n, + index: i)); + + var index = dividerSelect.LastOrDefault(n => n.dividerAppeared).index; + SelectedIndex = index; + } + + ResetNotifySource(); + break; + + case NotifyType.SelectedIndex: + SetAndNotify(ref _scrollOffset, value); + break; + + case NotifyType.ScrollOffset: + break; + + default: + throw new ArgumentOutOfRangeException(); + } + } + } + + #endregion 设置页面列表和滚动视图联动绑定 + /// /// Requires the user to restart to apply settings. /// diff --git a/src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs b/src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs index 2ec7ca3a81..8cac55bb46 100644 --- a/src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs +++ b/src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs @@ -1210,7 +1210,7 @@ namespace MaaWpfGui.ViewModels.UI // 虽然更改时已经保存过了,不过保险起见在点击开始之后再次保存任务和基建列表 TaskItemSelectionChanged(); - Instances.SettingsViewModel.InfrastOrderSelectionChanged(); + SettingsViewModel.InfrastTask.InfrastOrderSelectionChanged(); InfrastTaskRunning = true; @@ -1429,7 +1429,7 @@ namespace MaaWpfGui.ViewModels.UI // 虽然更改时已经保存过了,不过保险起见在点击开始之后再次保存任务和基建列表 TaskItemSelectionChanged(); - Instances.SettingsViewModel.InfrastOrderSelectionChanged(); + SettingsViewModel.InfrastTask.InfrastOrderSelectionChanged(); ClearLog(); @@ -1629,39 +1629,39 @@ namespace MaaWpfGui.ViewModels.UI private void SetInfrastParams() { - var order = Instances.SettingsViewModel.GetInfrastOrderList(); + var order = SettingsViewModel.InfrastTask.GetInfrastOrderList(); Instances.AsstProxy.AsstSetInfrastTaskParams( order, - Instances.SettingsViewModel.UsesOfDrones, - Instances.SettingsViewModel.ContinueTraining, - Instances.SettingsViewModel.DormThreshold / 100.0, - Instances.SettingsViewModel.DormFilterNotStationedEnabled, - Instances.SettingsViewModel.DormTrustEnabled, - Instances.SettingsViewModel.OriginiumShardAutoReplenishment, - Instances.SettingsViewModel.CustomInfrastEnabled, - Instances.SettingsViewModel.CustomInfrastFile, + SettingsViewModel.InfrastTask.UsesOfDrones, + SettingsViewModel.InfrastTask.ContinueTraining, + SettingsViewModel.InfrastTask.DormThreshold / 100.0, + SettingsViewModel.InfrastTask.DormFilterNotStationedEnabled, + SettingsViewModel.InfrastTask.DormTrustEnabled, + SettingsViewModel.InfrastTask.OriginiumShardAutoReplenishment, + SettingsViewModel.InfrastTask.CustomInfrastEnabled, + SettingsViewModel.InfrastTask.CustomInfrastFile, CustomInfrastPlanIndex); } private bool AppendInfrast() { - if (Instances.SettingsViewModel.CustomInfrastEnabled && (!File.Exists(Instances.SettingsViewModel.CustomInfrastFile) || CustomInfrastPlanInfoList.Count == 0)) + if (SettingsViewModel.InfrastTask.CustomInfrastEnabled && (!File.Exists(SettingsViewModel.InfrastTask.CustomInfrastFile) || CustomInfrastPlanInfoList.Count == 0)) { AddLog(LocalizationHelper.GetString("CustomizeInfrastSelectionEmpty"), UiLogColor.Error); return false; } - var order = Instances.SettingsViewModel.GetInfrastOrderList(); + var order = SettingsViewModel.InfrastTask.GetInfrastOrderList(); return Instances.AsstProxy.AsstAppendInfrast( order, - Instances.SettingsViewModel.UsesOfDrones, - Instances.SettingsViewModel.ContinueTraining, - Instances.SettingsViewModel.DormThreshold / 100.0, - Instances.SettingsViewModel.DormFilterNotStationedEnabled, - Instances.SettingsViewModel.DormTrustEnabled, - Instances.SettingsViewModel.OriginiumShardAutoReplenishment, - Instances.SettingsViewModel.CustomInfrastEnabled, - Instances.SettingsViewModel.CustomInfrastFile, + SettingsViewModel.InfrastTask.UsesOfDrones, + SettingsViewModel.InfrastTask.ContinueTraining, + SettingsViewModel.InfrastTask.DormThreshold / 100.0, + SettingsViewModel.InfrastTask.DormFilterNotStationedEnabled, + SettingsViewModel.InfrastTask.DormTrustEnabled, + SettingsViewModel.InfrastTask.OriginiumShardAutoReplenishment, + SettingsViewModel.InfrastTask.CustomInfrastEnabled, + SettingsViewModel.InfrastTask.CustomInfrastFile, CustomInfrastPlanIndex); } @@ -2839,14 +2839,14 @@ namespace MaaWpfGui.ViewModels.UI return; } - if (!File.Exists(Instances.SettingsViewModel.CustomInfrastFile)) + if (!File.Exists(SettingsViewModel.InfrastTask.CustomInfrastFile)) { return; } try { - string jsonStr = File.ReadAllText(Instances.SettingsViewModel.CustomInfrastFile); + string jsonStr = File.ReadAllText(SettingsViewModel.InfrastTask.CustomInfrastFile); var root = (JObject)JsonConvert.DeserializeObject(jsonStr); if (root != null && _customInfrastInfoOutput && root.TryGetValue("title", out var title)) diff --git a/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/InfrastSettingsUserControlModel.cs b/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/InfrastSettingsUserControlModel.cs new file mode 100644 index 0000000000..9039cb1662 --- /dev/null +++ b/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/InfrastSettingsUserControlModel.cs @@ -0,0 +1,372 @@ +// +// MaaWpfGui - A part of the MaaCoreArknights project +// Copyright (C) 2021 MistEO and Contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License v3.0 only as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY +// + +#nullable enable +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.Linq; +using MaaWpfGui.Constants; +using MaaWpfGui.Helper; +using MaaWpfGui.Models; +using MaaWpfGui.Utilities.ValueType; +using MaaWpfGui.ViewModels.UI; +using Microsoft.Win32; +using Stylet; + +namespace MaaWpfGui.ViewModels.UserControl.TaskQueue; + +/// +/// 基建任务 +/// +public class InfrastSettingsUserControlModel : PropertyChangedBase +{ + /// + /// Gets the visibility of task setting views. + /// + public static TaskSettingVisibilityInfo TaskSettingVisibilities => TaskSettingVisibilityInfo.Current; + + public void InitInfrast() + { + var facilityList = new[] + { + "Mfg", + "Trade", + "Control", + "Power", + "Reception", + "Office", + "Dorm", + "Processing", + "Training", + }; + + var tempOrderList = new List(new DragItemViewModel[facilityList.Length]); + var nonOrderList = new List(); + for (int i = 0; i != facilityList.Length; ++i) + { + var facility = facilityList[i]; + bool parsed = int.TryParse(ConfigurationHelper.GetFacilityOrder(facility, "-1"), out int order); + + DragItemViewModel vm = new DragItemViewModel( + LocalizationHelper.GetString(facility), + facility, + "Infrast."); + + if (!parsed || order < 0 || order >= tempOrderList.Count || tempOrderList[order] != null) + { + nonOrderList.Add(vm); + } + else + { + tempOrderList[order] = vm; + } + } + + foreach (var newVm in nonOrderList) + { + int i = 0; + while (i < tempOrderList.Count && tempOrderList[i] != null) + { + ++i; + } + + tempOrderList[i] = newVm; + ConfigurationHelper.SetFacilityOrder(newVm.OriginalName, i.ToString()); + } + + InfrastItemViewModels = new ObservableCollection(tempOrderList!); + InfrastItemViewModels.CollectionChanged += InfrastOrderSelectionChanged; + + _dormThresholdLabel = LocalizationHelper.GetString("DormThreshold") + ": " + _dormThreshold + "%"; + } + + /// + /// Gets or sets the infrast item view models. + /// + public ObservableCollection InfrastItemViewModels { get; set; } = []; + + /// + /// Gets the list of uses of drones. + /// + public List UsesOfDronesList { get; } = + [ + new() { Display = LocalizationHelper.GetString("DronesNotUse"), Value = "_NotUse" }, + new() { Display = LocalizationHelper.GetString("Money"), Value = "Money" }, + new() { Display = LocalizationHelper.GetString("SyntheticJade"), Value = "SyntheticJade" }, + new() { Display = LocalizationHelper.GetString("CombatRecord"), Value = "CombatRecord" }, + new() { Display = LocalizationHelper.GetString("PureGold"), Value = "PureGold" }, + new() { Display = LocalizationHelper.GetString("OriginStone"), Value = "OriginStone" }, + new() { Display = LocalizationHelper.GetString("Chip"), Value = "Chip" }, + ]; + + /// + /// Gets the list of uses of default infrast. + /// + public List DefaultInfrastList { get; } = + [ + new() { Display = LocalizationHelper.GetString("UserDefined"), Value = UserDefined }, + new() { Display = LocalizationHelper.GetString("153Time3"), Value = "153_layout_3_times_a_day.json" }, + new() { Display = LocalizationHelper.GetString("153Time4"), Value = "153_layout_4_times_a_day.json" }, + new() { Display = LocalizationHelper.GetString("243Time3"), Value = "243_layout_3_times_a_day.json" }, + new() { Display = LocalizationHelper.GetString("243Time4"), Value = "243_layout_4_times_a_day.json" }, + new() { Display = LocalizationHelper.GetString("333Time3"), Value = "333_layout_for_Orundum_3_times_a_day.json" }, + ]; + + private int _dormThreshold = Convert.ToInt32(ConfigurationHelper.GetValue(ConfigurationKeys.DormThreshold, "30")); + + /// + /// Gets or sets the threshold to enter dormitory. + /// + public int DormThreshold + { + get => _dormThreshold; + set + { + SetAndNotify(ref _dormThreshold, value); + DormThresholdLabel = LocalizationHelper.GetString("DormThreshold") + ": " + _dormThreshold + "%"; + ConfigurationHelper.SetValue(ConfigurationKeys.DormThreshold, value.ToString()); + } + } + + private string _dormThresholdLabel; + + /// + /// Gets or sets the label of dormitory threshold. + /// + public string DormThresholdLabel + { + get => _dormThresholdLabel; + set => SetAndNotify(ref _dormThresholdLabel, value); + } + + /// + /// Gets infrast order list. + /// + /// The infrast order list. + public List GetInfrastOrderList() + { + return (from item in InfrastItemViewModels where item.IsChecked select item.OriginalName).ToList(); + } + + // UI 绑定的方法 + // ReSharper disable once UnusedMember.Global + public void InfrastItemSelectedAll() + { + foreach (var item in InfrastItemViewModels) + { + item.IsChecked = true; + } + } + + // UI 绑定的方法 + // ReSharper disable once UnusedMember.Global + public void InfrastItemUnselectedAll() + { + foreach (var item in InfrastItemViewModels) + { + item.IsChecked = false; + } + } + + /// + /// 实时更新基建换班顺序 + /// + /// ignored object + /// ignored NotifyCollectionChangedEventArgs + public void InfrastOrderSelectionChanged(object? sender = null, NotifyCollectionChangedEventArgs? e = null) + { + _ = (sender, e); + int index = 0; + foreach (var item in InfrastItemViewModels) + { + ConfigurationHelper.SetFacilityOrder(item.OriginalName, index.ToString()); + ++index; + } + } + + public static TaskQueueViewModel CustomInfrastPlanDataContext { get => Instances.TaskQueueViewModel; } + + private string _usesOfDrones = ConfigurationHelper.GetValue(ConfigurationKeys.UsesOfDrones, "Money"); + + /// + /// Gets or sets the uses of drones. + /// + public string UsesOfDrones + { + get => _usesOfDrones; + set + { + SetAndNotify(ref _usesOfDrones, value); + ConfigurationHelper.SetValue(ConfigurationKeys.UsesOfDrones, value); + } + } + + private bool _continueTraining = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.ContinueTraining, bool.FalseString)); + + /// + /// Gets or sets a value indicating whether to continue training after current training completed. + /// + public bool ContinueTraining + { + get => _continueTraining; + set + { + SetAndNotify(ref _continueTraining, value); + ConfigurationHelper.SetValue(ConfigurationKeys.ContinueTraining, value.ToString()); + } + } + + private string _defaultInfrast = ConfigurationHelper.GetValue(ConfigurationKeys.DefaultInfrast, UserDefined); + + private const string UserDefined = "user_defined"; + + /// + /// Gets or sets the uses of drones. + /// + public string DefaultInfrast + { + get => _defaultInfrast; + set + { + SetAndNotify(ref _defaultInfrast, value); + if (_defaultInfrast != UserDefined) + { + CustomInfrastFile = @"resource\custom_infrast\" + value; + IsCustomInfrastFileReadOnly = true; + } + else + { + IsCustomInfrastFileReadOnly = false; + } + + ConfigurationHelper.SetValue(ConfigurationKeys.DefaultInfrast, value); + } + } + + private bool _isCustomInfrastFileReadOnly = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.IsCustomInfrastFileReadOnly, bool.FalseString)); + + /// + /// Gets or sets a value indicating whether CustomInfrastFile is read-only + /// + public bool IsCustomInfrastFileReadOnly + { + get => _isCustomInfrastFileReadOnly; + set + { + SetAndNotify(ref _isCustomInfrastFileReadOnly, value); + ConfigurationHelper.SetValue(ConfigurationKeys.IsCustomInfrastFileReadOnly, value.ToString()); + } + } + + private bool _dormFilterNotStationedEnabled = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.DormFilterNotStationedEnabled, bool.TrueString)); + + /// + /// Gets or sets a value indicating whether the not stationed filter in dorm is enabled. + /// + public bool DormFilterNotStationedEnabled + { + get => _dormFilterNotStationedEnabled; + set + { + SetAndNotify(ref _dormFilterNotStationedEnabled, value); + ConfigurationHelper.SetValue(ConfigurationKeys.DormFilterNotStationedEnabled, value.ToString()); + } + } + + private bool _dormTrustEnabled = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.DormTrustEnabled, bool.FalseString)); + + /// + /// Gets or sets a value indicating whether trust in dorm is enabled. + /// + public bool DormTrustEnabled + { + get => _dormTrustEnabled; + set + { + SetAndNotify(ref _dormTrustEnabled, value); + ConfigurationHelper.SetValue(ConfigurationKeys.DormTrustEnabled, value.ToString()); + } + } + + private bool _originiumShardAutoReplenishment = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.OriginiumShardAutoReplenishment, bool.TrueString)); + + /// + /// Gets or sets a value indicating whether Originium shard auto replenishment is enabled. + /// + public bool OriginiumShardAutoReplenishment + { + get => _originiumShardAutoReplenishment; + set + { + SetAndNotify(ref _originiumShardAutoReplenishment, value); + ConfigurationHelper.SetValue(ConfigurationKeys.OriginiumShardAutoReplenishment, value.ToString()); + } + } + + private bool _customInfrastEnabled = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.CustomInfrastEnabled, bool.FalseString)); + + public bool CustomInfrastEnabled + { + get => _customInfrastEnabled; + set + { + SetAndNotify(ref _customInfrastEnabled, value); + ConfigurationHelper.SetValue(ConfigurationKeys.CustomInfrastEnabled, value.ToString()); + Instances.TaskQueueViewModel.CustomInfrastEnabled = value; + } + } + + /// + /// Selects infrast config file. + /// + // UI 绑定的方法 + // ReSharper disable once UnusedMember.Global + public void SelectCustomInfrastFile() + { + var dialog = new OpenFileDialog + { + Filter = LocalizationHelper.GetString("CustomInfrastFile") + "|*.json", + }; + + if (dialog.ShowDialog() == true) + { + CustomInfrastFile = dialog.FileName; + } + + DefaultInfrast = UserDefined; + } + + private string _customInfrastFile = ConfigurationHelper.GetValue(ConfigurationKeys.CustomInfrastFile, string.Empty); + + public string CustomInfrastFile + { + get => _customInfrastFile; + set + { + SetAndNotify(ref _customInfrastFile, value); + ConfigurationHelper.SetValue(ConfigurationKeys.CustomInfrastFile, value); + Instances.TaskQueueViewModel.RefreshCustomInfrastPlan(); + + // SetAndNotify 在值没有变化时不会触发 PropertyChanged 事件,所以这里手动触发一下 + Instances.TaskQueueViewModel.NeedAddCustomInfrastPlanInfo = false; + { + Instances.TaskQueueViewModel.CustomInfrastPlanIndex--; + Instances.TaskQueueViewModel.CustomInfrastPlanIndex++; + } + + Instances.TaskQueueViewModel.NeedAddCustomInfrastPlanInfo = true; + } + } +} diff --git a/src/MaaWpfGui/Views/UI/TaskQueueView.xaml b/src/MaaWpfGui/Views/UI/TaskQueueView.xaml index d93739e869..23f84a3b18 100644 --- a/src/MaaWpfGui/Views/UI/TaskQueueView.xaml +++ b/src/MaaWpfGui/Views/UI/TaskQueueView.xaml @@ -251,11 +251,12 @@ DataContext="{Binding TaskSettingDataContext}" IsEnabled="{Binding Idle}" Visibility="{c:Binding TaskSettingVisibilities.WakeUp}" /> - + - + + IsEnabled="{Binding Idle, Source={x:Static setting:TaskQueueViewModel.TaskSettingDataContext}}" />