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
This commit is contained in:
Kurt 2019-08-20 19:50:28 -07:00
parent d0ae47eb6c
commit bf6c25eca7
20 changed files with 552 additions and 330 deletions

View File

@ -0,0 +1,57 @@
using System;
namespace PKHeX.Core
{
/// <summary>
/// Represents a Box Editor that loads the contents for easy manipulation.
/// </summary>
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;
}
}
}

View File

@ -1,12 +1,11 @@
namespace PKHeX.Core
{
public class SlotChangeInfo
public class SlotChangeInfo<T>
{
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;
}
}
}

View File

@ -0,0 +1,10 @@
namespace PKHeX.Core
{
public class SlotTracker<T>
{
public int Box { get; set; } = -1;
public int Slot { get; set; } = -1;
public T View { get; private set; }
public SlotTouchType Interaction { get; set; }
}
}

View File

@ -733,5 +733,19 @@ public static IEnumerable<ShowdownSet> GetShowdownSets(IEnumerable<string> lines
/// <param name="separator">Splitter between each set.</param>
/// <returns>Single string containing all <see cref="Text"/> lines.</returns>
public static string GetShowdownSets(IEnumerable<PKM> data, string separator) => string.Join(separator, GetShowdownSets(data));
/// <summary>
/// Gets a localized string preview of the provided <see cref="pk"/>.
/// </summary>
/// <param name="pk">Pokémon data</param>
/// <param name="language">Language code</param>
/// <returns>Multi-line string</returns>
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);
}
}
}

View File

@ -170,7 +170,7 @@ public PKM[] GetBoxData(int box)
return data;
}
private void AddBoxData(IList<PKM> data, int box, int index)
public void AddBoxData(IList<PKM> data, int box, int index)
{
int ofs = GetBoxOffset(box);
var boxName = GetBoxName(box);

View File

@ -18,7 +18,6 @@ public partial class BoxEditor : UserControl, ISlotViewer<PictureBox>
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
}
}
}

View File

@ -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<ISlotViewer<PictureBox>>(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
{

View File

@ -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;
}
}
}

View File

@ -0,0 +1,33 @@
using System.Drawing;
using System.Windows.Forms;
using PKHeX.Core;
namespace PKHeX.WinForms.Controls
{
public class DragManager
{
public SlotChangeInfo<Cursor> 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<Cursor>(SAV);
}
public void Reset() => Info.Reset();
public Point MouseDownPosition { get; set; }
public bool CanStartDrag => Info.LeftMouseIsDown && !Cursor.Position.Equals(MouseDownPosition);
}
}

View File

@ -0,0 +1,9 @@
namespace PKHeX.WinForms.Controls
{
public enum DropModifier
{
None,
Overwrite,
Clone,
}
}

View File

@ -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();
}

View File

@ -17,43 +17,22 @@ namespace PKHeX.WinForms.Controls
/// </summary>
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<BoxEditor> Boxes = new List<BoxEditor>();
public readonly List<ISlotViewer<PictureBox>> OtherSlots = new List<ISlotViewer<PictureBox>>();
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<ISlotViewer<PictureBox>>(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<PictureBox> 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<T> GetViewParent<T>(T pb) where T : Control
=> WinFormsUtil.FindFirstControlOfType<ISlotViewer<T>>(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<string> files, DragEventArgs e, bool noEgg)
/// <summary>
/// Tries to load the input <see cref="files"/>
/// </summary>
/// <param name="files">Files to load</param>
/// <param name="e">Args</param>
/// <param name="badDest">Destination slot disallows eggs/blanks</param>
/// <returns>True if loaded</returns>
private bool TryLoadFiles(IReadOnlyList<string> 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<string> 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<string> 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<string> 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<PictureBox> 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);
}
}
}

View File

@ -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<ISlotViewer<PictureBox>>(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();
}
}
}

View File

@ -0,0 +1,27 @@
using System.Drawing;
using System.Windows.Forms;
using PKHeX.Core;
namespace PKHeX.WinForms.Controls
{
public class SlotTrackerImage : SlotTracker<PictureBox>
{
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;
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -225,6 +225,10 @@
<Compile Include="Controls\SAV Editor\ContextMenuSAV.Designer.cs">
<DependentUpon>ContextMenuSAV.cs</DependentUpon>
</Compile>
<Compile Include="Controls\SAV Editor\CryPlayer.cs" />
<Compile Include="Controls\SAV Editor\DragManager.cs" />
<Compile Include="Controls\SAV Editor\DropModifier.cs" />
<Compile Include="Controls\SAV Editor\SlotHoverHandler.cs" />
<Compile Include="Controls\SAV Editor\SlotIndex.cs" />
<Compile Include="Controls\SAV Editor\SlotChangeManager.cs" />
<Compile Include="Controls\SAV Editor\SAVEditor.cs">
@ -239,6 +243,9 @@
<Compile Include="Controls\SAV Editor\SlotList.Designer.cs">
<DependentUpon>SlotList.cs</DependentUpon>
</Compile>
<Compile Include="Controls\SAV Editor\SlotUtil.cs" />
<Compile Include="Controls\SAV Editor\SummaryPreviewer.cs" />
<Compile Include="Controls\SAV Editor\SlotTrackerImage.cs" />
<Compile Include="Controls\SAV Editor\SlotViewer.cs" />
<Compile Include="Controls\SAV Editor\BoxMenuStrip.cs">
<SubType>Component</SubType>

View File

@ -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);

View File

@ -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)