From bf6c25eca72787a2a08bfbf65cafd89fe7bedc92 Mon Sep 17 00:00:00 2001 From: Kurt Date: Tue, 20 Aug 2019 19:50:28 -0700 Subject: [PATCH] Break up SlotChangeManager logic A little bit cleaner when the logic is separated Keep an abstraction of BoxEdit to cache the current box contents. Already fetched to show sprites; any future fetches (for preview text / hover sprite) can reuse the already fetched pkm data. Should probably rewrite this stuff completely, but effort better spent elsewhere --- PKHeX.Core/Editing/Saves/Slots/BoxEdit.cs | 57 +++ .../Editing/Saves/Slots/SlotChangeInfo.cs | 16 +- PKHeX.Core/Editing/Saves/Slots/SlotTracker.cs | 10 + PKHeX.Core/Editing/ShowdownSet.cs | 14 + PKHeX.Core/Saves/SaveFile.cs | 2 +- .../Controls/SAV Editor/BoxEditor.cs | 69 ++- .../Controls/SAV Editor/ContextMenuSAV.cs | 16 +- .../Controls/SAV Editor/CryPlayer.cs | 36 ++ .../Controls/SAV Editor/DragManager.cs | 33 ++ .../Controls/SAV Editor/DropModifier.cs | 9 + .../Controls/SAV Editor/SAVEditor.cs | 22 +- .../Controls/SAV Editor/SlotChangeManager.cs | 409 +++++++----------- .../Controls/SAV Editor/SlotHoverHandler.cs | 75 ++++ .../Controls/SAV Editor/SlotTrackerImage.cs | 27 ++ .../Controls/SAV Editor/SlotUtil.cs | 35 ++ .../Controls/SAV Editor/SummaryPreviewer.cs | 24 + PKHeX.WinForms/MainWindow/Main.cs | 10 +- PKHeX.WinForms/PKHeX.WinForms.csproj | 7 + PKHeX.WinForms/Subforms/SAV_Database.cs | 4 +- .../Subforms/Save Editors/SAV_BoxViewer.cs | 7 +- 20 files changed, 552 insertions(+), 330 deletions(-) create mode 100644 PKHeX.Core/Editing/Saves/Slots/BoxEdit.cs create mode 100644 PKHeX.Core/Editing/Saves/Slots/SlotTracker.cs create mode 100644 PKHeX.WinForms/Controls/SAV Editor/CryPlayer.cs create mode 100644 PKHeX.WinForms/Controls/SAV Editor/DragManager.cs create mode 100644 PKHeX.WinForms/Controls/SAV Editor/DropModifier.cs create mode 100644 PKHeX.WinForms/Controls/SAV Editor/SlotHoverHandler.cs create mode 100644 PKHeX.WinForms/Controls/SAV Editor/SlotTrackerImage.cs create mode 100644 PKHeX.WinForms/Controls/SAV Editor/SlotUtil.cs create mode 100644 PKHeX.WinForms/Controls/SAV Editor/SummaryPreviewer.cs diff --git a/PKHeX.Core/Editing/Saves/Slots/BoxEdit.cs b/PKHeX.Core/Editing/Saves/Slots/BoxEdit.cs new file mode 100644 index 000000000..b96eccad4 --- /dev/null +++ b/PKHeX.Core/Editing/Saves/Slots/BoxEdit.cs @@ -0,0 +1,57 @@ +using System; + +namespace PKHeX.Core +{ + /// + /// Represents a Box Editor that loads the contents for easy manipulation. + /// + public class BoxEdit + { + private readonly SaveFile SAV; + private readonly PKM[] CurrentContents; + + public BoxEdit(SaveFile sav) + { + SAV = sav; + CurrentContents = new PKM[sav.BoxSlotCount]; + } + + public void LoadBox(int box) + { + if ((uint)box >= SAV.BoxCount) + throw new ArgumentOutOfRangeException(nameof(box)); + + SAV.AddBoxData(CurrentContents, box, 0); + CurrentBox = box; + } + + public PKM this[int index] + { + get => CurrentContents[index]; + set + { + CurrentContents[index] = value; + int ofs = SAV.GetBoxSlotOffset(index); + SAV.SetStoredSlot(value, ofs); + } + } + + public int CurrentBox { get; private set; } + public int BoxWallpaper { get => SAV.GetBoxWallpaper(CurrentBox); set => SAV.SetBoxWallpaper(CurrentBox, value); } + public string BoxName { get => SAV.GetBoxName(CurrentBox); set => SAV.SetBoxName(CurrentBox, value); } + + public int MoveLeft(bool max = false) + { + int newBox = max ? 0 : (CurrentBox + SAV.BoxCount - 1) % SAV.BoxCount; + LoadBox(newBox); + return newBox; + } + + public int MoveRight(bool max = false) + { + int newBox = max ? SAV.BoxCount - 1 : (CurrentBox + 1) % SAV.BoxCount; + LoadBox(newBox); + return newBox; + } + } +} \ No newline at end of file diff --git a/PKHeX.Core/Editing/Saves/Slots/SlotChangeInfo.cs b/PKHeX.Core/Editing/Saves/Slots/SlotChangeInfo.cs index 05272f8e2..64b73252c 100644 --- a/PKHeX.Core/Editing/Saves/Slots/SlotChangeInfo.cs +++ b/PKHeX.Core/Editing/Saves/Slots/SlotChangeInfo.cs @@ -1,12 +1,11 @@ namespace PKHeX.Core { - public class SlotChangeInfo + public class SlotChangeInfo { public bool LeftMouseIsDown { get; set; } - public bool RightMouseIsDown { get; set; } public bool DragDropInProgress { get; set; } - public object Cursor { get; set; } + public T Cursor { get; set; } public string CurrentPath { get; set; } public SlotChange Source { get; set; } @@ -21,13 +20,20 @@ public SlotChangeInfo(SaveFile sav) } public bool SameSlot => Source.Slot == Destination.Slot && Source.Box == Destination.Box; + public bool EitherIsParty => Source.IsParty || Destination.IsParty; public void Reset() { - LeftMouseIsDown = RightMouseIsDown = DragDropInProgress = false; + LeftMouseIsDown = DragDropInProgress = false; Source = new SlotChange { PKM = Blank }; Destination = new SlotChange(); - Cursor = CurrentPath = null; + CurrentPath = null; + Cursor = default; + } + + public void Invalidate() + { + Destination.Slot = -1; } } } diff --git a/PKHeX.Core/Editing/Saves/Slots/SlotTracker.cs b/PKHeX.Core/Editing/Saves/Slots/SlotTracker.cs new file mode 100644 index 000000000..d7fd3f46a --- /dev/null +++ b/PKHeX.Core/Editing/Saves/Slots/SlotTracker.cs @@ -0,0 +1,10 @@ +namespace PKHeX.Core +{ + public class SlotTracker + { + public int Box { get; set; } = -1; + public int Slot { get; set; } = -1; + public T View { get; private set; } + public SlotTouchType Interaction { get; set; } + } +} \ No newline at end of file diff --git a/PKHeX.Core/Editing/ShowdownSet.cs b/PKHeX.Core/Editing/ShowdownSet.cs index c1a3ae976..9e189ab14 100644 --- a/PKHeX.Core/Editing/ShowdownSet.cs +++ b/PKHeX.Core/Editing/ShowdownSet.cs @@ -733,5 +733,19 @@ public static IEnumerable GetShowdownSets(IEnumerable lines /// Splitter between each set. /// Single string containing all lines. public static string GetShowdownSets(IEnumerable data, string separator) => string.Join(separator, GetShowdownSets(data)); + + /// + /// Gets a localized string preview of the provided . + /// + /// Pokémon data + /// Language code + /// Multi-line string + public static string GetLocalizedPreviewText(PKM pk, string language) + { + var set = new ShowdownSet(pk); + if (pk.Format <= 2) // Nature preview from IVs + set.Nature = Experience.GetNatureVC(pk.EXP); + return set.LocalizedText(language); + } } } diff --git a/PKHeX.Core/Saves/SaveFile.cs b/PKHeX.Core/Saves/SaveFile.cs index 2d17ced74..77e7cc681 100644 --- a/PKHeX.Core/Saves/SaveFile.cs +++ b/PKHeX.Core/Saves/SaveFile.cs @@ -170,7 +170,7 @@ public PKM[] GetBoxData(int box) return data; } - private void AddBoxData(IList data, int box, int index) + public void AddBoxData(IList data, int box, int index) { int ofs = GetBoxOffset(box); var boxName = GetBoxName(box); diff --git a/PKHeX.WinForms/Controls/SAV Editor/BoxEditor.cs b/PKHeX.WinForms/Controls/SAV Editor/BoxEditor.cs index a1143b249..b57aecd65 100644 --- a/PKHeX.WinForms/Controls/SAV Editor/BoxEditor.cs +++ b/PKHeX.WinForms/Controls/SAV Editor/BoxEditor.cs @@ -18,7 +18,6 @@ public partial class BoxEditor : UserControl, ISlotViewer public SlotChangeManager M { get; set; } public bool FlagIllegal { get; set; } public bool CanSetCurrentBox { get; set; } - private const int SlotCount = 30; public BoxEditor() { @@ -84,7 +83,13 @@ public bool ControlsEnabled public int CurrentBox { get => CB_BoxSelect.SelectedIndex; - set => CB_BoxSelect.SelectedIndex = value; + set + { + CB_BoxSelect.SelectedIndex = value; + if (value < 0) + return; + Editor.LoadBox(value); + } } public string CurrentBoxName => CB_BoxSelect.Text; @@ -107,6 +112,14 @@ public void SetSlotFiller(PKM p, int box = -1, int slot = -1, PictureBox pb = nu { if (pb == null) pb = SlotPictureBoxes[slot]; + + if (p.Species == 0) // Nothing in slot + { + pb.Image = null; + pb.BackColor = Color.Transparent; + pb.Visible = true; + return; + } if (!p.Valid) // Invalid { // Bad Egg present in slot. @@ -120,8 +133,8 @@ public void SetSlotFiller(PKM p, int box = -1, int slot = -1, PictureBox pb = nu pb.BackColor = Color.Transparent; pb.Visible = true; - if (M != null && M.ColorizedBox == box && M.ColorizedSlot == slot) - pb.BackgroundImage = M.ColorizedColor; + if (M != null && M.LastSlot.Box == box && M.LastSlot.Slot == slot) + pb.BackgroundImage = M.LastSlot.InteractionColor; } public void ResetBoxNames(int box = -1) @@ -160,21 +173,20 @@ void getBoxNamesDefault() public void ResetSlots() { int box = CurrentBox; - int boxoffset = SAV.GetBoxOffset(box); PAN_Box.BackgroundImage = SAV.WallpaperImage(box); - M?.HoverWorker?.Stop(); + M?.Hover.Stop(); - int slot = M?.ColorizedBox == box ? M.ColorizedSlot : -1; + int slot = M?.LastSlot.Box == box ? M.LastSlot.Slot : -1; int index = box * SAV.BoxSlotCount; for (int i = 0; i < BoxSlotCount; i++) { var pb = SlotPictureBoxes[i]; if (i < SAV.BoxSlotCount && index + i < SAV.SlotCount) - GetSlotFiller(boxoffset + (SAV.SIZE_STORED * i), pb, box, i); + SetSlotFiller(Editor[i], box, slot, pb); else pb.Visible = false; - pb.BackgroundImage = slot == i ? M?.ColorizedColor : null; + pb.BackgroundImage = slot == i ? M?.LastSlot.InteractionColor : null; } } @@ -219,39 +231,17 @@ public void Reset() private void GetBox(object sender, EventArgs e) { + CurrentBox = CB_BoxSelect.SelectedIndex; if (SAV.CurrentBox != CurrentBox && CanSetCurrentBox) SAV.CurrentBox = CurrentBox; ResetSlots(); - M?.RefreshHoverSlot(this); + M?.Hover.Stop(); } - private void ClickBoxLeft(object sender, EventArgs e) => MoveLeft(ModifierKeys == Keys.Control); + private void ClickBoxLeft(object sender, EventArgs e) => CurrentBox = Editor.MoveLeft(ModifierKeys == Keys.Control); + private void ClickBoxRight(object sender, EventArgs e) => CurrentBox = Editor.MoveRight(ModifierKeys == Keys.Control); - public void MoveLeft(bool max = false) - { - CurrentBox = max ? 0 : (CurrentBox + SAV.BoxCount - 1) % SAV.BoxCount; - } - - private void ClickBoxRight(object sender, EventArgs e) => MoveRight(ModifierKeys == Keys.Control); - - public void MoveRight(bool max = false) - { - CurrentBox = max ? SAV.BoxCount - 1 : (CurrentBox + 1) % SAV.BoxCount; - } - - private void GetSlotFiller(int offset, PictureBox pb, int box = -1, int slot = -1) - { - if (!SAV.IsPKMPresent(offset)) - { - // 00s present in slot. - pb.Image = null; - pb.BackColor = Color.Transparent; - pb.Visible = true; - return; - } - PKM p = SAV.GetStoredSlot(offset); - SetSlotFiller(p, box, slot, pb); - } + public BoxEdit Editor { get; set; } // Drag & Drop Handling private void BoxSlot_MouseEnter(object sender, EventArgs e) => M?.MouseEnter(sender, e); @@ -263,5 +253,12 @@ private void GetSlotFiller(int offset, PictureBox pb, int box = -1, int slot = - private void BoxSlot_DragEnter(object sender, DragEventArgs e) => M?.DragEnter(sender, e); private void BoxSlot_QueryContinueDrag(object sender, QueryContinueDragEventArgs e) => M?.QueryContinueDrag(sender, e); private void BoxSlot_DragDrop(object sender, DragEventArgs e) => M?.DragDrop(sender, e); + + public void InitializeFromSAV(SaveFile sav) + { + Editor = new BoxEdit(sav); + Editor.LoadBox(sav.CurrentBox); + ResetBoxNames(); // Display the Box Names + } } } diff --git a/PKHeX.WinForms/Controls/SAV Editor/ContextMenuSAV.cs b/PKHeX.WinForms/Controls/SAV Editor/ContextMenuSAV.cs index 07f937e7e..080feccd9 100644 --- a/PKHeX.WinForms/Controls/SAV Editor/ContextMenuSAV.cs +++ b/PKHeX.WinForms/Controls/SAV Editor/ContextMenuSAV.cs @@ -33,10 +33,10 @@ private void ClickView(object sender, EventArgs e) if ((sender as PictureBox)?.Image == null) { System.Media.SystemSounds.Asterisk.Play(); return; } - m.HoverCancel(); + m.Hover.Stop(); m.SE.PKME_Tabs.PopulateFields(m.GetPKM(info), false, true); - m.SetColor(info.Box, info.Slot, Resources.slotView); + m.SetColor(info.Box, info.Slot, SlotTouchType.Get); } private void ClickSet(object sender, EventArgs e) @@ -61,7 +61,7 @@ private void ClickSet(object sender, EventArgs e) if (errata.Count > 0 && DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, string.Join(Environment.NewLine, errata), MsgContinue)) return; - m.HoverCancel(); + m.Hover.Stop(); if (info.Type == StorageSlotType.Party) // Party { @@ -72,7 +72,7 @@ private void ClickSet(object sender, EventArgs e) var view = WinFormsUtil.FindFirstControlOfType>(pb); info = view.GetSlotData(view.SlotPictureBoxes[sav.PartyCount]); } - m.SetPKM(pk, info, true, Resources.slotSet); + m.SetPKM(pk, info, true, SlotTouchType.Set); } else if (info.Type == StorageSlotType.Box || m.SE.HaX) { @@ -82,7 +82,7 @@ private void ClickSet(object sender, EventArgs e) m.SE.Menu_Undo.Enabled = true; } - m.SetPKM(pk, info, true, Resources.slotSet); + m.SetPKM(pk, info, true, SlotTouchType.Set); } else { @@ -108,11 +108,11 @@ private void ClickDelete(object sender, EventArgs e) if (sav.IsSlotLocked(info.Box, info.Slot)) { WinFormsUtil.Alert(MsgSaveSlotLocked); return; } - m.HoverCancel(); + m.Hover.Stop(); if (info.Type == StorageSlotType.Party) // Party { - m.SetPKM(sav.BlankPKM, info, true, Resources.slotDel); + m.SetPKM(sav.BlankPKM, info, true, SlotTouchType.Delete); return; } if (info.Type == StorageSlotType.Box || m.SE.HaX) @@ -122,7 +122,7 @@ private void ClickDelete(object sender, EventArgs e) m.SE.UndoStack.Push(new SlotChange(info, sav)); m.SE.Menu_Undo.Enabled = true; } - m.SetPKM(sav.BlankPKM, info, true, Resources.slotDel); + m.SetPKM(sav.BlankPKM, info, true, SlotTouchType.Delete); } else { diff --git a/PKHeX.WinForms/Controls/SAV Editor/CryPlayer.cs b/PKHeX.WinForms/Controls/SAV Editor/CryPlayer.cs new file mode 100644 index 000000000..cd49592dc --- /dev/null +++ b/PKHeX.WinForms/Controls/SAV Editor/CryPlayer.cs @@ -0,0 +1,36 @@ +using System.IO; +using System.Media; +using PKHeX.Core; + +namespace PKHeX.WinForms.Controls +{ + public class CryPlayer + { + private readonly SoundPlayer Sounds = new SoundPlayer(); + + public void PlayCry(PKM pk) + { + if (pk.Species == 0) + return; + + string path = GetCryPath(pk, Main.CryPath); + if (!File.Exists(path)) + return; + + Sounds.SoundLocation = path; + try { Sounds.Play(); } + catch { } + } + + public void Stop() => Sounds.Stop(); + + private static string GetCryPath(PKM pk, string cryFolder) + { + var name = PKX.GetResourceStringSprite(pk.Species, pk.AltForm, pk.Gender, pk.Format).Replace('_', '-').Substring(1); + var path = Path.Combine(cryFolder, $"{name}.wav"); + if (!File.Exists(path)) + path = Path.Combine(cryFolder, $"{pk.Species}.wav"); + return path; + } + } +} \ No newline at end of file diff --git a/PKHeX.WinForms/Controls/SAV Editor/DragManager.cs b/PKHeX.WinForms/Controls/SAV Editor/DragManager.cs new file mode 100644 index 000000000..43a1306c4 --- /dev/null +++ b/PKHeX.WinForms/Controls/SAV Editor/DragManager.cs @@ -0,0 +1,33 @@ +using System.Drawing; +using System.Windows.Forms; +using PKHeX.Core; + +namespace PKHeX.WinForms.Controls +{ + public class DragManager + { + public SlotChangeInfo Info; + public event DragEventHandler RequestExternalDragDrop; + public void RequestDD(object sender, DragEventArgs e) => RequestExternalDragDrop?.Invoke(sender, e); + + public void SetCursor(Form f, Cursor z) + { + Info.Cursor = f.Cursor = z; + } + + public void ResetCursor(Form sender) + { + SetCursor(sender, Cursors.Default); + } + + public void Initialize(SaveFile SAV) + { + Info = new SlotChangeInfo(SAV); + } + + public void Reset() => Info.Reset(); + + public Point MouseDownPosition { get; set; } + public bool CanStartDrag => Info.LeftMouseIsDown && !Cursor.Position.Equals(MouseDownPosition); + } +} \ No newline at end of file diff --git a/PKHeX.WinForms/Controls/SAV Editor/DropModifier.cs b/PKHeX.WinForms/Controls/SAV Editor/DropModifier.cs new file mode 100644 index 000000000..4a042cd50 --- /dev/null +++ b/PKHeX.WinForms/Controls/SAV Editor/DropModifier.cs @@ -0,0 +1,9 @@ +namespace PKHeX.WinForms.Controls +{ + public enum DropModifier + { + None, + Overwrite, + Clone, + } +} \ No newline at end of file diff --git a/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs b/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs index fcfcc307c..676bc6bc2 100644 --- a/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs +++ b/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs @@ -6,7 +6,6 @@ using System.Media; using System.Windows.Forms; using PKHeX.Core; -using PKHeX.WinForms.Properties; using static PKHeX.Core.MessageStrings; namespace PKHeX.WinForms.Controls @@ -106,10 +105,7 @@ private void InitializeEvents() { if (menu.mnuVSD.Visible) return; - if (e.Delta > 1) - Box.MoveLeft(); - else - Box.MoveRight(); + Box.CurrentBox = e.Delta > 1 ? Box.Editor.MoveLeft() : Box.Editor.MoveRight(); }; GB_Daycare.Click += SwitchDaycare; @@ -153,7 +149,7 @@ public void EnableDragDrop(DragEventHandler enter, DragEventHandler drop) tab.DragEnter += enter; tab.DragDrop += drop; } - M.RequestExternalDragDrop += drop; + M.Drag.RequestExternalDragDrop += drop; } // Generic Subfunctions // @@ -190,8 +186,8 @@ public void SetPKMBoxes() ResetNonBoxSlots(); // Recoloring of a storage box slot (to not show for other storage boxes) - if (M?.ColorizedSlot >= (int)SlotIndex.Party && M.ColorizedSlot < SlotPictureBoxes.Count) - SlotPictureBoxes[M.ColorizedSlot].BackgroundImage = M.ColorizedColor; + if (M?.LastSlot.Slot >= (int)SlotIndex.Party && M.LastSlot.Slot < SlotPictureBoxes.Count) + SlotPictureBoxes[M.LastSlot.Slot].BackgroundImage = M.LastSlot.InteractionColor; } private void ResetNonBoxSlots() @@ -288,7 +284,7 @@ public void ClickUndo() PKM = SAV.GetStoredSlot(change.Offset) }); UndoSlotChange(change); - M.SetColor(change.Box, change.Slot, Resources.slotSet); + M.SetColor(change.Box, change.Slot, SlotTouchType.Set); } public void ClickRedo() @@ -308,7 +304,7 @@ public void ClickRedo() PKM = SAV.GetStoredSlot(change.Offset) }); UndoSlotChange(change); - M.SetColor(change.Box, change.Slot, Resources.slotSet); + M.SetColor(change.Box, change.Slot, SlotTouchType.Set); } public void SetClonesToBox(PKM pk) @@ -359,7 +355,7 @@ private void UndoSlotChange(SlotChange change) Box.CurrentBox = change.Box; SAV.SetStoredSlot(pk, offset); Box.SetSlotFiller(pk, box, slot); - M?.SetColor(box, slot, Resources.slotSet); + M.SetColor(box, slot, SlotTouchType.Set); if (Menu_Undo != null) Menu_Undo.Enabled = UndoStack.Count > 0; @@ -924,8 +920,8 @@ private void ToggleViewReset() UndoStack.Clear(); RedoStack.Clear(); Box.M = M; - Box.ResetBoxNames(); // Display the Box Names - M.SetColor(-1, -1, null); + Box.InitializeFromSAV(SAV); + M.SetColor(-1, -1, SlotTouchType.None); SortMenu.ToggleVisibility(); } diff --git a/PKHeX.WinForms/Controls/SAV Editor/SlotChangeManager.cs b/PKHeX.WinForms/Controls/SAV Editor/SlotChangeManager.cs index a05ebecf9..39f28e4c0 100644 --- a/PKHeX.WinForms/Controls/SAV Editor/SlotChangeManager.cs +++ b/PKHeX.WinForms/Controls/SAV Editor/SlotChangeManager.cs @@ -17,43 +17,22 @@ namespace PKHeX.WinForms.Controls /// public sealed class SlotChangeManager : IDisposable { - // Disposeables public readonly SAVEditor SE; - private Image OriginalBackground; - private Image CurrentBackground; - - public Image ColorizedColor { get; private set; } - public int ColorizedBox { get; private set; } = -1; - public int ColorizedSlot { get; private set; } = -1; - - public DrawConfig Draw { private get; set; } - - public bool GlowHover { get; set; } = true; - public readonly BitmapAnimator HoverWorker; + public readonly SlotTrackerImage LastSlot = new SlotTrackerImage(); + public readonly DragManager Drag = new DragManager(); private SaveFile SAV => SE.SAV; - public SlotChangeInfo DragInfo; public readonly List Boxes = new List(); public readonly List> OtherSlots = new List>(); - public event DragEventHandler RequestExternalDragDrop; - private readonly ToolTip ShowSet = new ToolTip {InitialDelay = 200, IsBalloon = false}; - private readonly SoundPlayer Sounds = new SoundPlayer(); - private PictureBox HoveredSlot; + public readonly SlotHoverHandler Hover = new SlotHoverHandler(); - public SlotChangeManager(SAVEditor se) + public SlotChangeManager(SAVEditor se) => SE = se; + + public void Reset() { - HoverWorker = new BitmapAnimator(Resources.slotHover); - SE = se; - } - - public void Reset() { DragInfo = new SlotChangeInfo(SAV); ColorizedBox = ColorizedSlot = -1; } - public bool CanStartDrag => DragInfo.LeftMouseIsDown && !Cursor.Position.Equals(MouseDownPosition); - private Point MouseDownPosition { get; set; } - - public void SetCursor(Cursor z, object sender) - { - if (SE != null) - DragInfo.Cursor = ((Control)sender).FindForm().Cursor = z; + Drag.Initialize(SAV); + LastSlot.Reset(); + Hover.SAV = SAV; } public void MouseEnter(object sender, EventArgs e) @@ -61,105 +40,41 @@ public void MouseEnter(object sender, EventArgs e) var pb = (PictureBox)sender; if (pb.Image == null) return; - BeginHoverSlot(pb); - } - - private void BeginHoverSlot(PictureBox pb) - { - var view = WinFormsUtil.FindFirstControlOfType>(pb); - var data = view.GetSlotData(pb); - var pk = SAV.GetStoredSlot(data.Offset); - HoveredSlot = pb; - - OriginalBackground = pb.BackgroundImage; - - Bitmap hover; - if (GlowHover) - { - HoverWorker.Stop(); - - SpriteUtil.GetSpriteGlow(pk, Draw.GlowInitial.B, Draw.GlowInitial.G, Draw.GlowInitial.R, out var glowdata, out var GlowBase); - hover = ImageUtil.LayerImage(GlowBase, Resources.slotHover, 0, 0); - HoverWorker.GlowToColor = Draw.GlowFinal; - HoverWorker.GlowFromColor = Draw.GlowInitial; - HoverWorker.Start(pb, GlowBase, glowdata, OriginalBackground); - } - else - { - hover = Resources.slotHover; - } - - pb.BackgroundImage = CurrentBackground = OriginalBackground == null ? hover : ImageUtil.LayerImage(OriginalBackground, hover, 0, 0); - - if (Settings.Default.HoverSlotShowText) - ShowSimulatorSetTooltip(pb, pk); - if (Settings.Default.HoverSlotPlayCry) - PlayCry(pk); - } - - private void EndHoverSlot() - { - if (HoveredSlot != null) - HoverCancel(); - ShowSet.RemoveAll(); - Sounds.Stop(); - } - - public void HoverCancel() - { - HoverWorker.Stop(); - HoveredSlot = null; - } - - public void RefreshHoverSlot(ISlotViewer parent) - { - if (HoveredSlot == null || !parent.SlotPictureBoxes.Contains(HoveredSlot)) - return; - - BeginHoverSlot(HoveredSlot); + Hover.Start(pb, LastSlot); } public void MouseLeave(object sender, EventArgs e) { - EndHoverSlot(); - var pb = (PictureBox)sender; - if (pb.BackgroundImage != CurrentBackground) - return; - pb.BackgroundImage = OriginalBackground; + Hover.Stop(); } public void MouseClick(object sender, MouseEventArgs e) { - if (!DragInfo.DragDropInProgress) + if (!Drag.Info.DragDropInProgress) SE.ClickSlot(sender, e); } public void MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) - DragInfo.LeftMouseIsDown = false; - if (e.Button == MouseButtons.Right) - DragInfo.RightMouseIsDown = false; + Drag.Info.LeftMouseIsDown = false; } public void MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { - DragInfo.LeftMouseIsDown = true; - MouseDownPosition = Cursor.Position; + Drag.Info.LeftMouseIsDown = true; + Drag.MouseDownPosition = Cursor.Position; } - if (e.Button == MouseButtons.Right) - DragInfo.RightMouseIsDown = true; } public void QueryContinueDrag(object sender, QueryContinueDragEventArgs e) { if (e.Action != DragAction.Cancel && e.Action != DragAction.Drop) return; - DragInfo.LeftMouseIsDown = false; - DragInfo.RightMouseIsDown = false; - DragInfo.DragDropInProgress = false; + Drag.Info.LeftMouseIsDown = false; + Drag.Info.DragDropInProgress = false; } public void DragEnter(object sender, DragEventArgs e) @@ -169,13 +84,13 @@ public void DragEnter(object sender, DragEventArgs e) else if (e.Data != null) // within e.Effect = DragDropEffects.Move; - if (DragInfo.DragDropInProgress) - SetCursor((Cursor)DragInfo.Cursor, sender); + if (Drag.Info.DragDropInProgress) + Drag.SetCursor(((Control)sender).FindForm(), Drag.Info.Cursor); } public void MouseMove(object sender, MouseEventArgs e) { - if (!CanStartDrag) + if (!Drag.CanStartDrag) return; // Abort if there is no Pokemon in the given slot. @@ -199,84 +114,61 @@ public void DragDrop(object sender, DragEventArgs e) { SystemSounds.Asterisk.Play(); e.Effect = DragDropEffects.Copy; - DragInfo.Reset(); + Drag.Reset(); return; } - bool overwrite = Control.ModifierKeys == Keys.Alt; - bool clone = Control.ModifierKeys == Keys.Control; - DragInfo.Destination = src; - HandleDropPKM(sender, e, overwrite, clone); - } - - private void ShowSimulatorSetTooltip(Control pb, PKM pk) - { - if (pk.Species == 0) - { - ShowSet.RemoveAll(); - return; - } - var text = GetLocalizedPreviewText(pk, Settings.Default.Language); - ShowSet.SetToolTip(pb, text); - } - - private void PlayCry(PKM pk) - { - if (pk.Species == 0) - return; - - string path = GetCryPath(pk, Main.CryPath); - if (!File.Exists(path)) - return; - - Sounds.SoundLocation = path; - try { Sounds.Play(); } - catch { } + var mod = SlotUtil.GetDropModifier(); + Drag.Info.Destination = src; + HandleDropPKM(pb, e, mod); } private static ISlotViewer GetViewParent(T pb) where T : Control => WinFormsUtil.FindFirstControlOfType>(pb); - public void HandleMovePKM(PictureBox pb, bool encrypt) + private void HandleMovePKM(PictureBox pb, bool encrypt) { // Create a temporary PKM file to perform a drag drop operation. // Set flag to prevent re-entering. - DragInfo.DragDropInProgress = true; + Drag.Info.DragDropInProgress = true; // Prepare Data - DragInfo.Source = GetViewParent(pb).GetSlotData(pb); - DragInfo.Source.PKM = SAV.GetStoredSlot(DragInfo.Source.Offset); + Drag.Info.Source = GetViewParent(pb).GetSlotData(pb); + Drag.Info.Source.PKM = SAV.GetStoredSlot(Drag.Info.Source.Offset); // Make a new file name based off the PID string newfile = CreateDragDropPKM(pb, encrypt, out bool external); - DragInfo.Reset(); - SetCursor(SE.GetDefaultCursor, pb); + + // drop finished, clean up + Drag.Reset(); + Drag.ResetCursor(pb.FindForm()); // Browser apps need time to load data since the file isn't moved to a location on the user's local storage. // Tested 10ms -> too quick, 100ms was fine. 500ms should be safe? // Keep it to 10 seconds; Discord upload only stores the file path until you click Upload. int delay = external ? 10_000 : 0; DeleteAsync(newfile, delay); - if (DragInfo.Source.IsParty || DragInfo.Destination.IsParty) + if (Drag.Info.EitherIsParty) SE.SetParty(); } private async void DeleteAsync(string path, int delay) { await Task.Delay(delay).ConfigureAwait(true); - if (File.Exists(path) && DragInfo.CurrentPath == null) + if (File.Exists(path) && Drag.Info.CurrentPath == null) File.Delete(path); } private string CreateDragDropPKM(PictureBox pb, bool encrypt, out bool external) { // Make File - PKM pk = DragInfo.Source.PKM; + PKM pk = Drag.Info.Source.PKM; string newfile = FileUtil.GetPKMTempFileName(pk, encrypt); try { - TryMakeDragDropPKM(pb, encrypt, pk, newfile, out external); + var data = encrypt ? pk.EncryptedBoxData : pk.DecryptedBoxData; + external = TryMakeDragDropPKM(pb, data, newfile); } catch (Exception x) { @@ -287,90 +179,117 @@ private string CreateDragDropPKM(PictureBox pb, bool encrypt, out bool external) return newfile; } - private bool TryMakeDragDropPKM(PictureBox pb, bool encrypt, PKM pk, string newfile, out bool external) + private bool TryMakeDragDropPKM(PictureBox pb, byte[] data, string newfile) { - File.WriteAllBytes(newfile, encrypt ? pk.EncryptedBoxData : pk.DecryptedBoxData); + File.WriteAllBytes(newfile, data); var img = (Bitmap)pb.Image; - SetCursor(new Cursor(img.GetHicon()), pb); - HoverCancel(); + Drag.SetCursor(pb.FindForm(), new Cursor(img.GetHicon())); + Hover.Stop(); pb.Image = null; pb.BackgroundImage = Resources.slotDrag; + // Thread Blocks on DoDragDrop - DragInfo.CurrentPath = newfile; - DragDropEffects result = pb.DoDragDrop(new DataObject(DataFormats.FileDrop, new[] { newfile }), DragDropEffects.Move); - external = !DragInfo.Source.IsValid || result != DragDropEffects.Link; - if (external || DragInfo.SameSlot || result != DragDropEffects.Link) // not dropped to another box slot, restore img + Drag.Info.CurrentPath = newfile; + var result = pb.DoDragDrop(new DataObject(DataFormats.FileDrop, new[] { newfile }), DragDropEffects.Move); + var external = !Drag.Info.Source.IsValid || result != DragDropEffects.Link; + if (external || Drag.Info.SameSlot) // not dropped to another box slot, restore img { pb.Image = img; - pb.BackgroundImage = OriginalBackground; - SetCursor(SE.GetDefaultCursor, pb); - return false; + pb.BackgroundImage = LastSlot.OriginalBackground; + Drag.ResetCursor(pb.FindForm()); + return external; } if (result == DragDropEffects.Copy) // viewed in tabs or cloned { - if (!DragInfo.Destination.IsValid) // apply 'view' highlight - SetColor(DragInfo.Source.Box, DragInfo.Source.Slot, Resources.slotView); - external = false; + if (!Drag.Info.Destination.IsValid) // apply 'view' highlight + SetColor(Drag.Info.Source.Box, Drag.Info.Source.Slot, SlotTouchType.Get); + return false; } return true; } - private void SetSlotSprite(SlotChange loc, PKM pk, BoxEditor x = null) => (x ?? SE.Box).SetSlotFiller(pk, loc.Box, loc.Slot); - - public void HandleDropPKM(object sender, DragEventArgs e, bool overwrite, bool clone) + private void HandleDropPKM(PictureBox pb, DragEventArgs e, DropModifier mod) { - var pb = (PictureBox)sender; - DragInfo.Destination = GetViewParent(pb).GetSlotData(pb); - // Check for In-Dropped files (PKX,SAV,ETC) - string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); - if (Directory.Exists(files[0])) { SE.LoadBoxes(out string _, files[0]); return; } - if (DragInfo.SameSlot) + var files = (string[])e.Data.GetData(DataFormats.FileDrop); + if (Directory.Exists(files[0])) // folder + { + SE.LoadBoxes(out string _, files[0]); + return; + } + + e.Effect = mod == DropModifier.Clone ? DragDropEffects.Copy : DragDropEffects.Link; + + // file + Drag.Info.Destination = GetViewParent(pb).GetSlotData(pb); + if (Drag.Info.SameSlot) { e.Effect = DragDropEffects.Link; return; } - if (SAV.IsSlotLocked(DragInfo.Destination.Box, DragInfo.Destination.Slot)) + + var dest = Drag.Info.Destination; + if (SAV.IsSlotLocked(dest.Box, dest.Slot)) { AlertInvalidate(MessageStrings.MsgSaveSlotLocked); return; } - bool noEgg = DragInfo.Destination.IsParty && SE.SAV.IsPartyAllEggs(DragInfo.Destination.Slot) && !SE.HaX; - if (DragInfo.Source.Offset < 0) // external source + + bool badDest = IsDisallowedDrop(dest); + if (Drag.Info.Source.Offset < 0) // external source { - if (!TryLoadFiles(files, e, noEgg)) + if (!TryLoadFiles(files, e, badDest)) AlertInvalidate(MessageStrings.MsgSaveSlotBadData); return; } - if (!TrySetPKMDestination(sender, e, overwrite, clone, noEgg)) + + if (!TrySetPKMDestination(pb, mod, badDest)) { AlertInvalidate(MessageStrings.MsgSaveSlotEmpty); return; } - if (DragInfo.Source.Parent == null) // internal file - DragInfo.Reset(); + if (Drag.Info.Source.Parent == null) // internal file + Drag.Reset(); + } + + private bool IsDisallowedDrop(SlotChange dest) + { + if (SE.HaX) + return false; + if (!dest.IsParty) + return false; + return SE.SAV.IsPartyAllEggs(dest.Slot); } private void AlertInvalidate(string msg) { - DragInfo.Destination.Slot = -1; // Invalidate + Drag.Info.Invalidate(); WinFormsUtil.Alert(msg); } - private bool TryLoadFiles(IReadOnlyList files, DragEventArgs e, bool noEgg) + /// + /// Tries to load the input + /// + /// Files to load + /// Args + /// Destination slot disallows eggs/blanks + /// True if loaded + private bool TryLoadFiles(IReadOnlyList files, DragEventArgs e, bool badDest) { if (files.Count == 0) return false; - var temp = FileUtil.GetSingleFromPath(files[0], SAV); + var sav = SAV; + var path = files[0]; + var temp = FileUtil.GetSingleFromPath(path, sav); if (temp == null) { - RequestExternalDragDrop?.Invoke(this, e); // pass thru + Drag.RequestDD(this, e); // pass thru return true; // treat as handled } - PKM pk = PKMConverter.ConvertToType(temp, SAV.PKMType, out string c); + PKM pk = PKMConverter.ConvertToType(temp, sav.PKMType, out string c); if (pk == null) { WinFormsUtil.Error(c); @@ -378,10 +297,10 @@ private bool TryLoadFiles(IReadOnlyList files, DragEventArgs e, bool noE return false; } - if (noEgg && (pk.Species == 0 || pk.IsEgg)) + if (badDest && (pk.Species == 0 || pk.IsEgg)) return false; - if (SAV is ILangDeviantSave il && PKMConverter.IsIncompatibleGB(pk.Format, il.Japanese, pk.Japanese)) + if (sav is ILangDeviantSave il && PKMConverter.IsIncompatibleGB(pk.Format, il.Japanese, pk.Japanese)) { c = PKMConverter.GetIncompatibleGBMessage(pk, il.Japanese); WinFormsUtil.Error(c); @@ -389,7 +308,7 @@ private bool TryLoadFiles(IReadOnlyList files, DragEventArgs e, bool noE return false; } - var errata = SAV.IsPKMCompatible(pk); + var errata = sav.IsPKMCompatible(pk); if (errata.Count > 0) { string concat = string.Join(Environment.NewLine, errata); @@ -401,52 +320,52 @@ private bool TryLoadFiles(IReadOnlyList files, DragEventArgs e, bool noE } } - SetPKM(pk, false, Resources.slotSet); + SetPKM(pk, Drag.Info.Destination, false, SlotTouchType.Set); Debug.WriteLine(c); return true; } - private bool TrySetPKMDestination(object sender, DragEventArgs e, bool overwrite, bool clone, bool noEgg) + private bool TrySetPKMDestination(PictureBox pb, DropModifier mod, bool badDest) { - PKM pkz = GetPKM(true); - if (noEgg && (pkz.Species == 0 || pkz.IsEgg)) + PKM pk = GetPKM(Drag.Info.Source); + if (badDest && (pk.Species == 0 || pk.IsEgg)) return false; - if (DragInfo.Source.IsValid) - TrySetPKMSource(sender, overwrite, clone); + if (Drag.Info.Source.IsValid) + TrySetPKMSource(pb, mod); // Copy from temp to destination slot. - SetPKM(pkz, false, null); - - e.Effect = clone ? DragDropEffects.Copy : DragDropEffects.Link; - SetCursor(SE.GetDefaultCursor, sender); + SetPKM(pk, Drag.Info.Destination, false, SlotTouchType.Set); + Drag.ResetCursor(pb.FindForm()); return true; } - private bool TrySetPKMSource(object sender, bool overwrite, bool clone) + private bool TrySetPKMSource(PictureBox sender, DropModifier mod) { - if (overwrite && DragInfo.Destination.IsValid) // overwrite delete old slot - { - // Clear from slot - SetPKM(SAV.BlankPKM, true, null); - return true; - } - if (!clone && DragInfo.Destination.IsValid) - { - // Load data from destination - PKM pk = ((PictureBox)sender).Image != null - ? GetPKM(false) - : SAV.BlankPKM; + if (!Drag.Info.Destination.IsValid || mod == DropModifier.Clone) + return false; - // Set destination pokemon data to source slot - SetPKM(pk, true, null); - return true; + switch (mod) + { + case DropModifier.Overwrite: + // overwrite delete old slot + SetPKM(SAV.BlankPKM, Drag.Info.Source, true, SlotTouchType.Delete); + return true; + default: + // Load data from destination + var pk = sender.Image == null + ? SAV.BlankPKM + : GetPKM(Drag.Info.Destination); + + // Set destination pokemon data to source slot + SetPKM(pk, Drag.Info.Source, true, SlotTouchType.Set); + return true; } - return false; } - public void SetColor(int box, int slot, Image img) + public void SetColor(int box, int slot, SlotTouchType t) { + var img = SlotUtil.GetTouchTypeBackground(t); foreach (var boxview in Boxes) updateView(boxview); foreach (var other in OtherSlots) @@ -454,49 +373,44 @@ public void SetColor(int box, int slot, Image img) void updateView(ISlotViewer view) { - if (view.ViewIndex == ColorizedBox && ColorizedSlot >= 0) - view.SlotPictureBoxes[ColorizedSlot].BackgroundImage = null; + if (view.ViewIndex == LastSlot.Box && LastSlot.Slot >= 0) + view.SlotPictureBoxes[LastSlot.Slot].BackgroundImage = null; if (view.ViewIndex == box && slot >= 0) view.SlotPictureBoxes[slot].BackgroundImage = img; } - ColorizedBox = box; - ColorizedSlot = slot; - ColorizedColor = img; - - OriginalBackground = img; - if (HoverWorker != null) - HoverWorker.OriginalBackground = img; + LastSlot.SetInteraction(box, slot, img); } // PKM Get Set - private PKM GetPKM(bool src) => GetPKM(src ? DragInfo.Source : DragInfo.Destination); - public PKM GetPKM(SlotChange slot) { - int o = slot.Offset; - if (o < 0) + if (slot.Offset < 0) return slot.PKM; - if (slot.IsParty) - return SAV.GetPartySlot(o); + var sav = SAV; + return PartySlot(slot, sav); + } - var pk = SAV.GetStoredSlot(o); + private static PKM PartySlot(SlotChange slot, SaveFile sav) + { + if (slot.IsParty) + return sav.GetPartySlot(slot.Offset); + + var pk = sav.GetStoredSlot(slot.Offset); pk.Slot = slot.Slot; pk.Box = slot.Box; return pk; } - private void SetPKM(PKM pk, bool src, Image img) => SetPKM(pk, src ? DragInfo.Source : DragInfo.Destination, src, img); - - public void SetPKM(PKM pk, SlotChange slot, bool src, Image img) + public void SetPKM(PKM pk, SlotChange slot, bool src, SlotTouchType type) { if (slot.IsParty) { SetPKMParty(pk, src, slot); - if (img == Resources.slotDel) + if (type == SlotTouchType.Delete) slot.Slot = SAV.PartyCount; - SetColor(slot.Box, slot.Slot, img ?? Resources.slotSet); + SetColor(slot.Box, slot.Slot, SlotTouchType.Set); return; } @@ -509,10 +423,11 @@ public void SetPKM(PKM pk, SlotChange slot, bool src, Image img) if (boxview.CurrentBox != slot.Box) continue; Debug.WriteLine($"Setting to {boxview.Parent.Name}'s [{boxview.CurrentBox + 1:d2}]|{boxview.CurrentBoxName} at Slot {slot.Slot + 1}."); - SetSlotSprite(slot, pk, boxview); + boxview.SetSlotFiller(pk, slot.Box, slot.Slot); } } - SetColor(slot.Box, slot.Slot, img ?? Resources.slotSet); + + SetColor(slot.Box, slot.Slot, type); } private void SetPKMParty(PKM pk, bool src, SlotChange slot) @@ -551,12 +466,11 @@ public void SwapBoxes(int index, int other) public void Dispose() { - Sounds.Dispose(); - HoverWorker.Dispose(); + Hover.Dispose(); SE?.Dispose(); - OriginalBackground?.Dispose(); - CurrentBackground?.Dispose(); - ColorizedColor?.Dispose(); + LastSlot.OriginalBackground?.Dispose(); + LastSlot.CurrentBackground?.Dispose(); + LastSlot.InteractionColor?.Dispose(); } private void UpdateBoxViewAtBoxIndexes(params int[] boxIndexes) @@ -570,22 +484,5 @@ private void UpdateBoxViewAtBoxIndexes(params int[] boxIndexes) box.ResetBoxNames(current); } } - - private static string GetCryPath(PKM pk, string cryFolder) - { - var name = PKX.GetResourceStringSprite(pk.Species, pk.AltForm, pk.Gender, pk.Format).Replace('_', '-').Substring(1); - var path = Path.Combine(cryFolder, $"{name}.wav"); - if (!File.Exists(path)) - path = Path.Combine(cryFolder, $"{pk.Species}.wav"); - return path; - } - - public static string GetLocalizedPreviewText(PKM pk, string language) - { - var set = new ShowdownSet(pk); - if (pk.Format <= 2) // Nature preview from IVs - set.Nature = Experience.GetNatureVC(pk.EXP); - return set.LocalizedText(language); - } } } diff --git a/PKHeX.WinForms/Controls/SAV Editor/SlotHoverHandler.cs b/PKHeX.WinForms/Controls/SAV Editor/SlotHoverHandler.cs new file mode 100644 index 000000000..22a6ca7a7 --- /dev/null +++ b/PKHeX.WinForms/Controls/SAV Editor/SlotHoverHandler.cs @@ -0,0 +1,75 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using PKHeX.Core; +using PKHeX.WinForms.Properties; + +namespace PKHeX.WinForms.Controls +{ + public class SlotHoverHandler : IDisposable + { + public SaveFile SAV { private get; set; } + public DrawConfig Draw { private get; set; } + public bool GlowHover { private get; set; } = true; + + public static readonly CryPlayer CryPlayer = new CryPlayer(); + public static readonly SummaryPreviewer Preview = new SummaryPreviewer(); + + private readonly BitmapAnimator HoverWorker = new BitmapAnimator(Resources.slotHover); + + private PictureBox Slot; + + public void Start(PictureBox pb, SlotTrackerImage LastSlot) + { + var view = WinFormsUtil.FindFirstControlOfType>(pb); + var data = view.GetSlotData(pb); + var pk = SAV.GetStoredSlot(data.Offset); + Slot = pb; + + var orig = LastSlot.OriginalBackground = pb.BackgroundImage; + + Bitmap bg; + if (GlowHover) + { + HoverWorker.Stop(); + + SpriteUtil.GetSpriteGlow(pk, Draw.GlowInitial.B, Draw.GlowInitial.G, Draw.GlowInitial.R, out var glowdata, out var GlowBase); + bg = ImageUtil.LayerImage(GlowBase, Resources.slotHover, 0, 0); + HoverWorker.GlowToColor = Draw.GlowFinal; + HoverWorker.GlowFromColor = Draw.GlowInitial; + HoverWorker.Start(pb, GlowBase, glowdata, orig); + } + else + { + bg = Resources.slotHover; + } + + if (orig != null) + bg = ImageUtil.LayerImage(orig, bg, 0, 0); + pb.BackgroundImage = LastSlot.CurrentBackground = bg; + + if (Settings.Default.HoverSlotShowText) + Preview.Show(pb, pk); + if (Settings.Default.HoverSlotPlayCry) + CryPlayer.PlayCry(pk); + } + + public void Stop() + { + if (Slot != null) + { + HoverWorker.Stop(); + Slot = null; + } + Preview.Clear(); + CryPlayer.Stop(); + } + + public void Dispose() + { + HoverWorker?.Dispose(); + Slot?.Dispose(); + Draw?.Dispose(); + } + } +} \ No newline at end of file diff --git a/PKHeX.WinForms/Controls/SAV Editor/SlotTrackerImage.cs b/PKHeX.WinForms/Controls/SAV Editor/SlotTrackerImage.cs new file mode 100644 index 000000000..817035966 --- /dev/null +++ b/PKHeX.WinForms/Controls/SAV Editor/SlotTrackerImage.cs @@ -0,0 +1,27 @@ +using System.Drawing; +using System.Windows.Forms; +using PKHeX.Core; + +namespace PKHeX.WinForms.Controls +{ + public class SlotTrackerImage : SlotTracker + { + public Image InteractionColor { get; private set; } + public Image OriginalBackground { get; set; } + public Image CurrentBackground { get; set; } + + public void Reset() + { + Box = Slot = -1; + OriginalBackground = CurrentBackground = null; + } + + public void SetInteraction(int box, int slot, Image img) + { + Box = box; + Slot = slot; + InteractionColor = img; + OriginalBackground = img; + } + } +} \ No newline at end of file diff --git a/PKHeX.WinForms/Controls/SAV Editor/SlotUtil.cs b/PKHeX.WinForms/Controls/SAV Editor/SlotUtil.cs new file mode 100644 index 000000000..320a0c116 --- /dev/null +++ b/PKHeX.WinForms/Controls/SAV Editor/SlotUtil.cs @@ -0,0 +1,35 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using PKHeX.Core; +using PKHeX.WinForms.Properties; + +namespace PKHeX.WinForms.Controls +{ + public static class SlotUtil + { + public static Image GetTouchTypeBackground(SlotTouchType t) + { + switch (t) + { + case SlotTouchType.None: return Resources.slotTrans; + case SlotTouchType.Get: return Resources.slotView; + case SlotTouchType.Set: return Resources.slotSet; + case SlotTouchType.Delete: return Resources.slotDel; + case SlotTouchType.Swap: return Resources.slotSet; + default: + throw new ArgumentOutOfRangeException(nameof(t), t, null); + } + } + + public static DropModifier GetDropModifier() + { + switch (Control.ModifierKeys) + { + case Keys.Shift: return DropModifier.Clone; + case Keys.Alt: return DropModifier.Overwrite; + default: return DropModifier.None; + } + } + } +} \ No newline at end of file diff --git a/PKHeX.WinForms/Controls/SAV Editor/SummaryPreviewer.cs b/PKHeX.WinForms/Controls/SAV Editor/SummaryPreviewer.cs new file mode 100644 index 000000000..d25a50267 --- /dev/null +++ b/PKHeX.WinForms/Controls/SAV Editor/SummaryPreviewer.cs @@ -0,0 +1,24 @@ +using System.Windows.Forms; +using PKHeX.Core; +using PKHeX.WinForms.Properties; + +namespace PKHeX.WinForms.Controls +{ + public class SummaryPreviewer + { + private readonly ToolTip ShowSet = new ToolTip { InitialDelay = 200, IsBalloon = false }; + + public void Show(Control pb, PKM pk) + { + if (pk.Species == 0) + { + Clear(); + return; + } + var text = ShowdownSet.GetLocalizedPreviewText(pk, Settings.Default.Language); + ShowSet.SetToolTip(pb, text); + } + + public void Clear() => ShowSet.RemoveAll(); + } +} \ No newline at end of file diff --git a/PKHeX.WinForms/MainWindow/Main.cs b/PKHeX.WinForms/MainWindow/Main.cs index 1a76f13aa..8857d1f6c 100644 --- a/PKHeX.WinForms/MainWindow/Main.cs +++ b/PKHeX.WinForms/MainWindow/Main.cs @@ -279,7 +279,7 @@ private static void FormLoadConfig(out bool BAKprompt, out bool showChangelog) private void FormInitializeSecond() { var settings = Settings.Default; - Draw = C_SAV.M.Draw = PKME_Tabs.Draw = DrawConfig.GetConfig(settings.Draw); + Draw = C_SAV.M.Hover.Draw = PKME_Tabs.Draw = DrawConfig.GetConfig(settings.Draw); ReloadProgramSettings(settings); CB_MainLanguage.Items.AddRange(main_langlist); PB_Legal.Visible = !HaX; @@ -433,7 +433,7 @@ private void ReloadProgramSettings(Settings settings) C_SAV.ModifyPKM = PKME_Tabs.ModifyPKM = settings.SetUpdatePKM; CommonEdits.ShowdownSetIVMarkings = settings.ApplyMarkings; C_SAV.FlagIllegal = settings.FlagIllegal; - C_SAV.M.GlowHover = settings.HoverSlotGlowEdges; + C_SAV.M.Hover.GlowHover = settings.HoverSlotGlowEdges; SpriteBuilder.ShowEggSpriteAsItem = settings.ShowEggSpriteAsHeldItem; ParseSettings.AllowGen1Tradeback = settings.AllowGen1Tradeback; PKME_Tabs.HideSecretValues = C_SAV.HideSecretDetails = settings.HideSecretDetails; @@ -1125,16 +1125,16 @@ private void Dragout_MouseDown(object sender, MouseEventArgs e) try { File.WriteAllBytes(newfile, data); - C_SAV.M.DragInfo.Source.PKM = pk; + C_SAV.M.Drag.Info.Source.PKM = pk; var pb = (PictureBox)sender; if (pb.Image != null) - C_SAV.M.DragInfo.Cursor = Cursor = new Cursor(((Bitmap)pb.Image).GetHicon()); + C_SAV.M.Drag.Info.Cursor = Cursor = new Cursor(((Bitmap)pb.Image).GetHicon()); DoDragDrop(new DataObject(DataFormats.FileDrop, new[] { newfile }), DragDropEffects.Move); } catch (Exception x) { WinFormsUtil.Error("Drag && Drop Error", x); } - C_SAV.M.SetCursor(DefaultCursor, sender); + C_SAV.M.Drag.ResetCursor(this); File.Delete(newfile); } diff --git a/PKHeX.WinForms/PKHeX.WinForms.csproj b/PKHeX.WinForms/PKHeX.WinForms.csproj index 3c98bef11..974deb480 100644 --- a/PKHeX.WinForms/PKHeX.WinForms.csproj +++ b/PKHeX.WinForms/PKHeX.WinForms.csproj @@ -225,6 +225,10 @@ ContextMenuSAV.cs + + + + @@ -239,6 +243,9 @@ SlotList.cs + + + Component diff --git a/PKHeX.WinForms/Subforms/SAV_Database.cs b/PKHeX.WinForms/Subforms/SAV_Database.cs index ee07a10cd..3922daecf 100644 --- a/PKHeX.WinForms/Subforms/SAV_Database.cs +++ b/PKHeX.WinForms/Subforms/SAV_Database.cs @@ -85,7 +85,7 @@ public SAV_Database(PKMEditor f1, SAVEditor saveditor) return; } - var text = SlotChangeManager.GetLocalizedPreviewText(pk, Settings.Default.Language); + var text = ShowdownSet.GetLocalizedPreviewText(pk, Settings.Default.Language); ShowSet.SetToolTip(slot, text); }; } @@ -194,7 +194,7 @@ private void ClickDelete(object sender, EventArgs e) return; } var change = new SlotChange {Box = box, Offset = offset, Slot = slot}; - BoxView.M.SetPKM(BoxView.SAV.BlankPKM, change, true, Properties.Resources.slotDel); + BoxView.M.SetPKM(BoxView.SAV.BlankPKM, change, true, SlotTouchType.Delete); } // Remove from database. RawDB.Remove(pk); diff --git a/PKHeX.WinForms/Subforms/Save Editors/SAV_BoxViewer.cs b/PKHeX.WinForms/Subforms/Save Editors/SAV_BoxViewer.cs index be3535b65..63294eb54 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/SAV_BoxViewer.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/SAV_BoxViewer.cs @@ -1,5 +1,6 @@ using System; using System.Windows.Forms; +using PKHeX.Core; using PKHeX.WinForms.Controls; namespace PKHeX.WinForms @@ -12,6 +13,7 @@ public SAV_BoxViewer(SAVEditor p, SlotChangeManager m) { parent = p; InitializeComponent(); + Box.Editor = new BoxEdit(m.SE.SAV); Box.Setup(m); Box.Reset(); CenterToParent(); @@ -30,10 +32,7 @@ public SAV_BoxViewer(SAVEditor p, SlotChangeManager m) { if (parent.menu.mnuVSD.Visible) return; - if (e.Delta > 1) - Box.MoveLeft(); - else - Box.MoveRight(); + Box.CurrentBox = e.Delta > 1 ? Box.Editor.MoveLeft() : Box.Editor.MoveRight(); }; foreach (PictureBox pb in Box.SlotPictureBoxes)