commit 7382a8ed3623bd7013839f560c40a52f25bb754a
Author: meli <57847713+ff-meli@users.noreply.github.com>
Date: Tue Apr 28 13:21:51 2020 -0700
Initial simple sample plugin and associated UI testbed
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7990fe7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+.vs/
+obj/
+bin/
+*.user
\ No newline at end of file
diff --git a/Data/NotoSansCJKjp-Medium.otf b/Data/NotoSansCJKjp-Medium.otf
new file mode 100644
index 0000000..ba41937
Binary files /dev/null and b/Data/NotoSansCJKjp-Medium.otf differ
diff --git a/Data/gamesym.ttf b/Data/gamesym.ttf
new file mode 100644
index 0000000..8bfc546
Binary files /dev/null and b/Data/gamesym.ttf differ
diff --git a/Data/goat.png b/Data/goat.png
new file mode 100644
index 0000000..4ca06ac
Binary files /dev/null and b/Data/goat.png differ
diff --git a/Data/samplePlugin.json b/Data/samplePlugin.json
new file mode 100644
index 0000000..b287019
--- /dev/null
+++ b/Data/samplePlugin.json
@@ -0,0 +1,9 @@
+{
+ "Author": "your name here",
+ "Name": "Sample Plugin",
+ "Description": "A simple description that shows up in /xlplugins. List any major slash-command(s).",
+ "InternalName": "samplePlugin",
+ "AssemblyVersion": "1.0.0.0",
+ "RepoUrl": "https://github.com/yourName/yourRepo",
+ "ApplicableVersion": "any"
+}
diff --git a/SamplePlugin.sln b/SamplePlugin.sln
new file mode 100644
index 0000000..d1e8332
--- /dev/null
+++ b/SamplePlugin.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29709.97
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SamplePlugin", "SamplePlugin\SamplePlugin.csproj", "{13C812E9-0D42-4B95-8646-40EEBF30636F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UIDev", "UIDev\UIDev.csproj", "{4FEC9558-EB25-419F-B86E-51B8CFDA32B7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {13C812E9-0D42-4B95-8646-40EEBF30636F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {13C812E9-0D42-4B95-8646-40EEBF30636F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {13C812E9-0D42-4B95-8646-40EEBF30636F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {13C812E9-0D42-4B95-8646-40EEBF30636F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4FEC9558-EB25-419F-B86E-51B8CFDA32B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4FEC9558-EB25-419F-B86E-51B8CFDA32B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4FEC9558-EB25-419F-B86E-51B8CFDA32B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4FEC9558-EB25-419F-B86E-51B8CFDA32B7}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {B17E85B1-5F60-4440-9F9A-3DDE877E8CDF}
+ EndGlobalSection
+EndGlobal
diff --git a/SamplePlugin/Configuration.cs b/SamplePlugin/Configuration.cs
new file mode 100644
index 0000000..954de16
--- /dev/null
+++ b/SamplePlugin/Configuration.cs
@@ -0,0 +1,29 @@
+using Dalamud.Configuration;
+using Dalamud.Plugin;
+using System;
+
+namespace SamplePlugin
+{
+ [Serializable]
+ public class Configuration : IPluginConfiguration
+ {
+ public int Version { get; set; } = 0;
+
+ public bool SomePropertyToBeSavedAndWithADefault { get; set; } = true;
+
+ // the below exist just to make saving less cumbersome
+
+ [NonSerialized]
+ private DalamudPluginInterface pluginInterface;
+
+ public void Initialize(DalamudPluginInterface pluginInterface)
+ {
+ this.pluginInterface = pluginInterface;
+ }
+
+ public void Save()
+ {
+ this.pluginInterface.SavePluginConfig(this);
+ }
+ }
+}
diff --git a/SamplePlugin/Plugin.cs b/SamplePlugin/Plugin.cs
new file mode 100644
index 0000000..97827b4
--- /dev/null
+++ b/SamplePlugin/Plugin.cs
@@ -0,0 +1,64 @@
+using Dalamud.Game.Command;
+using Dalamud.Plugin;
+using System;
+using System.IO;
+using System.Reflection;
+
+namespace SamplePlugin
+{
+ public class Plugin : IDalamudPlugin
+ {
+ public string Name => "Sample Plugin";
+
+ private const string commandName = "/pmycommand";
+
+ private DalamudPluginInterface pi;
+ private Configuration configuration;
+ private PluginUI ui;
+
+ public void Initialize(DalamudPluginInterface pluginInterface)
+ {
+ this.pi = pluginInterface;
+
+ this.configuration = this.pi.GetPluginConfig() as Configuration ?? new Configuration();
+ this.configuration.Initialize(this.pi);
+
+ // you might normally want to embed resources and load them from the manifest stream
+ var imagePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"goat.png");
+ var goatImage = this.pi.UiBuilder.LoadImage(imagePath);
+ this.ui = new PluginUI(this.configuration, goatImage);
+
+ this.pi.CommandManager.AddHandler(commandName, new CommandInfo(OnCommand)
+ {
+ HelpMessage = "A useful message to display in /xlhelp"
+ });
+
+ this.pi.UiBuilder.OnBuildUi += DrawUI;
+ this.pi.UiBuilder.OnOpenConfigUi += (sender, args) => DrawConfigUI();
+ }
+
+ public void Dispose()
+ {
+ this.ui.Dispose();
+
+ this.pi.CommandManager.RemoveHandler(commandName);
+ this.pi.Dispose();
+ }
+
+ private void OnCommand(string command, string args)
+ {
+ // in response to the slash command, just display our main ui
+ this.ui.Visible = true;
+ }
+
+ private void DrawUI()
+ {
+ this.ui.Draw();
+ }
+
+ private void DrawConfigUI()
+ {
+ this.ui.SettingsVisible = true;
+ }
+ }
+}
diff --git a/SamplePlugin/PluginUI.cs b/SamplePlugin/PluginUI.cs
new file mode 100644
index 0000000..f078807
--- /dev/null
+++ b/SamplePlugin/PluginUI.cs
@@ -0,0 +1,106 @@
+using ImGuiNET;
+using System;
+using System.Numerics;
+
+namespace SamplePlugin
+{
+ // It is good to have this be disposable in general, in case you ever need it
+ // to do any cleanup
+ class PluginUI : IDisposable
+ {
+ private Configuration configuration;
+
+ private ImGuiScene.TextureWrap goatImage;
+
+ // this extra bool exists for ImGui, since you can't ref a property
+ private bool visible = false;
+ public bool Visible
+ {
+ get { return this.visible; }
+ set { this.visible = value; }
+ }
+
+ private bool settingsVisible = false;
+ public bool SettingsVisible
+ {
+ get { return this.settingsVisible; }
+ set { this.settingsVisible = value; }
+ }
+
+ // passing in the image here just for simplicity
+ public PluginUI(Configuration configuration, ImGuiScene.TextureWrap goatImage)
+ {
+ this.configuration = configuration;
+ this.goatImage = goatImage;
+ }
+
+ public void Dispose()
+ {
+ this.goatImage.Dispose();
+ }
+
+ public void Draw()
+ {
+ // This is our only draw handler attached to UIBuilder, so it needs to be
+ // able to draw any windows we might have open.
+ // Each method checks its own visibility/state to ensure it only draws when
+ // it actually makes sense.
+ // There are other ways to do this, but it is generally best to keep the number of
+ // draw delegates as low as possible.
+
+ DrawMainWindow();
+ DrawSettingsWindow();
+ }
+
+ public void DrawMainWindow()
+ {
+ if (!Visible)
+ {
+ return;
+ }
+
+ ImGui.SetNextWindowSize(new Vector2(375, 330), ImGuiCond.FirstUseEver);
+ ImGui.SetNextWindowSizeConstraints(new Vector2(375, 330), new Vector2(float.MaxValue, float.MaxValue));
+ if (ImGui.Begin("My Amazing Window", ref this.visible, ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse))
+ {
+ ImGui.Text($"The random config bool is {this.configuration.SomePropertyToBeSavedAndWithADefault}");
+
+ if (ImGui.Button("Show Settings"))
+ {
+ SettingsVisible = true;
+ }
+
+ ImGui.Spacing();
+
+ ImGui.Text("Have a goat:");
+ ImGui.Indent(55);
+ ImGui.Image(this.goatImage.ImGuiHandle, new Vector2(this.goatImage.Width, this.goatImage.Height));
+ ImGui.Unindent(55);
+ }
+ ImGui.End();
+ }
+
+ public void DrawSettingsWindow()
+ {
+ if (!SettingsVisible)
+ {
+ return;
+ }
+
+ ImGui.SetNextWindowSize(new Vector2(232, 75), ImGuiCond.Always);
+ if (ImGui.Begin("A Wonderful Configuration Window", ref this.settingsVisible,
+ ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse))
+ {
+ // can't ref a property, so use a local copy
+ var configValue = this.configuration.SomePropertyToBeSavedAndWithADefault;
+ if (ImGui.Checkbox("Random Config Bool", ref configValue))
+ {
+ this.configuration.SomePropertyToBeSavedAndWithADefault = configValue;
+ // can save immediately on change, if you don't want to provide a "Save and Close" button
+ this.configuration.Save();
+ }
+ }
+ ImGui.End();
+ }
+ }
+}
diff --git a/SamplePlugin/Properties/AssemblyInfo.cs b/SamplePlugin/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..8c14100
--- /dev/null
+++ b/SamplePlugin/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("samplePlugin")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SamplePlugin")]
+[assembly: AssemblyCopyright("Copyright © 2020")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("13c812e9-0d42-4b95-8646-40eebf30636f")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/SamplePlugin/SamplePlugin.csproj b/SamplePlugin/SamplePlugin.csproj
new file mode 100644
index 0000000..16494c8
--- /dev/null
+++ b/SamplePlugin/SamplePlugin.csproj
@@ -0,0 +1,72 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {13C812E9-0D42-4B95-8646-40EEBF30636F}
+ Library
+ Properties
+ SamplePlugin
+ samplePlugin
+ v4.7.2
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\..\Dalamud\Dalamud\bin\Release\Dalamud.dll
+ False
+
+
+ ..\..\Dalamud\Dalamud\bin\Release\ImGui.NET.dll
+ False
+
+
+ ..\..\Dalamud\Dalamud\bin\Release\ImGuiScene.dll
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+ false
+
+
+
+
\ No newline at end of file
diff --git a/UIDev/App.config b/UIDev/App.config
new file mode 100644
index 0000000..56efbc7
--- /dev/null
+++ b/UIDev/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UIDev/Framework/IPluginUIMock.cs b/UIDev/Framework/IPluginUIMock.cs
new file mode 100644
index 0000000..6f356cd
--- /dev/null
+++ b/UIDev/Framework/IPluginUIMock.cs
@@ -0,0 +1,10 @@
+using ImGuiScene;
+using System;
+
+namespace UIDev
+{
+ interface IPluginUIMock : IDisposable
+ {
+ void Initialize(SimpleImGuiScene scene);
+ }
+}
diff --git a/UIDev/Framework/UIBootstrap.cs b/UIDev/Framework/UIBootstrap.cs
new file mode 100644
index 0000000..6de0014
--- /dev/null
+++ b/UIDev/Framework/UIBootstrap.cs
@@ -0,0 +1,100 @@
+using ImGuiNET;
+using ImGuiScene;
+using System;
+using System.Numerics;
+using System.Runtime.InteropServices;
+using static SDL2.SDL;
+
+namespace UIDev
+{
+ class UIBootstrap
+ {
+ public static unsafe void Inititalize(IPluginUIMock pluginUI)
+ {
+ // you can edit this if you want more control over things
+ // mainly if you want a regular window instead of transparent overlay
+ // Typically you don't want to change any colors here if you keep the fullscreen overlay
+ using (var scene = new SimpleImGuiScene(RendererFactory.RendererBackend.DirectX11, new WindowCreateInfo
+ {
+ Title = "UI Test",
+ Fullscreen = true,
+ TransparentColor = new float[] { 0, 0, 0 },
+ }))
+ {
+ // the background color of your window - typically don't change this for fullscreen overlays
+ scene.Renderer.ClearColor = new Vector4(0, 0, 0, 0);
+
+ // this just makes the application quit if you hit escape
+ scene.Window.OnSDLEvent += (ref SDL_Event sdlEvent) =>
+ {
+ if (sdlEvent.type == SDL_EventType.SDL_KEYDOWN && sdlEvent.key.keysym.scancode == SDL_Scancode.SDL_SCANCODE_ESCAPE)
+ {
+ scene.ShouldQuit = true;
+ }
+ };
+
+ // all of this is taken straight from dalamud
+
+ ImFontConfigPtr fontConfig = ImGuiNative.ImFontConfig_ImFontConfig();
+ fontConfig.MergeMode = true;
+ fontConfig.PixelSnapH = true;
+
+ var fontPathJp = @"NotoSansCJKjp-Medium.otf";
+ ImGui.GetIO().Fonts.AddFontFromFileTTF(fontPathJp, 17.0f, null, ImGui.GetIO().Fonts.GetGlyphRangesJapanese());
+
+ var fontPathGame = @"gamesym.ttf";
+
+ var rangeHandle = GCHandle.Alloc(new ushort[]
+ {
+ 0xE020,
+ 0xE0DB,
+ 0
+ }, GCHandleType.Pinned);
+
+
+ ImGui.GetIO().Fonts.AddFontFromFileTTF(fontPathGame, 17.0f, fontConfig, rangeHandle.AddrOfPinnedObject());
+
+ ImGui.GetIO().Fonts.Build();
+
+ fontConfig.Destroy();
+ rangeHandle.Free();
+
+
+ ImGui.GetStyle().GrabRounding = 3f;
+ ImGui.GetStyle().FrameRounding = 4f;
+ ImGui.GetStyle().WindowRounding = 4f;
+ ImGui.GetStyle().WindowBorderSize = 0f;
+ ImGui.GetStyle().WindowMenuButtonPosition = ImGuiDir.Right;
+ ImGui.GetStyle().ScrollbarSize = 16f;
+
+ ImGui.GetStyle().Colors[(int)ImGuiCol.WindowBg] = new Vector4(0.06f, 0.06f, 0.06f, 0.87f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.FrameBg] = new Vector4(0.29f, 0.29f, 0.29f, 0.54f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.FrameBgHovered] = new Vector4(0.54f, 0.54f, 0.54f, 0.40f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.FrameBgActive] = new Vector4(0.64f, 0.64f, 0.64f, 0.67f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.TitleBgActive] = new Vector4(0.29f, 0.29f, 0.29f, 1.00f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.CheckMark] = new Vector4(0.86f, 0.86f, 0.86f, 1.00f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.SliderGrab] = new Vector4(0.54f, 0.54f, 0.54f, 1.00f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.SliderGrabActive] = new Vector4(0.67f, 0.67f, 0.67f, 1.00f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.Button] = new Vector4(0.71f, 0.71f, 0.71f, 0.40f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.ButtonHovered] = new Vector4(0.47f, 0.47f, 0.47f, 1.00f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.ButtonActive] = new Vector4(0.74f, 0.74f, 0.74f, 1.00f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.Header] = new Vector4(0.59f, 0.59f, 0.59f, 0.31f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.HeaderHovered] = new Vector4(0.50f, 0.50f, 0.50f, 0.80f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.HeaderActive] = new Vector4(0.60f, 0.60f, 0.60f, 1.00f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.ResizeGrip] = new Vector4(0.79f, 0.79f, 0.79f, 0.25f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.ResizeGripHovered] = new Vector4(0.78f, 0.78f, 0.78f, 0.67f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.ResizeGripActive] = new Vector4(0.88f, 0.88f, 0.88f, 0.95f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.Tab] = new Vector4(0.23f, 0.23f, 0.23f, 0.86f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.TabHovered] = new Vector4(0.71f, 0.71f, 0.71f, 0.80f);
+ ImGui.GetStyle().Colors[(int)ImGuiCol.TabActive] = new Vector4(0.36f, 0.36f, 0.36f, 1.00f);
+ // end dalamud copy
+
+ pluginUI.Initialize(scene);
+
+ scene.Run();
+
+ pluginUI.Dispose();
+ }
+ }
+ }
+}
diff --git a/UIDev/Properties/AssemblyInfo.cs b/UIDev/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..b25f720
--- /dev/null
+++ b/UIDev/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("UIDev")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("UIDev")]
+[assembly: AssemblyCopyright("Copyright © 2020")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("4fec9558-eb25-419f-b86e-51b8cfda32b7")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/UIDev/UIDev.csproj b/UIDev/UIDev.csproj
new file mode 100644
index 0000000..0deaf02
--- /dev/null
+++ b/UIDev/UIDev.csproj
@@ -0,0 +1,110 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {4FEC9558-EB25-419F-B86E-51B8CFDA32B7}
+ Exe
+ UIDev
+ UIDev
+ v4.7.2
+ 512
+ true
+ true
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+ true
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ false
+ true
+
+
+
+ ..\..\Dalamud\Dalamud\bin\Release\ImGui.NET.dll
+
+
+ ..\..\Dalamud\Dalamud\bin\Release\ImGuiScene.dll
+
+
+ ..\..\Dalamud\Dalamud\bin\Release\SDL2-CS.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+ false
+
+
+ PreserveNewest
+ false
+
+
+ PreserveNewest
+ false
+
+
+
+
+ False
+ Microsoft .NET Framework 4.7.2 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+
+
\ No newline at end of file
diff --git a/UIDev/UITest.cs b/UIDev/UITest.cs
new file mode 100644
index 0000000..a42d042
--- /dev/null
+++ b/UIDev/UITest.cs
@@ -0,0 +1,122 @@
+using ImGuiNET;
+using ImGuiScene;
+using System;
+using System.Numerics;
+
+namespace UIDev
+{
+ class UITest : IPluginUIMock
+ {
+ public static void Main(string[] args)
+ {
+ UIBootstrap.Inititalize(new UITest());
+ }
+
+ private TextureWrap goatImage;
+ private SimpleImGuiScene scene;
+
+ public void Initialize(SimpleImGuiScene scene)
+ {
+ // scene is a little different from what you have access to in dalamud
+ // but it can accomplish the same things, and is really only used for initial setup here
+
+ // eg, to load an image resource for use with ImGui
+ this.goatImage = scene.LoadImage(@"goat.png");
+
+ scene.OnBuildUI += Draw;
+
+ this.Visible = true;
+
+ // saving this only so we can kill the test application by closing the window
+ // (instead of just by hitting escape)
+ this.scene = scene;
+ }
+
+ public void Dispose()
+ {
+ this.goatImage.Dispose();
+ }
+
+ // You COULD go all out here and make your UI generic and work on interfaces etc, and then
+ // mock dependencies and conceivably use exactly the same class in this testbed and the actual plugin
+ // That is, however, a bit excessive in general - it could easily be done for this sample, but I
+ // don't want to imply that is easy or the best way to go usually, so it's not done here either
+ private void Draw()
+ {
+ DrawMainWindow();
+ DrawSettingsWindow();
+
+ if (!Visible)
+ {
+ this.scene.ShouldQuit = true;
+ }
+ }
+
+ #region Nearly a copy/paste of PluginUI
+ private bool visible = false;
+ public bool Visible
+ {
+ get { return this.visible; }
+ set { this.visible = value; }
+ }
+
+ private bool settingsVisible = false;
+ public bool SettingsVisible
+ {
+ get { return this.settingsVisible; }
+ set { this.settingsVisible = value; }
+ }
+
+ // this is where you'd have to start mocking objects if you really want to match
+ // but for simple UI creation purposes, just hardcoding values works
+ private bool fakeConfigBool = true;
+
+ public void DrawMainWindow()
+ {
+ if (!Visible)
+ {
+ return;
+ }
+
+ ImGui.SetNextWindowSize(new Vector2(375, 330), ImGuiCond.FirstUseEver);
+ ImGui.SetNextWindowSizeConstraints(new Vector2(375, 330), new Vector2(float.MaxValue, float.MaxValue));
+ if (ImGui.Begin("My Amazing Window", ref this.visible, ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse))
+ {
+ ImGui.Text($"The random config bool is {this.fakeConfigBool}");
+
+ if (ImGui.Button("Show Settings"))
+ {
+ SettingsVisible = true;
+ }
+
+ ImGui.Spacing();
+
+ ImGui.Text("Have a goat:");
+ ImGui.Indent(55);
+ ImGui.Image(this.goatImage.ImGuiHandle, new Vector2(this.goatImage.Width, this.goatImage.Height));
+ ImGui.Unindent(55);
+ }
+ ImGui.End();
+ }
+
+ public void DrawSettingsWindow()
+ {
+ if (!SettingsVisible)
+ {
+ return;
+ }
+
+ ImGui.SetNextWindowSize(new Vector2(232, 75), ImGuiCond.Always);
+ if (ImGui.Begin("A Wonderful Configuration Window", ref this.settingsVisible,
+ ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse))
+ {
+ if (ImGui.Checkbox("Random Config Bool", ref this.fakeConfigBool))
+ {
+ // nothing to do in a fake ui!
+ }
+ }
+ ImGui.End();
+ }
+ #endregion
+ }
+}