Refactor UI components for improved theming and accessibility

- Updated UiCardPanel to use UiTheme.CardCornerRadius for consistent corner styling.
- Modified UiPillTab to enable TabStop and set AccessibleRole to PageTab, enhancing keyboard navigation.
- Implemented keyboard handling in UiPillTab for Enter and Space keys to trigger click events.
- Enhanced focus visuals in UiPillTab with focus rectangle drawing.
- Introduced new constants in UiTheme for CardPadding, PageGap, ActionButtonHeight, GridRowHeight, TabBarHeight, CardCornerRadius, and ControlCornerRadius for better layout management.
- Updated UnitEditorForm to utilize new theming constants and improved layout with UiCardPanel for better visual structure.
- Refined action button styling in UnitEditorForm for consistent button sizes and margins.
- Adjusted labeled row height in UnitEditorForm for better alignment.
This commit is contained in:
waynebian01
2026-08-25 15:58:44 +08:00
parent b549a56edd
commit da2eeb3b39
15 changed files with 1007 additions and 309 deletions

View File

@@ -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

View File

@@ -80,7 +80,7 @@ Fuyutsui.difficultyToText = {
-- 首领ID
Fuyutsui.bossID = {
[0] = 0, -- 未战斗
-- 团本
-- 虚影尖塔
[3176] = 1, -- 元首阿福扎恩
[3177] = 2, -- 弗拉希乌斯
[3179] = 3, -- 陨落之王萨哈达尔

View File

@@ -9,9 +9,9 @@
<AssemblyName>Shigure</AssemblyName>
<RootNamespace>Shigure</RootNamespace>
<Company>Arasaka Corporation</Company>
<Version>1.2.1.10</Version>
<AssemblyVersion>1.2.1.10</AssemblyVersion>
<FileVersion>1.2.1.10</FileVersion>
<Version>1.2.1.11</Version>
<AssemblyVersion>1.2.1.11</AssemblyVersion>
<FileVersion>1.2.1.11</FileVersion>
<ApplicationIcon>Assets\arasaka-icon.ico</ApplicationIcon>
<ApplicationHighDpiMode>PerMonitorV2</ApplicationHighDpiMode>
</PropertyGroup>

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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));

View File

@@ -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;

View File

@@ -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<string> CurrentSeasonDungeonNames =
[
"烈毒之渊",
"潮缚石窟",
"毒牙祭坛",
"纳洛拉克的洞穴",
"密谋小径",
"夺目谷",
"诸王之眠",
"红玉新生法池",
"虚空之痕竞技场",
"塞塔里斯神庙"
];
private static readonly IReadOnlyList<BossNumberGroup> 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<ListView, Label> _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<BossNumberGroup> 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<string> items, int minimumHeight)
private Control CreateCommonFieldCard(string title, IReadOnlyList<string> 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<BossDungeon> Dungeons);
private sealed record BossDungeon(string Name, IReadOnlyList<BossNumberEntry> Bosses);
private sealed record BossNumberEntry(int Sequence, string Name, int Number);
}

View File

@@ -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()
{

View File

@@ -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);
}
}
}

View File

@@ -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<int, Image?> ClassIcons = new();
private static readonly Dictionary<(int ClassId, int SpecId), Image?> SpecIcons = new();
private static readonly ConditionalWeakTable<ListView, ListColumnLayoutState> 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)

View File

@@ -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
};