From 89b9549c12a6726887b377a31361988a6f56c590 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 26 Jan 2026 19:24:58 +0000 Subject: [PATCH 1/5] Initial plan From abfe28ad49b2b4d5f79acdb3073baac466a7a8cb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 26 Jan 2026 19:33:05 +0000 Subject: [PATCH 2/5] Add category attributes to TombEngine Moveables.xml Added category attributes to all 941 moveables in the TombEngine catalog with appropriate categorization: - PLAYER (13): Lara and her components - VEHICLE (13): Vehicles and their animations - ENEMY (111): Hostile enemies and dangerous creatures - CREATURE (13): Non-hostile animals - BOSS (20): Boss enemies - NPC (9): Non-player characters - PROJECTILE (13): Projectiles and weapons - TRAP (67): Traps and obstacles - PICKUP (86): Pickupable items (weapons, ammo, health) - EMITTER (7): Particle emitters - PUZZLE (188): Puzzle items, keys, and related objects - DOOR (51): All door types - SWITCH (36): Switches and levers - DECORATION (208): Decorative and visual objects - MECHANISM (62): Mechanisms and machinery AI objects and internal markers intentionally left without categories. Co-authored-by: TrainWrack <120750885+TrainWrack@users.noreply.github.com> --- .../Catalogs/Engines/TombEngine/Moveables.xml | 1882 ++++++++--------- TombLib/TombLib/Wad/Catalog/TrCatalog.cs | 48 +- 2 files changed, 987 insertions(+), 943 deletions(-) diff --git a/TombLib/TombLib/Catalogs/Engines/TombEngine/Moveables.xml b/TombLib/TombLib/Catalogs/Engines/TombEngine/Moveables.xml index bbf2c6c7d..f5e604bfb 100644 --- a/TombLib/TombLib/Catalogs/Engines/TombEngine/Moveables.xml +++ b/TombLib/TombLib/Catalogs/Engines/TombEngine/Moveables.xml @@ -1,753 +1,753 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -756,204 +756,204 @@ - + - - - + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + \ No newline at end of file diff --git a/TombLib/TombLib/Wad/Catalog/TrCatalog.cs b/TombLib/TombLib/Wad/Catalog/TrCatalog.cs index 09d3e727e..9168dc04a 100644 --- a/TombLib/TombLib/Wad/Catalog/TrCatalog.cs +++ b/TombLib/TombLib/Wad/Catalog/TrCatalog.cs @@ -50,6 +50,7 @@ private struct Item public bool FreeRotation { get; set; } public bool IsHidden { get; set; } public bool IsEssential { get; set; } + public string Category { get; set; } } private struct ItemSound @@ -125,6 +126,7 @@ public static int PredictSoundMapSize(TRVersion.Game version, bool IsNg, int num public static bool IsHidden(TRVersion.Game version, uint id) => GetMoveable(version, id)?.IsHidden ?? false; public static bool IsEssential(TRVersion.Game version, uint id) => GetMoveable(version, id)?.IsEssential ?? false; public static bool IsFreelyRotateable(TRVersion.Game version, uint id) => GetMoveable(version, id)?.FreeRotation ?? false; + public static string GetMoveableCategory(TRVersion.Game version, uint id) => GetMoveable(version, id)?.Category ?? string.Empty; public static string GetSpriteSequenceTombEngineSlot(TRVersion.Game version, uint id) { @@ -192,6 +194,19 @@ public static bool IsStaticShatterable(TRVersion.Game version, uint id) return entry.Shatterable; } + public static string GetStaticCategory(TRVersion.Game version, uint id) + { + Game game; + if (!Games.TryGetValue(version.Native(), out game)) + return string.Empty; + + Item entry; + if (!game.Statics.TryGetValue(id, out entry)) + return string.Empty; + + return entry.Category ?? string.Empty; + } + public static uint? GetItemIndex(TRVersion.Game version, string name, out bool isMoveable) { Game game; @@ -416,6 +431,32 @@ public static IDictionary GetAllStatics(TRVersion.Game version) return Games[version.Native()].Statics.DicSelect(item => item.Value.Names.LastOrDefault()); } + public static IEnumerable GetAllMoveableCategories(TRVersion.Game version) + { + Game game; + if (!Games.TryGetValue(version.Native(), out game)) + return Enumerable.Empty(); + + return game.Moveables.Values + .Select(item => item.Category) + .Where(category => !string.IsNullOrEmpty(category)) + .Distinct() + .OrderBy(category => category); + } + + public static IEnumerable GetAllStaticCategories(TRVersion.Game version) + { + Game game; + if (!Games.TryGetValue(version.Native(), out game)) + return Enumerable.Empty(); + + return game.Statics.Values + .Select(item => item.Category) + .Where(category => !string.IsNullOrEmpty(category)) + .Distinct() + .OrderBy(category => category); + } + public static IDictionary GetAllSpriteSequences(TRVersion.Game version) { return Games[version.Native()].SpriteSequences.DicSelect(item => item.Value.Names.LastOrDefault()); @@ -539,6 +580,7 @@ public static void LoadCatalog(string rootFolder) bool hidden = bool.Parse(moveableNode.Attributes["hidden"]?.Value ?? "false"); bool essential = bool.Parse(moveableNode.Attributes["essential"]?.Value ?? "true"); string tombEngineSlot = moveableNode.Attributes["ten"]?.Value ?? string.Empty; + string category = moveableNode.Attributes["category"]?.Value ?? string.Empty; game.Moveables.Add(id, new Item { @@ -549,7 +591,8 @@ public static void LoadCatalog(string rootFolder) TombEngineSlot = tombEngineSlot, FreeRotation = isFreeRotation, IsHidden = hidden, - IsEssential = essential + IsEssential = essential, + Category = category }); } } @@ -566,7 +609,8 @@ public static void LoadCatalog(string rootFolder) uint id = uint.Parse(staticNode.Attributes["id"].Value); string[] names = (staticNode.Attributes["name"]?.Value ?? "").Split('|'); bool shatter = bool.Parse(staticNode.Attributes["shatter"]?.Value ?? "false"); - game.Statics.Add(id, new Item { Names = new List(names), Shatterable = shatter }); + string category = staticNode.Attributes["category"]?.Value ?? string.Empty; + game.Statics.Add(id, new Item { Names = new List(names), Shatterable = shatter, Category = category }); } } From b3807d1f9aedc1a24fee7d5ff424e3314b3cf749 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 26 Jan 2026 19:37:35 +0000 Subject: [PATCH 3/5] Add category attributes to TR4 XML files - Added category attributes to all 520 moveables in TR4/Moveables.xml - Added category attributes to all 160 statics in TR4/Statics.xml - Used TombEngine categorization logic for consistency - Categories: PLAYER, VEHICLE, ENEMY, CREATURE, BOSS, NPC, PROJECTILE, TRAP, PICKUP, EMITTER, PUZZLE, DOOR, SWITCH, DECORATION, MECHANISM, ARCHITECTURE, SHATTER --- .../Catalogs/Engines/TR4/Moveables.xml | 1040 ++++++++--------- .../TombLib/Catalogs/Engines/TR4/Statics.xml | 320 ++--- 2 files changed, 680 insertions(+), 680 deletions(-) diff --git a/TombLib/TombLib/Catalogs/Engines/TR4/Moveables.xml b/TombLib/TombLib/Catalogs/Engines/TR4/Moveables.xml index 732172546..c05fb04c0 100644 --- a/TombLib/TombLib/Catalogs/Engines/TR4/Moveables.xml +++ b/TombLib/TombLib/Catalogs/Engines/TR4/Moveables.xml @@ -1,523 +1,523 @@ - - \ No newline at end of file diff --git a/TombLib/TombLib/Catalogs/Engines/TR4/Statics.xml b/TombLib/TombLib/Catalogs/Engines/TR4/Statics.xml index 907cbdfcd..6e1aff8d6 100644 --- a/TombLib/TombLib/Catalogs/Engines/TR4/Statics.xml +++ b/TombLib/TombLib/Catalogs/Engines/TR4/Statics.xml @@ -1,163 +1,163 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 5162f8c016068dc307d69888e5a293aedf765b74 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 26 Jan 2026 19:40:31 +0000 Subject: [PATCH 4/5] Add filter button to ItemBrowser with dynamic category filtering Co-authored-by: TrainWrack <120750885+TrainWrack@users.noreply.github.com> --- .../ToolWindows/ItemBrowser.Designer.cs | 17 ++- TombEditor/ToolWindows/ItemBrowser.cs | 126 ++++++++++++++++-- 2 files changed, 130 insertions(+), 13 deletions(-) diff --git a/TombEditor/ToolWindows/ItemBrowser.Designer.cs b/TombEditor/ToolWindows/ItemBrowser.Designer.cs index a1e6492f8..68838d5cd 100644 --- a/TombEditor/ToolWindows/ItemBrowser.Designer.cs +++ b/TombEditor/ToolWindows/ItemBrowser.Designer.cs @@ -19,6 +19,7 @@ private void InitializeComponent() this.panelItem = new TombEditor.Controls.PanelRenderingItem(); this.panelHeader = new System.Windows.Forms.Panel(); this.butAddItem = new DarkUI.Controls.DarkButton(); + this.butFilter = new DarkUI.Controls.DarkButton(); this.comboItems = new TombLib.Controls.DarkSearchableComboBox(); this.panelRightBottom = new System.Windows.Forms.Panel(); this.lblFromWad = new DarkUI.Controls.DarkLabel(); @@ -48,6 +49,7 @@ private void InitializeComponent() // panelHeader // this.panelHeader.Controls.Add(this.butAddItem); + this.panelHeader.Controls.Add(this.butFilter); this.panelHeader.Controls.Add(this.comboItems); this.panelHeader.Dock = System.Windows.Forms.DockStyle.Top; this.panelHeader.Location = new System.Drawing.Point(0, 25); @@ -67,13 +69,25 @@ private void InitializeComponent() this.butAddItem.TabIndex = 3; this.butAddItem.Tag = "AddItem"; // + // butFilter + // + this.butFilter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.butFilter.Checked = false; + this.butFilter.Image = global::TombEditor.Properties.Resources.general_filter_16; + this.butFilter.Location = new System.Drawing.Point(231, 2); + this.butFilter.Name = "butFilter"; + this.butFilter.Size = new System.Drawing.Size(24, 23); + this.butFilter.TabIndex = 2; + this.toolTip.SetToolTip(this.butFilter, "Filter items"); + this.butFilter.Click += new System.EventHandler(this.butFilter_Click); + // // comboItems // this.comboItems.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.comboItems.Location = new System.Drawing.Point(3, 2); this.comboItems.Name = "comboItems"; - this.comboItems.Size = new System.Drawing.Size(249, 23); + this.comboItems.Size = new System.Drawing.Size(222, 23); this.comboItems.TabIndex = 1; this.comboItems.Format += new System.Windows.Forms.ListControlConvertEventHandler(this.comboItems_Format); this.comboItems.SelectedIndexChanged += new System.EventHandler(this.comboItems_SelectedIndexChanged); @@ -185,6 +199,7 @@ private void InitializeComponent() private Controls.PanelRenderingItem panelItem; private System.Windows.Forms.Panel panelHeader; private DarkUI.Controls.DarkButton butAddItem; + private DarkUI.Controls.DarkButton butFilter; private TombLib.Controls.DarkSearchableComboBox comboItems; private System.Windows.Forms.Panel panelRightBottom; private System.Windows.Forms.Panel panelRight; diff --git a/TombEditor/ToolWindows/ItemBrowser.cs b/TombEditor/ToolWindows/ItemBrowser.cs index bf45da702..858b0fc21 100644 --- a/TombEditor/ToolWindows/ItemBrowser.cs +++ b/TombEditor/ToolWindows/ItemBrowser.cs @@ -1,5 +1,6 @@ using DarkUI.Docking; using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows.Forms; @@ -13,6 +14,8 @@ namespace TombEditor.ToolWindows public partial class ItemBrowser : DarkToolWindow { private readonly Editor _editor; + private HashSet _selectedCategories = new HashSet(); + private bool _staticsOnlyFilter = false; public ItemBrowser() { @@ -46,18 +49,7 @@ private void EditorEventRaised(IEditorEvent obj) obj is Editor.GameVersionChangedEvent || obj is Editor.ConfigurationChangedEvent) { - var allMoveables = _editor.Level.Settings.WadGetAllMoveables(); - var allStatics = _editor.Level.Settings.WadGetAllStatics(); - - comboItems.GameVersion = _editor.Level.Settings.GameVersion; - comboItems.Items.Clear(); - foreach (var moveable in allMoveables.Values) - if (!_editor.Configuration.RenderingItem_HideInternalObjects || - !TrCatalog.IsHidden(_editor.Level.Settings.GameVersion, moveable.Id.TypeId)) - comboItems.Items.Add(moveable); - - foreach (var staticMesh in allStatics.Values) - comboItems.Items.Add(staticMesh); + PopulateItemsList(); if (comboItems.Items.Count > 0) { @@ -74,6 +66,9 @@ obj is Editor.GameVersionChangedEvent || { comboItems.SelectedIndex = 0; + var allMoveables = _editor.Level.Settings.WadGetAllMoveables(); + var allStatics = _editor.Level.Settings.WadGetAllStatics(); + // Update visible conflicting item, otherwise it's not updated in 3D control. if (comboItems.SelectedItem is WadMoveable) { @@ -229,5 +224,112 @@ private void butItemDown_Click(object sender, EventArgs e) else comboItems.SelectedIndex = 0; } + + private void PopulateItemsList() + { + var allMoveables = _editor.Level.Settings.WadGetAllMoveables(); + var allStatics = _editor.Level.Settings.WadGetAllStatics(); + + comboItems.GameVersion = _editor.Level.Settings.GameVersion; + comboItems.Items.Clear(); + + // Add moveables with filtering + if (!_staticsOnlyFilter) + { + foreach (var moveable in allMoveables.Values) + { + if (!_editor.Configuration.RenderingItem_HideInternalObjects || + !TrCatalog.IsHidden(_editor.Level.Settings.GameVersion, moveable.Id.TypeId)) + { + // Apply category filter if any categories are selected + if (_selectedCategories.Count == 0 || ShouldIncludeMoveable(moveable)) + { + comboItems.Items.Add(moveable); + } + } + } + } + + // Add statics with filtering + foreach (var staticMesh in allStatics.Values) + { + // Apply category filter if any categories are selected + if (_selectedCategories.Count == 0 || ShouldIncludeStatic(staticMesh)) + { + comboItems.Items.Add(staticMesh); + } + } + } + + private bool ShouldIncludeMoveable(WadMoveable moveable) + { + var category = TrCatalog.GetMoveableCategory(_editor.Level.Settings.GameVersion, moveable.Id.TypeId); + return !string.IsNullOrEmpty(category) && _selectedCategories.Contains(category); + } + + private bool ShouldIncludeStatic(WadStatic staticMesh) + { + var category = TrCatalog.GetStaticCategory(_editor.Level.Settings.GameVersion, staticMesh.Id.TypeId); + return !string.IsNullOrEmpty(category) && _selectedCategories.Contains(category); + } + + private void butFilter_Click(object sender, EventArgs e) + { + // Get all available categories from the current game version + var moveableCategories = TrCatalog.GetAllMoveableCategories(_editor.Level.Settings.GameVersion).ToList(); + var staticCategories = TrCatalog.GetAllStaticCategories(_editor.Level.Settings.GameVersion).ToList(); + var allCategories = moveableCategories.Union(staticCategories).Distinct().OrderBy(c => c).ToList(); + + // Create context menu + var contextMenu = new DarkUI.Controls.DarkContextMenu(); + + // Add "Clear Filter" option + var clearItem = new System.Windows.Forms.ToolStripMenuItem("Clear Filter"); + clearItem.Checked = _selectedCategories.Count == 0 && !_staticsOnlyFilter; + clearItem.Click += (s, ev) => + { + _selectedCategories.Clear(); + _staticsOnlyFilter = false; + PopulateItemsList(); + }; + contextMenu.Items.Add(clearItem); + + // Add "Statics Only" option + var staticsOnlyItem = new System.Windows.Forms.ToolStripMenuItem("Statics Only"); + staticsOnlyItem.Checked = _staticsOnlyFilter; + staticsOnlyItem.Click += (s, ev) => + { + _staticsOnlyFilter = !_staticsOnlyFilter; + if (_staticsOnlyFilter) + _selectedCategories.Clear(); // Clear category filters when enabling statics only + PopulateItemsList(); + }; + contextMenu.Items.Add(staticsOnlyItem); + + // Add separator + contextMenu.Items.Add(new System.Windows.Forms.ToolStripSeparator()); + + // Add category items + foreach (var category in allCategories) + { + var categoryItem = new System.Windows.Forms.ToolStripMenuItem(category); + categoryItem.Checked = _selectedCategories.Contains(category); + categoryItem.Click += (s, ev) => + { + if (_selectedCategories.Contains(category)) + _selectedCategories.Remove(category); + else + { + _selectedCategories.Add(category); + _staticsOnlyFilter = false; // Disable statics only when selecting categories + } + PopulateItemsList(); + }; + contextMenu.Items.Add(categoryItem); + } + + // Show the menu below the filter button + contextMenu.Show(butFilter, new System.Drawing.Point(0, butFilter.Height)); + } } } From be9569204bc91b7fb7fe7da5f1199ca3c7b09941 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 26 Jan 2026 19:41:41 +0000 Subject: [PATCH 5/5] Address code review feedback - simplify type names Co-authored-by: TrainWrack <120750885+TrainWrack@users.noreply.github.com> --- TombEditor/ToolWindows/ItemBrowser.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/TombEditor/ToolWindows/ItemBrowser.cs b/TombEditor/ToolWindows/ItemBrowser.cs index 858b0fc21..6be251773 100644 --- a/TombEditor/ToolWindows/ItemBrowser.cs +++ b/TombEditor/ToolWindows/ItemBrowser.cs @@ -284,7 +284,7 @@ private void butFilter_Click(object sender, EventArgs e) var contextMenu = new DarkUI.Controls.DarkContextMenu(); // Add "Clear Filter" option - var clearItem = new System.Windows.Forms.ToolStripMenuItem("Clear Filter"); + var clearItem = new ToolStripMenuItem("Clear Filter"); clearItem.Checked = _selectedCategories.Count == 0 && !_staticsOnlyFilter; clearItem.Click += (s, ev) => { @@ -295,7 +295,7 @@ private void butFilter_Click(object sender, EventArgs e) contextMenu.Items.Add(clearItem); // Add "Statics Only" option - var staticsOnlyItem = new System.Windows.Forms.ToolStripMenuItem("Statics Only"); + var staticsOnlyItem = new ToolStripMenuItem("Statics Only"); staticsOnlyItem.Checked = _staticsOnlyFilter; staticsOnlyItem.Click += (s, ev) => { @@ -307,12 +307,12 @@ private void butFilter_Click(object sender, EventArgs e) contextMenu.Items.Add(staticsOnlyItem); // Add separator - contextMenu.Items.Add(new System.Windows.Forms.ToolStripSeparator()); + contextMenu.Items.Add(new ToolStripSeparator()); // Add category items foreach (var category in allCategories) { - var categoryItem = new System.Windows.Forms.ToolStripMenuItem(category); + var categoryItem = new ToolStripMenuItem(category); categoryItem.Checked = _selectedCategories.Contains(category); categoryItem.Click += (s, ev) => {