Add search box to flag/work row search

This commit is contained in:
Kurt 2026-03-01 19:59:57 -06:00
parent b6eb0745a3
commit 553f154657
4 changed files with 380 additions and 43 deletions

View File

@ -87,10 +87,9 @@ private void LoadFlags(EventLabelCollectionSystem editor)
};
var panel = CreateBoolPanel($"TLP_F{group.Key}");
tab.Controls.Add(panel);
var rows = new List<(string Search, CheckBox Check, Label Label)>();
TC_Flags.TabPages.Add(tab);
int i = 0;
foreach (var (name, index, _) in group)
{
var lbl = new Label { Text = name, Margin = Padding.Empty, AutoSize = true };
@ -108,12 +107,14 @@ private void LoadFlags(EventLabelCollectionSystem editor)
if (NUD_Flag.Value == index)
CHK_CustomFlag.Checked = chk.Checked;
};
panel.Controls.Add(chk, 0, i);
panel.Controls.Add(lbl, 1, i);
rows.Add((name, chk, lbl));
FlagDict.Add(index, chk);
i++;
}
ApplyBoolFilter(panel, rows, string.Empty);
var search = CreateSearchBox(text => ApplyBoolFilter(panel, rows, text));
var host = CreateSearchHost(search, panel);
tab.Controls.Add(host);
}
}
@ -131,10 +132,9 @@ private void LoadSystem(EventLabelCollectionSystem editor)
};
var panel = CreateBoolPanel($"TLP_S{group.Key}");
tab.Controls.Add(panel);
var rows = new List<(string Search, CheckBox Check, Label Label)>();
TC_System.TabPages.Add(tab);
int i = 0;
foreach (var (name, index, _) in group)
{
var lbl = new Label { Text = name, Margin = Padding.Empty, AutoSize = true };
@ -152,12 +152,14 @@ private void LoadSystem(EventLabelCollectionSystem editor)
if (NUD_System.Value == index)
CHK_CustomSystem.Checked = chk.Checked;
};
panel.Controls.Add(chk, 0, i);
panel.Controls.Add(lbl, 1, i);
rows.Add((name, chk, lbl));
SystemDict.Add(index, chk);
i++;
}
ApplyBoolFilter(panel, rows, string.Empty);
var search = CreateSearchBox(text => ApplyBoolFilter(panel, rows, text));
var host = CreateSearchHost(search, panel);
tab.Controls.Add(host);
}
}
@ -175,10 +177,9 @@ private void LoadWork(EventLabelCollectionSystem editor)
};
var panel = CreateWorkPanel($"TLP_W{group.Key}");
tab.Controls.Add(panel);
var rows = new List<(string Search, Label Label, ComboBox Combo, NumericUpDown Numeric)>();
TC_Work.TabPages.Add(tab);
int i = 0;
foreach (var entry in group)
{
var lbl = new Label { Text = entry.Name, Margin = Padding.Empty, AutoSize = true };
@ -235,16 +236,99 @@ void ChangeConstValue(object? sender, EventArgs e)
if (mtb.Value == 0)
ChangeConstValue(this, EventArgs.Empty);
panel.Controls.Add(lbl, 0, i);
panel.Controls.Add(cb, 1, i);
panel.Controls.Add(mtb, 2, i);
rows.Add((entry.Name, lbl, cb, mtb));
WorkDict.Add(entry.Index, mtb);
i++;
}
ApplyWorkFilter(panel, rows, string.Empty);
var search = CreateSearchBox(text => ApplyWorkFilter(panel, rows, text));
var host = CreateSearchHost(search, panel);
tab.Controls.Add(host);
}
}
private static void ApplyBoolFilter(TableLayoutPanel panel, IReadOnlyList<(string Search, CheckBox Check, Label Label)> rows, string text)
{
var query = text.Trim();
var hasQuery = query.Length != 0;
panel.SuspendLayout();
panel.Controls.Clear();
var rowIndex = 0;
for (var i = 0; i < rows.Count; i++)
{
var row = rows[i];
if (hasQuery && !row.Search.Contains(query, StringComparison.CurrentCultureIgnoreCase))
continue;
panel.Controls.Add(row.Check, 0, rowIndex);
panel.Controls.Add(row.Label, 1, rowIndex);
rowIndex++;
}
panel.ResumeLayout();
}
private static void ApplyWorkFilter(TableLayoutPanel panel, IReadOnlyList<(string Search, Label Label, ComboBox Combo, NumericUpDown Numeric)> rows, string text)
{
var query = text.Trim();
var hasQuery = query.Length != 0;
panel.SuspendLayout();
panel.Controls.Clear();
var rowIndex = 0;
for (var i = 0; i < rows.Count; i++)
{
var row = rows[i];
if (hasQuery && !row.Search.Contains(query, StringComparison.CurrentCultureIgnoreCase))
continue;
panel.Controls.Add(row.Label, 0, rowIndex);
panel.Controls.Add(row.Combo, 1, rowIndex);
panel.Controls.Add(row.Numeric, 2, rowIndex);
rowIndex++;
}
panel.ResumeLayout();
}
private TextBox CreateSearchBox(Action<string> applyFilter)
{
var box = new TextBox
{
PlaceholderText = "Search...",
Dock = DockStyle.Top,
Margin = Padding.Empty,
};
if (Application.IsDarkModeEnabled)
WinFormsTranslator.ReformatDark(box);
var timer = new Timer { Interval = 150 };
timer.Tick += (_, _) =>
{
timer.Stop();
applyFilter(box.Text);
};
box.TextChanged += (_, _) =>
{
timer.Stop();
timer.Start();
};
box.Disposed += (_, _) => timer.Dispose();
return box;
}
private static Panel CreateSearchHost(TextBox search, Control content)
{
var host = new Panel
{
Dock = DockStyle.Fill,
Margin = Padding.Empty,
};
content.Dock = DockStyle.Fill;
host.Controls.Add(content);
host.Controls.Add(search);
return host;
}
private static TableLayoutPanel CreateBoolPanel(string name)
{
var panel = new TableLayoutPanel

View File

@ -97,10 +97,12 @@ private void AddFlagList(EventLabelCollection list, bool[] values)
Name = $"Tab_F{group.Key}",
Text = WinFormsTranslator.TranslateEnum(group.Key, Main.CurrentLanguage),
};
TC_Flags.TabPages.Add(tab);
var grid = CreateFlagGrid();
tab.Controls.Add(grid);
var search = CreateSearchBox(text => ApplyGridFilter(grid, text));
var host = CreateSearchHost(search, grid);
tab.Controls.Add(host);
TC_Flags.TabPages.Add(tab);
var cFlag = new DataGridViewCheckBoxColumn
{
@ -137,6 +139,8 @@ private void AddFlagList(EventLabelCollection list, bool[] values)
cells[1].Value = name;
}
ApplyGridFilter(grid, string.Empty);
grid.CellValueChanged += (_, e) =>
{
if (e.ColumnIndex != 0 || e.RowIndex == -1)
@ -172,6 +176,25 @@ private void AddFlagList(EventLabelCollection list, bool[] values)
}
}
private static void ApplyGridFilter(DataGridView grid, string text)
{
var query = text.Trim();
var hasQuery = query.Length != 0;
foreach (DataGridViewRow row in grid.Rows)
{
if (row.Cells.Count < 2)
continue;
if (!hasQuery)
{
row.Visible = true;
continue;
}
var value = row.Cells[1].Value?.ToString() ?? string.Empty;
row.Visible = value.Contains(query, StringComparison.CurrentCultureIgnoreCase);
}
}
private static DoubleBufferedDataGridView CreateFlagGrid() => new()
{
AllowUserToAddRows = false,
@ -214,10 +237,10 @@ private void AddConstList(EventLabelCollection list, ushort[] values)
};
var panel = CreateConstPanel();
tab.Controls.Add(panel);
TC_Const.TabPages.Add(tab);
var grouped = group.ToList();
var rows = new List<(string Search, Label Label, ComboBox Combo, NumericUpDown Numeric)>(grouped.Count);
for (var i = 0; i < grouped.Count; i++)
{
var entry = grouped[i];
@ -276,15 +299,78 @@ void ChangeConstValue(object? sender, EventArgs e)
if (mtb.Value == 0)
ChangeConstValue(this, EventArgs.Empty);
panel.Controls.Add(lbl, 0, i);
panel.Controls.Add(cb, 1, i);
panel.Controls.Add(mtb, 2, i);
rows.Add((entry.Name, lbl, cb, mtb));
WorkDict.Add(entry.Index, mtb);
}
ApplyConstFilter(panel, rows, string.Empty);
var search = CreateSearchBox(text => ApplyConstFilter(panel, rows, text));
var host = CreateSearchHost(search, panel);
tab.Controls.Add(host);
}
}
private static void ApplyConstFilter(TableLayoutPanel panel, IReadOnlyList<(string Search, Label Label, ComboBox Combo, NumericUpDown Numeric)> rows, string text)
{
var query = text.Trim();
var hasQuery = query.Length != 0;
panel.SuspendLayout();
panel.Controls.Clear();
var rowIndex = 0;
for (var i = 0; i < rows.Count; i++)
{
var row = rows[i];
if (hasQuery && !row.Search.Contains(query, StringComparison.CurrentCultureIgnoreCase))
continue;
panel.Controls.Add(row.Label, 0, rowIndex);
panel.Controls.Add(row.Combo, 1, rowIndex);
panel.Controls.Add(row.Numeric, 2, rowIndex);
rowIndex++;
}
panel.ResumeLayout();
}
private TextBox CreateSearchBox(Action<string> applyFilter)
{
var box = new TextBox
{
PlaceholderText = "Search...",
Dock = DockStyle.Top,
Margin = Padding.Empty,
};
if (Application.IsDarkModeEnabled)
WinFormsTranslator.ReformatDark(box);
var timer = new Timer { Interval = 150 };
timer.Tick += (_, _) =>
{
timer.Stop();
applyFilter(box.Text);
};
box.TextChanged += (_, _) =>
{
timer.Stop();
timer.Start();
};
box.Disposed += (_, _) => timer.Dispose();
return box;
}
private static Panel CreateSearchHost(TextBox search, Control content)
{
var host = new Panel
{
Dock = DockStyle.Fill,
Margin = Padding.Empty,
};
content.Dock = DockStyle.Fill;
host.Controls.Add(content);
host.Controls.Add(search);
return host;
}
private static TableLayoutPanel CreateConstPanel()
{
var panel = new TableLayoutPanel

View File

@ -104,7 +104,9 @@ private void AddFlagList(EventLabelCollection list, bool[] values)
};
var grid = CreateFlagGrid();
tab.Controls.Add(grid);
var search = CreateSearchBox(text => ApplyGridFilter(grid, text));
var host = CreateSearchHost(search, grid);
tab.Controls.Add(host);
TC_Flags.TabPages.Add(tab);
var cFlag = new DataGridViewCheckBoxColumn
@ -177,6 +179,25 @@ private void AddFlagList(EventLabelCollection list, bool[] values)
}
}
private static void ApplyGridFilter(DataGridView grid, string text)
{
var query = text.Trim();
var hasQuery = query.Length != 0;
foreach (DataGridViewRow row in grid.Rows)
{
if (row.Cells.Count < 2)
continue;
if (!hasQuery)
{
row.Visible = true;
continue;
}
var value = row.Cells[1].Value?.ToString() ?? string.Empty;
row.Visible = value.Contains(query, StringComparison.CurrentCultureIgnoreCase);
}
}
private static DoubleBufferedDataGridView CreateFlagGrid() => new()
{
AllowUserToAddRows = false,
@ -219,10 +240,10 @@ private void AddConstList(EventLabelCollection list, ReadOnlySpan<byte> values)
};
var panel = CreateConstPanel();
tab.Controls.Add(panel);
TC_Const.TabPages.Add(tab);
var grouped = group.ToList();
var rows = new List<(string Search, Label Label, ComboBox Combo, NumericUpDown Numeric)>(grouped.Count);
for (var i = 0; i < grouped.Count; i++)
{
var entry = grouped[i];
@ -280,15 +301,78 @@ void ChangeConstValue(object? sender, EventArgs e)
if (mtb.Value == 0)
ChangeConstValue(this, EventArgs.Empty);
panel.Controls.Add(lbl, 0, i);
panel.Controls.Add(cb, 1, i);
panel.Controls.Add(mtb, 2, i);
rows.Add((entry.Name, lbl, cb, mtb));
WorkDict.Add(entry.Index, mtb);
}
ApplyConstFilter(panel, rows, string.Empty);
var search = CreateSearchBox(text => ApplyConstFilter(panel, rows, text));
var host = CreateSearchHost(search, panel);
tab.Controls.Add(host);
}
}
private static void ApplyConstFilter(TableLayoutPanel panel, IReadOnlyList<(string Search, Label Label, ComboBox Combo, NumericUpDown Numeric)> rows, string text)
{
var query = text.Trim();
var hasQuery = query.Length != 0;
panel.SuspendLayout();
panel.Controls.Clear();
var rowIndex = 0;
for (var i = 0; i < rows.Count; i++)
{
var row = rows[i];
if (hasQuery && !row.Search.Contains(query, StringComparison.CurrentCultureIgnoreCase))
continue;
panel.Controls.Add(row.Label, 0, rowIndex);
panel.Controls.Add(row.Combo, 1, rowIndex);
panel.Controls.Add(row.Numeric, 2, rowIndex);
rowIndex++;
}
panel.ResumeLayout();
}
private TextBox CreateSearchBox(Action<string> applyFilter)
{
var box = new TextBox
{
PlaceholderText = "Search...",
Dock = DockStyle.Top,
Margin = Padding.Empty,
};
if (Application.IsDarkModeEnabled)
WinFormsTranslator.ReformatDark(box);
var timer = new Timer { Interval = 150 };
timer.Tick += (_, _) =>
{
timer.Stop();
applyFilter(box.Text);
};
box.TextChanged += (_, _) =>
{
timer.Stop();
timer.Start();
};
box.Disposed += (_, _) => timer.Dispose();
return box;
}
private static Panel CreateSearchHost(TextBox search, Control content)
{
var host = new Panel
{
Dock = DockStyle.Fill,
Margin = Padding.Empty,
};
content.Dock = DockStyle.Fill;
host.Controls.Add(content);
host.Controls.Add(search);
return host;
}
private static TableLayoutPanel CreateConstPanel()
{
var panel = new TableLayoutPanel

View File

@ -78,7 +78,7 @@ private void LoadFlags(IEnumerable<EventVarGroup> editorFlag)
{
var tlp = new TableLayoutPanel { Dock = DockStyle.Fill, Name = $"TLP_F{g.Type}", AutoScroll = true };
tlp.SuspendLayout();
int i = 0;
var rows = new List<(string Search, CheckBox Check, Label Label)>();
foreach (var f in g.Vars.OfType<EventFlag>())
{
var lbl = new Label
@ -98,16 +98,17 @@ private void LoadFlags(IEnumerable<EventVarGroup> editorFlag)
};
lbl.Click += (_, _) => chk.Checked ^= true;
chk.CheckedChanged += (_, _) => f.Flag = chk.Checked;
tlp.Controls.Add(chk, 0, i);
tlp.Controls.Add(lbl, 1, i);
i++;
rows.Add((f.Name, chk, lbl));
}
ApplyBoolFilter(tlp, rows, string.Empty);
var tab = new TabPage
{
Name = $"Tab_F{g.Type}",
Text = WinFormsTranslator.TranslateEnum(g.Type, Main.CurrentLanguage),
};
tab.Controls.Add(tlp);
var search = CreateSearchBox(text => ApplyBoolFilter(tlp, rows, text));
var host = CreateSearchHost(search, tlp);
tab.Controls.Add(host);
TC_Flag.Controls.Add(tab);
tlp.ResumeLayout();
}
@ -119,7 +120,7 @@ private void LoadWork(IEnumerable<EventVarGroup> editorWork)
{
var tlp = new TableLayoutPanel { Dock = DockStyle.Fill, Name = $"TLP_W{g.Type}", AutoScroll = true };
tlp.SuspendLayout();
int i = 0;
var rows = new List<(string Search, Label Label, ComboBox Combo, NumericUpDown Numeric)>();
foreach (var f in g.Vars.OfType<EventWork<int>>())
{
var lbl = new Label
@ -182,9 +183,6 @@ private void LoadWork(IEnumerable<EventVarGroup> editorWork)
NUD_Stat.Text = value.ToString();
editing = false;
};
tlp.Controls.Add(lbl, 0, i);
tlp.Controls.Add(cb, 1, i);
tlp.Controls.Add(nud, 2, i);
{
var match = f.Options.FirstOrDefault(z => z.Value == f.Value);
if (match is not null)
@ -193,19 +191,104 @@ private void LoadWork(IEnumerable<EventVarGroup> editorWork)
nud.Enabled = false;
}
}
i++;
rows.Add((f.Name, lbl, cb, nud));
}
ApplyWorkFilter(tlp, rows, string.Empty);
var tab = new TabPage
{
Name = $"Tab_W{g.Type}",
Text = WinFormsTranslator.TranslateEnum(g.Type, Main.CurrentLanguage),
};
tab.Controls.Add(tlp);
var search = CreateSearchBox(text => ApplyWorkFilter(tlp, rows, text));
var host = CreateSearchHost(search, tlp);
tab.Controls.Add(host);
TC_Work.Controls.Add(tab);
tlp.ResumeLayout();
}
}
private static void ApplyBoolFilter(TableLayoutPanel panel, IReadOnlyList<(string Search, CheckBox Check, Label Label)> rows, string text)
{
var query = text.Trim();
var hasQuery = query.Length != 0;
panel.SuspendLayout();
panel.Controls.Clear();
var rowIndex = 0;
for (var i = 0; i < rows.Count; i++)
{
var row = rows[i];
if (hasQuery && !row.Search.Contains(query, StringComparison.CurrentCultureIgnoreCase))
continue;
panel.Controls.Add(row.Check, 0, rowIndex);
panel.Controls.Add(row.Label, 1, rowIndex);
rowIndex++;
}
panel.ResumeLayout();
}
private static void ApplyWorkFilter(TableLayoutPanel panel, IReadOnlyList<(string Search, Label Label, ComboBox Combo, NumericUpDown Numeric)> rows, string text)
{
var query = text.Trim();
var hasQuery = query.Length != 0;
panel.SuspendLayout();
panel.Controls.Clear();
var rowIndex = 0;
for (var i = 0; i < rows.Count; i++)
{
var row = rows[i];
if (hasQuery && !row.Search.Contains(query, StringComparison.CurrentCultureIgnoreCase))
continue;
panel.Controls.Add(row.Label, 0, rowIndex);
panel.Controls.Add(row.Combo, 1, rowIndex);
panel.Controls.Add(row.Numeric, 2, rowIndex);
rowIndex++;
}
panel.ResumeLayout();
}
private TextBox CreateSearchBox(Action<string> applyFilter)
{
var box = new TextBox
{
PlaceholderText = "Search...",
Dock = DockStyle.Top,
Margin = Padding.Empty,
};
if (Application.IsDarkModeEnabled)
WinFormsTranslator.ReformatDark(box);
var timer = new Timer { Interval = 150 };
timer.Tick += (_, _) =>
{
timer.Stop();
applyFilter(box.Text);
};
box.TextChanged += (_, _) =>
{
timer.Stop();
timer.Start();
};
box.Disposed += (_, _) => timer.Dispose();
return box;
}
private static Panel CreateSearchHost(TextBox search, Control content)
{
var host = new Panel
{
Dock = DockStyle.Fill,
Margin = Padding.Empty,
};
content.Dock = DockStyle.Fill;
host.Controls.Add(content);
host.Controls.Add(search);
return host;
}
private const string flagTag = "bool_";
private const string constTag = "const_";
private const string constCBTag = "cbconst_";