using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using ImGuiNET; using ImGuiScene; using Serilog; namespace Dalamud.Interface { /// /// This class represents the Dalamud UI that is drawn on top of the game. /// It can be used to draw custom windows and overlays. /// public class UiBuilder : IDisposable { private readonly string namespaceName; /// /// The delegate that gets called when Dalamud is ready to draw your windows or overlays. /// When it is called, you can use static ImGui calls. /// public event RawDX11Scene.BuildUIDelegate OnBuildUi; private readonly InterfaceManager interfaceManager; /// /// Create a new UiBuilder and register it. You do not have to call this manually. /// /// The interface manager to register on. /// The plugin namespace. public UiBuilder(InterfaceManager interfaceManager, string namespaceName) { this.namespaceName = namespaceName; this.interfaceManager = interfaceManager; this.interfaceManager.OnDraw += OnDraw; } /// /// Unregister the UiBuilder. Do not call this in plugin code. /// public void Dispose() { this.interfaceManager.OnDraw -= OnDraw; } /// /// Loads an image from the specified file. /// /// The full filepath to the image. /// A object wrapping the created image. Use inside ImGui.Image() public TextureWrap LoadImage(string filePath) => this.interfaceManager.LoadImage(filePath); /// /// Loads an image from a byte stream, such as a png downloaded into memory. /// /// A byte array containing the raw image data. /// A object wrapping the created image. Use inside ImGui.Image() public TextureWrap LoadImage(byte[] imageData) => this.interfaceManager.LoadImage(imageData); /// /// Loads an image from raw unformatted pixel data, with no type or header information. To load formatted data, use . /// /// A byte array containing the raw pixel data. /// The width of the image contained in . /// The height of the image contained in . /// The number of channels (bytes per pixel) of the image contained in . This should usually be 4. /// A object wrapping the created image. Use inside ImGui.Image() public TextureWrap LoadImageRaw(byte[] imageData, int width, int height, int numChannels) => this.interfaceManager.LoadImageRaw(imageData, width, height, numChannels); /// /// Event that is fired when the plugin should open its configuration interface. /// public EventHandler OnOpenConfigUi; private bool hasErrorWindow; private void OnDraw() { ImGui.PushID(this.namespaceName); if (this.hasErrorWindow && ImGui.Begin(string.Format("{0} Error", this.namespaceName), ref this.hasErrorWindow, ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoResize)) { ImGui.Text(string.Format("The plugin {0} ran into an error.\nContact the plugin developer for support.\n\nPlease try restarting your game.", this.namespaceName)); ImGui.Spacing(); if (ImGui.Button("OK")) { this.hasErrorWindow = false; } ImGui.End(); } try { OnBuildUi?.Invoke(); } catch (Exception ex) { Log.Error(ex, "[{0}] UiBuilder OnBuildUi caught exception", this.namespaceName); OnBuildUi = null; OnOpenConfigUi = null; this.hasErrorWindow = true; } ImGui.PopID(); } } }