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 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 InputTextWithHint( string label, string hint, ref string input, uint maxLength, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback) => InputTextWithHint(label, hint, ref input, maxLength, flags, callback, IntPtr.Zero);
public unsafe TextInput() { TextCallbackDelegate = (data) => { InputtedString = new string((sbyte *)(data->Buf)); return(0); }; }
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 TextBuffer(int sz = 2048) { if ((sz % 8) != 0) { throw new Exception("Must be multiple of 8"); } Size = sz; Pointer = Marshal.AllocHGlobal(sz); Clear(); Callback = HandleTextEditCallback; }
public static bool InputTextMultiline( string label, ref string input, uint maxLength, Vector2 size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, IntPtr user_data) { int labelByteCount = Encoding.UTF8.GetByteCount(label); byte *labelBytes = stackalloc byte[labelByteCount]; fixed(char *labelPtr = label) { Encoding.UTF8.GetBytes(labelPtr, label.Length, labelBytes, labelByteCount); } int originalByteCount = Encoding.UTF8.GetByteCount(input); int stackBufSize = Math.Max((int)maxLength, originalByteCount); byte *bufBytes = stackalloc byte[stackBufSize]; fixed(char *u16Ptr = input) { Encoding.UTF8.GetBytes(u16Ptr, input.Length, bufBytes, stackBufSize); } byte *originalBufBytes = stackalloc byte[originalByteCount]; Unsafe.CopyBlock(originalBufBytes, bufBytes, (uint)originalByteCount); byte result = ImGuiNative.igInputTextMultiline( labelBytes, bufBytes, (uint)stackBufSize, size, flags, callback, user_data.ToPointer()); if (!Util.AreStringsEqual(originalBufBytes, originalByteCount, bufBytes)) { input = Util.StringFromPtr(bufBytes); } return(result != 0); }
public static bool InputText( string label, IntPtr buf, uint buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, IntPtr user_data) { int labelByteCount = Encoding.UTF8.GetByteCount(label); byte *labelBytes = stackalloc byte[labelByteCount]; fixed(char *labelPtr = label) { Encoding.UTF8.GetBytes(labelPtr, label.Length, labelBytes, labelByteCount); } return(ImGuiNative.igInputText(labelBytes, (byte *)buf.ToPointer(), buf_size, flags, callback, user_data.ToPointer()) != 0); }
public static bool InputTextWithHint( string label, string hint, 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 utf8HintByteCount = Encoding.UTF8.GetByteCount(hint); byte *utf8HintBytes; if (utf8HintByteCount > Util.StackAllocationSizeLimit) { utf8HintBytes = Util.Allocate(utf8HintByteCount + 1); } else { byte *stackPtr = stackalloc byte[utf8HintByteCount + 1]; utf8HintBytes = stackPtr; } Util.GetUtf8(hint, utf8HintBytes, utf8HintByteCount); 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.igInputTextWithHint( utf8LabelBytes, utf8HintBytes, 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 unsafe void Draw(string title, byte[] mem_data, int mem_size, int base_display_addr = 0) { ImGui.SetNextWindowSize(new Vector2(500, 350), ImGuiCond.FirstUseEver); if (!ImGui.Begin(title)) { ImGui.End(); return; } float line_height = ImGuiNative.igGetTextLineHeight(); int line_total_count = (mem_size + Rows - 1) / Rows; ImGuiNative.igSetNextWindowContentSize(new Vector2(0.0f, line_total_count * line_height)); ImGui.BeginChild("##scrolling", new Vector2(0, -ImGuiNative.igGetFrameHeightWithSpacing()), false, 0); ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, new Vector2(0, 0)); ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(0, 0)); int addr_digits_count = 0; for (int n = base_display_addr + mem_size - 1; n > 0; n >>= 4) { addr_digits_count++; } float glyph_width = ImGui.CalcTextSize("F").X; float cell_width = glyph_width * 3; // "FF " we include trailing space in the width to easily catch clicks everywhere var clipper = new ImGuiListClipper2(line_total_count, line_height); int visible_start_addr = clipper.DisplayStart * Rows; int visible_end_addr = clipper.DisplayEnd * Rows; bool data_next = false; if (!AllowEdits || DataEditingAddr >= mem_size) { DataEditingAddr = -1; } int data_editing_addr_backup = DataEditingAddr; if (DataEditingAddr != -1) { if (ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.UpArrow)) && DataEditingAddr >= Rows) { DataEditingAddr -= Rows; DataEditingTakeFocus = true; } else if (ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.DownArrow)) && DataEditingAddr < mem_size - Rows) { DataEditingAddr += Rows; DataEditingTakeFocus = true; } else if (ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.LeftArrow)) && DataEditingAddr > 0) { DataEditingAddr -= 1; DataEditingTakeFocus = true; } else if (ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.RightArrow)) && DataEditingAddr < mem_size - 1) { DataEditingAddr += 1; DataEditingTakeFocus = true; } } if ((DataEditingAddr / Rows) != (data_editing_addr_backup / Rows)) { // Track cursor movements float scroll_offset = ((DataEditingAddr / Rows) - (data_editing_addr_backup / Rows)) * line_height; bool scroll_desired = (scroll_offset < 0.0f && DataEditingAddr < visible_start_addr + Rows * 2) || (scroll_offset > 0.0f && DataEditingAddr > visible_end_addr - Rows * 2); if (scroll_desired) { ImGuiNative.igSetScrollYFloat(ImGuiNative.igGetScrollY() + scroll_offset); } } for (int line_i = clipper.DisplayStart; line_i < clipper.DisplayEnd; line_i++) // display only visible items { int addr = line_i * Rows; ImGui.Text(FixedHex(base_display_addr + addr, addr_digits_count) + ": "); ImGui.SameLine(); // Draw Hexadecimal float line_start_x = ImGuiNative.igGetCursorPosX(); for (int n = 0; n < Rows && addr < mem_size; n++, addr++) { ImGui.SameLine(line_start_x + cell_width * n); if (DataEditingAddr == addr) { // Display text input on current byte ImGui.PushID(addr); // FIXME: We should have a way to retrieve the text edit cursor position more easily in the API, this is rather tedious. ImGuiInputTextCallback callback = (data) => { int *p_cursor_pos = (int *)data->UserData; if (ImGuiNative.ImGuiInputTextCallbackData_HasSelection(data) == 0) { *p_cursor_pos = data->CursorPos; } return(0); }; int cursor_pos = -1; bool data_write = false; if (DataEditingTakeFocus) { ImGui.SetKeyboardFocusHere(); ReplaceChars(DataInput, FixedHex(mem_data[addr], 2)); ReplaceChars(AddrInput, FixedHex(base_display_addr + addr, addr_digits_count)); } ImGui.PushItemWidth(ImGui.CalcTextSize("FF").X); var flags = ImGuiInputTextFlags.CharsHexadecimal | ImGuiInputTextFlags.EnterReturnsTrue | ImGuiInputTextFlags.AutoSelectAll | ImGuiInputTextFlags.NoHorizontalScroll | ImGuiInputTextFlags.AlwaysOverwrite | ImGuiInputTextFlags.CallbackAlways; if (ImGui.InputText("##data", DataInput, 32, flags, callback, (IntPtr)(&cursor_pos))) { data_write = data_next = true; } else if (!DataEditingTakeFocus && !ImGui.IsItemActive()) { DataEditingAddr = -1; } DataEditingTakeFocus = false; ImGui.PopItemWidth(); if (cursor_pos >= 2) { data_write = data_next = true; } if (data_write) { int data; if (TryHexParse(DataInput, out data)) { mem_data[addr] = (byte)data; } } ImGui.PopID(); } else { ImGui.Text(FixedHex(mem_data[addr], 2)); if (AllowEdits && ImGui.IsItemHovered() && ImGui.IsMouseClicked(0)) { DataEditingTakeFocus = true; DataEditingAddr = addr; } } } ImGui.SameLine(line_start_x + cell_width * Rows + glyph_width * 2); //separator line drawing replaced by printing a pipe char // Draw ASCII values addr = line_i * Rows; var asciiVal = new System.Text.StringBuilder(2 + Rows); asciiVal.Append("| "); for (int n = 0; n < Rows && addr < mem_size; n++, addr++) { int c = mem_data[addr]; asciiVal.Append((c >= 32 && c < 128) ? Convert.ToChar(c) : '.'); } ImGui.TextUnformatted(asciiVal.ToString()); //use unformatted, so string can contain the '%' character } //clipper.End(); //not implemented ImGui.PopStyleVar(2); ImGui.EndChild(); if (data_next && DataEditingAddr < mem_size) { DataEditingAddr = DataEditingAddr + 1; DataEditingTakeFocus = true; } ImGui.Separator(); ImGuiNative.igAlignTextToFramePadding(); ImGui.PushItemWidth(50); ImGui.PushAllowKeyboardFocus(true); int rows_backup = Rows; if (ImGui.DragInt("##rows", ref Rows, 0.2f, 4, 32, "%.0f rows")) { if (Rows <= 0) { Rows = 4; } Vector2 new_window_size = ImGui.GetWindowSize(); new_window_size.X += (Rows - rows_backup) * (cell_width + glyph_width); ImGui.SetWindowSize(new_window_size); } ImGui.PopAllowKeyboardFocus(); ImGui.PopItemWidth(); ImGui.SameLine(); ImGui.Text(string.Format(" Range {0}..{1} ", FixedHex(base_display_addr, addr_digits_count), FixedHex(base_display_addr + mem_size - 1, addr_digits_count))); ImGui.SameLine(); ImGui.PushItemWidth(70); if (ImGui.InputText("##addr", AddrInput, 32, ImGuiInputTextFlags.CharsHexadecimal | ImGuiInputTextFlags.EnterReturnsTrue, null)) { int goto_addr; if (TryHexParse(AddrInput, out goto_addr)) { goto_addr -= base_display_addr; if (goto_addr >= 0 && goto_addr < mem_size) { ImGui.BeginChild("##scrolling"); ImGui.SetScrollFromPosY(ImGui.GetCursorStartPos().Y + (goto_addr / Rows) * ImGuiNative.igGetTextLineHeight()); ImGui.EndChild(); DataEditingAddr = goto_addr; DataEditingTakeFocus = true; } } } ImGui.PopItemWidth(); ImGui.End(); }
public abstract byte igInputText(byte *label, byte *buf, uint buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void *user_data);
private unsafe void SubmitAdvancedEditor() { if (ImGui.BeginChild("editor", Vector2.Zero, true)) { // handle basic input if (editorSelectedLineIndex != -1) { if ((editorSelectedLineCursorPosition == 0 && ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.LeftArrow), false)) || ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.UpArrow), true)) { SetSelectedLine(editorSelectedLineIndex - 1); } if ((editorSelectedLineCursorPosition == editorSelectedLineContent.Length && ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.RightArrow), false)) || ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.DownArrow), true)) { SetSelectedLine(editorSelectedLineIndex + 1); } if (ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.Enter), true)) { string newLineContent = ""; if (editorSelectedLineCursorPosition != editorSelectedLineContent.Length) { fragmentCodeLines[editorSelectedLineIndex] = editorSelectedLineContent.Take(editorSelectedLineCursorPosition).ToSystemString(); newLineContent = editorSelectedLineContent.Skip(editorSelectedLineCursorPosition).ToSystemString(); } fragmentCodeLines.Insert(editorSelectedLineIndex + 1, newLineContent); SetSelectedLine(editorSelectedLineIndex + 1); } if (editorSelectedLineIndex > 0) { if (editorSelectedLineCursorPosition == 0 && ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.Backspace), true)) { if (!string.IsNullOrEmpty(editorSelectedLineContent)) { fragmentCodeLines[editorSelectedLineIndex - 1] += editorSelectedLineContent; } fragmentCodeLines.RemoveAt(editorSelectedLineIndex); SetSelectedLine(editorSelectedLineIndex - 1); } } } // draw lines for (int i = 0; i < fragmentCodeLines.Count; i++) { string line = fragmentCodeLines[i]; string lineNumber = $"{i + Controller.Context.FragmentHeaderLineCount}"; bool isError = errorMessages.Any(msg => msg.StartsWith($"{lineNumber}:")); bool isEdited = i == editorSelectedLineIndex; ImGui.TextColored( isEdited ? RgbaFloat.Green.ToVector4() : isError ? RgbaFloat.Red.ToVector4() : RgbaFloat.LightGrey.ToVector4(), lineNumber); ImGui.SameLine(50); if (isError) { ImGui.PushStyleColor(ImGuiCol.Text, RgbaFloat.Red.ToVector4()); } if (isEdited) { ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, Vector2.Zero); ImGui.PushItemWidth(-1); // taken from https://github.com/mellinoe/ImGui.NET/blob/0b9c9ea07d720ac0c4e382deb8f08de30703a9a3/src/ImGui.NET.SampleProgram/MemoryEditor.cs#L128 // which is not ideal ImGuiInputTextCallback callback = (data) => { int *p_cursor_pos = (int *)data->UserData; if (ImGuiNative.ImGuiInputTextCallbackData_HasSelection(data) == 0) { *p_cursor_pos = data->CursorPos; } return(0); }; int cursorPos = -1; const ImGuiInputTextFlags flags = ImGuiInputTextFlags.AllowTabInput | ImGuiInputTextFlags.CallbackAlways; if (ImGui.InputText(lineNumber, ref editorSelectedLineContent, 1000, flags, callback, (IntPtr)(&cursorPos))) { fragmentCodeLines[editorSelectedLineIndex] = editorSelectedLineContent; } ImGui.PopItemWidth(); ImGui.PopStyleVar(1); editorSelectedLineCursorPosition = cursorPos; } else if (ImGui.Selectable(line)) { SetSelectedLine(i); } if (isError) { ImGui.PopStyleColor(1); } } ImGui.EndChild(); } }
unsafe void Layout() { if (!CursorDefault.consoleIsOpen) { //ImGui.ShowDemoWindow(); return; } ImGui.SetNextWindowSize(new Vector2(Screen.width, 200)); ImGui.SetNextWindowPos(new Vector2(0, 0)); if (ImGui.Begin("window", ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.MenuBar | ImGuiWindowFlags.NoSavedSettings)) { ImGui.Separator(); if (ImGui.BeginMenuBar()) { ImGui.Checkbox("Errors", ref showErrors); ImGui.Checkbox("Warnings", ref showWarnings); ImGui.Checkbox("Info", ref showInfo); ImGui.Spacing(); ImGui.Checkbox("Timestamps", ref timestamps); ImGui.EndMenuBar(); } ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(0, 0)); ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, Vector2.one); if (ImGui.BeginChildFrame(1, ImGui.GetWindowSize() - new Vector2(0, 60))) { uint idx = 0; foreach (var log in inst.logs) { string str = timestamps ? log.logStr : log.logStrNoTimestamp; ImGui.PushStyleVar(ImGuiStyleVar.ItemInnerSpacing, Vector2.zero); TimeSpan diff = DateTime.Now - log.time; float alpha = 1 - Mathf.Clamp01((float)diff.TotalSeconds - (float)CmdFadeTime.TotalSeconds); Vector4 col = Vector4.one; if (log.logType == LogType.Assert || log.logType == LogType.Exception) { col = new Vector4(.6f, 0, 0, 1); } if (log.logType == LogType.Error) { col = new Vector4(1, 0, 0, 1); } if (log.logType == LogType.Warning) { col = new Vector4(1, 1, .3f, 1); } if (log.logType == LogType.Log) { col = new Vector4(1, 1, 1, 1); } ImGui.PushStyleColor(ImGuiCol.Button, new Vector4(1, 1, 1, 0.1f * alpha)); ImGui.PushStyleColor(ImGuiCol.Text, col); Vector2 size = new Vector2(ImGui.GetWindowWidth(), ImGui.CalcTextSize(str).y + 3); ImGui.PushStyleVar(ImGuiStyleVar.ButtonTextAlign, new Vector2(0f, 0.5f)); bool show = ((log.logType == LogType.Assert || log.logType == LogType.Exception) && showErrors) || (log.logType == LogType.Error && showErrors) || (log.logType == LogType.Warning && showWarnings) || (log.logType == LogType.Log && showInfo); if (show) { if (ImGui.Button(str, size)) { log.isOpen = !log.isOpen; } if (ImGui.BeginPopupContextItem($"expand_log_{idx}")) { ImGui.Checkbox("Stack trace", ref log.isOpen); if (ImGui.Selectable("Copy...")) { if (log.isOpen) { ImGui.SetClipboardText($"{str}\n{log.stackTrace}"); } else { ImGui.SetClipboardText(str); } inst.PushStatus("Copied!"); } ImGui.EndPopup(); } if (log.isOpen) { ImGui.Text(log.stackTrace); } } ImGui.PopStyleColor(); ImGui.PopStyleColor(); ImGui.PopStyleVar(); ImGui.PopStyleVar(); idx++; } inst.scrollToBottom = ImGui.GetScrollY() >= ImGui.GetScrollMaxY(); if (inst.scrollToBottom) { ImGui.SetScrollHereY(1.0f); } ImGui.EndChildFrame(); } ImGui.PopStyleVar(); ImGui.PopStyleVar(); ImGui.Spacing(); ImGuiInputTextCallback cb = (ImGuiInputTextCallbackData * data) => { ImGuiInputTextCallbackDataPtr ptr = new ImGuiInputTextCallbackDataPtr(data); if (desiredConsoleInput != null) { ptr.DeleteChars(0, ptr.BufTextLen); ptr.InsertChars(0, desiredConsoleInput); desiredConsoleInput = null; } return(ptr.BufTextLen); }; if (ImGui.InputTextWithHint("", ">", ref consoleInput, 150, ImGuiInputTextFlags.EnterReturnsTrue | ImGuiInputTextFlags.CallbackAlways, cb)) { bool didRun = ComReg.RunCom(consoleInput); //if (history.Count == 0 || history[history.Count - 1] != consoleInput) if (didRun) { history.Add(consoleInput); } consoleInput = ""; historyLogIndex = -1; ImGui.SetKeyboardFocusHere(); } if (FocusText) { ImGui.SetKeyboardFocusHere(-1); FocusText = false; } if (consoleInput.Contains("`")) //hack { consoleInput = consoleInput.Replace("`", ""); } ImGui.SameLine(); inst.DrawStatusImgui(); ImGui.End(); } }