2017-05-23 04:55:05 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2017-07-02 02:43:51 +00:00
|
|
|
|
using System.Diagnostics;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.IO;
|
2018-09-16 19:44:00 +00:00
|
|
|
|
using System.Linq;
|
2018-05-11 23:58:29 +00:00
|
|
|
|
using System.Media;
|
2017-06-18 01:37:19 +00:00
|
|
|
|
using System.Threading.Tasks;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
using PKHeX.Core;
|
2019-11-16 01:34:18 +00:00
|
|
|
|
using PKHeX.Drawing;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
|
|
|
|
|
namespace PKHeX.WinForms.Controls
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
2019-09-03 02:30:58 +00:00
|
|
|
|
/// Orchestrates the movement of slots within the GUI.
|
2017-05-23 04:55:05 +00:00
|
|
|
|
/// </summary>
|
2017-12-16 22:11:41 +00:00
|
|
|
|
public sealed class SlotChangeManager : IDisposable
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
|
|
|
|
public readonly SAVEditor SE;
|
2020-12-22 07:37:07 +00:00
|
|
|
|
public readonly SlotTrackerImage LastSlot = new();
|
|
|
|
|
public readonly DragManager Drag = new();
|
2020-10-18 18:02:39 +00:00
|
|
|
|
public SaveDataEditor<PictureBox> Env { get; set; } = null!;
|
2017-06-18 01:37:19 +00:00
|
|
|
|
|
2020-12-22 07:37:07 +00:00
|
|
|
|
public readonly List<BoxEditor> Boxes = new();
|
|
|
|
|
public readonly SlotHoverHandler Hover = new();
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2019-08-21 02:50:28 +00:00
|
|
|
|
public SlotChangeManager(SAVEditor se) => SE = se;
|
2018-05-11 23:38:09 +00:00
|
|
|
|
|
2019-08-21 02:50:28 +00:00
|
|
|
|
public void Reset()
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
2019-09-03 02:30:58 +00:00
|
|
|
|
Drag.Initialize();
|
2019-08-21 02:50:28 +00:00
|
|
|
|
LastSlot.Reset();
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2020-11-14 16:20:48 +00:00
|
|
|
|
public void MouseEnter(object? sender, EventArgs e)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
2020-12-22 07:37:07 +00:00
|
|
|
|
if (sender is not PictureBox pb)
|
2020-11-14 16:20:48 +00:00
|
|
|
|
return;
|
2021-07-24 07:16:51 +00:00
|
|
|
|
bool dataPresent = pb.Image is not null;
|
|
|
|
|
if (dataPresent)
|
|
|
|
|
Hover.Start(pb, LastSlot);
|
|
|
|
|
pb.Cursor = dataPresent ? Cursors.Hand : Cursors.Default;
|
2018-05-13 15:14:46 +00:00
|
|
|
|
}
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2020-11-14 16:20:48 +00:00
|
|
|
|
public void MouseLeave(object? sender, EventArgs e)
|
2018-05-13 15:14:46 +00:00
|
|
|
|
{
|
2019-08-21 02:50:28 +00:00
|
|
|
|
Hover.Stop();
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2020-11-14 16:20:48 +00:00
|
|
|
|
public void MouseClick(object? sender, MouseEventArgs e)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
2020-11-14 16:20:48 +00:00
|
|
|
|
if (sender == null)
|
|
|
|
|
return;
|
2019-08-21 02:50:28 +00:00
|
|
|
|
if (!Drag.Info.DragDropInProgress)
|
2017-06-18 01:37:19 +00:00
|
|
|
|
SE.ClickSlot(sender, e);
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2020-11-14 16:20:48 +00:00
|
|
|
|
public void MouseUp(object? sender, MouseEventArgs e)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
2020-11-14 16:20:48 +00:00
|
|
|
|
if (sender == null)
|
|
|
|
|
return;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
if (e.Button == MouseButtons.Left)
|
2019-08-21 02:50:28 +00:00
|
|
|
|
Drag.Info.LeftMouseIsDown = false;
|
2019-09-04 02:54:41 +00:00
|
|
|
|
Drag.Info.Source = null;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2020-11-14 16:20:48 +00:00
|
|
|
|
public void MouseDown(object? sender, MouseEventArgs e)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
2020-11-14 16:20:48 +00:00
|
|
|
|
if (sender == null)
|
|
|
|
|
return;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
if (e.Button == MouseButtons.Left)
|
2018-05-11 23:38:09 +00:00
|
|
|
|
{
|
2019-08-21 02:50:28 +00:00
|
|
|
|
Drag.Info.LeftMouseIsDown = true;
|
|
|
|
|
Drag.MouseDownPosition = Cursor.Position;
|
2018-05-11 23:38:09 +00:00
|
|
|
|
}
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2020-11-14 16:20:48 +00:00
|
|
|
|
public void QueryContinueDrag(object? sender, QueryContinueDragEventArgs e)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
2020-11-14 16:20:48 +00:00
|
|
|
|
if (sender == null)
|
|
|
|
|
return;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
if (e.Action != DragAction.Cancel && e.Action != DragAction.Drop)
|
|
|
|
|
return;
|
2019-08-21 02:50:28 +00:00
|
|
|
|
Drag.Info.LeftMouseIsDown = false;
|
|
|
|
|
Drag.Info.DragDropInProgress = false;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2020-11-14 16:20:48 +00:00
|
|
|
|
public void DragEnter(object? sender, DragEventArgs e)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
2020-11-14 16:20:48 +00:00
|
|
|
|
if (sender == null)
|
|
|
|
|
return;
|
2020-05-26 23:59:47 +00:00
|
|
|
|
if ((e.AllowedEffect & DragDropEffects.Copy) != 0) // external file
|
2017-05-23 04:55:05 +00:00
|
|
|
|
e.Effect = DragDropEffects.Copy;
|
|
|
|
|
else if (e.Data != null) // within
|
|
|
|
|
e.Effect = DragDropEffects.Move;
|
|
|
|
|
|
2019-08-21 02:50:28 +00:00
|
|
|
|
if (Drag.Info.DragDropInProgress)
|
|
|
|
|
Drag.SetCursor(((Control)sender).FindForm(), Drag.Info.Cursor);
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2019-09-04 02:54:41 +00:00
|
|
|
|
private static SlotViewInfo<T> GetSlotInfo<T>(T pb) where T : Control
|
|
|
|
|
{
|
|
|
|
|
var view = WinFormsUtil.FindFirstControlOfType<ISlotViewer<T>>(pb);
|
2020-10-18 18:02:39 +00:00
|
|
|
|
if (view == null)
|
2020-11-14 16:20:48 +00:00
|
|
|
|
throw new InvalidCastException("Unable to find View Parent");
|
2019-09-04 02:54:41 +00:00
|
|
|
|
var src = view.GetSlotData(pb);
|
PKHeX.Core Nullable cleanup (#2401)
* Handle some nullable cases
Refactor MysteryGift into a second abstract class (backed by a byte array, or fake data)
Make some classes have explicit constructors instead of { } initialization
* Handle bits more obviously without null
* Make SaveFile.BAK explicitly readonly again
* merge constructor methods to have readonly fields
* Inline some properties
* More nullable handling
* Rearrange box actions
define straightforward classes to not have any null properties
* Make extrabyte reference array immutable
* Move tooltip creation to designer
* Rearrange some logic to reduce nesting
* Cache generated fonts
* Split mystery gift album purpose
* Handle more tooltips
* Disallow null setters
* Don't capture RNG object, only type enum
* Unify learnset objects
Now have readonly properties which are never null
don't new() empty learnsets (>800 Learnset objects no longer created,
total of 2400 objects since we also new() a move & level array)
optimize g1/2 reader for early abort case
* Access rewrite
Initialize blocks in a separate object, and get via that object
removes a couple hundred "might be null" warnings since blocks are now readonly getters
some block references have been relocated, but interfaces should expose all that's needed
put HoF6 controls in a groupbox, and disable
* Readonly personal data
* IVs non nullable for mystery gift
* Explicitly initialize forced encounter moves
* Make shadow objects readonly & non-null
Put murkrow fix in binary data resource, instead of on startup
* Assign dex form fetch on constructor
Fixes legality parsing edge cases
also handle cxd parse for valid; exit before exception is thrown in FrameGenerator
* Remove unnecessary null checks
* Keep empty value until init
SetPouch sets the value to an actual one during load, but whatever
* Readonly team lock data
* Readonly locks
Put locked encounters at bottom (favor unlocked)
* Mail readonly data / offset
Rearrange some call flow and pass defaults
Add fake classes for SaveDataEditor mocking
Always party size, no need to check twice in stat editor
use a fake save file as initial data for savedata editor, and for
gamedata (wow i found a usage)
constrain eventwork editor to struct variable types (uint, int, etc),
thus preventing null assignment errors
2019-10-17 01:47:31 +00:00
|
|
|
|
return new SlotViewInfo<T>(src, view);
|
2019-09-04 02:54:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-11-14 16:20:48 +00:00
|
|
|
|
public void MouseMove(object? sender, MouseEventArgs e)
|
2018-05-11 23:38:09 +00:00
|
|
|
|
{
|
2020-11-14 16:20:48 +00:00
|
|
|
|
if (sender == null)
|
|
|
|
|
return;
|
2019-08-21 02:50:28 +00:00
|
|
|
|
if (!Drag.CanStartDrag)
|
2018-05-11 23:38:09 +00:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// Abort if there is no Pokemon in the given slot.
|
|
|
|
|
PictureBox pb = (PictureBox)sender;
|
|
|
|
|
if (pb.Image == null)
|
|
|
|
|
return;
|
|
|
|
|
bool encrypt = Control.ModifierKeys == Keys.Control;
|
2018-05-12 15:41:23 +00:00
|
|
|
|
HandleMovePKM(pb, encrypt);
|
2018-05-11 23:38:09 +00:00
|
|
|
|
}
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2020-11-14 16:20:48 +00:00
|
|
|
|
public void DragDrop(object? sender, DragEventArgs e)
|
2018-05-11 23:38:09 +00:00
|
|
|
|
{
|
2020-11-14 16:20:48 +00:00
|
|
|
|
if (sender == null)
|
|
|
|
|
return;
|
2018-05-11 23:38:09 +00:00
|
|
|
|
PictureBox pb = (PictureBox)sender;
|
2019-09-04 02:54:41 +00:00
|
|
|
|
var info = GetSlotInfo(pb);
|
2021-07-24 07:16:51 +00:00
|
|
|
|
if (!info.CanWriteTo() || Drag.Info.Source?.CanWriteTo() == false)
|
2018-05-11 23:38:09 +00:00
|
|
|
|
{
|
2018-05-11 23:58:29 +00:00
|
|
|
|
SystemSounds.Asterisk.Play();
|
2018-05-11 23:38:09 +00:00
|
|
|
|
e.Effect = DragDropEffects.Copy;
|
2019-08-21 02:50:28 +00:00
|
|
|
|
Drag.Reset();
|
2018-05-11 23:38:09 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-21 02:50:28 +00:00
|
|
|
|
var mod = SlotUtil.GetDropModifier();
|
2019-09-04 02:54:41 +00:00
|
|
|
|
Drag.Info.Destination = info;
|
2019-08-21 02:50:28 +00:00
|
|
|
|
HandleDropPKM(pb, e, mod);
|
2018-05-11 23:58:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-21 02:50:28 +00:00
|
|
|
|
private void HandleMovePKM(PictureBox pb, bool encrypt)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
|
|
|
|
// Create a temporary PKM file to perform a drag drop operation.
|
|
|
|
|
|
|
|
|
|
// Set flag to prevent re-entering.
|
2019-08-21 02:50:28 +00:00
|
|
|
|
Drag.Info.DragDropInProgress = true;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
|
|
|
|
|
// Prepare Data
|
2019-09-04 02:54:41 +00:00
|
|
|
|
Drag.Info.Source = GetSlotInfo(pb);
|
2019-11-23 06:22:25 +00:00
|
|
|
|
Drag.Info.Destination = null;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
|
|
|
|
|
// Make a new file name based off the PID
|
2018-05-12 15:41:23 +00:00
|
|
|
|
string newfile = CreateDragDropPKM(pb, encrypt, out bool external);
|
2019-08-21 02:50:28 +00:00
|
|
|
|
|
|
|
|
|
// drop finished, clean up
|
2019-09-04 02:54:41 +00:00
|
|
|
|
Drag.Info.Source = null;
|
2019-08-21 02:50:28 +00:00
|
|
|
|
Drag.Reset();
|
|
|
|
|
Drag.ResetCursor(pb.FindForm());
|
2017-05-23 04:55:05 +00:00
|
|
|
|
|
|
|
|
|
// 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?
|
2018-12-17 19:17:19 +00:00
|
|
|
|
// Keep it to 10 seconds; Discord upload only stores the file path until you click Upload.
|
|
|
|
|
int delay = external ? 10_000 : 0;
|
2017-07-02 02:43:51 +00:00
|
|
|
|
DeleteAsync(newfile, delay);
|
2019-09-04 02:54:41 +00:00
|
|
|
|
if (Drag.Info.DragIsParty)
|
2017-06-18 01:37:19 +00:00
|
|
|
|
SE.SetParty();
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2017-07-02 02:43:51 +00:00
|
|
|
|
private async void DeleteAsync(string path, int delay)
|
|
|
|
|
{
|
2018-05-25 04:22:44 +00:00
|
|
|
|
await Task.Delay(delay).ConfigureAwait(true);
|
2019-08-21 02:50:28 +00:00
|
|
|
|
if (File.Exists(path) && Drag.Info.CurrentPath == null)
|
2017-07-02 02:43:51 +00:00
|
|
|
|
File.Delete(path);
|
|
|
|
|
}
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2018-05-12 15:41:23 +00:00
|
|
|
|
private string CreateDragDropPKM(PictureBox pb, bool encrypt, out bool external)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
|
|
|
|
// Make File
|
2020-10-18 18:02:39 +00:00
|
|
|
|
var pk = Drag.Info.Source!.ReadCurrent();
|
2019-02-15 19:46:46 +00:00
|
|
|
|
string newfile = FileUtil.GetPKMTempFileName(pk, encrypt);
|
2017-05-23 04:55:05 +00:00
|
|
|
|
try
|
|
|
|
|
{
|
2019-11-16 22:03:25 +00:00
|
|
|
|
var data = encrypt ? pk.EncryptedPartyData : pk.DecryptedPartyData;
|
2019-08-21 02:50:28 +00:00
|
|
|
|
external = TryMakeDragDropPKM(pb, data, newfile);
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
2020-09-19 05:11:13 +00:00
|
|
|
|
#pragma warning disable CA1031 // Do not catch general exception types
|
|
|
|
|
// Tons of things can happen with drag & drop; don't try to handle things, just indicate failure.
|
2017-05-23 04:55:05 +00:00
|
|
|
|
catch (Exception x)
|
2020-09-19 05:11:13 +00:00
|
|
|
|
#pragma warning restore CA1031 // Do not catch general exception types
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
2020-09-19 05:11:13 +00:00
|
|
|
|
WinFormsUtil.Error("Drag && Drop Error", x);
|
2017-05-23 04:55:05 +00:00
|
|
|
|
external = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return newfile;
|
|
|
|
|
}
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2019-08-21 02:50:28 +00:00
|
|
|
|
private bool TryMakeDragDropPKM(PictureBox pb, byte[] data, string newfile)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
2019-08-21 02:50:28 +00:00
|
|
|
|
File.WriteAllBytes(newfile, data);
|
2017-05-23 04:55:05 +00:00
|
|
|
|
var img = (Bitmap)pb.Image;
|
2019-08-21 02:50:28 +00:00
|
|
|
|
Drag.SetCursor(pb.FindForm(), new Cursor(img.GetHicon()));
|
|
|
|
|
Hover.Stop();
|
2017-05-23 04:55:05 +00:00
|
|
|
|
pb.Image = null;
|
2019-11-16 01:34:18 +00:00
|
|
|
|
pb.BackgroundImage = SpriteUtil.Spriter.Drag;
|
2019-08-21 02:50:28 +00:00
|
|
|
|
|
2017-05-23 04:55:05 +00:00
|
|
|
|
// Thread Blocks on DoDragDrop
|
2019-08-21 02:50:28 +00:00
|
|
|
|
Drag.Info.CurrentPath = newfile;
|
|
|
|
|
var result = pb.DoDragDrop(new DataObject(DataFormats.FileDrop, new[] { newfile }), DragDropEffects.Move);
|
2019-11-23 06:22:25 +00:00
|
|
|
|
var external = Drag.Info.Destination == null || result != DragDropEffects.Link;
|
2019-11-24 14:42:41 +00:00
|
|
|
|
if (external || Drag.Info.SameLocation) // not dropped to another box slot, restore img
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
|
|
|
|
pb.Image = img;
|
2019-08-21 02:50:28 +00:00
|
|
|
|
pb.BackgroundImage = LastSlot.OriginalBackground;
|
|
|
|
|
Drag.ResetCursor(pb.FindForm());
|
|
|
|
|
return external;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (result == DragDropEffects.Copy) // viewed in tabs or cloned
|
|
|
|
|
{
|
2019-09-03 02:30:58 +00:00
|
|
|
|
if (Drag.Info.Destination == null) // apply 'view' highlight
|
2020-10-18 18:02:39 +00:00
|
|
|
|
Env.Slots.Get(Drag.Info.Source!.Slot);
|
2019-08-21 02:50:28 +00:00
|
|
|
|
return false;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return true;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-21 02:50:28 +00:00
|
|
|
|
private void HandleDropPKM(PictureBox pb, DragEventArgs e, DropModifier mod)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
2020-10-18 18:02:39 +00:00
|
|
|
|
var files = (string[]?)e.Data.GetData(DataFormats.FileDrop);
|
2020-06-17 02:53:24 +00:00
|
|
|
|
if (files == null)
|
|
|
|
|
{
|
|
|
|
|
Drag.Reset();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-21 02:50:28 +00:00
|
|
|
|
if (Directory.Exists(files[0])) // folder
|
|
|
|
|
{
|
|
|
|
|
SE.LoadBoxes(out string _, files[0]);
|
2019-09-23 22:13:22 +00:00
|
|
|
|
Drag.Reset();
|
2019-08-21 02:50:28 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
e.Effect = mod == DropModifier.Clone ? DragDropEffects.Copy : DragDropEffects.Link;
|
|
|
|
|
|
|
|
|
|
// file
|
2019-09-03 02:30:58 +00:00
|
|
|
|
if (Drag.Info.SameLocation)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
|
|
|
|
e.Effect = DragDropEffects.Link;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-08-21 02:50:28 +00:00
|
|
|
|
|
|
|
|
|
var dest = Drag.Info.Destination;
|
|
|
|
|
|
2019-09-03 02:30:58 +00:00
|
|
|
|
if (Drag.Info.Source == null) // external source
|
2017-05-24 01:35:32 +00:00
|
|
|
|
{
|
2020-10-18 18:02:39 +00:00
|
|
|
|
bool badDest = !dest!.CanWriteTo();
|
2019-08-21 02:50:28 +00:00
|
|
|
|
if (!TryLoadFiles(files, e, badDest))
|
2019-09-03 02:30:58 +00:00
|
|
|
|
WinFormsUtil.Alert(MessageStrings.MsgSaveSlotBadData);
|
2017-06-22 03:24:42 +00:00
|
|
|
|
}
|
2019-09-03 02:30:58 +00:00
|
|
|
|
else if (!TrySetPKMDestination(pb, mod))
|
2017-06-22 03:24:42 +00:00
|
|
|
|
{
|
2019-09-03 02:30:58 +00:00
|
|
|
|
WinFormsUtil.Alert(MessageStrings.MsgSaveSlotEmpty);
|
2017-05-24 01:35:32 +00:00
|
|
|
|
}
|
2019-09-03 02:30:58 +00:00
|
|
|
|
Drag.Reset();
|
2017-06-22 03:24:42 +00:00
|
|
|
|
}
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2019-08-21 02:50:28 +00:00
|
|
|
|
/// <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)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
2018-09-16 19:44:00 +00:00
|
|
|
|
if (files.Count == 0)
|
2017-07-11 01:57:03 +00:00
|
|
|
|
return false;
|
2018-09-16 19:44:00 +00:00
|
|
|
|
|
2020-10-18 18:02:39 +00:00
|
|
|
|
var sav = Drag.Info.Destination!.View.SAV;
|
2019-08-21 02:50:28 +00:00
|
|
|
|
var path = files[0];
|
|
|
|
|
var temp = FileUtil.GetSingleFromPath(path, sav);
|
2018-09-16 19:44:00 +00:00
|
|
|
|
if (temp == null)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
2019-08-21 02:50:28 +00:00
|
|
|
|
Drag.RequestDD(this, e); // pass thru
|
2018-05-25 02:05:13 +00:00
|
|
|
|
return true; // treat as handled
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-10-18 18:02:39 +00:00
|
|
|
|
var pk = PKMConverter.ConvertToType(temp, sav.PKMType, out string c);
|
2017-05-23 04:55:05 +00:00
|
|
|
|
if (pk == null)
|
|
|
|
|
{
|
|
|
|
|
WinFormsUtil.Error(c);
|
2017-07-02 02:43:51 +00:00
|
|
|
|
Debug.WriteLine(c);
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return false;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-21 02:50:28 +00:00
|
|
|
|
if (badDest && (pk.Species == 0 || pk.IsEgg))
|
2017-06-22 03:24:42 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
2020-10-04 21:42:48 +00:00
|
|
|
|
if (sav is ILangDeviantSave il && PKMConverter.IsIncompatibleGB(temp, il.Japanese, pk.Japanese))
|
2018-07-24 22:49:00 +00:00
|
|
|
|
{
|
2019-07-14 22:06:45 +00:00
|
|
|
|
c = PKMConverter.GetIncompatibleGBMessage(pk, il.Japanese);
|
2018-07-24 22:49:00 +00:00
|
|
|
|
WinFormsUtil.Error(c);
|
|
|
|
|
Debug.WriteLine(c);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-21 02:50:28 +00:00
|
|
|
|
var errata = sav.IsPKMCompatible(pk);
|
2018-07-21 04:32:33 +00:00
|
|
|
|
if (errata.Count > 0)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
|
|
|
|
string concat = string.Join(Environment.NewLine, errata);
|
2018-12-17 19:17:19 +00:00
|
|
|
|
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, concat, MessageStrings.MsgContinue))
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
2017-07-02 02:43:51 +00:00
|
|
|
|
Debug.WriteLine(c);
|
|
|
|
|
Debug.WriteLine(concat);
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return false;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-18 18:02:39 +00:00
|
|
|
|
Env.Slots.Set(Drag.Info.Destination!.Slot, pk);
|
2017-07-02 02:43:51 +00:00
|
|
|
|
Debug.WriteLine(c);
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return true;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2019-09-03 02:30:58 +00:00
|
|
|
|
private bool TrySetPKMDestination(PictureBox pb, DropModifier mod)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
2020-10-18 18:02:39 +00:00
|
|
|
|
var pk = Drag.Info.Source!.ReadCurrent();
|
|
|
|
|
var msg = Drag.Info.Destination!.CanWriteTo(pk);
|
2019-09-03 02:30:58 +00:00
|
|
|
|
if (msg != WriteBlockedMessage.None)
|
2017-06-22 03:24:42 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
2019-09-03 02:30:58 +00:00
|
|
|
|
if (Drag.Info.Source != null)
|
2019-08-21 02:50:28 +00:00
|
|
|
|
TrySetPKMSource(pb, mod);
|
2017-05-23 04:55:05 +00:00
|
|
|
|
|
|
|
|
|
// Copy from temp to destination slot.
|
2020-10-18 18:02:39 +00:00
|
|
|
|
Env.Slots.Set(Drag.Info.Destination!.Slot, pk);
|
2019-08-21 02:50:28 +00:00
|
|
|
|
Drag.ResetCursor(pb.FindForm());
|
2017-06-22 03:24:42 +00:00
|
|
|
|
return true;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2019-08-21 02:50:28 +00:00
|
|
|
|
private bool TrySetPKMSource(PictureBox sender, DropModifier mod)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
2019-09-03 02:30:58 +00:00
|
|
|
|
if (Drag.Info.Destination == null || mod == DropModifier.Clone)
|
2019-08-21 02:50:28 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
2019-09-03 02:30:58 +00:00
|
|
|
|
if (sender.Image == null || mod == DropModifier.Overwrite)
|
2017-05-23 04:55:05 +00:00
|
|
|
|
{
|
2020-10-18 18:02:39 +00:00
|
|
|
|
Env.Slots.Delete(Drag.Info.Source!.Slot);
|
2019-09-03 02:30:58 +00:00
|
|
|
|
return true;
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-09-04 02:54:41 +00:00
|
|
|
|
var pk = Drag.Info.Destination.ReadCurrent();
|
2020-10-18 18:02:39 +00:00
|
|
|
|
Env.Slots.Set(Drag.Info.Source!.Slot, pk);
|
2019-09-03 02:30:58 +00:00
|
|
|
|
return true;
|
2017-06-18 01:37:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-01-24 06:37:55 +00:00
|
|
|
|
// Utility
|
2019-09-04 02:54:41 +00:00
|
|
|
|
public void SwapBoxes(int index, int other, SaveFile SAV)
|
2018-01-24 06:37:55 +00:00
|
|
|
|
{
|
|
|
|
|
if (index == other)
|
|
|
|
|
return;
|
|
|
|
|
SAV.SwapBox(index, other);
|
2018-09-16 19:44:00 +00:00
|
|
|
|
UpdateBoxViewAtBoxIndexes(index, other);
|
2018-01-24 06:37:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-06-18 01:37:19 +00:00
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
2019-08-21 02:50:28 +00:00
|
|
|
|
Hover.Dispose();
|
2020-10-18 18:02:39 +00:00
|
|
|
|
SE.Dispose();
|
2019-08-21 02:50:28 +00:00
|
|
|
|
LastSlot.OriginalBackground?.Dispose();
|
|
|
|
|
LastSlot.CurrentBackground?.Dispose();
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
2018-09-16 19:44:00 +00:00
|
|
|
|
|
|
|
|
|
private void UpdateBoxViewAtBoxIndexes(params int[] boxIndexes)
|
|
|
|
|
{
|
|
|
|
|
foreach (var box in Boxes)
|
|
|
|
|
{
|
|
|
|
|
var current = box.CurrentBox;
|
|
|
|
|
if (!boxIndexes.Contains(current))
|
|
|
|
|
continue;
|
|
|
|
|
box.ResetSlots();
|
|
|
|
|
box.ResetBoxNames(current);
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-05-23 04:55:05 +00:00
|
|
|
|
}
|
|
|
|
|
}
|