diff --git a/PKHeX.Core/PKM/Editing/CommonEdits.cs b/PKHeX.Core/Editing/CommonEdits.cs similarity index 100% rename from PKHeX.Core/PKM/Editing/CommonEdits.cs rename to PKHeX.Core/Editing/CommonEdits.cs diff --git a/PKHeX.Core/PKM/Editing/HiddenPower.cs b/PKHeX.Core/Editing/HiddenPower.cs similarity index 100% rename from PKHeX.Core/PKM/Editing/HiddenPower.cs rename to PKHeX.Core/Editing/HiddenPower.cs diff --git a/PKHeX.Core/Editing/IPKMView.cs b/PKHeX.Core/Editing/IPKMView.cs new file mode 100644 index 000000000..44ed4d0a7 --- /dev/null +++ b/PKHeX.Core/Editing/IPKMView.cs @@ -0,0 +1,48 @@ +namespace PKHeX.Core +{ + /// + /// Simple interface representing a viewer. + /// + public interface IPKMView + { + /// + /// Fetches the currently loaded data from the viewer. + /// + PKM Data { get; } + + /// + /// Indicates if the Viewer supports using Unicode characters or not. + /// + bool Unicode { get; } + + /// + /// Indicates if the Viewer's controls have been fully initialized after a reload. + /// + bool FieldsInitialized { get; } + + /// + /// Indicates if the Viewer is providing extra flexibility or not. + /// + bool HaX { get; } + + /// + /// Indicates if the Viewer's controls are changing their values and should avoid triggering other updates. + /// + bool ChangingFields { get; set; } + + /// + /// Fetches the currently loaded data from the viewer by finishing any pending changes or auto-modifications. + /// + /// Cause the viewer to do extra actions to force validation of its children. + /// Prepared data from the viewer. + PKM PreparePKM(bool click = true); + + /// + /// Loads a given data to the viewer. + /// + /// Pokémon data to load. + /// Cause the viewer to give focus to itself. + /// Cause the viewer to skip converting the data. Faster if it is known that the format is the same as the previous format. + void PopulateFields(PKM pk, bool focus = true, bool skipConversionCheck = false); + } +} diff --git a/PKHeX.Core/Editing/IPlugin.cs b/PKHeX.Core/Editing/IPlugin.cs new file mode 100644 index 000000000..c3349d7f9 --- /dev/null +++ b/PKHeX.Core/Editing/IPlugin.cs @@ -0,0 +1,10 @@ +namespace PKHeX.Core +{ + public interface IPlugin + { + string Name { get; } + void Initialize(params object[] args); + void NotifySaveLoaded(); + ISaveFileProvider SaveFileEditor { get; } + } +} diff --git a/PKHeX.Core/Editing/ISaveFileProvider.cs b/PKHeX.Core/Editing/ISaveFileProvider.cs new file mode 100644 index 000000000..83c527817 --- /dev/null +++ b/PKHeX.Core/Editing/ISaveFileProvider.cs @@ -0,0 +1,23 @@ +namespace PKHeX.Core +{ + /// + /// Simple interface representing a Save File viewer. + /// + public interface ISaveFileProvider + { + /// + /// Retrieves the save file the has control over. + /// + SaveFile SAV { get; } + + /// + /// Retrieves the current box the has control over. + /// + int CurrentBox { get; } + + /// + /// Triggers a refresh of any individual view slots. + /// + void ReloadSlots(); + } +} diff --git a/PKHeX.WinForms/Controls/PKM Editor/IMainEditor.cs b/PKHeX.WinForms/Controls/PKM Editor/IMainEditor.cs index 716d1b8e9..265ad855d 100644 --- a/PKHeX.WinForms/Controls/PKM Editor/IMainEditor.cs +++ b/PKHeX.WinForms/Controls/PKM Editor/IMainEditor.cs @@ -2,15 +2,9 @@ namespace PKHeX.WinForms.Controls { - public interface IMainEditor + public interface IMainEditor : IPKMView { - bool Unicode { get; } - bool FieldsInitialized { get; } - bool ChangingFields { get; set; } - bool HaX { get; } - - PKM pkm { get; } - void UpdateIVsGB(bool skipForm); + PKM pkm { get; } } } \ No newline at end of file diff --git a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs index fa2c1280d..87751c3ae 100644 --- a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs +++ b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs @@ -62,6 +62,7 @@ private void SavePartyStats(PKM pk) public bool HaX { get; set; } public byte[] LastData { private get; set; } + public PKM Data { get => pkm; set => pkm = value; } public PKM pkm { get; private set; } public bool FieldsInitialized { get; private set; } public bool FieldsLoaded { get; private set; } diff --git a/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs b/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs index 96a25f996..ed690997e 100644 --- a/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs +++ b/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs @@ -13,9 +13,10 @@ namespace PKHeX.WinForms.Controls { - public partial class SAVEditor : UserControl, ISlotViewer + public partial class SAVEditor : UserControl, ISlotViewer, ISaveFileProvider { - public SaveFile SAV; + public SaveFile SAV { get; set; } + public int CurrentBox => Box.CurrentBox; public SlotChangeManager M { get; } public readonly Stack UndoStack = new Stack(); public readonly Stack RedoStack = new Stack(); diff --git a/PKHeX.WinForms/MainWindow/Main.cs b/PKHeX.WinForms/MainWindow/Main.cs index df719d9c3..8ad4817cf 100644 --- a/PKHeX.WinForms/MainWindow/Main.cs +++ b/PKHeX.WinForms/MainWindow/Main.cs @@ -83,6 +83,7 @@ private set "中文", // CHN "Português", // Portuguese }; + private static readonly List Plugins = new List(); #endregion #region Path Variables @@ -92,6 +93,7 @@ private set public static string MGDatabasePath => Path.Combine(WorkingDirectory, "mgdb"); public static string BackupPath => Path.Combine(WorkingDirectory, "bak"); private static string TemplatePath => Path.Combine(WorkingDirectory, "template"); + private static string PluginPath => Path.Combine(WorkingDirectory, "plugins"); private const string ThreadPath = "https://projectpokemon.org/pkhex/"; private const string VersionPath = "https://raw.githubusercontent.com/kwsch/PKHeX/master/PKHeX.WinForms/Resources/text/version.txt"; @@ -125,6 +127,8 @@ private void FormLoadInitialSettings(string[] args, out bool showChangelog, out WinFormsUtil.Error(MsgSettingsLoadFail, e); } + FormLoadPlugins(); + PKME_Tabs.InitializeFields(); PKME_Tabs.TemplateFields(LoadTemplate(C_SAV.SAV)); } @@ -246,6 +250,14 @@ private void FormLoadConfig(out bool BAKprompt, out bool showChangelog) Settings.Version = Resources.ProgramVersion; } + private void FormLoadPlugins() + { + if (!Directory.Exists(PluginPath)) + return; + Plugins.AddRange(PluginLoader.LoadPlugins(PluginPath)); + foreach (var p in Plugins) + p.Initialize(C_SAV, PKME_Tabs, menuStrip1); + } private static void DeleteConfig(string settingsFilename) { var dr = WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MsgSettingsResetCorrupt, MsgSettingsResetPrompt); @@ -746,6 +758,8 @@ private void ResetSAVPKMEditors(SaveFile sav) PKME_Tabs.FlickerInterface(); PKME_Tabs.TemplateFields(LoadTemplate(sav)); + foreach (var p in Plugins) + p.NotifySaveLoaded(); sav.Edited = false; } private static string GetProgramTitle() diff --git a/PKHeX.WinForms/MainWindow/PluginLoader.cs b/PKHeX.WinForms/MainWindow/PluginLoader.cs new file mode 100644 index 000000000..409faad1a --- /dev/null +++ b/PKHeX.WinForms/MainWindow/PluginLoader.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; + +namespace PKHeX.WinForms +{ + public static class PluginLoader + { + public static IEnumerable LoadPlugins(string pluginPath) + { + var dllFileNames = Directory.EnumerateFiles(pluginPath, "*.dll", SearchOption.AllDirectories); + var assemblies = GetAssemblies(dllFileNames); + var pluginTypes = GetPluginsOfType(assemblies); + return LoadPlugins(pluginTypes); + } + private static IEnumerable LoadPlugins(IEnumerable pluginTypes) + { + return pluginTypes.Select(type => (T)Activator.CreateInstance(type)); + } + private static IEnumerable GetAssemblies(IEnumerable dllFileNames) + { + return dllFileNames.Select(AssemblyName.GetAssemblyName).Select(Assembly.Load); + } + private static IEnumerable GetPluginsOfType(IEnumerable assemblies) + { + var pluginType = typeof(T); + foreach (var type in assemblies.Where(z => z != null).SelectMany(a => a.GetTypes())) + { + if (type.IsInterface || type.IsAbstract) + continue; + if (type.GetInterface(pluginType.FullName) == null) + continue; + yield return type; + } + } + } +} diff --git a/PKHeX.WinForms/PKHeX.WinForms.csproj b/PKHeX.WinForms/PKHeX.WinForms.csproj index 7742a7720..2b0db0bd4 100644 --- a/PKHeX.WinForms/PKHeX.WinForms.csproj +++ b/PKHeX.WinForms/PKHeX.WinForms.csproj @@ -245,6 +245,7 @@ PKMEditor.cs + Form