PKHeX/PKHeX.WinForms/Controls/Slots/SlotList.cs
Kurt 88830e0d00
Update from .NET Framework 4.6 to .NET 7 (#3729)
Updates from net46->net7, dropping support for mono in favor of using the latest runtime (along with the performance/API improvements). Releases will be posted as 64bit only for now.

Refactors a good amount of internal API methods to be more performant and more customizable for future updates & fixes.

Adds functionality for Batch Editor commands to `>`, `<` and <=/>=

TID/SID properties renamed to TID16/SID16 for clarity; other properties exposed for Gen7 / display variants.

Main window has a new layout to account for DPI scaling (8 point grid)

Fixed: Tatsugiri and Paldean Tauros now output Showdown form names as Showdown expects
Changed: Gen9 species now interact based on the confirmed National Dex IDs (closes #3724)
Fixed: Pokedex set all no longer clears species with unavailable non-base forms (closes #3720)
Changed: Hyper Training suggestions now apply for level 50 in SV. (closes #3714)
Fixed: B2/W2 hatched egg met locations exclusive to specific versions are now explicitly checked (closes #3691)
Added: Properties for ribbon/mark count (closes #3659)
Fixed: Traded SV eggs are now checked correctly (closes #3692)
2023-01-21 20:02:33 -08:00

164 lines
4.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using PKHeX.Core;
using PKHeX.Drawing.PokeSprite;
namespace PKHeX.WinForms.Controls;
public partial class SlotList : UserControl, ISlotViewer<PictureBox>
{
private static readonly string[] names = Enum.GetNames(typeof(StorageSlotType));
private readonly Label[] Labels = new Label[names.Length];
private readonly List<PictureBox> slots = new();
private List<SlotInfoMisc> SlotOffsets = new();
public int SlotCount { get; private set; }
public SaveFile SAV { get; set; } = null!;
public bool FlagIllegal { get; set; }
public SlotList()
{
InitializeComponent();
AddLabels();
}
/// <summary>
/// Initializes the extra slot viewers with a list of offsets and sets up event handling.
/// </summary>
/// <param name="list">Extra slots to show</param>
/// <param name="enableDragDropContext">Events to set up</param>
/// <remarks>Uses an object pool for viewers (only generates as needed)</remarks>
public void Initialize(List<SlotInfoMisc> list, Action<Control> enableDragDropContext)
{
SlotOffsets = list;
LoadSlots(list.Count, enableDragDropContext);
}
/// <summary>
/// Hides all slots from the <see cref="SlotList"/>.
/// </summary>
public void HideAllSlots() => LoadSlots(0, _ => { });
public void NotifySlotOld(ISlotInfo previous)
{
if (previous is not SlotInfoMisc m)
return;
var index = SlotOffsets.FindIndex(m.Equals);
if (index < 0)
return;
var pb = slots[index];
pb.BackgroundImage = null;
}
public void NotifySlotChanged(ISlotInfo slot, SlotTouchType type, PKM pk)
{
if (slot is not SlotInfoMisc m)
return;
var index = GetViewIndex(m);
if (index < 0)
return;
var pb = slots[index];
SlotUtil.UpdateSlot(pb, slot, pk, SAV, FlagIllegal, type);
}
public int GetViewIndex(ISlotInfo info) => SlotOffsets.FindIndex(info.Equals);
public ISlotInfo GetSlotData(PictureBox view)
{
int slot = GetSlot(view);
return GetSlotData(slot);
}
public ISlotInfo GetSlotData(int slot) => SlotOffsets[slot];
public IList<PictureBox> SlotPictureBoxes => slots;
public int GetSlot(PictureBox sender)
{
var view = WinFormsUtil.GetUnderlyingControl<PictureBox>(sender);
if (view == null)
return -1;
return slots.IndexOf(view);
}
public int GetSlotOffset(int slot) => SlotOffsets[slot].Offset;
public int ViewIndex { get; set; } = -1;
private void LoadSlots(int count, Action<Control> enableDragDropContext)
{
var controls = FLP_Slots.Controls;
controls.Clear();
if (count == 0)
{
SlotCount = 0;
return;
}
AddSlots(count, enableDragDropContext);
AddControls(count);
SlotCount = count;
}
private void AddControls(int countTotal)
{
var type = (StorageSlotType)(-1);
int added = -1;
for (int i = 0; i < countTotal; i++)
{
var info = SlotOffsets[i];
if (type != info.Type)
{
added++;
type = info.Type;
var label = Labels[(int)type];
FLP_Slots.Controls.Add(label, 0, added++);
}
var slot = slots[i];
FLP_Slots.Controls.Add(slot, 0, added);
}
}
private void AddSlots(int after, Action<Control> enableDragDropContext)
{
int before = SlotCount;
int diff = after - before;
if (diff <= 0)
return;
for (int i = 0; i < diff; i++)
{
var slot = GetPictureBox(i, SpriteUtil.Spriter);
enableDragDropContext(slot);
slots.Add(slot);
}
}
private const int PadPixels = 2;
private static PictureBox GetPictureBox(int index, SpriteBuilder s) => new()
{
BorderStyle = BorderStyle.FixedSingle,
Width = s.Width + 2,
Height = s.Height + 2,
AllowDrop = true,
Margin = new Padding(PadPixels),
Padding = Padding.Empty,
SizeMode = PictureBoxSizeMode.CenterImage,
Name = $"bpkm{index}",
};
private void AddLabels()
{
for (var i = 0; i < names.Length; i++)
{
var name = names[i];
Labels[i] = new Label
{
Name = $"L_{name}",
Text = name,
AutoSize = true,
Margin = Padding.Empty,
Padding = Padding.Empty,
};
}
}
}