mirror of
https://github.com/waynebian01/Shigure.git
synced 2026-09-03 07:15:24 +08:00
Refactor ModuleEditorControl and StatusForm for improved UI consistency and functionality
- Updated ModuleEditorControl to utilize UiCardPanel for sidebar and footer layouts, enhancing visual coherence. - Introduced UiPillTab for tab navigation, providing a more modern and responsive design. - Adjusted padding, margins, and background colors across various controls for a cleaner appearance. - Implemented new methods for handling button styles and actions, including a new OpenModuleFolder method for better user experience. - Refined StatusForm layout, integrating UiCardPanel for information display and adjusting component arrangements for clarity. - Removed redundant graphics path creation methods, centralizing functionality in UiTheme. - Enhanced overall code readability and maintainability through consistent styling and structure.
This commit is contained in:
@@ -98,13 +98,12 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
|
||||
private Control BuildSidebar()
|
||||
{
|
||||
var panel = new TableLayoutPanel
|
||||
var panel = new UiCardPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.SurfaceRaised,
|
||||
ColumnCount = 1,
|
||||
RowCount = 2,
|
||||
Padding = new Padding(12),
|
||||
Padding = new Padding(14),
|
||||
Margin = new Padding(0, 0, 12, 0)
|
||||
};
|
||||
panel.RowStyles.Add(new RowStyle(SizeType.Absolute, 28));
|
||||
@@ -117,6 +116,7 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
ForeColor = UiTheme.Text,
|
||||
Font = new Font(Font.FontFamily, 10F, FontStyle.Bold),
|
||||
TextAlign = ContentAlignment.MiddleLeft,
|
||||
BackColor = Color.Transparent,
|
||||
Margin = new Padding(0)
|
||||
}, 0, 0);
|
||||
|
||||
@@ -125,6 +125,7 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
_classList,
|
||||
item => (item as ClassListItem)?.ClassId,
|
||||
iconSize: 40);
|
||||
_classList.BackColor = UiTheme.SurfaceRaised;
|
||||
_classList.SelectedIndexChanged += (_, _) =>
|
||||
{
|
||||
if (_suppressUi)
|
||||
@@ -140,13 +141,12 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
|
||||
private Control BuildSpecSidebar()
|
||||
{
|
||||
var panel = new TableLayoutPanel
|
||||
var panel = new UiCardPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.SurfaceRaised,
|
||||
ColumnCount = 1,
|
||||
RowCount = 2,
|
||||
Padding = new Padding(12),
|
||||
Padding = new Padding(14),
|
||||
Margin = new Padding(0, 0, 12, 0)
|
||||
};
|
||||
panel.RowStyles.Add(new RowStyle(SizeType.Absolute, 28));
|
||||
@@ -159,6 +159,7 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
ForeColor = UiTheme.Text,
|
||||
Font = new Font(Font.FontFamily, 10F, FontStyle.Bold),
|
||||
TextAlign = ContentAlignment.MiddleLeft,
|
||||
BackColor = Color.Transparent,
|
||||
Margin = new Padding(0)
|
||||
}, 0, 0);
|
||||
|
||||
@@ -167,6 +168,7 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
_specList,
|
||||
item => item is SpecOption spec ? (spec.ClassId, spec.Id) : null,
|
||||
iconSize: 40);
|
||||
_specList.BackColor = UiTheme.SurfaceRaised;
|
||||
_specList.SelectedIndexChanged += (_, _) =>
|
||||
{
|
||||
if (_suppressUi)
|
||||
@@ -202,14 +204,13 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 64));
|
||||
|
||||
var header = new TableLayoutPanel
|
||||
var header = new UiCardPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.SurfaceRaised,
|
||||
ColumnCount = 2,
|
||||
RowCount = 2,
|
||||
Padding = new Padding(14, 12, 14, 12),
|
||||
Margin = new Padding(0, 0, 0, 8)
|
||||
Margin = new Padding(0, 0, 0, 12)
|
||||
};
|
||||
header.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 56));
|
||||
header.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
|
||||
@@ -233,14 +234,13 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
|
||||
root.Controls.Add(BuildSectionTabs(), 0, 1);
|
||||
|
||||
var actionRow = new TableLayoutPanel
|
||||
var actionRow = new UiCardPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.Surface,
|
||||
ColumnCount = 2,
|
||||
RowCount = 1,
|
||||
Margin = new Padding(0),
|
||||
Padding = new Padding(0, 8, 12, 12)
|
||||
Margin = new Padding(0, 12, 0, 0),
|
||||
Padding = new Padding(14, 10, 14, 10)
|
||||
};
|
||||
actionRow.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
|
||||
actionRow.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 228));
|
||||
@@ -250,7 +250,7 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
Dock = DockStyle.Fill,
|
||||
FlowDirection = FlowDirection.LeftToRight,
|
||||
WrapContents = false,
|
||||
BackColor = UiTheme.Surface,
|
||||
BackColor = Color.Transparent,
|
||||
Margin = new Padding(0)
|
||||
};
|
||||
StyleActionButton(_reloadButton);
|
||||
@@ -276,16 +276,16 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
RowCount = 2,
|
||||
Margin = new Padding(0)
|
||||
};
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 40));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 42));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
|
||||
var tabBar = new TableLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.Border,
|
||||
BackColor = UiTheme.Surface,
|
||||
ColumnCount = 5,
|
||||
RowCount = 1,
|
||||
Margin = new Padding(0),
|
||||
Margin = new Padding(0, 0, 0, 8),
|
||||
Padding = new Padding(0)
|
||||
};
|
||||
for (var i = 0; i < 5; i++)
|
||||
@@ -293,13 +293,25 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
tabBar.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 20));
|
||||
}
|
||||
|
||||
var contentCard = new UiCardPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
ColumnCount = 1,
|
||||
RowCount = 1,
|
||||
Margin = new Padding(0),
|
||||
Padding = new Padding(14)
|
||||
};
|
||||
contentCard.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
|
||||
contentCard.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
|
||||
var contentHost = new Panel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.SurfaceRaised,
|
||||
Margin = new Padding(0),
|
||||
Padding = new Padding(12)
|
||||
Padding = new Padding(0)
|
||||
};
|
||||
contentCard.Controls.Add(contentHost, 0, 0);
|
||||
|
||||
var pages = new Control[]
|
||||
{
|
||||
@@ -313,10 +325,11 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
{
|
||||
page.Dock = DockStyle.Fill;
|
||||
page.Visible = false;
|
||||
page.BackColor = UiTheme.SurfaceRaised;
|
||||
contentHost.Controls.Add(page);
|
||||
}
|
||||
|
||||
var labels = new Label[5];
|
||||
var tabs = new UiPillTab[5];
|
||||
var selectedIndex = -1;
|
||||
void SelectTab(int index)
|
||||
{
|
||||
@@ -326,12 +339,10 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
}
|
||||
|
||||
selectedIndex = index;
|
||||
for (var i = 0; i < labels.Length; i++)
|
||||
for (var i = 0; i < tabs.Length; i++)
|
||||
{
|
||||
var selected = i == index;
|
||||
labels[i].BackColor = selected ? UiTheme.Field : UiTheme.Surface;
|
||||
labels[i].ForeColor = selected ? UiTheme.Text : UiTheme.Muted;
|
||||
labels[i].Invalidate();
|
||||
tabs[i].Selected = selected;
|
||||
pages[i].Visible = selected;
|
||||
if (selected)
|
||||
{
|
||||
@@ -344,49 +355,14 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
for (var i = 0; i < titles.Length; i++)
|
||||
{
|
||||
var index = i;
|
||||
var label = new Label
|
||||
{
|
||||
Text = titles[i],
|
||||
Dock = DockStyle.Fill,
|
||||
TextAlign = ContentAlignment.MiddleCenter,
|
||||
AutoSize = false,
|
||||
BackColor = UiTheme.Surface,
|
||||
ForeColor = UiTheme.Muted,
|
||||
Cursor = Cursors.Hand,
|
||||
Margin = new Padding(i == 0 ? 0 : 1, 0, 0, 0)
|
||||
};
|
||||
label.Click += (_, _) => SelectTab(index);
|
||||
label.MouseEnter += (_, _) =>
|
||||
{
|
||||
if (selectedIndex != index)
|
||||
{
|
||||
label.BackColor = UiTheme.Hover;
|
||||
}
|
||||
};
|
||||
label.MouseLeave += (_, _) =>
|
||||
{
|
||||
if (selectedIndex != index)
|
||||
{
|
||||
label.BackColor = UiTheme.Surface;
|
||||
}
|
||||
};
|
||||
label.Paint += (_, e) =>
|
||||
{
|
||||
if (selectedIndex != index)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var accent = new SolidBrush(UiTheme.Accent);
|
||||
e.Graphics.FillRectangle(accent, 8, label.Height - 3, Math.Max(0, label.Width - 16), 2);
|
||||
};
|
||||
label.SizeChanged += (_, _) => label.Invalidate();
|
||||
labels[i] = label;
|
||||
tabBar.Controls.Add(label, i, 0);
|
||||
var tab = new UiPillTab(titles[i]);
|
||||
tab.Click += (_, _) => SelectTab(index);
|
||||
tabs[i] = tab;
|
||||
tabBar.Controls.Add(tab, i, 0);
|
||||
}
|
||||
|
||||
root.Controls.Add(tabBar, 0, 0);
|
||||
root.Controls.Add(contentHost, 0, 1);
|
||||
root.Controls.Add(contentCard, 0, 1);
|
||||
SelectTab(0);
|
||||
return root;
|
||||
}
|
||||
@@ -432,7 +408,7 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
var tabBar = new TableLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.Border,
|
||||
BackColor = UiTheme.SurfaceRaised,
|
||||
ColumnCount = categories.Length,
|
||||
RowCount = 1,
|
||||
Margin = new Padding(0),
|
||||
@@ -443,15 +419,12 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
tabBar.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F / categories.Length));
|
||||
}
|
||||
|
||||
var labels = new Label[categories.Length];
|
||||
var tabs = new UiPillTab[categories.Length];
|
||||
void ApplySelection()
|
||||
{
|
||||
for (var i = 0; i < labels.Length; i++)
|
||||
for (var i = 0; i < tabs.Length; i++)
|
||||
{
|
||||
var selected = string.Equals(categories[i], _selectedStateCategory, StringComparison.Ordinal);
|
||||
labels[i].BackColor = selected ? UiTheme.Field : UiTheme.Surface;
|
||||
labels[i].ForeColor = selected ? UiTheme.Text : UiTheme.Muted;
|
||||
labels[i].Invalidate();
|
||||
tabs[i].Selected = string.Equals(categories[i], _selectedStateCategory, StringComparison.Ordinal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,45 +447,10 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
for (var i = 0; i < categories.Length; i++)
|
||||
{
|
||||
var category = categories[i];
|
||||
var label = new Label
|
||||
{
|
||||
Text = category,
|
||||
Dock = DockStyle.Fill,
|
||||
TextAlign = ContentAlignment.MiddleCenter,
|
||||
AutoSize = false,
|
||||
BackColor = UiTheme.Surface,
|
||||
ForeColor = UiTheme.Muted,
|
||||
Cursor = Cursors.Hand,
|
||||
Margin = new Padding(i == 0 ? 0 : 1, 0, 0, 0)
|
||||
};
|
||||
label.Click += (_, _) => SelectCategory(category);
|
||||
label.MouseEnter += (_, _) =>
|
||||
{
|
||||
if (!string.Equals(category, _selectedStateCategory, StringComparison.Ordinal))
|
||||
{
|
||||
label.BackColor = UiTheme.Hover;
|
||||
}
|
||||
};
|
||||
label.MouseLeave += (_, _) =>
|
||||
{
|
||||
if (!string.Equals(category, _selectedStateCategory, StringComparison.Ordinal))
|
||||
{
|
||||
label.BackColor = UiTheme.Surface;
|
||||
}
|
||||
};
|
||||
label.Paint += (_, e) =>
|
||||
{
|
||||
if (!string.Equals(category, _selectedStateCategory, StringComparison.Ordinal))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var accent = new SolidBrush(UiTheme.Accent);
|
||||
e.Graphics.FillRectangle(accent, 8, label.Height - 3, Math.Max(0, label.Width - 16), 2);
|
||||
};
|
||||
label.SizeChanged += (_, _) => label.Invalidate();
|
||||
labels[i] = label;
|
||||
tabBar.Controls.Add(label, i, 0);
|
||||
var tab = new UiPillTab(category);
|
||||
tab.Click += (_, _) => SelectCategory(category);
|
||||
tabs[i] = tab;
|
||||
tabBar.Controls.Add(tab, i, 0);
|
||||
}
|
||||
|
||||
ApplySelection();
|
||||
@@ -859,6 +797,7 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
Dock = DockStyle.Fill,
|
||||
AutoSize = false,
|
||||
ForeColor = UiTheme.Muted,
|
||||
BackColor = Color.Transparent,
|
||||
TextAlign = ContentAlignment.MiddleLeft,
|
||||
Margin = new Padding(0),
|
||||
AutoEllipsis = true
|
||||
@@ -869,6 +808,7 @@ public sealed class ClassConfigEditorControl : UserControl
|
||||
label.Dock = DockStyle.Fill;
|
||||
label.AutoSize = false;
|
||||
label.ForeColor = foreColor;
|
||||
label.BackColor = Color.Transparent;
|
||||
label.TextAlign = ContentAlignment.MiddleLeft;
|
||||
label.AutoEllipsis = true;
|
||||
label.Margin = new Padding(0);
|
||||
|
||||
@@ -73,13 +73,12 @@ public sealed class ClassMacrosEditorControl : UserControl
|
||||
|
||||
private Control BuildSidebar()
|
||||
{
|
||||
var panel = new TableLayoutPanel
|
||||
var panel = new UiCardPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.SurfaceRaised,
|
||||
ColumnCount = 1,
|
||||
RowCount = 2,
|
||||
Padding = new Padding(12),
|
||||
Padding = new Padding(14),
|
||||
Margin = new Padding(0, 0, 12, 0)
|
||||
};
|
||||
panel.RowStyles.Add(new RowStyle(SizeType.Absolute, 28));
|
||||
@@ -92,6 +91,7 @@ public sealed class ClassMacrosEditorControl : UserControl
|
||||
ForeColor = UiTheme.Text,
|
||||
Font = new Font(Font.FontFamily, 10F, FontStyle.Bold),
|
||||
TextAlign = ContentAlignment.MiddleLeft,
|
||||
BackColor = Color.Transparent,
|
||||
Margin = new Padding(0)
|
||||
}, 0, 0);
|
||||
|
||||
@@ -100,6 +100,7 @@ public sealed class ClassMacrosEditorControl : UserControl
|
||||
_classList,
|
||||
item => (item as ClassListItem)?.ClassId,
|
||||
iconSize: 40);
|
||||
_classList.BackColor = UiTheme.SurfaceRaised;
|
||||
_classList.SelectedIndexChanged += (_, _) =>
|
||||
{
|
||||
if (!_suppressUi)
|
||||
@@ -134,14 +135,13 @@ public sealed class ClassMacrosEditorControl : UserControl
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 64));
|
||||
|
||||
var header = new TableLayoutPanel
|
||||
var header = new UiCardPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.SurfaceRaised,
|
||||
ColumnCount = 2,
|
||||
RowCount = 2,
|
||||
Padding = new Padding(14, 12, 14, 12),
|
||||
Margin = new Padding(0, 0, 0, 8)
|
||||
Margin = new Padding(0, 0, 0, 12)
|
||||
};
|
||||
header.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 56));
|
||||
header.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
|
||||
@@ -166,6 +166,7 @@ public sealed class ClassMacrosEditorControl : UserControl
|
||||
_offsetLabel.Dock = DockStyle.Fill;
|
||||
_offsetLabel.AutoSize = false;
|
||||
_offsetLabel.ForeColor = UiTheme.Muted;
|
||||
_offsetLabel.BackColor = Color.Transparent;
|
||||
_offsetLabel.TextAlign = ContentAlignment.MiddleLeft;
|
||||
_offsetLabel.Padding = new Padding(14, 0, 14, 0);
|
||||
_offsetLabel.Margin = new Padding(0);
|
||||
@@ -175,14 +176,13 @@ public sealed class ClassMacrosEditorControl : UserControl
|
||||
|
||||
root.Controls.Add(BuildSectionTabs(), 0, 2);
|
||||
|
||||
var actionRow = new TableLayoutPanel
|
||||
var actionRow = new UiCardPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.Surface,
|
||||
ColumnCount = 2,
|
||||
RowCount = 1,
|
||||
Margin = new Padding(0),
|
||||
Padding = new Padding(0, 8, 12, 12)
|
||||
Margin = new Padding(0, 12, 0, 0),
|
||||
Padding = new Padding(14, 10, 14, 10)
|
||||
};
|
||||
actionRow.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
|
||||
actionRow.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 228));
|
||||
@@ -192,7 +192,7 @@ public sealed class ClassMacrosEditorControl : UserControl
|
||||
Dock = DockStyle.Fill,
|
||||
FlowDirection = FlowDirection.LeftToRight,
|
||||
WrapContents = false,
|
||||
BackColor = UiTheme.Surface,
|
||||
BackColor = Color.Transparent,
|
||||
Margin = new Padding(0)
|
||||
};
|
||||
StyleActionButton(_reloadButton);
|
||||
@@ -218,29 +218,42 @@ public sealed class ClassMacrosEditorControl : UserControl
|
||||
RowCount = 2,
|
||||
Margin = new Padding(0)
|
||||
};
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 40));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 42));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
|
||||
var tabBar = new TableLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.Border,
|
||||
BackColor = UiTheme.Surface,
|
||||
ColumnCount = 3,
|
||||
RowCount = 1,
|
||||
Margin = new Padding(0)
|
||||
Margin = new Padding(0, 0, 0, 8),
|
||||
Padding = new Padding(0)
|
||||
};
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
tabBar.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.33f));
|
||||
}
|
||||
|
||||
var contentCard = new UiCardPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
ColumnCount = 1,
|
||||
RowCount = 1,
|
||||
Margin = new Padding(0),
|
||||
Padding = new Padding(14)
|
||||
};
|
||||
contentCard.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
|
||||
contentCard.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
|
||||
var contentHost = new Panel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.SurfaceRaised,
|
||||
Margin = new Padding(0),
|
||||
Padding = new Padding(12)
|
||||
Padding = new Padding(0)
|
||||
};
|
||||
contentCard.Controls.Add(contentHost, 0, 0);
|
||||
|
||||
var pages = new Control[]
|
||||
{
|
||||
@@ -252,10 +265,11 @@ public sealed class ClassMacrosEditorControl : UserControl
|
||||
{
|
||||
page.Dock = DockStyle.Fill;
|
||||
page.Visible = false;
|
||||
page.BackColor = UiTheme.SurfaceRaised;
|
||||
contentHost.Controls.Add(page);
|
||||
}
|
||||
|
||||
var labels = new Label[3];
|
||||
var tabs = new UiPillTab[3];
|
||||
var selectedIndex = -1;
|
||||
void SelectTab(int index)
|
||||
{
|
||||
@@ -265,12 +279,10 @@ public sealed class ClassMacrosEditorControl : UserControl
|
||||
}
|
||||
|
||||
selectedIndex = index;
|
||||
for (var i = 0; i < labels.Length; i++)
|
||||
for (var i = 0; i < tabs.Length; i++)
|
||||
{
|
||||
var selected = i == index;
|
||||
labels[i].BackColor = selected ? UiTheme.Field : UiTheme.Surface;
|
||||
labels[i].ForeColor = selected ? UiTheme.Text : UiTheme.Muted;
|
||||
labels[i].Invalidate();
|
||||
tabs[i].Selected = selected;
|
||||
pages[i].Visible = selected;
|
||||
if (selected)
|
||||
{
|
||||
@@ -283,49 +295,14 @@ public sealed class ClassMacrosEditorControl : UserControl
|
||||
for (var i = 0; i < titles.Length; i++)
|
||||
{
|
||||
var index = i;
|
||||
var label = new Label
|
||||
{
|
||||
Text = titles[i],
|
||||
Dock = DockStyle.Fill,
|
||||
TextAlign = ContentAlignment.MiddleCenter,
|
||||
AutoSize = false,
|
||||
BackColor = UiTheme.Surface,
|
||||
ForeColor = UiTheme.Muted,
|
||||
Cursor = Cursors.Hand,
|
||||
Margin = new Padding(i == 0 ? 0 : 1, 0, 0, 0)
|
||||
};
|
||||
label.Click += (_, _) => SelectTab(index);
|
||||
label.MouseEnter += (_, _) =>
|
||||
{
|
||||
if (selectedIndex != index)
|
||||
{
|
||||
label.BackColor = UiTheme.Hover;
|
||||
}
|
||||
};
|
||||
label.MouseLeave += (_, _) =>
|
||||
{
|
||||
if (selectedIndex != index)
|
||||
{
|
||||
label.BackColor = UiTheme.Surface;
|
||||
}
|
||||
};
|
||||
label.Paint += (_, e) =>
|
||||
{
|
||||
if (selectedIndex != index)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var accent = new SolidBrush(UiTheme.Accent);
|
||||
e.Graphics.FillRectangle(accent, 8, label.Height - 3, Math.Max(0, label.Width - 16), 2);
|
||||
};
|
||||
label.SizeChanged += (_, _) => label.Invalidate();
|
||||
labels[i] = label;
|
||||
tabBar.Controls.Add(label, i, 0);
|
||||
var tab = new UiPillTab(titles[i]);
|
||||
tab.Click += (_, _) => SelectTab(index);
|
||||
tabs[i] = tab;
|
||||
tabBar.Controls.Add(tab, i, 0);
|
||||
}
|
||||
|
||||
root.Controls.Add(tabBar, 0, 0);
|
||||
root.Controls.Add(contentHost, 0, 1);
|
||||
root.Controls.Add(contentCard, 0, 1);
|
||||
SelectTab(0);
|
||||
return root;
|
||||
}
|
||||
@@ -614,6 +591,7 @@ public sealed class ClassMacrosEditorControl : UserControl
|
||||
Dock = DockStyle.Fill,
|
||||
AutoSize = false,
|
||||
ForeColor = UiTheme.Muted,
|
||||
BackColor = Color.Transparent,
|
||||
TextAlign = ContentAlignment.MiddleLeft,
|
||||
Margin = new Padding(0),
|
||||
AutoEllipsis = true
|
||||
@@ -624,6 +602,7 @@ public sealed class ClassMacrosEditorControl : UserControl
|
||||
label.Dock = DockStyle.Fill;
|
||||
label.AutoSize = false;
|
||||
label.ForeColor = foreColor;
|
||||
label.BackColor = Color.Transparent;
|
||||
label.TextAlign = ContentAlignment.MiddleLeft;
|
||||
label.AutoEllipsis = true;
|
||||
label.Margin = new Padding(0);
|
||||
|
||||
@@ -109,6 +109,9 @@ public sealed class ModuleEditorControl : UserControl
|
||||
_rulesGrid.Invalidate();
|
||||
}
|
||||
|
||||
private const int ModuleFooterBarHeight = 56;
|
||||
private const int ModuleFooterButtonHeight = 36;
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
Dock = DockStyle.Fill;
|
||||
@@ -121,29 +124,32 @@ public sealed class ModuleEditorControl : UserControl
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.Surface,
|
||||
ColumnCount = 2,
|
||||
RowCount = 1,
|
||||
RowCount = 2,
|
||||
Margin = new Padding(0)
|
||||
};
|
||||
root.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 300));
|
||||
root.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Absolute, ModuleFooterBarHeight));
|
||||
Controls.Add(root);
|
||||
|
||||
root.Controls.Add(BuildSidebar(), 0, 0);
|
||||
root.Controls.Add(BuildEditor(), 1, 0);
|
||||
root.Controls.Add(BuildSidebarFooter(), 0, 1);
|
||||
root.Controls.Add(BuildActionRow(), 1, 1);
|
||||
}
|
||||
|
||||
private Control BuildSidebar()
|
||||
{
|
||||
var sidebar = new TableLayoutPanel
|
||||
var sidebar = new UiCardPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.Background,
|
||||
Padding = new Padding(0, 0, 14, 0),
|
||||
Padding = new Padding(14),
|
||||
Margin = new Padding(0, 0, 12, 12),
|
||||
ColumnCount = 1,
|
||||
RowCount = 2
|
||||
RowCount = 1
|
||||
};
|
||||
sidebar.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
sidebar.RowStyles.Add(new RowStyle(SizeType.Absolute, 50));
|
||||
|
||||
_moduleList.Dock = DockStyle.Fill;
|
||||
UiTheme.StyleListBox(
|
||||
@@ -152,39 +158,39 @@ public sealed class ModuleEditorControl : UserControl
|
||||
index => index >= 0 && index < _modules.Count
|
||||
? (_modules[index].Match.ClassId, _modules[index].Match.SpecId)
|
||||
: (null, null));
|
||||
_moduleList.BackColor = UiTheme.Background;
|
||||
_moduleList.BackColor = UiTheme.SurfaceRaised;
|
||||
_moduleList.SelectedIndexChanged += (_, _) => SelectModule(_moduleList.SelectedIndex);
|
||||
sidebar.Controls.Add(_moduleList, 0, 0);
|
||||
return sidebar;
|
||||
}
|
||||
|
||||
var buttons = new TableLayoutPanel
|
||||
private Control BuildSidebarFooter()
|
||||
{
|
||||
var footer = new UiCardPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.Background,
|
||||
Margin = new Padding(0),
|
||||
Padding = new Padding(14, 3, 14, 3),
|
||||
Padding = new Padding(14, 10, 14, 10),
|
||||
Margin = new Padding(0, 0, 12, 0),
|
||||
ColumnCount = 3,
|
||||
RowCount = 1
|
||||
};
|
||||
buttons.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50));
|
||||
buttons.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 6));
|
||||
buttons.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50));
|
||||
buttons.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
footer.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50));
|
||||
footer.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 8));
|
||||
footer.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50));
|
||||
footer.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
|
||||
var reloadButton = UiTheme.CreateButton("刷新", UiTheme.Field, UiTheme.Text);
|
||||
reloadButton.AutoSize = false;
|
||||
var reloadButton = UiTheme.CreateButton("刷新", UiTheme.ButtonKind.Secondary);
|
||||
StyleModuleFooterButton(reloadButton);
|
||||
reloadButton.Dock = DockStyle.Fill;
|
||||
reloadButton.Margin = new Padding(0);
|
||||
reloadButton.Click += (_, _) => LoadModules();
|
||||
|
||||
var getModulesButton = UiTheme.CreateButton(
|
||||
"获取模块",
|
||||
Color.FromArgb(252, 238, 10),
|
||||
Color.Black);
|
||||
getModulesButton.AutoSize = false;
|
||||
StyleModuleFooterButton(getModulesButton);
|
||||
getModulesButton.Dock = DockStyle.Fill;
|
||||
getModulesButton.Margin = new Padding(0);
|
||||
getModulesButton.Padding = new Padding(0, 2, 24, 2);
|
||||
getModulesButton.TextAlign = ContentAlignment.MiddleCenter;
|
||||
getModulesButton.FlatAppearance.BorderColor = Color.FromArgb(252, 238, 10);
|
||||
getModulesButton.FlatAppearance.MouseOverBackColor = Color.FromArgb(255, 244, 64);
|
||||
getModulesButton.FlatAppearance.MouseDownBackColor = Color.FromArgb(220, 207, 8);
|
||||
@@ -197,11 +203,9 @@ public sealed class ModuleEditorControl : UserControl
|
||||
getModulesButton.DeviceDpi / 96F);
|
||||
getModulesButton.Click += (_, _) => OpenModuleWebsite();
|
||||
|
||||
buttons.Controls.Add(reloadButton, 0, 0);
|
||||
buttons.Controls.Add(getModulesButton, 2, 0);
|
||||
sidebar.Controls.Add(buttons, 0, 1);
|
||||
|
||||
return sidebar;
|
||||
footer.Controls.Add(reloadButton, 0, 0);
|
||||
footer.Controls.Add(getModulesButton, 2, 0);
|
||||
return footer;
|
||||
}
|
||||
|
||||
private static void DrawExternalLinkIcon(
|
||||
@@ -280,20 +284,18 @@ public sealed class ModuleEditorControl : UserControl
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.Surface,
|
||||
Padding = new Padding(10, 0, 0, 6),
|
||||
Padding = new Padding(0),
|
||||
Margin = new Padding(0, 0, 0, 12),
|
||||
ColumnCount = 1,
|
||||
RowCount = 4
|
||||
RowCount = 3
|
||||
};
|
||||
editor.RowStyles.Add(new RowStyle(SizeType.Absolute, 82));
|
||||
// 匹配卡片略增高,给首行居中和推荐天赋行的上下间距留出空间。
|
||||
editor.RowStyles.Add(new RowStyle(SizeType.Absolute, 112));
|
||||
editor.RowStyles.Add(new RowStyle(SizeType.Absolute, 86));
|
||||
editor.RowStyles.Add(new RowStyle(SizeType.Absolute, 120));
|
||||
editor.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
editor.RowStyles.Add(new RowStyle(SizeType.Absolute, 54));
|
||||
|
||||
editor.Controls.Add(BuildNameRow(), 0, 0);
|
||||
editor.Controls.Add(BuildMatchRow(), 0, 1);
|
||||
editor.Controls.Add(BuildEditorTabs(), 0, 2);
|
||||
editor.Controls.Add(BuildActionRow(), 0, 3);
|
||||
return editor;
|
||||
}
|
||||
|
||||
@@ -302,13 +304,13 @@ public sealed class ModuleEditorControl : UserControl
|
||||
var root = new TableLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
Margin = new Padding(0, 12, 0, 8),
|
||||
Margin = new Padding(0, 12, 0, 0),
|
||||
Padding = new Padding(0),
|
||||
BackColor = UiTheme.Surface,
|
||||
ColumnCount = 1,
|
||||
RowCount = 2
|
||||
};
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 38));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 42));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
|
||||
var tabBar = new TableLayoutPanel
|
||||
@@ -317,7 +319,7 @@ public sealed class ModuleEditorControl : UserControl
|
||||
BackColor = UiTheme.Surface,
|
||||
ColumnCount = 3,
|
||||
RowCount = 1,
|
||||
Margin = new Padding(0),
|
||||
Margin = new Padding(0, 0, 0, 8),
|
||||
Padding = new Padding(0)
|
||||
};
|
||||
tabBar.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
@@ -326,12 +328,24 @@ public sealed class ModuleEditorControl : UserControl
|
||||
tabBar.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F / 3F));
|
||||
}
|
||||
|
||||
var contentCard = new UiCardPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
ColumnCount = 1,
|
||||
RowCount = 1,
|
||||
Margin = new Padding(0),
|
||||
Padding = new Padding(0)
|
||||
};
|
||||
contentCard.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
|
||||
contentCard.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
|
||||
var contentHost = new Panel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.SurfaceRaised,
|
||||
Margin = new Padding(0)
|
||||
};
|
||||
contentCard.Controls.Add(contentHost, 0, 0);
|
||||
|
||||
var pages = new[]
|
||||
{
|
||||
@@ -343,6 +357,7 @@ public sealed class ModuleEditorControl : UserControl
|
||||
{
|
||||
page.Dock = DockStyle.Fill;
|
||||
page.Visible = false;
|
||||
page.BackColor = UiTheme.SurfaceRaised;
|
||||
contentHost.Controls.Add(page);
|
||||
}
|
||||
|
||||
@@ -355,7 +370,7 @@ public sealed class ModuleEditorControl : UserControl
|
||||
contentHost.Controls.Add(_editorEmptyHint);
|
||||
_editorEmptyHint.BringToFront();
|
||||
|
||||
var labels = new Label[3];
|
||||
var tabs = new UiPillTab[3];
|
||||
var selectedIndex = -1;
|
||||
|
||||
void SelectTab(int index)
|
||||
@@ -366,12 +381,10 @@ public sealed class ModuleEditorControl : UserControl
|
||||
}
|
||||
|
||||
selectedIndex = index;
|
||||
for (var i = 0; i < labels.Length; i++)
|
||||
for (var i = 0; i < tabs.Length; i++)
|
||||
{
|
||||
var selected = i == index;
|
||||
labels[i].BackColor = selected ? UiTheme.Field : UiTheme.Surface;
|
||||
labels[i].ForeColor = selected ? UiTheme.Text : UiTheme.Muted;
|
||||
labels[i].Invalidate();
|
||||
tabs[i].Selected = selected;
|
||||
pages[i].Visible = selected;
|
||||
if (selected)
|
||||
{
|
||||
@@ -384,51 +397,14 @@ public sealed class ModuleEditorControl : UserControl
|
||||
for (var i = 0; i < titles.Length; i++)
|
||||
{
|
||||
var index = i;
|
||||
var label = new Label
|
||||
{
|
||||
Text = titles[i],
|
||||
Dock = DockStyle.Fill,
|
||||
TextAlign = ContentAlignment.MiddleCenter,
|
||||
AutoSize = false,
|
||||
BackColor = UiTheme.Surface,
|
||||
ForeColor = UiTheme.Muted,
|
||||
Cursor = Cursors.Hand,
|
||||
Margin = new Padding(i == 0 ? 0 : 1, 0, 0, 0)
|
||||
};
|
||||
label.Click += (_, _) => SelectTab(index);
|
||||
label.MouseEnter += (_, _) =>
|
||||
{
|
||||
if (selectedIndex != index)
|
||||
{
|
||||
label.BackColor = UiTheme.Hover;
|
||||
}
|
||||
};
|
||||
label.MouseLeave += (_, _) =>
|
||||
{
|
||||
if (selectedIndex != index)
|
||||
{
|
||||
label.BackColor = UiTheme.Surface;
|
||||
}
|
||||
};
|
||||
label.Paint += (_, e) =>
|
||||
{
|
||||
if (selectedIndex != index)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var accent = new SolidBrush(UiTheme.Accent);
|
||||
e.Graphics.FillRectangle(accent, 8, label.Height - 3, Math.Max(0, label.Width - 16), 2);
|
||||
};
|
||||
// 标签随窗口/侧栏宽度变化时重绘, 否则选中下划线会停留在旧宽度。
|
||||
label.SizeChanged += (_, _) => label.Invalidate();
|
||||
|
||||
labels[i] = label;
|
||||
tabBar.Controls.Add(label, i, 0);
|
||||
var tab = new UiPillTab(titles[i]);
|
||||
tab.Click += (_, _) => SelectTab(index);
|
||||
tabs[i] = tab;
|
||||
tabBar.Controls.Add(tab, i, 0);
|
||||
}
|
||||
|
||||
root.Controls.Add(tabBar, 0, 0);
|
||||
root.Controls.Add(contentHost, 0, 1);
|
||||
root.Controls.Add(contentCard, 0, 1);
|
||||
SelectTab(0);
|
||||
return root;
|
||||
}
|
||||
@@ -553,14 +529,13 @@ public sealed class ModuleEditorControl : UserControl
|
||||
|
||||
private Control BuildNameRow()
|
||||
{
|
||||
var row = new TableLayoutPanel
|
||||
var row = new UiCardPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.SurfaceRaised,
|
||||
ColumnCount = 4,
|
||||
RowCount = 2,
|
||||
Padding = new Padding(12, 10, 12, 4),
|
||||
Margin = new Padding(0, 0, 0, 10)
|
||||
Padding = new Padding(14, 10, 14, 8),
|
||||
Margin = new Padding(0, 0, 0, 12)
|
||||
};
|
||||
// 名称/作者各占剩余宽度的一半, 两个输入框等宽并铺满窗口。
|
||||
row.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 58));
|
||||
@@ -584,6 +559,7 @@ public sealed class ModuleEditorControl : UserControl
|
||||
|
||||
_pathLabel.Dock = DockStyle.Fill;
|
||||
_pathLabel.ForeColor = UiTheme.Muted;
|
||||
_pathLabel.BackColor = Color.Transparent;
|
||||
_pathLabel.TextAlign = ContentAlignment.MiddleLeft;
|
||||
_pathLabel.AutoEllipsis = true;
|
||||
_pathLabel.TextChanged += (_, _) => _pathToolTip.SetToolTip(_pathLabel, _pathLabel.Text);
|
||||
@@ -593,6 +569,7 @@ public sealed class ModuleEditorControl : UserControl
|
||||
// 版本号紧贴窗口右侧, 右对齐显示在"路径"同一行。
|
||||
_versionLabel.Dock = DockStyle.Fill;
|
||||
_versionLabel.ForeColor = UiTheme.Muted;
|
||||
_versionLabel.BackColor = Color.Transparent;
|
||||
_versionLabel.TextAlign = ContentAlignment.MiddleRight;
|
||||
_versionLabel.AutoEllipsis = true;
|
||||
row.Controls.Add(_versionLabel, 3, 1);
|
||||
@@ -604,13 +581,12 @@ public sealed class ModuleEditorControl : UserControl
|
||||
{
|
||||
var matchLabels = new[] { "职业", "专精", "英雄天赋", "队伍类型" };
|
||||
|
||||
var row = new TableLayoutPanel
|
||||
var row = new UiCardPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.SurfaceRaised,
|
||||
ColumnCount = 12,
|
||||
RowCount = 2,
|
||||
Padding = new Padding(12),
|
||||
Padding = new Padding(14),
|
||||
Margin = new Padding(0)
|
||||
};
|
||||
foreach (var label in matchLabels)
|
||||
@@ -649,7 +625,7 @@ public sealed class ModuleEditorControl : UserControl
|
||||
var recommendedTalentRow = new TableLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.SurfaceRaised,
|
||||
BackColor = Color.Transparent,
|
||||
ColumnCount = 2,
|
||||
RowCount = 1,
|
||||
// 推荐天赋整行相对原位置下移 4px,并与上方匹配项保持清晰间距。
|
||||
@@ -2218,7 +2194,7 @@ public sealed class ModuleEditorControl : UserControl
|
||||
|
||||
var oldSmoothingMode = e.Graphics.SmoothingMode;
|
||||
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
using (var path = CreateRoundedRectanglePath(buttonBounds, 4))
|
||||
using (var path = UiTheme.CreateRoundedRectanglePath(buttonBounds, 4))
|
||||
using (var background = new SolidBrush(selected ? UiTheme.Pressed : UiTheme.Hover))
|
||||
using (var border = new Pen(selected ? UiTheme.Accent : UiTheme.Border))
|
||||
{
|
||||
@@ -2243,18 +2219,6 @@ public sealed class ModuleEditorControl : UserControl
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private static GraphicsPath CreateRoundedRectanglePath(Rectangle bounds, int radius)
|
||||
{
|
||||
var path = new GraphicsPath();
|
||||
var diameter = radius * 2;
|
||||
path.AddArc(bounds.Left, bounds.Top, diameter, diameter, 180, 90);
|
||||
path.AddArc(bounds.Right - diameter, bounds.Top, diameter, diameter, 270, 90);
|
||||
path.AddArc(bounds.Right - diameter, bounds.Bottom - diameter, diameter, diameter, 0, 90);
|
||||
path.AddArc(bounds.Left, bounds.Bottom - diameter, diameter, diameter, 90, 90);
|
||||
path.CloseFigure();
|
||||
return path;
|
||||
}
|
||||
|
||||
// 自绘 2×3 六点抓手, 不依赖字体里是否有 grip 字形; 新行不画。
|
||||
private void PaintRuleDragHandle(DataGridViewCellPaintingEventArgs e)
|
||||
{
|
||||
@@ -2869,56 +2833,128 @@ public sealed class ModuleEditorControl : UserControl
|
||||
|
||||
private Control BuildActionRow()
|
||||
{
|
||||
var row = new Panel
|
||||
var row = new UiCardPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.SurfaceRaised,
|
||||
ColumnCount = 3,
|
||||
RowCount = 1,
|
||||
Margin = new Padding(0),
|
||||
Padding = new Padding(12, 0, 12, 0)
|
||||
Padding = new Padding(14, 10, 14, 10)
|
||||
};
|
||||
row.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 148));
|
||||
row.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
|
||||
row.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 360));
|
||||
row.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
|
||||
var hint = new Label
|
||||
var openFolderButton = UiTheme.CreateButton("打开目录", UiTheme.ButtonKind.Secondary);
|
||||
StyleModuleFooterButton(openFolderButton);
|
||||
openFolderButton.Dock = DockStyle.Fill;
|
||||
openFolderButton.Margin = new Padding(0, 0, 8, 0);
|
||||
openFolderButton.Click += (_, _) => OpenModuleFolder();
|
||||
_pathToolTip.SetToolTip(
|
||||
openFolderButton,
|
||||
"在资源管理器中打开模块目录;若已选中已保存模块则定位到对应文件");
|
||||
|
||||
var spacer = new Panel
|
||||
{
|
||||
Text = "目标可选技能支持的单位或上方定义的动态单位;宏条件来自对应宏的方括号;点击“条件”列打开可视化编辑器",
|
||||
Dock = DockStyle.Fill,
|
||||
ForeColor = UiTheme.Muted,
|
||||
TextAlign = ContentAlignment.MiddleLeft,
|
||||
AutoEllipsis = true,
|
||||
BackColor = Color.Transparent,
|
||||
Margin = new Padding(0)
|
||||
};
|
||||
|
||||
var buttons = new FlowLayoutPanel
|
||||
var buttons = new TableLayoutPanel
|
||||
{
|
||||
AutoSize = true,
|
||||
AutoSizeMode = AutoSizeMode.GrowAndShrink,
|
||||
Dock = DockStyle.Right,
|
||||
FlowDirection = FlowDirection.RightToLeft,
|
||||
WrapContents = false,
|
||||
BackColor = UiTheme.SurfaceRaised,
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = Color.Transparent,
|
||||
ColumnCount = 3,
|
||||
RowCount = 1,
|
||||
Margin = new Padding(0),
|
||||
Padding = new Padding(0, 8, 0, 8)
|
||||
Padding = new Padding(0)
|
||||
};
|
||||
|
||||
_saveButton = UiTheme.CreateButton("保存", UiTheme.ButtonKind.Primary);
|
||||
_saveButton.Margin = new Padding(8, 0, 0, 0);
|
||||
_saveButton.Click += async (_, _) => await RunModuleCommandAsync(SaveSelectedModuleAsync);
|
||||
|
||||
_deleteButton = UiTheme.CreateButton("删除", UiTheme.ButtonKind.Danger);
|
||||
_deleteButton.Margin = new Padding(8, 0, 0, 0);
|
||||
_deleteButton.Click += async (_, _) => await RunModuleCommandAsync(DeleteSelectedModuleAsync);
|
||||
buttons.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.33f));
|
||||
buttons.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.33f));
|
||||
buttons.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.34f));
|
||||
buttons.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
|
||||
|
||||
_addButton = UiTheme.CreateButton("新建", UiTheme.ButtonKind.Secondary);
|
||||
_addButton.Margin = new Padding(8, 0, 0, 0);
|
||||
StyleModuleFooterButton(_addButton);
|
||||
_addButton.Dock = DockStyle.Fill;
|
||||
_addButton.Margin = new Padding(0, 0, 8, 0);
|
||||
_addButton.Click += async (_, _) => await RunModuleCommandAsync(AddModuleAsync);
|
||||
|
||||
buttons.Controls.Add(_saveButton);
|
||||
buttons.Controls.Add(_deleteButton);
|
||||
buttons.Controls.Add(_addButton);
|
||||
row.Controls.Add(hint);
|
||||
row.Controls.Add(buttons);
|
||||
_deleteButton = UiTheme.CreateButton("删除", UiTheme.ButtonKind.Danger);
|
||||
StyleModuleFooterButton(_deleteButton);
|
||||
_deleteButton.Dock = DockStyle.Fill;
|
||||
_deleteButton.Margin = new Padding(0, 0, 8, 0);
|
||||
_deleteButton.Click += async (_, _) => await RunModuleCommandAsync(DeleteSelectedModuleAsync);
|
||||
|
||||
_saveButton = UiTheme.CreateButton("保存", UiTheme.ButtonKind.Primary);
|
||||
StyleModuleFooterButton(_saveButton);
|
||||
_saveButton.Dock = DockStyle.Fill;
|
||||
_saveButton.Margin = new Padding(0);
|
||||
_saveButton.Click += async (_, _) => await RunModuleCommandAsync(SaveSelectedModuleAsync);
|
||||
|
||||
buttons.Controls.Add(_addButton, 0, 0);
|
||||
buttons.Controls.Add(_deleteButton, 1, 0);
|
||||
buttons.Controls.Add(_saveButton, 2, 0);
|
||||
|
||||
row.Controls.Add(openFolderButton, 0, 0);
|
||||
row.Controls.Add(spacer, 1, 0);
|
||||
row.Controls.Add(buttons, 2, 0);
|
||||
return row;
|
||||
}
|
||||
|
||||
private void OpenModuleFolder()
|
||||
{
|
||||
var moduleDirectory = ModuleStore.ResolveModuleDirectory(_baseDirectory);
|
||||
var filePath = _selectedModule?.FilePath;
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(filePath) && File.Exists(filePath))
|
||||
{
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = "explorer.exe",
|
||||
Arguments = $"/select,\"{filePath}\"",
|
||||
UseShellExecute = true
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Directory.Exists(moduleDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(moduleDirectory);
|
||||
}
|
||||
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = "explorer.exe",
|
||||
Arguments = $"\"{moduleDirectory}\"",
|
||||
UseShellExecute = true
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(
|
||||
$"无法打开模块文件夹:{ex.Message}",
|
||||
"Shigure",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
private static void StyleModuleFooterButton(Button button)
|
||||
{
|
||||
button.AutoSize = false;
|
||||
button.Height = ModuleFooterButtonHeight;
|
||||
button.Margin = new Padding(0);
|
||||
button.Padding = new Padding(10, 0, 10, 0);
|
||||
button.TextAlign = ContentAlignment.MiddleCenter;
|
||||
}
|
||||
|
||||
private static void StyleModuleActionButton(Button button)
|
||||
=> StyleModuleFooterButton(button);
|
||||
|
||||
private void LoadModules()
|
||||
{
|
||||
_moduleStore.Reload();
|
||||
@@ -3358,6 +3394,7 @@ public sealed class ModuleEditorControl : UserControl
|
||||
Text = text,
|
||||
Dock = DockStyle.Fill,
|
||||
ForeColor = UiTheme.Muted,
|
||||
BackColor = Color.Transparent,
|
||||
TextAlign = ContentAlignment.MiddleLeft,
|
||||
AutoEllipsis = true
|
||||
};
|
||||
|
||||
102
UI/StatusForm.cs
102
UI/StatusForm.cs
@@ -651,7 +651,7 @@ public sealed class StatusForm : Form
|
||||
AboutWatermarkOpacity)
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
BackColor = UiTheme.SurfaceRaised,
|
||||
BackColor = UiTheme.Surface,
|
||||
AutoScroll = true,
|
||||
Margin = new Padding(0)
|
||||
};
|
||||
@@ -663,13 +663,25 @@ public sealed class StatusForm : Form
|
||||
AutoSizeMode = AutoSizeMode.GrowAndShrink,
|
||||
BackColor = Color.Transparent,
|
||||
ColumnCount = 1,
|
||||
RowCount = 4,
|
||||
Padding = new Padding(18)
|
||||
RowCount = 3,
|
||||
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));
|
||||
panel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||
|
||||
var infoCard = new UiCardPanel
|
||||
{
|
||||
AutoSize = true,
|
||||
Dock = DockStyle.Top,
|
||||
ColumnCount = 1,
|
||||
RowCount = 2,
|
||||
Padding = new Padding(14),
|
||||
Margin = new Padding(0, 0, 0, 12)
|
||||
};
|
||||
infoCard.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||
infoCard.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||
|
||||
var heading = new TableLayoutPanel
|
||||
{
|
||||
@@ -678,7 +690,7 @@ public sealed class StatusForm : Form
|
||||
BackColor = Color.Transparent,
|
||||
ColumnCount = 1,
|
||||
RowCount = 2,
|
||||
Margin = new Padding(0, 0, 0, 22)
|
||||
Margin = new Padding(0, 0, 0, 16)
|
||||
};
|
||||
heading.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||
heading.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||
@@ -687,6 +699,7 @@ public sealed class StatusForm : Form
|
||||
Text = "Shigure",
|
||||
AutoSize = true,
|
||||
ForeColor = UiTheme.Text,
|
||||
BackColor = Color.Transparent,
|
||||
Font = new Font(Font.FontFamily, 18F, FontStyle.Bold),
|
||||
Margin = new Padding(0, 0, 0, 4)
|
||||
}, 0, 0);
|
||||
@@ -695,10 +708,11 @@ public sealed class StatusForm : Form
|
||||
Text = "应用信息与 ClassBlocks 可用状态字段参考",
|
||||
AutoSize = true,
|
||||
ForeColor = UiTheme.Muted,
|
||||
BackColor = Color.Transparent,
|
||||
Font = new Font(Font.FontFamily, 9.5F, FontStyle.Regular),
|
||||
Margin = new Padding(0)
|
||||
}, 0, 1);
|
||||
panel.Controls.Add(heading, 0, 0);
|
||||
infoCard.Controls.Add(heading, 0, 0);
|
||||
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
var version = AppInfo.Version;
|
||||
@@ -709,13 +723,13 @@ public sealed class StatusForm : Form
|
||||
AutoSize = true,
|
||||
Dock = DockStyle.Top,
|
||||
BackColor = Color.Transparent,
|
||||
ColumnCount = 3,
|
||||
ColumnCount = 2,
|
||||
RowCount = 0,
|
||||
Padding = new Padding(0)
|
||||
Padding = new Padding(0),
|
||||
Margin = new Padding(0)
|
||||
};
|
||||
details.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 120));
|
||||
details.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
|
||||
details.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 72));
|
||||
|
||||
AddAboutRow(details, "产品", "Shigure");
|
||||
AddAboutRow(details, "公司", company);
|
||||
@@ -727,17 +741,18 @@ public sealed class StatusForm : Form
|
||||
var configPath = ConfigService.ResolveConfigPath(AppPaths.BaseDirectory);
|
||||
AddAboutRow(details, "模块目录", FormatAboutPath(modulePath), modulePath);
|
||||
AddAboutRow(details, "配置目录", FormatAboutPath(configPath), configPath);
|
||||
|
||||
panel.Controls.Add(details, 0, 1);
|
||||
infoCard.Controls.Add(details, 0, 1);
|
||||
panel.Controls.Add(infoCard, 0, 0);
|
||||
|
||||
panel.Controls.Add(new Label
|
||||
{
|
||||
Text = "可用状态字段",
|
||||
AutoSize = true,
|
||||
ForeColor = UiTheme.Text,
|
||||
BackColor = Color.Transparent,
|
||||
Font = new Font(Font.FontFamily, 12F, FontStyle.Bold),
|
||||
Margin = new Padding(0, 18, 0, 12)
|
||||
}, 0, 2);
|
||||
Margin = new Padding(2, 6, 0, 12)
|
||||
}, 0, 1);
|
||||
|
||||
var fields = new TableLayoutPanel
|
||||
{
|
||||
@@ -789,7 +804,7 @@ public sealed class StatusForm : Form
|
||||
["类型", "生命值", "距离", "施法", "施法可打断", "引导", "引导可打断"],
|
||||
104), 1, 2);
|
||||
|
||||
panel.Controls.Add(fields, 0, 3);
|
||||
panel.Controls.Add(fields, 0, 2);
|
||||
scrollHost.Controls.Add(panel);
|
||||
return scrollHost;
|
||||
}
|
||||
@@ -799,12 +814,12 @@ public sealed class StatusForm : Form
|
||||
|
||||
private Control CreateAboutFieldCard(string title, IReadOnlyList<string> items, int minimumHeight)
|
||||
{
|
||||
var card = new AboutFieldCardPanel
|
||||
var card = new UiCardPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
ColumnCount = 1,
|
||||
RowCount = 2,
|
||||
Padding = new Padding(16, 14, 16, 14),
|
||||
Padding = new Padding(14),
|
||||
Margin = new Padding(0, 0, 12, 12),
|
||||
MinimumSize = new Size(0, minimumHeight)
|
||||
};
|
||||
@@ -816,6 +831,7 @@ public sealed class StatusForm : Form
|
||||
Text = title,
|
||||
Dock = DockStyle.Fill,
|
||||
ForeColor = UiTheme.Accent,
|
||||
BackColor = Color.Transparent,
|
||||
Font = new Font(Font.FontFamily, 10.5F, FontStyle.Bold),
|
||||
TextAlign = ContentAlignment.MiddleLeft,
|
||||
Margin = new Padding(0)
|
||||
@@ -826,6 +842,7 @@ public sealed class StatusForm : Form
|
||||
Dock = DockStyle.Fill,
|
||||
AutoSize = false,
|
||||
ForeColor = UiTheme.Text,
|
||||
BackColor = Color.Transparent,
|
||||
Font = new Font(Font.FontFamily, 9.5F, FontStyle.Regular),
|
||||
TextAlign = ContentAlignment.TopLeft,
|
||||
Margin = new Padding(0, 6, 0, 0)
|
||||
@@ -853,7 +870,7 @@ public sealed class StatusForm : Form
|
||||
}
|
||||
}
|
||||
|
||||
private void AddAboutRow(TableLayoutPanel panel, string name, string value, string? copyValue = null)
|
||||
private void AddAboutRow(TableLayoutPanel panel, string name, string value, string? tooltip = null)
|
||||
{
|
||||
var row = panel.RowCount++;
|
||||
panel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||
@@ -864,6 +881,7 @@ public sealed class StatusForm : Form
|
||||
Width = 104,
|
||||
Height = 26,
|
||||
ForeColor = UiTheme.Muted,
|
||||
BackColor = Color.Transparent,
|
||||
AutoEllipsis = true,
|
||||
TextAlign = ContentAlignment.MiddleLeft,
|
||||
Margin = new Padding(0, 0, 18, 14)
|
||||
@@ -875,23 +893,12 @@ public sealed class StatusForm : Form
|
||||
AutoSize = false,
|
||||
AutoEllipsis = true,
|
||||
ForeColor = UiTheme.Text,
|
||||
BackColor = Color.Transparent,
|
||||
TextAlign = ContentAlignment.MiddleLeft,
|
||||
Margin = new Padding(0, 0, 12, 14)
|
||||
Margin = new Padding(0, 0, 0, 14)
|
||||
};
|
||||
_toolTip.SetToolTip(valueLabel, copyValue ?? value);
|
||||
_toolTip.SetToolTip(valueLabel, tooltip ?? value);
|
||||
panel.Controls.Add(valueLabel, 1, row);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(copyValue))
|
||||
{
|
||||
var copyButton = UiTheme.CreateButton("复制", UiTheme.ButtonKind.Secondary);
|
||||
copyButton.AutoSize = false;
|
||||
copyButton.Dock = DockStyle.Top;
|
||||
copyButton.Height = 28;
|
||||
copyButton.Margin = new Padding(0, 0, 0, 10);
|
||||
copyButton.Padding = new Padding(4, 0, 4, 0);
|
||||
copyButton.Click += (_, _) => Clipboard.SetText(copyValue);
|
||||
panel.Controls.Add(copyButton, 2, row);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class WatermarkPanel : Panel
|
||||
@@ -966,25 +973,6 @@ public sealed class StatusForm : Form
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class AboutFieldCardPanel : TableLayoutPanel
|
||||
{
|
||||
private const int BackgroundOpacity = 166;
|
||||
|
||||
public AboutFieldCardPanel()
|
||||
{
|
||||
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
|
||||
BackColor = Color.Transparent;
|
||||
DoubleBuffered = true;
|
||||
}
|
||||
|
||||
protected override void OnPaintBackground(PaintEventArgs e)
|
||||
{
|
||||
base.OnPaintBackground(e);
|
||||
using var background = new SolidBrush(Color.FromArgb(BackgroundOpacity, UiTheme.Field));
|
||||
e.Graphics.FillRectangle(background, e.ClipRectangle);
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowOrActivate(RenderSnapshot? snapshot)
|
||||
{
|
||||
if (snapshot is not null)
|
||||
@@ -1447,7 +1435,7 @@ public sealed class StatusForm : Form
|
||||
: _hovered
|
||||
? UiTheme.Hover
|
||||
: UiTheme.Background;
|
||||
using (var path = CreateRoundedPath(bounds, Math.Max(6, (int)Math.Round(8 * scale))))
|
||||
using (var path = UiTheme.CreateRoundedRectanglePath(bounds, Math.Max(6, (int)Math.Round(8 * scale))))
|
||||
using (var background = new SolidBrush(backgroundColor))
|
||||
{
|
||||
graphics.FillPath(background, path);
|
||||
@@ -1502,18 +1490,6 @@ public sealed class StatusForm : Form
|
||||
}
|
||||
}
|
||||
|
||||
private static GraphicsPath CreateRoundedPath(Rectangle bounds, int radius)
|
||||
{
|
||||
var diameter = Math.Min(radius * 2, Math.Min(bounds.Width, bounds.Height));
|
||||
var path = new GraphicsPath();
|
||||
path.AddArc(bounds.Left, bounds.Top, diameter, diameter, 180, 90);
|
||||
path.AddArc(bounds.Right - diameter, bounds.Top, diameter, diameter, 270, 90);
|
||||
path.AddArc(bounds.Right - diameter, bounds.Bottom - diameter, diameter, diameter, 0, 90);
|
||||
path.AddArc(bounds.Left, bounds.Bottom - diameter, diameter, diameter, 90, 90);
|
||||
path.CloseFigure();
|
||||
return path;
|
||||
}
|
||||
|
||||
private static void DrawIcon(Graphics graphics, SettingsNavIcon icon, Rectangle bounds, Color color, float scale)
|
||||
{
|
||||
var x = bounds.Left;
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using System.ComponentModel;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace Shigure;
|
||||
|
||||
internal sealed class UiCardPanel : TableLayoutPanel
|
||||
{
|
||||
private const int CornerRadius = 8;
|
||||
private Color _fillColor = UiTheme.SurfaceRaised;
|
||||
private int _cornerRadius = 10;
|
||||
|
||||
public UiCardPanel()
|
||||
{
|
||||
@@ -17,6 +19,41 @@ internal sealed class UiCardPanel : TableLayoutPanel
|
||||
BackColor = Color.Transparent;
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public Color FillColor
|
||||
{
|
||||
get => _fillColor;
|
||||
set
|
||||
{
|
||||
if (_fillColor == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_fillColor = value;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public int CornerRadius
|
||||
{
|
||||
get => _cornerRadius;
|
||||
set
|
||||
{
|
||||
var next = Math.Max(0, value);
|
||||
if (_cornerRadius == next)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_cornerRadius = next;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPaintBackground(PaintEventArgs e)
|
||||
{
|
||||
base.OnPaintBackground(e);
|
||||
@@ -25,8 +62,8 @@ internal sealed class UiCardPanel : TableLayoutPanel
|
||||
return;
|
||||
}
|
||||
|
||||
using var path = CreateRoundedPath(ClientRectangle, UiTheme.Scale(this, CornerRadius));
|
||||
using var fill = new SolidBrush(UiTheme.SurfaceRaised);
|
||||
using var path = UiTheme.CreateRoundedRectanglePath(ClientRectangle, UiTheme.Scale(this, CornerRadius));
|
||||
using var fill = new SolidBrush(FillColor);
|
||||
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
e.Graphics.FillPath(fill, path);
|
||||
}
|
||||
@@ -40,25 +77,9 @@ internal sealed class UiCardPanel : TableLayoutPanel
|
||||
}
|
||||
|
||||
var bounds = Rectangle.Inflate(ClientRectangle, -1, -1);
|
||||
using var path = CreateRoundedPath(bounds, UiTheme.Scale(this, CornerRadius));
|
||||
using var path = UiTheme.CreateRoundedRectanglePath(bounds, UiTheme.Scale(this, CornerRadius));
|
||||
using var outline = new Pen(UiTheme.Border);
|
||||
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
e.Graphics.DrawPath(outline, path);
|
||||
}
|
||||
|
||||
private static GraphicsPath CreateRoundedPath(Rectangle bounds, int radius)
|
||||
{
|
||||
var diameter = Math.Max(2, Math.Min(radius * 2, Math.Min(bounds.Width, bounds.Height)));
|
||||
var arc = new Rectangle(bounds.Location, new Size(diameter, diameter));
|
||||
var path = new GraphicsPath();
|
||||
path.AddArc(arc, 180, 90);
|
||||
arc.X = bounds.Right - diameter;
|
||||
path.AddArc(arc, 270, 90);
|
||||
arc.Y = bounds.Bottom - diameter;
|
||||
path.AddArc(arc, 0, 90);
|
||||
arc.X = bounds.Left;
|
||||
path.AddArc(arc, 90, 90);
|
||||
path.CloseFigure();
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
129
UI/UiPillTab.cs
Normal file
129
UI/UiPillTab.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
using System.ComponentModel;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace Shigure;
|
||||
|
||||
/// <summary>
|
||||
/// 编辑器分区标签:圆角 pill,选中为 AccentSoft 填充。
|
||||
/// </summary>
|
||||
internal sealed class UiPillTab : Control
|
||||
{
|
||||
private bool _selected;
|
||||
private bool _hovered;
|
||||
private bool _pressed;
|
||||
|
||||
public UiPillTab(string text)
|
||||
{
|
||||
SetStyle(
|
||||
ControlStyles.AllPaintingInWmPaint
|
||||
| ControlStyles.OptimizedDoubleBuffer
|
||||
| ControlStyles.ResizeRedraw
|
||||
| ControlStyles.UserPaint
|
||||
| ControlStyles.SupportsTransparentBackColor,
|
||||
true);
|
||||
Text = text;
|
||||
Dock = DockStyle.Fill;
|
||||
Cursor = Cursors.Hand;
|
||||
BackColor = Color.Transparent;
|
||||
ForeColor = UiTheme.Muted;
|
||||
Margin = new Padding(3, 2, 3, 2);
|
||||
TabStop = false;
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public bool Selected
|
||||
{
|
||||
get => _selected;
|
||||
set
|
||||
{
|
||||
if (_selected == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_selected = value;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnMouseEnter(EventArgs e)
|
||||
{
|
||||
base.OnMouseEnter(e);
|
||||
_hovered = true;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override void OnMouseLeave(EventArgs e)
|
||||
{
|
||||
base.OnMouseLeave(e);
|
||||
_hovered = false;
|
||||
_pressed = false;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseDown(e);
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
_pressed = true;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseUp(e);
|
||||
if (_pressed)
|
||||
{
|
||||
_pressed = false;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
var graphics = e.Graphics;
|
||||
graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
|
||||
var bounds = new Rectangle(0, 0, Math.Max(1, Width - 1), Math.Max(1, Height - 1));
|
||||
var fill = _selected
|
||||
? UiTheme.AccentSoft
|
||||
: _pressed
|
||||
? UiTheme.Pressed
|
||||
: _hovered
|
||||
? UiTheme.Hover
|
||||
: Color.Transparent;
|
||||
|
||||
if (fill.A > 0)
|
||||
{
|
||||
using var path = UiTheme.CreateRoundedRectanglePath(bounds, UiTheme.Scale(this, 8));
|
||||
using var brush = new SolidBrush(fill);
|
||||
graphics.FillPath(brush, path);
|
||||
if (_selected)
|
||||
{
|
||||
using var border = new Pen(Color.FromArgb(90, UiTheme.Accent));
|
||||
graphics.DrawPath(border, path);
|
||||
}
|
||||
}
|
||||
|
||||
var textColor = _selected || _hovered ? UiTheme.Text : UiTheme.Muted;
|
||||
if (_selected)
|
||||
{
|
||||
textColor = UiTheme.Accent;
|
||||
}
|
||||
|
||||
TextRenderer.DrawText(
|
||||
graphics,
|
||||
Text,
|
||||
Font,
|
||||
ClientRectangle,
|
||||
textColor,
|
||||
TextFormatFlags.HorizontalCenter
|
||||
| TextFormatFlags.VerticalCenter
|
||||
| TextFormatFlags.SingleLine
|
||||
| TextFormatFlags.EndEllipsis
|
||||
| TextFormatFlags.NoPrefix);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -223,6 +224,7 @@ 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);
|
||||
return button;
|
||||
}
|
||||
|
||||
@@ -241,6 +243,71 @@ internal static class UiTheme
|
||||
public static int Scale(Control control, int logicalPixels)
|
||||
=> Math.Max(1, (int)Math.Round(logicalPixels * control.DeviceDpi / 96F));
|
||||
|
||||
public static GraphicsPath CreateRoundedRectanglePath(Rectangle bounds, int radius)
|
||||
{
|
||||
var path = new GraphicsPath();
|
||||
if (bounds.Width <= 0 || bounds.Height <= 0)
|
||||
{
|
||||
path.AddRectangle(bounds);
|
||||
return path;
|
||||
}
|
||||
|
||||
var diameter = Math.Max(2, Math.Min(radius * 2, Math.Min(bounds.Width, bounds.Height)));
|
||||
var arc = new Rectangle(bounds.Location, new Size(diameter, diameter));
|
||||
path.AddArc(arc, 180, 90);
|
||||
arc.X = bounds.Right - diameter;
|
||||
path.AddArc(arc, 270, 90);
|
||||
arc.Y = bounds.Bottom - diameter;
|
||||
path.AddArc(arc, 0, 90);
|
||||
arc.X = bounds.Left;
|
||||
path.AddArc(arc, 90, 90);
|
||||
path.CloseFigure();
|
||||
return path;
|
||||
}
|
||||
|
||||
public static void ApplyControlRoundedRegion(Control control, int logicalRadius = 8)
|
||||
{
|
||||
void UpdateRegion()
|
||||
{
|
||||
if (control.Width <= 0 || control.Height <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var diameter = Math.Min(
|
||||
Scale(control, logicalRadius) * 2,
|
||||
Math.Min(control.Width, control.Height));
|
||||
var regionHandle = CreateRoundRectRgn(0, 0, control.Width + 1, control.Height + 1, diameter, diameter);
|
||||
if (regionHandle == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var previous = control.Region;
|
||||
control.Region = Region.FromHrgn(regionHandle);
|
||||
previous?.Dispose();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_ = DeleteObject(regionHandle);
|
||||
}
|
||||
}
|
||||
|
||||
control.Resize -= OnRoundedRegionResize;
|
||||
control.Resize += OnRoundedRegionResize;
|
||||
control.HandleCreated -= OnRoundedRegionHandleCreated;
|
||||
control.HandleCreated += OnRoundedRegionHandleCreated;
|
||||
if (control.IsHandleCreated)
|
||||
{
|
||||
UpdateRegion();
|
||||
}
|
||||
|
||||
void OnRoundedRegionResize(object? sender, EventArgs e) => UpdateRegion();
|
||||
void OnRoundedRegionHandleCreated(object? sender, EventArgs e) => UpdateRegion();
|
||||
}
|
||||
|
||||
public static void StyleTextBox(TextBox textBox)
|
||||
{
|
||||
textBox.BackColor = Field;
|
||||
|
||||
Reference in New Issue
Block a user