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)