diff --git a/PKHeX.Drawing.PokeSprite/Builder/SpriteBuilder5668.cs b/PKHeX.Drawing.PokeSprite/Builder/SpriteBuilder5668.cs index 150c3fe35..0fc578ffd 100644 --- a/PKHeX.Drawing.PokeSprite/Builder/SpriteBuilder5668.cs +++ b/PKHeX.Drawing.PokeSprite/Builder/SpriteBuilder5668.cs @@ -26,14 +26,14 @@ public sealed class SpriteBuilder5668s : SpriteBuilder protected override Bitmap Unknown => Resources.b_unknown; protected override Bitmap GetEggSprite(ushort species) => species == (int)Species.Manaphy ? Resources.b_490_e : Resources.b_egg; - public override Bitmap Hover => Resources.slotHover68; - public override Bitmap View => Resources.slotView68; - public override Bitmap Set => Resources.slotSet68; - public override Bitmap Delete => Resources.slotDel68; - public override Bitmap Transparent => Resources.slotTrans68; + public override Bitmap Hover { get; } = Resources.slotHover68; + public override Bitmap View { get; } = Resources.slotView68; + public override Bitmap Set { get; } = Resources.slotSet68; + public override Bitmap Delete { get; } = Resources.slotDel68; + public override Bitmap Transparent { get; } = Resources.slotTrans68; public override Bitmap Drag => Resources.slotDrag68; public override Bitmap UnknownItem => Resources.bitem_unk; - public override Bitmap None => Resources.b_0; + public override Bitmap None { get; } = Resources.b_0; public override Bitmap ItemTM => Resources.bitem_tm; public override Bitmap ItemTR => Resources.bitem_tr; public override Bitmap ShadowLugia => Resources.b_249x; diff --git a/PKHeX.Drawing.PokeSprite/Builder/SpriteBuilder5668a.cs b/PKHeX.Drawing.PokeSprite/Builder/SpriteBuilder5668a.cs index abae3d71f..5247a896a 100644 --- a/PKHeX.Drawing.PokeSprite/Builder/SpriteBuilder5668a.cs +++ b/PKHeX.Drawing.PokeSprite/Builder/SpriteBuilder5668a.cs @@ -26,14 +26,14 @@ public sealed class SpriteBuilder5668a : SpriteBuilder protected override Bitmap Unknown => Resources.b_unknown; protected override Bitmap GetEggSprite(ushort species) => species == (int)Species.Manaphy ? Resources.a_490_e : Resources.a_egg; - public override Bitmap Hover => Resources.slotHover68; - public override Bitmap View => Resources.slotView68; - public override Bitmap Set => Resources.slotSet68; - public override Bitmap Delete => Resources.slotDel68; - public override Bitmap Transparent => Resources.slotTrans68; + public override Bitmap Hover { get; } = Resources.slotHover68; + public override Bitmap View { get; } = Resources.slotView68; + public override Bitmap Set { get; } = Resources.slotSet68; + public override Bitmap Delete { get; } = Resources.slotDel68; + public override Bitmap Transparent { get; } = Resources.slotTrans68; public override Bitmap Drag => Resources.slotDrag68; public override Bitmap UnknownItem => Resources.bitem_unk; - public override Bitmap None => Resources.b_0; + public override Bitmap None { get; } = Resources.b_0; public override Bitmap ItemTM => Resources.aitem_tm; public override Bitmap ItemTR => Resources.bitem_tr; public override Bitmap ShadowLugia => Resources.b_249x; diff --git a/PKHeX.Drawing.PokeSprite/Builder/SpriteBuilder5668c.cs b/PKHeX.Drawing.PokeSprite/Builder/SpriteBuilder5668c.cs index 493203f71..8dfaf60cb 100644 --- a/PKHeX.Drawing.PokeSprite/Builder/SpriteBuilder5668c.cs +++ b/PKHeX.Drawing.PokeSprite/Builder/SpriteBuilder5668c.cs @@ -26,14 +26,14 @@ public sealed class SpriteBuilder5668c : SpriteBuilder protected override Bitmap Unknown => Resources.b_unknown; protected override Bitmap GetEggSprite(ushort species) => species == (int)Species.Manaphy ? Resources.b_490_e : Resources.b_egg; - public override Bitmap Hover => Resources.slotHover68; - public override Bitmap View => Resources.slotView68; - public override Bitmap Set => Resources.slotSet68; - public override Bitmap Delete => Resources.slotDel68; - public override Bitmap Transparent => Resources.slotTrans68; + public override Bitmap Hover { get; } = Resources.slotHover68; + public override Bitmap View { get; } = Resources.slotView68; + public override Bitmap Set { get; } = Resources.slotSet68; + public override Bitmap Delete { get; } = Resources.slotDel68; + public override Bitmap Transparent { get; } = Resources.slotTrans68; public override Bitmap Drag => Resources.slotDrag68; public override Bitmap UnknownItem => Resources.bitem_unk; - public override Bitmap None => Resources.b_0; + public override Bitmap None { get; } = Resources.b_0; public override Bitmap ItemTM => Resources.bitem_tm; public override Bitmap ItemTR => Resources.bitem_tr; public override Bitmap ShadowLugia => Resources.b_249x; diff --git a/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs b/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs index 2ac9228d5..fd0d46773 100644 --- a/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs +++ b/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs @@ -104,6 +104,8 @@ private void InitializeEvents() if (menu.mnuVSD.Visible) return; Box.CurrentBox = e.Delta > 1 ? Box.Editor.MoveLeft() : Box.Editor.MoveRight(); + if (Box.M is { } m) + m.MouseRestart(); // should always trigger if properly connected }; GB_Daycare.Click += (_, _) => SwitchDaycare(); diff --git a/PKHeX.WinForms/Controls/SAV Editor/SlotChangeManager.cs b/PKHeX.WinForms/Controls/SAV Editor/SlotChangeManager.cs index 33e7f1b1b..24a9805bf 100644 --- a/PKHeX.WinForms/Controls/SAV Editor/SlotChangeManager.cs +++ b/PKHeX.WinForms/Controls/SAV Editor/SlotChangeManager.cs @@ -18,6 +18,7 @@ public sealed class SlotChangeManager(SAVEditor se) : IDisposable { public readonly SAVEditor SE = se; public readonly SlotTrackerImage LastSlot = new(); + public PictureBox? Hovered { get; private set; } public readonly DragManager Drag = new(); public SaveDataEditor Env { get; set; } = null!; @@ -34,15 +35,28 @@ public void MouseEnter(object? sender, EventArgs e) { if (sender is not PictureBox pb) return; + MouseRestart(pb); + } + + public void MouseRestart() + { + if (Hovered is { } pb) + MouseRestart(pb); + } + + private void MouseRestart(PictureBox pb) + { bool dataPresent = pb.Image is not null; if (dataPresent) Hover.Start(pb, LastSlot); + Hovered = pb; pb.Cursor = dataPresent ? Cursors.Hand : Cursors.Default; } public void MouseLeave(object? sender, EventArgs e) { Hover.Stop(); + Hovered = null; } public void MouseClick(object? sender, MouseEventArgs e) diff --git a/PKHeX.WinForms/Controls/Slots/PokePreview.cs b/PKHeX.WinForms/Controls/Slots/PokePreview.cs index f3eed0e70..f9f26bbdb 100644 --- a/PKHeX.WinForms/Controls/Slots/PokePreview.cs +++ b/PKHeX.WinForms/Controls/Slots/PokePreview.cs @@ -447,4 +447,30 @@ protected override CreateParams CreateParams private readonly record struct RenderMoveLine(string Text, Image? Icon, Color Color); private readonly record struct RenderTextLine(string Text, Color Color, int TopPadding, int BottomPadding); + + /// + /// Moves the form to the specified screen coordinates without resizing or changing its z-order. + /// + /// + /// This method updates the form's position using the Win32 SetWindowPos API with flags that minimize redraws and prevent activation or z-order changes. + /// Use this method when you need to reposition the form efficiently without affecting its size or focus. + /// + /// The new horizontal position, in pixels, of the form's upper-left corner relative to the screen. + /// The new vertical position, in pixels, of the form's upper-left corner relative to the screen. + public void MoveForm(int x, int y) + { + const uint SWP_NOSIZE = 0x0001; + const uint SWP_NOZORDER = 0x0004; + const uint SWP_NOREDRAW = 0x0008; + const uint SWP_NOACTIVATE = 0x0010; + const uint SWP_NOSENDCHANGING = 0x0400; + const uint SWP_ASYNCWINDOWPOS = 0x4000; + const uint flags = SWP_NOZORDER | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_ASYNCWINDOWPOS; + + SetWindowPos(Handle, 0, x, y, 0, 0, flags); + return; + + [System.Runtime.InteropServices.DllImport("user32.dll")] + static extern bool SetWindowPos(nint hWnd, nint hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags); + } } diff --git a/PKHeX.WinForms/Controls/Slots/SlotUtil.cs b/PKHeX.WinForms/Controls/Slots/SlotUtil.cs index 73a32dd42..69393d4ee 100644 --- a/PKHeX.WinForms/Controls/Slots/SlotUtil.cs +++ b/PKHeX.WinForms/Controls/Slots/SlotUtil.cs @@ -14,9 +14,9 @@ public static class SlotUtil /// /// Gets the background image for a slot based on the provided . /// - public static Bitmap GetTouchTypeBackground(SlotTouchType type) => type switch + public static Bitmap? GetTouchTypeBackground(SlotTouchType type) => type switch { - SlotTouchType.None => SpriteUtil.Spriter.Transparent, + SlotTouchType.None => null, SlotTouchType.Get => SpriteUtil.Spriter.View, SlotTouchType.Set => SpriteUtil.Spriter.Set, SlotTouchType.Delete => SpriteUtil.Spriter.Delete, @@ -42,6 +42,9 @@ public static class SlotUtil /// public static void UpdateSlot(PictureBox pb, ISlotInfo info, PKM pk, SaveFile sav, SlotVisibilityType flags, SlotTouchType t = SlotTouchType.None) { + pb.Image?.Dispose(); + pb.BackgroundImage?.Dispose(); + pb.BackgroundImage = GetTouchTypeBackground(t); if (pk.Species == 0) // Nothing in slot { diff --git a/PKHeX.WinForms/Controls/Slots/SummaryPreviewer.cs b/PKHeX.WinForms/Controls/Slots/SummaryPreviewer.cs index c44289b8c..7388c5f90 100644 --- a/PKHeX.WinForms/Controls/Slots/SummaryPreviewer.cs +++ b/PKHeX.WinForms/Controls/Slots/SummaryPreviewer.cs @@ -103,7 +103,7 @@ public void UpdatePreviewPosition(Point location) var cLoc = Cursor.Position; var shift = Settings.PreviewCursorShift; cLoc.Offset(shift); - Previewer.Location = cLoc; + Previewer.MoveForm(cLoc.X, cLoc.Y); } public void Show(Control pb, IEncounterInfo enc) diff --git a/PKHeX.WinForms/Subforms/Save Editors/SAV_BoxViewer.cs b/PKHeX.WinForms/Subforms/Save Editors/SAV_BoxViewer.cs index e5de66e9a..60da5b479 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/SAV_BoxViewer.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/SAV_BoxViewer.cs @@ -54,6 +54,7 @@ public SAV_BoxViewer(SAVEditor p, SlotChangeManager m, int box) if (parent.menu.mnuVSD.Visible) return; Box.CurrentBox = e.Delta > 1 ? Box.Editor.MoveLeft() : Box.Editor.MoveRight(); + m.MouseRestart(); }; var mnu = parent.SlotPictureBoxes[0].ContextMenuStrip; diff --git a/PKHeX.WinForms/Subforms/Save Editors/SAV_GroupViewer.cs b/PKHeX.WinForms/Subforms/Save Editors/SAV_GroupViewer.cs index 8cb7e89ce..7ee39e6c8 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/SAV_GroupViewer.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/SAV_GroupViewer.cs @@ -15,6 +15,8 @@ public sealed partial class SAV_GroupViewer : Form private readonly IReadOnlyList Groups; private readonly SummaryPreviewer Preview = new(); + private PictureBox? Hover; + public int CurrentGroup { get; set; } = -1; public SAV_GroupViewer(SaveFile sav, IPKMView view, IReadOnlyList groups) @@ -28,7 +30,12 @@ public SAV_GroupViewer(SaveFile sav, IPKMView view, IReadOnlyList gro Regenerate(count); CenterToParent(); - MouseWheel += (_, e) => CurrentGroup = e.Delta > 1 ? MoveLeft() : MoveRight(); + MouseWheel += (_, e) => + { + CurrentGroup = e.Delta > 1 ? MoveLeft() : MoveRight(); + if (Hover is { } pb) + HoverSlot(pb); + }; var names = groups.Select(z => $"{z.GroupName}").ToArray(); CB_BoxSelect.Items.AddRange(names); @@ -48,7 +55,11 @@ public SAV_GroupViewer(SaveFile sav, IPKMView view, IReadOnlyList gro pb.ContextMenuStrip = mnu; pb.MouseMove += (_, args) => Preview.UpdatePreviewPosition(args.Location); pb.MouseEnter += (_, _) => HoverSlot(pb); - pb.MouseLeave += (_, _) => Preview.Clear(); + pb.MouseLeave += (_, _) => + { + Preview.Clear(); + Hover = null; + }; } FormClosing += (_, _) => Preview.Clear(); } @@ -59,6 +70,7 @@ private void HoverSlot(PictureBox pb) var index = Box.Entries.IndexOf(pb); var slot = group.Slots[index]; Preview.Show(pb, slot, group.Type); + Hover = pb; } private void OmniClick(object sender, EventArgs e)