优化界面

This commit is contained in:
waynebian01
2026-07-29 17:24:46 +08:00
parent 8d5de52861
commit 3ecba771ad
9 changed files with 528 additions and 79 deletions

View File

@@ -1449,7 +1449,24 @@ public sealed class ModuleEditorControl : UserControl
Count
}
private sealed record RuleRowValues(bool Enabled, string Spell, string UnitText, string Condition, IReadOnlyList<string> SubConditions);
private sealed record RuleRowValues(
bool Enabled,
string Spell,
string UnitText,
string Condition,
IReadOnlyList<string> SubConditions,
int? DelayMs,
int? LogicDelayMs);
private sealed class RuleRowMetadata(
IEnumerable<string>? subConditions = null,
int? delayMs = null,
int? logicDelayMs = null)
{
public List<string> SubConditions { get; } = subConditions?.ToList() ?? new List<string>();
public int? DelayMs { get; set; } = delayMs;
public int? LogicDelayMs { get; set; } = logicDelayMs;
}
private void ApplyColumnWidths(Dictionary<string, int>? widths)
{
@@ -1562,21 +1579,45 @@ public sealed class ModuleEditorControl : UserControl
// 「条件」列在有子条件时显示成 "主条件 且任一(子1 | 子2)"; 仅改显示, 底层值仍是主条件, 不影响 ReadRules 存盘。
if (columnName == "Condition" && !row.IsNewRow)
{
e.Value = DecorateCondition(e.Value?.ToString() ?? string.Empty, row.Tag as List<string>);
var metadata = GetRuleMetadata(row);
e.Value = DecorateCondition(
e.Value?.ToString() ?? string.Empty,
metadata.SubConditions,
metadata.DelayMs,
metadata.LogicDelayMs);
e.FormattingApplied = true;
}
}
// 把主条件子条件合成可读文本(与 ModuleRule.DescribeCondition / 弹窗预览同形)。无子条件时原样返回
private static string DecorateCondition(string main, List<string>? subs)
// 把主条件子条件和规则延迟合成可读文本;仅改显示,不改变底层条件表达式
private static string DecorateCondition(
string main,
IReadOnlyList<string>? subs,
int? delayMs,
int? logicDelayMs)
{
if (subs is not { Count: > 0 })
var conditionText = main;
if (subs is { Count: > 0 })
{
return main;
var any = string.Join(" | ", subs);
conditionText = main.Length == 0 ? $"任一({any})" : $"{main} 且任一({any})";
}
var any = string.Join(" | ", subs);
return main.Length == 0 ? $"任一({any})" : $"{main} 且任一({any})";
if (delayMs is > 0)
{
conditionText = conditionText.Length == 0
? $"延迟 {delayMs.Value} ms"
: $"{conditionText};延迟 {delayMs.Value} ms";
}
if (logicDelayMs is > 0)
{
conditionText = conditionText.Length == 0
? $"逻辑延迟 {logicDelayMs.Value} ms"
: $"{conditionText};逻辑延迟 {logicDelayMs.Value} ms";
}
return conditionText;
}
private void OnRulesGridCellPainting(object? sender, DataGridViewCellPaintingEventArgs e)
@@ -1678,8 +1719,13 @@ public sealed class ModuleEditorControl : UserControl
var text = CellText(row, columnName);
if (columnName == "Condition")
{
// 提示与裁剪检测都用合成后的完整文本(含子条件), 与单元格显示一致。
text = DecorateCondition(text, row.Tag as List<string>);
// 提示与裁剪检测都用合成后的完整文本(含子条件和延迟), 与单元格显示一致。
var metadata = GetRuleMetadata(row);
text = DecorateCondition(
text,
metadata.SubConditions,
metadata.DelayMs,
metadata.LogicDelayMs);
if (text.Length == 0)
{
return "点击编辑条件 (当前: 始终命中)";
@@ -2040,7 +2086,14 @@ public sealed class ModuleEditorControl : UserControl
return;
}
InsertRuleAfter(rowIndex, new RuleRowValues(true, string.Empty, string.Empty, string.Empty, Array.Empty<string>()));
InsertRuleAfter(rowIndex, new RuleRowValues(
true,
string.Empty,
string.Empty,
string.Empty,
Array.Empty<string>(),
null,
null));
}
private void InsertRuleAfter(int rowIndex, RuleRowValues values)
@@ -2250,8 +2303,10 @@ public sealed class ModuleEditorControl : UserControl
CellText(row, "Spell"),
CellText(row, "Unit"),
CellText(row, "Condition"),
// 子条件挂在 row.Tag, 随行一起被移动/拖拽/复制搬运。
row.Tag as List<string> ?? new List<string>());
// 子条件和延迟挂在 row.Tag, 随行一起被移动/拖拽/复制搬运。
GetRuleMetadata(row).SubConditions,
GetRuleMetadata(row).DelayMs,
GetRuleMetadata(row).LogicDelayMs);
}
private void WriteRuleRow(DataGridViewRow row, RuleRowValues values)
@@ -2260,7 +2315,7 @@ public sealed class ModuleEditorControl : UserControl
EnsureComboItem(_spellColumn, values.Spell);
row.Cells["Spell"].Value = values.Spell;
row.Cells["Condition"].Value = values.Condition;
row.Tag = new List<string>(values.SubConditions);
row.Tag = new RuleRowMetadata(values.SubConditions, values.DelayMs, values.LogicDelayMs);
RebuildUnitCell(row, values.UnitText);
}
@@ -2268,10 +2323,17 @@ public sealed class ModuleEditorControl : UserControl
{
var row = _rulesGrid.Rows[rowIndex];
var current = row.IsNewRow ? string.Empty : CellText(row, "Condition");
var currentSubs = row.IsNewRow ? null : row.Tag as List<string>;
var fields = BuildConditionFields();
var currentMetadata = row.IsNewRow ? new RuleRowMetadata() : GetRuleMetadata(row);
var fields = BuildConditionFields(includeRuleSettings: true);
using var editor = new ConditionEditorForm(fields, current, currentSubs, allowSubConditions: true);
using var editor = new ConditionEditorForm(
fields,
current,
currentMetadata.SubConditions,
allowSubConditions: true,
delayMs: currentMetadata.DelayMs,
logicDelayMs: currentMetadata.LogicDelayMs,
allowRuleSettings: true);
if (editor.ShowDialog(FindForm()) != DialogResult.OK)
{
return;
@@ -2281,29 +2343,53 @@ public sealed class ModuleEditorControl : UserControl
if (row.IsNewRow)
{
// 新行占位符不能直接赋值, 改为追加一行(主条件或子条件任一非空即可)。
if (!string.IsNullOrWhiteSpace(editor.ConditionText) || subs.Count > 0)
if (!string.IsNullOrWhiteSpace(editor.ConditionText)
|| subs.Count > 0
|| editor.DelayMs is > 0
|| editor.LogicDelayMs is > 0)
{
var index = _rulesGrid.Rows.Add(true, string.Empty, string.Empty, editor.ConditionText);
_rulesGrid.Rows[index].Tag = subs;
_rulesGrid.Rows[index].Tag = new RuleRowMetadata(
subs,
editor.DelayMs,
editor.LogicDelayMs);
}
return;
}
row.Cells["Condition"].Value = editor.ConditionText;
row.Tag = subs;
row.Tag = new RuleRowMetadata(subs, editor.DelayMs, editor.LogicDelayMs);
// 让「条件」列的装饰显示(主条件 且任一(…))立即刷新。
_rulesGrid.InvalidateRow(rowIndex);
}
// 条件字段 = 状态/技能字段 + 每个动态单位的裸名(存在)和值名称 + 每个数量名。
private IReadOnlyList<ConditionField> BuildConditionFields()
private IReadOnlyList<ConditionField> BuildConditionFields(bool includeRuleSettings = false)
{
var classId = ReadMatchCombo(_classBox);
var specId = ReadMatchCombo(_specBox);
var fields = new List<ConditionField>(_fieldCatalog.GetFields(classId, specId));
var seen = new HashSet<string>(fields.Select(field => field.Name), StringComparer.Ordinal);
if (includeRuleSettings && seen.Add(ShigureConditionFields.Delay))
{
fields.Add(new ConditionField(
ShigureConditionFields.Delay,
"延迟 (ms)",
ConditionFieldType.Int,
ConditionFieldCategory.Shigure));
}
if (includeRuleSettings && seen.Add(ShigureConditionFields.LogicDelay))
{
fields.Add(new ConditionField(
ShigureConditionFields.LogicDelay,
"逻辑延迟 (ms)",
ConditionFieldType.Int,
ConditionFieldCategory.Shigure));
}
foreach (var unit in _units)
{
if (string.IsNullOrWhiteSpace(unit.Name))
@@ -2470,9 +2556,10 @@ public sealed class ModuleEditorControl : UserControl
EnsureComboItem(_spellColumn, rule.Spell);
// 先加行(目标先留空), 再按技能重建目标选项并写回目标值, 避免值不在选项内被吞掉。
var index = _rulesGrid.Rows.Add(rule.Enabled, rule.Spell, string.Empty, rule.Condition);
_rulesGrid.Rows[index].Tag = rule.SubConditions is null
? new List<string>()
: new List<string>(rule.SubConditions);
_rulesGrid.Rows[index].Tag = new RuleRowMetadata(
rule.SubConditions,
rule.DelayMs,
rule.LogicDelayMs);
RebuildUnitCell(_rulesGrid.Rows[index], unitText);
}
}
@@ -2719,16 +2806,20 @@ public sealed class ModuleEditorControl : UserControl
var condition = CellText(row, "Condition");
var spell = CellText(row, "Spell");
var unitText = CellText(row, "Unit");
var metadata = GetRuleMetadata(row);
if (string.IsNullOrWhiteSpace(condition)
&& string.IsNullOrWhiteSpace(spell)
&& string.IsNullOrWhiteSpace(unitText))
&& string.IsNullOrWhiteSpace(unitText)
&& metadata.SubConditions.Count == 0
&& metadata.DelayMs is not > 0
&& metadata.LogicDelayMs is not > 0)
{
continue;
}
// 目标文本命中已定义动态单位名 → UnitName; 否则按数字 → Unit; 都不是则留空。
var isDynamic = unitNames.Contains(unitText);
var subs = (row.Tag as List<string>)?
var subs = metadata.SubConditions
.Select(sub => sub?.Trim() ?? string.Empty)
.Where(sub => sub.Length > 0)
.ToList();
@@ -2741,13 +2832,26 @@ public sealed class ModuleEditorControl : UserControl
Spell = spell,
Hotkey = string.Empty,
Step = string.Empty,
SubConditions = subs is { Count: > 0 } ? subs : null
SubConditions = subs is { Count: > 0 } ? subs : null,
DelayMs = metadata.DelayMs,
LogicDelayMs = metadata.LogicDelayMs
});
}
return rules;
}
private static RuleRowMetadata GetRuleMetadata(DataGridViewRow row)
{
return row.Tag switch
{
RuleRowMetadata metadata => metadata,
// 兼容本次升级前已经加载到控件中的旧 Tag 结构。
List<string> subConditions => new RuleRowMetadata(subConditions),
_ => new RuleRowMetadata()
};
}
private static void AddMatchField(TableLayoutPanel row, string label, ComboBox box, int column)
{
row.Controls.Add(CreateLabel(label), column, 0);