コード例 #1
0
 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);
コード例 #2
0
        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);
        }
コード例 #3
0
 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);
コード例 #4
0
 public unsafe TextInput()
 {
     TextCallbackDelegate = (data) =>
     {
         InputtedString = new string((sbyte *)(data->Buf));
         return(0);
     };
 }
コード例 #5
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));
 }
コード例 #6
0
 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;
 }
コード例 #7
0
        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);
        }
コード例 #8
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);
        }
コード例 #10
0
ファイル: MemoryEditor.cs プロジェクト: Kaydax/ImGui.NET
        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();
        }
コード例 #11
0
 public abstract byte igInputText(byte *label, byte *buf, uint buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void *user_data);
コード例 #12
0
ファイル: ShaderEditor.cs プロジェクト: Calebsem/YALCT
        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();
            }
        }
コード例 #13
0
    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();
        }
    }