mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-07-28 11:07:22 -05:00
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:
parent
d0ae47eb6c
commit
bf6c25eca7
57
PKHeX.Core/Editing/Saves/Slots/BoxEdit.cs
Normal file
57
PKHeX.Core/Editing/Saves/Slots/BoxEdit.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
PKHeX.Core/Editing/Saves/Slots/SlotTracker.cs
Normal file
10
PKHeX.Core/Editing/Saves/Slots/SlotTracker.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
36
PKHeX.WinForms/Controls/SAV Editor/CryPlayer.cs
Normal file
36
PKHeX.WinForms/Controls/SAV Editor/CryPlayer.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
33
PKHeX.WinForms/Controls/SAV Editor/DragManager.cs
Normal file
33
PKHeX.WinForms/Controls/SAV Editor/DragManager.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
9
PKHeX.WinForms/Controls/SAV Editor/DropModifier.cs
Normal file
9
PKHeX.WinForms/Controls/SAV Editor/DropModifier.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
namespace PKHeX.WinForms.Controls
|
||||
{
|
||||
public enum DropModifier
|
||||
{
|
||||
None,
|
||||
Overwrite,
|
||||
Clone,
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
75
PKHeX.WinForms/Controls/SAV Editor/SlotHoverHandler.cs
Normal file
75
PKHeX.WinForms/Controls/SAV Editor/SlotHoverHandler.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
27
PKHeX.WinForms/Controls/SAV Editor/SlotTrackerImage.cs
Normal file
27
PKHeX.WinForms/Controls/SAV Editor/SlotTrackerImage.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
PKHeX.WinForms/Controls/SAV Editor/SlotUtil.cs
Normal file
35
PKHeX.WinForms/Controls/SAV Editor/SlotUtil.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
PKHeX.WinForms/Controls/SAV Editor/SummaryPreviewer.cs
Normal file
24
PKHeX.WinForms/Controls/SAV Editor/SummaryPreviewer.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user