From 7ea94ef014195ed1b7a7cb7970c807b2051db508 Mon Sep 17 00:00:00 2001
From: status102 <102887808+status102@users.noreply.github.com>
Date: Fri, 22 Nov 2024 21:48:21 +0800
Subject: [PATCH] =?UTF-8?q?rft:=20WpfGui=E9=87=8D=E6=9E=84=20=E6=8B=86?=
=?UTF-8?q?=E5=88=86`=E4=B8=80=E9=94=AE=E9=95=BF=E8=8D=89-=E5=9F=BA?=
=?UTF-8?q?=E5=BB=BA=E4=BB=BB=E5=8A=A1`=E4=BB=BB=E5=8A=A1=20(#11219)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* rft: WpfGui重构 拆分`一键长草-基建任务`
* perf: 简化
---
.../RemoteControl/RemoteControlService.cs | 2 +-
.../ViewModels/UI/SettingsViewModel.cs | 622 ++++--------------
.../ViewModels/UI/TaskQueueViewModel.cs | 46 +-
.../InfrastSettingsUserControlModel.cs | 372 +++++++++++
src/MaaWpfGui/Views/UI/TaskQueueView.xaml | 11 +-
.../InfrastSettingsUserControl.xaml | 18 +-
.../InfrastSettingsUserControl.xaml.cs | 4 +-
7 files changed, 556 insertions(+), 519 deletions(-)
create mode 100644 src/MaaWpfGui/ViewModels/UserControl/TaskQueue/InfrastSettingsUserControlModel.cs
rename src/MaaWpfGui/Views/UserControl/{ => TaskQueue}/InfrastSettingsUserControl.xaml (91%)
rename src/MaaWpfGui/Views/UserControl/{ => TaskQueue}/InfrastSettingsUserControl.xaml.cs (97%)
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}}" />
+ IsEnabled="{Binding Idle, Source={x:Static setting:TaskQueueViewModel.TaskSettingDataContext}}" />
diff --git a/src/MaaWpfGui/Views/UserControl/InfrastSettingsUserControl.xaml.cs b/src/MaaWpfGui/Views/UserControl/TaskQueue/InfrastSettingsUserControl.xaml.cs
similarity index 97%
rename from src/MaaWpfGui/Views/UserControl/InfrastSettingsUserControl.xaml.cs
rename to src/MaaWpfGui/Views/UserControl/TaskQueue/InfrastSettingsUserControl.xaml.cs
index b24dcb9ab4..abffb1dba0 100644
--- a/src/MaaWpfGui/Views/UserControl/InfrastSettingsUserControl.xaml.cs
+++ b/src/MaaWpfGui/Views/UserControl/TaskQueue/InfrastSettingsUserControl.xaml.cs
@@ -11,11 +11,11 @@
// but WITHOUT ANY WARRANTY
//
-using System.Windows.Input;
using System.Windows;
using System.Windows.Controls;
+using System.Windows.Input;
-namespace MaaWpfGui.Views.UserControl
+namespace MaaWpfGui.Views.UserControl.TaskQueue
{
///
/// InfrastSettingsUserControl.xaml 的交互逻辑