mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-24 04:53:08 +00:00
6ddcdee9cf
Refresh the image if the team slot indication needs updating (true->false, false->true), else stay lazy and just set the image. Could just refresh the image regardless but muh negligible speed
348 lines
14 KiB
C#
348 lines
14 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Windows.Forms;
|
|
using PKHeX.Core;
|
|
using static PKHeX.WinForms.Main;
|
|
|
|
namespace PKHeX.WinForms
|
|
{
|
|
public partial class SAV_BoxViewer : Form
|
|
{
|
|
public SAV_BoxViewer(Main p)
|
|
{
|
|
InitializeComponent();
|
|
parent = p;
|
|
CenterToParent();
|
|
|
|
AllowDrop = true;
|
|
DragEnter += tabMain_DragEnter;
|
|
DragDrop += (sender, e) =>
|
|
{
|
|
Cursor = DefaultCursor;
|
|
System.Media.SystemSounds.Asterisk.Play();
|
|
};
|
|
|
|
SlotPictureBoxes = new[] {
|
|
bpkx1, bpkx2, bpkx3, bpkx4, bpkx5, bpkx6,
|
|
bpkx7, bpkx8, bpkx9, bpkx10,bpkx11,bpkx12,
|
|
bpkx13,bpkx14,bpkx15,bpkx16,bpkx17,bpkx18,
|
|
bpkx19,bpkx20,bpkx21,bpkx22,bpkx23,bpkx24,
|
|
bpkx25,bpkx26,bpkx27,bpkx28,bpkx29,bpkx30,
|
|
};
|
|
foreach (PictureBox pb in SlotPictureBoxes)
|
|
{
|
|
pb.AllowDrop = true;
|
|
pb.GiveFeedback += (sender, e) => { e.UseDefaultCursors = false; };
|
|
pb.MouseUp += pbBoxSlot_MouseUp;
|
|
pb.MouseDown += pbBoxSlot_MouseDown;
|
|
pb.MouseMove += pbBoxSlot_MouseMove;
|
|
pb.DragDrop += pbBoxSlot_DragDrop;
|
|
pb.DragEnter += pbBoxSlot_DragEnter;
|
|
pb.QueryContinueDrag += pbBoxSlot_QueryContinueDrag;
|
|
}
|
|
for (int i = SAV.BoxSlotCount; i < SlotPictureBoxes.Length; i++)
|
|
SlotPictureBoxes[i].Visible = false;
|
|
|
|
try
|
|
{
|
|
CB_BoxSelect.Items.Clear();
|
|
for (int i = 0; i < SAV.BoxCount; i++)
|
|
CB_BoxSelect.Items.Add(SAV.getBoxName(i));
|
|
}
|
|
catch
|
|
{
|
|
CB_BoxSelect.Items.Clear();
|
|
for (int i = 1; i <= SAV.BoxCount; i++)
|
|
CB_BoxSelect.Items.Add($"BOX {i}");
|
|
}
|
|
CB_BoxSelect.SelectedIndex = 0;
|
|
}
|
|
private readonly Main parent;
|
|
private readonly PictureBox[] SlotPictureBoxes;
|
|
public int CurrentBox => CB_BoxSelect.SelectedIndex;
|
|
|
|
private void CB_BoxSelect_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
setPKXBoxes();
|
|
}
|
|
private void clickBoxRight(object sender, EventArgs e)
|
|
{
|
|
CB_BoxSelect.SelectedIndex = (CB_BoxSelect.SelectedIndex + 1) % SAV.BoxCount;
|
|
}
|
|
private void clickBoxLeft(object sender, EventArgs e)
|
|
{
|
|
CB_BoxSelect.SelectedIndex = (CB_BoxSelect.SelectedIndex + SAV.BoxCount - 1) % SAV.BoxCount;
|
|
}
|
|
private void PB_BoxSwap_Click(object sender, EventArgs e)
|
|
{
|
|
CB_BoxSelect.SelectedIndex = parent.swapBoxesViewer(CB_BoxSelect.SelectedIndex);
|
|
}
|
|
|
|
// Copied Methods from Main.cs (slightly modified)
|
|
private int getPKXOffset(int slot)
|
|
{
|
|
return SAV.getBoxOffset(CB_BoxSelect.SelectedIndex) + slot * SAV.SIZE_STORED;
|
|
}
|
|
public void setPKXBoxes()
|
|
{
|
|
int boxoffset = SAV.getBoxOffset(CB_BoxSelect.SelectedIndex);
|
|
int boxbgval = SAV.getBoxWallpaper(CB_BoxSelect.SelectedIndex);
|
|
PAN_Box.BackgroundImage = SAV.WallpaperImage(boxbgval);
|
|
|
|
for (int i = 0; i < SAV.BoxSlotCount; i++)
|
|
getSlotFiller(boxoffset + SAV.SIZE_STORED*i, SlotPictureBoxes[i]);
|
|
}
|
|
private void getSlotFiller(int offset, PictureBox pb)
|
|
{
|
|
if (SAV.getData(offset, SAV.SIZE_STORED).SequenceEqual(new byte[SAV.SIZE_STORED]))
|
|
{
|
|
// 00s present in slot.
|
|
pb.Image = null;
|
|
pb.BackColor = Color.Transparent;
|
|
return;
|
|
}
|
|
PKM p = SAV.getStoredSlot(offset);
|
|
if (!p.Valid) // Invalid
|
|
{
|
|
// Bad Egg present in slot.
|
|
pb.Image = null;
|
|
pb.BackColor = Color.Red;
|
|
return;
|
|
}
|
|
|
|
int slot = getSlot(pb);
|
|
pb.Image = p.Sprite(SAV, CB_BoxSelect.SelectedIndex, slot, parent.Menu_FlagIllegal.Checked);
|
|
pb.BackColor = Color.Transparent;
|
|
pb.Visible = true;
|
|
}
|
|
private void getQuickFiller(PictureBox pb, PKM pk)
|
|
{
|
|
int slot = getSlot(pb);
|
|
pb.Image = pk.Sprite(SAV, CB_BoxSelect.SelectedIndex, slot, parent.Menu_FlagIllegal.Checked);
|
|
if (pb.BackColor == Color.Red)
|
|
pb.BackColor = Color.Transparent;
|
|
}
|
|
private int getSlot(object sender)
|
|
{
|
|
sender = ((sender as ToolStripItem)?.Owner as ContextMenuStrip)?.SourceControl ?? sender as PictureBox;
|
|
return Array.IndexOf(SlotPictureBoxes, sender);
|
|
}
|
|
|
|
// Drag and drop related functions
|
|
private void pbBoxSlot_MouseUp(object sender, MouseEventArgs e)
|
|
{
|
|
if (e.Button == MouseButtons.Left)
|
|
DragInfo.slotLeftMouseIsDown = false;
|
|
if (e.Button == MouseButtons.Right)
|
|
DragInfo.slotRightMouseIsDown = false;
|
|
}
|
|
private void pbBoxSlot_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
if (e.Button == MouseButtons.Left)
|
|
DragInfo.slotLeftMouseIsDown = true;
|
|
if (e.Button == MouseButtons.Right)
|
|
DragInfo.slotRightMouseIsDown = true;
|
|
}
|
|
private void pbBoxSlot_MouseMove(object sender, MouseEventArgs e)
|
|
{
|
|
if (DragInfo.slotDragDropInProgress)
|
|
return;
|
|
|
|
if (!DragInfo.slotLeftMouseIsDown)
|
|
return;
|
|
|
|
// The goal is to create a temporary PKX file for the underlying Pokemon
|
|
// and use that file to perform a drag drop operation.
|
|
|
|
// Abort if there is no Pokemon in the given slot.
|
|
PictureBox pb = (PictureBox)sender;
|
|
if (pb.Image == null)
|
|
return;
|
|
|
|
int slot = getSlot(pb);
|
|
int box = slot >= 30 ? -1 : CB_BoxSelect.SelectedIndex;
|
|
if (SAV.getIsSlotLocked(box, slot))
|
|
return;
|
|
|
|
// Set flag to prevent re-entering.
|
|
DragInfo.slotDragDropInProgress = true;
|
|
|
|
DragInfo.slotSource = this;
|
|
DragInfo.slotSourceSlotNumber = slot;
|
|
DragInfo.slotSourceBoxNumber = box;
|
|
DragInfo.slotSourceOffset = getPKXOffset(DragInfo.slotSourceSlotNumber);
|
|
|
|
// Prepare Data
|
|
DragInfo.slotPkmSource = SAV.getData(DragInfo.slotSourceOffset, SAV.SIZE_STORED);
|
|
|
|
// Make a new file name based off the PID
|
|
byte[] dragdata = SAV.decryptPKM(DragInfo.slotPkmSource);
|
|
Array.Resize(ref dragdata, SAV.SIZE_STORED);
|
|
PKM pkx = SAV.getPKM(dragdata);
|
|
string filename = pkx.FileName;
|
|
|
|
// Make File
|
|
string newfile = Path.Combine(Path.GetTempPath(), Util.CleanFileName(filename));
|
|
try
|
|
{
|
|
File.WriteAllBytes(newfile, dragdata);
|
|
var img = (Bitmap)pb.Image;
|
|
DragInfo.Cursor = Cursor.Current = new Cursor(img.GetHicon());
|
|
pb.Image = null;
|
|
pb.BackgroundImage = Core.Properties.Resources.slotDrag;
|
|
// Thread Blocks on DoDragDrop
|
|
DragInfo.CurrentPath = newfile;
|
|
DragDropEffects result = pb.DoDragDrop(new DataObject(DataFormats.FileDrop, new[] { newfile }), DragDropEffects.Move);
|
|
if (!DragInfo.SourceValid || result != DragDropEffects.Link) // not dropped to another box slot, restore img
|
|
pb.Image = img;
|
|
else // refresh image
|
|
getQuickFiller(pb, SAV.getStoredSlot(DragInfo.slotSourceOffset));
|
|
pb.BackgroundImage = null;
|
|
|
|
if (DragInfo.SameBox && DragInfo.DestinationValid)
|
|
{
|
|
if (SAV.getIsTeamSet(box, DragInfo.slotDestinationSlotNumber) ^ SAV.getIsTeamSet(box, DragInfo.slotSourceSlotNumber))
|
|
getQuickFiller(SlotPictureBoxes[DragInfo.slotDestinationSlotNumber], SAV.getStoredSlot(DragInfo.slotDestinationOffset));
|
|
else
|
|
SlotPictureBoxes[DragInfo.slotDestinationSlotNumber].Image = img;
|
|
}
|
|
}
|
|
catch (Exception x)
|
|
{
|
|
WinFormsUtil.Error("Drag & Drop Error", x);
|
|
}
|
|
parent.notifyBoxViewerRefresh();
|
|
DragInfo.Reset();
|
|
Cursor = DefaultCursor;
|
|
|
|
// 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?
|
|
new Thread(() =>
|
|
{
|
|
Thread.Sleep(500);
|
|
if (File.Exists(newfile) && DragInfo.CurrentPath == null)
|
|
File.Delete(newfile);
|
|
}).Start();
|
|
}
|
|
private void pbBoxSlot_DragDrop(object sender, DragEventArgs e)
|
|
{
|
|
DragInfo.slotDestination = this;
|
|
DragInfo.slotDestinationSlotNumber = getSlot(sender);
|
|
DragInfo.slotDestinationOffset = getPKXOffset(DragInfo.slotDestinationSlotNumber);
|
|
DragInfo.slotDestinationBoxNumber = CB_BoxSelect.SelectedIndex;
|
|
|
|
// Check for In-Dropped files (PKX,SAV,ETC)
|
|
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
|
|
if (Directory.Exists(files[0])) { return; }
|
|
if (SAV.getIsSlotLocked(DragInfo.slotDestinationBoxNumber, DragInfo.slotDestinationSlotNumber))
|
|
{
|
|
DragInfo.slotDestinationSlotNumber = -1; // Invalidate
|
|
WinFormsUtil.Alert("Unable to set to locked slot.");
|
|
return;
|
|
}
|
|
if (DragInfo.slotSourceOffset < 0) // file
|
|
{
|
|
if (files.Length <= 0)
|
|
return;
|
|
string file = files[0];
|
|
FileInfo fi = new FileInfo(file);
|
|
if (!PKX.getIsPKM(fi.Length) && !MysteryGift.getIsMysteryGift(fi.Length))
|
|
{ return; }
|
|
|
|
byte[] data = File.ReadAllBytes(file);
|
|
MysteryGift mg = MysteryGift.getMysteryGift(data, fi.Extension);
|
|
PKM temp = mg != null ? mg.convertToPKM(SAV) : PKMConverter.getPKMfromBytes(data, prefer: SAV.Generation);
|
|
string c;
|
|
|
|
PKM pk = PKMConverter.convertToFormat(temp, SAV.PKMType, out c);
|
|
if (pk == null)
|
|
{ WinFormsUtil.Error(c); Console.WriteLine(c); return; }
|
|
|
|
string[] errata = SAV.IsPKMCompatible(pk);
|
|
if (errata.Length > 0)
|
|
{
|
|
string concat = string.Join(Environment.NewLine, errata);
|
|
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, concat, "Continue?"))
|
|
{ Console.WriteLine(c); Console.WriteLine(concat); return; }
|
|
}
|
|
|
|
DragInfo.setPKMtoDestination(SAV, pk);
|
|
getQuickFiller(SlotPictureBoxes[DragInfo.slotDestinationSlotNumber], pk);
|
|
Console.WriteLine(c);
|
|
}
|
|
else
|
|
{
|
|
PKM pkz = DragInfo.getPKMfromSource(SAV);
|
|
if (!DragInfo.SourceValid) { } // not overwritable, do nothing
|
|
else if (ModifierKeys == Keys.Alt && DragInfo.DestinationValid) // overwrite
|
|
{
|
|
// Clear from slot
|
|
if (DragInfo.SameBox)
|
|
getQuickFiller(SlotPictureBoxes[DragInfo.slotSourceSlotNumber], SAV.BlankPKM); // picturebox
|
|
|
|
DragInfo.setPKMtoSource(SAV, SAV.BlankPKM);
|
|
}
|
|
else if (ModifierKeys != Keys.Control && DragInfo.DestinationValid) // move
|
|
{
|
|
// Load data from destination
|
|
PKM pk = ((PictureBox)sender).Image != null
|
|
? DragInfo.getPKMfromDestination(SAV)
|
|
: SAV.BlankPKM;
|
|
|
|
// Set destination pokemon image to source picture box
|
|
if (DragInfo.SameBox)
|
|
getQuickFiller(SlotPictureBoxes[DragInfo.slotSourceSlotNumber], pk);
|
|
|
|
// Set destination pokemon data to source slot
|
|
DragInfo.setPKMtoSource(SAV, pk);
|
|
}
|
|
else if (DragInfo.SameBox) // clone
|
|
getQuickFiller(SlotPictureBoxes[DragInfo.slotSourceSlotNumber], pkz);
|
|
|
|
// Copy from temp to destination slot.
|
|
DragInfo.setPKMtoDestination(SAV, pkz);
|
|
getQuickFiller(SlotPictureBoxes[DragInfo.slotDestinationSlotNumber], pkz);
|
|
|
|
e.Effect = DragDropEffects.Link;
|
|
Cursor = DefaultCursor;
|
|
}
|
|
if (DragInfo.SourceParty || DragInfo.DestinationParty)
|
|
parent.setParty();
|
|
if (DragInfo.slotSource == null) // another instance or file
|
|
{
|
|
parent.notifyBoxViewerRefresh();
|
|
DragInfo.Reset();
|
|
}
|
|
}
|
|
private void pbBoxSlot_DragEnter(object sender, DragEventArgs e)
|
|
{
|
|
if (e.AllowedEffect == (DragDropEffects.Copy | DragDropEffects.Link)) // external file
|
|
e.Effect = DragDropEffects.Copy;
|
|
else if (e.Data != null) // within
|
|
e.Effect = DragDropEffects.Move;
|
|
|
|
if (DragInfo.slotDragDropInProgress)
|
|
Cursor = (Cursor)DragInfo.Cursor;
|
|
}
|
|
private void pbBoxSlot_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
|
|
{
|
|
if (e.Action == DragAction.Cancel || e.Action == DragAction.Drop)
|
|
{
|
|
DragInfo.slotLeftMouseIsDown = false;
|
|
DragInfo.slotRightMouseIsDown = false;
|
|
DragInfo.slotDragDropInProgress = false;
|
|
}
|
|
}
|
|
|
|
private void tabMain_DragEnter(object sender, DragEventArgs e)
|
|
{
|
|
if (e.AllowedEffect == (DragDropEffects.Copy | DragDropEffects.Link)) // external file
|
|
e.Effect = DragDropEffects.Copy;
|
|
else if (e.Data != null) // within
|
|
e.Effect = DragDropEffects.Move;
|
|
}
|
|
}
|
|
}
|