diff --git a/Fuyutsui/Fuyutsui.toc b/Fuyutsui/Fuyutsui.toc
index afcc1b60..dd1dd19f 100644
--- a/Fuyutsui/Fuyutsui.toc
+++ b/Fuyutsui/Fuyutsui.toc
@@ -1,7 +1,7 @@
## Interface: 120100
## Title: Fuyutsui
-## Version: 1.2.1.10
+## Version: 1.2.1.11
## Author: Wayne Bian
## IconTexture: Interface\AddOns\Fuyutsui\core\Spell_Misc_EmotionHappy.blp
## OptionalDeps: LibRangeCheck-3.0
diff --git a/Fuyutsui/core/config.lua b/Fuyutsui/core/config.lua
index 8c897f04..93baeedf 100644
--- a/Fuyutsui/core/config.lua
+++ b/Fuyutsui/core/config.lua
@@ -80,7 +80,7 @@ Fuyutsui.difficultyToText = {
-- 首领ID
Fuyutsui.bossID = {
[0] = 0, -- 未战斗
- -- 团本
+ -- 虚影尖塔
[3176] = 1, -- 元首阿福扎恩
[3177] = 2, -- 弗拉希乌斯
[3179] = 3, -- 陨落之王萨哈达尔
diff --git a/Shigure.csproj b/Shigure.csproj
index 0bd24453..bb8859ac 100644
--- a/Shigure.csproj
+++ b/Shigure.csproj
@@ -9,9 +9,9 @@
Shigure
Shigure
Arasaka Corporation
- 1.2.1.10
- 1.2.1.10
- 1.2.1.10
+ 1.2.1.11
+ 1.2.1.11
+ 1.2.1.11
Assets\arasaka-icon.ico
PerMonitorV2
diff --git a/UI/ClassConfigEditorControl.cs b/UI/ClassConfigEditorControl.cs
index 5d7f3668..d888125d 100644
--- a/UI/ClassConfigEditorControl.cs
+++ b/UI/ClassConfigEditorControl.cs
@@ -101,8 +101,8 @@ public sealed class ClassConfigEditorControl : UserControl
RowCount = 1,
Margin = new Padding(0)
};
- root.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 154));
- root.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 196));
+ root.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 146));
+ root.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 184));
root.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
Controls.Add(root);
@@ -118,8 +118,8 @@ public sealed class ClassConfigEditorControl : UserControl
Dock = DockStyle.Fill,
ColumnCount = 1,
RowCount = 2,
- Padding = new Padding(14),
- Margin = new Padding(0, 0, 12, 0)
+ Padding = new Padding(UiTheme.CardPadding),
+ Margin = new Padding(0, 0, UiTheme.PageGap, 0)
};
panel.RowStyles.Add(new RowStyle(SizeType.Absolute, 28));
panel.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
@@ -161,8 +161,8 @@ public sealed class ClassConfigEditorControl : UserControl
Dock = DockStyle.Fill,
ColumnCount = 1,
RowCount = 2,
- Padding = new Padding(14),
- Margin = new Padding(0, 0, 12, 0)
+ Padding = new Padding(UiTheme.CardPadding),
+ Margin = new Padding(0, 0, UiTheme.PageGap, 0)
};
panel.RowStyles.Add(new RowStyle(SizeType.Absolute, 28));
panel.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
@@ -199,10 +199,8 @@ public sealed class ClassConfigEditorControl : UserControl
private static void StyleActionButton(Button button)
{
- button.AutoSize = false;
- button.Size = new Size(110, 36);
+ UiTheme.StyleActionButton(button);
button.Margin = new Padding(0, 0, 0, 8);
- button.TextAlign = ContentAlignment.MiddleCenter;
}
private Control BuildEditor()
@@ -217,15 +215,15 @@ public sealed class ClassConfigEditorControl : UserControl
};
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 92));
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
- root.RowStyles.Add(new RowStyle(SizeType.Absolute, 64));
+ root.RowStyles.Add(new RowStyle(SizeType.Absolute, 68));
var header = new UiCardPanel
{
Dock = DockStyle.Fill,
ColumnCount = 2,
RowCount = 2,
- Padding = new Padding(14, 12, 14, 12),
- Margin = new Padding(0, 0, 0, 12)
+ Padding = new Padding(UiTheme.CardPadding, 12, UiTheme.CardPadding, 12),
+ Margin = new Padding(0, 0, 0, UiTheme.PageGap)
};
header.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 56));
header.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
@@ -254,8 +252,8 @@ public sealed class ClassConfigEditorControl : UserControl
Dock = DockStyle.Fill,
ColumnCount = 2,
RowCount = 1,
- Margin = new Padding(0, 12, 0, 0),
- Padding = new Padding(14, 10, 14, 10)
+ Margin = new Padding(0, UiTheme.PageGap, 0, 0),
+ Padding = new Padding(UiTheme.CardPadding, 10, UiTheme.CardPadding, 10)
};
actionRow.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
actionRow.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 228));
@@ -291,7 +289,7 @@ public sealed class ClassConfigEditorControl : UserControl
RowCount = 2,
Margin = new Padding(0)
};
- root.RowStyles.Add(new RowStyle(SizeType.Absolute, 42));
+ root.RowStyles.Add(new RowStyle(SizeType.Absolute, UiTheme.TabBarHeight));
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
var tabBar = new TableLayoutPanel
@@ -314,7 +312,7 @@ public sealed class ClassConfigEditorControl : UserControl
ColumnCount = 1,
RowCount = 1,
Margin = new Padding(0),
- Padding = new Padding(14)
+ Padding = new Padding(0)
};
contentCard.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
contentCard.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
@@ -341,6 +339,7 @@ public sealed class ClassConfigEditorControl : UserControl
page.Dock = DockStyle.Fill;
page.Visible = false;
page.BackColor = UiTheme.SurfaceRaised;
+ page.Padding = new Padding(UiTheme.CardPadding);
contentHost.Controls.Add(page);
}
@@ -971,10 +970,10 @@ public sealed class ClassConfigEditorControl : UserControl
};
var up = UiTheme.CreateButton("▲", UiTheme.Field, UiTheme.Text);
var down = UiTheme.CreateButton("▼", UiTheme.Field, UiTheme.Text);
- up.AutoSize = false;
- down.AutoSize = false;
- up.Size = new Size(48, 32);
- down.Size = new Size(48, 32);
+ UiTheme.StyleActionButton(up, 48);
+ UiTheme.StyleActionButton(down, 48);
+ up.Margin = new Padding(0, 4, 8, 4);
+ down.Margin = new Padding(0, 4, 0, 4);
up.Click += (_, _) => MoveSelectedRow(grid, -1);
down.Click += (_, _) => MoveSelectedRow(grid, 1);
bar.Controls.Add(up);
diff --git a/UI/ClassMacrosEditorControl.cs b/UI/ClassMacrosEditorControl.cs
index 827295eb..2416b6c9 100644
--- a/UI/ClassMacrosEditorControl.cs
+++ b/UI/ClassMacrosEditorControl.cs
@@ -64,7 +64,7 @@ public sealed class ClassMacrosEditorControl : UserControl
RowCount = 1,
Margin = new Padding(0)
};
- root.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 154));
+ root.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 146));
root.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
Controls.Add(root);
@@ -79,8 +79,8 @@ public sealed class ClassMacrosEditorControl : UserControl
Dock = DockStyle.Fill,
ColumnCount = 1,
RowCount = 2,
- Padding = new Padding(14),
- Margin = new Padding(0, 0, 12, 0)
+ Padding = new Padding(UiTheme.CardPadding),
+ Margin = new Padding(0, 0, UiTheme.PageGap, 0)
};
panel.RowStyles.Add(new RowStyle(SizeType.Absolute, 28));
panel.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
@@ -115,10 +115,8 @@ public sealed class ClassMacrosEditorControl : UserControl
private static void StyleActionButton(Button button)
{
- button.AutoSize = false;
- button.Size = new Size(110, 36);
+ UiTheme.StyleActionButton(button);
button.Margin = new Padding(0, 0, 0, 8);
- button.TextAlign = ContentAlignment.MiddleCenter;
}
private Control BuildEditor()
@@ -134,15 +132,15 @@ public sealed class ClassMacrosEditorControl : UserControl
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 92));
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 36));
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
- root.RowStyles.Add(new RowStyle(SizeType.Absolute, 64));
+ root.RowStyles.Add(new RowStyle(SizeType.Absolute, 68));
var header = new UiCardPanel
{
Dock = DockStyle.Fill,
ColumnCount = 2,
RowCount = 2,
- Padding = new Padding(14, 12, 14, 12),
- Margin = new Padding(0, 0, 0, 12)
+ Padding = new Padding(UiTheme.CardPadding, 12, UiTheme.CardPadding, 12),
+ Margin = new Padding(0, 0, 0, UiTheme.PageGap)
};
header.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 56));
header.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
@@ -182,8 +180,8 @@ public sealed class ClassMacrosEditorControl : UserControl
Dock = DockStyle.Fill,
ColumnCount = 2,
RowCount = 1,
- Margin = new Padding(0, 12, 0, 0),
- Padding = new Padding(14, 10, 14, 10)
+ Margin = new Padding(0, UiTheme.PageGap, 0, 0),
+ Padding = new Padding(UiTheme.CardPadding, 10, UiTheme.CardPadding, 10)
};
actionRow.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
actionRow.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 228));
@@ -219,7 +217,7 @@ public sealed class ClassMacrosEditorControl : UserControl
RowCount = 2,
Margin = new Padding(0)
};
- root.RowStyles.Add(new RowStyle(SizeType.Absolute, 42));
+ root.RowStyles.Add(new RowStyle(SizeType.Absolute, UiTheme.TabBarHeight));
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
var tabBar = new TableLayoutPanel
@@ -242,7 +240,7 @@ public sealed class ClassMacrosEditorControl : UserControl
ColumnCount = 1,
RowCount = 1,
Margin = new Padding(0),
- Padding = new Padding(14)
+ Padding = new Padding(0)
};
contentCard.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
contentCard.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
@@ -267,6 +265,7 @@ public sealed class ClassMacrosEditorControl : UserControl
page.Dock = DockStyle.Fill;
page.Visible = false;
page.BackColor = UiTheme.SurfaceRaised;
+ page.Padding = new Padding(UiTheme.CardPadding);
contentHost.Controls.Add(page);
}
@@ -318,7 +317,7 @@ public sealed class ClassMacrosEditorControl : UserControl
BackColor = UiTheme.SurfaceRaised,
Margin = new Padding(0)
};
- root.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 196));
+ root.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 184));
root.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
root.Controls.Add(BuildDynamicSpecSidebar(), 0, 0);
@@ -509,10 +508,10 @@ public sealed class ClassMacrosEditorControl : UserControl
};
var up = UiTheme.CreateButton("▲", UiTheme.Field, UiTheme.Text);
var down = UiTheme.CreateButton("▼", UiTheme.Field, UiTheme.Text);
- up.AutoSize = false;
- down.AutoSize = false;
- up.Size = new Size(48, 32);
- down.Size = new Size(48, 32);
+ UiTheme.StyleActionButton(up, 48);
+ UiTheme.StyleActionButton(down, 48);
+ up.Margin = new Padding(0, 4, 8, 4);
+ down.Margin = new Padding(0, 4, 0, 4);
up.Click += (_, _) => MoveSelectedRow(grid, -1);
down.Click += (_, _) => MoveSelectedRow(grid, 1);
bar.Controls.Add(up);
diff --git a/UI/ConditionEditorForm.cs b/UI/ConditionEditorForm.cs
index 306b6220..03e47676 100644
--- a/UI/ConditionEditorForm.cs
+++ b/UI/ConditionEditorForm.cs
@@ -314,7 +314,8 @@ public sealed class ConditionEditorForm : Form
{
Text = "编辑条件";
Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
- BackColor = UiTheme.Background;
+ AutoScaleMode = AutoScaleMode.Dpi;
+ BackColor = UiTheme.Surface;
ForeColor = UiTheme.Text;
var initialHeight = _allowSubConditions ? 650 : 460;
ClientSize = new Size(1080, initialHeight);
@@ -328,8 +329,8 @@ public sealed class ConditionEditorForm : Form
var root = new TableLayoutPanel
{
Dock = DockStyle.Fill,
- BackColor = UiTheme.Background,
- Padding = new Padding(12, 10, 12, 10),
+ BackColor = UiTheme.Surface,
+ Padding = new Padding(UiTheme.CardPadding, 10, UiTheme.CardPadding, 10),
ColumnCount = 1
};
Controls.Add(root);
@@ -338,15 +339,11 @@ public sealed class ConditionEditorForm : Form
var rowIndex = 0;
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
- root.Controls.Add(_conditionsGrid, 0, rowIndex++);
-
- // 「添加条件」紧贴主条件行下方, 明确它作用于上面的主条件(而非子条件)。
- root.RowStyles.Add(new RowStyle(SizeType.Absolute, 48));
- root.Controls.Add(BuildAddConditionRow(), 0, rowIndex++);
+ root.Controls.Add(BuildConditionsCard(), 0, rowIndex++);
if (_allowSubConditions)
{
- root.RowStyles.Add(new RowStyle(SizeType.Absolute, 188));
+ root.RowStyles.Add(new RowStyle(SizeType.Absolute, 200));
root.Controls.Add(BuildSubConditionsPanel(), 0, rowIndex++);
}
@@ -355,23 +352,50 @@ public sealed class ConditionEditorForm : Form
_previewLabel.TextAlign = ContentAlignment.MiddleLeft;
_previewLabel.AutoEllipsis = true;
_previewLabel.Margin = new Padding(0);
- root.RowStyles.Add(new RowStyle(SizeType.Absolute, 28));
- root.Controls.Add(_previewLabel, 0, rowIndex++);
+ var previewCard = new UiCardPanel
+ {
+ Dock = DockStyle.Fill,
+ Padding = new Padding(UiTheme.CardPadding, 6, UiTheme.CardPadding, 6),
+ Margin = new Padding(0, 0, 0, UiTheme.PageGap),
+ ColumnCount = 1,
+ RowCount = 1
+ };
+ previewCard.Controls.Add(_previewLabel, 0, 0);
+ root.RowStyles.Add(new RowStyle(SizeType.Absolute, 48));
+ root.Controls.Add(previewCard, 0, rowIndex++);
- root.RowStyles.Add(new RowStyle(SizeType.Absolute, 40));
+ root.RowStyles.Add(new RowStyle(SizeType.Absolute, 56));
root.Controls.Add(BuildActionRow(), 0, rowIndex++);
root.RowCount = rowIndex;
}
+ private Control BuildConditionsCard()
+ {
+ var card = new UiCardPanel
+ {
+ Dock = DockStyle.Fill,
+ Padding = new Padding(UiTheme.CardPadding),
+ Margin = new Padding(0, 0, 0, UiTheme.PageGap),
+ ColumnCount = 1,
+ RowCount = 2
+ };
+ card.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
+ card.RowStyles.Add(new RowStyle(SizeType.Absolute, 44));
+ _conditionsGrid.Margin = new Padding(0);
+ card.Controls.Add(_conditionsGrid, 0, 0);
+ card.Controls.Add(BuildAddConditionRow(), 0, 1);
+ return card;
+ }
+
// 子条件区: 标题 + 暗色列表 + 添加/编辑/删除。每条子条件本身也是一条完整条件,
// 通过嵌套的(无子条件区的)条件编辑弹窗来编辑。
private Control BuildSubConditionsPanel()
{
- var panel = new TableLayoutPanel
+ var panel = new UiCardPanel
{
Dock = DockStyle.Fill,
- BackColor = UiTheme.Background,
- Margin = new Padding(0, 4, 0, 4),
+ Padding = new Padding(UiTheme.CardPadding),
+ Margin = new Padding(0, 0, 0, UiTheme.PageGap),
ColumnCount = 2,
RowCount = 2
};
@@ -392,10 +416,8 @@ public sealed class ConditionEditorForm : Form
panel.SetColumnSpan(title, 2);
_subList.Dock = DockStyle.Fill;
- _subList.BackColor = UiTheme.Field;
- _subList.ForeColor = UiTheme.Text;
- _subList.BorderStyle = BorderStyle.FixedSingle;
- _subList.IntegralHeight = false;
+ UiTheme.StyleListBox(_subList, Font);
+ _subList.BackColor = UiTheme.Surface;
_subList.Margin = new Padding(0, 0, 12, 0);
_subList.DoubleClick += (_, _) => EditSelectedSubCondition();
panel.Controls.Add(_subList, 0, 1);
@@ -405,7 +427,7 @@ public sealed class ConditionEditorForm : Form
Dock = DockStyle.Fill,
FlowDirection = FlowDirection.TopDown,
WrapContents = false,
- BackColor = UiTheme.Background,
+ BackColor = Color.Transparent,
Margin = new Padding(0),
Padding = new Padding(0, 0, 4, 0)
};
@@ -940,8 +962,8 @@ public sealed class ConditionEditorForm : Form
Dock = DockStyle.Fill,
FlowDirection = FlowDirection.LeftToRight,
WrapContents = false,
- BackColor = UiTheme.Background,
- Margin = new Padding(0, 4, 0, 4)
+ BackColor = Color.Transparent,
+ Margin = new Padding(0, 8, 0, 0)
};
var addButton = UiTheme.CreateButton("添加条件", UiTheme.Field, UiTheme.Text);
@@ -955,8 +977,9 @@ public sealed class ConditionEditorForm : Form
var row = AddRow(null);
RefreshConnectors();
UpdatePreview();
- _conditionsGrid.CurrentCell = row.Cells[TypeColumn];
- _conditionsGrid.BeginEdit(true);
+ ShowConditionComboDropDown(
+ row.Index,
+ _conditionsGrid.Columns[TypeColumn]!.Index);
};
panel.Controls.Add(addButton);
return panel;
@@ -964,36 +987,35 @@ public sealed class ConditionEditorForm : Form
private Control BuildActionRow()
{
- var row = new TableLayoutPanel
+ var row = new UiCardPanel
{
Dock = DockStyle.Fill,
- BackColor = UiTheme.Background,
Margin = new Padding(0),
+ Padding = new Padding(UiTheme.CardPadding, 10, UiTheme.CardPadding, 10),
ColumnCount = 2,
RowCount = 1
};
row.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
- row.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 170));
+ row.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 184));
+ row.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
var rightButtons = new FlowLayoutPanel
{
Dock = DockStyle.Fill,
FlowDirection = FlowDirection.RightToLeft,
WrapContents = false,
- BackColor = UiTheme.Background,
+ BackColor = Color.Transparent,
Margin = new Padding(0)
};
- var okButton = UiTheme.CreateButton("确定", UiTheme.Accent, Color.Black);
- okButton.Width = 72;
- okButton.Height = 30;
- okButton.Margin = new Padding(6, 4, 0, 0);
+ var okButton = UiTheme.CreateButton("确定", UiTheme.ButtonKind.Primary);
+ UiTheme.StyleActionButton(okButton, 80);
+ okButton.Margin = new Padding(8, 0, 0, 0);
okButton.Click += (_, _) => TryConfirm();
- var cancelButton = UiTheme.CreateButton("取消", UiTheme.Field, UiTheme.Text);
- cancelButton.Width = 72;
- cancelButton.Height = 30;
- cancelButton.Margin = new Padding(6, 4, 0, 0);
+ var cancelButton = UiTheme.CreateButton("取消", UiTheme.ButtonKind.Secondary);
+ UiTheme.StyleActionButton(cancelButton, 80);
+ cancelButton.Margin = new Padding(8, 0, 0, 0);
cancelButton.Click += (_, _) => DialogResult = DialogResult.Cancel;
rightButtons.Controls.Add(okButton);
diff --git a/UI/FormulaEditorForm.cs b/UI/FormulaEditorForm.cs
index 1e247387..24375bd8 100644
--- a/UI/FormulaEditorForm.cs
+++ b/UI/FormulaEditorForm.cs
@@ -24,7 +24,8 @@ public sealed class FormulaEditorForm : Form
{
Text = "编辑公式";
Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
- BackColor = UiTheme.Background;
+ AutoScaleMode = AutoScaleMode.Dpi;
+ BackColor = UiTheme.Surface;
ForeColor = UiTheme.Text;
ClientSize = new Size(760, 260);
FormBorderStyle = FormBorderStyle.FixedDialog;
@@ -36,55 +37,78 @@ public sealed class FormulaEditorForm : Form
var root = new TableLayoutPanel
{
Dock = DockStyle.Fill,
- BackColor = UiTheme.Background,
- Padding = new Padding(12),
+ BackColor = UiTheme.Surface,
+ Padding = new Padding(UiTheme.CardPadding, 12, UiTheme.CardPadding, 12),
ColumnCount = 1,
RowCount = 2
};
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
- root.RowStyles.Add(new RowStyle(SizeType.Absolute, 40));
+ root.RowStyles.Add(new RowStyle(SizeType.Absolute, 56));
Controls.Add(root);
_formulaBox.Multiline = true;
_formulaBox.ScrollBars = ScrollBars.Vertical;
_formulaBox.Text = FormulaText;
_formulaBox.Dock = DockStyle.Fill;
- _formulaBox.Margin = new Padding(0, 0, 0, 8);
+ _formulaBox.Margin = new Padding(0);
UiTheme.StyleTextBox(_formulaBox);
- root.Controls.Add(_formulaBox, 0, 0);
+ var editorCard = new UiCardPanel
+ {
+ Dock = DockStyle.Fill,
+ Padding = new Padding(UiTheme.CardPadding),
+ Margin = new Padding(0, 0, 0, UiTheme.PageGap),
+ ColumnCount = 1,
+ RowCount = 2
+ };
+ editorCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 28));
+ editorCard.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
+ editorCard.Controls.Add(UiTheme.CreateSectionTitle(Font, "公式表达式"), 0, 0);
+ editorCard.Controls.Add(_formulaBox, 0, 1);
+ root.Controls.Add(editorCard, 0, 0);
root.Controls.Add(BuildActionRow(), 0, 1);
}
private Control BuildActionRow()
{
- var row = new FlowLayoutPanel
+ var row = new UiCardPanel
+ {
+ Dock = DockStyle.Fill,
+ Padding = new Padding(UiTheme.CardPadding, 10, UiTheme.CardPadding, 10),
+ Margin = new Padding(0),
+ ColumnCount = 2,
+ RowCount = 1
+ };
+ row.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
+ row.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 184));
+ row.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
+
+ var actions = new FlowLayoutPanel
{
Dock = DockStyle.Fill,
FlowDirection = FlowDirection.RightToLeft,
WrapContents = false,
- BackColor = UiTheme.Background,
+ BackColor = Color.Transparent,
Margin = new Padding(0)
};
- var okButton = UiTheme.CreateButton("确定", UiTheme.Accent, Color.Black);
- okButton.Width = 72;
- okButton.Height = 30;
- okButton.Margin = new Padding(6, 6, 0, 0);
+ var okButton = UiTheme.CreateButton("确定", UiTheme.ButtonKind.Primary);
+ UiTheme.StyleActionButton(okButton, 84);
+ okButton.Margin = new Padding(8, 0, 0, 0);
okButton.Click += (_, _) =>
{
FormulaText = _formulaBox.Text.Trim();
DialogResult = DialogResult.OK;
};
- var cancelButton = UiTheme.CreateButton("取消", UiTheme.Field, UiTheme.Text);
- cancelButton.Width = 72;
- cancelButton.Height = 30;
- cancelButton.Margin = new Padding(6, 6, 0, 0);
+ var cancelButton = UiTheme.CreateButton("取消", UiTheme.ButtonKind.Secondary);
+ UiTheme.StyleActionButton(cancelButton, 84);
+ cancelButton.Margin = new Padding(8, 0, 0, 0);
cancelButton.Click += (_, _) => DialogResult = DialogResult.Cancel;
- row.Controls.Add(okButton);
- row.Controls.Add(cancelButton);
+ actions.Controls.Add(okButton);
+ actions.Controls.Add(cancelButton);
+ row.Controls.Add(actions, 1, 0);
AcceptButton = okButton;
CancelButton = cancelButton;
return row;
diff --git a/UI/MainForm.cs b/UI/MainForm.cs
index 6c278cd2..159859db 100644
--- a/UI/MainForm.cs
+++ b/UI/MainForm.cs
@@ -741,32 +741,15 @@ public sealed class MainForm : Form, IMessageFilter
};
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50));
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50));
- const int settingsCardHeight = 232;
- const int settingsCardGap = 14;
- const int settingsActionButtonHeight = 36;
- // 第一行包含 14px 下间距;第二行无需间距,因此卡片的实际高度均为 232px。
+ const int settingsCardHeight = 190;
+ const int settingsCardGap = UiTheme.PageGap;
+ const int settingsActionButtonHeight = UiTheme.ActionButtonHeight;
panel.RowStyles.Add(new RowStyle(SizeType.Absolute, settingsCardHeight + settingsCardGap));
panel.RowStyles.Add(new RowStyle(SizeType.Absolute, settingsCardHeight + settingsCardGap));
panel.RowStyles.Add(new RowStyle(SizeType.Absolute, settingsCardHeight));
- Label CreateTitle(string text) => new()
- {
- Text = text,
- Dock = DockStyle.Fill,
- ForeColor = UiTheme.Text,
- Font = new Font(Font.FontFamily, 11F, FontStyle.Bold),
- TextAlign = ContentAlignment.MiddleLeft,
- Margin = new Padding(0)
- };
- Label CreateDescription(string text) => new()
- {
- Text = text,
- Dock = DockStyle.Fill,
- ForeColor = UiTheme.Muted,
- AutoEllipsis = true,
- TextAlign = ContentAlignment.MiddleLeft,
- Margin = new Padding(0)
- };
+ Label CreateTitle(string text) => UiTheme.CreateSectionTitle(Font, text);
+ Label CreateDescription(string text) => UiTheme.CreateDescription(text);
Label CreateSettingLabel(string text) => new()
{
Text = text,
@@ -781,13 +764,13 @@ public sealed class MainForm : Form, IMessageFilter
Dock = DockStyle.Fill,
ColumnCount = 2,
RowCount = 4,
- Padding = new Padding(18),
- Margin = new Padding(0, 0, 7, 14)
+ Padding = new Padding(UiTheme.CardPadding),
+ Margin = new Padding(0, 0, settingsCardGap / 2, settingsCardGap)
};
inputCard.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 100));
inputCard.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
inputCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 32));
- inputCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 38));
+ inputCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 30));
inputCard.RowStyles.Add(new RowStyle(SizeType.Absolute, settingsActionButtonHeight + 8));
inputCard.RowStyles.Add(new RowStyle(SizeType.Absolute, settingsActionButtonHeight + 8));
inputCard.Controls.Add(CreateTitle("输入与运行"), 0, 0);
@@ -822,11 +805,11 @@ public sealed class MainForm : Form, IMessageFilter
Dock = DockStyle.Fill,
ColumnCount = 1,
RowCount = 4,
- Padding = new Padding(18),
- Margin = new Padding(7, 0, 0, 14)
+ Padding = new Padding(UiTheme.CardPadding),
+ Margin = new Padding(settingsCardGap / 2, 0, 0, settingsCardGap)
};
configCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 32));
- configCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 38));
+ configCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 30));
configCard.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
configCard.RowStyles.Add(new RowStyle(SizeType.Absolute, settingsActionButtonHeight));
configCard.Controls.Add(CreateTitle("配置同步"), 0, 0);
@@ -852,13 +835,13 @@ public sealed class MainForm : Form, IMessageFilter
Dock = DockStyle.Fill,
ColumnCount = 2,
RowCount = 4,
- Padding = new Padding(18),
- Margin = new Padding(0, 0, 7, settingsCardGap)
+ Padding = new Padding(UiTheme.CardPadding),
+ Margin = new Padding(0, 0, settingsCardGap / 2, settingsCardGap)
};
moduleCard.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
- moduleCard.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 140));
+ moduleCard.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 132));
moduleCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 32));
- moduleCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 38));
+ moduleCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 30));
moduleCard.RowStyles.Add(new RowStyle(SizeType.Absolute, settingsActionButtonHeight));
moduleCard.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
moduleCard.Controls.Add(CreateTitle("模块选择"), 0, 0);
@@ -902,11 +885,11 @@ public sealed class MainForm : Form, IMessageFilter
Dock = DockStyle.Fill,
ColumnCount = 1,
RowCount = 4,
- Padding = new Padding(18),
- Margin = new Padding(7, 0, 0, settingsCardGap)
+ Padding = new Padding(UiTheme.CardPadding),
+ Margin = new Padding(settingsCardGap / 2, 0, 0, settingsCardGap)
};
getModulesCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 32));
- getModulesCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 38));
+ getModulesCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 30));
getModulesCard.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
getModulesCard.RowStyles.Add(new RowStyle(SizeType.Absolute, settingsActionButtonHeight));
getModulesCard.Controls.Add(CreateTitle("获取模块"), 0, 0);
@@ -969,11 +952,11 @@ public sealed class MainForm : Form, IMessageFilter
Dock = DockStyle.Fill,
ColumnCount = 1,
RowCount = 4,
- Padding = new Padding(18),
- Margin = new Padding(0, 0, 7, 0)
+ Padding = new Padding(UiTheme.CardPadding),
+ Margin = new Padding(0, 0, settingsCardGap / 2, 0)
};
layoutCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 32));
- layoutCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 38));
+ layoutCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 30));
layoutCard.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
layoutCard.RowStyles.Add(new RowStyle(SizeType.Absolute, settingsActionButtonHeight));
layoutCard.Controls.Add(CreateTitle("界面布局"), 0, 0);
@@ -1019,11 +1002,11 @@ public sealed class MainForm : Form, IMessageFilter
Dock = DockStyle.Fill,
ColumnCount = 1,
RowCount = 4,
- Padding = new Padding(18),
- Margin = new Padding(7, 0, 0, 0)
+ Padding = new Padding(UiTheme.CardPadding),
+ Margin = new Padding(settingsCardGap / 2, 0, 0, 0)
};
closeBehaviorCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 32));
- closeBehaviorCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 38));
+ closeBehaviorCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 30));
closeBehaviorCard.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
closeBehaviorCard.RowStyles.Add(new RowStyle(SizeType.Absolute, settingsActionButtonHeight));
closeBehaviorCard.Controls.Add(CreateTitle("点击 X 时(关闭窗口按钮)"), 0, 0);
diff --git a/UI/ModuleEditorControl.cs b/UI/ModuleEditorControl.cs
index fc6c3fbc..f2b5ff9f 100644
--- a/UI/ModuleEditorControl.cs
+++ b/UI/ModuleEditorControl.cs
@@ -151,7 +151,7 @@ public sealed class ModuleEditorControl : UserControl
RowCount = 2,
Margin = new Padding(0)
};
- root.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 300));
+ root.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 280));
root.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
root.RowStyles.Add(new RowStyle(SizeType.Absolute, ModuleFooterBarHeight));
@@ -168,8 +168,8 @@ public sealed class ModuleEditorControl : UserControl
var sidebar = new UiCardPanel
{
Dock = DockStyle.Fill,
- Padding = new Padding(14),
- Margin = new Padding(0, 0, 12, 12),
+ Padding = new Padding(UiTheme.CardPadding),
+ Margin = new Padding(0, 0, UiTheme.PageGap, UiTheme.PageGap),
ColumnCount = 1,
RowCount = 1
};
@@ -193,8 +193,8 @@ public sealed class ModuleEditorControl : UserControl
var footer = new UiCardPanel
{
Dock = DockStyle.Fill,
- Padding = new Padding(14, 10, 14, 10),
- Margin = new Padding(0, 0, 12, 0),
+ Padding = new Padding(UiTheme.CardPadding, 10, UiTheme.CardPadding, 10),
+ Margin = new Padding(0, 0, UiTheme.PageGap, 0),
ColumnCount = 3,
RowCount = 1
};
@@ -258,7 +258,7 @@ public sealed class ModuleEditorControl : UserControl
Dock = DockStyle.Fill,
BackColor = UiTheme.Surface,
Padding = new Padding(0),
- Margin = new Padding(0, 0, 0, 12),
+ Margin = new Padding(0, 0, 0, UiTheme.PageGap),
ColumnCount = 1,
RowCount = 3
};
@@ -277,13 +277,13 @@ public sealed class ModuleEditorControl : UserControl
var root = new TableLayoutPanel
{
Dock = DockStyle.Fill,
- Margin = new Padding(0, 12, 0, 0),
+ Margin = new Padding(0, UiTheme.PageGap, 0, 0),
Padding = new Padding(0),
BackColor = UiTheme.Surface,
ColumnCount = 1,
RowCount = 2
};
- root.RowStyles.Add(new RowStyle(SizeType.Absolute, 42));
+ root.RowStyles.Add(new RowStyle(SizeType.Absolute, UiTheme.TabBarHeight));
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
var tabBar = new TableLayoutPanel
@@ -390,7 +390,7 @@ public sealed class ModuleEditorControl : UserControl
BackColor = UiTheme.SurfaceRaised,
ColumnCount = 1,
RowCount = 4,
- Padding = new Padding(14),
+ Padding = new Padding(UiTheme.CardPadding),
Margin = new Padding(0)
};
@@ -415,7 +415,7 @@ public sealed class ModuleEditorControl : UserControl
BackColor = UiTheme.SurfaceRaised,
ColumnCount = 1,
RowCount = 1,
- Padding = new Padding(14),
+ Padding = new Padding(UiTheme.CardPadding),
Margin = new Padding(0)
};
@@ -432,7 +432,7 @@ public sealed class ModuleEditorControl : UserControl
BackColor = UiTheme.SurfaceRaised,
ColumnCount = 2,
RowCount = 1,
- Padding = new Padding(14),
+ Padding = new Padding(UiTheme.CardPadding),
Margin = new Padding(0)
};
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
@@ -499,8 +499,8 @@ public sealed class ModuleEditorControl : UserControl
Dock = DockStyle.Fill,
ColumnCount = 4,
RowCount = 2,
- Padding = new Padding(14, 10, 14, 8),
- Margin = new Padding(0, 0, 0, 12)
+ Padding = new Padding(UiTheme.CardPadding, 10, UiTheme.CardPadding, 8),
+ Margin = new Padding(0, 0, 0, UiTheme.PageGap)
};
// 名称/作者各占剩余宽度的一半, 两个输入框等宽并铺满窗口。
row.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 58));
@@ -551,7 +551,7 @@ public sealed class ModuleEditorControl : UserControl
Dock = DockStyle.Fill,
ColumnCount = 12,
RowCount = 2,
- Padding = new Padding(14),
+ Padding = new Padding(UiTheme.CardPadding),
Margin = new Padding(0)
};
foreach (var label in matchLabels)
@@ -3161,7 +3161,7 @@ public sealed class ModuleEditorControl : UserControl
ColumnCount = 3,
RowCount = 1,
Margin = new Padding(0),
- Padding = new Padding(14, 10, 14, 10)
+ Padding = new Padding(UiTheme.CardPadding, 10, UiTheme.CardPadding, 10)
};
row.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 148));
row.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
diff --git a/UI/RuleTextEditorForm.cs b/UI/RuleTextEditorForm.cs
index 71b5a392..7d3842cc 100644
--- a/UI/RuleTextEditorForm.cs
+++ b/UI/RuleTextEditorForm.cs
@@ -27,7 +27,8 @@ internal sealed class RuleTextEditorForm : Form
{
Text = "编辑规则注释";
Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
- BackColor = UiTheme.Background;
+ AutoScaleMode = AutoScaleMode.Dpi;
+ BackColor = UiTheme.Surface;
ForeColor = UiTheme.Text;
ClientSize = new Size(760, 380);
MinimumSize = new Size(620, 320);
@@ -40,46 +41,66 @@ internal sealed class RuleTextEditorForm : Form
var root = new TableLayoutPanel
{
Dock = DockStyle.Fill,
- BackColor = UiTheme.Background,
- Padding = new Padding(14, 12, 14, 12),
+ BackColor = UiTheme.Surface,
+ Padding = new Padding(UiTheme.CardPadding, 12, UiTheme.CardPadding, 12),
ColumnCount = 1,
- RowCount = 3
+ RowCount = 2
};
- root.RowStyles.Add(new RowStyle(SizeType.Absolute, 28));
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
- root.RowStyles.Add(new RowStyle(SizeType.Absolute, 50));
+ root.RowStyles.Add(new RowStyle(SizeType.Absolute, 56));
Controls.Add(root);
- root.Controls.Add(CreateLabel("注释"), 0, 0);
ConfigureMultilineTextBox(_commentBox, wordWrap: true);
- _commentBox.Margin = new Padding(0, 0, 0, 8);
- root.Controls.Add(_commentBox, 0, 1);
+ _commentBox.Margin = new Padding(0);
+ var editorCard = new UiCardPanel
+ {
+ Dock = DockStyle.Fill,
+ Padding = new Padding(UiTheme.CardPadding),
+ Margin = new Padding(0, 0, 0, UiTheme.PageGap),
+ ColumnCount = 1,
+ RowCount = 2
+ };
+ editorCard.RowStyles.Add(new RowStyle(SizeType.Absolute, 28));
+ editorCard.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
+ editorCard.Controls.Add(UiTheme.CreateSectionTitle(Font, "规则注释"), 0, 0);
+ editorCard.Controls.Add(_commentBox, 0, 1);
+ root.Controls.Add(editorCard, 0, 0);
+
+ var actionCard = new UiCardPanel
+ {
+ Dock = DockStyle.Fill,
+ Margin = Padding.Empty,
+ Padding = new Padding(UiTheme.CardPadding, 10, UiTheme.CardPadding, 10),
+ ColumnCount = 2,
+ RowCount = 1
+ };
+ actionCard.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
+ actionCard.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 184));
+ actionCard.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
var actions = new FlowLayoutPanel
{
Dock = DockStyle.Fill,
FlowDirection = FlowDirection.RightToLeft,
WrapContents = false,
- BackColor = UiTheme.Background,
- Margin = Padding.Empty,
- Padding = new Padding(0, 8, 0, 0)
+ BackColor = Color.Transparent,
+ Margin = Padding.Empty
};
- var saveButton = UiTheme.CreateButton("保存", UiTheme.Accent, Color.Black);
- saveButton.AutoSize = false;
- saveButton.Size = new Size(84, 36);
- saveButton.Margin = Padding.Empty;
+ var saveButton = UiTheme.CreateButton("保存", UiTheme.ButtonKind.Primary);
+ UiTheme.StyleActionButton(saveButton, 84);
+ saveButton.Margin = new Padding(8, 0, 0, 0);
saveButton.Click += (_, _) => SaveAndClose();
- var cancelButton = UiTheme.CreateButton("取消", UiTheme.Field, UiTheme.Text);
- cancelButton.AutoSize = false;
- cancelButton.Size = new Size(84, 36);
- cancelButton.Margin = new Padding(0, 0, 10, 0);
+ var cancelButton = UiTheme.CreateButton("取消", UiTheme.ButtonKind.Secondary);
+ UiTheme.StyleActionButton(cancelButton, 84);
+ cancelButton.Margin = new Padding(8, 0, 0, 0);
cancelButton.Click += (_, _) => DialogResult = DialogResult.Cancel;
actions.Controls.Add(saveButton);
actions.Controls.Add(cancelButton);
- root.Controls.Add(actions, 0, 2);
+ actionCard.Controls.Add(actions, 1, 0);
+ root.Controls.Add(actionCard, 0, 1);
AcceptButton = saveButton;
CancelButton = cancelButton;
diff --git a/UI/StatusForm.cs b/UI/StatusForm.cs
index 0c81d25f..879d4e84 100644
--- a/UI/StatusForm.cs
+++ b/UI/StatusForm.cs
@@ -15,6 +15,8 @@ internal enum SettingsPage
Party,
Logic,
Logs,
+ BossNumbers,
+ CommonFields,
About
}
@@ -28,6 +30,8 @@ internal enum SettingsNavIcon
Party,
Logic,
Logs,
+ BossNumbers,
+ CommonFields,
About
}
@@ -37,6 +41,171 @@ public sealed class StatusForm : Form
private const int AboutWatermarkSize = 440;
private const int AboutWatermarkTopMargin = 16;
private const float AboutWatermarkOpacity = 0.08F;
+ private const int BossNumberCardWidth = 400;
+
+ private static readonly IReadOnlyList CurrentSeasonDungeonNames =
+ [
+ "烈毒之渊",
+ "潮缚石窟",
+ "毒牙祭坛",
+ "纳洛拉克的洞穴",
+ "密谋小径",
+ "夺目谷",
+ "诸王之眠",
+ "红玉新生法池",
+ "虚空之痕竞技场",
+ "塞塔里斯神庙"
+ ];
+
+ private static readonly IReadOnlyList BossNumberGroups =
+ [
+ new(string.Empty,
+ [
+ new("虚影尖塔",
+ [
+ new(1, "元首阿福扎恩", 1),
+ new(2, "弗拉希乌斯", 2),
+ new(3, "陨落之王萨哈达尔", 3),
+ new(4, "威厄高尔和艾佐拉克", 4),
+ new(5, "光盲先锋军", 5),
+ new(6, "宇宙之冕", 6)
+ ]),
+ new("梦境裂隙", [new(1, "奇美鲁斯,未梦之神", 7)]),
+ new("奎尔丹纳斯岛",
+ [
+ new(1, "贝洛朗,奥的子嗣", 8),
+ new(2, "至暗之夜降临", 9)
+ ]),
+ new("世界",
+ [
+ new(1, "鲁阿夏尔", 10),
+ new(2, "索姆贝兰", 11),
+ new(3, "普雷达萨斯", 12),
+ new(4, "克拉格平", 13)
+ ]),
+ new("孢陨幽境", [new(1, "腐沼", 14)]),
+ new("潮缚石窟", [new(1, "尼姆瑞莎·唤波者", 15)]),
+ new("烈毒之渊",
+ [
+ new(1, "盘魂者内克扎莉", 16),
+ new(2, "陵寝哨兵", 17),
+ new(3, "迷失的探险者", 18),
+ new(4, "万毒邪祟者瓦什尼克", 19),
+ new(5, "斯索拉克", 20),
+ new(6, "双子毒牙", 21),
+ new(7, "盘卷祭坛", 22),
+ new(8, "乌拉特克", 23)
+ ])
+ ]),
+ new("大米",
+ [
+ new("节点希纳斯",
+ [
+ new(1, "核技工程长卡斯雷瑟", 51),
+ new(2, "核心守卫奈萨拉", 52),
+ new(3, "洛萨克森", 53)
+ ]),
+ new("迈萨拉洞窟",
+ [
+ new(1, "姆罗金和内克拉克斯", 54),
+ new(2, "沃达扎", 55),
+ new(3, "拉克图尔,聚魂之器", 56)
+ ]),
+ new("风行者之塔",
+ [
+ new(1, "烬晓", 57),
+ new(2, "被遗弃的二人组", 58),
+ new(3, "指挥官克罗鲁科", 59),
+ new(4, "无眠之心", 60)
+ ]),
+ new("魔导师平台",
+ [
+ new(1, "奥能金刚库斯托斯", 61),
+ new(2, "瑟拉奈尔·日鞭", 62),
+ new(3, "吉美尔鲁斯", 63),
+ new(4, "迪詹崔乌斯", 64)
+ ]),
+ new("执政团之座",
+ [
+ new(1, "晋升者祖拉尔", 65),
+ new(2, "萨普瑞什", 66),
+ new(3, "总督奈扎尔", 67),
+ new(4, "鲁拉", 68)
+ ]),
+ new("艾杰斯亚学院",
+ [
+ new(1, "维克萨姆斯", 69),
+ new(2, "茂林古树", 70),
+ new(3, "克罗兹", 71),
+ new(4, "多拉苟萨的回响", 72)
+ ]),
+ new("萨隆矿坑",
+ [
+ new(1, "熔炉之主加弗斯特", 73),
+ new(2, "伊克和科瑞克", 74),
+ new(3, "天灾领主泰兰努斯", 75)
+ ]),
+ new("通天峰",
+ [
+ new(1, "兰吉特", 76),
+ new(2, "阿拉卡纳斯", 77),
+ new(3, "鲁克兰", 78),
+ new(4, "高阶贤者维里克斯", 79)
+ ]),
+ new("毒牙祭坛",
+ [
+ new(1, "拉维", 80),
+ new(2, "扭缠盘蛇", 81),
+ new(3, "祖尔加", 82)
+ ]),
+ new("纳洛拉克的洞穴",
+ [
+ new(1, "囤宝狂人", 83),
+ new(2, "寒冬哨兵", 84),
+ new(3, "纳洛拉克", 85)
+ ]),
+ new("密谋小径",
+ [
+ new(1, "凯斯媞亚·魔力之心", 86),
+ new(2, "赞恩·刃悲", 87),
+ new(3, "歼灭者萨祖克斯", 88),
+ new(4, "利希尔·烬怒", 89)
+ ]),
+ new("夺目谷",
+ [
+ new(1, "光明众花", 90),
+ new(2, "圣光猎手伊库兹", 91),
+ new(3, "护光者鲁伊亚", 92),
+ new(4, "兹欧凯特", 93)
+ ]),
+ new("诸王之眠",
+ [
+ new(1, "黄金风蛇", 94),
+ new(2, "部族议会", 95),
+ new(3, "殓尸者姆沁巴", 96),
+ new(4, "达萨大王", 97)
+ ]),
+ new("红玉新生法池",
+ [
+ new(1, "梅莉杜莎·寒妆", 98),
+ new(2, "柯姬雅·焰蹄", 99),
+ new(3, "基拉卡与厄克哈特·风脉", 100)
+ ]),
+ new("虚空之痕竞技场",
+ [
+ new(1, "塔兹拉尔", 101),
+ new(2, "阿特洛苏斯", 102),
+ new(3, "煞戎努斯", 103)
+ ]),
+ new("塞塔里斯神庙",
+ [
+ new(1, "阿德里斯和阿斯匹克斯", 104),
+ new(2, "米利克萨", 105),
+ new(3, "加瓦兹特", 106),
+ new(4, "塞塔里斯的化身", 107)
+ ])
+ ])
+ ];
private readonly List<(SettingsNavButton Button, Control View, SettingsPage Page)> _navItems = new();
private readonly Dictionary _listCounts = new();
@@ -138,22 +307,22 @@ public sealed class StatusForm : Form
_moduleHost = CreatePageHost();
_aboutHost = CreatePageHost();
- _stateList = UiTheme.CreateListView(Font, "status-state",
- new UiTheme.ListColumn("#", 48, 48, FixedWidth: true),
- new UiTheme.ListColumn("名称", 110, 260),
- new UiTheme.ListColumn("值", 100, 900, FillRemaining: true));
- _auraList = UiTheme.CreateListView(Font, "status-aura",
- new UiTheme.ListColumn("#", 48, 48, FixedWidth: true),
- new UiTheme.ListColumn("光环", 120, 300),
- new UiTheme.ListColumn("值", 96, 900, FillRemaining: true));
- _dynamicUnitList = UiTheme.CreateListView(Font, "status-dynamic-unit",
- new UiTheme.ListColumn("类型", 72, 160),
- new UiTheme.ListColumn("名称", 92, 280),
- new UiTheme.ListColumn("值", 96, 900, FillRemaining: true));
- _spellList = UiTheme.CreateListView(Font, "status-spell",
- new UiTheme.ListColumn("#", 48, 48, FixedWidth: true),
- new UiTheme.ListColumn("技能", 120, 300),
- new UiTheme.ListColumn("状态", 100, 900, FillRemaining: true));
+ _stateList = UiTheme.CreateListView(Font, "status-state-v2",
+ new UiTheme.ListColumn("#", 28, 28, FixedWidth: true),
+ new UiTheme.ListColumn("名称", 40, 220),
+ new UiTheme.ListColumn("值", 40, 900, FillRemaining: true));
+ _auraList = UiTheme.CreateListView(Font, "status-aura-v2",
+ new UiTheme.ListColumn("#", 28, 28, FixedWidth: true),
+ new UiTheme.ListColumn("光环", 40, 260),
+ new UiTheme.ListColumn("值", 40, 900, FillRemaining: true));
+ _dynamicUnitList = UiTheme.CreateListView(Font, "status-dynamic-unit-v2",
+ new UiTheme.ListColumn("类型", 40, 140),
+ new UiTheme.ListColumn("名称", 40, 240),
+ new UiTheme.ListColumn("值", 40, 900, FillRemaining: true));
+ _spellList = UiTheme.CreateListView(Font, "status-spell-v2",
+ new UiTheme.ListColumn("#", 28, 28, FixedWidth: true),
+ new UiTheme.ListColumn("技能", 40, 260),
+ new UiTheme.ListColumn("状态", 40, 900, FillRemaining: true));
_partyList = UiTheme.CreateListView(Font, "status-party",
new UiTheme.ListColumn("单位", 120, 180, FixedWidth: true),
@@ -179,7 +348,7 @@ public sealed class StatusForm : Form
{
Dock = DockStyle.Fill,
BackColor = UiTheme.Surface,
- Padding = new Padding(20),
+ Padding = new Padding(16),
Margin = new Padding(0)
};
@@ -194,8 +363,11 @@ public sealed class StatusForm : Form
AddNavItem(nav, SettingsPage.Party, SettingsNavIcon.Party, "队伍", CreatePageShell("队伍", "当前队伍单位与扫描字段摘要", BuildSection("队伍成员", _partyList, "实时队伍数据")));
AddNavItem(nav, SettingsPage.Logic, SettingsNavIcon.Logic, "逻辑", CreatePageShell("逻辑", "运行时推荐目标与调试值", BuildSection("逻辑信息", _unitInfoList, "当前模块的决策输出")));
AddNavItem(nav, SettingsPage.Logs, SettingsNavIcon.Logs, "日志", CreatePageShell("日志", "运行、模块匹配与施放记录", BuildLogPage()));
+ AddNavGroup(nav, "说明");
+ AddNavItem(nav, SettingsPage.BossNumbers, SettingsNavIcon.BossNumbers, "首领编号", CreatePageShell("首领编号", "副本首领的序号、名称与扫描编号", BuildBossNumbersPage()));
+ AddNavItem(nav, SettingsPage.CommonFields, SettingsNavIcon.CommonFields, "常用字段", CreatePageShell("常用字段", "模块条件可用的状态字段参考", BuildCommonFieldsPanel()));
AddNavGroup(nav, "系统");
- AddNavItem(nav, SettingsPage.About, SettingsNavIcon.About, "关于", CreatePageShell("关于", "应用信息与状态字段参考", _aboutHost));
+ AddNavItem(nav, SettingsPage.About, SettingsNavIcon.About, "关于", CreatePageShell("关于", "应用信息", _aboutHost));
_aboutHost.Controls.Add(BuildAboutPanel());
root.Controls.Add(navShell, 0, 0);
@@ -224,12 +396,12 @@ public sealed class StatusForm : Form
BackColor = UiTheme.Background,
ColumnCount = 1,
RowCount = 3,
- Padding = new Padding(12, 16, 12, 12),
+ Padding = new Padding(12, 10, 12, 8),
Margin = new Padding(0)
};
- shell.RowStyles.Add(new RowStyle(SizeType.Absolute, 74));
+ shell.RowStyles.Add(new RowStyle(SizeType.Absolute, 54));
shell.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
- shell.RowStyles.Add(new RowStyle(SizeType.Absolute, 34));
+ shell.RowStyles.Add(new RowStyle(SizeType.Absolute, 20));
var brand = new TableLayoutPanel
{
@@ -309,40 +481,47 @@ public sealed class StatusForm : Form
RowCount = 2,
Margin = new Padding(0)
};
- // 预留标题实际高度与 header 的 14px 下边距,避免高 DPI 下标题被裁切。
- shell.RowStyles.Add(new RowStyle(SizeType.Absolute, hasSubtitle ? 84 : 60));
+ // 所有页面统一使用单行页头,标题与说明文字保持各自原有字号。
+ shell.RowStyles.Add(new RowStyle(SizeType.Absolute, 50));
shell.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
var header = new TableLayoutPanel
{
Dock = DockStyle.Fill,
BackColor = UiTheme.Surface,
- ColumnCount = 1,
- RowCount = hasSubtitle ? 2 : 1,
- Margin = new Padding(0, 0, 0, 14)
+ ColumnCount = hasSubtitle ? 2 : 1,
+ RowCount = 1,
+ Margin = new Padding(0, 0, 0, UiTheme.PageGap)
};
- header.RowStyles.Add(new RowStyle(SizeType.Absolute, 46));
+ header.RowStyles.Add(new RowStyle(SizeType.Absolute, 38));
+ header.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
+ if (hasSubtitle)
+ {
+ header.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
+ }
+
header.Controls.Add(new Label
{
Text = title,
Dock = DockStyle.Fill,
+ AutoSize = true,
ForeColor = UiTheme.Text,
Font = new Font(Font.FontFamily, 16F, FontStyle.Bold),
- TextAlign = ContentAlignment.MiddleLeft,
- Margin = new Padding(0)
+ TextAlign = ContentAlignment.BottomLeft,
+ Margin = new Padding(0, 0, hasSubtitle ? 14 : 0, 0)
}, 0, 0);
if (hasSubtitle)
{
- header.RowStyles.Add(new RowStyle(SizeType.Absolute, 24));
header.Controls.Add(new Label
{
Text = subtitle,
Dock = DockStyle.Fill,
+ AutoEllipsis = true,
ForeColor = UiTheme.Muted,
Font = new Font(Font.FontFamily, 9.5F, FontStyle.Regular),
- TextAlign = ContentAlignment.MiddleLeft,
+ TextAlign = ContentAlignment.BottomLeft,
Margin = new Padding(0)
- }, 0, 1);
+ }, 1, 0);
}
shell.Controls.Add(header, 0, 0);
@@ -362,24 +541,61 @@ public sealed class StatusForm : Form
RowCount = 1,
Margin = new Padding(0)
};
- for (var i = 0; i < 4; i++)
- {
- statusSplit.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25));
- }
- statusSplit.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
- var state = BuildSection("状态", _stateList, "基础字段与当前模块");
- state.Margin = new Padding(0, 0, 6, 0);
- var aura = BuildSection("光环", _auraList, "光环数值状态");
- aura.Margin = new Padding(6, 0, 6, 0);
- var spell = BuildSection("技能", _spellList, "冷却与可用状态");
- spell.Margin = new Padding(6, 0, 6, 0);
- var units = BuildSection("动态单位", _dynamicUnitList, "模块运行时计算值");
- units.Margin = new Padding(6, 0, 0, 0);
- statusSplit.Controls.Add(state, 0, 0);
- statusSplit.Controls.Add(aura, 1, 0);
- statusSplit.Controls.Add(spell, 2, 0);
- statusSplit.Controls.Add(units, 3, 0);
+ var sections = new[]
+ {
+ BuildSection("状态", _stateList, "基础字段与当前模块"),
+ BuildSection("光环", _auraList, "光环数值状态"),
+ BuildSection("技能", _spellList, "冷却与可用状态"),
+ BuildSection("动态单位", _dynamicUnitList, "模块运行时计算值")
+ };
+ bool? usingCompactLayout = null;
+
+ void ApplyLayout()
+ {
+ // 四张卡片需要为三列表头保留可读宽度;不足时切成 2×2,避免原生横向滚动条。
+ // ClientSize 已是当前 WinForms 布局坐标,不再二次按 DPI 放大断点。
+ var compact = statusSplit.ClientSize.Width < 1100;
+ if (usingCompactLayout == compact)
+ {
+ return;
+ }
+
+ usingCompactLayout = compact;
+ statusSplit.SuspendLayout();
+ statusSplit.Controls.Clear();
+ statusSplit.ColumnStyles.Clear();
+ statusSplit.RowStyles.Clear();
+ statusSplit.ColumnCount = compact ? 2 : 4;
+ statusSplit.RowCount = compact ? 2 : 1;
+ for (var column = 0; column < statusSplit.ColumnCount; column++)
+ {
+ statusSplit.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F / statusSplit.ColumnCount));
+ }
+
+ for (var row = 0; row < statusSplit.RowCount; row++)
+ {
+ statusSplit.RowStyles.Add(new RowStyle(SizeType.Percent, 100F / statusSplit.RowCount));
+ }
+
+ for (var i = 0; i < sections.Length; i++)
+ {
+ var column = compact ? i % 2 : i;
+ var row = compact ? i / 2 : 0;
+ sections[i].Margin = new Padding(
+ column == 0 ? 0 : UiTheme.PageGap / 2,
+ row == 0 ? 0 : UiTheme.PageGap / 2,
+ column == statusSplit.ColumnCount - 1 ? 0 : UiTheme.PageGap / 2,
+ row == statusSplit.RowCount - 1 ? 0 : UiTheme.PageGap / 2);
+ statusSplit.Controls.Add(sections[i], column, row);
+ }
+
+ statusSplit.ResumeLayout(true);
+ }
+
+ statusSplit.SizeChanged += (_, _) => ApplyLayout();
+ statusSplit.HandleCreated += (_, _) => BeginInvoke(ApplyLayout);
+ ApplyLayout();
return statusSplit;
}
@@ -390,11 +606,11 @@ public sealed class StatusForm : Form
Dock = DockStyle.Fill,
ColumnCount = 1,
RowCount = 3,
- Padding = new Padding(16),
+ Padding = new Padding(UiTheme.CardPadding),
Margin = new Padding(0)
};
- section.RowStyles.Add(new RowStyle(SizeType.Absolute, 30));
- section.RowStyles.Add(new RowStyle(SizeType.Absolute, 24));
+ section.RowStyles.Add(new RowStyle(SizeType.Absolute, 28));
+ section.RowStyles.Add(new RowStyle(SizeType.Absolute, 22));
section.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
var heading = new TableLayoutPanel
@@ -428,6 +644,7 @@ public sealed class StatusForm : Form
TextAlign = ContentAlignment.MiddleCenter,
Margin = new Padding(4, 2, 0, 2)
};
+ UiTheme.ApplyControlRoundedRegion(countLabel, UiTheme.ControlCornerRadius);
_listCounts[listView] = countLabel;
heading.Controls.Add(countLabel, 1, 0);
}
@@ -443,7 +660,7 @@ public sealed class StatusForm : Form
}, 0, 1);
content.Dock = DockStyle.Fill;
- content.Margin = new Padding(0, 12, 0, 0);
+ content.Margin = new Padding(0, 8, 0, 0);
section.Controls.Add(content, 0, 2);
return section;
}
@@ -455,10 +672,10 @@ public sealed class StatusForm : Form
Dock = DockStyle.Fill,
ColumnCount = 1,
RowCount = 2,
- Padding = new Padding(16),
+ Padding = new Padding(UiTheme.CardPadding),
Margin = new Padding(0)
};
- card.RowStyles.Add(new RowStyle(SizeType.Absolute, 44));
+ card.RowStyles.Add(new RowStyle(SizeType.Absolute, 42));
card.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
var toolbar = new FlowLayoutPanel
@@ -470,6 +687,7 @@ public sealed class StatusForm : Form
Margin = new Padding(0)
};
var copyButton = UiTheme.CreateButton("复制全部", UiTheme.ButtonKind.Secondary);
+ UiTheme.StyleActionButton(copyButton, 96);
copyButton.Margin = new Padding(0, 0, 8, 6);
copyButton.Click += (_, _) =>
{
@@ -479,17 +697,16 @@ public sealed class StatusForm : Form
}
};
var clearButton = UiTheme.CreateButton("清空显示", UiTheme.ButtonKind.Danger);
+ UiTheme.StyleActionButton(clearButton, 96);
clearButton.Margin = new Padding(0, 0, 16, 6);
clearButton.Click += (_, _) => _logTextBox.Clear();
var autoScroll = new CheckBox
{
Text = "自动滚动",
Checked = true,
- AutoSize = true,
- ForeColor = UiTheme.Text,
- BackColor = UiTheme.SurfaceRaised,
Margin = new Padding(0, 8, 0, 0)
};
+ UiTheme.StyleCheckBox(autoScroll, UiTheme.SurfaceRaised);
autoScroll.CheckedChanged += (_, _) => _autoScrollLog = autoScroll.Checked;
toolbar.Controls.Add(copyButton);
toolbar.Controls.Add(clearButton);
@@ -595,12 +812,12 @@ public sealed class StatusForm : Form
{
Text = text,
AutoSize = false,
- Size = new Size(192, 30),
+ Size = new Size(192, 25),
ForeColor = UiTheme.Muted,
Font = new Font(Font.FontFamily, 9F, FontStyle.Bold),
- TextAlign = ContentAlignment.BottomLeft,
- Padding = new Padding(10, 0, 0, 4),
- Margin = new Padding(0, nav.Controls.Count == 0 ? 0 : 10, 0, 3)
+ TextAlign = ContentAlignment.MiddleLeft,
+ Padding = new Padding(10, 0, 0, 0),
+ Margin = new Padding(0, nav.Controls.Count == 0 ? 0 : 6, 0, 2)
});
}
@@ -614,9 +831,9 @@ public sealed class StatusForm : Form
{
Text = text,
AutoSize = false,
- Size = new Size(192, 44),
+ Size = new Size(192, 39),
Font = new Font(Font.FontFamily, 10F, FontStyle.Regular),
- Margin = new Padding(0, 0, 0, 3),
+ Margin = new Padding(0, 0, 0, 1),
Cursor = Cursors.Hand,
TabStop = true,
AccessibleName = text
@@ -642,6 +859,204 @@ public sealed class StatusForm : Form
}
}
+ private Control BuildBossNumbersPage()
+ {
+ var scrollHost = new Panel
+ {
+ Dock = DockStyle.Fill,
+ AutoScroll = true,
+ BackColor = UiTheme.Surface,
+ Margin = new Padding(0)
+ };
+
+ var cards = new TableLayoutPanel
+ {
+ Dock = DockStyle.None,
+ Anchor = AnchorStyles.Top | AnchorStyles.Left,
+ AutoSize = true,
+ AutoSizeMode = AutoSizeMode.GrowAndShrink,
+ BackColor = UiTheme.Surface,
+ ColumnCount = 4,
+ RowCount = 0,
+ MinimumSize = new Size(BossNumberCardWidth * 4 + UiTheme.PageGap * 3, 0),
+ Padding = new Padding(0),
+ Margin = new Padding(0)
+ };
+
+ var allDungeons = BossNumberGroups
+ .SelectMany(group => group.Dungeons)
+ .ToDictionary(dungeon => dungeon.Name, StringComparer.Ordinal);
+ var currentSeasonNames = CurrentSeasonDungeonNames.ToHashSet(StringComparer.Ordinal);
+ IReadOnlyList seasonGroups =
+ [
+ new("当前赛季", CurrentSeasonDungeonNames.Select(name => allDungeons[name]).ToArray()),
+ new("第一赛季", BossNumberGroups
+ .SelectMany(group => group.Dungeons)
+ .Where(dungeon => !currentSeasonNames.Contains(dungeon.Name))
+ .ToArray())
+ ];
+
+ var seasonViews = seasonGroups
+ .Select(group =>
+ {
+ var title = new Label
+ {
+ Text = group.Title,
+ AutoSize = true,
+ ForeColor = UiTheme.Text,
+ BackColor = Color.Transparent,
+ Font = new Font(Font.FontFamily, 12F, FontStyle.Bold)
+ };
+ var groupCards = group.Dungeons.Select(CreateBossNumberCard).ToArray();
+ foreach (var card in groupCards)
+ {
+ card.Margin = new Padding(0, 0, 0, UiTheme.PageGap);
+ }
+
+ return (Title: title, Cards: groupCards);
+ })
+ .ToArray();
+
+ void ApplyLayout()
+ {
+ const int columnCount = 4;
+ cards.SuspendLayout();
+ cards.Controls.Clear();
+ cards.ColumnStyles.Clear();
+ cards.RowStyles.Clear();
+ cards.ColumnCount = columnCount;
+ cards.RowCount = 0;
+ for (var columnIndex = 0; columnIndex < columnCount; columnIndex++)
+ {
+ var columnWidth = BossNumberCardWidth
+ + (columnIndex < columnCount - 1 ? UiTheme.PageGap : 0);
+ cards.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, columnWidth));
+ }
+
+ var row = 0;
+ var column = 0;
+ foreach (var (title, groupCards) in seasonViews)
+ {
+ if (column != 0)
+ {
+ row++;
+ column = 0;
+ }
+
+ cards.RowStyles.Add(new RowStyle(SizeType.AutoSize));
+ cards.RowCount = row + 1;
+ title.Margin = new Padding(2, row == 0 ? 0 : UiTheme.PageGap, 0, UiTheme.PageGap);
+ cards.Controls.Add(title, 0, row);
+ cards.SetColumnSpan(title, columnCount);
+ row++;
+
+ foreach (var card in groupCards)
+ {
+ if (cards.RowStyles.Count <= row)
+ {
+ cards.RowStyles.Add(new RowStyle(SizeType.AutoSize));
+ cards.RowCount = row + 1;
+ }
+
+ cards.Controls.Add(card, column, row);
+
+ column++;
+ if (column == columnCount)
+ {
+ column = 0;
+ row++;
+ }
+ }
+ }
+
+ cards.ResumeLayout(true);
+ }
+
+ scrollHost.Controls.Add(cards);
+ ApplyLayout();
+ return scrollHost;
+ }
+
+ private Control CreateBossNumberCard(BossDungeon dungeon)
+ {
+ var card = new UiCardPanel
+ {
+ AutoSize = false,
+ Size = new Size(
+ BossNumberCardWidth,
+ UiTheme.CardPadding * 2 + 34 + (dungeon.Bosses.Count + 1) * 28),
+ ColumnCount = 1,
+ RowCount = 2,
+ Padding = new Padding(UiTheme.CardPadding),
+ MinimumSize = new Size(0, 0)
+ };
+ card.RowStyles.Add(new RowStyle(SizeType.Absolute, 34));
+ card.RowStyles.Add(new RowStyle(SizeType.AutoSize));
+ card.Controls.Add(new Label
+ {
+ Text = dungeon.Name,
+ Dock = DockStyle.Fill,
+ ForeColor = UiTheme.Accent,
+ BackColor = Color.Transparent,
+ Font = new Font(Font.FontFamily, 10F, FontStyle.Bold),
+ TextAlign = ContentAlignment.MiddleLeft,
+ Margin = new Padding(0)
+ }, 0, 0);
+
+ var table = new TableLayoutPanel
+ {
+ Dock = DockStyle.Top,
+ AutoSize = true,
+ AutoSizeMode = AutoSizeMode.GrowAndShrink,
+ BackColor = Color.Transparent,
+ ColumnCount = 3,
+ RowCount = dungeon.Bosses.Count + 1,
+ Margin = new Padding(0)
+ };
+ table.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 64));
+ table.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
+ table.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 64));
+ AddBossNumberCell(table, "序号", 0, 0, UiTheme.Muted, FontStyle.Bold, ContentAlignment.MiddleCenter);
+ AddBossNumberCell(table, "名称", 1, 0, UiTheme.Muted, FontStyle.Bold, ContentAlignment.MiddleLeft);
+ AddBossNumberCell(table, "编号", 2, 0, UiTheme.Muted, FontStyle.Bold, ContentAlignment.MiddleCenter);
+
+ for (var index = 0; index < dungeon.Bosses.Count; index++)
+ {
+ var boss = dungeon.Bosses[index];
+ var tableRow = index + 1;
+ AddBossNumberCell(table, boss.Sequence.ToString(), 0, tableRow, UiTheme.Muted, FontStyle.Regular, ContentAlignment.MiddleCenter);
+ AddBossNumberCell(table, boss.Name, 1, tableRow, UiTheme.Text, FontStyle.Regular, ContentAlignment.MiddleLeft);
+ AddBossNumberCell(table, boss.Number.ToString(), 2, tableRow, UiTheme.Accent, FontStyle.Regular, ContentAlignment.MiddleCenter);
+ }
+
+ card.Controls.Add(table, 0, 1);
+ return card;
+ }
+
+ private void AddBossNumberCell(
+ TableLayoutPanel table,
+ string text,
+ int column,
+ int row,
+ Color color,
+ FontStyle style,
+ ContentAlignment alignment)
+ {
+ table.Controls.Add(new Label
+ {
+ Text = text,
+ Dock = DockStyle.Fill,
+ AutoSize = false,
+ Height = 28,
+ AutoEllipsis = true,
+ ForeColor = color,
+ BackColor = Color.Transparent,
+ Font = new Font(Font.FontFamily, 9F, style),
+ TextAlign = alignment,
+ Margin = new Padding(column == 1 ? 6 : 0, 0, column == 1 ? 6 : 0, 0)
+ }, column, row);
+ }
+
private Control BuildAboutPanel()
{
var scrollHost = new WatermarkPanel(
@@ -663,13 +1078,11 @@ public sealed class StatusForm : Form
AutoSizeMode = AutoSizeMode.GrowAndShrink,
BackColor = Color.Transparent,
ColumnCount = 1,
- RowCount = 3,
+ RowCount = 1,
Padding = new Padding(0),
Margin = new Padding(0)
};
panel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
- panel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
- panel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
var infoCard = new UiCardPanel
{
@@ -677,8 +1090,8 @@ public sealed class StatusForm : Form
Dock = DockStyle.Top,
ColumnCount = 1,
RowCount = 2,
- Padding = new Padding(14),
- Margin = new Padding(0, 0, 0, 12)
+ Padding = new Padding(UiTheme.CardPadding),
+ Margin = new Padding(0)
};
infoCard.RowStyles.Add(new RowStyle(SizeType.AutoSize));
infoCard.RowStyles.Add(new RowStyle(SizeType.AutoSize));
@@ -690,7 +1103,7 @@ public sealed class StatusForm : Form
BackColor = Color.Transparent,
ColumnCount = 1,
RowCount = 2,
- Margin = new Padding(0, 0, 0, 16)
+ Margin = new Padding(0, 0, 0, UiTheme.PageGap)
};
heading.RowStyles.Add(new RowStyle(SizeType.AutoSize));
heading.RowStyles.Add(new RowStyle(SizeType.AutoSize));
@@ -744,21 +1157,25 @@ public sealed class StatusForm : Form
infoCard.Controls.Add(details, 0, 1);
panel.Controls.Add(infoCard, 0, 0);
- panel.Controls.Add(new Label
+ scrollHost.Controls.Add(panel);
+ return scrollHost;
+ }
+
+ private Control BuildCommonFieldsPanel()
+ {
+ var scrollHost = new Panel
{
- Text = "可用状态字段",
- AutoSize = true,
- ForeColor = UiTheme.Text,
- BackColor = Color.Transparent,
- Font = new Font(Font.FontFamily, 12F, FontStyle.Bold),
- Margin = new Padding(2, 6, 0, 12)
- }, 0, 1);
+ Dock = DockStyle.Fill,
+ BackColor = UiTheme.Surface,
+ AutoScroll = true,
+ Margin = new Padding(0)
+ };
var fields = new TableLayoutPanel
{
AutoSize = true,
Dock = DockStyle.Top,
- BackColor = Color.Transparent,
+ BackColor = UiTheme.Surface,
ColumnCount = 2,
RowCount = 3,
Margin = new Padding(0)
@@ -769,7 +1186,7 @@ public sealed class StatusForm : Form
fields.RowStyles.Add(new RowStyle(SizeType.AutoSize));
fields.RowStyles.Add(new RowStyle(SizeType.AutoSize));
- fields.Controls.Add(CreateAboutFieldCard(
+ fields.Controls.Add(CreateCommonFieldCard(
"状态",
[
"有效性", "战斗时间", "移动", "生命值", "一键辅助", "插入法术",
@@ -779,7 +1196,7 @@ public sealed class StatusForm : Form
"酒池", "符文", "姿态", "神圣军备", "自律", "英勇打击", "收割者战刃"
],
150), 0, 0);
- fields.Controls.Add(CreateAboutFieldCard(
+ fields.Controls.Add(CreateCommonFieldCard(
"能量",
[
"法力值", "怒气值", "集中值", "能量值", "符文", "符文能量",
@@ -787,40 +1204,39 @@ public sealed class StatusForm : Form
"连击点", "神圣能量", "精华能量", "灵魂碎片", "真气", "增压层数"
],
150), 1, 0);
- fields.Controls.Add(CreateAboutFieldCard(
+ fields.Controls.Add(CreateCommonFieldCard(
"配置开关",
["爆发开关", "AOE开关", "输出模式", "爆发药水开关", "延迟"],
92), 0, 1);
- fields.Controls.Add(CreateAboutFieldCard(
+ fields.Controls.Add(CreateCommonFieldCard(
"物品",
["治疗药水", "魔法药水", "治疗石", "鲁莽药水", "圣光潜力"],
92), 1, 1);
- fields.Controls.Add(CreateAboutFieldCard(
+ fields.Controls.Add(CreateCommonFieldCard(
"目标",
["类型", "生命值", "距离", "施法(倒计时)", "施法(正计时)", "施法可打断", "引导", "引导可打断"],
104), 0, 2);
- fields.Controls.Add(CreateAboutFieldCard(
+ fields.Controls.Add(CreateCommonFieldCard(
"焦点",
["类型", "生命值", "距离", "施法(倒计时)", "施法(正计时)", "施法可打断", "引导", "引导可打断"],
104), 1, 2);
- panel.Controls.Add(fields, 0, 2);
- scrollHost.Controls.Add(panel);
+ scrollHost.Controls.Add(fields);
return scrollHost;
}
private static string GetEmbeddedResourceName(string resourcePath)
=> $"{typeof(StatusForm).Namespace}.{resourcePath}";
- private Control CreateAboutFieldCard(string title, IReadOnlyList items, int minimumHeight)
+ private Control CreateCommonFieldCard(string title, IReadOnlyList items, int minimumHeight)
{
var card = new UiCardPanel
{
Dock = DockStyle.Fill,
ColumnCount = 1,
RowCount = 2,
- Padding = new Padding(14),
- Margin = new Padding(0, 0, 12, 12),
+ Padding = new Padding(UiTheme.CardPadding),
+ Margin = new Padding(0, 0, UiTheme.PageGap, UiTheme.PageGap),
MinimumSize = new Size(0, minimumHeight)
};
card.RowStyles.Add(new RowStyle(SizeType.Absolute, 30));
@@ -832,7 +1248,7 @@ public sealed class StatusForm : Form
Dock = DockStyle.Fill,
ForeColor = UiTheme.Accent,
BackColor = Color.Transparent,
- Font = new Font(Font.FontFamily, 10.5F, FontStyle.Bold),
+ Font = new Font(Font.FontFamily, 10F, FontStyle.Bold),
TextAlign = ContentAlignment.MiddleLeft,
Margin = new Padding(0)
}, 0, 0);
@@ -843,7 +1259,7 @@ public sealed class StatusForm : Form
AutoSize = false,
ForeColor = UiTheme.Text,
BackColor = Color.Transparent,
- Font = new Font(Font.FontFamily, 9.5F, FontStyle.Regular),
+ Font = new Font(Font.FontFamily, 9F, FontStyle.Regular),
TextAlign = ContentAlignment.TopLeft,
Margin = new Padding(0, 6, 0, 0)
}, 0, 1);
@@ -891,7 +1307,7 @@ public sealed class StatusForm : Form
BackColor = Color.Transparent,
AutoEllipsis = true,
TextAlign = ContentAlignment.MiddleLeft,
- Margin = new Padding(0, 0, 18, 14)
+ Margin = new Padding(0, 0, 18, 8)
}, 0, row);
var valueLabel = new Label
{
@@ -902,7 +1318,7 @@ public sealed class StatusForm : Form
ForeColor = UiTheme.Text,
BackColor = Color.Transparent,
TextAlign = ContentAlignment.MiddleLeft,
- Margin = new Padding(0, 0, 0, 14)
+ Margin = new Padding(0, 0, 0, 8)
};
_toolTip.SetToolTip(valueLabel, tooltip ?? value);
panel.Controls.Add(valueLabel, 1, row);
@@ -1589,6 +2005,19 @@ public sealed class StatusForm : Form
graphics.DrawLine(pen, x + w * 0.32f, y + h * 0.52f, x + w * 0.68f, y + h * 0.52f);
graphics.DrawLine(pen, x + w * 0.32f, y + h * 0.70f, x + w * 0.58f, y + h * 0.70f);
break;
+ case SettingsNavIcon.BossNumbers:
+ graphics.DrawRectangle(pen, x + w * 0.12f, y + h * 0.12f, w * 0.76f, h * 0.76f);
+ graphics.DrawLine(pen, x + w * 0.38f, y + h * 0.27f, x + w * 0.31f, y + h * 0.73f);
+ graphics.DrawLine(pen, x + w * 0.65f, y + h * 0.27f, x + w * 0.58f, y + h * 0.73f);
+ graphics.DrawLine(pen, x + w * 0.25f, y + h * 0.43f, x + w * 0.72f, y + h * 0.43f);
+ graphics.DrawLine(pen, x + w * 0.22f, y + h * 0.59f, x + w * 0.69f, y + h * 0.59f);
+ break;
+ case SettingsNavIcon.CommonFields:
+ graphics.DrawRectangle(pen, x + w * 0.12f, y + h * 0.12f, w * 0.76f, h * 0.76f);
+ graphics.DrawLine(pen, x + w * 0.34f, y + h * 0.12f, x + w * 0.34f, y + h * 0.88f);
+ graphics.DrawLine(pen, x + w * 0.12f, y + h * 0.38f, x + w * 0.88f, y + h * 0.38f);
+ graphics.DrawLine(pen, x + w * 0.12f, y + h * 0.63f, x + w * 0.88f, y + h * 0.63f);
+ break;
case SettingsNavIcon.About:
graphics.DrawEllipse(pen, x + w * 0.12f, y + h * 0.12f, w * 0.76f, h * 0.76f);
graphics.FillEllipse(brush, x + w * 0.46f, y + h * 0.28f, w * 0.08f, h * 0.08f);
@@ -1604,4 +2033,10 @@ public sealed class StatusForm : Form
graphics.FillEllipse(brush, x + width * knobPosition - knobSize / 2, y - knobSize / 2, knobSize, knobSize);
}
}
+
+ private sealed record BossNumberGroup(string Title, IReadOnlyList Dungeons);
+
+ private sealed record BossDungeon(string Name, IReadOnlyList Bosses);
+
+ private sealed record BossNumberEntry(int Sequence, string Name, int Number);
}
diff --git a/UI/UiCardPanel.cs b/UI/UiCardPanel.cs
index fee6183e..3658721d 100644
--- a/UI/UiCardPanel.cs
+++ b/UI/UiCardPanel.cs
@@ -6,7 +6,7 @@ namespace Shigure;
internal sealed class UiCardPanel : TableLayoutPanel
{
private Color _fillColor = UiTheme.SurfaceRaised;
- private int _cornerRadius = 10;
+ private int _cornerRadius = UiTheme.CardCornerRadius;
public UiCardPanel()
{
diff --git a/UI/UiPillTab.cs b/UI/UiPillTab.cs
index 1ae8ee25..2bdb2c99 100644
--- a/UI/UiPillTab.cs
+++ b/UI/UiPillTab.cs
@@ -27,7 +27,8 @@ internal sealed class UiPillTab : Control
BackColor = Color.Transparent;
ForeColor = UiTheme.Muted;
Margin = new Padding(3, 2, 3, 2);
- TabStop = false;
+ TabStop = true;
+ AccessibleRole = AccessibleRole.PageTab;
}
[Browsable(false)]
@@ -82,6 +83,29 @@ internal sealed class UiPillTab : Control
}
}
+ protected override void OnKeyDown(KeyEventArgs e)
+ {
+ base.OnKeyDown(e);
+ if (e.KeyCode is Keys.Enter or Keys.Space)
+ {
+ OnClick(EventArgs.Empty);
+ e.Handled = true;
+ e.SuppressKeyPress = true;
+ }
+ }
+
+ protected override void OnGotFocus(EventArgs e)
+ {
+ base.OnGotFocus(e);
+ Invalidate();
+ }
+
+ protected override void OnLostFocus(EventArgs e)
+ {
+ base.OnLostFocus(e);
+ Invalidate();
+ }
+
protected override void OnPaint(PaintEventArgs e)
{
var graphics = e.Graphics;
@@ -98,7 +122,7 @@ internal sealed class UiPillTab : Control
if (fill.A > 0)
{
- using var path = UiTheme.CreateRoundedRectanglePath(bounds, UiTheme.Scale(this, 8));
+ using var path = UiTheme.CreateRoundedRectanglePath(bounds, UiTheme.Scale(this, UiTheme.ControlCornerRadius));
using var brush = new SolidBrush(fill);
graphics.FillPath(brush, path);
if (_selected)
@@ -125,5 +149,11 @@ internal sealed class UiPillTab : Control
| TextFormatFlags.SingleLine
| TextFormatFlags.EndEllipsis
| TextFormatFlags.NoPrefix);
+
+ if (Focused && ShowFocusCues)
+ {
+ var focusBounds = Rectangle.Inflate(bounds, -4, -4);
+ ControlPaint.DrawFocusRectangle(graphics, focusBounds, UiTheme.Text, fill);
+ }
}
}
diff --git a/UI/UiTheme.cs b/UI/UiTheme.cs
index 5bc02364..d175b0c3 100644
--- a/UI/UiTheme.cs
+++ b/UI/UiTheme.cs
@@ -8,6 +8,14 @@ namespace Shigure;
internal static class UiTheme
{
+ public const int PageGap = 12;
+ public const int CardPadding = 14;
+ public const int ActionButtonHeight = 36;
+ public const int GridRowHeight = 40;
+ public const int TabBarHeight = 42;
+ public const int CardCornerRadius = 10;
+ public const int ControlCornerRadius = 8;
+
private static readonly Dictionary ClassIcons = new();
private static readonly Dictionary<(int ClassId, int SpecId), Image?> SpecIcons = new();
private static readonly ConditionalWeakTable ListColumnLayouts = new();
@@ -229,7 +237,50 @@ internal static class UiTheme
button.FlatAppearance.BorderColor = backColor == Accent ? Accent : Border;
button.FlatAppearance.MouseOverBackColor = backColor == Accent ? Color.FromArgb(112, 234, 221) : Hover;
button.FlatAppearance.MouseDownBackColor = backColor == Accent ? Color.FromArgb(62, 194, 181) : Pressed;
- ApplyControlRoundedRegion(button, 8);
+ ApplyControlRoundedRegion(button, ControlCornerRadius);
+
+ if (backColor == Accent)
+ {
+ // WinForms ignores ForeColor for a disabled flat button and falls back to
+ // the system disabled-text color, which is nearly black on our dark theme.
+ button.Paint += (_, e) => PaintDisabledPrimaryButton(button, e);
+ }
+
+ button.EnabledChanged += (_, _) =>
+ {
+ button.Cursor = button.Enabled ? Cursors.Hand : Cursors.Default;
+ button.ForeColor = button.Enabled ? foreColor : Muted;
+ button.BackColor = button.Enabled ? backColor : SurfaceRaised;
+ button.FlatAppearance.BorderColor = button.Enabled ? (backColor == Accent ? Accent : Border) : Border;
+ button.Invalidate();
+ };
+ }
+
+ private static void PaintDisabledPrimaryButton(Button button, PaintEventArgs e)
+ {
+ if (button.Enabled || button.ClientSize.Width <= 1 || button.ClientSize.Height <= 1)
+ {
+ return;
+ }
+
+ e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
+ var bounds = new Rectangle(0, 0, button.ClientSize.Width - 1, button.ClientSize.Height - 1);
+ using var path = CreateRoundedRectanglePath(bounds, Scale(button, ControlCornerRadius));
+ using var backgroundBrush = new SolidBrush(SurfaceRaised);
+ using var borderPen = new Pen(Border);
+ e.Graphics.FillPath(backgroundBrush, path);
+ e.Graphics.DrawPath(borderPen, path);
+ TextRenderer.DrawText(
+ e.Graphics,
+ button.Text,
+ button.Font,
+ button.ClientRectangle,
+ Muted,
+ TextFormatFlags.HorizontalCenter
+ | TextFormatFlags.VerticalCenter
+ | TextFormatFlags.SingleLine
+ | TextFormatFlags.EndEllipsis
+ | TextFormatFlags.NoPadding);
}
public static Button CreateButton(string text, ButtonKind kind)
@@ -368,6 +419,12 @@ internal static class UiTheme
textBox.BackColor = Field;
textBox.ForeColor = Text;
textBox.BorderStyle = BorderStyle.FixedSingle;
+ textBox.Margin = new Padding(0);
+ textBox.EnabledChanged += (_, _) =>
+ {
+ textBox.BackColor = textBox.Enabled ? Field : SurfaceRaised;
+ textBox.ForeColor = textBox.Enabled ? Text : Muted;
+ };
}
public static void StyleNumericUpDown(NumericUpDown numeric)
@@ -375,6 +432,12 @@ internal static class UiTheme
numeric.BackColor = Field;
numeric.ForeColor = Text;
numeric.BorderStyle = BorderStyle.FixedSingle;
+ numeric.Margin = new Padding(0);
+ numeric.EnabledChanged += (_, _) =>
+ {
+ numeric.BackColor = numeric.Enabled ? Field : SurfaceRaised;
+ numeric.ForeColor = numeric.Enabled ? Text : Muted;
+ };
}
public static void StyleCheckedListBox(CheckedListBox listBox)
@@ -387,6 +450,56 @@ internal static class UiTheme
listBox.ItemHeight = Math.Max(30, listBox.Font.Height + 14);
}
+ public static void StyleCheckBox(CheckBox checkBox, Color? backColor = null)
+ {
+ checkBox.AutoSize = true;
+ checkBox.ForeColor = Text;
+ checkBox.BackColor = backColor ?? Color.Transparent;
+ checkBox.Cursor = Cursors.Hand;
+ checkBox.FlatStyle = FlatStyle.Flat;
+ checkBox.FlatAppearance.BorderColor = Border;
+ checkBox.FlatAppearance.CheckedBackColor = AccentSoft;
+ checkBox.FlatAppearance.MouseOverBackColor = Hover;
+ checkBox.UseVisualStyleBackColor = false;
+ checkBox.EnabledChanged += (_, _) =>
+ {
+ checkBox.Cursor = checkBox.Enabled ? Cursors.Hand : Cursors.Default;
+ checkBox.ForeColor = checkBox.Enabled ? Text : Muted;
+ };
+ }
+
+ public static void StyleActionButton(Button button, int width = 110)
+ {
+ button.AutoSize = false;
+ button.Size = new Size(width, ActionButtonHeight);
+ button.TextAlign = ContentAlignment.MiddleCenter;
+ }
+
+ public static Label CreateSectionTitle(Font baseFont, string text)
+ => new()
+ {
+ Text = text,
+ Dock = DockStyle.Fill,
+ ForeColor = Text,
+ BackColor = Color.Transparent,
+ Font = new Font(baseFont.FontFamily, 10F, FontStyle.Bold),
+ TextAlign = ContentAlignment.MiddleLeft,
+ AutoEllipsis = true,
+ Margin = new Padding(0)
+ };
+
+ public static Label CreateDescription(string text)
+ => new()
+ {
+ Text = text,
+ Dock = DockStyle.Fill,
+ ForeColor = Muted,
+ BackColor = Color.Transparent,
+ TextAlign = ContentAlignment.MiddleLeft,
+ AutoEllipsis = true,
+ Margin = new Padding(0)
+ };
+
public static void StyleComboBox(ComboBox comboBox)
{
comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
@@ -396,6 +509,8 @@ internal static class UiTheme
comboBox.DrawMode = DrawMode.OwnerDrawFixed;
comboBox.ItemHeight = Math.Max(28, comboBox.Font.Height + 12);
comboBox.DropDownHeight = 320;
+ comboBox.Margin = new Padding(0);
+ comboBox.EnabledChanged += (_, _) => comboBox.Invalidate();
comboBox.DrawItem += (_, e) =>
{
@@ -407,12 +522,23 @@ internal static class UiTheme
var isSelected = (e.State & DrawItemState.Selected) == DrawItemState.Selected;
var isEditBox = (e.State & DrawItemState.ComboBoxEdit) == DrawItemState.ComboBoxEdit;
- using (var background = new SolidBrush(isEditBox ? Field : isSelected ? Hover : Surface))
+ var backgroundColor = !comboBox.Enabled
+ ? SurfaceRaised
+ : isEditBox
+ ? Field
+ : isSelected
+ ? Hover
+ : Surface;
+ using (var background = new SolidBrush(backgroundColor))
{
e.Graphics.FillRectangle(background, e.Bounds);
}
- var textColor = !isEditBox && isSelected ? Accent : Text;
+ var textColor = !comboBox.Enabled
+ ? Muted
+ : !isEditBox && isSelected
+ ? Accent
+ : Text;
var textBounds = new Rectangle(e.Bounds.X + 8, e.Bounds.Y, e.Bounds.Width - 8, e.Bounds.Height);
TextRenderer.DrawText(
e.Graphics,
@@ -444,6 +570,7 @@ internal static class UiTheme
Scale(listBox, logicalItemHeight),
font.Height + Scale(listBox, 14));
+ var hoveredIndex = -1;
listBox.DrawItem += (_, e) =>
{
if (e.Index < 0)
@@ -454,6 +581,8 @@ internal static class UiTheme
var selected = (e.State & DrawItemState.Selected) == DrawItemState.Selected;
var backgroundColor = selected
? Hover
+ : e.Index == hoveredIndex
+ ? SurfaceRaised
: e.Index % 2 == 0
? listBox.BackColor
: RowAlt;
@@ -523,6 +652,23 @@ internal static class UiTheme
selected ? Text : Muted,
TextFormatFlags.VerticalCenter | TextFormatFlags.Left | TextFormatFlags.EndEllipsis);
};
+
+ listBox.MouseMove += (_, e) =>
+ {
+ var index = listBox.IndexFromPoint(e.Location);
+ if (index == hoveredIndex)
+ {
+ return;
+ }
+
+ hoveredIndex = index;
+ listBox.Invalidate();
+ };
+ listBox.MouseLeave += (_, _) =>
+ {
+ hoveredIndex = -1;
+ listBox.Invalidate();
+ };
}
public static void StyleClassIconListBox(
@@ -900,7 +1046,7 @@ internal static class UiTheme
grid.DefaultCellStyle.WrapMode = DataGridViewTriState.False;
grid.AlternatingRowsDefaultCellStyle.BackColor = RowAlt;
grid.AlternatingRowsDefaultCellStyle.ForeColor = Text;
- grid.RowTemplate.Height = Math.Max(40, grid.Font.Height + 16);
+ grid.RowTemplate.Height = Math.Max(GridRowHeight, grid.Font.Height + 16);
grid.RowHeadersVisible = false;
grid.AllowUserToResizeRows = false;
grid.CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal;
@@ -910,7 +1056,7 @@ internal static class UiTheme
{
var verticalPadding = Scale(grid, 12);
grid.ColumnHeadersHeight = Math.Max(Scale(grid, 38), grid.Font.Height + verticalPadding);
- grid.RowTemplate.Height = Math.Max(Scale(grid, 40), grid.Font.Height + verticalPadding);
+ grid.RowTemplate.Height = Math.Max(Scale(grid, GridRowHeight), grid.Font.Height + verticalPadding);
foreach (DataGridViewRow row in grid.Rows)
{
if (!row.IsNewRow)
diff --git a/UI/UnitEditorForm.cs b/UI/UnitEditorForm.cs
index 26993439..11e071a8 100644
--- a/UI/UnitEditorForm.cs
+++ b/UI/UnitEditorForm.cs
@@ -146,7 +146,8 @@ public sealed class UnitEditorForm : Form
{
Text = "编辑单位";
Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
- BackColor = UiTheme.Background;
+ AutoScaleMode = AutoScaleMode.Dpi;
+ BackColor = UiTheme.Surface;
ForeColor = UiTheme.Text;
ClientSize = new Size(RowWidth + 36, 534);
FormBorderStyle = FormBorderStyle.FixedDialog;
@@ -158,16 +159,15 @@ public sealed class UnitEditorForm : Form
var root = new TableLayoutPanel
{
Dock = DockStyle.Fill,
- BackColor = UiTheme.Background,
- Padding = new Padding(14, 12, 14, 12),
+ BackColor = UiTheme.Surface,
+ Padding = new Padding(UiTheme.CardPadding, 12, UiTheme.CardPadding, 12),
ColumnCount = 1,
- RowCount = 5
+ RowCount = 4
};
- root.RowStyles.Add(new RowStyle(SizeType.Absolute, 38));
- root.RowStyles.Add(new RowStyle(SizeType.Absolute, 38));
+ root.RowStyles.Add(new RowStyle(SizeType.Absolute, 112));
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
- root.RowStyles.Add(new RowStyle(SizeType.Absolute, 26));
- root.RowStyles.Add(new RowStyle(SizeType.Absolute, 42));
+ root.RowStyles.Add(new RowStyle(SizeType.Absolute, 48));
+ root.RowStyles.Add(new RowStyle(SizeType.Absolute, 56));
Controls.Add(root);
UiTheme.StyleComboBox(_categoryBox);
@@ -189,27 +189,56 @@ public sealed class UnitEditorForm : Form
UpdateHealthNameState();
};
- root.Controls.Add(BuildSplitRow("类别", _categoryBox, "选择器", _selectorBox), 0, 0);
- root.Controls.Add(BuildNameRow(), 0, 1);
+ var headerCard = new UiCardPanel
+ {
+ Dock = DockStyle.Fill,
+ Padding = new Padding(4),
+ Margin = new Padding(0, 0, 0, UiTheme.PageGap),
+ ColumnCount = 1,
+ RowCount = 2
+ };
+ headerCard.RowStyles.Add(new RowStyle(SizeType.Percent, 50));
+ headerCard.RowStyles.Add(new RowStyle(SizeType.Percent, 50));
+ headerCard.Controls.Add(BuildSplitRow("类别", _categoryBox, "选择器", _selectorBox), 0, 0);
+ headerCard.Controls.Add(BuildNameRow(), 0, 1);
+ root.Controls.Add(headerCard, 0, 0);
_paramPanel.Dock = DockStyle.Fill;
- _paramPanel.BackColor = UiTheme.SurfaceRaised;
+ _paramPanel.BackColor = Color.Transparent;
_paramPanel.FlowDirection = FlowDirection.TopDown;
_paramPanel.WrapContents = false;
_paramPanel.AutoScroll = true;
- _paramPanel.Margin = new Padding(0, 8, 0, 6);
- _paramPanel.Padding = new Padding(8, 6, 8, 6);
+ _paramPanel.Margin = new Padding(0);
+ _paramPanel.Padding = new Padding(4, 6, 4, 6);
BuildParamRows();
- root.Controls.Add(_paramPanel, 0, 2);
+ var paramsCard = new UiCardPanel
+ {
+ Dock = DockStyle.Fill,
+ Padding = new Padding(4),
+ Margin = new Padding(0, 0, 0, UiTheme.PageGap),
+ ColumnCount = 1,
+ RowCount = 1
+ };
+ paramsCard.Controls.Add(_paramPanel, 0, 0);
+ root.Controls.Add(paramsCard, 0, 1);
_previewLabel.Dock = DockStyle.Fill;
_previewLabel.ForeColor = UiTheme.Muted;
_previewLabel.TextAlign = ContentAlignment.MiddleLeft;
_previewLabel.AutoEllipsis = true;
- _previewLabel.Margin = new Padding(2, 2, 2, 0);
- root.Controls.Add(_previewLabel, 0, 3);
+ _previewLabel.Margin = new Padding(0);
+ var previewCard = new UiCardPanel
+ {
+ Dock = DockStyle.Fill,
+ Padding = new Padding(UiTheme.CardPadding, 6, UiTheme.CardPadding, 6),
+ Margin = new Padding(0, 0, 0, UiTheme.PageGap),
+ ColumnCount = 1,
+ RowCount = 1
+ };
+ previewCard.Controls.Add(_previewLabel, 0, 0);
+ root.Controls.Add(previewCard, 0, 2);
- root.Controls.Add(BuildActionRow(), 0, 4);
+ root.Controls.Add(BuildActionRow(), 0, 3);
PopulateSelectors();
}
@@ -260,8 +289,7 @@ public sealed class UnitEditorForm : Form
_roleBox.SelectedIndex = 0;
_reverseBox.Text = "取逆序最后一个匹配单位";
- _reverseBox.ForeColor = UiTheme.Text;
- _reverseBox.BackColor = UiTheme.SurfaceRaised;
+ UiTheme.StyleCheckBox(_reverseBox, UiTheme.SurfaceRaised);
_reverseBox.AutoSize = false;
_reverseBox.TextAlign = ContentAlignment.MiddleLeft;
@@ -329,29 +357,40 @@ public sealed class UnitEditorForm : Form
private Control BuildActionRow()
{
- var row = new FlowLayoutPanel
+ var row = new UiCardPanel
+ {
+ Dock = DockStyle.Fill,
+ Padding = new Padding(UiTheme.CardPadding, 10, UiTheme.CardPadding, 10),
+ Margin = new Padding(0),
+ ColumnCount = 2,
+ RowCount = 1
+ };
+ row.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
+ row.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 184));
+ row.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
+
+ var actions = new FlowLayoutPanel
{
Dock = DockStyle.Fill,
FlowDirection = FlowDirection.RightToLeft,
WrapContents = false,
- BackColor = UiTheme.Background,
+ BackColor = Color.Transparent,
Margin = new Padding(0)
};
- var okButton = UiTheme.CreateButton("确定", UiTheme.Accent, Color.Black);
- okButton.Width = 76;
- okButton.Height = 30;
- okButton.Margin = new Padding(6, 6, 0, 0);
+ var okButton = UiTheme.CreateButton("确定", UiTheme.ButtonKind.Primary);
+ UiTheme.StyleActionButton(okButton, 84);
+ okButton.Margin = new Padding(8, 0, 0, 0);
okButton.Click += (_, _) => OnConfirm();
- var cancelButton = UiTheme.CreateButton("取消", UiTheme.Field, UiTheme.Text);
- cancelButton.Width = 76;
- cancelButton.Height = 30;
- cancelButton.Margin = new Padding(6, 6, 0, 0);
+ var cancelButton = UiTheme.CreateButton("取消", UiTheme.ButtonKind.Secondary);
+ UiTheme.StyleActionButton(cancelButton, 84);
+ cancelButton.Margin = new Padding(8, 0, 0, 0);
cancelButton.Click += (_, _) => DialogResult = DialogResult.Cancel;
- row.Controls.Add(okButton);
- row.Controls.Add(cancelButton);
+ actions.Controls.Add(okButton);
+ actions.Controls.Add(cancelButton);
+ row.Controls.Add(actions, 1, 0);
AcceptButton = okButton;
CancelButton = cancelButton;
return row;
@@ -1226,7 +1265,7 @@ public sealed class UnitEditorForm : Form
return Math.Clamp(value, (int)box.Minimum, (int)box.Maximum);
}
- private static Panel BuildLabeledRow(string label, Control control, int height = 32)
+ private static Panel BuildLabeledRow(string label, Control control, int height = 44)
{
var panel = new Panel
{
@@ -1241,7 +1280,7 @@ public sealed class UnitEditorForm : Form
Text = label,
ForeColor = UiTheme.Muted,
TextAlign = ContentAlignment.MiddleLeft,
- Bounds = new Rectangle(0, 4, LabelWidth, 24),
+ Bounds = new Rectangle(0, height > 50 ? 4 : Math.Max(0, (height - 24) / 2), LabelWidth, 24),
AutoEllipsis = true
};