diff --git a/PKHeX.Core/PKM/Util/Conversion/ItemConverter.cs b/PKHeX.Core/PKM/Util/Conversion/ItemConverter.cs index 0b671a987..13572eb3d 100644 --- a/PKHeX.Core/PKM/Util/Conversion/ItemConverter.cs +++ b/PKHeX.Core/PKM/Util/Conversion/ItemConverter.cs @@ -164,6 +164,20 @@ public static byte GetItemFuture1(byte value) return value; } + /// + /// Gets a format specific item index depending on the desired format and the provided item index & origin format. + /// + /// Item ID to convert + /// Current format + /// Converted item ID + public static int GetItemDisplay(int itemID, EntityContext format) => itemID == 0 ? 0 : format switch + { + EntityContext.Gen1 => GetItemFuture2(GetItemFuture1((byte)itemID)), + EntityContext.Gen2 => GetItemFuture2((byte)itemID), + EntityContext.Gen3 => GetItemFuture3((ushort)itemID), + _ => itemID, + }; + /// /// Gets a format specific value depending on the desired format and the provided item index & origin format. /// diff --git a/PKHeX.Drawing.PokeSprite/Builder/SpriteBuilder.cs b/PKHeX.Drawing.PokeSprite/Builder/SpriteBuilder.cs index 60ae21ba4..1f0f882a2 100644 --- a/PKHeX.Drawing.PokeSprite/Builder/SpriteBuilder.cs +++ b/PKHeX.Drawing.PokeSprite/Builder/SpriteBuilder.cs @@ -184,13 +184,7 @@ private Bitmap GetBaseImageFallback(ushort species, byte form, byte gender, uint private Bitmap LayerOverImageItem(Bitmap baseImage, int item, EntityContext context) { - var lump = HeldItemLumpUtil.GetIsLump(item, context); - var itemimg = lump switch - { - HeldItemLumpImage.TechnicalMachine => ItemTM, - HeldItemLumpImage.TechnicalRecord => ItemTR, - _ => (Image?)Resources.ResourceManager.GetObject(GetItemResourceName(item)) ?? UnknownItem, - }; + var itemimg = GetItemSprite(item, context); // Redraw item in bottom right corner; since images are cropped, try to not have them at the edge int x = baseImage.Width - itemimg.Width - ((ItemMaxSize - itemimg.Width) / 4) - ItemShiftX; @@ -198,6 +192,17 @@ private Bitmap LayerOverImageItem(Bitmap baseImage, int item, EntityContext cont return ImageUtil.LayerImage(baseImage, itemimg, x, y); } + public Bitmap GetItemSprite(int item, EntityContext context) + { + var lump = HeldItemLumpUtil.GetIsLump(item, context); + return lump switch + { + HeldItemLumpImage.TechnicalMachine => ItemTM, + HeldItemLumpImage.TechnicalRecord => ItemTR, + _ => (Bitmap?)Resources.ResourceManager.GetObject(GetItemResourceName(item)) ?? UnknownItem, + }; + } + private static Bitmap LayerOverImageShiny(Bitmap baseImage, Shiny shiny) { // Add shiny star to top left of image. diff --git a/PKHeX.WinForms/Subforms/Save Editors/SAV_Inventory.cs b/PKHeX.WinForms/Subforms/Save Editors/SAV_Inventory.cs index c2482ec9d..61aab606e 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/SAV_Inventory.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/SAV_Inventory.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Windows.Forms; using PKHeX.Core; +using PKHeX.Drawing.PokeSprite; using PKHeX.WinForms.Controls; using static PKHeX.Core.MessageStrings; @@ -15,6 +16,8 @@ public sealed partial class SAV_Inventory : Form private static readonly ImageList IL_Pouch = InventoryTypeImageUtil.GetImageList(); + private readonly Bitmap _none = new(1, 1); + public SAV_Inventory(SaveFile sav) { InitializeComponent(); @@ -69,6 +72,9 @@ public SAV_Inventory(SaveFile sav) private readonly bool HasNewShop; private readonly bool HasHeld; private bool IsCountValidationSuppressed; + private bool DropDownNextComboEdit; + + private const int ColumnSprite = 0; // assume that all pouches have the same amount of columns private int ColumnItem; @@ -113,10 +119,13 @@ private DoubleBufferedDataGridView GetDGV(InventoryPouch pouch) { // Add DataGrid var dgv = GetBaseDataGrid(pouch); + dgv.CellMouseDown += Dgv_CellMouseDown; dgv.CellValueChanged += Dgv_CellValueChanged; dgv.EditingControlShowing += Dgv_EditingControlShowing; + dgv.CurrentCellDirtyStateChanged += Dgv_CurrentCellDirtyStateChanged; // Get Columns + dgv.Columns.Add(GetSpriteColumn()); var item = GetItemColumn(ColumnItem = dgv.Columns.Count); dgv.Columns.Add(item); dgv.Columns.Add(GetCountColumn(ColumnCount = dgv.Columns.Count)); @@ -166,9 +175,20 @@ private static DoubleBufferedDataGridView GetBaseDataGrid(InventoryPouch pouch) SelectionMode = DataGridViewSelectionMode.CellSelect, CellBorderStyle = DataGridViewCellBorderStyle.None, + RowTemplate = { Height = 24 }, Tag = pouch, }; + private static DataGridViewImageColumn GetSpriteColumn() => new() + { + HeaderText = string.Empty, + DisplayIndex = ColumnSprite, + ReadOnly = true, + ImageLayout = DataGridViewImageCellLayout.Zoom, + AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader, + DividerWidth = 2, + }; + private DataGridViewComboBoxColumn GetItemColumn(int c, string name = "Item") => new() { HeaderText = name, @@ -193,9 +213,16 @@ private static DataGridViewTextBoxColumn GetCountColumn(int c, string name = "Co DisplayIndex = c, Width = 45, DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter }, + DividerWidth = 2, MaxInputLength = 5 // enough to cover ushort.MaxValue (absolute maximum of any quantity ever allowed) }; + private static void Dgv_CurrentCellDirtyStateChanged(object? sender, EventArgs e) + { + if (sender is DataGridView { IsCurrentCellDirty: true } dgv) + dgv.CommitEdit(DataGridViewDataErrorContexts.Commit); + } + private void LoadAllBags() { foreach (var pouch in Bag.Pouches) @@ -237,6 +264,7 @@ private void GetBag(DataGridView dgv, InventoryPouch pouch) item = pouch.Items[i] = pouch.GetEmpty(); var cells = dgv.Rows[i].Cells; + UpdateSprite(cells, item.Index); cells[ColumnItem].Value = itemlist[item.Index]; cells[ColumnCount].Value = item.Count; @@ -271,13 +299,15 @@ private void Dgv_CellValueChanged(object? sender, DataGridViewCellEventArgs e) if (sender is not DataGridView { Tag: InventoryPouch pouch } dgv) return; - // Sanity check the item count against its maximum var cells = dgv.Rows[e.RowIndex].Cells; var itemName = cells[ColumnItem].Value?.ToString(); if (string.IsNullOrEmpty(itemName)) return; var itemID = itemlist.IndexOf(itemName); + UpdateSprite(cells, itemID); + + // Sanity check the item count against its maximum var cell = cells[ColumnCount]; var text = cell.Value?.ToString(); var count = Util.ToInt32(text); @@ -290,11 +320,28 @@ private void Dgv_CellValueChanged(object? sender, DataGridViewCellEventArgs e) IsCountValidationSuppressed = false; } - private static void Dgv_EditingControlShowing(object? sender, DataGridViewEditingControlShowingEventArgs e) + private void Dgv_CellMouseDown(object? sender, DataGridViewCellMouseEventArgs e) { - if (sender is not DataGridView dgv || e.Control is not ComboBox cb) + DropDownNextComboEdit = sender is DataGridView dgv && + e is { Button: MouseButtons.Left, RowIndex: >= 0, ColumnIndex: >= 0 } && + dgv.Columns[e.ColumnIndex] is DataGridViewComboBoxColumn; + } + + private void UpdateSprite(DataGridViewCellCollection cells, int itemID) + { + var context = Origin.Context; + itemID = ItemConverter.GetItemDisplay(itemID, context); + cells[ColumnSprite].Value = itemID == 0 ? _none : SpriteUtil.Spriter.GetItemSprite(itemID, context); + } + + + private void Dgv_EditingControlShowing(object? sender, DataGridViewEditingControlShowingEventArgs e) + { + if (sender is not DataGridView dgv || e.Control is not ComboBox cb || !DropDownNextComboEdit) return; + DropDownNextComboEdit = false; + if (dgv.CurrentCell?.OwningColumn is not DataGridViewComboBoxColumn) return;