using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; namespace ImGuiNET { public static unsafe partial class ImGui { public static bool InputText( string label, byte[] buf, uint buf_size) { return InputText(label, buf, buf_size, 0, null, IntPtr.Zero); } public static bool InputText( string label, byte[] buf, uint buf_size, ImGuiInputTextFlags flags) { return InputText(label, buf, buf_size, flags, null, IntPtr.Zero); } public static bool InputText( string label, byte[] buf, uint buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback) { return InputText(label, buf, buf_size, flags, callback, IntPtr.Zero); } public static bool InputText( string label, byte[] buf, uint buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, IntPtr user_data) { int utf8LabelByteCount = Encoding.UTF8.GetByteCount(label); byte* utf8LabelBytes; if (utf8LabelByteCount > Util.StackAllocationSizeLimit) { utf8LabelBytes = Util.Allocate(utf8LabelByteCount + 1); } else { byte* stackPtr = stackalloc byte[utf8LabelByteCount + 1]; utf8LabelBytes = stackPtr; } Util.GetUtf8(label, utf8LabelBytes, utf8LabelByteCount); bool ret; fixed (byte* bufPtr = buf) { ret = ImGuiNative.igInputText(utf8LabelBytes, bufPtr, buf_size, flags, callback, user_data.ToPointer()) != 0; } if (utf8LabelByteCount > Util.StackAllocationSizeLimit) { Util.Free(utf8LabelBytes); } return ret; } public static bool InputText( string label, ref string input, uint maxLength) => InputText(label, ref input, maxLength, 0, null, IntPtr.Zero); public static bool InputText( string label, ref string input, uint maxLength, ImGuiInputTextFlags flags) => InputText(label, ref input, maxLength, flags, null, IntPtr.Zero); public static bool InputText( string label, ref string input, uint maxLength, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback) => InputText(label, ref input, maxLength, flags, callback, IntPtr.Zero); public static bool InputText( string label, ref string input, uint maxLength, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, IntPtr user_data) { int utf8LabelByteCount = Encoding.UTF8.GetByteCount(label); byte* utf8LabelBytes; if (utf8LabelByteCount > Util.StackAllocationSizeLimit) { utf8LabelBytes = Util.Allocate(utf8LabelByteCount + 1); } else { byte* stackPtr = stackalloc byte[utf8LabelByteCount + 1]; utf8LabelBytes = stackPtr; } Util.GetUtf8(label, utf8LabelBytes, utf8LabelByteCount); int utf8InputByteCount = Encoding.UTF8.GetByteCount(input); int inputBufSize = Math.Max((int)maxLength + 1, utf8InputByteCount + 1); byte* utf8InputBytes; byte* originalUtf8InputBytes; if (inputBufSize > Util.StackAllocationSizeLimit) { utf8InputBytes = Util.Allocate(inputBufSize); originalUtf8InputBytes = Util.Allocate(inputBufSize); } else { byte* inputStackBytes = stackalloc byte[inputBufSize]; utf8InputBytes = inputStackBytes; byte* originalInputStackBytes = stackalloc byte[inputBufSize]; originalUtf8InputBytes = originalInputStackBytes; } Util.GetUtf8(input, utf8InputBytes, inputBufSize); uint clearBytesCount = (uint)(inputBufSize - utf8InputByteCount); Unsafe.InitBlockUnaligned(utf8InputBytes + utf8InputByteCount, 0, clearBytesCount); Unsafe.CopyBlock(originalUtf8InputBytes, utf8InputBytes, (uint)inputBufSize); byte result = ImGuiNative.igInputText( utf8LabelBytes, utf8InputBytes, (uint)inputBufSize, flags, callback, user_data.ToPointer()); if (!Util.AreStringsEqual(originalUtf8InputBytes, inputBufSize, utf8InputBytes)) { input = Util.StringFromPtr(utf8InputBytes); } if (utf8LabelByteCount > Util.StackAllocationSizeLimit) { Util.Free(utf8LabelBytes); } if (inputBufSize > Util.StackAllocationSizeLimit) { Util.Free(utf8InputBytes); Util.Free(originalUtf8InputBytes); } return result != 0; } public static bool InputTextMultiline( string label, ref string input, uint maxLength, Vector2 size) => InputTextMultiline(label, ref input, maxLength, size, 0, null, IntPtr.Zero); public static bool InputTextMultiline( string label, ref string input, uint maxLength, Vector2 size, ImGuiInputTextFlags flags) => InputTextMultiline(label, ref input, maxLength, size, flags, null, IntPtr.Zero); public static bool InputTextMultiline( string label, ref string input, uint maxLength, Vector2 size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback) => InputTextMultiline(label, ref input, maxLength, size, flags, callback, IntPtr.Zero); public static bool InputTextMultiline( string label, ref string input, uint maxLength, Vector2 size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, IntPtr user_data) { int utf8LabelByteCount = Encoding.UTF8.GetByteCount(label); byte* utf8LabelBytes; if (utf8LabelByteCount > Util.StackAllocationSizeLimit) { utf8LabelBytes = Util.Allocate(utf8LabelByteCount + 1); } else { byte* stackPtr = stackalloc byte[utf8LabelByteCount + 1]; utf8LabelBytes = stackPtr; } Util.GetUtf8(label, utf8LabelBytes, utf8LabelByteCount); int utf8InputByteCount = Encoding.UTF8.GetByteCount(input); int inputBufSize = Math.Max((int)maxLength + 1, utf8InputByteCount + 1); byte* utf8InputBytes; byte* originalUtf8InputBytes; if (inputBufSize > Util.StackAllocationSizeLimit) { utf8InputBytes = Util.Allocate(inputBufSize); originalUtf8InputBytes = Util.Allocate(inputBufSize); } else { byte* inputStackBytes = stackalloc byte[inputBufSize]; utf8InputBytes = inputStackBytes; byte* originalInputStackBytes = stackalloc byte[inputBufSize]; originalUtf8InputBytes = originalInputStackBytes; } Util.GetUtf8(input, utf8InputBytes, inputBufSize); uint clearBytesCount = (uint)(inputBufSize - utf8InputByteCount); Unsafe.InitBlockUnaligned(utf8InputBytes + utf8InputByteCount, 0, clearBytesCount); Unsafe.CopyBlock(originalUtf8InputBytes, utf8InputBytes, (uint)inputBufSize); byte result = ImGuiNative.igInputTextMultiline( utf8LabelBytes, utf8InputBytes, (uint)inputBufSize, size, flags, callback, user_data.ToPointer()); if (!Util.AreStringsEqual(originalUtf8InputBytes, inputBufSize, utf8InputBytes)) { input = Util.StringFromPtr(utf8InputBytes); } if (utf8LabelByteCount > Util.StackAllocationSizeLimit) { Util.Free(utf8LabelBytes); } if (inputBufSize > Util.StackAllocationSizeLimit) { Util.Free(utf8InputBytes); Util.Free(originalUtf8InputBytes); } return result != 0; } public static bool InputText( string label, IntPtr buf, uint buf_size) { return InputText(label, buf, buf_size, 0, null, IntPtr.Zero); } public static bool InputText( string label, IntPtr buf, uint buf_size, ImGuiInputTextFlags flags) { return InputText(label, buf, buf_size, flags, null, IntPtr.Zero); } public static bool InputText( string label, IntPtr buf, uint buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback) { return InputText(label, buf, buf_size, flags, callback, IntPtr.Zero); } public static bool InputText( string label, IntPtr buf, uint buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, IntPtr user_data) { int utf8LabelByteCount = Encoding.UTF8.GetByteCount(label); byte* utf8LabelBytes; if (utf8LabelByteCount > Util.StackAllocationSizeLimit) { utf8LabelBytes = Util.Allocate(utf8LabelByteCount + 1); } else { byte* stackPtr = stackalloc byte[utf8LabelByteCount + 1]; utf8LabelBytes = stackPtr; } Util.GetUtf8(label, utf8LabelBytes, utf8LabelByteCount); bool ret = ImGuiNative.igInputText(utf8LabelBytes, (byte*)buf.ToPointer(), buf_size, flags, callback, user_data.ToPointer()) != 0; if (utf8LabelByteCount > Util.StackAllocationSizeLimit) { Util.Free(utf8LabelBytes); } return ret; } public static bool Begin(string name, ImGuiWindowFlags flags) { int utf8NameByteCount = Encoding.UTF8.GetByteCount(name); byte* utf8NameBytes; if (utf8NameByteCount > Util.StackAllocationSizeLimit) { utf8NameBytes = Util.Allocate(utf8NameByteCount + 1); } else { byte* stackPtr = stackalloc byte[utf8NameByteCount + 1]; utf8NameBytes = stackPtr; } Util.GetUtf8(name, utf8NameBytes, utf8NameByteCount); byte* p_open = null; byte ret = ImGuiNative.igBegin(utf8NameBytes, p_open, flags); if (utf8NameByteCount > Util.StackAllocationSizeLimit) { Util.Free(utf8NameBytes); } return ret != 0; } public static bool MenuItem(string label, bool enabled) { return MenuItem(label, string.Empty, false, enabled); } } }