diff --git a/UoFiddler.Controls/UserControls/ItemsControl.cs b/UoFiddler.Controls/UserControls/ItemsControl.cs index c05922c7..4b1446fe 100644 --- a/UoFiddler.Controls/UserControls/ItemsControl.cs +++ b/UoFiddler.Controls/UserControls/ItemsControl.cs @@ -1735,7 +1735,11 @@ private void AddSingleItem(string fileName, int index) continue; } - _itemList[i] = index; + // Insert before the first larger id; the id may already be listed + if (_itemList[i] != index) + { + _itemList.Insert(i, index); + } done = true; diff --git a/UoFiddler.Plugin.MultiEditor/UserControls/MultiEditorControl.Designer.cs b/UoFiddler.Plugin.MultiEditor/UserControls/MultiEditorControl.Designer.cs index 77b5b8a1..00a0a5bd 100644 --- a/UoFiddler.Plugin.MultiEditor/UserControls/MultiEditorControl.Designer.cs +++ b/UoFiddler.Plugin.MultiEditor/UserControls/MultiEditorControl.Designer.cs @@ -48,6 +48,7 @@ private void InitializeComponent() DummyContextMenu = new System.Windows.Forms.ContextMenuStrip(components); pictureBoxDrawTiles = new System.Windows.Forms.PictureBox(); vScrollBarDrawTiles = new System.Windows.Forms.VScrollBar(); + textBoxDrawTilesFilter = new System.Windows.Forms.TextBox(); designTab = new System.Windows.Forms.TabPage(); groupBox1 = new System.Windows.Forms.GroupBox(); BTN_CreateBlank = new System.Windows.Forms.Button(); @@ -199,6 +200,7 @@ private void InitializeComponent() // splitContainer4.Panel2.Controls.Add(pictureBoxDrawTiles); splitContainer4.Panel2.Controls.Add(vScrollBarDrawTiles); + splitContainer4.Panel2.Controls.Add(textBoxDrawTilesFilter); splitContainer4.Size = new System.Drawing.Size(264, 250); splitContainer4.SplitterDistance = 112; splitContainer4.SplitterWidth = 5; @@ -247,6 +249,16 @@ private void InitializeComponent() vScrollBarDrawTiles.TabIndex = 0; vScrollBarDrawTiles.Scroll += VScrollBarDrawTiles_Scroll; // + // textBoxDrawTilesFilter + // + textBoxDrawTilesFilter.Dock = System.Windows.Forms.DockStyle.Top; + textBoxDrawTilesFilter.Location = new System.Drawing.Point(0, 0); + textBoxDrawTilesFilter.Name = "textBoxDrawTilesFilter"; + textBoxDrawTilesFilter.PlaceholderText = "Filter by name or 0x id"; + textBoxDrawTilesFilter.Size = new System.Drawing.Size(264, 23); + textBoxDrawTilesFilter.TabIndex = 1; + textBoxDrawTilesFilter.TextChanged += TextBoxDrawTilesFilter_TextChanged; + // // designTab // designTab.BackColor = System.Drawing.SystemColors.Window; @@ -1177,6 +1189,7 @@ private void InitializeComponent() private System.Windows.Forms.NumericUpDown numericUpDown_Size_Width; private System.Windows.Forms.NumericUpDown numericUpDown_Z; private System.Windows.Forms.PictureBox pictureBoxDrawTiles; + private System.Windows.Forms.TextBox textBoxDrawTilesFilter; private System.Windows.Forms.PictureBox pictureBoxMulti; private System.Windows.Forms.ToolStripMenuItem removeAllTransToolStripMenuItem; private System.Windows.Forms.TabPage Save; diff --git a/UoFiddler.Plugin.MultiEditor/UserControls/MultiEditorControl.cs b/UoFiddler.Plugin.MultiEditor/UserControls/MultiEditorControl.cs index 720b9fd0..7bda5672 100644 --- a/UoFiddler.Plugin.MultiEditor/UserControls/MultiEditorControl.cs +++ b/UoFiddler.Plugin.MultiEditor/UserControls/MultiEditorControl.cs @@ -686,7 +686,6 @@ private void ApplyDarkModeIfNeeded() } ApplyPreviewBackgroundColor(); - ControlEvents.PreviewBackgroundColorChangeEvent += ApplyPreviewBackgroundColor; } private void ApplyPreviewBackgroundColor() @@ -831,6 +830,7 @@ private void OnLoad(object sender, EventArgs e) { ControlEvents.FilePathChangeEvent += OnFilePathChangeEvent; ControlEvents.MultiChangeEvent += OnMultiChangeEvent; + ControlEvents.PreviewBackgroundColorChangeEvent += ApplyPreviewBackgroundColor; } _loaded = true; @@ -1819,8 +1819,58 @@ private void TreeViewTilesXML_OnAfterSelect(object sender, TreeViewEventArgs e) return; } - _drawTilesList = (List)e.Node.Tag; - vScrollBarDrawTiles.Maximum = (_drawTilesList.Count / _pictureBoxDrawTilesCol) + 1; + _drawTilesCategory = e.Node.Tag as List ?? GetAllValidStatics(); + ApplyDrawTilesFilter(); + } + + /// + /// Tiles of the selected tree node, before the filter textbox is applied. + /// + private List _drawTilesCategory = new List(); + + private const string _allTilesTag = "AllTiles"; + + private static List GetAllValidStatics() + { + int maxItemId = Art.GetMaxItemId(); + var list = new List(maxItemId + 1); + for (int i = 0; i <= maxItemId; ++i) + { + if (Art.IsValidStatic(i)) + { + list.Add(i); + } + } + + return list; + } + + /// + /// Shows the tiles of the selected node whose name contains the filter text (case insensitive), + /// or whose id matches when the text is a 0x prefixed hex number. + /// + private void ApplyDrawTilesFilter() + { + string filter = textBoxDrawTilesFilter.Text.Trim(); + + if (filter.Length == 0) + { + _drawTilesList = _drawTilesCategory; + } + else if (filter.StartsWith("0x", StringComparison.OrdinalIgnoreCase) && Utils.ConvertStringToInt(filter, out int id)) + { + _drawTilesList = _drawTilesCategory.Where(tile => tile == id).ToList(); + } + else + { + _drawTilesList = _drawTilesCategory + // Art can hold more ids than tiledata + .Where(tile => tile < TileData.ItemTable.Length && + TileData.ItemTable[tile].Name?.Contains(filter, StringComparison.OrdinalIgnoreCase) == true) + .ToList(); + } + + vScrollBarDrawTiles.Maximum = (_drawTilesList.Count / Math.Max(1, _pictureBoxDrawTilesCol)) + 1; vScrollBarDrawTiles.Minimum = 1; vScrollBarDrawTiles.SmallChange = 1; vScrollBarDrawTiles.LargeChange = 1; @@ -1828,6 +1878,11 @@ private void TreeViewTilesXML_OnAfterSelect(object sender, TreeViewEventArgs e) pictureBoxDrawTiles.Invalidate(); } + private void TextBoxDrawTilesFilter_TextChanged(object sender, EventArgs e) + { + ApplyDrawTilesFilter(); + } + private void Undo_onClick(object sender, EventArgs e) { if (_compList == null) @@ -1920,6 +1975,14 @@ private static void XML_AddChildren(TreeNode node, XmlElement mainNode) private void XML_InitializeToolBox() { + // Rebuilt on every file path change, so start over instead of appending duplicates + treeViewTilesXML.Nodes.Clear(); + _drawTilesCategory = new List(); + _drawTilesList = _drawTilesCategory; + + // Every valid static, built when selected so it reflects the art loaded at that time + treeViewTilesXML.Nodes.Add(new TreeNode("All Tiles") { Tag = _allTilesTag, ImageIndex = 0 }); + string path = Options.AppDataPath; string fileName = Path.Combine(path, "plugins/multieditor.xml"); if (!File.Exists(fileName))