PKHeX/PKHeX.WinForms/Controls/SAV Editor/ContextMenuSAV.cs
Kurt 1ca9180e21
use SlotList view to dynamically show slots (#1798)
Closes #1795 by redoing the controls

Allows for a specified slot type & offset to be passed, can easily add extra slots by updating the GetExtraSlots extension method.
2018-01-30 18:52:55 -08:00

209 lines
7.5 KiB
C#

using System;
using System.ComponentModel;
using System.Windows.Forms;
using PKHeX.Core;
using PKHeX.WinForms.Properties;
namespace PKHeX.WinForms.Controls
{
public partial class ContextMenuSAV : UserControl
{
public ContextMenuSAV()
{
InitializeComponent();
}
public event LegalityRequest RequestEditorLegality;
public delegate void LegalityRequest(object sender, EventArgs e, PKM pkm);
public void OmniClick(object sender, EventArgs e, Keys z)
{
switch (z)
{
case Keys.Control: ClickView(sender, e); break;
case Keys.Shift: ClickSet(sender, e); break;
case Keys.Alt: ClickDelete(sender, e); break;
}
}
private static void ClickView(object sender, EventArgs e)
{
SlotChangeManager m = GetSenderInfo(ref sender, out SlotChange info);
if (m == null)
return;
if ((sender as PictureBox)?.Image == null)
{ System.Media.SystemSounds.Asterisk.Play(); return; }
m.SE.PKME_Tabs.PopulateFields(m.GetPKM(info), false, true);
m.SetColor(info.Box, info.Slot, Resources.slotView);
}
private static void ClickSet(object sender, EventArgs e)
{
SlotChangeManager m = GetSenderInfo(ref sender, out SlotChange info);
if (m == null)
return;
var editor = m.SE.PKME_Tabs;
var sav = m.SE.SAV;
if (info.IsParty && editor.IsEmptyOrEgg && sav.IsPartyAllEggs(info.Slot - 30) && !m.SE.HaX)
{ WinFormsUtil.Alert("Can't have empty/egg party."); return; }
if (m.SE.SAV.IsSlotLocked(info.Box, info.Slot))
{ WinFormsUtil.Alert("Can't set to locked slot."); return; }
if (!editor.VerifiedPKM())
return;
PKM pk = editor.PreparePKM();
string[] errata = sav.IsPKMCompatible(pk);
if (errata.Length > 0 && DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, string.Join(Environment.NewLine, errata), "Continue?"))
return;
if (info.Slot >= 30)
info.Box = -1;
if (info.Slot >= 30 && info.Slot < 36) // Party
{
// If info.Slot isn't overwriting existing PKM, make it write to the lowest empty PKM info.Slot
if (sav.PartyCount < info.Slot + 1 - 30)
{
info.Slot = sav.PartyCount + 30;
info.Offset = m.SE.GetPKMOffset(info.Slot);
}
m.SetPKM(pk, info, true, Resources.slotSet);
}
else if (info.Slot < 30 || m.SE.HaX)
{
if (info.Slot < 30)
{
m.SE.UndoStack.Push(new SlotChange
{
Box = info.Box,
Slot = info.Slot,
Offset = info.Offset,
PKM = sav.GetStoredSlot(info.Offset)
});
m.SE.Menu_Undo.Enabled = true;
}
m.SetPKM(pk, info, true, Resources.slotSet);
}
else
return;
editor.LastData = pk.Data;
m.SE.RedoStack.Clear(); m.SE.Menu_Redo.Enabled = false;
}
private static void ClickDelete(object sender, EventArgs e)
{
SlotChangeManager m = GetSenderInfo(ref sender, out SlotChange info);
if (m == null)
return;
if ((sender as PictureBox)?.Image == null)
{ System.Media.SystemSounds.Asterisk.Play(); return; }
var sav = m.SE.SAV;
if (info.IsParty && sav.IsPartyAllEggs(info.Slot - 30) && !m.SE.HaX)
{ WinFormsUtil.Alert("Can't delete this slot."); return; }
if (sav.IsSlotLocked(info.Box, info.Slot))
{ WinFormsUtil.Alert("Can't delete locked slot."); return; }
if (info.Slot >= 30 && info.Slot < 36) // Party
{
m.SetPKM(sav.BlankPKM, info, true, Resources.slotDel);
return;
}
if (info.Slot < 30 || m.SE.HaX)
{
if (info.Slot < 30)
{
m.SE.UndoStack.Push(new SlotChange
{
Box = info.Box,
Slot = info.Slot,
Offset = info.Offset,
PKM = sav.GetStoredSlot(info.Offset)
});
m.SE.Menu_Undo.Enabled = true;
}
m.SetPKM(sav.BlankPKM, info, true, Resources.slotDel);
}
else return;
m.SE.RedoStack.Clear(); m.SE.Menu_Redo.Enabled = false;
}
private void ClickShowLegality(object sender, EventArgs e)
{
SlotChangeManager m = GetSenderInfo(ref sender, out SlotChange info);
if (m == null)
return;
var pk = m.GetPKM(info);
RequestEditorLegality?.Invoke(sender, e, pk);
}
private void MenuOpening(object sender, CancelEventArgs e)
{
var items = ((ContextMenuStrip)sender).Items;
object ctrl = ((ContextMenuStrip)sender).SourceControl;
GetSenderInfo(ref ctrl, out SlotChange info);
bool SlotFull = (ctrl as PictureBox)?.Image != null;
bool Editable = info.Slot < 36;
bool legality = ModifierKeys == Keys.Control;
ToggleItem(items, mnuSet, Editable);
ToggleItem(items, mnuDelete, Editable && SlotFull);
ToggleItem(items, mnuLegality, legality && SlotFull && RequestEditorLegality != null);
ToggleItem(items, mnuView, SlotFull || !Editable, true);
if (items.Count == 0)
e.Cancel = true;
}
private static SlotChangeManager GetSenderInfo(ref object sender, out SlotChange loc)
{
loc = new SlotChange();
var ctrl = WinFormsUtil.GetUnderlyingControl(sender);
var obj = ctrl.Parent.Parent;
if (obj is BoxEditor b)
{
loc.Box = b.CurrentBox;
loc.Slot = b.GetSlot(sender);
loc.Offset = b.GetOffset(loc.Slot, loc.Box);
loc.Parent = b.FindForm();
sender = ctrl;
return b.M;
}
if (obj is SlotList s)
{
const int shift = 44;
loc.Slot = s.GetSlot(sender) + shift;
loc.Offset = s.GetSlotOffset(loc.Slot - shift);
loc.Parent = s.FindForm();
sender = ctrl;
return s.M;
}
obj = obj.Parent.Parent;
if (obj is SAVEditor z)
{
loc.Box = z.Box.CurrentBox;
loc.Slot = z.GetSlot(sender);
loc.Offset = z.GetPKMOffset(loc.Slot, loc.Box);
loc.Parent = z.FindForm();
sender = ctrl;
return z.M;
}
return null;
}
private static void ToggleItem(ToolStripItemCollection items, ToolStripItem item, bool visible, bool first = false)
{
if (visible)
{
if (first)
items.Insert(0, item);
else
items.Add(item);
}
else if (items.Contains(item))
items.Remove(item);
}
}
}