mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-04-26 02:29:59 -05:00
* Add slot search to box editor Alt-Click: Clears the current search. Shift-Click: Jump to the next box with a result.
211 lines
6.0 KiB
C#
211 lines
6.0 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 = GetEnumNames();
|
|
|
|
public static string[] GetEnumNames()
|
|
{
|
|
var list = Enum.GetNames<StorageSlotType>();
|
|
foreach (ref var item in list.AsSpan())
|
|
{
|
|
if (item.StartsWith("Fused"))
|
|
item = "Fused";
|
|
}
|
|
return list;
|
|
}
|
|
|
|
public readonly Label[] Labels = new Label[names.Length];
|
|
private readonly List<PictureBox> slots = [];
|
|
private List<SlotInfoMisc> SlotOffsets = [];
|
|
public int SlotCount { get; private set; }
|
|
public SaveFile SAV { get; set; } = null!;
|
|
public bool FlagIllegal { get; set; }
|
|
private Func<PKM, bool>? _searchFilter;
|
|
|
|
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];
|
|
var hideLegality = m is { HideLegality: true };
|
|
var flags = GetFlags(pk, hideLegality);
|
|
SlotUtil.UpdateSlot(pb, slot, pk, SAV, flags, type);
|
|
}
|
|
|
|
public void ApplyNewFilter(Func<PKM, bool>? filter, bool reload = true)
|
|
{
|
|
_searchFilter = filter;
|
|
if (reload)
|
|
ResetSlots();
|
|
}
|
|
|
|
private void ResetSlots()
|
|
{
|
|
for (int i = 0; i < SlotOffsets.Count; i++)
|
|
{
|
|
var info = SlotOffsets[i];
|
|
var pb = slots[i];
|
|
var hideLegality = info is { HideLegality: true };
|
|
var flags = GetFlags(info.Read(SAV), hideLegality);
|
|
var type = SlotTouchType.None;
|
|
SlotUtil.UpdateSlot(pb, info, info.Read(SAV), SAV, flags, type);
|
|
}
|
|
}
|
|
|
|
private SlotVisibilityType GetFlags(PKM pk, bool ignoreLegality = false)
|
|
{
|
|
var result = SlotVisibilityType.None;
|
|
if (FlagIllegal && !ignoreLegality)
|
|
result |= SlotVisibilityType.CheckLegalityIndicate;
|
|
if (_searchFilter != null && !_searchFilter(pk))
|
|
result |= SlotVisibilityType.FilterMismatch;
|
|
return result;
|
|
}
|
|
|
|
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)
|
|
{
|
|
if (!WinFormsUtil.TryGetUnderlying<PictureBox>(sender, out var view))
|
|
return -1;
|
|
return slots.IndexOf(view);
|
|
}
|
|
|
|
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 = string.Empty;
|
|
int added = -1;
|
|
for (int i = 0; i < countTotal; i++)
|
|
{
|
|
var info = SlotOffsets[i];
|
|
var label = Labels[(int)info.Type];
|
|
if (label.Text != type)
|
|
{
|
|
added++;
|
|
type = label.Text;
|
|
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 name = $"bpkm{before + i}";
|
|
var slot = GetPictureBox(SpriteUtil.Spriter, name);
|
|
enableDragDropContext(slot);
|
|
slots.Add(slot);
|
|
}
|
|
}
|
|
|
|
private const int PadPixels = 2;
|
|
|
|
private static SelectablePictureBox GetPictureBox(SpriteBuilder s, string name) => 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 = name,
|
|
AccessibleName = name,
|
|
AccessibleRole = AccessibleRole.Graphic,
|
|
};
|
|
|
|
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,
|
|
};
|
|
}
|
|
}
|
|
}
|